cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Check out the JMP® Marketplace featured Capability Explorer add-in
Choose Language Hide Translation Bar
shampton82
Level VII

How to add a graphics script but using a variable vs a hard coded value

I'm trying to have a dynamic drawing of a spec "box" in graph builder but I can't seem to get it to work.  I've tried making the usl and lsl expr(usl) and expr(lsl) and done eval(eval expr()) but that did not work either.  Any suggestions would be greatly appreciated!

 

 

rpt=dt<<Graph Builder(
	Size( 527, 456 ),
	Show Control Panel( 0 ),
	Graph Spacing( 5 ),
	Variables( X( :Min ), Y( :Max ) ),
	Elements(
		Points( X, Y, Legend( 3 ) ),
		Ellipse( X, Y, Legend( 5 ), Coverage( "99%" ), Mean Point( 1 ) )
	),
	SendToReport(
		Dispatch( {}, "Graph Builder", FrameBox,
			{Add Graphics Script(
				2,
				Description( "" ),
				Pen Color( "red" );
				Line( [lsl, usl], [usl, usl] );
				Line( [usl, usl], [lsl, usl] );
				Line( [lsl, usl], [lsl, lsl] );
				Line( [lsl, lsl], [lsl, usl] );
			)}
		)
	)
);

Want it to look like this (this was using the hard coding instead of lsl and usl)

 

shampton82_0-1732921846646.png

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
hogi
Level XII

Re: How to add a graphics script but using a variable vs a hard coded value

You could put the definition of xmin, xmax ... inside the graphics script. Here is an example with gets the values from the column properties.

 

This way it will work outside of the Here namespace -  e.g. when you save the graph as a table script.

 

:height << Set Property("Spec Limits",{LSL( 55 ), USL( 100 ), Show Limits( 0 )});
:weight << Set Property("Spec Limits",{LSL( 0 ), USL( 100 ), Show Limits( 0 )});

Report( gb )[framebox( 1 )] << Add Graphics Script(
	Pen Color( "red" );
	
	Xspecs= (:height << Get Property("Spec Limits"));
	xmin=Xspecs["LSL"];
	xmax= Xspecs["USL"];
	Yspecs= (:weight << Get Property("Spec Limits"));
	ymin=Yspecs["LSL"];
	ymax= Yspecs["USL"];
	
xMat =  Matrix({xmin, xmin, xmax, xmax, xmin});
yMat =  Matrix({ymin, ymax, ymax, ymin, ymin});
	Line( xMat, yMat );
);

 

View solution in original post

9 REPLIES 9
txnelson
Super User

Re: How to add a graphics script but using a variable vs a hard coded value

Here is an example of one way to code the example

txnelson_0-1732940505936.png

Names Default To Here( 1 );
dt = 
// Open Data Table: Big Class.jmp
// → Data Table( "Big Class" )
Open( "$SAMPLE_DATA/Big Class.jmp" );

gb = dt << Graph Builder(
	Size( 527, 456 ),
	Show Control Panel( 0 ),
	Graph Spacing( 5 ),
	Variables( X( :height ), Y( :weight ) ),
	Elements( Points( X, Y, Legend( 3 ) ), Ellipse( X, Y, Legend( 5 ), Coverage( "99%" ), Mean Point( 1 ) ) )
);

xmin = 55;
ymin = 0;
xmax = 100;
ymax = 100;
//eval(evalexpr(
Report( gb )[framebox( 1 )] << Add Graphics Script(
	Pen Color( "red" );
	
	xMat = Matrix( xmin );
	xMat = xMat || Matrix( xmin );
	xMat = xMat || Matrix( xmax );
	xMat = xMat || Matrix( xmax );
	xMat = xMat || Matrix( xmin );
	yMat = Matrix( ymin );
	yMat = yMat || Matrix( ymax );
	yMat = yMat || Matrix( ymax );
	yMat = yMat || Matrix( ymin );
	yMat = yMat || Matrix( ymin );
	Line( xMat, yMat );
);
Jim
hogi
Level XII

Re: How to add a graphics script but using a variable vs a hard coded value

