Subscribe Bookmark RSS Feed

Multiple spec limits in one column

gandi2223

Community Trekker

Joined:

Oct 1, 2014

Is it possible to have multiple spec limits for one column? Let's say I have a table that looks like this:

7362_Capture1.PNG

I would like to generate a variability chart from it that shows separate spec limits for samples A and B, as indicated below:

7363_Variability Chart.png

In the graph above, this was done by manually entering the limits as reference lines, but I was wondering if there was a smarter way of doing it, ideally with the limits being shown only in the section of the graph where the data for sample A or B lies, rather than across the entire graph.

Thanks in advance!

4 ACCEPTED SOLUTIONS

Accepted Solutions
notoriousapp

Community Trekker

Joined:

Jun 4, 2014

Solution

hardner: excellent, thanks for the info.  I also hijacked some of your scripting above to add spec limits by group in a variability chart.  I did have a few more questions:

1) How do I change the type and color of line used for the reference lines (i.e. dotted, dashed, etc.)

2) Using the addgraphicsscript function, is there a way to tell JMP which X subgroup to reference when drawing the length of the line (in the x-axis direction)?  For example, the way I've scripted this I'm able to create the reference lines using "Run #" but what if I want use "Group" to define the length of the reference line?


3) If adding my own column property, I assume you're talking about column property --> Other....and then what?  Just copy some scripting into the column property submenu? [Maybe this should be it's own thread if it doesn't already exist]


Thanks in advance!

Here is my test script for the table:

