cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Have your say in shaping JMP's future by participating in the new JMP Wish List Prioritization Survey
Choose Language Hide Translation Bar
SpannerHead
Level III

Automatic Scaling Matching X and Y Axes

Solved: Re: Automatically plot associated columns - JMP User Community

 

As a follow on to the discussion above, I would like to automate the scaling of some plots to be symmetric about the zero value on both the X and Y axes.

 

I'd like to have this

Autoscale 1.png

automatically output as this.

Autoscale 2.png

The code that got me here is included in the link above

 

Slán

 

SpannerHead

1 ACCEPTED SOLUTION

Accepted Solutions
jthi
Super User

Re: Automatic Scaling Matching X and Y Axes

Calculate max values (of absolute values), take negative of that and set the values might be one option. You can also calculate the values from data table using Col Max() / Col Min() or Summarize

 

Names Default To Here(1); 

dt = open("$SAMPLE_DATA/Big Class.jmp");

biv = dt << Bivariate(Y(:height), X(:weight));

ms = Report(biv)[FrameBox(1)] << Find Seg(Marker Seg(1));

xs = ms << Get X Values;
ys = ms << Get Y Values;

val = Max(Max(Abs(xs)), Max(Abs(ys)));

xaxis = Report(biv)[AxisBox(1)];
yaxis = Report(biv)[AxisBox(2)];

xaxis << Min(-1*val) << Max(val);
yaxis << Min(-1*val) << Max(val);

 

 

-Jarmo

View solution in original post

8 REPLIES 8
jthi
Super User

Re: Automatic Scaling Matching X and Y Axes

Calculate max values (of absolute values), take negative of that and set the values might be one option. You can also calculate the values from data table using Col Max() / Col Min() or Summarize

 

Names Default To Here(1); 

dt = open("$SAMPLE_DATA/Big Class.jmp");

biv = dt << Bivariate(Y(:height), X(:weight));

ms = Report(biv)[FrameBox(1)] << Find Seg(Marker Seg(1));

xs = ms << Get X Values;
ys = ms << Get Y Values;

val = Max(Max(Abs(xs)), Max(Abs(ys)));

xaxis = Report(biv)[AxisBox(1)];
yaxis = Report(biv)[AxisBox(2)];

xaxis << Min(-1*val) << Max(val);
yaxis << Min(-1*val) << Max(val);

 

 

-Jarmo
SpannerHead
Level III

Re: Automatic Scaling Matching X and Y Axes

Epic!  Works like a charm.

SpannerHead
Level III

Re: Automatic Scaling Matching X and Y Axes

There is one small thing that I came to realise.  In some instances, one of the ys or xs matrices has missing values because it has been given a missing value code.  The partner matrix values may not be missing and can be included to set the scales.  Is there a way to eliminate values from ys if the row is marked as missing for xs with the same elimination of xs occurring when ys is a missing value.

 

Slán

 

SpannerHead

jthi
Super User

Re: Automatic Scaling Matching X and Y Axes

What does "marked as missing" mean in this case?

 

If you wish to keep the other value, I think that should still work even if the matrices have missing values.

jthi_0-1717650622005.png

 

-Jarmo
SpannerHead
Level III

Re: Automatic Scaling Matching X and Y Axes

I have a lot of error codes that are numeric to preserve the data type for the column.  I need to turn a blind eye to those in the analysis.  However, if either X or Y are marked with a missing value code and the partner is not, the scales can be set by data that is not actually plotted on the graph

 

SpannerHead_0-1717772943135.png

Thanks for the great help.

 

Slán

 

SpannerHead

 

jthi
Super User

Re: Automatic Scaling Matching X and Y Axes

As you know the columns you are using, you can use Col Min + Col Max to get the minimum and maximum values (they should respect Missing Value Codes). Then use combination of your values, Abs() function and Max() function to get your value to use for x and y axis

Names Default To Here(1); 

dt = Open("$SAMPLE_DATA/Big Class.jmp");

