cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Try the Materials Informatics Toolkit, which is designed to easily handle SMILES data. This and other helpful add-ins are available in the JMP® Marketplace
Choose Language Hide Translation Bar
FJMoesler
Level I

Scripting Graph Builder - Box Plot to Points?

Hello,

 

I am finding scripting to the Graph Builder a brutal experience (I have been scripting JMP for some time). It doesn't seem to be intuitive, nor can I seem to find the specific help I need. So I'm waving my white flag and asking the group. 

 

My script grabs the correct columns (which vary in count) and creates a Graph Builder with two nested X levels all properly. The problem is that although the first variable I give is properly points, for some reason the graph builder assigns box plots to every other variable (which is nowhere to be seen in my script). So, I'm looking for an easy way to turn all of my y variables to points. I suspect it involves looping through Elements, but I'll be darned if I can find how to do it properly. 

 

Thoughts? Also, does anyone have a good reference for detailed scripting to Graph Builder?

 

TIA! Fred

Fred
6 REPLIES 6
FJMoesler
Level I

Re: Scripting Graph Builder - Box Plot to Points?

Well, found a bit of a work around, but it's definitely unstable. 

I ended up:

  1. making the initial graph with my desired nested x variables, but no Y variables.
  2. Then I run a loop to add the Y variables.
  3. Then I add another loop to remove the element for each Y and add a new element for each Y that has points. 
  4. Then I add another loop to add grid lines for each Y.

Almost every step has a Wait(1) between them. I initially tried a single loop for each variable that did each thing, and I crashed JMP complete somewhere around 10 times so far. It was my troubleshooting that got me to the form above. 

 

So, it works, but I sure don't like the crashing of JMP if not coded correctly. And I would still appreciate someone pointing me to a solid reference for the Graph Builder scripting. Thanks in advance!  Fred

 

Fred
pmroz
Super User

Re: Scripting Graph Builder - Box Plot to Points?

Graph Builder JSL scripts are not easy to understand.  My approach is to tweak the graph to my liking and then click the red triangle and get the resulting script.

However if you have a dynamic number of Y variables you could get the script for 2 or 3 Y variables, and study the GB script for patterns.  Then to extend it to n Y variables you would dynamically build a string containing the gb script to execute, and then run it with eval(parse(gb_string)).

FJMoesler
Level I

Re: Scripting Graph Builder - Box Plot to Points?

Yes. I agree. That's been my approach to learn it as well, but it is amazingly frustrating relative to the other scripting. A ripe area for more discussions!

Fred

Re: Scripting Graph Builder - Box Plot to Points?

Are you plotting multiple columns in the Y role or using multiple Graph Builder objects, one for each column?

Re: Scripting Graph Builder - Box Plot to Points?

Here is one way using expressions. I like this approach in this case because I have complete control and I can make the entire launch expression in one go.

 

Names Default to Here( 1 );

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

// a list of columns to plot in Y role was previously created somehow
col = List( :height, :weight );
nc = N Items( col );

// create expression for Variables launch argument with first column,
// using same two nested X variables
vars arg = Eval Expr(
	Variables(
		X( :age ),
		X( :sex, Position( 1 ) ),
		Y( Expr( col[1] ) )
	)
);

// create expression for Points launch argument with first column
points arg = Eval Expr(
	Points( X( 1 ), X( 2 ), Y( 1 ) ) 
);

// add remaining columns in the Y role
If( nc > 1,
	For( c = 2, c <= nc, c++,
		Insert Into( vars arg, Eval Expr( Y( Expr( col[c] ), Position( 1 ) ) ) );
		Insert Into( points arg, Eval Expr( Y( Expr( c ) ) ) );
	);
);

// finish GB launch expression
gb expr = Substitute(
	Expr(
		Graph Builder(
			Size( 534, 464 ),
			Show Control Panel( 0 ),
			vvv,
			Elements( ppp )
		)
	),
	Expr( vvv ), Name Expr( vars arg ),
	Expr( ppp ), Name Expr( points arg )
);