You could put the definition of xmin, xmax ... inside the graphics script. Here is an example with gets the values from the column properties.

 

This way it will work outside of the Here namespace -  e.g. when you save the graph as a table script.

 

:height << Set Property("Spec Limits",{LSL( 55 ), USL( 100 ), Show Limits( 0 )});
:weight << Set Property("Spec Limits",{LSL( 0 ), USL( 100 ), Show Limits( 0 )});

Report( gb )[framebox( 1 )] << Add Graphics Script(
	Pen Color( "red" );
	
	Xspecs= (:height << Get Property("Spec Limits"));
	xmin=Xspecs["LSL"];
	xmax= Xspecs["USL"];
	Yspecs= (:weight << Get Property("Spec Limits"));
	ymin=Yspecs["LSL"];
	ymax= Yspecs["USL"];
	
xMat =  Matrix({xmin, xmin, xmax, xmax, xmin});
yMat =  Matrix({ymin, ymax, ymax, ymin, ymin});
	Line( xMat, yMat );
);

 

jthi
Super User

Re: How to add a graphics script but using a variable vs a hard coded value

Where are the limits coming from? Column properties? Do both columns have limits? Are they same? Do you know column names beforehand? Are you using column switcher?

Names Default To Here(1); 

dt = open("$SAMPLE_DATA/Big Class.jmp");

gb = dt << Graph Builder(
	Size(525, 454),
	Show Control Panel(0),
	Variables(X(:weight), Y(:height), Overlay(:sex)),
	Elements(Points(X, Y, Legend(9))),
	SendToReport(
		Dispatch({}, "weight", ScaleBox,
			{Min(38.9121338912134), Max(180), Inc(20), Minor Ticks(0)}
		),
		Dispatch({}, "height", ScaleBox,
			{Min(47.513125), Max(180.625510686239), Inc(20), Minor Ticks(0)}
		)
	)
);

fb = Report(gb)[FrameBox(1)];

low = 60;
high = 140;
Eval(EvalExpr(
	fb << Add Graphics Script(
		Pen Color("Red");
		Rect(Expr(low), Expr(high), Expr(high), Expr(low));
	);	
));
-Jarmo
hogi
Level XII

Re: How to add a graphics script but using a variable vs a hard coded value

Eval(EvalExpr(
	fb << Add Graphics Script(
		Pen Color("Red");
		Rect(Expr(low), Expr(high), Expr(high), Expr(low));
	);	
));


after saving the plot,

hogi_0-1732988654569.png

the code will not work anymore.
low & high should be defined INSIDE the graphics script - see previous post.

jthi
Super User

Re: How to add a graphics script but using a variable vs a hard coded value


@hogi wrote:
Eval(EvalExpr(
	fb << Add Graphics Script(
		Pen Color("Red");
		Rect(Expr(low), Expr(high), Expr(high), Expr(low));
	);	
));


after saving the plot, the code will not work anymore.
low & high should be defined INSIDE the graphics script - see previous post.


How would you save the plot so they wouldn't work?

 

View more...

The values won't update if user makes changes, but without knowing where values are coming from, it is extremely difficult to take that into account.

jthi_0-1732986746126.png

 

Graph Builder(
	Size(525, 454),
	Show Control Panel(0),
	Variables(X(:weight), Y(:height), Overlay(:sex)),
	Elements(Points(X, Y, Legend(9))),
	SendToReport(
		Dispatch({}, "weight", ScaleBox,
			{Min(38.9121338912134), Max(180), Inc(20), Minor Ticks(0)}
		),
		Dispatch({}, "height", ScaleBox,
			{Min(47.513125), Max(180.625510686239), Inc(20), Minor Ticks(0)}
		),
		Dispatch({}, "Graph Builder", FrameBox,
			{Add Graphics Script(
				5,
				Description(""),
				Pen Color("Red");
				Rect(60, 140, 140, 60);
			)}
		)
	)
);

 

 

-Jarmo
shampton82
Level VII

Re: How to add a graphics script but using a variable vs a hard coded value

Hey @jthi ,

