(FILECREATED "17-Apr-86 16:44:13" {MITFS1-E40:SLOAN% SCHOOL:MASSINSTTECH}<EDAN% KABATCHNIK>BOXPLOT.;7 previous date: "16-Apr-86 17:24:30" {MITFS1-E40:SLOAN% SCHOOL:MASSINSTTECH}<EDAN% KABATCHNIK>BOXPLOT.;4) (* Copyright (c) 1986 by Massachusetts Institute of Technology. All rights reserved.) (PRETTYCOMPRINT BOXPLOTCOMS) (RPAQQ BOXPLOTCOMS ((RECORDS BoxPlotRecord) (FNS BOXPLOT BOXPLOT.CALCULATE BOXPLOT.GETNAMES BOXPLOT.INITIALIZE BOXPLOT.MAKE LISTMAX LISTMIN))) [DECLARE: EVAL@COMPILE (RECORD BoxPlotRecord (Minimum Maximum BoxPlotNumber Median LowerHinge UpperHinge LowerFence UpperFence LeftExtreme RightExtreme Middle LeftMarker RightMarker SortedDataSet Length)) ] (DEFINEQ (BOXPLOT [LAMBDA (ListOfLists OptionalListOfBoxPlotNames OptionalPlotObject) (* enk "17-Apr-86 15:18") (* BOXPLOT accumulates all necessary information for each dataset within the list of lists in BoxPlotData by calling BOXPLOT.CALCULATE and calls BOXPLOT.INITIALIZE to calculate and set the extent of the BoxPlot object. BOXPLOT.MAKE is then called to actually place the BoxPlot parts within the PlotObject.) (LET* [(Plot (if (NULL OptionalPlotObject) then (CREATEPLOT NIL NIL (QUOTE BoxPlot)) else OptionalPlotObject)) (NumberOfBoxPlots (LENGTH ListOfLists)) (BoxPlotNames (BOXPLOT.GETNAMES NumberOfBoxPlots 1 OptionalListOfBoxPlotNames)) (BoxPlotData (for BoxPlotNumber from 1 to NumberOfBoxPlots as DataSet in ListOfLists collect (BOXPLOT.CALCULATE Plot DataSet BoxPlotNumber] (BOXPLOT.INITIALIZE Plot NumberOfBoxPlots BoxPlotData BoxPlotNames) (for BoxPlotRecordItem in BoxPlotData as BoxPlotName in BoxPlotNames do (BOXPLOT.MAKE Plot BoxPlotRecordItem BoxPlotName) finally (REDRAWPLOTWINDOW Plot) (RETURN Plot]) (BOXPLOT.CALCULATE [LAMBDA (Plot DataSet BoxPlotNumber) (* enk "16-Apr-86 16:35") (* BOXPLOT.CALCULATE calculates all necessary BoxPlot information and packs it into a BoxPlotRecord which is accumulate by the calling function) (LET* ((Length (LENGTH DataSet)) [SortedDataSet (MAKEARRAY Length (QUOTE INITIALCONTENTS) (SORT DataSet (QUOTE LESSP] (Minimum (AREF SortedDataSet 0)) (Maximum (AREF SortedDataSet (DIFFERENCE Length 1))) (DepthOfMedian (FIX (FQUOTIENT (FDIFFERENCE Length 1) 2.0))) (Median (if (ODDP Length) then (AREF SortedDataSet DepthOfMedian) else (FQUOTIENT (FPLUS (AREF SortedDataSet DepthOfMedian) (AREF SortedDataSet (PLUS DepthOfMedian 1))) 2.0))) (DepthOfLowerHinge (FQUOTIENT DepthOfMedian 2.0)) [LowerHinge (LET ((IntegerDepthOfLowerHinge (FIX DepthOfLowerHinge))) (if (EVENP DepthOfMedian) then (AREF SortedDataSet IntegerDepthOfLowerHinge) else (FQUOTIENT (FPLUS (AREF SortedDataSet IntegerDepthOfLowerHinge) (AREF SortedDataSet (PLUS IntegerDepthOfLowerHinge 1))) 2.0] (DepthOfUpperHinge (FIX (FPLUS Length (MINUS DepthOfLowerHinge) -1))) (UpperHinge (if (EVENP DepthOfMedian) then (AREF SortedDataSet DepthOfUpperHinge) else (FQUOTIENT (FPLUS (AREF SortedDataSet DepthOfUpperHinge) (AREF SortedDataSet (PLUS DepthOfUpperHinge 1))) 2.0))) (HSpread (FDIFFERENCE UpperHinge LowerHinge)) (LowerFence (FDIFFERENCE LowerHinge (FTIMES 1.5 HSpread))) (UpperFence (FPLUS UpperHinge (FTIMES 1.5 HSpread))) (LeftExtreme (FDIFFERENCE BoxPlotNumber .25)) (RightExtreme (FPLUS BoxPlotNumber .25)) (Middle BoxPlotNumber) (LeftMarker (FDIFFERENCE BoxPlotNumber .05)) (RightMarker (FPLUS BoxPlotNumber .05))) (create BoxPlotRecord Minimum ← Minimum Maximum ← Maximum BoxPlotNumber ← BoxPlotNumber Median ← Median LowerHinge ← LowerHinge UpperHinge ← UpperHinge LowerFence ← LowerFence UpperFence ← UpperFence LeftExtreme ← LeftExtreme RightExtreme ← RightExtreme Middle ← Middle LeftMarker ← LeftMarker RightMarker ← RightMarker SortedDataSet ← SortedDataSet Length ← Length]) (BOXPLOT.GETNAMES [LAMBDA (TotalNumberOfBoxPlots BoxPlotCounter ListOfBoxPlotNames) (* enk "17-Apr-86 16:39") (if (GREATERP BoxPlotCounter TotalNumberOfBoxPlots) then NIL elseif (NULL ListOfBoxPlotNames) then (CONS (CONCAT "DataSet" (MKSTRING BoxPlotCounter)) (BOXPLOT.GETNAMES TotalNumberOfBoxPlots (PLUS BoxPlotCounter 1))) else (CONS (CAR ListOfBoxPlotNames) (BOXPLOT.GETNAMES TotalNumberOfBoxPlots (PLUS BoxPlotCounter 1) (CDR ListOfBoxPlotNames]) (BOXPLOT.INITIALIZE [LAMBDA (Plot NumberOfBoxPlots BoxPlotData BoxPlotNames) (* enk "17-Apr-86 15:46") (* BOXPLOT.INITIALIZE calculates the extent of the BoxPlot and sets the interval of the X and Y axes. It also creates two dummy points in the lower-left and upper-right hand corner of the BoxPlot to prevent a rescale function from making the BoxPlot ugly.) (LET* ([MinimumY (fetch (BoxPlotRecord Minimum) of (for BoxPlotItem in BoxPlotData smallest (fetch (BoxPlotRecord Minimum) of BoxPlotItem] [MaximumY (fetch (BoxPlotRecord Maximum) of (for BoxPlotItem in BoxPlotData largest (fetch (BoxPlotRecord Maximum) of BoxPlotItem] (ModifyY (TIMES (DIFFERENCE MaximumY MinimumY) .05)) (RelativeMinimumY (DIFFERENCE MinimumY ModifyY)) (RelativeMaximumY (PLUS MaximumY ModifyY))) (* The following block sets the extent of the X-axis.) (PLOTAXISINTERVAL Plot (QUOTE X) (CHOOSESCALE 0.0 NumberOfBoxPlots) T) (* The following block sets the extent of the Y-axis.) (PLOTAXISINTERVAL Plot (QUOTE Y) (CHOOSESCALE RelativeMinimumY RelativeMaximumY) T) (PLOTTICS Plot (QUOTE LEFT) (QUOTE BOTH) T) (PLOTTICS Plot (QUOTE BOTTOM) (QUOTE BOTH) T) (PLOTTICMETHOD Plot (QUOTE BOTTOM) (for I from 1 to NumberOfBoxPlots as BoxPlotName in BoxPlotNames collect (CONS I BoxPlotName)) T) (* The following two blocks create the dummy points.) (PLOTPOINT Plot (create POSITION XCOORD ← 0 YCOORD ← RelativeMinimumY) NIL CIRCLE NIL T) (PLOTPOINT Plot (create POSITION XCOORD ←(PLUS NumberOfBoxPlots 1) YCOORD ← RelativeMaximumY) NIL CIRCLE NIL T) NIL]) (BOXPLOT.MAKE [LAMBDA (Plot BoxPlotRecordItem BoxPlotName) (* enk "17-Apr-86 14:58") (LET ((BoxPlotNumber (fetch BoxPlotNumber BoxPlotRecordItem)) (Median (fetch Median BoxPlotRecordItem)) (LowerHinge (fetch LowerHinge BoxPlotRecordItem)) (UpperHinge (fetch UpperHinge BoxPlotRecordItem)) (LowerFence (fetch LowerFence BoxPlotRecordItem)) (UpperFence (fetch UpperFence BoxPlotRecordItem)) (LeftExtreme (fetch LeftExtreme BoxPlotRecordItem)) (RightExtreme (fetch RightExtreme BoxPlotRecordItem)) (Middle (fetch Middle BoxPlotRecordItem)) (LeftMarker (fetch LeftMarker BoxPlotRecordItem)) (RightMarker (fetch RightMarker BoxPlotRecordItem)) (SortedDataSet (fetch SortedDataSet BoxPlotRecordItem)) (Length (fetch Length BoxPlotRecordItem))) (* The following block creates the Median) (PLOTCURVE Plot (LIST (create POSITION XCOORD ← LeftExtreme YCOORD ← Median) (create POSITION XCOORD ← RightExtreme YCOORD ← Median)) (LIST BoxPlotName (LIST (QUOTE Median:) Median)) 3 NIL T) (* The following 2 blocks create the sides of the box) (PLOTCURVE Plot (LIST (create POSITION XCOORD ← LeftExtreme YCOORD ← LowerHinge) (create POSITION XCOORD ← LeftExtreme YCOORD ← UpperHinge)) NIL 2 NIL T) (PLOTCURVE Plot (LIST (create POSITION XCOORD ← RightExtreme YCOORD ← LowerHinge) (create POSITION XCOORD ← RightExtreme YCOORD ← UpperHinge)) NIL 2 NIL T) (* The following block creates the UpperHinge) (PLOTCURVE Plot (LIST (create POSITION XCOORD ← LeftExtreme YCOORD ← UpperHinge) (create POSITION XCOORD ← RightExtreme YCOORD ← UpperHinge)) (LIST BoxPlotName (LIST (QUOTE UpperHinge:) UpperHinge)) 2 NIL T) (* The following block creates the LowerHinge) (PLOTCURVE Plot (LIST (create POSITION XCOORD ← LeftExtreme YCOORD ← LowerHinge) (create POSITION XCOORD ← RightExtreme YCOORD ← LowerHinge)) (LIST BoxPlotName (LIST (QUOTE LowerHinge:) LowerHinge)) 2 NIL T) (* The following block finds and creates the UpperAdjacentValue, the LowerAdjacentValue, and all Outliers) (bind (LowerAdjacentValue ← NIL) (UpperAdjacentValue ← NIL) (NOVBLAVALH ← 0) (NOVBUHAUAV ← 0) for X from 0 to (DIFFERENCE Length 1) do (LET ((ADataItem (AREF SortedDataSet X))) (if (OR (GREATERP ADataItem UpperFence) (LESSP ADataItem LowerFence)) then (PLOTPOINT Plot (create POSITION XCOORD ← Middle YCOORD ← ADataItem) (LIST BoxPlotName (LIST (QUOTE Outlier:) ADataItem)) CIRCLE NIL T) else (if (NULL UpperAdjacentValue) then (SETQ LowerAdjacentValue ADataItem)) (if (LESSP ADataItem LowerHinge) then (SETQ NOVBLAVALH (ADD1 NOVBLAVALH)) elseif (GREATERP ADataItem UpperHinge) then (SETQ NOVBUHAUAV (ADD1 NOVBUHAUAV))) (SETQ UpperAdjacentValue ADataItem))) finally (PLOTCURVE Plot (LIST (create POSITION XCOORD ← LeftMarker YCOORD ← LowerAdjacentValue) (create POSITION XCOORD ← RightMarker YCOORD ← LowerAdjacentValue)) (LIST BoxPlotName (LIST (QUOTE LowerAdjacentValue:) LowerAdjacentValue)) 1 NIL T) (PLOTCURVE Plot (LIST (create POSITION XCOORD ← Middle YCOORD ← LowerAdjacentValue) (create POSITION XCOORD ← Middle YCOORD ← LowerHinge)) (LIST BoxPlotName (LIST (QUOTE ValuesWithin:) (DIFFERENCE NOVBLAVALH 1))) 1 NIL T) (PLOTCURVE Plot (LIST (create POSITION XCOORD ← LeftMarker YCOORD ← UpperAdjacentValue) (create POSITION XCOORD ← RightMarker YCOORD ← UpperAdjacentValue)) (LIST BoxPlotName (LIST (QUOTE UpperAdjacentValue:) UpperAdjacentValue)) 1 NIL T) (PLOTCURVE Plot (LIST (create POSITION XCOORD ← Middle YCOORD ← UpperAdjacentValue) (create POSITION XCOORD ← Middle YCOORD ← UpperHinge)) (LIST BoxPlotName (LIST (QUOTE ValuesWithin:) (DIFFERENCE NOVBUHAUAV 1))) 1 NIL T))) NIL]) (LISTMAX [LAMBDA (List) (* enk "15-Apr-86 16:07") (if (NULL List) then MIN.FLOAT else (MAX (CAR List) (LISTMAX (CDR List]) (LISTMIN [LAMBDA (List) (* enk "15-Apr-86 16:06") (if (NULL List) then MAX.FLOAT else (MIN (CAR List) (LISTMIN (CDR List]) ) (PUTPROPS BOXPLOT COPYRIGHT ("Massachusetts Institute of Technology" 1986)) STOP