Eval( gb expr );

 

I realize that this answer is not a complete solution. You did not give enough information to attempt a solution. Also, it is better for you to learn how to solve it yourself. It is meant to illustrate an approach that might work for you.

FJMoesler
Level I

Re: Scripting Graph Builder - Box Plot to Points?

Thanks for the help. I took the following approach (through iteration... lots of fails!):

1. I have a list of column names that I want to put into the chart. It's in list "a" (not shown). It's what I would like to plot.

2. I build a list from the data table columns that match my search list. These are the Y axis variables that exist that I can plot.

3. I build a Graph Builder, and set my X axis with nested variables. This is common for all of my data. 

4. I then loop through and add the variables.

5. Then I loop through and add the elements.

6. Then I loop through and add gridlines. And then finally titles. 

 

For steps 4-6, I kept crashing JMP if I tried to do these things within a single loop. It's how I came to this point. The script works (had to pull some minor confidential stuff out), but isn't fast. 

Compared to other JSL I've programmed, this is rather cludgy. I haven't had this many JMP crashes ever. But it works.  


dtname = dt << Get Name();
currentTime = Today();
timeString = "Last Updated " || Format( currentTime, "mm-dd-yyyy" ) ;

// Find columns that match the terms in list "a"

col = dt << get column names( string );
nc = N Items( col );
nsrch = N Items( a );


xxx = {};
For( j = 1, j <= nsrch, j++,
For( i = 1, i <= nc, i++,
If( Uppercase( col[i] ) == Uppercase( a[j] ),
Insert Into( xxx, col[i] ),

)
)
);

colList = xxx;


//Build Basic Chart with nested X variables, no Y variables (yet)
gb = dt << Graph Builder(
Size( 1226, 608 ),
Show Control Panel( 0 ),
Show Legend( 0 ),
Show Subtitle( 1 ),
Variables(
X( :XVar1, Combine( "Nested" ) ),
X( :XVar2, Position( 1 ), Combine( "Nested" ) ),
X( :XVar3, Position( 1 ), Combine( "Nested" ) ),

),

);
gbb = Report( gb )[Graph Builder Box( 1 )];

// I don't know why I have to break these into separate loops, but I tried not to....
// I think it's something to do with needing the "wait".

//Add Y variables.
For( i = 1, i <= N Items( colList ), i++,
gbb << Add Variable( {colList[i], Role( "Y" )} );
If( i == 1,
chrtname = colList[i],
chrtname = chrtname || ", " || colList[i]
);

);

Wait( 1 );
//Remove existing element and replace with points.
For( i = 1, i <= N Items( colList ), i++,
gbb << Remove Element( 1, i, 1 );
gbb << Add Element( 1, i, {Type( "Points" ), X, Y} );
);
Wait( 1 );
For( i = 1, i <= N Items( colList ), i++,
gbb << Add Element( 1, i, {Type( "Line" ), X, Y} )
);

//Set Major Axes
For( i = 1, i <= N Items( colList ), i++,
gbb << Dispatch( {}, colList[i], ScaleBox, {Label Row( Show Major Grid( 1 ) )} ),

);

//Set Various Titles
gb << SendToReport( Dispatch( {}, "graph 1 title", TextEditBox, {Set Text( timeString )} ) );
gb << SendToReport( Dispatch( {}, "Graph Builder", OutlineBox, {Set Title( chrtname || " from " || dtname ), Image Export Display( Normal )} ) );
gb << SendToReport(
Dispatch(
{},
"XVar1",
ScaleBox,
{Label Row( 2, {Major Grid Line Color( 3 ), Show Major Grid( 1 )} ), Label Row( 3, {Major Grid Line Color( 5 ), Show Major Grid( 1 )} )}
)
);
);
Fred