Right now the limits are coming from a user interface where they enter the limits and they get assigned to lsl and lsl , the analysis runs, and then this is part of the output that is generated.

jthi
Super User

Re: How to add a graphics script but using a variable vs a hard coded value

Does user select/enter columns of interest and the limits? And by LSL and USL you mean spec limits column properties lower/upper spec limits? Should the column properties be utilized or the user inputs (they might initially be the same, but user can change spec limits from column properties whereas they cannot change their initial selections without re-running analysis and creating new plot)?

-Jarmo
shampton82
Level VII

Re: How to add a graphics script but using a variable vs a hard coded value

They currently select the columns of interest and then enter what the LSL and USL are for the columns but that was just for my development phase.  Once I get a loop worked out I could grab the specs from the column properties.  Probably would populate the user interface with the column values and then they could change the if they were incorrect for any reason.

jthi
Super User

Re: How to add a graphics script but using a variable vs a hard coded value

Graph Builder is extremely complicated platform and we don't have easy access what it has from just a frame box (where the graphic script is). If I had to make this as dynamic as possible when using column properties, something like this is one option:

Names Default To Here(1); 

dt = open("$SAMPLE_DATA/Semiconductor Capability.jmp");

gb = dt << Graph Builder(
	Size(789, 594),
	Show Control Panel(0),
	Fit to Window("On"),
	Variables(X(:PNP1), Y(:NPN1)),
	Elements(Points(X, Y, Legend(3))),
	Column Switcher(
		:NPN1,
		{:NPN1, :PNP2, :NPN2, :PNP3, :IVP1, :PNP4, :NPN3, :IVP2, :NPN4, :SIT1, :INM1,
		:INM2, :VPM1, :VPM2, :VPM3, :PMS1, :SNM1, :SPM1, :NPN5, :EP2, :ZD6, :PBA,
		:PLG, :CAP, :PBA3, :PLG2, :PNP5, :NPN6, :PNP6, :PNP7, :NPN7, :PNP8, :IVP3,
		:IVP4, :IVP5, :IVP6, :PNP9, :NPN8, :NPN9, :IVP7, :NPN10, :N_1, :PBA1, :WPR1,
		:B10, :PLY10, :VBE210, :VTN210, :VTP210, :SIT2, :SIT3, :INV2, :INV3, :INV4,
		:INV5, :FST1, :FST2, :RES1, :RES2, :PNM1, :PPM1, :FNM1, :FPM1, :FST3, :FST4,
		:RES3, :RES4, :A1, :B1, :A2N, :A2P, :A2P1, :IVP8, :IVP9, :DE_H1, :NF_H1,
		:ESM1, :ESM2, :ESP1, :YFU1, :VPM4, :PBA2, :PBB1, :LYA1, :LYB1, :DEM1, :DEP1,
		:NFM1, :PLY1, :VDP1, :VDP2, :SNW1, :RSP2, :PLY2, :RSP1, :VDP3, :PBL1, :PLG1,
		:VDP4, :SPW1, :VIA1, :INM3, :VPM5, :VPM6, :INM4, :VPM7, :M1_M1, :M2_M2,
		:P1_P1, :E2A1, :E2B1, :NPN11, :IVP10, :PNP10, :INM5, :VPM8, :VPM9, :INM6,
		:VPM10, :N2A1, :N2B1, :NM_L1, :P2A1, :P2B1, :PM_L1, :P1, :M1},
		Layout(1)
	),
	Column Switcher(
		:PNP1,
		{:PNP1, :PNP2, :NPN2, :PNP3, :IVP1, :PNP4, :NPN3, :IVP2, :NPN4, :SIT1, :INM1,
		:INM2, :VPM1, :VPM2, :VPM3, :PMS1, :SNM1, :SPM1, :NPN5, :EP2, :ZD6, :PBA,
		:PLG, :CAP, :PBA3, :PLG2, :PNP5, :NPN6, :PNP6, :PNP7, :NPN7, :PNP8, :IVP3,
		:IVP4, :IVP5, :IVP6, :PNP9, :NPN8, :NPN9, :IVP7, :NPN10, :N_1, :PBA1, :WPR1,
		:B10, :PLY10, :VBE210, :VTN210, :VTP210, :SIT2, :SIT3, :INV2, :INV3, :INV4,
		:INV5, :FST1, :FST2, :RES1, :RES2, :PNM1, :PPM1, :FNM1, :FPM1, :FST3, :FST4,
		:RES3, :RES4, :A1, :B1, :A2N, :A2P, :A2P1, :IVP8, :IVP9, :DE_H1, :NF_H1,
		:ESM1, :ESM2, :ESP1, :YFU1, :VPM4, :PBA2, :PBB1, :LYA1, :LYB1, :DEM1, :DEP1,
		:NFM1, :PLY1, :VDP1, :VDP2, :SNW1, :RSP2, :PLY2, :RSP1, :VDP3, :PBL1, :PLG1,
		:VDP4, :SPW1, :VIA1, :INM3, :VPM5, :VPM6, :INM4, :VPM7, :M1_M1, :M2_M2,
		:P1_P1, :E2A1, :E2B1, :NPN11, :IVP10, :PNP10, :INM5, :VPM8, :VPM9, :INM6,
		:VPM10, :N2A1, :N2B1, :NM_L1, :P2A1, :P2B1, :PM_L1, :P1, :M1},
		Layout(1)
	)
);


