Hi All,
I am developing a JMP Application that uses Python integration to give the application users the flexibility of loading in any (Excel) data file with industrial process data. This Application includes multiple module windows and extensive scripting.
One thing I am trying to do is to simply plot all of the data from a loaded data file onto one graph, where the first column is always time (X) and the remaining columns are the process variables (Y). I have built a module with a Graph Box to display this once the application runs and the data is loaded, but I am having trouble scripting this functionality. Because I don't know how many columns will be in any given data file, nor what they are titled, I need the script to automatically accept all the Y's (all data columns other than the first one) and pass that through the graph.
Messing around with JMP's different graphing options, I have not been able to get Time Series graphs to show multiple overlaid plots, so I have been trying to script with Graph Builder. When I manually plot the data in Graph Builder, I can select all the columns I want and drag them onto the Graph Builder Y and it shows up how I want, with all the data shown on one plot. However, when I try to script this, Graph Builder only shows the first Y variable I pass through the script.
I am not sure how to solve this problem. Any advice/other suggestions are greatly appreciated!
Thank you!
- Estelle
P.S. If there is another way to graph this data in this way without using Graph Builder, please let me know. I prefer that this application only shows the user the graphed result and not all the additional functionality that is available when using Graph Builder.
Combining the solution me and @txnelson provided earlier you should be able to modify point/smoother and so on. First create the graph with JMP (no need to have all columns in y axis, you can use just two). I will go through the process how I would develop this script (this will be a bit long):
1. Open JMP sample data. In this case Semiconductor Capability.jmp as I know it has many columns
2. Create a graph in graph builder with some column as X axis and two as Y axis

Take the script
Graph Builder(
Variables(X(:lot_id), Y(:NPN1), Y(:PNP1, Position(1))),
Elements(Points(X, Y(1), Y(2), Legend(3)))
)
3. Change the points to line and I will also change Summary Statistic from default value, so I can see how that can be changed in script

Take script
Graph Builder(
Variables(X(:lot_id), Y(:NPN1), Y(:PNP1, Position(1))),
Elements(Line(X, Y(1), Y(2), Legend(4), Summary Statistic("Median")))
)
4. Now I have quite good baseline scripts to start working on this. Because I know Re: Can you construct this without writing expression a string? can be used to solve this issue, I use that as my baseline (script I did provide earlier).
With basic graph:
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Semiconductor Capability.jmp");
x_col = Column(dt, 1);
y_cols = (dt << Get Column Names())[5::N Cols(dt)];
var_expr = EvalExpr(
Variables(X(Expr(x_col))
));
For Each({col}, y_cols,
y_expr = Expr(Y(Position(1)));
Insert Into(y_expr, NameExpr(col), 1);
Insert Into(var_expr, Name Expr(y_expr));
);
gb = Eval(Substitute(
Expr(
gb = dt << Graph Builder(
Size(838, 391),
Show Control Panel(0),
vvv,
)
),
Expr(vvv), Name Expr(var_expr),
));
gb_image = gb << get picture;
gb << Close Window;
New window("test",
gb_image
);
Now If I wanted to have Line instead of points I would check what I have to change in the "line" script JMP gave me earlier. Basically I will need to add elements.
Elements(Line(X, Y(1), Y(2), Legend(4), Summary Statistic("Median")))
Luckily these have been added in the other post
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Semiconductor Capability.jmp");
x_col = Column(dt, 1);
y_cols = (dt << Get Column Names())[5::N Cols(dt)];
var_expr = EvalExpr(
Variables(X(Expr(x_col))
));
var_line = Expr(Line(X));
For Each({col, idx}, y_cols,
y_expr = Expr(Y(Position(1)));
Insert Into(y_expr, NameExpr(col), 1);
Insert Into(var_expr, Name Expr(y_expr));
yline_expr = Parse("Y("||char(idx)||")");
Insert Into(var_line, Name Expr(yline_expr));
);
gb = Eval(Substitute(
Expr(
gb = dt << Graph Builder(
Size(838, 391),
Show Control Panel(0),
vvv,
Elements(yyy)
)
),
Expr(vvv), Name Expr(var_expr),
Expr(yyy), Name Expr(var_line)
));
gb_image = gb << get picture;
gb << Close Window;
New window("test",
gb_image
);

