Individual Measurements Chart with Boxplot

 /****************************************************************/
 /*          S A S   S A M P L E   L I B R A R Y                 */
 /*                                                              */
 /*    NAME: SHWIBOX                                             */
 /*   TITLE: Individual Measurements Chart with Boxplot          */
 /* PRODUCT: QC                                                  */
 /*  SYSTEM: ALL                                                 */
 /*    KEYS: Shewhart Charts, Individual Measurements Charts,    */
 /*   PROCS: SHEWHART CAPABILITY                                 */
 /*    DATA:                                                     */
 /*                                                              */
 /*     REF: SAS/QC Software:  Examples                          */
 /*                                                              */
 /****************************************************************/

  options ps=60 ls=80;

  data plates;
     label gap    = 'Plate Gap in cm'
           sample = 'Sample Number';
     input gap @@; sample+1;
     cards;
  0.746  0.357  0.376  0.327  0.485
  1.741  0.241  0.777  0.768  0.409
  0.252  0.512  0.534  1.656  0.742
  0.378  0.714  1.121  0.597  0.231
  0.541  0.805  0.682  0.418  0.506
  0.501  0.247  0.922  0.880  0.344
  0.519  1.302  0.275  0.601  0.388
  0.450  0.845  0.319  0.486  0.529
  1.547  0.690  0.676  0.314  0.736
  0.643  0.483  0.352  0.636  1.080
  ;

  proc capability data=plates normaltest;
     var gap;
     output out=quantile
            min=min q1=q1 median=median mean=mean q3=q3 max=max;
  run;

  data boxplot;
     length function color style $ 8;
     retain xsys '3' ysys '2' color 'black';
     drop   min q1 median q3 max center halfwd;
     set quantile;

     center = 95;
     halfwd = 3;
     qrtrwd = 0.5 * halfwd;

     line   =  0;
     style  = 'E';

     /* draw the box outline */
     function = 'MOVE';   x = center - halfwd; y = q1;     output;
     function = 'BAR' ;   x = center + halfwd; y = q3;     output;

     line = 1;
     size = 1;

     /* draw the upper whisker */
     function = 'MOVE';   x = center;          y = q3;     output;
     function = 'DRAW';   x = center;          y = max;    output;
     function = 'MOVE';   x = center - qrtrwd; y = max;    output;
     function = 'DRAW';   x = center + qrtrwd; y = max;    output;

     /* draw the lower whisker */
     function = 'MOVE';   x = center;          y = q1;     output;
     function = 'DRAW';   x = center;          y = min;    output;
     function = 'MOVE';   x = center - qrtrwd; y = min;    output;
     function = 'DRAW';   x = center + qrtrwd; y = min;    output;

     /* draw the center line for the median */
     function = 'MOVE';   x = center - halfwd; y = median; output;
     function = 'DRAW';   x = center + halfwd; y = median; output;

     /* draw an asterisk for the mean */
     size     = 1;
     position = '5';
     style    = 'NONE';
     function = 'LABEL';  text = '*';
                          x = center;          y = mean;   output;
  run;

  data frame;
     retain  xsys '3' ysys '1' color 'black' style 'E' line 0;
     function = 'MOVE'; x =  91; y = 0;   output;
     function = 'BAR' ; x =  99; y = 100; output;
  run;

  symbol1 v=dot h=.75 c=white;

  title  'Analysis of Plate Gap Variation';
  title2 'Incorrectly Assuming Normality' ;

  proc shewhart data=plates anno=frame;
     irchart gap * sample / rtm       = 22
                            alpha     = 0.02
                            outlimits = nrmllim
                            cframe    = gray
                            cinfill   = blue
                            separate
                            nochart2
                            novangle
                            annotate  = boxplot;
  run;

  proc capability data=plates noprint ;
     var gap;
     histogram / lognormal( noprint threshold = 0 )
                 outfit = lnfit
                 nochart;
  run;

  data lnrmllim;
     merge nrmllim lnfit;
     drop _sigmas_ ;
     _lcli_ = _locatn_ +
               exp(_scale_ + probit(      0.5*_alpha_)*_shape1_);
     _ucli_ = _locatn_ +
              exp(_scale_ + probit(1.0 - 0.5*_alpha_)*_shape1_);
     _mean_ = _locatn_ +
              exp(_scale_ + 0.5*_shape1_*_shape1_             );
  run;

  title  'Analysis of Plate Gap Variation';
  title2 'Lognormal Probability Limits'   ;

  proc shewhart data=plates anno=frame limits=lnrmllim;
     irchart gap * sample / rtmargin = 22
                            readlimits
                            separate
                            nochart2
                            novangle
                            cframe   = gray
                            cinfill  = blue
                            annotate = boxplot;
  run;

  goptions reset=all;