cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
  • Sign-in to the JMP Community will be unavailable intermittently Dec. 6-7 due to a system update. Thank you for your understanding!
  • We’re retiring the File Exchange at the end of this year. The JMP Marketplace is now your destination for add-ins and extensions.
  • JMP 19 is here! Learn more about the new features.

Discussions

Solve problems, and share tips and tricks with other JMP users.
Choose Language Hide Translation Bar
ankitgssingh
Level III

Making a Bivariate chart with group by column with unknow number of categories ?

Hello All

 

I have a big list of columns which I loop through to create a Bivariate chart each of every column in my column list. My x-axis remains the same every time. 

I am grouping by the same categorical column as well. But the number of groups/categories in that column changes everytime. 

How can I use the "Fit Where" function in the bivariate plot so see all categories in one graph for each column when I dont know how many categories would be there? 

 

Generally I do this to create what I want, 

Names Default To Here( 1 );

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


bivNew = dt << Bivariate(
	Y( :Fish Caught ),
	X( :People ),
	Automatic Recalc( 1 ),
	Fit Where( :Validation == 1, Fit Spline( 1, {Line Color( {212, 73, 88} )} ) ),
	Fit Where( :Validation == 2, Fit Spline( 1, {Line Color( {66, 112, 221} )} ) )
);

But in this I have hard coded the grouping (Fit Where) for each category in the Validation column. How can I get the same output if I dont know how many categories are there in the Validation column in terms of scripting a automated solution . 

 

Any help would be appreciated. 

 

1 ACCEPTED SOLUTION

Accepted Solutions
ErraticAttack
Level VI

Re: Making a Bivariate chart with group by column with unknow number of categories ?

Here is one method that can work -- I personally do not use JMP's built-in splines as it creates too much visual clutter with the added control boxes.

 

Names Default To Here( 1 );

