cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Have your say in shaping JMP's future by participating in the new JMP Wish List Prioritization Survey
Choose Language Hide Translation Bar
neelsrejan
Level III

How to add a dynamic horizontal lines with a shared y axis in a variability chart with grouped x axis with repeat values of different N?

Hi all, 

 

I wanted to create a new thread to differentiate based on my previous post: https://community.jmp.com/t5/Discussions/How-to-add-Dynamic-horizontal-line-by-shared-y-axis-among/m.... The same idea is to be applied where I would want a dynamic horizontal line across a variability chart, but unlike the previous solution that uses an associative array as there is one value per x, this case potentially has multiple values per x grouping in which graphing based on N per x doesn't work as the N is split between conditions and has to be drawn as such. This is where I am struggling to figure out how to do that and would appreciate someone with more graph scripting experience to aid if possible. Below is the desired output with hand drawn lines for example and the code for generating the graph is below as well. 

 

In the example below, Toyota is now split among :Protection in which there is N=8 and N=3 and likewise Ford is N=11 and N=3 for the groupings and I would like to ensure that both Toyota groups and Ford groups among others have a horizontal line with the value of Max(:Wt) as shown by the red and blue lines and all other's have an equally unique line as shown by the purple lines. Any idea of how to accomplish that would be fantastic. At the bottom of the post, the code given by @ErraticAttack is posted as a wonderful template for grouping and graphing but since its an associative array it would say Toyota is N: 8+3 = 11 and likewise Ford is 11+3=14 wide and graph the ranges wrong as they are now split up. neelsrejan_0-1717728020584.png

dt = Open( "$SAMPLE_DATA/Cars.jmp" );

rpt = dt << Variability Chart(
	Y( :Head IC),
	X( :Protection, :Make, :Model ),
	Analysis Type( "Choose best analysis (EMS REML Bayesian)" ),
	Show Range Bars( 0 ),
	Show Cell Means( 0 ),
	Std Dev Chart( 0 ),
	Points Jittered( 1 ),
	By( :NAME("D/P")),
);

@ErraticAttack 's code to aid my previous question. 

names default to here(1);
dt = 
// Open Data Table: Big Class.jmp
// → Data Table( "Big Class" )
Open( "$SAMPLE_DATA/Cars.jmp" );

rpt = dt << Variability Chart(
	Y( :Head IC),
	X( :Make, :Model ),
	Analysis Type( "Choose best analysis (EMS REML Bayesian)" ),
	Show Range Bars( 0 ),
	Show Cell Means( 0 ),
	Std Dev Chart( 0 ),
	Points Jittered( 1 ),
	Where( :NAME("D/P") == "Driver" & :Protection == "manual belts" ),
);

//find groupings:
rows = dt << Get Rows Where( :NAME("D/P") == "Driver" & :Protection == "manual belts" );
subt = dt << Subset( Rows( rows ), Columns( :Make, :Model, :Wt ), Not Linked, Private );
sumt = subt << Summary( Group( :Make, Model ), Mean( :Wt ), Statistics Column Name Format( "Column" ), Link to Original Data Table( 0 ), Private );
Close( subt, No Save );
subt = sumt << Summary( Group( :Make ), Mean( :Wt ), Statistics Column Name Format( "Column" ), Link to Original Data Table( 0 ), Private );
Close( sumt, No Save );

category number = [=>];
category average = [=>];
For Each Row( subt,
	category number[:Make] = :N Rows; // each least-significant category in a VariabilityPlot is exactly X=1 width on the hidden x-axis, starting at zero
	category average[:Make] = :Wt
);
Close( subt, No Save );

tree = rpt << Report;
Eval( Eval Expr(
tree[FrameBox( 1 )] << Add Graphics Script(
	Local( {values = Expr( category average ), numbers = Expr( category number ), i, items, sum = 0},
		items = numbers << Get Keys;
		Pen Size( 2 );
		Pen Color( "Blue" );
		Summation( i = 1, N Items( items ),
			Line( Eval List( {sum, values[items[i]]} ), Eval List( {sum += numbers[items[i]], values[items[i]]} ) );
			0
		)
	)
)
) )

Thank you, truly appreciate any help! 

1 ACCEPTED SOLUTION

Accepted Solutions
neelsrejan
Level III

Re: How to add a dynamic horizontal lines with a shared y axis in a variability chart with grouped x axis with repeat values of different N?

Hi @jthi , 

 

Thanks for the solution, there is a quite elegant answer. As you mentioned, it is only for one Framebox and I would ideally like it to work for both frameboxes that the variability chart generates. I have adapted your code to this but am stuck in getting the horizontal lines to show up for both. If you could see the error and know how to go about it, that would be fantastic. Thanks!

Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Cars.jmp");

varchart = dt << Variability Chart(
	Y(:Head IC),
	X(:Protection, :Make, :Model),
	Analysis Type("Choose best analysis (EMS REML Bayesian)"),
	Show Range Bars(0),
	Show Cell Means(0),
	Std Dev Chart(0),
	Points Jittered(1),
	By(:"D/P"n)
);

dt << new column("Group", Character, Nominal, Formula(
	:"D/P"n || :Protection || :Make // don't add model here
));
dt_summary = dt << Summary(
	Group(:Group),
	Max(:Wt),
	N Categories(:Model),
	Freq("None"),
	Weight("None"),
	statistics column name format("column"),
	Link to original data table(0),
	//Invisible
);

