cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Browse apps to extend the software in the new JMP Marketplace
Choose Language Hide Translation Bar
JulieSAppel
Level IV

Multiple reference lines on x-axis

Hi,

 

For a project I´m working on I have created a graph with time on the x-axis which shows a period of approx 24 hours. To visually illustrate when it is night time and day time I have added reference lines as shown in the below script and attached image.

 

Properties for x-axis column:

SableData << New Column(
	"Time since first dose-[hours]", 
	Numeric, "Continuous", 
	Format("Best", 12), 
	Formula((:Date Time - :StartTime) / (60 * 60)),
	Set Property("Spec Limits", {LSL(8), USL(20), Show Limits(0)}), Set Selected);	

Creating graph, adding and configuring ref lines:

Oxygen consumption = SableData << Graph Builder(
	Size( 1007, 689 ),
	Variables(
		X( :Name( "Time since first dose-[hours]" ) ),
		Y( :Name("VO2-[ml/min]" )),
		Overlay( :Treatment )
	),
	Elements( Line( X, Y, Legend( 21 ), Error Bars( "Standard Error" ) ) ),
	SendToReport(
		Dispatch( {}, "Graph Builder", OutlineBox, {Set Title( "Oxygen consumption" )} ),
		Dispatch(
			{},
			"Time since first dose-[hours]",
			ScaleBox,
			{Min( 168 ), Max( 288), Inc( 2 ), Minor Ticks( 12 )}
		),
		Dispatch(
			{},
			"400",
			ScaleBox,
			{Legend Model(
				21,
				Properties( 0, {Line Color( 0 )}, Item ID( "A", 1 ) ),
				Properties(
					1,
					{Line Color( 53 )},
					Item ID( "B", 1 )
				),
				Properties(
					2,
					{Line Color( 37 )},
					Item ID( "C", 1 )
				),
				Properties( 3, {Line Color( 0 )}, Item ID( "A", 2 ) ),
				Properties(
					4,
					{Line Color( 53 )},
					Item ID( "B", 2 )
				),
				Properties(
					5,
					{Line Color( 37 )},
					Item ID( "C", 2 )
				)
			)}
		),
		Dispatch( {}, "Graph Builder", FrameBox, {Marker Size( 0 )} ),
		Dispatch( {}, "400", LegendBox, {Set Title( "" )} )
	)
);
Eval(
	Substitute(
			Expr(
				Report( Oxygen consumption )[AxisBox( 1 )] << Add Ref Line( {__LSL__, __USL__}, "Solid", "Black", "", 1, 0.25 ) //try show limits(1) in spec limits
			),
		Expr( __LSL__ ), (SableData:Name( "Time since first dose-[hours]" ) << get property( "spec limits" ))["LSL"],
		Expr( __USL__ ), (SableData:Name( "Time since first dose-[hours]" ) << get property( "spec limits" ))["USL"]
	));

 

 

But now I have data covering two weeks and I would still like to illustrate visually when it is night and day. I can of course add these manually but and copy the script but I would like to do this in a robust manner.

 

Can I in any way add these extra properties to the "Time since first dose-[hours]" column or is it possible to create a separate data table including all limits and pull them into the data table in one go?

 

Thanks in advance.

 

Br Julie

nightday ref lines.jpg

1 ACCEPTED SOLUTION

Accepted Solutions
Byron_JMP
Staff

Re: Multiple reference lines on x-axis

The second problem with the light and dark phase lines not showing up where expected is due to a mismatch between the axis variable and the variable used to define where the lines should go.

 

In the graph the x axis is a duration and in the custom script the lines are based on the row number, so graph builder uses the row number and plots it on the time duration, which kind of just doesn't work.

 

I added a couple of columns to the data table, they are similar to some of the original columns, but with some small tweaks and formatting differences.

//if you have the data table open, make it the active table and run this 


