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
SDF1
Super User

Anyone have add-in or JSL code for adding a 45-degree line and squarify a GB plot?

Hi All,

 

  I'm wondering if anyone might have available some JSL code or an add-in to be able to take a graph builder (GB) plot and squarify it (set both x and y axis the same) and add a 45-degree line, like how the Actual by Predicted plots often do, see example below.

SDF1_0-1661539031787.png

  As far as I know, GB does not have any kind of option to automatically do this for you, which is too bad, because I often like making graphs like the Actual by Predicted graphs and have the added versatility of the GB platform for adding color or other kinds of formatting to the graphic.

 

  Maybe this could be on the wish-list for a new feature in GB?

 

Thanks!,

DS

4 ACCEPTED SOLUTIONS

Accepted Solutions
txnelson
Super User

Re: Anyone have add-in or JSL code for adding a 45-degree line and squarify a GB plot?

Here is a simple script that maintains a square display with a diagonal line.  The code is written to hopefully show all that is going on.  Far more efficient code could be written.

Names Default To Here( 1 );
dt = Current Data Table();
Graph Builder(
	Show Control Panel( 0 ),
	Variables( X( :weight ), Y( :height ) ),
	Elements( Points( X, Y, Legend( 8 ) ) )
);
rpt = Current Report();
xmax = rpt[axisbox( 1 )] << get max;
ymax = rpt[axisbox( 2 )] << get max;
xmin = rpt[axisbox( 1 )] << get min;
ymin = rpt[axisbox( 2 )] << get min;
rpt[axisbox( 1 )] << Min( Min( ymin, xmin ) );
rpt[axisbox( 1 )] << Max( Max( ymax, xmax ) );
rpt[axisbox( 2 )] << Min( Min( ymin, xmin ) );
rpt[axisbox( 2 )] << Max( Max( ymax, xmax ) );
rpt[framebox( 1 )] << add graphics script(
	xmax = rpt[axisbox( 1 )] << get max;
	ymax = rpt[axisbox( 2 )] << get max;
	xmin = rpt[axisbox( 1 )] << get min;
	ymin = rpt[axisbox( 2 )] << get min;
	rpt[axisbox( 1 )] << Min( Min( ymin, xmin ) );
	rpt[axisbox( 1 )] << Max( Max( ymax, xmax ) );
	rpt[axisbox( 2 )] << Min( Min( ymin, xmin ) );
	rpt[axisbox( 2 )] << Max( Max( ymax, xmax ) );
	theMinLineList = {};
	theMaxLineList = {};
	Insert Into( theMinLineList, Min( ymin, xmin ) );
	Insert Into( theMinLineList, Min( ymin, xmin ) );
	Insert Into( theMaxLineList, Max( ymax, xmax ) );
	Insert Into( theMaxLineList, Max( ymax, xmax ) );
	Line( theMinLineList, theMaxLineList );
	xx = rpt[framebox( 1 )] << get size;
	Show( xx );
	xx[1] = Max( xx );
	xx[2] = Max( xx );
	rpt[framebox( 1 )] << framesize( xx[1], xx[2] );
);
Jim

View solution in original post

Craige_Hales
Super User

Re: Anyone have add-in or JSL code for adding a 45-degree line and squarify a GB plot?

Here's a variation that assumes you won't resize the graph or adjust the axes after it is drawn. Jim's version is resetting the squareness on each redraw of the graph, which may trigger another redraw of the graph. If you really need that, it might be necessary to use the scheduler to reset the squareness outside of the graphic script.

 

 

dt = Open( "$sample_data/big class.jmp" );
  	
gb = dt << Graph Builder( Show Control Panel( 0 ),
    Variables( X( :weight ), Y( :height ) ),
    Elements( Points( X, Y, Legend( 3 ) ), Smoother( X, Y, Legend( 4 ) ) )
);
Report( gb )[framebox( 1 )] << FrameSize( 500, 500 ); //force square

// fix JSL here to set the axis ranges the way you expect. 
theMax = Max( Report( gb )[axisbox( 1 )] << get max, Report( gb )[axisbox( 2 )] << get max );
theMin = Min( Report( gb )[axisbox( 1 )] << get min, Report( gb )[axisbox( 2 )] << get min );
Report( gb )[framebox( 1 )] << Xaxis( Min( theMin ), Max( theMax ) );
Report( gb )[framebox( 1 )] << Yaxis( Min( theMin ), Max( theMax ) );

// add the diagonal line
Report( gb )[framebox( 1 )] << AddGraphicsScript(
    xmin = X Origin();
    xmax = X Origin() + X Range();
    ymin = Y Origin();
    ymax = Y Origin() + Y Range();
    Pen Color( "red" );
    Pen Size( 3 );
    Line Style( "dotted" );
    Line( {xmin, ymin}, {xmax, ymax} );// the diagonal
);

