cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
  • JMP 19 is here! See the new features at jmp.com/new.
  • Register to attend Discovery Summit 2025 Online: Early Users Edition, Sept. 24-25.
Choose Language Hide Translation Bar
miguello
Level VII

Replacing 'Bivariate' with 'Graph Builder' in a 'Fit Group'

Hi community!

 

For ages I had a script where I was drawing bivariate plots in a fit group, like so:

 

Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
Y_Parameters = {"height", "weight"};

Fit Group(
	Bivariate( Y(Eval(Y_Parameters) ), X( :age ) ),
	<<{Arrange in Rows( 3 )}
);

Key thing here is - I get a list of parameters in a form of list of strings, and then plot them one by one.

 

Now I need to switch from Bivariate Plot to Graph Builder due to some features that Graph Builder has and Bivariate doesn't.

I figured out how to make the Graph Builder plot look exactly like Bivariate, but I cannot figure out if there is a simple way of drawing GBs in a Fit Group just like above. It looks like Fit Group can take GBs like so:

Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
Y_Parameters = {"height", "weight"};
Fit Group(
Graph Builder(
	Size( 480, 300 ),
	Show Control Panel( 0 ),
	Variables( X( :age ), Y(Eval(Y_Parameters[1]) ) ),
	Elements( Points( X, Y( 1 ), Y( 2 ), Legend( 3 ) ) )
), 
Graph Builder(
	Size( 480, 300 ),
	Show Control Panel( 0 ),
	Variables( X( :age ), Y(Eval(Y_Parameters[2]) ) ),
	Elements( Points( X, Y( 1 ), Y( 2 ), Legend( 3 ) ) )
),
	<<{Arrange in Rows( 3 )}
)