dt=current data table();
dt<<New Column( "Time 2",
		Numeric,
		"Continuous",
		Format( ":day:hr:m", 14 ),
		Input Format( ":day:hr:m" ),
		Formula( :DateTime - :StartTime ),
		Set Selected
	);
dt<<New Column( "step2",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Formula( If( :Phase == "Dark phase", 0, 1 ) ),
		Set Selected
	);
dt<<New Column( "phase2",
		Character,
		"Nominal",
		Formula( If( :Phase == "Dark phase", "D", "L" ) )
	);

The next step is to edit the custom script in the graph. 

//This script goes into the Custom Script in the graph builder plot
For Each Row( If( Is Missing( :NewPhase ) == 0, V Line( :Time2 ) ) );
For Each Row(
	If( Is Missing( :NewPhase ) == 0,
		Text(  {:Time2, 5 + :step2}, " "||:Phase2 )
	)
);

//The, " "||:phase2, inserts a space before the label so that it isn't touching the phase line.

The result is the fixed graph, like this.

Screen Shot 2020-06-19 at 9.27.11 AM.png

 

With all the changes, the x-axis is now in Days:Hours:minutes format, and all the light and dark phase lines show up in the right place. The phase label is abbreviated so that it doesn't overlap and just make a jumble off messy text. 

 

Graph script

Graph Builder(
	Size( 1455, 290 ),
	Show Control Panel( 0 ),
	Variables( X( :Time2 ), Y( :Name( "EE-[kcal/h]" ) ), Overlay( :Treatment ) ),
	Elements( Line( X, Y, Legend( 5 ) ) ),
	SendToReport(
		Dispatch(
			{},
			"Time2",
			ScaleBox,
			{Min( -586333.5 ), Max( 2531060.48337292 ), Interval( "Day" ), Inc( 1 ),
			Minor Ticks( 6 ), Label Row( Label Orientation( "Perpendicular" ) )}
		),
		Dispatch(
			{},
			"EE-[kcal/h]",
			ScaleBox,
			{Format( "Best", 12 ), Min( 1.7751677852349 ), Max( 5.7751677852349 ),
			Inc( 1 ), Minor Ticks( 0 )}
		),
		Dispatch(
			{},
			"Graph Builder",
			FrameBox,
			{Add Graphics Script(
				2,
				Description( "Script" ),
				For Each Row( If( Is Missing( :NewPhase ) == 0, V Line( :Time2 ) ) );
				For Each Row(
					If( Is Missing( :NewPhase ) == 0,
						Text( {:Time2, 5 + :step2}, " " || :Phase2 )
					)
				);
			), Grid Line Order( 1 ), Reference Line Order( 3 ),
			DispatchSeg(
				TopSeg( 1 ),
				{Set Script(
					For Each Row(
						If( Is Missing( :NewPhase ) == 0,
							V Line( :Time2 )
						)
					);
					For Each Row(
						If( Is Missing( :NewPhase ) == 0,
							Text( {:Time2, 5 + :step2}, " " || :Phase2 )
						)
					);
				)}
			)}
		)
	)
)
JMP Systems Engineer, Health and Life Sciences (Pharma)

View solution in original post

7 REPLIES 7
Byron_JMP
Staff

Re: Multiple reference lines on x-axis

I've used columns to define when to add reference lines. I suppose it would be just as easy to add ranges too.

 

Here are some notes that might be useful: Event Lines and Comments on Control Charts 

JMP Systems Engineer, Health and Life Sciences (Pharma)
JulieSAppel
Level IV

Re: Multiple reference lines on x-axis

Hi @Byron_JMP 

Thanks for the suggestion.

 

I tried using the setup you describe and it worked to some extend. In order to follow the same process I created a new column in my data table (NewPhase) where the rows that are not missing should result in a event line.

I based the NewPhase column output solely on the animal number with the highest number of rows so that I will only get one set of event lines instead one for each animal:

DataPointsAnimal = SableData << Summary(
			Group( :Animal No. ),
			N( :Phase ),
			Freq( "None" ),
			Weight( "None" ));
	
