cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Check out the JMP® Marketplace featured Capability Explorer add-in
Choose Language Hide Translation Bar
Sebastienlg
Level II

JMP SCRIPT: Control chart based on conditions

Hello everyone,

 

I would like to make control charts based on conditions.

I have two dataset:

1) the first dataset which contains the data for the control charts (with different variables),

2) the second dataset which contains the limits of the control chart. However, this dataset doesn't contain the limits of each variable of the first dataset.

 

I would like to create the following conditions: 

if the limits are available in the (second) dataset, then the limit are imported on the control chart.

However, if there is no limit in the (second) dataset, then no limit are set up on the control chart, and a run chart is developped.

 

In case there is no limit in the dataset JMP set limits based on the 3 standard deviations...

 

Does anyone have any suggestion to help me make this condition?

 

Thank you in advance,

Sebastien

 

7 REPLIES 7
txnelson
Super User

Re: JMP SCRIPT: Control chart based on conditions

The JMP platform, Control Chart Builder,  has the ability to load limits from a JMP Limits table.  Any limits found for a column in the limits table will be applied.  If the column is not found, then JMP will apply the standard limits.  The limits table can be in ether a wide or tall form

Wide    

txnelson_0-1681214488030.png

Tall

txnelson_1-1681214555640.png

Once you have your limits converted into one of these forms, then all that has to be done is to run the Control Chart Builder, specifying the columns to be charted, and telling it to get the limits from your limits table

 

Control Chart Builder(
	Variables( Y( <your list of column to chart goes here> ) ),
	Get Limits( "<the name of your limits table goes here>" )
);

 

 

Jim
Sebastienlg
Level II

Re: JMP SCRIPT: Control chart based on conditions

thank's a lot for your answer Jim.

This is already what I have done. However, for few variables, I do not have the limit available in the dataset: Example of the Age variable present below:

_LimitsKeyheightWeightAge
_UCL5480 
_LCL72150 

And when it is the case JMP apply the standard limits (here for the Age variable).

But I would like that JMP doesn't apply any limit in this case and just make a run chart.

I guess I need to make an "if" condition, but I do not know how to create it:

if ( "<the name of your limits table goes here>" ) isnot empty

not sure about it...

Do you have any suggestion for this condition?

Sebastien

 

txnelson
Super User

Re: JMP SCRIPT: Control chart based on conditions

As you suggest you will need to see if the limits are present or not.  Here is some pretty rough code to show an approach to use

names default to here(1);

dt= data table("<your data table>");
dtLimits = data table("<your limits table>");

colNames = {<create a list of columns to be processed>};

// Create a window to place all output into
nw = New Window("Charts",
	For(i=1,i<=nitems(colNames), i++,
		If( try(column(dtLimits, colNames[i]) << get name, "") == "" |
			try( col number(column(dtLimits, colNames[i])),0) == 0,
		Control Chart( 
			Chart ( as column(dt,colNames[i]),
				Run Chart(Run Chart( Show Center Line( 0 ) ))
			)
		),
		Control Chart Builder(
			Variables( Y( as column(dt, colNames[i]) ) ),
			Get Limits( dtLimits )
			);
			
		)
	)
);
Jim
Sebastienlg
Level II

Re: JMP SCRIPT: Control chart based on conditions

Thank's a lot for your answer Jim.

Almost there I hope... However, it is a bit trickier that I thought

It works well with in case there is no Column switcher...

 

However, in my case there is a column switcher, which is based on the user selection..

 

Here is my program:

 

New Window( "Test", 
	V List Box(
		coltstst = RAW_DATA_TABLE << 
		Column Switcher(:Name("Y"),Y_list),
		
		If( try( col number(column(LIMIT_TABLE, :"Y")),0) == 0 ,
		graph=Control Chart Builder(
				Size( 534, 450 ),
				Show Two Shewhart Charts( 0 ),
				Show Control Panel( 0 ),
				Sort by Row Order( 1 ),
				Show Limit Summaries( 0 ),
				Variables(
					Subgroup( :X ),
					Y( :"Y" ),
					Phase(:"Version")
				),
				Chart(
					Points( Statistic( "Individual" ) ),
					Limits(
						Sigma( "Moving Range" ),
						Show Lower Limit( 0 ),
						Show Upper Limit( 0 )
					)
				),
				SendToReport(
					Dispatch(
						{},
						"Control Chart Builder",
						OutlineBox,
						{Set Title( "Représentation graphique" )}
					)
				)
			),	
		graph = RAW_DATA_TABLE << 
				Control Chart Builder(
					Size( 534, 450 ),
					Show Two Shewhart Charts( 0 ),
					Show Control Panel( 0 ),			
					Sort by Row Order( 1 ),
					Show Limit Summaries( 0 ),
					Variables( Y( :"Y" ),Subgroup( :X ), Phase(:"Version")),	
					Get Limits(LIMIT_TABLE),
				),
		N = N Items( phaseLevels );
		// On met en forme les lignes
		For( i = 1, i <= N Items( phaseLevels ), i++,
			graph << SendToReport(
					Dispatch(
						{},
						"Control Chart Builder",
						OutlineBox,
						{Set Title( "Représentation graphique" )},
						FrameBox( 2 ),
						{
						DispatchSeg( Line Seg( Eval(3*i+N-2) ),		{Line Color( "Medium Light Green" ),Line Style( "Dotted" ), Line Width( 1.5 )} ),
						DispatchSeg( Line Seg( Eval(3*i+1+N-2) ),	{Line Color( "Medium Light Orange" ), Line Style( "Dotted" ), Line Width( 2.5 )}),
						DispatchSeg( Line Seg( Eval(3*i+2+N-2) ),	{Line Color( "Medium Light Red" ), Line Style( "Dotted" ), Line Width( 2.5 )})
						}
					)
				)
			)
		);
	));
	
