## 3.8 Writing new plotting functions

You may want to plot something not directly supported by one of the plotting primitive functions. Usually, you can write your own plotting function to perform such a task. As an example, suppose you want to plot a histogram -- that is, instead of a smooth curve connecting a series of (x,y) points, you want to draw a line consisting of a horizontal segment at each value of y, joined by vertical segments (this is sometimes called a Manhattan plot for its resemblance to the New York City skyline).

You quickly realize that to draw a histogram, you really need the x values at the vertical segments. This function works:

func plh(y,x) { yy = xx = array(0.0, 2*numberof(y)); yy(1:-1:2) = yy(2:0:2) = y; xx(2:-2:2) = xx(3:-1:2) = x(2:-1); xx(1) = x(1); xx(0) = x(0); plg, yy, xx; } |

Notice that the x array must have one more element that the y array; otherwise the assignment operations to xx will fail for lack of conformability.

A more sophistocated version would include the possibility for the caller to pass plh the keywords accepted by the plg function. Also, you might want to allow y to have one more element than x instead of x one more than y, in order to start and end the plot with a vertical segment instead of a horizontal segment. Here is a more complete version of plh:

func plh(y,x,marks=,color=,type=,width=) /* DOCUMENT plh, y, x plot a histogram (Manhattan plot) of Y versus X. That is, the result of a plh is a set of horizontal segments at the Y values connected by vertical segments at the X values. If X has one more element than Y, the plot will begin and end with a horizontal segment; if Y has one more element than X, the plot will begin and end with a vertical segment. The keywords are a subset of those for plg. KEYWORDS: marks, color, type, width SEE ALSO: plg */ { swap = numberof(x)<numberof(y); if (swap) { yy = y; y = x; x = yy; } yy = xx = array(0.0, 2*min(numberof(y),numberof(x))); yy(1:-1:2) = yy(2:0:2) = y; xx(2:-2:2) = xx(3:-1:2) = x(2:-1); xx(1) = x(1); xx(0) = x(0); if (swap) { y = yy; yy = xx; xx = y } plg, yy, xx, marks=marks, color=color, type=type, width=width; } |

The point of an interpreted language is to allow you to easily alter the user interface to suit your own needs. Designing an interface for a wide variety of users is much harder than designing one for your own use. (The first version of plh might be adequate for your own use; I wouldn't release less than the second version to a larger public.) Linking your routines to the Yorick help command via a document comment is useful even if never anticipate anyone other than yourself will use them. Public interface routines should always have a document comment.