As another illustration of what you can do by modifying existing plots let's construct a dynamic simulation -- a movie -- to examine the variation in the shape of histograms of samples from a standard normal distribution. To start off, use the expression
(def h (histogram (normal-rand 20)))to construct a single histogram and save its plot object as h. The :clear message is available for histograms as well. As you can see from its help message
> (send h :help :clear) :CLEAR Message args: (&key (draw t)) Clears the plot data. If DRAW is nil the plot is redrawn; otherwise its current screen image remains unchanged. NIL >the :clear message takes an optional keyword argument. If this argument is NIL then the plot will not actually be redrawn until some other event causes it to be redrawn. This is useful for dynamic simulations. Rearrange and resize your windows until you can see the histogram window even when the listener window is the active window. Then type the expression
(dotimes (i 50) (send h :clear :draw nil) (send h :add-points (normal-rand 20)))This should produce a sequence of 50 histograms, each based on a sample of size 20. By giving the keyword argument draw with value NIL to the :clear message you have insured that each histogram stays on the screen until the next one is ready to be drawn. Try the example again without this argument and see what difference it makes.
Programmed dynamic simulations may provide another approach to viewing the relation among several variables. As a simple example, suppose we want to examine the relation between the variables abrasion-loss and hardness introduced in Section 6.2 above. Let's start with a histogram of abrasion-loss produced by the expression
(def h (histogram abrasion-loss))The messages :point-selected , :point-hilited and :point-showing are particularly useful for dynamic simulations. Here is the help information for :point-selected in a histogram:
> (send h :help :point-selected) :POINT-SELECTED Method args: (point &optional selected) Sets or returns selection status (true or NIL) of POINT. Sends :ADJUST-POINT-SCREEN-STATES message if states are set. Vectorized. NIL >Thus you can use this message to determine whether a point is currently selected and also to select or unselect it. Again rearrange the windows so you can see the histogram while typing in the listener window and type the expression
(dolist (i (order hardness)) (send h :point-selected i t) (send h :point-selected i nil))The expression (order hardness) produces the list of indices of the ordered values of hardness. Thus the first element of the result is the index of the smallest element of hardness, the second element is the index of the second smallest element of hardness, etc.. The loop moves through each of these indices and selects and unselects the corresponding point.
The result on the screen is very similar to the result of brushing a hardness histogram linked to an abrasion-loss histogram from left to right. The drawback of this approach is that it is harder to write an expression than to use a mouse. On the other hand, when brushing with a mouse you tend to focus your attention on the plot you are brushing, rather than on the other linked plots. When you run a dynamic simulation you do not have to do anything while the simulation is running and can therefore concentrate fully on the results.
An intermediate solution is possible: You can set up a dialog window with a scroll bar that will run through the indices in the list (order hardness), selecting the corresponding point as it is scrolled. An example in Section 8 will show you how to do this.
Like most Lisp systems XLISP-STAT is not ideally suited to real time simulations because of the need for garbage collection, to reclaim dynamically allocated storage. This is the reason that the simulations in this section will occasionally pause for a second or two. Nevertheless, in a simple simulation like the last one each iteration may still be too fast for you to be able to pick up any pattern. To slow things down you can add some extra busy work to each iteration. For example, you could use
(dolist (i (order hardness)) (send h :point-selected i t) (dotimes (i 100)) (send h :point-selected i nil))in place of the previous expression.