(DEFINE-FILE-INFO READTABLE "INTERLISP" PACKAGE "INTERLISP")
(FILECREATED " 5-May-87 15:24:37" {PHYLUM}<LISPUSERS>LYRIC>PLOTEXAMPLES.;1 37750  

      changes to%:  (FNS HISTO.DRAW HISTPLOT MAKEBININTERVAL SCATPLOT SCAT.LOGSCALE LOGTICFN)

      previous date%: "18-Jun-86 12:50:08" {PHYLUM}<LISPUSERS>KOTO>PLOTEXAMPLES.;1)


(* "
Copyright (c) 1986, 1987 by Xerox Corporation.  All rights reserved.
")

(PRETTYCOMPRINT PLOTEXAMPLESCOMS)

(RPAQQ PLOTEXAMPLESCOMS ((* * HISTOGRAM FNS)
                         (FNS COMPUTEMULTIPLE HISTO.CHANGEBINS HISTO.COPYFN HISTO.DRAW 
                              HISTO.INTSCALEFN HISTO.INTTICFN HISTO.MAKEBINS HISTO.RESET HISTO.TICFN 
                              HISTO.VALUES HISTPLOT MAKEBININTERVAL SUMMARYWINDOW.REPAINTFN)
                         (RECORDS BININTERVAL)
                         (* * SCATTERPLOT FNS)
                         (FNS SCATPLOT SCAT.LOGSCALE SCAT.POINTCOORDS SCAT.WORLDCOORD LOGTICFN)
                         (* * Depends on PLOT)
                         (FILES PLOT)
                         (MACROS HISTO.GETFREQ HISTO.GETVALUE)
                         (DECLARE%: DONTCOPY DONTEVAL@LOAD DOEVAL@COMPILE (LOCALVARS . T))))
(* * HISTOGRAM FNS)

(DEFINEQ

(COMPUTEMULTIPLE
  [LAMBDA (MIN MAX INC MUTIPLE)                              (* jop%: "25-Feb-86 12:15")
          
          (* *)

    (LET* [(NEWINC (TIMES INC MUTIPLE))
           (MINMULT (PLOT.FLOOR (QUOTIENT MIN NEWINC)))
           (MAXMULT (PLOT.CEILING (QUOTIENT MAX NEWINC]
          (create TICINFO
                 TICMIN _ (TIMES MINMULT NEWINC)
                 TICMAX _ (TIMES MAXMULT NEWINC)
                 TICINC _ NEWINC
                 NTICS _ (ADD1 (DIFFERENCE MAXMULT MINMULT])

(HISTO.CHANGEBINS
  [LAMBDA (HISTOGRAM)                                        (* jop%: "27-Feb-86 15:05")
          
          (* * Allow the use to specify a range and a bin interval for the histogram)

    (PROG ((PLOTPROMPTWINDOW (PLOTPROP HISTOGRAM 'PLOTPROMPTWINDOW))
           (INTFLG (PLOTPROP HISTOGRAM 'INTFLG))
           (BININTERVAL (PLOTPROP HISTOGRAM 'BININTERVAL))
           INC START END NBINS)
          (SETQ INC (fetch (BININTERVAL BININC) of BININTERVAL))
          (SETQ START (fetch (BININTERVAL BINMIN) of BININTERVAL))
          (SETQ END (fetch (BININTERVAL BINMAX) of BININTERVAL))
                                                             (* have a dialogue with the user)
          (TERPRI PLOTPROMPTWINDOW)
          [SETQ START (READ (OPENSTRINGSTREAM (PROMPTFORWORD "From " START 
                                                     "Type start point of bin sequence" 
                                                     PLOTPROMPTWINDOW]
          (SETQ START (if INTFLG
                          then (PLOT.FLOOR START)
                        else (FLOAT START)))
          [SETQ END (READ (OPENSTRINGSTREAM (PROMPTFORWORD " to " END 
                                                   "Type end point of bin sequence" PLOTPROMPTWINDOW]
          (SETQ END (if INTFLG
                        then (PLOT.CEILING END)
                      else (FLOAT END)))
          [SETQ INC (READ (OPENSTRINGSTREAM (PROMPTFORWORD " by " INC "Type an increment" 
                                                   PLOTPROMPTWINDOW]
          (SETQ INC (if INTFLG
                        then (PLOT.CEILING INC)
                      else (FLOAT INC)))
          (SETQ NBINS (PLOT.CEILING (FQUOTIENT (DIFFERENCE END START)
                                           INC)))
          (SETQ END (PLUS START (TIMES INC NBINS)))
          (if INTFLG
              then (SETQ NBINS (ADD1 NBINS)))                (* Inform the user of what will happen)
          (PLOTPROMPT (CONCAT "Using: from " START " to " END " by " INC)
                 HISTOGRAM)
          (PLOTPROP HISTOGRAM 'BININTERVAL
                 (create BININTERVAL
                        BINMIN _ START
                        BINMAX _ END
                        BININC _ INC
                        NBINS _ NBINS))                      (* redraw the histogram based on the 
                                                             new parameters)
          (HISTO.DRAW HISTOGRAM])

(HISTO.COPYFN
  [LAMBDA (NEWHIST OLDHIST PROPNAME)                         (* jop%: "24-Feb-86 23:11")
    (SELECTQ PROPNAME
        (N (PLOTPROP OLDHIST 'N))
        (NBINS (PLOTPROP OLDHIST 'NBINS))
        (OBATCH (PLOTPROP OLDHIST 'OBATCH))
        (INTFLG (PLOTPROP OLDHIST 'INTFLG))
        (BINEDNUMBERS (PLOTPROP OLDHIST 'BINEDNUMBERS))
        (MARKS (PLOTPROP OLDHIST 'MARKS))
        NIL])

(HISTO.DRAW
  [LAMBDA (HISTOGRAM)                                        (* edited%: "27-Mar-86 21:56")
          
          (* *)

    (LET* ((SHADE (PLOTPROP HISTOGRAM 'SHADE))
           (OBATCH (PLOTPROP HISTOGRAM 'OBATCH))
           (INTFLG (PLOTPROP HISTOGRAM 'INTFLG))
           (BININTERVAL (OR (PLOTPROP HISTOGRAM 'BININTERVAL)
                            (LET ((NEWINTERVAL (MAKEBININTERVAL (HISTO.GETVALUE (CAR OBATCH))
                                                      (HISTO.GETVALUE (CAR (LAST OBATCH)))
                                                      (PLOTPROP HISTOGRAM 'NBINS)
                                                      INTFLG)))
                                 (PLOTPROP HISTOGRAM 'BININTERVAL NEWINTERVAL)
                                 NEWINTERVAL)))
           (BINMIN (fetch (BININTERVAL BINMIN) of BININTERVAL))
           (BINMAX (fetch (BININTERVAL BINMAX) of BININTERVAL))
           (BININC (fetch (BININTERVAL BININC) of BININTERVAL))
           (NBINS (fetch (BININTERVAL NBINS) of BININTERVAL))
           BINS)                                             (* Erase the old image, if any)
          [for OBJECT in (COPY (PLOTPROP HISTOGRAM 'PLOTOBJECTS))
             do (COND
                   ((AND (PLOTOBJECTSUBTYPE? FILLEDRECTANGLE OBJECT)
                         (PLOTOBJECTPROP OBJECT 'FROMHISTOGRAM?))
                    (DELETEPLOTOBJECT OBJECT HISTOGRAM T T]
          [COND
             (INTFLG (SETQ BINMIN (DIFFERENCE BINMIN 0.5))
                    (SETQ BINMAX (PLUS BINMAX 0.5]
          (SETQ BINS (bind (NUMBERS _ OBATCH)
                           FREQ for I from 1 to NBINS as MARK from (PLUS BINMIN BININC) by BININC
                        eachtime (SETQ FREQ (bind NUM eachtime (SETQ NUM (CAR NUMBERS))
                                               while (AND NUMBERS (LESSP (HISTO.GETVALUE NUM)
                                                                         MARK))
                                               sum (SETQ NUMBERS (CDR NUMBERS))
                                                   (HISTO.GETFREQ NUM)))
                        when (NEQ FREQ 0) collect (CONS MARK FREQ)))
          
          (* An optimization to speed up adding rectangles to the plot --
          extends the scale once)

          (ADJUSTSCALE? [create EXTENT
                               MINX _ BINMIN
                               MAXX _ BINMAX
                               MINY _ 0
                               MAXY _ (CDR (for BIN in BINS largest (CDR BIN]
                 HISTOGRAM)                                  (* Construct the new image)
          (RESETLST [RESETSAVE (FLTFMT '(FLOAT NIL NIL NIL NIL 5]
                                                             (* Round to five significant figures)
                 (RESETSAVE PRXFLG T)
                 (bind RECTANGLE LOWMARK HIGHMARK FREQ for BIN in BINS
                    do (SETQ HIGHMARK (CAR BIN))
                       (SETQ LOWMARK (DIFFERENCE HIGHMARK BININC))
                       (SETQ FREQ (CDR BIN))
                       (SETQ RECTANGLE
                        (PLOTFILLEDRECTANGLE HISTOGRAM LOWMARK 0 BININC FREQ
                               (COND
                                  [INTFLG (LET ((ILOWMARK (PLOT.CEILING LOWMARK))
                                                (IHIGHMARK (PLOT.FLOOR HIGHMARK)))
                                               (COND
                                                  ((IEQP ILOWMARK IHIGHMARK)
                                                   (CONCAT FREQ " Obs. at " ILOWMARK))
                                                  (T (CONCAT FREQ " Obs. between " ILOWMARK " and " 
                                                            IHIGHMARK]
                                  (T (CONCAT FREQ " Obs. between " LOWMARK " and " HIGHMARK)))
                               SHADE NIL 'BINMENU T))
                       (PLOTOBJECTPROP RECTANGLE 'FROMHISTOGRAM? T)
                       (PLOTOBJECTPROP RECTANGLE 'LOWMARK LOWMARK)
                       (PLOTOBJECTPROP RECTANGLE 'HIGHMARK HIGHMARK)))
                                                             (* Rescale the Histogram)
          (RESCALEPLOT HISTOGRAM 'BOTH T)                    (* refresh the image)
          (REDRAWPLOTWINDOW HISTOGRAM])

(HISTO.INTSCALEFN
  [LAMBDA (MIN MAX TICINFO)                                  (* jop%: "24-Feb-86 23:29")
    (with TICINFO TICINFO (create AXISINTERVAL
                                 MIN _ (DIFFERENCE TICMIN 0.5)
                                 MAX _ (PLUS TICMAX 0.5])

(HISTO.INTTICFN
  [LAMBDA (MIN MAX)                                          (* jop%: "12-Feb-86 22:38")
          
          (* *)

    (LET* ((INTMAX (PLOT.FLOOR MAX))
           (INTMIN (PLOT.CEILING MIN))
           (TICINFO (DEFAULTTICFN INTMIN INTMAX))
           NEWMAX NEWMIN INC NTICS)
          [SETQ NEWMIN (IMIN INTMIN (PLOT.CEILING (fetch (TICINFO TICMIN) of TICINFO]
          (SETQ INC (PLOT.CEILING (fetch (TICINFO TICINC) of TICINFO)))
          [SETQ NTICS (ADD1 (PLOT.CEILING (FQUOTIENT (DIFFERENCE INTMAX NEWMIN)
                                                 INC]
          [SETQ NEWMAX (IPLUS NEWMIN (ITIMES INC (SUB1 NTICS]
          (create TICINFO
                 TICMIN _ NEWMIN
                 TICMAX _ NEWMAX
                 TICINC _ INC
                 NTICS _ NTICS])

(HISTO.MAKEBINS
  [LAMBDA (HISTOGRAM)                                        (* jop%: "24-Feb-86 23:07")
          
          (* * Computes a BIN interval and the BINEDNUMBERS based on PLOT props.)

    (PROG ((OBATCH (PLOTPROP HISTOGRAM 'OBATCH))
           (BININTERVAL (PLOTPROP HISTOGRAM 'BININTERVAL))
           (INTFLG (PLOTPROP HISTOGRAM 'INTFLG))
           NBINS MARKS BINEDNUMBERS)
          (if (NULL BININTERVAL)
              then (SETQ BININTERVAL (MAKEBININTERVAL (HISTO.GETVALUE (CAR OBATCH))
                                            (HISTO.GETVALUE (CAR (LAST OBATCH)))
                                            (PLOTPROP HISTOGRAM 'NBINS)
                                            INTFLG)))
          
          (* MARKS is a list of the NBINS plus 1 bin end points)

          (SETQ NBINS (fetch (BININTERVAL NBINS) of BININTERVAL))
          (SETQ MARKS
           (LET ((BINMIN (fetch (BININTERVAL BINMIN) of BININTERVAL))
                 (BINMAX (fetch (BININTERVAL BINMAX) of BININTERVAL))
                 (BININC (fetch (BININTERVAL BININC) of BININTERVAL)))
                (if INTFLG
                    then (SETQ BINMIN (DIFFERENCE BINMIN 0.5))
                         (SETQ BINMAX (PLUS BINMAX 0.5)))
                (NCONC1 (for I from 1 to NBINS as MARK from BINMIN by BININC collect MARK)
                       BINMAX)))
          
          (* BINEDNUMBERS is a list of numbers, one for each bin, so that each entry is 
          the number of elements of BATCH that fall in that bin)

          [SETQ BINEDNUMBERS (bind (NUMBERS _ OBATCH) for MARK in (CDR MARKS)
                                collect (bind NUM eachtime (SETQ NUM (CAR NUMBERS))
                                           while (AND NUMBERS (LESSP (HISTO.GETVALUE NUM)
                                                                     MARK))
                                           sum (SETQ NUMBERS (CDR NUMBERS))
                                               (HISTO.GETFREQ NUM]
          (PLOTPROP HISTOGRAM 'BININTERVAL BININTERVAL)
          (PLOTPROP HISTOGRAM 'BINEDNUMBERS BINEDNUMBERS)
          (PLOTPROP HISTOGRAM 'MARKS MARKS])

(HISTO.RESET
  [LAMBDA (HISTOGRAM)                                        (* jop%: "27-Feb-86 15:06")
          
          (* * Resets the range and bin interval to their original values)

    (PLOTPROP HISTOGRAM 'BININTERVAL NIL)
    (HISTO.DRAW HISTOGRAM])

(HISTO.TICFN
  [LAMBDA (MIN MAX HISTOGRAM)                                (* jop%: "25-Feb-86 12:43")
          
          (* *)

    (LET* ((RANGE (DIFFERENCE MAX MIN))
           (BININTERVAL (PLOTPROP HISTOGRAM 'BININTERVAL))
           (BININC (fetch (BININTERVAL BININC) of BININTERVAL))
           (NBINS (fetch (BININTERVAL NBINS) of BININTERVAL)))
          (bind (MININTERVALLENGTH _ MAX.FLOAT)
                MININTERVAL INTERVAL INTERVALLENGTH for MULTIPLE
             from (PLOT.CEILING (QUOTIENT RANGE (TIMES BININC 9)))
             to (PLOT.CEILING (QUOTIENT RANGE BININC)) do (SETQ INTERVAL (COMPUTEMULTIPLE MIN MAX 
                                                                                BININC MULTIPLE))
                                                          (SETQ INTERVALLENGTH (fetch (TICINFO 
                                                                                    TICINTERVALLENGTH
                                                                                             )
                                                                                  of INTERVAL))
                                                          (if (LESSP INTERVALLENGTH MININTERVALLENGTH
                                                                     )
                                                              then (SETQ MININTERVAL INTERVAL)
                                                                   (SETQ MININTERVALLENGTH 
                                                                    INTERVALLENGTH))
             finally (RETURN MININTERVAL])

(HISTO.VALUES
  [LAMBDA (RECTANGLE HISTOGRAM)                              (* jop%: "24-Feb-86 23:25")
    (PROG [(SUMMARYWINDOW (WINDOWPROP (PLOTPROP HISTOGRAM 'PLOTWINDOW)
                                 'SUMMARYWINDOW))
           (LOWMARK (PLOTOBJECTPROP RECTANGLE 'LOWMARK))
           (HIGHMARK (PLOTOBJECTPROP RECTANGLE 'HIGHMARK))
           (OBATCH (PLOTPROP HISTOGRAM 'OBATCH]
          (COND
             ((NULL SUMMARYWINDOW)                           (* Make a window five chars high)
              (SETQ SUMMARYWINDOW (CREATEW (CREATEREGION 0 0 100
                                                  (HEIGHTIFWINDOW (ITIMES 5
                                                                         (FONTPROP
                                                                          (DEFAULTFONT 'DISPLAY)
                                                                          'HEIGHT))
                                                         T))
                                         "SUMMARY WINDOW" NIL T))
                                                             (* Supply a simple repaintfn)
              (WINDOWADDPROP SUMMARYWINDOW 'REPAINTFN (FUNCTION SUMMARYWINDOW.REPAINTFN))
              (WINDOWADDPROP SUMMARYWINDOW 'RESHAPEFN (FUNCTION SUMMARYWINDOW.REPAINTFN))
              (WINDOWPROP (PLOTPROP HISTOGRAM 'PLOTWINDOW)
                     'SUMMARYWINDOW SUMMARYWINDOW)))         (* cache the output as a window prop)
          (WINDOWPROP SUMMARYWINDOW 'OUTPUT (bind NUM for ITEM in OBATCH eachtime (SETQ NUM
                                                                                   (HISTO.GETVALUE
                                                                                    ITEM))
                                               when (AND (GEQ NUM LOWMARK)
                                                         (LESSP NUM HIGHMARK)) collect ITEM))
          
          (* If the window is not yet attached, then attach it)

          (COND
             ((NOT (OPENWP SUMMARYWINDOW))
              (ATTACHWINDOW SUMMARYWINDOW (fetch PLOTWINDOW of HISTOGRAM)
                     'TOP NIL 'LOCALCLOSE))
             (T (SUMMARYWINDOW.REPAINTFN SUMMARYWINDOW])

(HISTPLOT
  [LAMBDA (BATCH LABEL SHADE)                                (* jop%: "27-Feb-86 22:55")
          
          (* * Batch is assumed to be a list of numbers or a list of pairs
          (number . frequency) Label, a label to be associated with those numbers)

    (PROG ((HISTOGRAM (CREATEPLOT))
           (BINMENU (LIST (LIST 'Values (FUNCTION HISTO.VALUES)
                                "Output values in bin")))
           [RIGHTMENUITEMS (LIST (LIST 'Change% bins (FUNCTION HISTO.CHANGEBINS)
                                       "Change number of bins"
                                       (LIST 'SUBITEMS (LIST 'RESET (FUNCTION HISTO.RESET)
                                                             
                                                     "Reset range and bin interval to original value"
                                                             ]
           (LEFTLABEL "Frequency")
           (BOTTOMLABEL (OR LABEL "Values"))
           (N (for ITEM in BATCH sum (HISTO.GETFREQ ITEM)))
           (TOPLABEL (COND
                        (LABEL (CONCAT "Histogram of " LABEL))
                        (T "Histogram")))
           OBATCH INTFLG NBINS)
          
          (* * BINMENU is aspecial menu for the rectangle of the histogram.
          RIGHTMENUITEMS are additional right menu items.)

          [SETQ OBATCH (SORT (COPY BATCH)
                             (FUNCTION (LAMBDA (X Y)
                                         (LESSP (HISTO.GETVALUE X)
                                                (HISTO.GETVALUE Y]
                                                             (* Order the data)
          [SETQ INTFLG (for X in OBATCH always (FIXP (HISTO.GETVALUE X]
                                                             (* check if data are all integers)
          [SETQ NBINS (COND
                         [INTFLG (ADD1 (DIFFERENCE (HISTO.GETVALUE (CAR (LAST OBATCH)))
                                              (HISTO.GETVALUE (CAR OBATCH]
                         (T (COND
                               [(LESSP N 20)
                                (FIX (TIMES 2 (SQRT N]
                               (T (FIX (TIMES 10 (PLOT.LOG10 N]
                                                             (* Default number of bins set by an 
                                                             heuristic)
                                                             (* Set up a few key PLOT PROP'S)
          (PLOTPROP HISTOGRAM 'N N)
          (PLOTPROP HISTOGRAM 'NBINS NBINS)
          (PLOTPROP HISTOGRAM 'OBATCH OBATCH)
          (PLOTPROP HISTOGRAM 'INTFLG INTFLG)
          (PLOTPROP HISTOGRAM 'SHADE (OR SHADE SHADE3))      (* Function to copy the plot props)
          (PLOTPROP HISTOGRAM 'COPYFN (FUNCTION HISTO.COPYFN))
          
          (* Initialize the histogram so that labels and tics are displayed)

          (PLOTTICS HISTOGRAM 'BOTTOM T T)
          (PLOTTICS HISTOGRAM 'LEFT T T)
          (PLOTLABEL HISTOGRAM 'BOTTOM BOTTOMLABEL T)
          (PLOTLABEL HISTOGRAM 'LEFT LEFTLABEL T)
          (PLOTLABEL HISTOGRAM 'TOP TOPLABEL T)              (* add items to the right menu)
          (PLOTADDMENUITEMS HISTOGRAM 'RIGHT RIGHTMENUITEMS) (* Establish a special "bin" menu)
          (PLOTMENUITEMS HISTOGRAM 'BINMENU BINMENU)
          [COND
             (INTFLG (PLOTTICFN HISTOGRAM 'X (FUNCTION HISTO.INTTICFN))
                    (PLOTSCALEFN HISTOGRAM 'X (FUNCTION HISTO.INTSCALEFN)))
             (T (PLOTTICFN HISTOGRAM 'X (FUNCTION HISTO.TICFN]
                                                             (* Draw the histogram based on the 
                                                             PLOT PROP's)
          (HISTO.DRAW HISTOGRAM)                             (* Returns a PLOT)
          (RETURN HISTOGRAM])

(MAKEBININTERVAL
  [LAMBDA (BATCHMIN BATCHMAX NBINS INTFLG)                   (* jop%: "25-Feb-86 12:48")
          
          (* *)

    (COND
       [INTFLG (LET ((NINT (ADD1 (IDIFFERENCE BATCHMAX BATCHMIN)))
                     MULT)
                    (COND
                       ((IGEQ NBINS NINT)
                        (create BININTERVAL
                               BINMIN _ BATCHMIN
                               BINMAX _ BATCHMAX
                               BININC _ 1
                               NBINS _ NINT))
                       (T (SETQ MULT (PLOT.CEILING (FQUOTIENT (DIFFERENCE BATCHMAX BATCHMIN)
                                                          NBINS)))
                          (create BININTERVAL
                                 BINMIN _ BATCHMIN
                                 BINMAX _ (PLUS BATCHMIN (TIMES MULT NBINS))
                                 BININC _ MULT
                                 NBINS _ NBINS]
       (T (LET [(TICINFO (SCALE BATCHMIN BATCHMAX (ADD1 NBINS]
               (create BININTERVAL
                      BINMIN _ (fetch (TICINFO TICMIN) of TICINFO)
                      BINMAX _ (fetch (TICINFO TICMAX) of TICINFO)
                      BININC _ (fetch (TICINFO TICINC) of TICINFO)
                      NBINS _ NBINS])

(SUMMARYWINDOW.REPAINTFN
  [LAMBDA (WINDOW)                                           (* jop%: "12-May-85 14:40")
          
          (* * PRIN1 whatever happens to be under the OUTPUT PROP)

    (PROG [(OUTPUT (WINDOWPROP WINDOW 'OUTPUT]
          (CLEARW WINDOW)
          (printout WINDOW OUTPUT T])
)
(DECLARE%: EVAL@COMPILE

(RECORD BININTERVAL (BINMIN BINMAX BININC NBINS))
)
(* * SCATTERPLOT FNS)

(DEFINEQ

(SCATPLOT
  [LAMBDA (Y X POINTLABELS YLABEL XLABEL TITLE SYMBOL)       (* jop%: "26-Feb-86 12:44")
          
          (* * X and Y are equal length list of numbers, or X is NIL)

    (COND
       ((NULL X)
        (SETQ X (for I from 1 to (LENGTH Y) collect I)))
       ((NOT (EQLENGTH Y (LENGTH X)))
        (HELP "X and Y must be of equal length")))
    [COND
       ((NULL TITLE)
        (SETQ TITLE (COND
                       ((AND XLABEL YLABEL)
                        (CONCAT "Scatterplot of" YLABEL " vs " XLABEL))
                       (T "Scatterplot"]
    (COND
       ((NULL SYMBOL)
        (SETQ SYMBOL STAR)))
    (LET* [(SCATPLOT (CREATEPLOT))
           [RIGHTMENUITEMS '((Logscale SCAT.LOGSCALE "Toggle exponential tics"
                                    (SUBITEMS (X% axis (SCAT.LOGSCALE 'X)
                                                     "X axis only")
                                           (Y% axis (SCAT.LOGSCALE 'Y)
                                                  "Y axis only")))
                             (Coordinates SCAT.WORLDCOORD 
                                    "Display world coordinates at cursor position"]
           (POINTMENUITEMS '((Coordinates SCAT.POINTCOORDS "Display point coordinates"]
          (PLOTPOINTS SCATPLOT (for XVALUE in X as YVALUE in Y collect (CREATEPOSITION XVALUE YVALUE)
                                    )
                 POINTLABELS SYMBOL 'POINTMENU T)
          (PLOTTICS SCATPLOT 'BOTTOM T T)
          (PLOTTICS SCATPLOT 'LEFT T T)
          (PLOTLABEL SCATPLOT 'BOTTOM XLABEL T)
          (PLOTLABEL SCATPLOT 'LEFT YLABEL T)
          (PLOTLABEL SCATPLOT 'TOP TITLE T)
          (PLOTADDMENUITEMS SCATPLOT 'RIGHT RIGHTMENUITEMS)
          (PLOTMENUITEMS SCATPLOT 'POINTMENU (APPEND (PLOTMENUITEMS SCATPLOT 'MIDDLE)
                                                    POINTMENUITEMS))
          (RESCALEPLOT SCATPLOT 'BOTH T)
          (OPENPLOTWINDOW SCATPLOT)
          SCATPLOT])

(SCAT.LOGSCALE
  [LAMBDA (PLOT AXIS)                                        (* jop%: "25-Feb-86 13:22")
          
          (* * sets up PLOT to have log scale on AXIS --
          X, Y or both)

    [COND
       ((NULL AXIS)
        (SETQ AXIS 'BOTH]
    (PROG ((XON (EQ (PLOTTICFN PLOT 'X)
                    (FUNCTION LOGTICFN)))
           (YON (EQ (PLOTTICFN PLOT 'Y)
                    (FUNCTION LOGTICFN)))
           (XLOWER (fetch (PLOT XLOWER) of PLOT))
           (XUPPER (fetch (PLOT XUPPER) of PLOT))
           (YLOWER (fetch (PLOT YLOWER) of PLOT))
           (YUPPER (fetch (PLOT YUPPER) of PLOT)))
          [COND
             ((OR (EQ AXIS 'X)
                  (EQ AXIS 'BOTH))
              (COND
                 ((AND (NULL XON)
                       (OR (LESSP XLOWER -35)
                           (GREATERP XUPPER 35)))
                  (PLOTPROMPT "X axis scale not appropriate" PLOT))
                 (T (PLOTTICFN PLOT 'X (AND (NULL XON)
                                            (FUNCTION LOGTICFN))
                           T)
                    (PLOTPROP PLOT 'XLABELFN (AND (NULL XON)
                                                  (FUNCTION PLOT.EXP10)))
                    (PLOTPROP PLOT 'XWORLDFN (AND (NULL XON)
                                                  (FUNCTION PLOT.LOG10)))
                    (RESCALEPLOT PLOT 'X T]
          [COND
             ((OR (EQ AXIS 'Y)
                  (EQ AXIS 'BOTH))
              (COND
                 ((AND (NULL YON)
                       (OR (LESSP YLOWER -35)
                           (GREATERP YUPPER 35)))
                  (PLOTPROMPT "Y axis scale not appropriate" PLOT))
                 (T (PLOTTICFN PLOT 'Y (AND (NULL YON)
                                            (FUNCTION LOGTICFN))
                           T)
                    (PLOTPROP PLOT 'YLABELFN (AND (NULL YON)
                                                  (FUNCTION PLOT.EXP10)))
                    (PLOTPROP PLOT 'YWORLDFN (AND (NULL YON)
                                                  (FUNCTION PLOT.LOG10)))
                    (RESCALEPLOT PLOT 'Y T]
          (REDRAWPLOTWINDOW PLOT)
          (RETURN PLOT])

(SCAT.POINTCOORDS
  [LAMBDA (POINTOBJECT SCATTERPLOT)                          (* jop%: "20-Jan-86 21:18")
    (PROG ([POINTPOSITION (fetch (POINTDATA POINTPOSITION) of (PLOTOBJECTPROP POINTOBJECT
                                                                     'OBJECTDATA]
           (XLABEL (CONCAT (OR (PLOTLABEL SCATTERPLOT 'BOTTOM)
                               "XCOORD")
                          " "))
           (YLABEL (CONCAT " " (OR (PLOTLABEL SCATTERPLOT 'LEFT)
                                   "YCOORD")
                          " ")))
          (PLOTPROMPT (CONCAT XLABEL (PLOT.WORLDTOLABEL (fetch XCOORD of POINTPOSITION)
                                            SCATTERPLOT
                                            'X)
                             YLABEL
                             (PLOT.WORLDTOLABEL (fetch YCOORD of POINTPOSITION)
                                    SCATTERPLOT
                                    'Y))
                 SCATTERPLOT])

(SCAT.WORLDCOORD
  [LAMBDA (SCATTERPLOT)                                      (* jop%: "20-Jan-86 17:46")
    (PROG ((PLOTWINDOW (PLOTPROP SCATTERPLOT 'PLOTWINDOW))
           (PLOTPROMPTWINDOW (PLOTPROP SCATTERPLOT 'PLOTPROMPTWINDOW))
           (PLOTVIEWPORT (PLOTPROP SCATTERPLOT 'PLOTWINDOWVIEWPORT))
           (XLABEL (CONCAT (OR (PLOTLABEL SCATTERPLOT 'BOTTOM)
                               "X")
                          " at "))
           (YLABEL (CONCAT " " (OR (PLOTLABEL SCATTERPLOT 'LEFT)
                                   "Y")
                          " at "))
           (OLDCURSORPOS (CONSTANT (create POSITION
                                          XCOORD _ 0
                                          YCOORD _ 0)))
           (NEWCURSORPOS (CONSTANT (create POSITION)))
           STARTXCOORDX STARTXCOORDY STARTYCOORDX STARTYCOORDY)
          (PRINTOUT PLOTPROMPTWINDOW T XLABEL)
          (SETQ STARTXCOORDX (DSPXPOSITION NIL PLOTPROMPTWINDOW))
          (SETQ STARTXCOORDY (DSPYPOSITION NIL PLOTPROMPTWINDOW))
          (PRINTOUT PLOTPROMPTWINDOW .SP 10 YLABEL)
          (SETQ STARTYCOORDX (DSPXPOSITION NIL PLOTPROMPTWINDOW))
          (SETQ STARTYCOORDY (DSPYPOSITION NIL PLOTPROMPTWINDOW))
          (while (MOUSESTATE UP) do (SETQ NEWCURSORPOS (CURSORPOSITION NIL PLOTWINDOW NEWCURSORPOS))
                                    (if [NOT (AND (EQP (fetch XCOORD of OLDCURSORPOS)
                                                       (fetch XCOORD of NEWCURSORPOS))
                                                  (EQP (fetch YCOORD of OLDCURSORPOS)
                                                       (fetch YCOORD of NEWCURSORPOS]
                                        then (MOVETO STARTXCOORDX STARTXCOORDY PLOTPROMPTWINDOW)
                                             (PRINTOUT PLOTPROMPTWINDOW |.F10.4|
                                                    (STREAMTOWORLDX (fetch XCOORD of NEWCURSORPOS)
                                                           PLOTVIEWPORT))
                                             (MOVETO STARTYCOORDX STARTYCOORDY PLOTPROMPTWINDOW)
                                             (PRINTOUT PLOTPROMPTWINDOW |.F10.4|
                                                    (STREAMTOWORLDY (fetch YCOORD of NEWCURSORPOS)
                                                           PLOTVIEWPORT))
                                             (replace XCOORD of OLDCURSORPOS
                                                with (fetch XCOORD of NEWCURSORPOS))
                                             (replace YCOORD of OLDCURSORPOS
                                                with (fetch YCOORD of NEWCURSORPOS])

(LOGTICFN
  [LAMBDA (MIN MAX)                                          (* jop%: "18-Jun-86 12:49")
          
          (* * returns TICINFO for log scale)
          
          (* assumes log to base 10 -- later base could be determined by plot prop)

    (COND
       [(GREATERP (DIFFERENCE MAX MIN)
               1)
          
          (* spans more than 1 decade; use equispaced tics on logscale)

        (LET ((NEWMIN (PLOT.FLOOR MIN))
              (NEWMAX (PLOT.CEILING MAX))
              RANGE NUMINT INC EXCESS)
             (SETQ RANGE (IDIFFERENCE NEWMAX NEWMIN))
             [SETQ NUMINT (for NUMINT from 2 to 7 smallest   (* NUMINT is %# of intervals = 
                                                             %#tics-1)
                                                        (TIMES NUMINT (PLOT.CEILING (FQUOTIENT RANGE 
                                                                                           NUMINT]
             (SETQ INC (PLOT.CEILING (FQUOTIENT RANGE NUMINT)))
             (SETQ EXCESS (DIFFERENCE (TIMES NUMINT INC)
                                 RANGE))
          
          (* EXCESS is additional number of decades to include for pretty RANGE)

             (add NEWMIN (MINUS (IQUOTIENT EXCESS 2)))
             (add NEWMAX (DIFFERENCE EXCESS (IQUOTIENT EXCESS 2)))
             (create TICINFO
                    TICMAX _ NEWMAX
                    TICMIN _ NEWMIN
                    TICINC _ (for I from NEWMIN to NEWMAX by INC collect (CONS I (EXPT 10.0 I]
       (T (* plot is in a single decade; use equispaced tics on exponential scale)
          (LET ((MINEXP (EXPT 10.0 MIN))
                (MAXEXP (EXPT 10.0 MAX))
                (UNITSIZE (PLOT.FLOOR MIN))
                TICINFO)                                     (* UNITSIZE is the unit interval in 
                                                             this decade)
               (bind (RANGE _ (PLOT.LOG10 (DIFFERENCE MAXEXP MINEXP))) while (LESSP RANGE UNITSIZE)
                  do (SETQ UNITSIZE (SUB1 UNITSIZE)))
               (SETQ TICINFO (DEFAULTTICFN MINEXP MAXEXP NIL NIL UNITSIZE))
                                                             (* check for zero endpoint)
               (with TICINFO TICINFO
                     [COND
                        [(EQP 0 TICMIN)
                         (LET* ((UNITSIZEEXP (EXPT 10.0 UNITSIZE))
                                (LOWERMULT (PLOT.FLOOR (FQUOTIENT MINEXP UNITSIZEEXP)))
                                (UPPERMULT (PLOT.CEILING (FQUOTIENT MAXEXP UNITSIZEEXP)))
                                UPPERUNITSIZEEXP)
                               (COND
                                  [(LEQ UPPERMULT 10)
          
          (* entire plot fits in single decade -- put a tic at each unit)

                                   (SETQ TICMIN (TIMES UNITSIZEEXP LOWERMULT))
                                   (SETQ TICMAX (TIMES UNITSIZEEXP UPPERMULT))
                                   (SETQ TICINC UNITSIZEEXP)
                                   (SETQ NTICS (ADD1 (DIFFERENCE UPPERMULT LOWERMULT)))
                                   (SETQ TICINC
                                    (NCONC1 (for VALUE from TICMIN by TICINC as I from 1
                                               to (SUB1 NTICS) collect (CONS (PLOT.LOG10 VALUE)
                                                                             VALUE))
                                           (CONS (PLOT.LOG10 TICMAX)
                                                 TICMAX]
                                  (T 
          
          (* plot crosses decade bound -- switch to larger units after decade bound to 
          avoid possibility of large number of tic marks)

                                     (SETQ UPPERUNITSIZEEXP (TIMES 10 UNITSIZEEXP))
                                     (SETQ UPPERMULT (PLOT.CEILING (FQUOTIENT MAXEXP UPPERUNITSIZEEXP
                                                                          )))
                                     (SETQ TICMIN (TIMES UNITSIZEEXP LOWERMULT))
                                     (SETQ TICMAX (TIMES UPPERUNITSIZEEXP UPPERMULT))
          
          (* 10-LOWERMULT tics using small units, UPPERMULT tics using large units)

                                     (SETQ NTICS (PLUS 10 (DIFFERENCE UPPERMULT LOWERMULT)))
                                     (SETQ TICINC
                                      (NCONC1 (NCONC (for VALUE from TICMIN by UNITSIZEEXP
                                                        as I from LOWERMULT to 9
                                                        collect (CONS (PLOT.LOG10 VALUE)
                                                                      VALUE))
                                                     (for VALUE from UPPERUNITSIZEEXP by 
                                                                                     UPPERUNITSIZEEXP
                                                        as I from 1 to (SUB1 UPPERMULT)
                                                        collect (CONS (PLOT.LOG10 VALUE)
                                                                      VALUE)))
                                             (CONS (PLOT.LOG10 TICMAX)
                                                   TICMAX]
                        (T                                   (* no adjustment needed)
                           (SETQ TICINC
                            (NCONC1 (for VALUE from TICMIN by TICINC as I from 1
                                       to (SUB1 NTICS) collect (CONS (PLOT.LOG10 VALUE)
                                                                     VALUE))
                                   (CONS (PLOT.LOG10 TICMAX)
                                         TICMAX]
                     (SETQ TICMIN (PLOT.LOG10 TICMIN))
                     (SETQ TICMAX (PLOT.LOG10 TICMAX)))
               TICINFO])
)
(* * Depends on PLOT)

(FILESLOAD PLOT)
(DECLARE%: EVAL@COMPILE 
[PUTPROPS HISTO.GETFREQ MACRO (OPENLAMBDA (ITEM)
                                     (COND ((LISTP ITEM)
                                            (CDR ITEM))
                                           (T 1]
[PUTPROPS HISTO.GETVALUE MACRO (OPENLAMBDA (ITEM)
                                      (COND ((LISTP ITEM)
                                             (CAR ITEM))
                                            (T ITEM]
)
(DECLARE%: DONTCOPY DONTEVAL@LOAD DOEVAL@COMPILE 
(DECLARE%: DOEVAL@COMPILE DONTCOPY

(LOCALVARS . T)
)
)
(PUTPROPS PLOTEXAMPLES COPYRIGHT ("Xerox Corporation" 1986 1987))
(DECLARE%: DONTCOPY
  (FILEMAP (NIL (1236 22599 (COMPUTEMULTIPLE 1246 . 1769) (HISTO.CHANGEBINS 1771 . 4356) (HISTO.COPYFN 
4358 . 4770) (HISTO.DRAW 4772 . 9295) (HISTO.INTSCALEFN 9297 . 9591) (HISTO.INTTICFN 9593 . 10432) (
HISTO.MAKEBINS 10434 . 12734) (HISTO.RESET 12736 . 13014) (HISTO.TICFN 13016 . 14701) (HISTO.VALUES 
14703 . 16987) (HISTPLOT 16989 . 20921) (MAKEBININTERVAL 20923 . 22276) (SUMMARYWINDOW.REPAINTFN 22278
 . 22597)) (22709 37054 (SCATPLOT 22719 . 24759) (SCAT.LOGSCALE 24761 . 27017) (SCAT.POINTCOORDS 27019
 . 28040) (SCAT.WORLDCOORD 28042 . 30859) (LOGTICFN 30861 . 37052)))))
STOP
