(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