Corner-to-corner diagonal added by script.Corner-to-corner diagonal added by script.

 

 

You probably don't really want red,3,dotted!

 

 

Craige

View solution in original post

David_Burnham
Super User (Alumni)

Re: Anyone have add-in or JSL code for adding a 45-degree line and squarify a GB plot?

An alternative way to add the diagonal line is to add the function line y=x:

report(gb)[FrameBox(1)] << add graphics script(
	 Y Function( x, x )
)

 

-Dave

View solution in original post

Re: Anyone have add-in or JSL code for adding a 45-degree line and squarify a GB plot?

Adding to @David_Burnham's version, many people do not realize that you do not need to run a script to add a graphics script to a plot (frame box). You can interactively accomplish the same thing. Right-click in the plot box and select Customize. Click the add button (+) and then enter the expression Y Function( x, x ). There is even a macro for this common expression. This way might not be the best way for you now, but I wanted you to know about it as an alternative.

View solution in original post

8 REPLIES 8
txnelson
Super User

Re: Anyone have add-in or JSL code for adding a 45-degree line and squarify a GB plot?

Here is a simple script that maintains a square display with a diagonal line.  The code is written to hopefully show all that is going on.  Far more efficient code could be written.

Names Default To Here( 1 );
dt = Current Data Table();
Graph Builder(
	Show Control Panel( 0 ),
	Variables( X( :weight ), Y( :height ) ),
	Elements( Points( X, Y, Legend( 8 ) ) )
);
rpt = Current Report();
xmax = rpt[axisbox( 1 )] << get max;
ymax = rpt[axisbox( 2 )] << get max;
xmin = rpt[axisbox( 1 )] << get min;
ymin = rpt[axisbox( 2 )] << get min;
rpt[axisbox( 1 )] << Min( Min( ymin, xmin ) );
rpt[axisbox( 1 )] << Max( Max( ymax, xmax ) );
rpt[axisbox( 2 )] << Min( Min( ymin, xmin ) );
rpt[axisbox( 2 )] << Max( Max( ymax, xmax ) );
rpt[framebox( 1 )] << add graphics script(
	xmax = rpt[axisbox( 1 )] << get max;
	ymax = rpt[axisbox( 2 )] << get max;
	xmin = rpt[axisbox( 1 )] << get min;
	ymin = rpt[axisbox( 2 )] << get min;
	rpt[axisbox( 1 )] << Min( Min( ymin, xmin ) );
	rpt[axisbox( 1 )] << Max( Max( ymax, xmax ) );
	rpt[axisbox( 2 )] << Min( Min( ymin, xmin ) );
	rpt[axisbox( 2 )] << Max( Max( ymax, xmax ) );
	theMinLineList = {};
	theMaxLineList = {};
	Insert Into( theMinLineList, Min( ymin, xmin ) );
	Insert Into( theMinLineList, Min( ymin, xmin ) );
	Insert Into( theMaxLineList, Max( ymax, xmax ) );
	Insert Into( theMaxLineList, Max( ymax, xmax ) );
	Line( theMinLineList, theMaxLineList );
	xx = rpt[framebox( 1 )] << get size;
	Show( xx );
	xx[1] = Max( xx );
	xx[2] = Max( xx );
	rpt[framebox( 1 )] << framesize( xx[1], xx[2] );
);
Jim
Craige_Hales
Super User

Re: Anyone have add-in or JSL code for adding a 45-degree line and squarify a GB plot?

Here's a variation that assumes you won't resize the graph or adjust the axes after it is drawn. Jim's version is resetting the squareness on each redraw of the graph, which may trigger another redraw of the graph. If you really need that, it might be necessary to use the scheduler to reset the squareness outside of the graphic script.

 

 

dt = Open( "$sample_data/big class.jmp" );
  	
gb = dt << Graph Builder( Show Control Panel( 0 ),
    Variables( X( :weight ), Y( :height ) ),
    Elements( Points( X, Y, Legend( 3 ) ), Smoother( X, Y, Legend( 4 ) ) )
);
Report( gb )[framebox( 1 )] << FrameSize( 500, 500 ); //force square

// fix JSL here to set the axis ranges the way you expect. 
theMax = Max( Report( gb )[axisbox( 1 )] << get max, Report( gb )[axisbox( 2 )] << get max );
theMin = Min( Report( gb )[axisbox( 1 )] << get min, Report( gb )[axisbox( 2 )] << get min );
Report( gb )[framebox( 1 )] << Xaxis( Min( theMin ), Max( theMax ) );
Report( gb )[framebox( 1 )] << Yaxis( Min( theMin ), Max( theMax ) );

// add the diagonal line
Report( gb )[framebox( 1 )] << AddGraphicsScript(
    xmin = X Origin();
    xmax = X Origin() + X Range();
    ymin = Y Origin();
    ymax = Y Origin() + Y Range();
    Pen Color( "red" );
    Pen Size( 3 );
    Line Style( "dotted" );
    Line( {xmin, ymin}, {xmax, ymax} );// the diagonal
);