dt = Open( "$SAMPLE_DATA/Fishing.jmp" );
Try( dt << Delete Columns( "GROUPING" ) );
dt << New Column( "GROUPING", "Character",
	<<Set Each Value( {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J"}[Random Integer( 1, 10 )] )
);


bivNew = Expr( Bivariate(
	Y( :Fish Caught ),
	X( :People ),
	Automatic Recalc( 1 )
) );

categories = Associative Array( dt:GROUPING ) << Get Keys;
Summation( i = 1, N Items( categories ),
	Insert Into( bivNew,
		Eval Expr(
			Fit Where( :GROUPING == Expr( categories[i] ), Fit Spline( 1, Standardized ) )
		)
	)
);

Eval( Eval Expr(
	Send( dt, Expr( Name Expr( bivNew ) ) )
) )
Jordan

View solution in original post

4 REPLIES 4
ErraticAttack
Level VI

Re: Making a Bivariate chart with group by column with unknow number of categories ?

Here is one method that can work -- I personally do not use JMP's built-in splines as it creates too much visual clutter with the added control boxes.

 

Names Default To Here( 1 );

dt = Open( "$SAMPLE_DATA/Fishing.jmp" );
Try( dt << Delete Columns( "GROUPING" ) );
dt << New Column( "GROUPING", "Character",
	<<Set Each Value( {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J"}[Random Integer( 1, 10 )] )
);


bivNew = Expr( Bivariate(
	Y( :Fish Caught ),
	X( :People ),
	Automatic Recalc( 1 )
) );

categories = Associative Array( dt:GROUPING ) << Get Keys;
Summation( i = 1, N Items( categories ),
	Insert Into( bivNew,
		Eval Expr(
			Fit Where( :GROUPING == Expr( categories[i] ), Fit Spline( 1, Standardized ) )
		)
	)
);

Eval( Eval Expr(
	Send( dt, Expr( Name Expr( bivNew ) ) )
) )
Jordan
ankitgssingh
Level III

Re: Making a Bivariate chart with group by column with unknow number of categories ?

Thank you for the quick answer. Solved my problem.

 

Which splines do you generally prefer for your JMP bivar/graph plots in general? I don't need those additional control boxes as well but I am not able to find better/clear looking splines ? 

ErraticAttack
Level VI

Re: Making a Bivariate chart with group by column with unknow number of categories ?

There are many ways to do this, but one simple way is with a small namespace that holds the relevant functions:

 

Here is the library that holds the functions / default settings:

New Namespace( "bivar" );

bivar:default settings = [=>];
bivar:default settings["x size"] = 600;
bivar:default settings["y size"] = 400;
bivar:default settings["lambda"] = 1;
bivar:default settings["standardize splines"] = 1;
bivar:default settings["unselected line width"] = 4;
bivar:default settings["line width"] = 4;
bivar:default settings["selected line width"] = 5;
bivar:default settings["marker size"] = 4;
bivar:default settings["outline lines"] = 1;
bivar:default settings["fade unselected lines"] = 1;
bivar:default settings["spline points"] = 128;


//this is the only function that a user needs to call bivar:plot = Function( {table, x column, y column, categorical column, title = "", settings = bivar:default settings}, {Default Local}, columns = table << Get Column Names(); If( Not( Contains( columns, As Name( x column ) ) ), Throw( "Unable to find column \!"" || x column || "\!"" ); ); If( Not( Contains( columns, As Name( y column ) ) ), Throw( "Unable to find column \!"" || y column || "\!"" ); ); If( Not( Contains( columns, As Name( categorical column ) ) ), Throw( "Unable to find column \!"" || categorical column || "\!"" ); ); If( Column( table, x column ) << Get Data Type != "Numeric", Throw( "X column must be Numeric" ); ); If( Column( table, y column ) << Get Data Type != "Numeric", Throw( "Y column must be Numeric" ); ); If( Column( table, categorical column ) << Get Data Type != "Character", Throw( "Legend column must be Character" ); ); table << Color or Mark by Column( categorical column ); olb = Outline Box( "", Platform( table, Bivariate( X( Column( table, x column ) ), Y( Column( table, y column ) ), Dispatch( {}, "Bivar Plot", Frame Box, { Frame Size( settings["x size"], settings["y size"] ), Marker Size( settings["marker size"] ) , Row Legend( Column( table, categorical column ), Marker( 1 ), Continuous Scale( 0 ), Reverse Scale( 0 ), Excluded Rows( 0 ) ) } ) ) ) ); If( title != "", olb[Outline Box( 2 )] << Set Title( title ) ); bivar:add splines( table, olb[Frame Box( 1 )], olb[String Col Box( 1 )], x column, y column, categorical column, settings ); olb ); bivar:add splines = Function( {table, frame box, legend box, x column, y column, categorical column, settings = bivar:default settings}, {Default Local}, sub table = table << Summary( Group( categorical column ), Link to Original Data Table( 0 ), Private ); colors = [=>]; For Each Row( sub table, colors[Column( 1 )[]] = Color Of( Row State() ) ); legend values = Column( sub table, 1 ) << Get Values; Close( sub table, No Save ); splines = [=>]; splines["__items__"] = legend values; splines["__settings__"] = settings; splines["__colors__"] = colors; Summation( i = 1, N Items( legend values ), item = legend values[i]; splines[item] = [=>]; Eval( Parse( Eval Insert( JSL Quote( rows = table << Get Rows Where( !Excluded( Row State() ) & :Name("^categorical column^") == "^item^" & !Is Missing( :Name("^x column^") ) & !Is Missing( :Name("^y column^") ) ) ) ) ) ); ordinate = Column( table, y column )[rows]; abcissa = Column( table, x column )[rows]; If( N Rows( rows ) > 3 & Min( abcissa ) != Max( abcissa ), If( settings["standardize splines"], x mean = Mean( abcissa ); x std dev = Std Dev( abcissa ); abcissa = (abcissa - x mean) / x std dev ); x values = Min( abcissa )::Max( abcissa )::((Max( abcissa ) - Min( abcissa )) / settings["spline points"]); spline values = Spline Eval( x values, Spline Coef( abcissa, ordinate, settings["lambda"] ) ); If( settings["standardize splines"], x values = x std dev * x values + x mean ); , x values = abcissa; spline values = ordinate ); splines[item]["x"] = x values; splines[item]["y"] = spline values; ;0 ); Eval( Eval Expr( frame box << Add Graphics Script( "CUSTOM_SPLINES"; Local( {splines = Expr( splines ), legend = Expr( legend box ), settings = Expr( settings ), selected, i, items, item, selected items}, selected = legend << Get Selected Rows; If( N Rows( selected ) == 0, Summation( i = 1, N Items( splines["__items__"] ), item = splines["__items__"][i]; Transparency( 1 ); If( splines["__settings__"]["outline lines"], Pen Color( "Black" ); Pen Size( splines["__settings__"]["line width"] + 1 ); Line( splines[item]["x"], splines[item]["y"] ) ); Pen Color( splines["__colors__"][item] ); Pen Size( splines["__settings__"]["line width"] ); Line( splines[item]["x"], splines[item]["y"] ); ;0 ) , selected items = splines["__items__"][selected]; Summation( i = 1, N Items( splines["__items__"] ), item = splines["__items__"][i]; If( Not( Contains( selected items, item ) ), If( settings["fade unselected lines"], Transparency( 1 - Arg( Arg( Get Preferences( Graph Marker Unselected Fade ), 1 ), 1 ) / 100 ) , Transparency( 1 ) ); Pen Color( splines["__colors__"][item] ); Pen Size( splines["__settings__"]["unselected line width"] ); Line( splines[item]["x"], splines[item]["y"] ); ); ;0 ); Summation( i = 1, N Items( splines["__items__"] ), item = splines["__items__"][i]; If( Contains( selected items, item ), Transparency( 1 ); If( splines["__settings__"]["outline lines"], Pen Color( "Black" ); Pen Size( splines["__settings__"]["selected line width"] + 1 ); Line( splines[item]["x"], splines[item]["y"] ) ); Pen Color( splines["__colors__"][item] ); Pen Size( splines["__settings__"]["selected line width"] ); Line( splines[item]["x"], splines[item]["y"] ); ); ;0 ) ); items = splines["__items__"] ) ) ) ) ); 0

After the library has executed at least once (add it to the start script of an addin, for example), then you can make use of it very easily:

Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
dt2 = Open( "$SAMPLE_DATA/Reliability/Adhesive Bond.jmp" );
dt3 = Open( "$SAMPLE_DATA/Cars.jmp" );

settings = bivar:default settings;
settings["outline lines"] = 0;

New Window( "test",
	V List Box(
		bivar:plot( dt3, "year", "wt", "make" )
	,
		bivar:plot( dt3, "year", "wt", "make", "Custom Title", settings ) // show how to change settings
	,
		bivar:plot( dt, "Height", "weight", "sex" )
	,
		bivar:plot( dt2, "weeks", "strength", "censor" )
	)
)

Now there are no annoying control boxes and I've made it match the selection mode of the markers (assuming you've got the "Unselected Faded" Marker Selection Mode)

 

ErraticAttack_0-1663264415596.png

 

Hope this helps.

Jordan
ankitgssingh
Level III

Re: Making a Bivariate chart with group by column with unknow number of categories ?

Thanks a lot for this. Indeed very useful. 

 

However, this function seems to work for a single x and y column and not when I pass a list of y columns with the same x and grouping column. Would need to update it to work for group of columns. 

 

Thanks again for the help on this. 

Recommended Articles