cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Choose Language Hide Translation Bar
echava
Level I

How to add mean of coordinates in bivariate plot, aka plotting Centroids

I have a series of coordinates with two types of rows. Data is in three columns: Column1(x-coordinates), Column2 (y-coordinates), and Type.

After I plot them in a bivariate analysis and draw an ellipse around both groups of coordinates, I'd like to have a marker added to the center of each group marking the centroid of each group of coordinates. The marker should, preferably, match the color determined by column "Type".

 

I can see the values I need in the Statistics below the plot, it's the Mean of Column1 and the Mean of Column2 for each group but I don't know how to add those to the plot using colored markers . For the image below I added manually two "+" as text but it becomes a pain when I need to try with multiple groups for a number of times.

 

Centroids.jpg

4 REPLIES 4

Re: How to add mean of coordinates in bivariate plot, aka plotting Centroids

Simply add the coordinates and type for the centroids as two new rows in the data table. Change their row states to Excluded, red or blue color, and "+" marker.

echava
Level I

Re: How to add mean of coordinates in bivariate plot, aka plotting Centroids

However this is a simple example for my need. Regularly I would have tens of centroids that need to be added to the visualization. In my real analyses it becomes painful too quickly due to the number of possible categories for which I need the centroids plotted.

 

Maybe there's a way to add such coordinates without manually adding rows to my table.

Is there a way to graph the Mean values calculated by Type analysis avoiding manual plotting?

 

Or maybe even in Graph Builder, it doesn't matter, as long as it avoids manual addition of rows (markers).

echava
Level I

Re: How to add mean of coordinates in bivariate plot, aka plotting Centroids

In my mind it looks something like this:

 

Marker Size( 6 );
Marker(
	1,
	{Col Mean( :Column 1, :Type == "Type1" ),
	Col Mean( :Column 2, :Type == "Type1" )}
);
Marker(
	1,
	{Col Mean( :Column 1, :Type == "Type2" ),
	Col Mean( :Column 2, :Type == "Type2" )}
);

 

However that solution still requires adding one marker per group.

Is there a way I could add all markers for all groups included in column "Type"?

How to keep using the same color theme that is used in the analysis?

Craige_Hales
Super User

Re: How to add mean of coordinates in bivariate plot, aka plotting Centroids

Maybe something like this

Seemed easier to find the markers on a black background.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