uniq = Associative Array( Column( dt, "D/P" ) << GetValues ) << GetKeys;

for(i = 1, i <= N Items(uniq), i++,
	dt_summary_subset = dt_summary << Subset( Rows( dt_summary << get rows where(Substr(:Group, 1, Length(uniq[i])) == uniq[i])), 
	Columns(), Not Linked);
	weights = dt_summary_subset[0, "Wt"];
	counts = dt_summary_subset[0, "Model"];
	
	fb = Report(varchart)[i][FrameBox(1)];
	Eval(Eval Expr(
		fb << Add Graphics Script(
			Local({refs = Expr(weights), counts = Expr(counts), i, sum = 0},
				Pen Size(2);
				Pen Color("Blue");
				Summation(i = 1, N Items(counts),
					Line(Eval List({sum, refs[i]}), Eval List({sum += counts[i], refs[i]}));
				);
			)
		)
	));
);

View solution in original post

4 REPLIES 4
jthi
Super User

Re: How to add a dynamic horizontal lines with a shared y axis in a variability chart with grouped x axis with repeat values of different N?

One fairly easy option is to create new column for your group.

Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Cars.jmp");

// for simplicity sake we drop Passenger
rows_to_delete = dt << Get Rows Where(:"D/P"n == "Passenger");
dt << Delete Rows(rows_to_delete);

varchart = dt << Variability Chart(
	Y(:Head IC),
	X(:Protection, :Make, :Model),
	Analysis Type("Choose best analysis (EMS REML Bayesian)"),
	Show Range Bars(0),
	Show Cell Means(0),
	Std Dev Chart(0),
	Points Jittered(1),
	By(:"D/P"n)
);

dt << new column("Group", Character, Nominal, Formula(
	:"D/P"n || :Protection || :Make // don't add model here
));
dt_summary = dt << Summary(
	Group(:Group),
	Max(:Wt),
	N Categories(:Model),
	Freq("None"),
	Weight("None"),
	statistics column name format("column"),
	Link to original data table(0),
	Invisible
);
weights = dt_summary[0, "Wt"];
counts = dt_summary[0, "Model"];
Close(dt_summary, no save);


fb = Report(varchart)[FrameBox(1)];
Eval(Eval Expr(
	fb << Add Graphics Script(
		Local({refs = Expr(weights), counts = Expr(counts), i, sum = 0},
			Pen Size(2);
			Pen Color("Blue");
			Summation(i = 1, N Items(counts),
				Line(Eval List({sum, refs[i]}), Eval List({sum += counts[i], refs[i]}));
			);
		)
	)
));

Note that this example has only one framebox as other D/P is dropped

-Jarmo
neelsrejan
Level III

Re: How to add a dynamic horizontal lines with a shared y axis in a variability chart with grouped x axis with repeat values of different N?

Hi @jthi , 

 

Thanks for the solution, there is a quite elegant answer. As you mentioned, it is only for one Framebox and I would ideally like it to work for both frameboxes that the variability chart generates. I have adapted your code to this but am stuck in getting the horizontal lines to show up for both. If you could see the error and know how to go about it, that would be fantastic. Thanks!

Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Cars.jmp");

varchart = dt << Variability Chart(
	Y(:Head IC),
	X(:Protection, :Make, :Model),
	Analysis Type("Choose best analysis (EMS REML Bayesian)"),
	Show Range Bars(0),
	Show Cell Means(0),
	Std Dev Chart(0),
	Points Jittered(1),
	By(:"D/P"n)
);

dt << new column("Group", Character, Nominal, Formula(
	:"D/P"n || :Protection || :Make // don't add model here
));
dt_summary = dt << Summary(
	Group(:Group),
	Max(:Wt),
	N Categories(:Model),
	Freq("None"),
	Weight("None"),
	statistics column name format("column"),
	Link to original data table(0),
	//Invisible
);

uniq = Associative Array( Column( dt, "D/P" ) << GetValues ) << GetKeys;

for(i = 1, i <= N Items(uniq), i++,
	dt_summary_subset = dt_summary << Subset( Rows( dt_summary << get rows where(Substr(:Group, 1, Length(uniq[i])) == uniq[i])), 
	Columns(), Not Linked);
	weights = dt_summary_subset[0, "Wt"];
	counts = dt_summary_subset[0, "Model"];
	
	fb = Report(varchart)[i][FrameBox(1)];
	Eval(Eval Expr(
		fb << Add Graphics Script(
			Local({refs = Expr(weights), counts = Expr(counts), i, sum = 0},
				Pen Size(2);
				Pen Color("Blue");
				Summation(i = 1, N Items(counts),
					Line(Eval List({sum, refs[i]}), Eval List({sum += counts[i], refs[i]}));
				);
			)
		)
	));
);
txnelson
Super User

Re: How to add a dynamic horizontal lines with a shared y axis in a variability chart with grouped x axis with repeat values of different N?

On line 37 you need to change from

fb = Report(varchart)[i][FrameBox(1)];

to

 

fb = Report( varchart[i] )[FrameBox( 1 )];

 

 

 

Jim
neelsrejan
Level III

Re: How to add a dynamic horizontal lines with a shared y axis in a variability chart with grouped x axis with repeat values of different N?

Thank you Jim!