fb = Report(gb)[FrameBox(1)];

// Graphic script doesn't even know where it is -> we have to evaluate that
// to make this evaluation a bit easier, we could evaluate the graph builder reference
Eval(EvalExpr(
	fb << Add Graphics Script(
		mygb = Expr(gb); // with gb we can access Y and X axis. This is assuming uiser might be using Column Switcher
		xcol = "";
		ycol = "";
		For Each({var}, mygb << get variables,
			If(var["Role"] == "X",
				xcol = var[1] << get name;
			, var["Role"] == "Y",
				ycol = var[1] << get name;
			);
		);
		xspecs = Column(mygb << Get Data Table, xcol) << Get Property("Spec Limits");
		yspecs = Column(mygb << Get Data Table, ycol) << Get Property("Spec Limits");
		
		Pen Color("Red");
		Pen Size(2);
		Rect(xspecs["LSL"], yspecs["USL"], xspecs["USL"], yspecs["LSL"], 0);
		Fill Color("Green");
		Transparency(0.2);
		Rect(xspecs["LSL"], yspecs["USL"], xspecs["USL"], yspecs["LSL"], 1);
		
		/*
		// You might want to add dynamic scaling to X/Y axis as JMP isn't able to handle it
		// if column properties do not have Show as Graph Reference lines enabled
		// on problem is that user cannot really "scale" the axis if this is used
		// as it will be always scaled back
		// this can also "break"
		xmin = Min(xspecs["LSL"], Col Min(Column(mygb << Get Data Table, xcol)));
		xmax = Max(xspecs["USL"], Col Max(Column(mygb << Get Data Table, xcol)));
		
		ymin = Min(yspecs["LSL"], Col Min(Column(mygb << Get Data Table, ycol)));
		ymax = Max(yspecs["USL"], Col Max(Column(mygb << Get Data Table, ycol)));
		
		xmin *= If(xmin < 0, 1.1, 0.9);
		xmax *= If(xmax < 0, 0.9, 1.1);
		ymin *= If(ymin < 0, 1.1, 0.9);
		ymax *= If(ymax < 0, 0.9, 1.1);
		
		myfb = Report(mygb)[FrameBox(1)];
		myfb << X Axis(Min(xmin), Max(xmax)); 
		myfb << Y Axis(Min(ymin), Max(ymax));
		
		// Other option could be to enable show graph reference lines
		// and then dynamically try to hide the lines/text (not sure how well this would work)
		*/
	);
));

Write();

This can be most likely made much simpler and faster depending on the real use case. The simplest option (in my opinion) is to use Eval(EvalExpr()) (or Substitute() to evaluate the values inside graphic script which utilizes Rect() (like I did show in my first response)

-Jarmo