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
terapin
Level VI

Use variable list of columns as Y Axis in Graph Builder

Folks,

 

I just upgraded from JMP14 Pro to JMP15 Pro and am running into problems with many of my JSL scripts that use OverlayPlots.  I'm trying to covert some of my more complex OP's over to GB and am running into a hiccup when using variable lists in GB.  With OP's the following code successfully plotted all variables for a given data file that met the Y( Eval List ( ???? ) ) criteria.  I created this code to accomodate the fact that various field sites may have different number of sensors present that I want plotted.  

 

// Potential Tair Data
pot_tair_list = {"Datalogger Internal Temperature (C)", "Air Temperature - HMP - 5m (C)", "Air Temperature - HMP (C)",
"Air Temperature, STD - HMP (C)", "Air Temperature - WXT (C)", "Air Temperature @ 5m - HMP (C)", "Air Temperature - MA4100 (C)",
"Air Temperature - EE181 (C)", "Air Temperature - WS700 (C)", "Air Temperature - GMX541 (C)"};

// Create empty list to hold names of the those measurement variables found in data table
act_tair_list = {};

// Run through data table column names and put those that match measurement variable list into new list
For( i = 1, i <= N Items( pot_tair_list ), i++,
	If( Contains( dt_col_name_list, pot_tair_list[i] ),
		Insert Into( act_tair_list, pot_tair_list[i] )
	)
);

******************************
		// Plot Air Temperature data
		If( N Items( act_tair_list ) > 0,
			Graph Builder(
				Size( 1600, 500 ),
				Show Control Panel( 0 ),
				Show Legend( 0 ),
				Legend Position( "Right" ),
				Fit to Window( "Off" ),
				Graph Spacing( 3 ),
				Variables( X( :Name( "Date & Time" ) ), Y( Eval List( act_tair_list ) ) ),
				Elements( Line( X, Y, Legend( 4 ) ), Points( X, Y, Legend( 1 ) ) ),
				SendToReport(
					Dispatch(
						{},
						"Date & Time",
						ScaleBox,
						{Format( "m/d/y", 10 ), Min( sdate ), Max( edate ), Interval( "Day" ), Inc( 28 ), Minor Ticks( 0 )}
					),
					Dispatch(
						{},
						Y( Eval List( act_tair_list ) ),
						ScaleBox,
						{Format( "Fixed Dec", 10, 0 ), Inc ( 5 ), Show Major Grid( 1 ), Minor Ticks( 0 )}
					),
					Dispatch(
						{},
						"400",
						ScaleBox,
						{Legend Model( 1, Properties( 0, {Line Color( 3 ), Fill Color( 0 )}, Item ID( "Battery (V)", 1 ) ) )}
					),
					Dispatch( {}, "Graph Builder", FrameBox, {Marker Size( 1 )} )
				)
			)
		);

 

GB doesn't like the same list construction I've used with OPs and throws the following error: 

 

Specified Column not found in data table.{191471} in access or evaluation of 'Y' , Y( Eval List( act_tair_list ) ) /*###*/Exception in platform launch{191471} in access or evaluation of 'Graph Builder' 

 

I've completed most of my JSL graphing using the OP platform and lack the knowledge for how to resolve this issue.

 

Is it possible to pass a variable list to GB for the Y Axis, and if so, what does that format look like? I would appreciate any help in resolving this so that I can continue using a single graphing script for all variables at all field sites, regardless of the actual specific sensors present.  Thanks.

 

 

6 REPLIES 6

Re: Use variable list of columns as Y Axis in Graph Builder

The launch of Graph Builder does not work the same way as launching Overlay Plot. Overlay Plot used one named argument Y() that accepted a column reference or a list of column references. Graph Builder launches with a separate Y() argument for each column in that role. Here is an example based on the Fitness data table:

 

Names Default to Here( 1 );

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

gb = dt << Graph Builder(
	Size( 534, 456 ),
	Show Control Panel( 0 ),
	Variables(
		X( :Weight ),
		Y( :Runtime ),
		Y( :RunPulse, Position( 1 ) ),
		Y( :RstPulse, Position( 1 ) )
	),
	Elements(
		Points( X, Y( 1 ), Y( 2 ), Y( 3 ), Legend( 3 ) ),
		Smoother( X, Y( 1 ), Y( 2 ), Y( 3 ), Legend( 4 ) )
	)
);

One approach is to use expressions. The Insert Into() and Substitute() functions make it easy to create the necessary launch expression.

 

Names Default to Here( 1 );

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

col = { :Runtime, :RunPulse, :RstPulse };

var expr = Expr( Variables( X( :Weight ) ) );
For( c = 1, c <= N Items( col ), c++,
	y expr  = Expr( Y() );
	Insert Into( y expr, col[c] );
	Insert Into( var expr, Name Expr( y expr) );
);

