Maybe something like this
Seemed easier to find the markers on a black background.
// this is an imperfect solution; the added marker color and position is static and
// will not respond to changes. It also depends on the organization of the displayboxes
// in the report.
oldpref = getpreference(Continuous Color Theme( )); // remember the old color pref
setpreference(Continuous Color Theme( "Spectral" )); // set a more obvious color change
bc=open("$sample_data/big class.jmp");
// make a graph with density ellipses for each age
bv = bc<<Bivariate( Y( :height ), X( :weight ) );
bv << group by( age );
bv << density ellipse( .95 );
Report( bv )[framebox( 1 )] << backgroundcolor( "black" ); // see white marker color below
// get the list of reports for each ellipse
ellipseList = bv << xpath( "\[
//OutlineBox[text()[contains(.,'Ellipse')]]
]\" );
// add the mean marker for each report
for( iEllipse = 1, iEllipse <= N Items( ellipseList ), iEllipse += 1,
elOutline = ellipseList[iEllipse]; // outline report for this ellipse
if(jmpversion()>="15",
elname = elOutline << gettitle; // "Bivariate Normal Ellipse P=0.950 age==17"
// that same ellipse name appears above, with a color swatch. get the color.
query = Eval Insert( "//TextEditBox[text()[contains(.,'^elname^')]]" );
// the query is the label to the right of a popup and the color.
// .. moves up to the parent; the CustomBox child holds the color
customBoxColor = bv << xpath( query || "/../CustomBox" );
// extracting the color from the popupbox legend: write to svg
(customboxcolor) << savepicture( "$temp/color.svg", "svg" );
// read the svg text
svgblob = Load Text File( "$temp/color.svg", blob() );
// parse the svg text to a data table, just grab the color
dt = Open( svgblob, invisible, // I uses the XML wizard to generate this code.
XML Settings( Stack( 0 ), Row( "/svg/g/g/g" ), // SVG *is* XML
Col( "/svg/g/g/g/@stroke", Column Name( "color" ), Fill( "Use Once" ), Type( "Character" ), Format( {"Best"} ), Modeling Type( "Continuous" ) )
), XML Wizard( 0 ) );
// the data table's color column (and only row) is the color
elColor = Substr( dt:color[1], 2 ); // "#8E95D5", drop the #
close(dt,nosave); // don't leave the invisible table open
// convert the hex to a JSL color
elColor = rgbcolor(Hex To Number( Substr( elColor, 1, 2 ) ),Hex To Number( Substr( elColor, 3, 2 ) ),Hex To Number( Substr( elColor, 5, 2 ) ));
, // else JMP 14 has no XML
elColor = rgbcolor(1,1,1); // white, opposite of background color, black
);
// next, get the coordinates of the mean
// minimal validation we are looking at the right column...
if( elOutline[NumberColBox(1)]<<getheading!="Mean", throw("missing Mean"));
elLocation = elOutline[NumberColBox(1)]<<get;
// minimal validation that the column order matches the axis order...
columnList = elOutline[StringColBox(1)]<<get; // {"weight", "height"}
axes = bv<<xpath("//AxisBox/*/*/TextEditBox");
{yaxis,xaxis}=axes<<gettext; // {"height", "weight"}
if(columnList[1]!=xaxis | columnList[2]!=yaxis, throw("missing Cols"));
// Finally! add a snippet of script to plot the point elLocation using elColor
// Fortunately, elLocation, from the means col, is in x,y order
//
// eval(evalexpr( ... expr() ... )) captures the current value of expr into the
// graphic script, otherwise elColor and elLocation would be the final value
// for all the added markers.
eval(evalexpr(report(bv)[framebox(1)]<<Add Graphics Script(
marker(
combinestates(
selectedstate(1), // makes the marker darker
colorstate(expr(elColor)), // you might prefer black
markerstate(1) // the + marker
),
expr(elLocation)
)
)))
);
eval(oldpref); // restore your old preference
Links:
xpath: JMP Discovery 2015 - Mining JMP Reports - v10.pdf and this one
ellipse: Ellipse
XML: Open an RSS Feed in JMP , Contour Plot Areas , Currency Exchange Rates , SQL for Cord-Cutters
Craige