New Table( "Variability Spec Limits By Group Test_Data",

  Add Rows( 15 ),

  New Script(

  "Variability Chart",

  o = Variability Chart(

  Y( :Parametric Response ),

  X( :GROUP, :Run # ),

  Max Iter( 100 ),

  Conv Limit( 0.00000001 ),

  Number Integration Abscissas( 128 ),

  Number Function Evals( 65536 ),

  Analysis Type( Name( "Choose best analysis (EMS REML Bayesian)" ) ),

  Process Variation( 0 ),

  Std Dev Chart( 0 ),

  SendToReport(

  Dispatch(

  {"Variability Chart for Parametric Response"},

  "2",

  ScaleBox,

  {Min( 8.92666666666667 ), Max( 15.35 ), Inc( 1 ),

  Minor Ticks( 1 )}

  )

  )

  );

  r = o << report;

  r[framebox( 1 )] << addgraphicsscript( Line( {0, 12}, {5, 12} ) );

  r[framebox( 1 )] << addgraphicsscript( Line( {0, 14}, {5, 14} ) );

  r[framebox( 1 )] << addgraphicsscript( Line( {5, 13}, {10, 13} ) );

  r[framebox( 1 )] << addgraphicsscript( Line( {5, 15}, {10, 15} ) );

  r[framebox( 1 )] << addgraphicsscript( Line( {10, 10.5}, {15, 10.5} ) );

  r[framebox( 1 )] << addgraphicsscript( Line( {10, 13.5}, {15, 13.5} ) );

  ),

  New Column( "GROUP",

  Character( 4 ),

  Nominal,

  Set Selected,

  Set Values(

  {"1", "1", "1", "1", "1", "2", "2", "2", "2", "2", "3", "3", "3", "3",

  "3"}

  )

  ),

  New Column( "Run #",

  Numeric,

  Continuous,

  Format( "Best", 12 ),

  Set Values( [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5] )

  ),

  New Column( "Parametric Response",

  Numeric,

  Continuous,

  Format( "Best", 12 ),

  Set Values(

  [13.02, 13.05, 12.98, 12.62, 12.79, 13.9, 13.86, 14.1, 14, 13.99, 12.21,

  12.56, 12.89, 11.3, 12]

  )

  ),

  Set Row States( [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0] )

)

Here is my test script for the graph:

o=Variability Chart(

  Y( :Parametric Response ),

  X( :GROUP, :Run # ),

  Max Iter( 100 ),

  Conv Limit( 0.00000001 ),

  Number Integration Abscissas( 128 ),

  Number Function Evals( 65536 ),

  Analysis Type( Name( "Choose best analysis (EMS REML Bayesian)" ) ),

  Process Variation( 0 ),

  Std Dev Chart( 0 ),

  SendToReport(

  Dispatch(

  {"Variability Chart for Parametric Response"},

  "2",

  ScaleBox,

  {Min( 8.92666666666667 ), Max( 15.35 ), Inc( 1 ), Minor Ticks( 1 )}

  )

  )

);

r=o<<report;

r[framebox(1)]<<addgraphicsscript(line({0,12},{5,12}));

r[framebox(1)]<<addgraphicsscript(line({0,14},{5,14}));

r[framebox(1)]<<addgraphicsscript(line({5,13},{10,13}));

r[framebox(1)]<<addgraphicsscript(line({5,15},{10,15}));

r[framebox(1)]<<addgraphicsscript(line({10,10.5},{15,10.5}));

r[framebox(1)]<<addgraphicsscript(line({10,13.5},{15,13.5}));

hardner

Community Trekker

Joined:

Nov 13, 2012

Solution

1.   try this modification to your final lines...

[framebox(1)]<<addgraphicsscript(line({0,12},{5,12}))

r[framebox(1)]<<addgraphicsscript(line({0,14},{5,14}));

r[framebox(1)]<<addgraphicsscript(line({5,13},{10,13}));

r[framebox(1)]<<addgraphicsscript(linestyle(1);line({5,15},{10,15}));

r[framebox(1)]<<addgraphicsscript(line({10,10.5},{15,10.5}));

r[framebox(1)]<<addgraphicsscript(pencolor(5);line({10,13.5},{15,13.5}));

or this one... you can gang all the graphics script lines into one message but if you try what I tried here you'll see the line style only lasted for one line while pen color remained blue and pen size lasted for multiple lines too....

r[framebox(1)]<<addgraphicsscript(pencolor(5);linestyle(1);line({0,12},{5,12});

line({0,14},{5,14});linestyle(3);line({5,13},{10,13});line({5,15},{10,15});pensize(3);line({10,10.5},{15,10.5});line({10,13.5},{15,13.5}));

I see this decoder in the help for linestyle - 0 solid, 1 dotted, 2 dashed, 3 dashdot or 4 dash dot dot...

hardner

Community Trekker

Joined:

Nov 13, 2012

Solution

2.  I may be wrong but I think there is not a way to do it based on the column names or values used on X ("draw a line from group A to group B")   I think what you need to do (if you don't know in advance the number of items in each level) is summarize the data by the various attributes you will use on X and then count up what's in each group (how many items in the lists you get) and use those results to define the line ends.  So, if you summarize by GROUP in this data you'd find there are 5 items in each group but you could have found 4 in 1, 7 in 2, 5 in 3, etc. and used that to specify your line ends. 

Luckily with variability chart it will leave a space for a group even if the data is null, so you don't need to try to work out not only what groups you have but whether they have non-null data for the Y parameter and will actually appear on the plot.  That is an issue if you want to talk to parts of some other more complex plots - it can be very hard to work out what groups there will be on the final plot based on arbitrary possible data.

hardner

Community Trekker

Joined:

Nov 13, 2012

Solution

3. I mean that in JSL you could do something like this...

dt= currentdatatable();

dt:ParametricResponse<<setproperty("myspecs",{{12,14},{13,15},{10.5,13.5}});

//and then later...

group1spec=(dt:ParametricResponse<<getproperty("myspecs"))[1];

The point wouldn't be to get the spec right after you put it in the column of course - you already knew it on the previous line.   but you could save the data with the various specs embedded in the column then scripts could later apply those specs that went with this particular data without hard coding it in the script itself, instead getting it from the column.

See that this worked by the way an asterisk appeared by the column in the column pane.  you can click the asterisk and see the new myspecs property in the table, as well as access it from JSL..

Can be pretty handy actually to put stuff into column properties.  I recently used this where data had encoded column names and I couldn't decide if I wanted that code or a more descriptive name for the column name.  It was pretty easy in JSL to loop over a decoder table and the columns in the main table and put the descriptive name into a property and then to have a little script that would run through the column names and swap the column name and that property at will.  Fun!

8 REPLIES
notoriousapp

Community Trekker

Joined:

Jun 4, 2014

Great question!  Coincidentally the same question came up yesterday in my organization (you don't work for FSL do you?).  Looking forward to the answer!

hardner

Community Trekker

Joined:

Nov 13, 2012

No, what is FSL?  I may have to start charging a consulting fee!  Just joking. That is what my husband says every time I get some computer programming advice from him (he's a "real" programmer).

gandi2223

Community Trekker

Joined:

Oct 1, 2014

No I'm at Seagate. Different company, same problems, it appears! ;-)

hardner

Community Trekker

Joined:

Nov 13, 2012

I don't know if you were interested in scripting but you could certainly do a script to achieve the things you mention.  2 things that you could do in scripting:

1)  you could save multiple spec levels to the column, just create your own column properties instead of using the Spec Limits property.

2)  you can draw your own lines on the plot by adding a graphics script.  It's not obvious what the X values should be but I can offer that if you did it with a Oneway the X scale appeasr to run in integer steps one for each group.  Here's an example that shows drawing lines on a Oneway... and I just checked in on variability plot - it works the same way - X values from 0 to 1 are the first group...

New Table( "testdata",

  Add Rows( 24 ),

  New Column( "GROUP",

  Character( 4 ),

  Nominal,

  Set Property( "Value Ordering", {"REF1", "MED1", "MED2", "REF2"} ),

  Set Values(

  {"REF1", "REF1", "REF1", "REF1", "REF1", "MED1", "MED1", "MED1", "MED1",

  "MED2", "MED2", "MED2", "MED2", "MED2", "MED2", "MED2", "REF2", "REF2",

  "REF2", "REF2", "REF2", "REF2", "REF2", "REF2"}

  )

  ),

  New Column( "X",

  Numeric,

  Continuous,

  Format( "Best", 12 ),

  Set Values(

  [27, 28, 30, 32, 34, 34, 36, 38, 41, 31, 33, 34, 37, 39, 42, 44, 30, 31,

  33, 35, 37, 39, 41, 43]

  )

  ),

  New Column( "Y",

  Numeric,

  Continuous,

  Format( "Best", 12 ),

  Set Values(

  [52, 57, 62, 64, 66, 54, 56, 58, 59, 58, 57, 60, 64, 66, 75, 76, 50, 51,

  55, 58, 60, 63, 71, 72]

  )

  ),

  New Column( "Y SIGMA",

  Numeric,

  Continuous,

  Format( "Best", 12 ),

  Set Values(

  [4, 5, 3, 6, 8, 6, 8, 4, 6, 9, 7, 8, 6, 7, 6, 5, 3, 4, 2, 6, 5, 8, 5, 9]

  )

  )

);

o=Oneway(

  Y( :Y ),

  X( :GROUP ),

  Box Plots( 1 ),

  X Axis Proportional( 0 ),

  Grand Mean( 0 ),

  SendToReport(

  Dispatch(

  {},

  "Oneway Plot",

  FrameBox,

  {DispatchSeg(

  Box Plot Seg( 1 ),

  {Box Style( "Outlier" ), Line Color( "Red" )}

  ), DispatchSeg(

  Box Plot Seg( 2 ),

  {Box Style( "Outlier" ), Line Color( "Red" )}

  ), DispatchSeg(

  Box Plot Seg( 3 ),

  {Box Style( "Outlier" ), Line Color( "Red" )}

  ), DispatchSeg(

  Box Plot Seg( 4 ),

  {Box Style( "Outlier" ), Line Color( "Red" )}

  )}

  )

  )

);

r=o<<report;

r[framebox(1)]<<addgraphicsscript(line({0,60},{.5,60}));

r[framebox(1)]<<addgraphicsscript(line({0,50},{2,50}));

Of course to make this more general you'd need to work out which group on the plot is going to match which of your stored specs..

notoriousapp

Community Trekker

Joined:

Jun 4, 2014

Solution

hardner: excellent, thanks for the info.  I also hijacked some of your scripting above to add spec limits by group in a variability chart.  I did have a few more questions:

1) How do I change the type and color of line used for the reference lines (i.e. dotted, dashed, etc.)

2) Using the addgraphicsscript function, is there a way to tell JMP which X subgroup to reference when drawing the length of the line (in the x-axis direction)?  For example, the way I've scripted this I'm able to create the reference lines using "Run #" but what if I want use "Group" to define the length of the reference line?


3) If adding my own column property, I assume you're talking about column property --> Other....and then what?  Just copy some scripting into the column property submenu? [Maybe this should be it's own thread if it doesn't already exist]