(I didn't change summary statistics, but it should be fairly easy to change them by inserting few more expressions to var_line before creation of graph builder)
yline_expr = Expr(Legend(6));<BR />Insert Into(var_line, Name Expr(yline_expr));<BR />yline_expr = Expr(Summary Statistic("Median"));<BR />Insert Into(var_line, Name Expr(yline_expr));<BR />
Knowing how to use Expr, Substitute, NameExpr and so on I have learned through these couple of posts in community Insert one expression into another using Eval Insert, Eval Expr, Parse, and Substitute,Expression Handling Functions: Part I - Unraveling the Expr(), NameExpr(), Eval(), ... Conundrum and with lots and lots of trial and error (I still get confused with them, especially with Name Expr)
And finally,if I were to combine this script with the script you have (I would clean it up more, change order of expressions, most likely prefill column selectors and maybe provide option to select what type of graph to use, but this should give an idea):
View more...
Names Default To Here(1);
//the data table you want to operate on
dt = Open("$SAMPLE_DATA/Semiconductor Capability.jmp");
//number of columns in the data table
numcol = N Col(dt);
selectorwindow = New Window("Column Selector",
<<MODAL></MODAL>
It sounds as if you are generating your JSL from scratch....like a Python programmer would do, rather than taking the interactive Graph Builder that you produced and then having JMP generate the JSL that will create the graph. If I interactively create the below graph,

By going to the red triangle and selecting "Script" it produces a script that handles both Y axis variables
Graph Builder(
Size( 528, 448 ),
Show Control Panel( 0 ),
Variables( X( :age ), Y( :height ), Y( :weight, Position( 1 ) ) ),
Elements(
Points( X, Y( 1 ), Y( 2 ), Legend( 5 ) ),
Smoother( X, Y( 1 ), Y( 2 ), Legend( 6 ) )
),
SendToReport(
Dispatch(
{},
"400",
ScaleBox,
{Legend Model(
5,
Base( 0, 0, 0, Item ID( "height", 1 ) ),
Base( 1, 0, 0, Item ID( "weight", 1 ) )
)}
)
)
);
Now, if your issue is, that when you take a script like the one above, and are trying to expand it to handle as many Y columns as you need, that can sometimes require a bit more work.
Here is the same structure of a graph, but with many more Y columns

Here is the expanded JSL that JMP produced to recreate the graph
Graph Builder(
Size( 528, 458 ),
Show Control Panel( 0 ),
Variables(
X( :Wafer ID in lot ID ),
Y( :NPN1 ),
Y( :PNP1, Position( 1 ) ),
Y( :PNP2, Position( 1 ) ),
Y( :NPN2, Position( 1 ) ),
Y( :PNP3, Position( 1 ) ),
Y( :IVP1, Position( 1 ) ),
Y( :PNP4, Position( 1 ) )
),
Elements(
Points(
X,
Y( 1 ),
Y( 2 ),
Y( 3 ),
Y( 4 ),
Y( 5 ),
Y( 6 ),
Y( 7 ),
Legend( 3 )
),
Smoother(
X,
Y( 1 ),
Y( 2 ),
Y( 3 ),
Y( 4 ),
Y( 5 ),
Y( 6 ),
Y( 7 ),
Legend( 4 )
)
),
SendToReport(
Dispatch(
{},
"400",
ScaleBox,
{Legend Model(
3,
Base( 0, 0, 0, Item ID( "NPN1", 1 ) ),
Base( 1, 0, 0, Item ID( "PNP1", 1 ) ),
Base( 2, 0, 0, Item ID( "PNP2", 1 ) ),
Base( 3, 0, 0, Item ID( "NPN2", 1 ) ),
Base( 4, 0, 0, Item ID( "PNP3", 1 ) ),
Base( 5, 0, 0, Item ID( "IVP1", 1 ) ),
Base( 6, 0, 0, Item ID( "PNP4", 1 ) )
)}
)
)
);
Graph Builder(
Size( 528, 458 ),
Show Control Panel( 0 ),
Variables(
X( :Wafer ID in lot ID ),
Y( :NPN1 ),
Y( :PNP1, Position( 1 ) ),
Y( :PNP2, Position( 1 ) ),
Y( :NPN2, Position( 1 ) ),
Y( :PNP3, Position( 1 ) ),
Y( :IVP1, Position( 1 ) ),
Y( :PNP4, Position( 1 ) )
),
Elements(
Points(
X,
Y( 1 ),
Y( 2 ),
Y( 3 ),
Y( 4 ),
Y( 5 ),
Y( 6 ),
Y( 7 ),
Legend( 3 )
),
Smoother(
X,
Y( 1 ),
Y( 2 ),
Y( 3 ),
Y( 4 ),
Y( 5 ),
Y( 6 ),
Y( 7 ),
Legend( 4 )
)
),
SendToReport(
Dispatch(
{},
"400",
ScaleBox,
{Legend Model(
3,
Base( 0, 0, 0, Item ID( "NPN1", 1 ) ),
Base( 1, 0, 0, Item ID( "PNP1", 1 ) ),
Base( 2, 0, 0, Item ID( "PNP2", 1 ) ),
Base( 3, 0, 0, Item ID( "NPN2", 1 ) ),
Base( 4, 0, 0, Item ID( "PNP3", 1 ) ),
Base( 5, 0, 0, Item ID( "IVP1", 1 ) ),
Base( 6, 0, 0, Item ID( "PNP4", 1 ) )
)}
)
)
);
This is where the JSL programmer has to create the command string to execute to pass to Graph Builder. If you are already doing this, and you are only getting the 1st Y variable in the graph, then typically what is happening is that Graph Builder isn't able to evaluate the information being passed to it. If you provide the JSL you are using, the Community is usually pretty good at helping.