I have a script that plots metrics by wafer number. If the wafer falls below a threshold of passing die, it is designated a fail. Is there a way to have the colours of the plots reflect pass and fail aside from creating a separate grading column for each parameter?
Great idea to use a table variable as intermediate storage location for the column reference. Expr(dt) - Nice trick!
As an alternative, one can store the transform column with the report (the standard way when it's generated via right click in the column list of the dialog window).
names default to here(1);
dt = current data table();
gb = Graph Builder(
Transform Column(
"Col",
Nominal,
Formula(
specs = Column( :CURCOL ) << Get Property( "Spec Limits" );
Col Min( As Column( Column( :CURCOL ) ), :lot_id ) > specs["LSL"] &
Col Max( As Column( Column( :CURCOL ) ), :lot_id ) < specs["USL"];
)
),
Variables( X( :lot_id ), Y( :PBA3 ), Color( :Col ) ),
Elements( Points( X, Y ) ),
Column Switcher(:PBA3,{:PBA3,:SPM1})
);
cs = current report()["Column Switcher"] << get scriptable object;
Eval(EvalExpr(
post = Function({prevcol, curcol, switcher},
Expr(dt) << Set Table Variable("CURCOL", curcol);
);
));
handler = cs << Make Column Switch Handler(1, post);
I made a script that will test whether the mean of each wafer has exceeded the LSL or USL set as a column property, and will subsequently colour the rows based on a fail/pass - you can run this and the colours will come through to any of the reports in JMP (i.e. Graph Builder)
names default to here(1);
dt = Current Data Table();
dt<<clear select;
//get the limits
Spec_limits = dt:Y << get property( "Spec Limits" );
USL_val=try(spec_limits["usl"]);
LSL_val=try(spec_limits["lsl"]);
// Calculate the mean for each wafer group
Summarize( wafer_meangroup= By( :Wafer ),value_means= Mean( :Y ) );
failed_rows={}; //create a blank list that can store the rows that have failed
//add to an associative array
Assoc_array=associative array(wafer_meangroup,value_means); //get the association of wafer name to the mean value
//Run a for loop that checks every item in the wafer>mean list and sees if it exceeds the USL, if it does then it's inserted into the failed_rows list
for(i=1, i<=n items(Assoc_array),i++,
if(Assoc_array[wafer_meangroup[i]]>=usl_val, insert into(failed_rows, get=dt<<get rows where(:Wafer==wafer_meangroup[i])), {};
));
//Run a for loop that checks every item in the wafer<mean list and sees if it exceeds the LSL, if it does then it's inserted into the failed_rows list
for(i=1, i<=n items(Assoc_array),i++,
if(Assoc_array[wafer_meangroup[i]]<=lsl_val, insert into(failed_rows, get=dt<<get rows where(:Wafer==wafer_meangroup[i])), {};
));
write(failed_rows);
//Convert the failed rows list from a nested list to a continuous - probably an easier way to achieve this!
// Create a location to store the list
continuous_failed_Rows = {};
// Loop through each sublist in the nested list
for (i = 1, i <= N Items(failed_rows), i++,
// Loop through each element in the sublist
for (j = 1, j <= N Items(failed_rows[i]), j++,
// Insert each element into the continuous list
Insert Into(continuous_failed_Rows, failed_rows[i][j]);
)
);
// Display the continuous list
Write(continuous_failed_Rows);
dt<<select rows(continuous_failed_Rows);
dt<<colors("red");
dt<<invert row selection;
dt<<colors("green");
No, I've left this so it's agnostic of the report that is being opened to allow for flexibility, instead referring just to the data table. You could easily create an additional script to this to pull out the currently displayed Y variable name in whichever report is being used and have the script update according to that or use 'Make Filter Change Handler' to trigger the script searching for a change to the name
I've adapted the script to take advantage of the 'Graphics Scripts' you can apply to frameboxes to track what the column switcher is that is open and to then change the colour based on the Y being shown
names default to here(1);
//Setting up an example data set with some columns to work from - not needed for actual use
dt = Open("$SAMPLE_DATA/Variability Data/Wafer.jmp");
:"Y"n<<set property("Spec Limits", {LSL(75), USL(78)});
dt<<clear select;
dt:wafer<<set data type("Character");//Temporary change to this to become character - for nominal data would need to add a section to check data type and alter the script in a choice of two different expressions (a script for character and script for nominal)
dt<<New Column("Y2", "Numeric", "Continuous", Formula(Random Normal(20,10)));
:"Y2"n<<set property("Spec Limits", {LSL(0), USL(20)});
//Set up your initial graph/visualisation - this is set up for Graph builder but should be interchangable
gb_expr=gb=Graph Builder(
Variables( X( :Wafer ), Y( :Y ) ),
Elements( Points( X, Y, Legend( 5 ) ) ),
);
//Apply a column switcher
columnswitcher=gb<<Column Switcher( :Y, {:Y, :Y2} );//define your column names here
//Define the initial column name and create a blank for the previous column used in the switcher
col_name="Y";
previousColumn = "";
report(gb)[FrameBox(1)]<< add graphics script( ( checkAndRunScript();));//grab the current column name and run the method in run_expr;
// Function to check for changes and run the script
checkAndRunScript = function( {},
currentColumn = columnSwitcher << get current;
if (currentColumn != previousColumn,
previousColumn = currentColumn;
run_expr;
),
-1;//return -1 if no changes happens = this is needed to stop the script running again and again
);
get_limits_expr=expr(
//get the limits
Spec_limits = dt:Y_name << get property( "Spec Limits" );
USL_val=try(spec_limits["usl"]);
LSL_val=try(spec_limits["lsl"]);
);
// Calculate the mean for each wafer group
get_means_expr=expr(Summarize( wafer_meangroup= By( :Wafer ),value_means= Mean(y_name) ););
checklist_Expr=expr(failed_rows={}; //create a blank list that can store the rows that have failed
//add to an associative array
Assoc_array=associative array(wafer_meangroup,value_means); //get the association of wafer name to the mean value
//Run a for loop that checks every item in the wafer>mean list and sees if it exceeds the USL, if it does then it's inserted into the failed_rows list
for(i=1, i<=n items(Assoc_array),i++,
if(Assoc_array[wafer_meangroup[i]]>=usl_val, insert into(failed_rows, dt<<get rows where(:Wafer==wafer_meangroup[i])), {};
));
//Run a for loop that checks every item in the wafer<mean list and sees if it exceeds the LSL, if it does then it's inserted into the failed_rows list
for(i=1, i<=n items(Assoc_array),i++,
if(Assoc_array[wafer_meangroup[i]]<=lsl_val, insert into(failed_rows, dt<<get rows where(:Wafer==wafer_meangroup[i])), {};
));
);
convertlist_Expr=expr(
//Convert the failed rows list from a nested list to a continuous - probably an easier way to achieve this!
// Create a location to store the list
continuous_failed_Rows = {};
// Loop through each sublist in the nested list
for (i = 1, i <= N Items(failed_rows), i++,
// Loop through each element in the sublist
for (j = 1, j <= N Items(failed_rows[i]), j++,
// Insert each element into the continuous list
Insert Into(continuous_failed_Rows, failed_rows[i][j]);
)
);
// Display the continuous list
Write(continuous_failed_Rows););
colour_rows=expr(
dt<<select rows(continuous_failed_Rows);
dt<<colors("red");
dt<<invert row selection;
dt<<colors("green"););
get_col_name_expr=expr(Y_name=column(col_name));
run_expr=expr(
get_col_name_expr;
get_limits_expr;
get_means_expr;
checklist_Expr;
colour_rows;
);