Eval(
	Substitute(
		Expr(
			gb = dt << Graph Builder(
				Size( 534, 456 ),
				Show Control Panel( 0 ),
				vvv,
				Elements(
					Points( X, Y( 1 ), Y( 2 ), Y( 3 ), Legend( 3 ) ),
					Smoother( X, Y( 1 ), Y( 2 ), Y( 3 ), Legend( 4 ) )
				)
			);
		),
		Expr( vvv ),
		Name Expr( var expr )
	)
);
terapin
Level VI

Re: Use variable list of columns as Y Axis in Graph Builder

Thanks Mark for the very helpful suggestion,

 

Can you explain why you need to use what looks like a place holder, vvv, instead of calling Name Expr ( var expr ) in this location instead?  I see that no graph is produced when I do this, but I'm not clear why the need for vvv and calling the actual variable list at the end of the GB instruction instead of where the variables are normally declared.  

terapin
Level VI

Re: Use variable list of columns as Y Axis in Graph Builder

Mark,

The other thing about your solution is that it plots each variable in a separate panel rather than all on the same panel, which is ultimately what I want.  The code below illustrates what I want to produce.  I've tried different alterations of your code but to no avail.  Would you mind providing a suggestion on how I can accomplish this?  Thanks.

 

 

Names Default to Here( 1 );

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

Graph Builder(
	Fit to Window( "Off" ),
	Graph Spacing( 3 ),
	Variables(
		X( :Weight ),
		Y( :Runtime ),
		Y( :RunPulse, Position( 1 ) ),
		Y( :RstPulse, Position( 1 ) )
	),
	Elements(
		Points( X, Y( 1 ), Y( 2 ), Y( 3 ), Legend( 3 ) ),
		Line( X, Y( 1 ), Y( 2 ), Y( 3 ), Legend( 6 ) )
	),
	SendToReport(
		Dispatch(
			{},
			"400",
			ScaleBox,
			{Legend Model(
				3,
				Base( 0, 0, 0, Item ID( "Runtime", 1 ) ),
				Base( 1, 0, 0, Item ID( "RunPulse", 1 ) ),
				Base( 2, 0, 0, Item ID( "RstPulse", 1 ) )
			)}
		),
		Dispatch(
			{},
			"400",
			LegendBox,
			{Legend Position( {3, [-1, -1, -1], 6, [0, 1, 2]} ),
			Position( {-1, -1, -1, 0, 1, 2} )}
		)
	)
);

 

 

Re: Use variable list of columns as Y Axis in Graph Builder

Names Default to Here( 1 );

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

col = { :Runtime, :RunPulse, :RstPulse };

var expr = Expr( Variables( X( :Weight ) ) );
For( c = 1, c <= N Items( col ), c++,
	y expr  = Expr( Y( Position( 1 ) ) );
	Insert Into( y expr, col[c], 1 );
	Insert Into( var expr, Name Expr( y expr) );
);

Eval(
	Substitute(
		Expr(
			gb = dt << Graph Builder(
				Size( 534, 456 ),
				Show Control Panel( 0 ),
				vvv,
				Elements(
					Points( X, Y( 1 ), Y( 2 ), Y( 3 ), Legend( 3 ) ),
					Smoother( X, Y( 1 ), Y( 2 ), Y( 3 ), Legend( 4 ) )
				)
			);
		),
		Expr( vvv ),
		Name Expr( var expr )
	)
);

Re: Use variable list of columns as Y Axis in Graph Builder

The idea is simple. Substitute() looks for an expression within an expression, so I put an unusual expression, vvv, within the main expression so that it is the unambiguous target. The function replaces it with the expression I built for the columns in the Y role.

 

I do not know what you mean by "calling the actual variable list at the end of the GB instruction." I am not doing any such thing. I am guessing what you might be referring to, I can only say that you are confused about the difference between code that is executing and expressions. Also, named arguments in a function call or message send are position independent.

 

It might be instructive for you to select the Eval() expression and run this code by itself. It generates a new expression that is evaluated. 

 

This case is a simple application of of expressions. You should study the JMP Scripting Guide or attend one of our classes about introducing scripting.

Vball247
Level V

Re: Use variable list of columns as Y Axis in Graph Builder

Thanks for a great explanation. I am trying to teach the Substitute to employees starting to use scripts. I was noticing this example is hard coded for the 3 graphs in this section below. If you add a 4th column to the list (like col = {:Runtime, :RunPulse, :RstPulse, :MaxPulse}, still just plots 3 graphs in Graph Builder

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

 Is there a simple way to set these expressions up as well in the For loop? I am not quite certain if the new expression should start with Elements(), or can be done by assembling a Points() expression and a Smoother() expression, similar to the "var expr"? I will play around with this, but wanted to know if there is some other trick about what Substitute might see as an expression, or what level in the expression is recommended to start. For example, you started the var expr with "Variables (X (:Weight)) and then inserted the Y's. Is this a best practice?