JMP 17.2.0
EDIT: Example data file uploaded with main post.
I have run into a slight issue when trying to customize my graphs, either through graph builder or via JSL (or combo). I have scoured the JMP forums and found some similar topics, but no solution that actually works for what I specifically want to do.
What I want JMP to do is: color code my markers by test number (or in the code its RUN_NUM), choose different marker shapes by test number, and then plot a quadratic line of fit for each test number where the color of the line matches the color of the markers for each test number and the line of fit is also always a dashed line for every test number. The other thing to note here is that I don't want to permanently assign colors to specific tests using a feature like row color states. I want the graph to use the same color scheme no matter which test numbers I plot as this data is part of a growing data table that may end up with 100-200 tests. For example, if I plot Tests 1-5, I want them to always plot as a color scheme like blue, red, green, orange, purple so that if I change what I plot, say now Tests 1-4 + Test 7 the color scheme is the same for the five tests plotted.
I can almost get all the above features, but I fall short in getting the color coding of the markers and line of fit to match. Here's my process so far in graph builder/JSL:
- I plot my data points in GB, usually four data points per test.
- I drag 'test number' to the 'overlay' space in GB This color codes my data points per test.
- I drag 'test number' to the 'color' space in GB. This chooses a shape for each test.
- I click the line of fit option which adds the line to the graph, but they have different line styles and the color is always the JMP Default Blue.
So using the above steps, I'm close but not quite there. Using the JMP forums, I've found a good way to add JSL to modify the line style and/or color, but not both together. I can save my GB graph and then edit the JSL a bit to get one or the other.
Note: In the code below Test Number = RUN_NUM
By adding this at the top of my graph code:
dts = dt << Summary(
Group( :RUN_NUM ),
Freq( "None" ),
Weight( "None" ),
invisible
);
dlist = Column (dts, "RUN_NUM") << get values;
Close (dts, NoSave);
show (dlist);
And adding this at the bottom of my graph code:
For (i = 0, i < N Items (dlist), i++,
gb << SendToReport(
Dispatch(
{},
"400",
ScaleBox,
{Legend Model(
1, //change this legend number to match what is above in graph builder...when modifying this code
Properties (i, {Marker Size(8)} )
);
})));
For (i = 0, i < N Items (dlist), i++,
gb << SendToReport(
Dispatch(
{},
"400",
ScaleBox,
{Legend Model(
2, //change this legend number to match what is above in graph builder...when modifying this code
Properties (i, {Line Style( 2 ), Line Width (1)} )
);
})));
I am able to use the above code to modify the line of fit properties. However, I've found some quirks.
- As is, the above code modifies the line style to dashed for every line of fit
- As is, the above code modifies the line width for every line of fit
- As is, all lines of fit are colored black for some reason
It's almost everything I want except the lines are black. Next quirk:
- If I remove "test number" from the "color" property in GB all my lines of fit now match the color of the marker and they dynamically change with each selected test! They are also all dashed and correct width.
- Now my markers are all circles instead of unique shapes that change when selecting different tests and they ignore my specified marker size in the code.
So now I've gotten it all except the marker shape. This is where I'm stuck. It seems I must live with one of two outcomes:
- Everything I want except line of fits are always black lines
- Everything I want except marker shapes are always circles (and small)

Does anyone know of a way to accomplish everything I want for a custom graph? Maybe there is something I am misunderstanding? Any help is greatly appreciated.
Some previous relevant JMP discussions:
- https://community.jmp.com/t5/Discussions/Match-Line-Color-of-Normal-Quantile-Plot-to-Row-Color-Set-in-Row/m-p/124080
- https://community.jmp.com/t5/Discussions/Change-color-theme-in-plot-legend-of-FIt-Curve/td-p/368792
- https://community.jmp.com/t5/Discussions/assign-marker-style-line-style-by-quot-string-quot-or-specific/td-p/48860
Full GB code:
dt = Data Table( "DT" );
//this short section makes a list of all runs/tests in the data table
//then all the runs are counted in a later section for a "for loop"
dts = dt << Summary(
Group( :RUN_NUM ),
Freq( "None" ),
Weight( "None" ),
invisible
);
dlist = Column (dts, "RUN_NUM") << get values;
Close (dts, NoSave);
show (dlist);
//below is the graph builder code
gb = Graph Builder(
Size( 850, 600 ),
Show Legend( 1 ),
Show Title( 0 ),
Show Footer( 0 ),
Fit to Window( "Off" ),
Variables(
X( :TEMP ),
Y( :CONVERSION ),
Overlay( :RUN_NUM ),
Color( :RUN_NUM )
),
Elements(
Points( X, Y, Legend( 1 ) ),
Line Of Fit(
X,
Y,
Legend( 2 ),
Degree( "Quadratic" ),
Confidence of Fit( 0 )
)
),
SendToReport(
Dispatch( {"Line Of Fit"}, "", OutlineBox, {Close( 0 )} ),
Dispatch(
{},
"TEMP",
ScaleBox,
{Min( 50 ), Max( 100 ), Inc( 5 ), Minor Ticks( 4 ),
Label Row(
{Show Major Grid( 1 ), Set Font Size( 18 ), Set Font Style( "Bold" )
}
)}
),
Dispatch(
{},
"CONVERSION",
ScaleBox,
{Min( 40 ), Max( 60 ), Inc( 5 ), Minor Ticks( 4 ),
Label Row(
{Automatic Font Size( 0 ), Show Major Grid( 1 ),
Show Minor Grid( 1 ), Set Font Size( 18 ), Set Font Style( "Bold" )}
)}
),
Dispatch(
{},
"X title",
TextEditBox,
{Set Text( "Temperature" ), Set Font Size( 20 ),
Set Font Style( "Bold" )}
),
Dispatch(
{},
"Y title",
TextEditBox,
{Set Text( "Conversion" ), Set Font Size( 20 ),
Set Font Style( "Bold" )}
),
)
);
//this loop goes through all runs and changes lines to dashed and changes their width
For (i = 0, i < N Items (dlist), i++,
gb << SendToReport(
Dispatch(
{},
"400",
ScaleBox,
{Legend Model(
1, //change this legend number to match what is above in graph builder...when modifying this code
Properties (i, {Marker Size(8)} )
);
}
)
)
);
For (i = 0, i < N Items (dlist), i++,
gb << SendToReport(
Dispatch(
{},
"400",
ScaleBox,
{Legend Model(
2, //change this legend number to match what is above in graph builder...when modifying this code
Properties (i, {Line Style( 2 ), Line Width (1)} )
);
}
)
)
);
Thanks for the reply! Based on my limited understanding of row states, I don't think I quite want to use them. Row states work nicely for this very small data set, but my actual data sets involve over a hundred tests. If I use row states to assign color then the colors will eventually repeat with a slightly different shade so I'll have tests that are Red Shade #1, Red Shade #2, Red Shade #3, etc. Then, if I happen to need a plot of those specific tests they will all be slightly different reds and it will be very difficult to distinguish them based on color. I'd prefer if the color scheme is tied to the plot so no matter what subset of tests I plot the color scheme is always the same, i.e., the same tests that would be Red Shade #1, Red Shade #2, Red Shade #3, etc. with row states would be Blue, Red, Green, etc. with the color scheme tied to the plot. I only mentioned the color above, but I believe it would be the same scenario for the marker shapes as well, i.e, the row state marker shapes may eventually repeat in large data sets so there would be a subset of tests that would all have the same marker shapes.
For color you have more options and it is easier to manage than markers. Currently you can only have one column for Overlay so you most likely will have to rely on filter change handler to keep all the styles working as you want to. By default you will get a plot like this