Corner-to-corner diagonal added by script.Corner-to-corner diagonal added by script.

 

 

You probably don't really want red,3,dotted!

 

 

Craige
SDF1
Super User

Re: Anyone have add-in or JSL code for adding a 45-degree line and squarify a GB plot?

Hi @txnelson , @Craige_Hales , and @David_Burnham ,

 

  Thanks again for your previous help. I'm hoping you might be able to help me on another aspect of this side project.

 

  As mentioned in my last reply, I would like to implement this in a way that would be a toolbar hotbutton item that users in my organization can "install" in their JMP, like add-ins. That part I know how to do. What I'm stuck on is how to treat an existing open window as a report so you can manipulate it like in the above code on this post.

 

  For example, a user opens the Big Class.jmp file, then manually starts using Graph Builder to plot height vs. weight. This opens a child window under the Big Class data table called Big Class - Graph Builder. I know how to get window names and all that, but unlike in the previous code, I don't have the following

gb = dt << Graph Builder( Show Control Panel( 0 ),
    Variables( X( :weight ), Y( :height ) ),
    Elements( Points( X, Y, Legend( 4 ) ) )
);

  So I can't reference gb using Report (gb), where it's used for the following manipulations in the example code from Craige:

theMax = Max( Report( gb )[axisbox( 1 )] << get max, Report( gb )[axisbox( 2 )] << get max );
theMin = Min( Report( gb )[axisbox( 1 )] << get min, Report( gb )[axisbox( 2 )] << get min );
Report( gb )[framebox( 1 )] << Xaxis( Min( theMin ), Max( theMax ) );
Report( gb )[framebox( 1 )] << Yaxis( Min( theMin ), Max( theMax ) );

Report( gb )[framebox( 1 )] << AddGraphicsScript(Y Function(x,x), Pen Color("blue"));

Report( gb )[framebox( 1 )] << AddGraphicsScript(
    xmin = X Origin();
    xmax = X Origin() + X Range();
    ymin = Y Origin();
    ymax = Y Origin() + Y Range();
    Pen Color( "red" );
    Pen Size( 3 );
    Line Style( "dotted" );
    Line( {xmin, ymin}, {xmax, ymax} );// the diagonal
);

  In this kind of coding, it's easy to reference the report gb because you sent the command to the data table when doing gb = dt << Graph Builder (.....). In my case, I wouldn't have that because the user is doing this manually (with whatever graph he's creating).

 

  I'd like to make a toolbar hotbutton that one could push, the code then gets the current Graph Builder window name (in case there is more than one instance of Graph Builder open for that data table), and then performs the squarify and diagonal line as solved from before. I'm stumped on how to go from a window's name to assigning it as a report so all the other code can work.

 

Many thanks in advance!,

DS

  

txnelson
Super User

Re: Anyone have add-in or JSL code for adding a 45-degree line and squarify a GB plot?

Look in the Scripting Index for the documentation on the

   Current Report()

function

Jim
SDF1
Super User

Re: Anyone have add-in or JSL code for adding a 45-degree line and squarify a GB plot?

Hi @txnelson ,

 

  Thanks for the quick reply and hint. From that, I also found a previous solution you provided to another user looking to do something similar with windows and reports here.

 

  Adding this simple line of code allows me move on with the editing and modification of the current graph builder report.

gb=Current Report()[outlinebox(1)]<<Get Scriptable Object;

Thanks for the help!,

DS

David_Burnham
Super User (Alumni)

Re: Anyone have add-in or JSL code for adding a 45-degree line and squarify a GB plot?

An alternative way to add the diagonal line is to add the function line y=x:

report(gb)[FrameBox(1)] << add graphics script(
	 Y Function( x, x )
)

 

-Dave

Re: Anyone have add-in or JSL code for adding a 45-degree line and squarify a GB plot?

Adding to @David_Burnham's version, many people do not realize that you do not need to run a script to add a graphics script to a plot (frame box). You can interactively accomplish the same thing. Right-click in the plot box and select Customize. Click the add button (+) and then enter the expression Y Function( x, x ). There is even a macro for this common expression. This way might not be the best way for you now, but I wanted you to know about it as an alternative.

SDF1
Super User

Re: Anyone have add-in or JSL code for adding a 45-degree line and squarify a GB plot?

Hi @txnelson@Craige_Hales@David_Burnham, and @Mark_Bailey,

 

  Thanks for your feedback and input on this, I really appreciate it. I like both versions for different reasons, I like the additional ways to modify the line style with Jim and Craige's methods, but also like the simplified Function style from David and Mark. I could see both methods having value for different reasons and audiences.

 

  I will take your suggestions and figure out how to write up the JSL so that it can be added as a toolbar hotbutton so I can distribute it to others in my organization.

 

Thanks!,

DS