Force Legend with marker and color of row stateHello,
I am trying to make a legend with markers and colors, but I'd like to choose them. I thought it will be easy thanks to row state (color state, marker state,combine states). But once color and marker are assigned to each row, I am not able to find a way to force them in the legend.
I would like to do it by script (I was thinking to add a box with the legend), but I am not able to find a way to handle the "markers" I have created.
Thanks
Re: Force Legend with marker and color of row stateThanks Ian,
it is closer to my initial idea and it is easy to integrate in my script.
So I slightly prefer this solution, even though the other one works well.
Re: Force Legend with marker and color of row stateI haven't figured out how to do it with a script but if you go to Rows>Color or Mark By Column
you get the following

Now you can right click on the legend and change it to whatever you want, and if you have "Make Window with Legend" selected it will create a legend for you. This has the added benefit of selecting in the table anything you've selected in the legend.
You can do the same inside scripting with:
Names Default to here(1);
dt = Open("$SAMPLE_DATA\Big CLass.jmp");
legend = dt << Marker By Column(:age);
new window("Not Really",
Hlistbox(
bivariate(Y(:height), X(:weight)),
legend
)
)
But you lose (at least I haven't found a way to do it) the customizabilty that you're after
Re: Force Legend with marker and color of row stateAs an alternative, you might consider using 'MarkerSeg'. In the code below 'dt' is a table of all the distinct levels of the column you wish to colour and mark by. You could use 'Tables > Summary' and make this invisible.
NamesDefaultToHere(1);
// Example data table (markers and colors assigned by 'Lot ID')
dt = New Table( "Rows With Colors and Markers",
Add Rows( 12 ),
New Column( "Lot ID",
Character,
"Nominal",
Set Values(
{"lot1", "lot10", "lot11", "lot12", "lot13", "lot2", "lot3", "lot4",
"lot5", "lot6", "lot7", "lot8"}
),
Lock( 1 )
),
Set Row States(
[896.813481688499, 1104.17848521471, 34064.2516910434, 1584.79095828533,
1856.1745531559, 34848.5869575739, 35120.7292968035, 2704.17450988293,
2976.75480300188, 3200.51829791069, 3408.21706777811, 36368.77437675]
)
);
// Make legend window with MarkerSeg
n = NRow(dt);
xx = J(n, 1, 1);
yy = Transpose(1::n);
legendList = Column(dt, "Lot ID") << getValues;
gb = Graph Box(
FrameSize( 150, 300*(n/16) ),
Y Scale( 0, n+1 ),
X Scale( 0, 6 ),
Y Name(" "),
X Name(" "),
Y Axis(ShowLabels(0), ShowMajorTicks(0), ShowMinorTicks(0)),
X Axis(ShowLabels(0), ShowMajorTicks(0), ShowMinorTicks(0)),
Marker Seg( xx, yy, Row States( dt ) ),
For( i = 1, i<=n, i++, Text( {1.5, i-0.1}, legendList[i] ) )
);
db = PanelBox("Row State Colours and Markers for 'Lot ID'", gb);
New Window( "My Legend", db);
Re: Force Legend with marker and color of row stateIt seems to be a good solution. I need now to adapt it to my case. Thanks a lot!
Just disappointed by row state!
Re: Force Legend with marker and color of row stateIf you look at
Help==>Scripting Index
and look at both the Graph Builder and the Legend Box() elements, manipulating the legend after the Graph Builder has run, is limited. However, you can use a technique that works for anything, but is a bit cumbersom. If you generate a literal string, that contains the code you need to get the Graph Builder to do what you want, you can then run that literal string. Here is a very primitive example, but I think you will see what kinds of things you can do with it
Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA\big class.jmp" );
Summarize( dt, groups = by( dt:sex ) );
numofgroups = N Items( groups );
TheCode =
"Graph Builder(
Show Control Panel( 0 ),
Variables( X( :height ), Y( :weight ), Overlay( :sex ) ),
Elements( Points( X, Y, Legend( 1 ) ), Smoother( X, Y, Legend( 1 ) ) ),
SendToReport(
Dispatch(
{},
\!"400\!",
ScaleBox,
{Legend Model(
1,";
For( i = 0, i <= numofgroups - 1, i++,
Show( i );
TheCode = TheCode || "Properties(" || Char( i ) || ", {Line Color (" || Char( i + 3 ) || "),Marker( " || Char( 16 - i ) || ")}),";
);
TheCode = TheCode || "Dispatch( {}, \!"400\!", LegendBox, {Legend Position( {1, [2, 3], 1, [0, 1]} ), Position( {2, 3, 0, 1} )} ))';";
Eval( Parse( TheCode ) );Re: Force Legend with marker and color of row stateThanks Jim
1. I agree it is not a real issue... I can get the list with some work!
2. Maybe I wasn't clear enough. I can easily, as you mention, get the number (N) of item in need to modify in the legend. It means I will need to create N lines in the script making the graphbuilder (I need to dispatch N lines with "legend box(properties(0...N)"). But if I build a graph with N+1 lines in the legend box it will work partly (the N+1th line will not be modified). Thus I need to make a loop either within the script making the graphbuilder (is it feasible?) or after the script making the graphbuilder (it makes more sense, but I am not able to find message(s) I can send to legendbox).
Re: Force Legend with marker and color of row state1. The markers are numbered as can be seen in the chart below. This was generated by a script, as demonstrated int the scripting guide
Help==>Books==>Scripting Guide

Some of the markers have names assigned to them, which you have seen in the Graph Builder script. I don't know of any listing of those name, but you can always interactively run a Graph Builder and assign the marker you want, and then view the script it produced and see if it gives you a name and not just a number.
2. The legend is going to be listed out in alphabetical or numeric order, unless Value ordering or Row Order Level is turned on. Programatically, you can determine that, and then adjust your code. As far as finding out the ages in the data table, the Summarize() function is what I use most of the time
summarize(dt,bygroup = By(:Age));
The variable "bygroup" will have a list of all of the different ages found.
N Items(bygroup);
Gives you the number of different ages found
Re: Force Legend with marker and color of row stateThanks for the quick answer,
1/ It can work provided I have a full set of marker names (I found in the documentation the standards JMP colors). Do you know where I can find something equivalent for marker names?
2/ In that case if colors and markers are written in a dedicated table I am able to modify each line of the legend through an (eval(substitute(expr(graphbuilder(color1,marker1),expr(color1),mycolor, expr(marker1),mymarker))). It works, nice step forward, but I need to know the number of item in the legend in order to make the substitution.
To make it more clear for "big class" file, if the overlay is made with :AGE, and if I don't know the AGE(s) in the file, how can I do?
I could maybe do it in a loop (after the graph builder), if I was able to send a message to the legendbox. But I cannot find in the documentation messages that modify the item...And finally the tree node is "empty" in the legendbox node.
Re: Force Legend with marker and color of row stateThe easiest way that I found for JMP to handle this, is to modify the legend, and therefore the graph using JSL, to match your Row States. Here is a script that shows how to modify the legend in Graph Builder.
Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA\big class.jmp" );
Graph Builder(
Show Control Panel( 0 ),
Variables( X( :height ), Y( :weight ), Overlay( :sex ) ),
Elements( Points( X, Y, Legend( 1 ) ), Smoother( X, Y, Legend( 1 ) ) ),
SendToReport(
Dispatch(
{},
"400",
ScaleBox,
{Legend Model(
1,
Properties( 0, {Marker( "FilledTall" )} ),
Properties( 1, {Line Color( 1 ), Line Style( "Dashed" ), Marker( "Filled Diamond" )} )
), Legend Model(
1,
Properties( 0, {Marker( "FilledTall" )} ),
Properties( 1, {Line Color( 1 ), Line Style( "Dashed" ), Marker( "Filled Diamond" )} )
)}
),
Dispatch( {}, "400", LegendBox, {Legend Position( {1, [2, 3], 1, [0, 1]} ), Position( {2, 3, 0, 1} )} )
)
);
It produces the following