coltstst << Link Platform( graph );

In that case, the control chart made doesn't add any control limits even if the table_limits contains limits.

 

Do you have any idea to help me?

Thank's a lot 

Sebastien

 

txnelson
Super User

Re: JMP SCRIPT: Control chart based on conditions

You need to change your code to change the limits display/no display, when the column switcher changes.  The Column Switcher handles this by using "Make Column Switch Handler".  It allows the code to have JSL run every time the Column Switcher runs.  The code will have to do the checking if a limit exists or not within the Handler, and then change the limits display based upon that.

Check in the Scripting Index for the Column Switcher for an example of the Make Control Chart Handler.  Then check in the Scripting Index, Control Chart Builder, for the methods on how to turn the limits display on and off.

Jim
Sebastienlg
Level II

Re: JMP SCRIPT: Control chart based on conditions

Hi Jim,

Thanks for yours answer,

I tried with the function "Make Column Switch Handler", Here is my script (I tried to comment with the red lines):

 

New Window( "Test", 
	V List Box(
	coltstst = RAW_DATA_TABLE << 
	Column Switcher(:Name("Y"),Y_list),
		
/* Statistics I want to include:*/
Cadreall = Tabulate( Change Item Label( Statistics( N, "n" ), Statistics( Min, "Période d'étude entre le : " ), Statistics( Max, "Et le : " ) ), Show Control Panel( 0 ), Add Table( Row Table( Analysis Columns( :"Y"n ), Statistics( N ) ), Row Table( Analysis Columns( :Date ), Statistics( Min, Max ) ) ) ), // Création des statistiques descriptives table = Tabulate( Show Control Panel( 0 ), Set Format( Uniform Format( 10, 2 ) ), Show Test Build Panel( 1 ), Add Table( Column Table( Analysis Columns( :"Y" ), Statistics( Min, Max, Median, Mean ) ) ), SendToReport( Dispatch( {}, "Tabulate", OutlineBox, {Set Title( "Statistiques descriptives" )} ) ) ),
/* And then the graph:*/
pre = Function( {currentColumn, nextColumn, switcher}, If(

/* If the column selected is contained in the list containing limits, then make this graph: */
currentColumn <= Y_with_limit, graph = RAW_DATA_TABLE << Control Chart Builder( Size( 534, 450 ), Show Two Shewhart Charts( 0 ), Show Control Panel( 0 ), Sort by Row Order( 1 ), Show Limit Summaries( 0 ), Variables( Y( :"Y" ), Subgroup( :X ), Phase( :"Version" ) ), Get Limits( LIMIT_TABLE ), ), N = N Items( phaseLevels ); // On met en forme les lignes For( i = 1, i <= N Items( phaseLevels ), i++, graph << SendToReport( Dispatch( {}, "Control Chart Builder", OutlineBox, {Set Title( "Représentation graphique" )}, FrameBox( 2 ), {DispatchSeg( Line Seg( Eval( 3 * i + N - 2 ) ), {Line Color( "Medium Light Green" ), Line Style( "Dotted" ), Line Width( 1.5 )} ), DispatchSeg( Line Seg( Eval( 3 * i + 1 + N - 2 ) ), {Line Color( "Medium Light Orange" ), Line Style( "Dotted" ), Line Width( 2.5 )} ), DispatchSeg( Line Seg( Eval( 3 * i + 2 + N - 2 ) ), {Line Color( "Medium Light Red" ), Line Style( "Dotted" ), Line Width( 2.5 )} )} ) ) ),
/* If there is the column selected does not contained limits, then make this graph: */
graph = Control Chart Builder( Size( 534, 450 ), Show Two Shewhart Charts( 0 ), Show Control Panel( 0 ), Sort by Row Order( 1 ), Show Limit Summaries( 0 ), Variables( Subgroup( :Numéro de lot ), Y( :"Y" ), Phase( :"Version" ) ), Chart( Points( Statistic( "Individual" ) ), Limits( Sigma( "Moving Range" ), Show Lower Limit( 0 ), Show Upper Limit( 0 ) ) ), SendToReport( Dispatch( {}, "Control Chart Builder", OutlineBox, {Set Title( "Représentation graphique" )} ) ) ) ); Return( 1 ); )); post = Function( {previousColumn, currentColumn, switcher}, Print( "After switch: " || (previousColumn << get name) || " >> " || (currentColumn << get name) || " [Column Switcher] current: " || (columnSwitcher << Get Current) ) )); coltstst << Make Column Switch Handler( pre, post ); coltstst << Run; /* coltstst << Link Platform( table ); coltstst << Link Platform( Cadreall ); coltstst << Link Platform( graph );*/
/* Then, all graph are included in the journal: */
ncols = n items (coltstst << get list); for each ({i}, 1::ncols, cadreall << journal; table << journal; graph << Journal; coltstst << next; )

