Subscribe Bookmark RSS Feed

How to change the color of curves based on condition on the data

samir

Community Trekker

Joined:

May 20, 2016

Hello,

I am trying to color curves in a specific way and I do not find a way...

Basically, I have a couple of curves that are grouped by a label. How can I display all the curves with a different color for each group ?

So far, I tried in Graph Builder putting the "label" put in the "overlay" part...But like that JMP considers all the curves of a group like being ONE curve.

I tried a more advanced thing using JSL (find the code below). I was able to generate the curves and access the different lines and color them independently, but I lose the link between the lines and the label.

In the example below: how can I get all the curves of Honda in red, those of Ford in Blue, and those of GM in purple ? (this assuming of course that I do not know a priori how many curves are in each group, and not how many groups there are).

Any ideas ?

// Generate a simple table as example
dt = New Table( "Untitled 9050",
	Add Rows( 33 ),
	New Column( "Time [years]",
		Numeric,
		Continuous,
		Format( "Best", 2 ),
		Set Values(
			[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0,
			1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
		)
	),
	New Column( "car1",
		Numeric,
		Continuous,
		Format( "Best", 12 ),
		Set Values(
			[0, 0.8, 1.6, 2.4, 3.2, 4, 4.8, 5.6, 6.4, 7.2, 8, 0, 1.2, 2.4, 3.6, 4.8,
			6, 7.2, 8.4, 9.6, 10.8, 12, 0, 2.2, 4.4, 6.6, 8.8, 11, 13.2, 15.4, 17.6,
			19.8, 22]
		)
	),
	New Column( "car2",
		Numeric,
		Continuous,
		Format( "Best", 12 ),
		Set Selected,
		Set Values(
			[0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 0, 1.4, 2.8, 4.2, 5.6, 7,
			8.4, 9.8, 11.2, 12.6, 14, 0, 2.4, 4.8, 7.2, 9.6, 12, 14.4, 16.8, 19.2,
			21.6, 24]
		)
	),
	New Column( "car3",
		Numeric,
		Continuous,
		Format( "Best", 12 ),
		Set Values(
			[0, 0.6, 1.2, 1.8, 2.4, 3, 3.6, 4.2, 4.8, 5.4, 6, 0, 1.6, 3.2, 4.8, 6.4,
			8, 9.6, 11.2, 12.8, 14.4, 16, 0, 2.6, 5.2, 7.8, 10.4, 13, 15.6, 18.2,
			20.8, 23.4, 26]
		)
	),
	New Column( "car4",
		Numeric,
		Continuous,
		Format( "Best", 12 ),
		Set Values(
			[0, 0.4, 0.8, 1.2, 1.6, 2, 2.4, 2.8, 3.2, 3.6, 4, 0, 1.8, 3.6, 5.4, 7.2,
			9, 10.8, 12.6, 14.4, 16.2, 18, 0, 2.8, 5.6, 8.4, 11.2, 14, 16.8, 19.6,
			22.4, 25.2, 28]
		)
	),
	New Column( "Manufacturer",
		Character( 16 ),
		Nominal,
		Set Values(
			{"Honda", "Honda", "Honda", "Honda", "Honda", "Honda", "Honda", "Honda",
			"Honda", "Honda", "Honda", "Ford", "Ford", "Ford", "Ford", "Ford",
			"Ford", "Ford", "Ford", "Ford", "Ford", "Ford", "GM", "GM", "GM", "GM",
			"GM", "GM", "GM", "GM", "GM", "GM", "GM"}
		)
	)
);

// stack the table
dt_Stack = dt << Stack(
	columns( :car1, :car2, :car3, :car4 ),
	Source Label Column( "Label" ),
	Stacked Data Column( "Data" )
);

// Create a graph
MyGraph = Graph Builder(
	Variables( X( :Name( "Time [years]" ) ), Y( :Data ), Overlay( :Label ) ),
	Elements(
		Points( X, Y, Legend( 1 ), Jitter( 1 ) ),
		Smoother( X, Y, Legend( 2 ) )
	)
);

// Access the lines and their properties
GraphsRep = Report( MyGraph );
nbp = GraphsRep[FrameBox( 1 )] << segCount( "LineSeg" );
// Modify the lines colors
For( n = 1, n <= nbp, n++,
	s = GraphsRep[FrameBox( 1 )] << FindSeg( LineSeg( n ) );
	s << Line Color( "Black" );
			);
2 ACCEPTED SOLUTIONS

Accepted Solutions
ih

Community Trekker

Joined:

Sep 30, 2016

Solution

Four points:

 

Scripting

@XanGregg is probably right that what you really want is some group of plots created or modified using JSL instead of one big chart. Below are two things to try though.

 

Plotting Lines

I am having a hard time picturing the graph you want to create, it sounds like a lot of lines on one chart and a page-long legend. Using the pivoted data, the top chart in the script below creates lines for each car colored by manufacturer.  With only 5 lines styles to work with you can not be identify the car type in the legend using anything but color.  Maybe you could use this chart to identify the manufacturer of the car and then a second chart that is grouped or wrapped by manufacture and then colored by car? That is the bottom chart in this script, note you can click on a line and see it identified in the bottom chart.

 

//Start with the long table in your first post.
New Window("Two Graphs", Graph Builder( Size( 600, 400 ), Show Control Panel( 0 ), Variables( X( :Name( "Time [years]" ) ), Y( :Data ), Overlay( :Name( "Man-Car" ) ), Color( :Manufacturer ) ), Elements( Line( X, Y, Legend( 20 ) ) ), SendToReport( Dispatch( {}, "Time [years]", ScaleBox, {Label Row( Show Major Grid( 1 ) )} ), Dispatch( {}, "Data", ScaleBox, {Label Row( Show Major Grid( 1 ) )} ) ) ), Graph Builder( Size( 604, 448 ), Show Control Panel( 0 ), Variables( X( :Name( "Time [years]" ) ), Y( :Data ), Wrap( :Manufacturer ), Overlay( :Label ) ), Elements( Line( X, Y, Legend( 20 ) ) ), SendToReport( Dispatch( {}, "Time [years]", ScaleBox, {Label Row( Show Major Grid( 1 ) )} ), Dispatch( {}, "Data", ScaleBox, {Label Row( Show Major Grid( 1 ) )} ) ) ) )

 

 

Legend

To make the legend show the manufacturer and car together create a column that concatenates the manufacturer name with the car name.  For example:

 

New Column( "Man:Car",
	Character,
	"Nominal",
	Formula( :Manufacturer || " " || :Label ),
	Set Selected,
	Set Display Width( 108 )
)

 

Plot Points Instead

Another idea: Instead of trying to display that many lines, could you instead summarize each curve into whatever you are actually trying to visualize?  For the [i assume] simplified line example, you could plot individual points for each car showing the slope and intercept.  Two thousand points on a chart are easier to interpret than 2000 lines. At some point I still give up on the legend though).  Here I started with the long table and did a fit model 'by' the Man-Car column created above, then saved the estimates table as a combined table, split the table by term, then graphed:

 