But for arbitrary list of parameters I need to script it in a loop. I was hoping for something simpler like (obviously doesn't work):

 

Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
Y_Parameters = {"height", "weight"};
Fit Group(
Graph Builder(
	Size( 480, 300 ),
	Show Control Panel( 0 ),
	Variables( X( :age ), Y(Eval(Y_Parameters) ) ),
	Elements( Points( X, Y( 1 ), Y( 2 ), Legend( 3 ) ) )
), 
	<<{Arrange in Rows( 3 )}
)

Any way for GB to take a list of parameters and output a list of DisplayBoxes?

 

 

3 ACCEPTED SOLUTIONS

Accepted Solutions
jthi
Super User

Re: Replacing 'Bivariate' with 'Graph Builder' in a 'Fit Group'

For Graph Builder you would really be using Page to get similar effect but this if course requires your data to be in specific format. Or Column Switcher.

 

If you cannot use Page, I would consider dropping Fit Group for Graph Builder. Collect the graphs into Lineup Box so they can be easily grouped into rows.

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

Y_Parameters = {"height", "weight"};

nw = New Window("Graph Builder - " || (dt << get name),
	ob_group = Outline Box("Fit Group")
);

lub = Lineup Box(N Col(3));
gbs = {};

For Each({yparam}, Y_Parameters,
	lub << Append(
		Insert Into(gbs, Graph Builder(
			Size(480, 300),
			Show Control Panel(0),
			Variables(X(:age), Y(Eval(Y_Parameters))),
			Elements(Points(X, Y(1), Y(2), Legend(3)))
		))
	);
);

ob_group << Append(lub);
show(gbs);

If you wish to be able to change how many reports are in each row, you can do it with Lineup Box 

<< N Col(1);

You could add scripts to the highest level outline box if necessary.

 

And if you wish to use Fit Group, you could do it but it does require some expression handling. You could also make function to do this for you if you have to do this often

Names Default To Here(1);

dt = Open("$SAMPLE_DATA/Big Class.jmp");
ycols = {"height", "weight"};

fg_expr = Expr(Fit Group());

gb_expr = Expr(dt << Graph Builder(
	Size(480, 300),
	Show Control Panel(0),
	Variables(X(:age), Y(_ycol_)),
	Elements(Points(X, Y(1), Y(2), Legend(3)))
));

For Each({ycol}, ycols,
	cur_gb_expr = Substitute(Name Expr(gb_expr),
		Expr(_ycol_), Name Expr(AsColumn(dt, ycol))
	);
	Insert Into(fg_expr, Name Expr(cur_gb_expr))
);

fg = Eval(fg_expr);
fg << Arrange in Rows(2);

 

 

-Jarmo

View solution in original post

miguello
Level VII

Re: Replacing 'Bivariate' with 'Graph Builder' in a 'Fit Group'

Ok, it works in this form:

 

Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
Y_Parameters = {"height", "weight"};
X_Parameter = "age";
groupByColumnString = "sex";

gbF = Function( {dt, X_parameter, Y_Parameters, groupByColumnString},
	lub = Lineup Box( N Col( 3 ) );
	listOfGBs = {};
	groupByColumn = Column( dt, groupByColumnString );
	For Each( {Y_Parameter, index}, Y_Parameters,
		lub << Append(
			Insert Into(
				listOfGBs,
				Graph Builder(
					Size( 480, 300 ),
					Ignore Platform Preferences( 1 ),
					Show Control Panel( 0 ),
					Variables(
						X( Column( X_Parameter ) ),
						Y( Column( Y_Parameter ) ),
						Overlay( groupByColumn )
					), 

				)
			)
		)
		
	);
	Return( lub );
);



gbExpr = Expr(
	lub = Lineup Box( N Col( 3 ) );
	listOfGBs = {};
	groupByColumn = Column( dt, groupByColumnString );
	For Each( {Y_Parameter, index}, Y_Parameters,
		lub << Append(
			Insert Into(
				listOfGBs,
				Graph Builder(
					Size( 480, 300 ),
					Ignore Platform Preferences( 1 ),
					Show Control Panel( 0 ),
					Variables(
						X( Column( X_Parameter ) ),
						Y( Column( Y_Parameter ) ),
						Overlay( groupByColumn )
					), 

				)
			)
		)
		
	);
);

//gbExpr;
lub = gbF(dt, X_parameter, Y_Parameters, groupByColumnString);

ob_group = Outline Box( "Fit Group" );
ob_group << Append( lub );
Show( Type( ob_group ) );


nw = New Window( "Graph Builder - " || (dt << get name), ob_group );

I can use both function (my way) and expression (effectively your way);

 

I don't know what the previous problem was, but apparently I need to create LineUp Box inside the function and return it rather than GB object.

View solution in original post

jthi
Super User

Re: Replacing 'Bivariate' with 'Graph Builder' in a 'Fit Group'

You are appending a list and not graph builders to the lineup box. I would modify your script to something like this

 

Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
Y_Parameters = {"height", "weight"};
X_Parameter = "age";

gbF = Function( {dt, X_parameter, Y_Parameter, groupByColumnString},
	groupByColumn = Column( dt, groupByColumnString );
	gb = Graph Builder(
		Size( 350, 200 ),
		Ignore Platform Preferences( 1 ),
		Show Control Panel( 0 ),
		Variables( X( Column( X_Parameter ) ), Y( Column( Y_Parameter ) ), Overlay( groupByColumn ) ),

	);
	Return( gb );
	
);
lub = Lineup Box( N Col( 3 ) );

listOfGBs = {};
For Each( {Y_Parameter, index}, Y_Parameters,
	lub << Append(Insert Into(listOfGBs, gbF(dt, X_Parameter, Y_Parameter, "sex" )));
);

ob_group = Outline Box( "Fit Group" );
ob_group << Append( lub );

nw = New Window( "Graph Builder - " || (dt << get name), ob_group);

 

You have to be slightly careful when the graphs get created. This can generally be avoided if you start playing around with expressions but it will require you to build them. Also, if you do not need to collect the references it will be slightly easier as you won't need the Insert Into. And you can get them later with << XPath

View more...
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
Y_Parameters = {"height", "weight"};
X_Parameter = "age";

gbF = Function({dt, X_parameter, Y_Parameter, groupByColumnString},
	groupByColumn = Column(dt, groupByColumnString);
	gb = Graph Builder(
		Size(350, 200),
		Ignore Platform Preferences(1),
		Show Control Panel(0),
		Variables(X(Column(X_Parameter)), Y(Column(Y_Parameter)), Overlay(groupByColumn)), 

	);
	Return(gb);
	
);
lub = Lineup Box(N Col(3));

For Each( {Y_Parameter, index}, Y_Parameters,
	lub << Append(gbF(dt, X_Parameter, Y_Parameter, "sex" ));
);

ob_group = Outline Box("Fit Group");
ob_group << Append(lub);

nw = New Window("Graph Builder - " || (dt << get name), ob_group);

gbs = (ob_group << XPath("//OutlineBox[@helpKey='Graph Builder']")) << Get Scriptable Object;
-Jarmo

View solution in original post

8 REPLIES 8
mikedriscoll
Level VI

Re: Replacing 'Bivariate' with 'Graph Builder' in a 'Fit Group'

You were pretty close. You do need to script it in a loop. Below seems to work. you could replace the list of columns with a GUI output or if you're not comfortable with GUI scripting, maybe even script something to 'get selected columns', select the columns to be plotted, and then programmatically convert that to the list.

 

Graph builder's strength is interactivity. This makes it less optimal for having several plots on a window as each would need to be modified (assuming they do) but scripting makes it easy(ish).

 

One method I have is to use a script that outputs to several platforms including y by x and GB. But it also produces the column switcher. Then there is a button to plot each output in the column switcher list to a journal. Of course, no interactivity there.

 

anyway, here's the slightly modified script

 

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

nw = new window("output",
	vlb = vlistbox()
);

Y_Parameters = {"height", "weight"} //, "height 2", "weight 2"}; // test for n > 2

nColsNw = 3;

for(i = 1, i<= nitems(Y_Parameters), i++,
	if(modulo(i - 1, nColsNw) == 0,
		vlb << append(hlb = hlistbox()); //create a new hlb every N columns.
	);
	hlb << append(
		Fit Group(
			Graph Builder(
				Size( 480, 300 ),
				Show Control Panel( 0 ),
				Variables( X( :age ), Y(Eval(Y_Parameters[i]) ) ),
				Elements( Points( X, Y( 1 ), Y( 2 ), Legend( 3 ) ) )
			)//, 
	//			<<{Arrange in Rows( 3 )}
		);
	);
);
miguello
Level VII

Re: Replacing 'Bivariate' with 'Graph Builder' in a 'Fit Group'

The constraints that I have are the following:
This script is a part of an addin. It currently takes input as a list of columns in a text string (generated through GUI). 

And I don't need interactivity, I need a precise format of the plots that has been agreed upon with the customer.

I'm switching to GB as apparently Fit Y by X doesn't have an easy way to display error bars. Customer suddenly wants error bars on the plot.

The question is in the most efficient way of producing list of GBs rather than a single GB. I was hoping for a not documented feature that would allow to do it the same way as in Fit Group and Fit Y by X.

 

But looks like I'll have to script loops.

 

 

jthi
Super User

Re: Replacing 'Bivariate' with 'Graph Builder' in a 'Fit Group'

For Graph Builder you would really be using Page to get similar effect but this if course requires your data to be in specific format. Or Column Switcher.

 

If you cannot use Page, I would consider dropping Fit Group for Graph Builder. Collect the graphs into Lineup Box so they can be easily grouped into rows.

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

Y_Parameters = {"height", "weight"};

nw = New Window("Graph Builder - " || (dt << get name),
	ob_group = Outline Box("Fit Group")
);

lub = Lineup Box(N Col(3));
gbs = {};

For Each({yparam}, Y_Parameters,
	lub << Append(
		Insert Into(gbs, Graph Builder(
			Size(480, 300),
			Show Control Panel(0),
			Variables(X(:age), Y(Eval(Y_Parameters))),
			Elements(Points(X, Y(1), Y(2), Legend(3)))
		))
	);
);

ob_group << Append(lub);
show(gbs);

If you wish to be able to change how many reports are in each row, you can do it with Lineup Box 

<< N Col(1);

You could add scripts to the highest level outline box if necessary.

 

And if you wish to use Fit Group, you could do it but it does require some expression handling. You could also make function to do this for you if you have to do this often

Names Default To Here(1);

dt = Open("$SAMPLE_DATA/Big Class.jmp");
ycols = {"height", "weight"};

fg_expr = Expr(Fit Group());

gb_expr = Expr(dt << Graph Builder(
	Size(480, 300),
	Show Control Panel(0),
	Variables(X(:age), Y(_ycol_)),
	Elements(Points(X, Y(1), Y(2), Legend(3)))
));

For Each({ycol}, ycols,
	cur_gb_expr = Substitute(Name Expr(gb_expr),
		Expr(_ycol_), Name Expr(AsColumn(dt, ycol))
	);
	Insert Into(fg_expr, Name Expr(cur_gb_expr))
);

fg = Eval(fg_expr);
fg << Arrange in Rows(2);

 

 

-Jarmo
miguello
Level VII

Re: Replacing 'Bivariate' with 'Graph Builder' in a 'Fit Group'

I think I'll have to switch to Line Up Box. I didn't want to do it as it will require more invasive code changes, but I really don't like scripting expressions. I only hope that:
1. I don't use specific feature of this Fit Group anywhere else in the code

2. I will be able to make it look exactly like Fit Group in the output.

 

I'll show an example code of the final output though.

miguello
Level VII

Re: Replacing 'Bivariate' with 'Graph Builder' in a 'Fit Group'

Question for you.

 

Your script works perfectly fine after fixing an obvious typo:

 

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

Y_Parameters = {"height", "weight"};

nw = New Window("Graph Builder - " || (dt << get name),
	ob_group = Outline Box("Fit Group")
);

lub = Lineup Box(N Col(3));
gbs = {};

For Each({yparam}, Y_Parameters,
	lub << Append(
		Insert Into(gbs, Graph Builder(
			Size(480, 300),
			Show Control Panel(0),
			Variables(X(:age), Y(Eval(yparam))),
			Elements(Points(X, Y(1), Y(2), Legend(3)))
		))
	);
);

ob_group << Append(lub);
show(gbs);

For 'gbs'  it shows 

 

 

{Graph Builder[], Graph Builder[]}

which then appends to 'lub' just fine.

 

I re-wrote the first script you suggested in a slightly different shape and form:

Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
Y_Parameters = {"height", "weight"};
X_Parameter = "age";

gbF = Function( {dt, X_parameter, Y_Parameter, groupByColumnString},
	groupByColumn = Column( dt, groupByColumnString );
	gb = Graph Builder(
		Size( 350, 200 ),
		Ignore Platform Preferences( 1 ),
		Show Control Panel( 0 ),
		Variables( X( Column( X_Parameter ) ), Y( Column( Y_Parameter ) ), Overlay( groupByColumn ) ),

	);
	Return( gb );
	
);
lub = Lineup Box( N Col( 3 ) );

listOfGBs = {};
For Each( {Y_Parameter, index}, Y_Parameters,
	Insert Into( listOfGBs, gbF( dt, X_Parameter, Y_Parameter, "sex" ) )
);

lub << Append( listOfGBs );

ob_group = Outline Box( "Fit Group" );
ob_group << Append( lub );

nw = New Window( "Graph Builder - " || (dt << get name), ob_group = Outline Box( "Fit Group" ) );

in my case 'listOfGBs' also shows as:

{Graph Builder[], Graph Builder[]}

but then on line:

lub << Append( listOfGBs );

it generates error:

Not a display in access or evaluation of 'Append' , Append( listOfGBs ) /*###*/

at line 25 in ....

Any idea why?
I'll try to play around but I'd like to keep GB in a function.

 

 

miguello
Level VII

Re: Replacing 'Bivariate' with 'Graph Builder' in a 'Fit Group'

Your script stops working as weel as soon as I do this:

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

Y_Parameters = {"height", "weight"};

nw = New Window("Graph Builder - " || (dt << get name),
	ob_group = Outline Box("Fit Group")
);

lub = Lineup Box(N Col(3));
gbs = {};

For Each({yparam}, Y_Parameters,
	gb = Graph Builder(
			Size(480, 300),
			Show Control Panel(0),
			Variables(X(:age), Y(Eval(yparam))),
			Elements(Points(X, Y(1), Y(2), Legend(3)))
		);
	lub << Append(
		Insert Into(gbs, gb)
	);
);

ob_group << Append(lub);
show(gbs);

Semantically there should be no difference if I use Graph Builder expression directly or have a variable to represent it - that was my understanding. Why is it breaking the script?

jthi
Super User

Re: Replacing 'Bivariate' with 'Graph Builder' in a 'Fit Group'

You are appending a list and not graph builders to the lineup box. I would modify your script to something like this

 

Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
Y_Parameters = {"height", "weight"};
X_Parameter = "age";

gbF = Function( {dt, X_parameter, Y_Parameter, groupByColumnString},
	groupByColumn = Column( dt, groupByColumnString );
	gb = Graph Builder(
		Size( 350, 200 ),
		Ignore Platform Preferences( 1 ),
		Show Control Panel( 0 ),
		Variables( X( Column( X_Parameter ) ), Y( Column( Y_Parameter ) ), Overlay( groupByColumn ) ),

	);
	Return( gb );
	
);
lub = Lineup Box( N Col( 3 ) );

listOfGBs = {};
For Each( {Y_Parameter, index}, Y_Parameters,
	lub << Append(Insert Into(listOfGBs, gbF(dt, X_Parameter, Y_Parameter, "sex" )));
);

ob_group = Outline Box( "Fit Group" );
ob_group << Append( lub );

nw = New Window( "Graph Builder - " || (dt << get name), ob_group);

 

You have to be slightly careful when the graphs get created. This can generally be avoided if you start playing around with expressions but it will require you to build them. Also, if you do not need to collect the references it will be slightly easier as you won't need the Insert Into. And you can get them later with << XPath

View more...
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
Y_Parameters = {"height", "weight"};
X_Parameter = "age";

gbF = Function({dt, X_parameter, Y_Parameter, groupByColumnString},
	groupByColumn = Column(dt, groupByColumnString);
	gb = Graph Builder(
		Size(350, 200),
		Ignore Platform Preferences(1),
		Show Control Panel(0),
		Variables(X(Column(X_Parameter)), Y(Column(Y_Parameter)), Overlay(groupByColumn)), 

	);
	Return(gb);
	
);
lub = Lineup Box(N Col(3));

For Each( {Y_Parameter, index}, Y_Parameters,
	lub << Append(gbF(dt, X_Parameter, Y_Parameter, "sex" ));
);

ob_group = Outline Box("Fit Group");
ob_group << Append(lub);

nw = New Window("Graph Builder - " || (dt << get name), ob_group);

gbs = (ob_group << XPath("//OutlineBox[@helpKey='Graph Builder']")) << Get Scriptable Object;
-Jarmo
miguello
Level VII

Re: Replacing 'Bivariate' with 'Graph Builder' in a 'Fit Group'

Ok, it works in this form:

 

Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
Y_Parameters = {"height", "weight"};
X_Parameter = "age";
groupByColumnString = "sex";

gbF = Function( {dt, X_parameter, Y_Parameters, groupByColumnString},
	lub = Lineup Box( N Col( 3 ) );
	listOfGBs = {};
	groupByColumn = Column( dt, groupByColumnString );
	For Each( {Y_Parameter, index}, Y_Parameters,
		lub << Append(
			Insert Into(
				listOfGBs,
				Graph Builder(
					Size( 480, 300 ),
					Ignore Platform Preferences( 1 ),
					Show Control Panel( 0 ),
					Variables(
						X( Column( X_Parameter ) ),
						Y( Column( Y_Parameter ) ),
						Overlay( groupByColumn )
					), 

				)
			)
		)
		
	);
	Return( lub );
);



gbExpr = Expr(
	lub = Lineup Box( N Col( 3 ) );
	listOfGBs = {};
	groupByColumn = Column( dt, groupByColumnString );
	For Each( {Y_Parameter, index}, Y_Parameters,
		lub << Append(
			Insert Into(
				listOfGBs,
				Graph Builder(
					Size( 480, 300 ),
					Ignore Platform Preferences( 1 ),
					Show Control Panel( 0 ),
					Variables(
						X( Column( X_Parameter ) ),
						Y( Column( Y_Parameter ) ),
						Overlay( groupByColumn )
					), 

				)
			)
		)
		
	);
);

//gbExpr;
lub = gbF(dt, X_parameter, Y_Parameters, groupByColumnString);

ob_group = Outline Box( "Fit Group" );
ob_group << Append( lub );
Show( Type( ob_group ) );


nw = New Window( "Graph Builder - " || (dt << get name), ob_group );

I can use both function (my way) and expression (effectively your way);

 

I don't know what the previous problem was, but apparently I need to create LineUp Box inside the function and return it rather than GB object.

Recommended Articles