DataPointsAnimalSorted = DataPointsAnimal << Sort( By( :N Rows ), Order( Descending ) );
Close( DataPointsAnimal, No Save );
AnimalVar = DataPointsAnimalSorted:Animal No.[1];
SableData << New column("NewPhase", Formula(If( :Animal No. == AnimalVar,
	If( :Phase == Lag( :Phase, 1 ),
		.,
		"new"
	),
	.
)));

I then created the graph with your input

Graph Builder(
	Size( 924, 695 ),
	Variables(
		X( :Name( "Time since first dose-[hours]" ) ),
		Y( :Name( "EE-[kcal/h]" ) ),
		Overlay( :Treatment )
	),
	Elements( Line( X, Y, Legend( 5 ) ) ),
		SendToReport(
		Dispatch(
			{},
			"Graph Builder",
			FrameBox,
			{Add Graphics Script(
				2,
				Description( "Script" ),
				For Each Row( If( Is Missing( :NewPhase ) == 0, V Line( Row() ) ) );

				For Each Row(
					If( Is Missing( :NewPhase ) == 0,
						Text(
							Right Justified,
							{Row(), Col Maximum( :Name( "EE-[kcal/h]" ) ) * 1.2},
							:Phase
						)
					)
				);
			), Grid Line Order( 1 ), Reference Line Order( 3 )}
		)
	)
);

But for some reason it only includes a limited amount of lines and it doesn´t include any text at all.

What am I doing wrong?

Byron_JMP
Staff

Re: Multiple reference lines on x-axis

it looks like it works fine, just not as expected, due possibly to an outlier...

Screen Shot 2020-06-18 at 1.18.55 PM.png

the column max() of the Y axis variable  is over 23. So the text shows up off scale with the rest of the figure.

JMP Systems Engineer, Health and Life Sciences (Pharma)
Byron_JMP
Staff

Re: Multiple reference lines on x-axis

The second problem with the light and dark phase lines not showing up where expected is due to a mismatch between the axis variable and the variable used to define where the lines should go.

 

In the graph the x axis is a duration and in the custom script the lines are based on the row number, so graph builder uses the row number and plots it on the time duration, which kind of just doesn't work.

 

I added a couple of columns to the data table, they are similar to some of the original columns, but with some small tweaks and formatting differences.

//if you have the data table open, make it the active table and run this 


dt=current data table();
dt<<New Column( "Time 2",
		Numeric,
		"Continuous",
		Format( ":day:hr:m", 14 ),
		Input Format( ":day:hr:m" ),
		Formula( :DateTime - :StartTime ),
		Set Selected
	);
dt<<New Column( "step2",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Formula( If( :Phase == "Dark phase", 0, 1 ) ),
		Set Selected
	);
dt<<New Column( "phase2",
		Character,
		"Nominal",
		Formula( If( :Phase == "Dark phase", "D", "L" ) )
	);

The next step is to edit the custom script in the graph. 

//This script goes into the Custom Script in the graph builder plot
For Each Row( If( Is Missing( :NewPhase ) == 0, V Line( :Time2 ) ) );
For Each Row(
	If( Is Missing( :NewPhase ) == 0,
		Text(  {:Time2, 5 + :step2}, " "||:Phase2 )
	)
);

//The, " "||:phase2, inserts a space before the label so that it isn't touching the phase line.

The result is the fixed graph, like this.

Screen Shot 2020-06-19 at 9.27.11 AM.png

 

With all the changes, the x-axis is now in Days:Hours:minutes format, and all the light and dark phase lines show up in the right place. The phase label is abbreviated so that it doesn't overlap and just make a jumble off messy text. 

 

Graph script

