cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Choose Language Hide Translation Bar
Neo
Neo
Level VI

How to add box plots to points when supplied Y variables as list to graph builder?

The following example script from an earlier thread (solved, thanks to @jthi) of mine allow me to plot Y variables as points when Y variables are supplied from a list.

I want to add Box Plots in addition to Points in my chart. How to add box plots in the script below?

Names Default To Here(1);
dt = Open("$sample_data\Big Class.jmp");
y_values = {"name", "age", "sex", "weight"};
variables_expr = Expr(Variables(X(:height)));
For Each({y_col}, y_values,
	temp_expr = Expr(Y());
	Insert Into(temp_expr, Name Expr(AsColumn(dt, y_col)));
	Insert Into(variables_expr, Name Expr(temp_expr));
);
gb_expr = Expr(Graph Builder(
	Show Control Panel(0)
));
Insert Into(gb_expr, Name Expr(variables_expr));
For Each({y_col, idx}, y_values,
	Eval(EvalExpr(
		Insert Into(gb_expr,
			Name Expr(Elements(Position(1, Expr(idx)), Points(X, Y, Legend(Expr(idx)))))
		)
	));
);
Show(Name Expr(gb_expr));
Eval(gb_expr); 

 

When it's too good to be true, it's neither
2 ACCEPTED SOLUTIONS

Accepted Solutions
txnelson
Super User

Re: How to add box plots to points when supplied Y variables as list to graph builder?

Very minor changes were required to produce the graph you want.

The JSL produced by the initial script that runs the Graph Builder is

Graph Builder(
	Show Control Panel( 0 ),
	Variables( X( :lot_id ), Y( :NPN1 ), Y( :IVP1 ), Y( :PNP4 ), Y( :NPN4 ) ),
	Elements( Position( 1, 1 ), Points( X, Y, Legend( 1 ) ) ),
	Elements( Position( 1, 2 ), Points( X, Y, Legend( 2 ) ) ),
	Elements( Position( 1, 3 ), Points( X, Y, Legend( 3 ) ) ),
	Elements( Position( 1, 4 ), Points( X, Y, Legend( 4 ) ) )
);

When one looks at the JSL that created the above Graph Builder code, only 2 sections do the real work.

gb_expr = Expr(Graph Builder(
	Show Control Panel(0)
));

Creates the shell for the Graph Builder

Graph Builder(
	Show Control Panel( 0 ),


);

The JSL

variables_expr = Expr(Variables(X(:lot_id)));
For Each({y_col}, y_values,
	temp_expr = Expr(Y());
	Insert Into(temp_expr, Name Expr(AsColumn(dt, y_col)));
	Insert Into(variables_expr, Name Expr(temp_expr));
);

Generates the code

Variables( X( :lot_id ), Y( :NPN1 ), Y( :IVP1 ), Y( :PNP4 ), Y( :NPN4 ) )

Then, 

Insert Into(gb_expr, Name Expr(variables_expr));