Thanks in advance!

Here is my test script for the table:

New Table( "Variability Spec Limits By Group Test_Data",

  Add Rows( 15 ),

  New Script(

  "Variability Chart",

  o = Variability Chart(

  Y( :Parametric Response ),

  X( :GROUP, :Run # ),

  Max Iter( 100 ),

  Conv Limit( 0.00000001 ),

  Number Integration Abscissas( 128 ),

  Number Function Evals( 65536 ),

  Analysis Type( Name( "Choose best analysis (EMS REML Bayesian)" ) ),

  Process Variation( 0 ),

  Std Dev Chart( 0 ),

  SendToReport(

  Dispatch(

  {"Variability Chart for Parametric Response"},

  "2",

  ScaleBox,

  {Min( 8.92666666666667 ), Max( 15.35 ), Inc( 1 ),

  Minor Ticks( 1 )}

  )

  )

  );

  r = o << report;

  r[framebox( 1 )] << addgraphicsscript( Line( {0, 12}, {5, 12} ) );

  r[framebox( 1 )] << addgraphicsscript( Line( {0, 14}, {5, 14} ) );

  r[framebox( 1 )] << addgraphicsscript( Line( {5, 13}, {10, 13} ) );

  r[framebox( 1 )] << addgraphicsscript( Line( {5, 15}, {10, 15} ) );

  r[framebox( 1 )] << addgraphicsscript( Line( {10, 10.5}, {15, 10.5} ) );

  r[framebox( 1 )] << addgraphicsscript( Line( {10, 13.5}, {15, 13.5} ) );

  ),

  New Column( "GROUP",

  Character( 4 ),

  Nominal,

  Set Selected,

  Set Values(

  {"1", "1", "1", "1", "1", "2", "2", "2", "2", "2", "3", "3", "3", "3",

  "3"}

  )

  ),

  New Column( "Run #",

  Numeric,

  Continuous,

  Format( "Best", 12 ),

  Set Values( [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5] )

  ),

  New Column( "Parametric Response",

  Numeric,

  Continuous,

  Format( "Best", 12 ),

  Set Values(

  [13.02, 13.05, 12.98, 12.62, 12.79, 13.9, 13.86, 14.1, 14, 13.99, 12.21,

  12.56, 12.89, 11.3, 12]

  )

  ),

  Set Row States( [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0] )

)

Here is my test script for the graph:

o=Variability Chart(

  Y( :Parametric Response ),

  X( :GROUP, :Run # ),

  Max Iter( 100 ),

  Conv Limit( 0.00000001 ),

  Number Integration Abscissas( 128 ),

  Number Function Evals( 65536 ),

  Analysis Type( Name( "Choose best analysis (EMS REML Bayesian)" ) ),

  Process Variation( 0 ),

  Std Dev Chart( 0 ),

  SendToReport(

  Dispatch(

  {"Variability Chart for Parametric Response"},

  "2",

  ScaleBox,

  {Min( 8.92666666666667 ), Max( 15.35 ), Inc( 1 ), Minor Ticks( 1 )}

  )

  )

);

r=o<<report;

r[framebox(1)]<<addgraphicsscript(line({0,12},{5,12}));

r[framebox(1)]<<addgraphicsscript(line({0,14},{5,14}));

r[framebox(1)]<<addgraphicsscript(line({5,13},{10,13}));

r[framebox(1)]<<addgraphicsscript(line({5,15},{10,15}));

r[framebox(1)]<<addgraphicsscript(line({10,10.5},{15,10.5}));

r[framebox(1)]<<addgraphicsscript(line({10,13.5},{15,13.5}));

hardner

Community Trekker

Joined:

Nov 13, 2012

Solution

1.   try this modification to your final lines...

[framebox(1)]<<addgraphicsscript(line({0,12},{5,12}))

r[framebox(1)]<<addgraphicsscript(line({0,14},{5,14}));

r[framebox(1)]<<addgraphicsscript(line({5,13},{10,13}));

r[framebox(1)]<<addgraphicsscript(linestyle(1);line({5,15},{10,15}));

r[framebox(1)]<<addgraphicsscript(line({10,10.5},{15,10.5}));

r[framebox(1)]<<addgraphicsscript(pencolor(5);line({10,13.5},{15,13.5}));

or this one... you can gang all the graphics script lines into one message but if you try what I tried here you'll see the line style only lasted for one line while pen color remained blue and pen size lasted for multiple lines too....

r[framebox(1)]<<addgraphicsscript(pencolor(5);linestyle(1);line({0,12},{5,12});

line({0,14},{5,14});linestyle(3);line({5,13},{10,13});line({5,15},{10,15});pensize(3);line({10,10.5},{15,10.5});line({10,13.5},{15,13.5}));

I see this decoder in the help for linestyle - 0 solid, 1 dotted, 2 dashed, 3 dashdot or 4 dash dot dot...

hardner

Community Trekker

Joined:

Nov 13, 2012

Solution

2.  I may be wrong but I think there is not a way to do it based on the column names or values used on X ("draw a line from group A to group B")   I think what you need to do (if you don't know in advance the number of items in each level) is summarize the data by the various attributes you will use on X and then count up what's in each group (how many items in the lists you get) and use those results to define the line ends.  So, if you summarize by GROUP in this data you'd find there are 5 items in each group but you could have found 4 in 1, 7 in 2, 5 in 3, etc. and used that to specify your line ends. 

Luckily with variability chart it will leave a space for a group even if the data is null, so you don't need to try to work out not only what groups you have but whether they have non-null data for the Y parameter and will actually appear on the plot.  That is an issue if you want to talk to parts of some other more complex plots - it can be very hard to work out what groups there will be on the final plot based on arbitrary possible data.

hardner

Community Trekker

Joined:

Nov 13, 2012

Solution

3. I mean that in JSL you could do something like this...

dt= currentdatatable();

dt:ParametricResponse<<setproperty("myspecs",{{12,14},{13,15},{10.5,13.5}});

//and then later...

group1spec=(dt:ParametricResponse<<getproperty("myspecs"))[1];

The point wouldn't be to get the spec right after you put it in the column of course - you already knew it on the previous line.   but you could save the data with the various specs embedded in the column then scripts could later apply those specs that went with this particular data without hard coding it in the script itself, instead getting it from the column.

See that this worked by the way an asterisk appeared by the column in the column pane.  you can click the asterisk and see the new myspecs property in the table, as well as access it from JSL..

Can be pretty handy actually to put stuff into column properties.  I recently used this where data had encoded column names and I couldn't decide if I wanted that code or a more descriptive name for the column name.  It was pretty easy in JSL to loop over a decoder table and the columns in the main table and put the descriptive name into a property and then to have a little script that would run through the column names and swap the column name and that property at will.  Fun!