You could then use filter change handler to keep the markers size higher and the line style as lines. With something like this JMP will mess up from time to time and forget that it should be adding color
</CODE></PRE>
<P>I think you could also try dealing with the nightmare called Legend, but... I would avoid it if possible. It is one of the worst (or possibly the worst) things in Graph Builder you can and try to manipulate.</P></LINGO-BODY><LINGO-SUB id="lingo-sub-849266" slang="en-US" mode="CREATE">Re: Force JMP to match line of fit line color to marker color along with a forced line style</LINGO-SUB><LINGO-BODY id="lingo-body-849266" slang="en-US" mode="CREATE"><P>Marker Size can be controlled from right click menu and it is a control for frame box.</P>
<P><SPAN class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jthi_0-1742669047885.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_0-1742669047885.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_0-1742669047885.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_0-1742669047885.png" style="width: 400px;"><span class="lia-inline-image-display-wrapper" image-alt="jthi_0-1742669047885.png" style="width: 400px;"><img src="https://us.v-cdn.net/6038925/uploads/images/74118i18BC8FCF0D2275C2/jthi_0-1742669047885.png" role="button" title="jthi_0-1742669047885.png" alt="jthi_0-1742669047885.png" /></span></SPAN></SPAN></SPAN></SPAN></P>
<P>Couldn't find anything similar for lines though... so maybe something like this could work</P>
<PRE><CODE class=" language-jsl">Names Default To Here(1);
dt = Open("$DOWNLOADS/DT.jmp");
gb = dt << Graph Builder(
Size(525, 454),
Show Control Panel(0),
Variables(X(:TEMPERATURE), Y(:CONVERSION), Overlay(:RUN_NUM), Color(:RUN_NUM)),
Elements(Points(X, Y, Legend(5)), Line Of Fit(X, Y, Legend(7), Degree("Quadratic"), Confidence of Fit(0))),
Local Data Filter(Add Filter(columns(:RUN_NUM), Display(:RUN_NUM, N Items(7)))),
SendToReport(Dispatch({}, "Graph Builder", FrameBox, {Marker Size(6), Marker Drawing Mode("Normal")}))
);
l_expr = Expr(Legend Model(7));
Summarize(dt, c = By(:RUN_NUM));
For Each({item}, c,
cur_expr = EvalExpr(Properties(0, {Line Style("Dashed")}, Item ID(Expr(item), 1)));
Insert Into(l_expr, Name Expr(cur_expr));
);
d_expr = EvalExpr(
Dispatch({}, "400", ScaleBox,
{Expr(Name Expr(l_expr))}
)
);
Eval(EvalExpr(Send(gb, Expr(Name Expr(d_expr)))));Names Default To Here(1);
dt = Open("$DOWNLOADS/DT.jmp");
gb = dt << Graph Builder(
Size(525, 454),
Show Control Panel(0),
Variables(X(:TEMPERATURE), Y(:CONVERSION), Overlay(:RUN_NUM), Color(:RUN_NUM)),
Elements(
Points(X, Y, Legend(5)),
Line Of Fit(X, Y, Legend(7), Degree("Quadratic"), Confidence of Fit(0))
)
);
ldf = gb << Local Data Filter(Add Filter(columns(:RUN_NUM), Display(:RUN_NUM, N Items(7))));
Eval(EvalExpr(
f = Function({a},
gb_rep = Expr(Report(gb));
gb << inval;
fb = gb_rep[FrameBox(1)];
segs = fb << Find Segs;
For Each({seg}, segs,
Match(seg << class name,
"MarkerSeg", seg << Set Marker Size(10),
"LineSeg", seg << Set Line Style("Dashed")
);
);
);
));
rs = ldf << Make Filter Change Handler(f);
f(1); // to initialize at least once