Inserts the Variables( X(.................) JSL into the Graph Builder() code

Graph Builder(
	Show Control Panel( 0 ),
	Variables( X( :lot_id ), Y( :NPN1 ), Y( :IVP1 ), Y( :PNP4 ), Y( :NPN4 ) )

);

Now what needs to be done, is to build

    Elements( Position( 1, 1 ), Points( X, Y, Legend( 1 ) ) ),
	Elements( Position( 1, 2 ), Points( X, Y, Legend( 2 ) ) ),
	Elements( Position( 1, 3 ), Points( X, Y, Legend( 3 ) ) ),
	Elements( Position( 1, 4 ), Points( X, Y, Legend( 4 ) ) )

The JSL that creates these lines of code is

For Each({y_col, idx}, y_values,
	Eval(EvalExpr(
		Insert Into(gb_expr,
			Name Expr(Elements(Position(1, Expr(idx)), Points(X, Y, Legend(Expr(idx)))))
		)
	));
);

It loops through each of the Y values and creates the Elements line one at a time, and inserts it into the Graph Builder() JSL.

Finally, 

Eval(gb_expr); 

Runs the completed Graph Builder JSL

So now, what needs to be changed.

Basically if one looks at what is different between the JSL the original script creates, and the saved JSL from the Graph Builder with the new modifications, in the original script output, the Elements structure is

Elements( Position( 1, 1 ), Points( X, Y, Legend( 1 ) ) )

Where the Saved code's Elements section has a section for both Points, and Box Plot

Elements(
		Position( 1, 1 ),
		Points( X, Y, Legend( 1 ), Jitter( "None" ) ),
		Box Plot( X, Y, Legend( 5 ), Jitter( "None" ) )
	)

Therefore, all that needs to be changed is to add this second section to the code that generates the Elements section.

For Each( {y_col, idx}, y_values,
	Eval(
		Eval Expr(
			Insert Into(
				gb_expr,
				Name Expr(
					Elements(
						Position( 1, Expr( idx ) ),
						Points( X, Y, Legend( Expr( idx ) ), jitter( "None" ) ),
						Box Plot( X, Y, Legend( Expr( N Items( y_values ) + idx ), jitter( "None" ) ) )
					)
				)
			)
		)
	)
);

If you put all of this together, the new script is

Names Default To Here( 1 );
Clear Log();

dt = Open( "$sample_data\Semiconductor Capability.jmp" );

y_values = {"NPN1", "IVP1", "PNP4", "NPN4"};

variables_expr = Expr(
	Variables( X( :lot_id ) )
);
For Each( {y_col}, y_values,
	temp_expr = Expr( Y() );
	Insert Into( temp_expr, Name Expr( As Column( dt, y_col ) ) );
	Insert Into( variables_expr, Name Expr( temp_expr ) );
);
gb_expr = Expr(
	Graph Builder( Show Control Panel( 0 ) )
);
Insert Into( gb_expr, Name Expr( variables_expr ) );
For Each( {y_col, idx}, y_values,
	Eval(
		Eval Expr(
			Insert Into(
				gb_expr,
				Name Expr(
					Elements(
						Position( 1, Expr( idx ) ),
						Points( X, Y, Legend( Expr( idx ) ), jitter( "None" ) ),
						Box Plot( X, Y, Legend( Expr( N Items( y_values ) + idx ), jitter( "None" ) ) )
					)
				)
			)
		)
	)
);

Show( Name Expr( gb_expr ) );
Eval( gb_expr );
Jim

View solution in original post

jthi
Super User

Re: How to add box plots to points when supplied Y variables as list to graph builder?

You don't want to run gb_expr twice. You want to get the reference you get from gb_expr and send those messages to it

gb = Eval( gb_expr );
gb << Local data Filter(...)
server = gb << get legend server;
-Jarmo

View solution in original post

14 REPLIES 14
jthi
Super User

Re: How to add box plots to points when supplied Y variables as list to graph builder?

Create the graph interactively in JMP

jthi_0-1700502857244.png

take the script to your clipboard / script window

Graph Builder(
	Show Control Panel(0),
	Variables(X(:height), Y(:name), Y(:age), Y(:sex), Y(:weight)),
	Elements(Position(1, 1), Points(X, Y, Legend(1)), Box Plot(X, Y, Legend(5))),
	Elements(Position(1, 2), Points(X, Y, Legend(2)), Box Plot(X, Y, Legend(6))),
	Elements(Position(1, 3), Points(X, Y, Legend(3)), Box Plot(X, Y, Legend(7))),
	Elements(Position(1, 4), Points(X, Y, Legend(4)), Box Plot(X, Y, Legend(8))),
	SendToReport(
		Dispatch(
			{},
			"400",
			LegendBox,
			{Legend Position(
				{1, [0], 5, [4, -3], 2, [1], 6, [5, -3], 3, [2], 7, [6, -3], 4, [3],
				8, [7, -3]}
			)}
		)
	)
)

See what has to be changed to include BoxPlots when the original graph builder is like this

Graph Builder(
	Show Control Panel(0),
	Variables(X(:height), Y(:name), Y(:age), Y(:sex), Y(:weight)),
	Elements(Position(1, 1), Points(X, Y, Legend(1))),
	Elements(Position(1, 2), Points(X, Y, Legend(2))),
	Elements(Position(1, 3), Points(X, Y, Legend(3))),
	Elements(Position(1, 4), Points(X, Y, Legend(4)))
)

Go back to your script and try small modifications. You can fairly easily see, that you are missing something from Elements and based on your original script

Name Expr(Elements(Position(1, Expr(idx)), Points(X, Y, Legend(Expr(idx)))))

it seems like you should just try adding the Box Plot in correct format there

-Jarmo
txnelson
Super User

Re: How to add box plots to points when supplied Y variables as list to graph builder?

Run the graph.

Open the Control Panel

Add in the box plots you want.

Close the Control Panel

Go to the red triangle and select

     Save=>Script to Script Window

Examine the code, and change the script to add in the additional items that the new script has, that the old script does not.

Jim
Neo
Neo
Level VI

Re: How to add box plots to points when supplied Y variables as list to graph builder?

@txnelson I have been doing exactly that, added box plots interactively, then checked the resulting script, made the changes in my original script, still could not get box plots to work. I guess I am still not good at spotting what is missing/need.

Will try @jthi  suggestion now. 

When it's too good to be true, it's neither
txnelson
Super User

Re: How to add box plots to points when supplied Y variables as list to graph builder?

Run your JSL, and then modify he graph to how you want it to look, and then save the JSL from the new graph.  Add the new JSL to this Discussion Track and I will take a look at it.

Jim
Neo
Neo
Level VI

Re: How to add box plots to points when supplied Y variables as list to graph builder?

@txnelson The following is close to my actual case.

 

Names default To Here (1);
Clear Log ();

dt = Open("$sample_data\Semiconductor Capability.jmp");

y_values = {"NPN1", "IVP1", "PNP4", "NPN4"};

variables_expr = Expr(Variables(X(:lot_id)));
For Each({y_col}, y_values,
	temp_expr = Expr(Y());
	Insert Into(temp_expr, Name Expr(AsColumn(dt, y_col)));
	Insert Into(variables_expr, Name Expr(temp_expr));
);
gb_expr = Expr(Graph Builder(
	Show Control Panel(0)
));
Insert Into(gb_expr, Name Expr(variables_expr));
For Each({y_col, idx}, y_values,
	Eval(EvalExpr(
		Insert Into(gb_expr,
			Name Expr(Elements(Position(1, Expr(idx)), Points(X, Y, Legend(Expr(idx)))))
		)
	));
);
Show(Name Expr(gb_expr));
Eval(gb_expr); 

which gives

 

Neo_0-1700522918302.png

However, I would something like the following

Neo_1-1700523044870.png

The JMP generated script for which is 

Graph Builder(
	Show Control Panel( 0 ),
	Variables( X( :lot_id ), Y( :NPN1 ), Y( :IVP1 ), Y( :PNP4 ), Y( :NPN4 ) ),
	Elements(
		Position( 1, 1 ),
		Points( X, Y, Legend( 1 ), Jitter( "None" ) ),
		Box Plot( X, Y, Legend( 5 ), Jitter( "None" ) )
	),
	Elements(
		Position( 1, 2 ),
		Points( X, Y, Legend( 2 ), Jitter( "None" ) ),
		Box Plot( X, Y, Legend( 6 ), Jitter( "None" ) )
	),
	Elements(
		Position( 1, 3 ),
		Points( X, Y, Legend( 3 ), Jitter( "None" ) ),
		Box Plot( X, Y, Legend( 7 ), Jitter( "None" ) )
	),
	Elements(
		Position( 1, 4 ),
		Points( X, Y, Legend( 4 ), Jitter( "None" ) ),
		Box Plot( X, Y, Legend( 8 ), Jitter( "None" ) )
	),
	SendToReport(
		Dispatch(
			{},
			"400",
			LegendBox,
			{Legend Position(
				{1, [0], 5, [4, -3], 2, [1], 6, [5, -3], 3, [2], 7, [6, -3], 4, [3],
				8, [7, -3]}
			)}
		)
	)
);

The question is how to modify the top script in this post to include box plot in addition to points?

Adding Box Plots () just below Points () is not giving me both.

I guess my placement for Box Plots () is incorrect. Need help here.

When it's too good to be true, it's neither
WebDesignesCrow
Super User

Re: How to add box plots to points when supplied Y variables as list to graph builder?

I think you used default "Box Plot" Outliers.

Are you looking for "Box Plot" Quantile method that connects all points?

WebDesignesCrow_0-1700532279382.png

Graph Builder(
Size( 1135, 705 ),
Show Control Panel( 0 ),
Variables(
X( :“S-b"n ),
Y( :C),
Color( :“S-b"n )
),
Elements( Box Plot( X, Y, Legend( 4 ), Box Type( "Quantile" ) ) )
);

 

txnelson
Super User

Re: How to add box plots to points when supplied Y variables as list to graph builder?

Very minor changes were required to produce the graph you want.

The JSL produced by the initial script that runs the Graph Builder is

Graph Builder(
	Show Control Panel( 0 ),
	Variables( X( :lot_id ), Y( :NPN1 ), Y( :IVP1 ), Y( :PNP4 ), Y( :NPN4 ) ),
	Elements( Position( 1, 1 ), Points( X, Y, Legend( 1 ) ) ),
	Elements( Position( 1, 2 ), Points( X, Y, Legend( 2 ) ) ),
	Elements( Position( 1, 3 ), Points( X, Y, Legend( 3 ) ) ),
	Elements( Position( 1, 4 ), Points( X, Y, Legend( 4 ) ) )
);

When one looks at the JSL that created the above Graph Builder code, only 2 sections do the real work.

gb_expr = Expr(Graph Builder(
	Show Control Panel(0)
));

Creates the shell for the Graph Builder

Graph Builder(
	Show Control Panel( 0 ),


);

The JSL

variables_expr = Expr(Variables(X(:lot_id)));
For Each({y_col}, y_values,
	temp_expr = Expr(Y());
	Insert Into(temp_expr, Name Expr(AsColumn(dt, y_col)));
	Insert Into(variables_expr, Name Expr(temp_expr));
);

Generates the code

Variables( X( :lot_id ), Y( :NPN1 ), Y( :IVP1 ), Y( :PNP4 ), Y( :NPN4 ) )

Then, 

Insert Into(gb_expr, Name Expr(variables_expr));

Inserts the Variables( X(.................) JSL into the Graph Builder() code

Graph Builder(
	Show Control Panel( 0 ),
	Variables( X( :lot_id ), Y( :NPN1 ), Y( :IVP1 ), Y( :PNP4 ), Y( :NPN4 ) )

);

Now what needs to be done, is to build

    Elements( Position( 1, 1 ), Points( X, Y, Legend( 1 ) ) ),
	Elements( Position( 1, 2 ), Points( X, Y, Legend( 2 ) ) ),
	Elements( Position( 1, 3 ), Points( X, Y, Legend( 3 ) ) ),
	Elements( Position( 1, 4 ), Points( X, Y, Legend( 4 ) ) )

The JSL that creates these lines of code is

For Each({y_col, idx}, y_values,
	Eval(EvalExpr(
		Insert Into(gb_expr,
			Name Expr(Elements(Position(1, Expr(idx)), Points(X, Y, Legend(Expr(idx)))))
		)
	));
);

It loops through each of the Y values and creates the Elements line one at a time, and inserts it into the Graph Builder() JSL.

Finally, 

Eval(gb_expr); 

Runs the completed Graph Builder JSL

So now, what needs to be changed.

Basically if one looks at what is different between the JSL the original script creates, and the saved JSL from the Graph Builder with the new modifications, in the original script output, the Elements structure is

Elements( Position( 1, 1 ), Points( X, Y, Legend( 1 ) ) )

Where the Saved code's Elements section has a section for both Points, and Box Plot

Elements(
		Position( 1, 1 ),
		Points( X, Y, Legend( 1 ), Jitter( "None" ) ),
		Box Plot( X, Y, Legend( 5 ), Jitter( "None" ) )
	)

Therefore, all that needs to be changed is to add this second section to the code that generates the Elements section.

For Each( {y_col, idx}, y_values,
	Eval(
		Eval Expr(
			Insert Into(
				gb_expr,
				Name Expr(
					Elements(
						Position( 1, Expr( idx ) ),
						Points( X, Y, Legend( Expr( idx ) ), jitter( "None" ) ),
						Box Plot( X, Y, Legend( Expr( N Items( y_values ) + idx ), jitter( "None" ) ) )
					)
				)
			)
		)
	)
);

If you put all of this together, the new script is

Names Default To Here( 1 );
Clear Log();

dt = Open( "$sample_data\Semiconductor Capability.jmp" );

y_values = {"NPN1", "IVP1", "PNP4", "NPN4"};

variables_expr = Expr(
	Variables( X( :lot_id ) )
);
For Each( {y_col}, y_values,
	temp_expr = Expr( Y() );
	Insert Into( temp_expr, Name Expr( As Column( dt, y_col ) ) );
	Insert Into( variables_expr, Name Expr( temp_expr ) );
);
gb_expr = Expr(
	Graph Builder( Show Control Panel( 0 ) )
);
Insert Into( gb_expr, Name Expr( variables_expr ) );
For Each( {y_col, idx}, y_values,
	Eval(
		Eval Expr(
			Insert Into(
				gb_expr,
				Name Expr(
					Elements(
						Position( 1, Expr( idx ) ),
						Points( X, Y, Legend( Expr( idx ) ), jitter( "None" ) ),
						Box Plot( X, Y, Legend( Expr( N Items( y_values ) + idx ), jitter( "None" ) ) )
					)
				)
			)
		)
	)
);

Show( Name Expr( gb_expr ) );
Eval( gb_expr );
Jim
Neo
Neo
Level VI

Re: How to add box plots to points when supplied Y variables as list to graph builder?

@txnelson Thanks.

I would not have come up with this easily. 

Box Plot( X, Y, Legend( Expr( N Items( y_values ) + idx ), jitter( "None" ) ) )

How do I change the default markers in Points to say a  "+" or or a "square". This does not do the trick

Points( X, Y, Legend( Expr( idx ) ), jitter( "None" ), marker ("square") )

Changing the marker interactively shows that I need to direct the marker change via sendToReport () for each Y variable. How to do this all at once for all Y variables?

When it's too good to be true, it's neither
jthi
Super User

Re: How to add box plots to points when supplied Y variables as list to graph builder?

Depending on where you do it, where to see what will be different. Here is example if you do it from Legend:

Change it from legend and you get something like

{Legend Model(4, Properties(0, {Marker("Circle")}, Item ID("NPN4", 1)))}

So search for Legend Model from Scripting Index

jthi_0-1700562526669.png

Get the script from there, modify it to fit your needs but keep it as simple as possible (add second Y-axis) and test it out

Names Default To Here(1);

dt = Open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(
	Size(528, 448),
	Show Control Panel(0),
	Variables(X(:sex), Y(:height), Y(:weight)),
	Elements(Position(1, 1), Points(X, Y, Legend(3))),
	Elements(Position(1, 2), Points(X, Y, Legend(1)))
);

server = gb << Get Legend Server;
item = server << Get Legend Item(1, 1);
item << Set Properties({Marker("Circle")});

You managed to change markers on one plot. Then you ask: how do I change them on all of the plots? Then explore the script in more detail and it seems like there are some indices provided 

item = server << Get Legend Item(1, 1);

check << Get Legend item from scripting index and hope that it is there and if it isn't explore other legend related objects and hope they work in similar manner (or just try to send messages to the server << get lege Ctrl+Space here). 

server << Get Legend Items;
{{LegendModelItem(Label("height"), Type("Marker"))},
{LegendModelItem(Label("weight"), Type("Marker"))}}

Now you have a list of legend items. Try looping over that list and see what happens

Names Default To Here(1);

dt = Open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(
	Size(528, 448),
	Show Control Panel(0),
	Variables(X(:sex), Y(:height), Y(:weight)),
	Elements(Position(1, 1), Points(X, Y, Legend(3))),
	Elements(Position(1, 2), Points(X, Y, Legend(1)))
);

server = gb << Get Legend Server;
For Each({item}, server << Get Legend Items,
	item << Set Properties({Marker("Circle")});	
);

Easier option is to set the markers as row states to your data table if that works for you. 

 

-Jarmo