show(Col Max(Column(dt, "height")));
Column(dt, "height") << Set Property("Missing Value Codes", {70, 69, 68});
show(Col Max(Column(dt, "height")));

but I also think that Bivariate shouldn't plot those points at all if they have been ignored by Missing Value Codes

Names Default To Here(1); 

dt = Open("$SAMPLE_DATA/Big Class.jmp");

biv = dt << Bivariate(Y(:height), X(:weight));
ms = Report(biv)[FrameBox(1)] << Find Seg(Marker Seg(1));
xs = ms << Get X Values;
ys = ms << Get Y Values;
val1 = Max(Max(Abs(xs)), Max(Abs(ys)));
biv << close window;

Column(dt, "weight") << Set Property("Missing Value Codes", {172});
biv = dt << Bivariate(Y(:height), X(:weight));
ms = Report(biv)[FrameBox(1)] << Find Seg(Marker Seg(1));
xs = ms << Get X Values;
ys = ms << Get Y Values;
val2 = Max(Max(Abs(xs)), Max(Abs(ys)));

show(val1, val2);
-Jarmo
SpannerHead
Level III

Re: Automatic Scaling Matching X and Y Axes

Thanks and you are right with what you say, I think I'm not expressing the question properly.  Missing values in X are ignored when figuring out the maximum of X.  The partner Y values on the same row are not missing and therefore not ignored.  I should clarify that I'm iterating through columns in a data table and automatically plotting metrics that are connected.

 

 

This script might pick a voltage threshold and plot it against the respective current value if that gets selected.  When this rescales at the end a missing value in X for example will cause there to be no data point on the graph, however, the partner Y value could still set the scale of the graph.

 

To ensure the plot contains the 100 value on both axed, I did modify the matrix to include 110 with |/110;

 

Slán

 

Spannerhead

 