Here is the message I got:

Sebastienlg_0-1681718804360.png

"The send expects a scriptable object when accessing or evaluating send..."

Any idea?

Sebastien

txnelson
Super User

Re: JMP SCRIPT: Control chart based on conditions

Attached is an example of a script that turns limits off and on based upon the existing of external limits

 

Limits Exist:.....Control Chart

txnelson_0-1681853410975.png

 

Limits Off:   A Runs Chart

txnelson_1-1681853524477.png

Names Default To Here( 1 );

// Create a sample limits table
dtLimits = New Table( "limits",
	Add Rows( 2 ),
	New Script( "Source", Data Table( "limits" ) << Update( With( Data Table( "Summary of Process Measurements" ) ) ) ),
	New Column( "_LimitsKey",
		Character,
		"Nominal",
		Set Property( "Value Order", {Numerical Order( 0 )} ),
		Set Values( {"_LCL", "_UCL"} )
	),
	New Column( "Process 1", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [0.9, 21] ) ),
	New Column( "Process 2", Numeric, "Continuous", Format( "Fixed Dec", 12, 3 ), Set Values( [13.95, 13.61] ) ),
	New Column( "Process 3", Numeric, "Continuous", Format( "Fixed Dec", 12, 3 ), Set Values( [., .] ) ),
	New Column( "Process 4", Numeric, "Continuous", Format( "Fixed Dec", 12, 3 ), Set Values( [8.39, 0.81] ) ),
	New Column( "Process 5", Numeric, "Continuous", Format( "Fixed Dec", 12, 3 ), Set Values( [2.48, 0.00049] ) ),
	New Column( "Process 6", Numeric, "Continuous", Format( "Fixed Dec", 12, 3 ), Set Values( [0.91, 0.55] ) ),
	New Column( "Process 7", Numeric, "Continuous", Format( "Fixed Dec", 12, 3 ), Set Values( [11.45, 8.76] ) )
);

// Open the sample measurement table
dt = Open( "$SAMPLE_DATA/Process Measurements.jmp" );
// myList = {:Process 1, :Process 2, :Process 3, :Process 4, :Process 5, :Process 6, :Process 7};
myList = dt << get column names( continuous );

// Create the Control Chart
nw = New Window( "Report",
	H List Box(
		columnSwitcher = dt << Column Switcher( :Process 1, myList );
		gb = Control Chart Builder(
			Variables( Y( :Process 1 ) ),
			Chart( Position( 1 ) ),
			show two shewhart charts( 0 ),
			Show Limit Summaries( 0 ),
			Show Control Panel( 0 )
		);
		dis = Distribution(
			Continuous Distribution( Column( :Process 1 ), Process Capability( Use Column Property Specs ) )
		);
	)
);
columnSwitcher << Link Platform( gb );
columnSwitcher << Link Platform( dis );
pre = Function( {currentColumn, nextColumn, switcher},
	dtLimits << show window( 0 )
);
Post = Function( {currentColumn, nextColumn, switcher},
	// Get path to set limits checkboxes
	get_cbs = Expr(
		tbs = Report( gb ) << XPath(
			"//TextBox[contains(text(), 'Show Lower Limit') or contains(text(), 'Show Upper') or contains(text(), 'Show Center Line')]"
		);
		mbs = tbs << parent;
		cbs = mbs << sib;
		
	);
	get_cbs;
	
	// Check to see if limits exist in the limits table
	If( Col Number( As Column( dtlimits, nextColumn << get name ) ) != 0,
		// Limits Exist, therefore set the limits
		For( i = 1, i <= N Items( cbs ), i++,
			get_cbs;
			cbs[i] << Set( 1, 1 );
		),
		// Limits do not exist, turn off the displaying of limits
		For( i = 1, i <= N Items( cbs ), i++,
			get_cbs;
			cbs[i] << Set( 1, 0 );
		)
	);
	nw << bring window to front;
);
columnSwitcher << Make Column Switch Handler( Pre, Post );

 

 

Jim