Graph Builder(
	Size( 1455, 290 ),
	Show Control Panel( 0 ),
	Variables( X( :Time2 ), Y( :Name( "EE-[kcal/h]" ) ), Overlay( :Treatment ) ),
	Elements( Line( X, Y, Legend( 5 ) ) ),
	SendToReport(
		Dispatch(
			{},
			"Time2",
			ScaleBox,
			{Min( -586333.5 ), Max( 2531060.48337292 ), Interval( "Day" ), Inc( 1 ),
			Minor Ticks( 6 ), Label Row( Label Orientation( "Perpendicular" ) )}
		),
		Dispatch(
			{},
			"EE-[kcal/h]",
			ScaleBox,
			{Format( "Best", 12 ), Min( 1.7751677852349 ), Max( 5.7751677852349 ),
			Inc( 1 ), Minor Ticks( 0 )}
		),
		Dispatch(
			{},
			"Graph Builder",
			FrameBox,
			{Add Graphics Script(
				2,
				Description( "Script" ),
				For Each Row( If( Is Missing( :NewPhase ) == 0, V Line( :Time2 ) ) );
				For Each Row(
					If( Is Missing( :NewPhase ) == 0,
						Text( {:Time2, 5 + :step2}, " " || :Phase2 )
					)
				);
			), Grid Line Order( 1 ), Reference Line Order( 3 ),
			DispatchSeg(
				TopSeg( 1 ),
				{Set Script(
					For Each Row(
						If( Is Missing( :NewPhase ) == 0,
							V Line( :Time2 )
						)
					);
					For Each Row(
						If( Is Missing( :NewPhase ) == 0,
							Text( {:Time2, 5 + :step2}, " " || :Phase2 )
						)
					);
				)}
			)}
		)
	)
)
JMP Systems Engineer, Health and Life Sciences (Pharma)
JulieSAppel
Level IV

Re: Multiple reference lines on x-axis

Wow thanks a lot for the explanation. That made good sense and it works beautifully too.

Byron_JMP
Staff

Re: Multiple reference lines on x-axis

That is a very fun data set, thanks for posting it and your questions.

If I had infinite time, it would look even better if the dark phases were an interval line that was shaded just a little bit grey.  Maybe someone else can pick that up and run with it?

JMP Systems Engineer, Health and Life Sciences (Pharma)
JulieSAppel
Level IV

Re: Multiple reference lines on x-axis

I actually had help with that and it it turned out something like this:

 

DarkLight = SableData << select where(:NewPhase == "new" ) << subset(
	Output Table("DarkLight"),
	columns(
		:Date,
		:Phase,
		:Name("Time since first dose-[hours]"),
		:NewPhase)
	);

DarkLight:Date << data type( Character ) << Set Modeling Type( Nominal );	
DarkLight << new column("Phase per day", Character, "Nominal", Formula( :Date || "-" || :Phase ) ); 
DarkLight << new column("High", Numeric, "Continuous", Formula(
	Lag( :Name( "Time since first dose-[hours]" ), -1 ))
);

DarkLight:High << delete formula;

DarkLight << new column("Color", Character, "Nominal", set each value("Grey"));
 
column(DarkLight, "Time since first dose-[hours]") << Set Name("Low");

DarkLight << select where(:Phase == "Light phase") << delete rows;

RQ = SableData << Graph Builder(
	Size( 938, 712 ),
	Variables(
		X( :Name( "Time since first dose-[hours]" ) ),
		Y( :RQ ),
		Overlay( :Treatment )
	),
	Elements( Points( X, Y, Legend( 4 ) ) )
);

x axis = Report( RQ )[AxisBox(1)];

For Each Row( DarkLight,
	// draw colored regon
	Eval( Eval Expr( x axis << Add Ref Line( { Expr( :Low ), Expr( :High ) }, "Solid", Expr( :Color ), , , 0.25 ) ) );
	// draw border lines
	Eval( Eval Expr( x axis << Add Ref Line( Expr( :Low ), "Solid", "Black" ) ) );
	Eval( Eval Expr( x axis << Add Ref Line( Expr( :High ), "Solid", "Black" ) ) );
);