dt = Current Data Table();
dt << Clear Column Selection();
colList = dt << get column names( string );
check_list = {"VTX", "VTN", "VTP", "VTF", "IDS", "IBB", "ILK", "CMI"};
New Window( "Select Variables",
	<<Type( "Modal Dialog" ),
	<<On Validate( window:validated ),
	window:enable function = Function( {},
		{Default Local},
		X = window:lbMajor << Get Selected;
		Y = window:lbMinor << Get Selected;
		If( N Items( X ) & N Items( Y ) & X != Y,
			window:validated = 1,
			window:validated = 0
		);
		window:ok button << Enable( window:validated );
	);
	H List Box(
		V List Box(
			Text Box( "Select X Variable" ),
			window:lbMajor = List Box(
				check_list,
				<<Set Max Selected( 1 ),
				enable function
			)
		),
		V List Box(
			Text Box( "Select Y Variable" ),
			window:lbMinor = List Box(
				check_list,
				<<Set Max Selected( 1 ),
				enable function
			)
		)
	);,
	H List Box(
		window:ok button = Button Box( "OK",
			X = window:lbMajor << Get Selected;
			Y = window:lbMinor << Get Selected;
			If( N Items( X ) & N Items( Y ) & X != Y,
				window:validated = 1,
				window:validated = 0
			);
			If( window:validated,
				Print( "Processing with X: " || Char( X ) || ", Y: " || Char( Y ) );
				Window( "Select Variables" ) << Close Window;
			,
				Beep();
				Show( "Invalid Selection" );
				{window:lbMajor, window:lbMinor} << Select;
				window:lbMajor << Inval << Update Window;
				Wait( 0.25 );
				{window:lbMajor, window:lbMinor} << DeSelect;
				window:lbMajor << Inval << Update Window;
				Wait( 0.25 );
				{window:lbMajor, window:lbMinor} << Select;
				window:lbMajor << Inval << Update Window;
				Wait( 0.25 );
				{window:lbMajor, window:lbMinor} << DeSelect;
				window:lbMajor << Inval << Update Window;
			);,
			<<Enable( 0 )
		),
		Button Box( "Cancel", Throw( "!Canceled Analysis" ) )
	)
);
If(
	X[1] == "VTX", Xparam = "VTX",
	X[1] == "VTN", Xparam = "VTN",
	X[1] == "VTP", Xparam = "VTP",
	X[1] == "IDS", Xparam = "IDS",
	X[1] == "IBB", Xparam = "IBB",
	X[1] == "VTF", Xparam = "VTF",
	X[1] == "ILK", Xparam = "ILK",
	X[1] == "CMI", Xparam = "CMI"
);
If(
	Y[1] == "VTX", Yparam = "VTX",
	Y[1] == "VTN", Yparam = "VTN",
	Y[1] == "VTP", Yparam = "VTP",
	Y[1] == "IDS", Yparam = "IDS",
	Y[1] == "IBB", Yparam = "IBB",
	Y[1] == "VTF", Yparam = "VTF",
	Y[1] == "ILK", Yparam = "ILK",
	Y[1] == "CMI", Yparam = "CMI"
);
Show( Xparam );
Show( Yparam );
For( i = 1, i <= N Cols( dt ), i++,
	If(
		Contains( Munger( Head Name( As Namespace( colList[i] ) ), 0, 3 ), Xparam )
		 & Contains(
			Head Name( As Namespace( colList[i] ) ),
			"% Delta From Target"
		),
		Column( colList[i] ) << Set Selected( 1 )
	)
);
target = dt << get selected columns();
found_list = {};
Show( target );
New Window( "Compilation",
	For( j = 1, j <= N Items( target ), j++,
		If(
			Contains(
				Munger( Head Name( As Namespace( target[j] ) ), 0, 3 ),
				Xparam
			),
			Connected = Substitute( Head Name( As Namespace( target[j] ) ),
				Xparam, Yparam
			);
			Insert Into( found_list, Connected );
			Try(
				biv = Bivariate(
					Y( Column( dt, found_list[j] ) ),
					X( Column( dt, target[j] ) ),
					Automatic Recalc( 1 ),
					SendToReport(
						Dispatch(
							{},
							"Bivar Plot",
							FrameBox,
							{Frame Size( 470, 470 ),
							Add Graphics Script(
								2,
								Description( "" ),
								Transparency( 0.5 );
								Pen Color( "Red" );
								Fill Color( "Red" );
								Oval( -100, -100, 100, 100, 1 );
								Pen Color( "Green" );
								Fill Color( "Green" );
								Oval( -90, -90, 90, 90, 1 );
								Pen Color( "Blue" );
								Fill Color( "Blue" );
								Oval( -80, -80, 80, 80, 1 );
								Pen Color( "Black" );
								Line( [-110 0 110], [0 0 0] );
								Line( [0 0 0], [-110 0 110] );
							)}
						)
					)
				);
				ms = Report( biv )[FrameBox( 1 )] << Find Seg( Marker Seg( 1 ) );
				xs = ms << Get X Values|/110;
				Show(xs);
				ys = ms << Get Y Values|/110;
				Show(ys);
				val = Max( Max( Abs( xs ) ), Max( Abs( ys ) ) );
				xaxis = Report( biv )[AxisBox( 1 )];
				yaxis = Report( biv )[AxisBox( 2 )];
				xaxis << Min( -1 * val ) << Max( val );
				yaxis << Min( -1 * val ) << Max( val );
			);
		)
	)
);
jthi
Super User

Re: Automatic Scaling Matching X and Y Axes

One option is to use some matrices to check for "valid" rows, get values only from those and then calculate max as before.

Names Default To Here(1); 

dt = Open("$SAMPLE_DATA/Big Class.jmp");

Column(dt, "height") << Set Property("Missing Value Codes", {70, 69, 68});
Column(dt, "weight") << Set Property("Missing Value Codes", {172});

m1 = Column(dt, "height") << get values;
m2 = Column(dt, "weight") << get values;

valid_rows = Loc(V Sum(Is Missing(m1 || m2)`), 0);

val = Max(Abs(dt[valid_rows, "weight"] |/ dt[valid_rows, "height"]));
-Jarmo