summarized chart.png

samir

Community Trekker

Joined:

May 20, 2016

Solution

Hello ih,

Among your options, the solution called "plotting lines" is perfect and exactly what I wanted !!!

It is even excellent because it does not envolve complex scripting !

So basically, you propose to:

  1. add a column "Manufacturer-Car"
  2. Use this column as Overlay
  3. Color by manufacturer

And the result is perfect (I nerver really understood how the Overlay and color could be combined, now I see an example):

Graph Builder.png

 

5 REPLIES
ih

Community Trekker

Joined:

Sep 30, 2016

Are you looking for a separate curve or line for each car? If so, using your unpivoted data table, you could display all four cars on the y axis and then overlay manufacturer:

 

Graph Builder(
	Size( 528, 454 ),
	Show Control Panel( 0 ),
	Variables(
		X( :Name( "Time [years]" ) ),
		Y( :car1 ),
		Y( :car2, Position( 1 ) ),
		Y( :car3, Position( 1 ) ),
		Y( :car4, Position( 1 ) ),
		Overlay( :Manufacturer )
	),
	Elements( Line( X, Y( 1 ), Y( 2 ), Y( 3 ), Y( 4 ), Legend( 7 ) ) )
);
samir

Community Trekker

Joined:

May 20, 2016

That is pretty much what I wanted to do, except that in your solution, I need to know upfront how many "cars" are available and put them manually: suppose I have 2000 cars and not 4 as in the example :(

besides, what if I do not want a different line style per car ?

And if I just want a legend that mentions the manufacturer and not the manufacturer + car ? (to simplify the legend).

All in all, your solution is definitely interesting, but I need more control and automation.

Thanks.

XanGregg

Staff

Joined:

Jun 23, 2011

A good technique is to make a small graph like you want, save the script, and then use that script as a pattern to make an automated graph, possibly with more variables.

 

So start with @ih's graph and customize the legend interactively to change the line styles and item names. Save the script for that graphs to use as a template for a more elaborate one. You'll be writing a script that writes another script and then runs it. 

ih

Community Trekker

Joined:

Sep 30, 2016

Solution

Four points:

 

Scripting

@XanGregg is probably right that what you really want is some group of plots created or modified using JSL instead of one big chart. Below are two things to try though.

 

Plotting Lines

I am having a hard time picturing the graph you want to create, it sounds like a lot of lines on one chart and a page-long legend. Using the pivoted data, the top chart in the script below creates lines for each car colored by manufacturer.  With only 5 lines styles to work with you can not be identify the car type in the legend using anything but color.  Maybe you could use this chart to identify the manufacturer of the car and then a second chart that is grouped or wrapped by manufacture and then colored by car? That is the bottom chart in this script, note you can click on a line and see it identified in the bottom chart.

 

//Start with the long table in your first post.
New Window("Two Graphs", Graph Builder( Size( 600, 400 ), Show Control Panel( 0 ), Variables( X( :Name( "Time [years]" ) ), Y( :Data ), Overlay( :Name( "Man-Car" ) ), Color( :Manufacturer ) ), Elements( Line( X, Y, Legend( 20 ) ) ), SendToReport( Dispatch( {}, "Time [years]", ScaleBox, {Label Row( Show Major Grid( 1 ) )} ), Dispatch( {}, "Data", ScaleBox, {Label Row( Show Major Grid( 1 ) )} ) ) ), Graph Builder( Size( 604, 448 ), Show Control Panel( 0 ), Variables( X( :Name( "Time [years]" ) ), Y( :Data ), Wrap( :Manufacturer ), Overlay( :Label ) ), Elements( Line( X, Y, Legend( 20 ) ) ), SendToReport( Dispatch( {}, "Time [years]", ScaleBox, {Label Row( Show Major Grid( 1 ) )} ), Dispatch( {}, "Data", ScaleBox, {Label Row( Show Major Grid( 1 ) )} ) ) ) )

 

 

Legend

To make the legend show the manufacturer and car together create a column that concatenates the manufacturer name with the car name.  For example:

 

New Column( "Man:Car",
	Character,
	"Nominal",
	Formula( :Manufacturer || " " || :Label ),
	Set Selected,
	Set Display Width( 108 )
)

 

Plot Points Instead

Another idea: Instead of trying to display that many lines, could you instead summarize each curve into whatever you are actually trying to visualize?  For the [i assume] simplified line example, you could plot individual points for each car showing the slope and intercept.  Two thousand points on a chart are easier to interpret than 2000 lines. At some point I still give up on the legend though).  Here I started with the long table and did a fit model 'by' the Man-Car column created above, then saved the estimates table as a combined table, split the table by term, then graphed:

 

summarized chart.png

samir

Community Trekker

Joined:

May 20, 2016

Solution

Hello ih,

Among your options, the solution called "plotting lines" is perfect and exactly what I wanted !!!

It is even excellent because it does not envolve complex scripting !

So basically, you propose to:

  1. add a column "Manufacturer-Car"
  2. Use this column as Overlay
  3. Color by manufacturer

And the result is perfect (I nerver really understood how the Overlay and color could be combined, now I see an example):

Graph Builder.png