aboutsummaryrefslogtreecommitdiffstats
path: root/grapheps.txi
diff options
context:
space:
mode:
Diffstat (limited to 'grapheps.txi')
-rw-r--r--grapheps.txi465
1 files changed, 465 insertions, 0 deletions
diff --git a/grapheps.txi b/grapheps.txi
new file mode 100644
index 0000000..d587107
--- /dev/null
+++ b/grapheps.txi
@@ -0,0 +1,465 @@
+@code{(require 'eps-graph)}
+
+@noindent
+This is a graphing package creating encapsulated-PostScript files.
+Its motivations and design choice are described in
+@url{http://swissnet.ai.mit.edu/~jaffer/Docupage/grapheps}
+
+@noindent
+A dataset to be plotted is taken from a 2-dimensional array.
+Corresponding coordinates are in rows. Coordinates from any
+pair of columns can be plotted.
+
+
+@defun create-postscript-graph filename.eps size elt1 @dots{}
+
+@var{filename.eps} should be a string naming an output file to be created. @var{size}
+should be an exact integer, a list of two exact integers, or #f.
+@var{elt1}, ... are values returned by graphing primitives described here.
+
+@code{create-postscript-graph} creates an @dfn{Encapsulated-PostScript} file named @var{filename.eps} containing
+@cindex Encapsulated-PostScript
+graphs as directed by the @var{elt1}, ... arguments.
+
+The size of the graph is determined by the @var{size} argument. If a list
+of two integers, they specify the width and height. If one integer,
+then that integer is the width and the height is 3/4 of the width.
+If #f, the graph will be 800 by 600.
+@end defun
+@noindent
+These graphing procedures should be called as arguments to
+@code{create-postscript-graph}. The order of these arguments is
+significant; PostScript graphics state is affected serially from the
+first @var{elt} argument to the last.
+
+
+@defun whole-page
+
+Pushes a rectangle for the whole encapsulated page onto the
+PostScript stack. This pushed rectangle is an implicit argument to
+@code{partition-page} or @code{setup-plot}.
+@end defun
+@menu
+* Column Ranges::
+* Drawing the Graph::
+* Graphics Context::
+* Rectangles::
+* Legending::
+* Legacy Plotting::
+* Example Graph::
+@end menu
+
+@node Column Ranges, Drawing the Graph, PostScript Graphing, PostScript Graphing
+@subsubsection Column Ranges
+
+@noindent
+A @dfn{range} is a list of two numbers, the minimum and the maximum.
+@cindex range
+@cindex range
+Ranges can be given explicity or computed in PostScript by
+@code{column-range}.
+
+
+@defun column-range array k
+
+Returns the range of values in 2-dimensional @var{array} column @var{k}.
+@end defun
+
+@defun pad-range range p
+
+Expands @var{range} by @var{p}/100 on each end.
+@end defun
+
+@defun snap-range range
+
+Expands @var{range} to round number of ticks.
+@end defun
+
+@defun combine-ranges range1 range2 @dots{}
+
+Returns the minimal range covering all @var{range1}, @var{range2}, ...
+@end defun
+
+@defun setup-plot x-range y-range pagerect
+
+
+@defunx setup-plot x-range y-range
+@var{x-range} and @var{y-range} should each be a list of two numbers or the value returned
+by @code{pad-range}, @code{snap-range}, or @code{combine-range}.
+@var{pagerect} is the rectangle bounding the graph to be drawn; if missing, the
+rectangle from the top of the PostScript stack is popped and used.
+
+Based on the given ranges, @code{setup-plot} sets up scaling and margins for making
+a graph. The margins are sized proportional to the @var{fontheight}
+value at the time of the call to setup-plot. @code{setup-plot} sets two variables:
+
+@table @var
+@item plotrect
+The region where data points will be plotted.
+@item graphrect
+The @var{pagerect} argument to @code{setup-plot}. Includes plotrect, legends, etc.
+@end table
+@end defun
+@node Drawing the Graph, Graphics Context, Column Ranges, PostScript Graphing
+@subsubsection Drawing the Graph
+
+
+@defun plot-column array x-column y-column proc3s
+
+Plots points with x coordinate in @var{x-column} of @var{array} and y coordinate @var{y-column} of
+@var{array}. The symbol @var{proc3s} specifies the type of glyph or drawing style for
+presenting these coordinates.
+@end defun
+@noindent
+The glyphs and drawing styles available are:
+
+@table @code
+@item line
+Draws line connecting points in order.
+@item mountain
+Fill area below line connecting points.
+@item cloud
+Fill area above line connecting points.
+@item impulse
+Draw line from x-axis to each point.
+@item bargraph
+Draw rectangle from x-axis to each point.
+@item disc
+Solid round dot.
+@item point
+Minimal point -- invisible if linewidth is 0.
+@item square
+Square box.
+@item diamond
+Square box at 45.o
+@item plus
+Plus sign.
+@item cross
+X sign.
+@item triup
+Triangle pointing upward
+@item tridown
+Triangle pointing downward
+@item pentagon
+Five sided polygon
+@item circle
+Hollow circle
+@end table
+
+@node Graphics Context, Rectangles, Drawing the Graph, PostScript Graphing
+@subsubsection Graphics Context
+
+
+@defun in-graphic-context arg @dots{}
+
+Saves the current graphics state, executes @var{args}, then restores
+to saved graphics state.
+@end defun
+
+@defun set-color color
+
+@var{color} should be a string naming a Resene color, a saturate color, or a
+number between 0 and 100.
+
+@code{set-color} sets the PostScript color to the color of the given string, or a
+grey value between black (0) and white (100).
+@end defun
+
+@defun set-font name fontheight
+
+@var{name} should be a (case-sensitive) string naming a PostScript font.
+@var{fontheight} should be a positive real number.
+
+@code{set-font} Changes the current PostScript font to @var{name} with height equal to
+@var{fontheight}. The default font is Helvetica (12pt).
+@end defun
+@noindent
+The base set of PostScript fonts is:
+
+@multitable @columnfractions .20 .25 .25 .30
+@item Times @tab Times-Italic @tab Times-Bold @tab Times-BoldItalic
+@item Helvetica @tab Helvetica-Oblique @tab Helvetica-Bold @tab Helvetica-BoldOblique
+@item Courier @tab Courier-Oblique @tab Courier-Bold @tab Courier-BoldOblique
+@item Symbol
+@end multitable
+
+@noindent
+Line parameters do no affect fonts; they do effect glyphs.
+
+
+@defun set-linewidth w
+
+The default linewidth is 1. Setting it to 0 makes the lines drawn
+as skinny as possible. Linewidth must be much smaller than
+glyphsize for readable glyphs.
+@end defun
+
+@defun set-linedash j k
+
+Lines are drawn @var{j}-on @var{k}-off.
+
+@defunx set-linedash j
+Lines are drawn @var{j}-on @var{j}-off.
+
+@defunx set-linedash
+Turns off dashing.
+@end defun
+
+@defun set-glyphsize w
+
+Sets the (PostScript) variable glyphsize to @var{w}. The default
+glyphsize is 6.
+@end defun
+@noindent
+The effects of @code{clip-to-rect} are also part of the graphic
+context.
+
+@node Rectangles, Legending, Graphics Context, PostScript Graphing
+@subsubsection Rectangles
+
+@noindent
+A @dfn{rectangle} is a list of 4 numbers; the first two elements are
+@cindex rectangle
+the x and y coordinates of lower left corner of the rectangle. The
+other two elements are the width and height of the rectangle.
+
+
+@defun whole-page
+
+Pushes a rectangle for the whole encapsulated page onto the
+PostScript stack. This pushed rectangle is an implicit argument to
+@code{partition-page} or @code{setup-plot}.
+@end defun
+
+@defun partition-page xparts yparts
+
+Pops the rectangle currently on top of the stack and pushes @var{xparts} * @var{yparts}
+sub-rectangles onto the stack in decreasing y and increasing x order.
+If you are drawing just one graph, then you don't need @code{partition-page}.
+@end defun
+
+@defvar plotrect
+
+The rectangle where data points should be plotted. @var{plotrect} is set by
+@code{setup-plot}.
+@end defvar
+
+@defvar graphrect
+
+The @var{pagerect} argument of the most recent call to
+@code{setup-plot}. Includes plotrect, legends, etc.
+@end defvar
+
+@defun fill-rect rect
+
+fills @var{rect} with the current color.
+@end defun
+
+@defun outline-rect rect
+
+Draws the perimiter of @var{rect} in the current color.
+@end defun
+
+@defun clip-to-rect rect
+
+Modifies the current graphics-state so that nothing will be drawn
+outside of the rectangle @var{rect}. Use @code{in-graphic-context} to limit
+the extent of @code{clip-to-rect}.
+@end defun
+@node Legending, Legacy Plotting, Rectangles, PostScript Graphing
+@subsubsection Legending
+
+
+@defun title-top title subtitle
+
+
+@defunx title-top title
+Puts a @var{title} line and an optional @var{subtitle} line above the @code{graphrect}.
+@end defun
+
+@defun title-bottom title subtitle
+
+
+@defunx title-bottom title
+Puts a @var{title} line and an optional @var{subtitle} line below the @code{graphrect}.
+@end defun
+
+@defvar topedge
+@defvarx bottomedge
+
+These edge coordinates of @code{graphrect} are suitable for passing
+as the first argument to @code{rule-horizontal}.
+@end defvar
+
+@defvar leftedge
+@defvarx rightedge
+
+These edge coordinates of @code{graphrect} are suitable for passing
+as the first argument to @code{rule-vertical}.
+@end defvar
+
+@defun rule-vertical x-coord text tick-width
+
+Draws a vertical ruler with X coordinate @var{x-coord} and labeled with string
+@var{text}. If @var{tick-width} is positive, then the ticks are @var{tick-width} long on the right side
+of @var{x-coord}; and @var{text} and numeric legends are on the left. If @var{tick-width} is
+negative, then the ticks are -@var{tick-width} long on the left side of @var{x-coord}; and @var{text}
+and numeric legends are on the right.
+@end defun
+
+@defun rule-horizontal x-coord text tick-height
+
+Draws a horizontal ruler with X coordinate @var{x-coord} and labeled with
+string @var{text}. If @var{tick-height} is positive, then the ticks are @var{tick-height} long on the
+right side of @var{x-coord}; and @var{text} and numeric legends are on the left. If @var{tick-height}
+is negative, then the ticks are -@var{tick-height} long on the left side of @var{x-coord}; and
+@var{text} and numeric legends are on the right.
+@end defun
+
+@defun y-axis
+
+Draws the y-axis.
+@end defun
+
+@defun x-axis
+
+Draws the x-axis.
+@end defun
+
+@defun grid-verticals
+
+Draws vertical lines through @code{graphrect} at each tick on the
+vertical ruler.
+@end defun
+
+@defun grid-horizontals
+
+Draws horizontal lines through @code{graphrect} at each tick on the
+horizontal ruler.
+@end defun
+@node Legacy Plotting, Example Graph, Legending, PostScript Graphing
+@subsubsection Legacy Plotting
+
+
+@defvar graph:dimensions
+
+A list of the width and height of the graph to be plotted using
+@code{plot}.
+@end defvar
+
+@defun plot func x1 x2 npts
+
+
+@defunx plot func x1 x2
+Creates and displays using @code{(system "gv tmp.eps")} an
+encapsulated PostScript graph of the function of one argument @var{func}
+over the range @var{x1} to @var{x2}. If the optional integer argument @var{npts} is
+supplied, it specifies the number of points to evaluate @var{func} at.
+
+@defunx plot coords x-label y-label
+@var{coords} is a list or vector of coordinates, lists of x and y
+coordinates. @var{x-label} and @var{y-label} are strings with which
+to label the x and y axes.
+@end defun
+@node Example Graph, , Legacy Plotting, PostScript Graphing
+@subsubsection Example Graph
+
+@noindent
+The file @file{am1.5.html}, a table of solar irradiance, is fetched
+with @samp{wget} if it isn't already in the working directory. The
+file is read and stored into an array, @var{irradiance}.
+
+@code{create-postscript-graph} is then called to create an
+encapsulated-PostScript file, @file{solarad.eps}. The size of the
+page is set to 600 by 300. @code{whole-page} is called and leaves
+the rectangle on the PostScript stack. @code{setup-plot} is called
+with a literal range for x and computes the range for column 1.
+
+Two calls to @code{top-title} are made so a different font can be
+used for the lower half. @code{in-graphic-context} is used to limit
+the scope of the font change. The graphing area is outlined and a
+rule drawn on the left side.
+
+Because the X range was intentionally reduced,
+@code{in-graphic-context} is called and @code{clip-to-rect} limits
+drawing to the plotting area. A black line is drawn from data
+column 1. That line is then overlayed with a mountain plot of the
+same column colored "Bright Sun".
+
+After returning from the @code{in-graphic-context}, the bottom ruler
+is drawn. Had it been drawn earlier, all its ticks would have been
+painted over by the mountain plot.
+
+The color is then changed to @samp{seagreen} and the same graphrect
+is setup again, this time with a different Y scale, 0 to 1000. The
+graphic context is again clipped to @var{plotrect}, linedash is set,
+and column 2 is plotted as a dashed line. Finally the rightedge is
+ruled. Having the line and its scale both in green helps
+disambiguate the scales.
+
+@example
+(require 'eps-graph)
+(require 'line-i/o)
+(require 'string-port)
+
+(define irradiance
+ (let ((url "http://www.pv.unsw.edu.au/am1.5.html")
+ (file "am1.5.html"))
+ (define (read->list line)
+ (define elts '())
+ (call-with-input-string line
+ (lambda (iprt) (do ((elt (read iprt) (read iprt)))
+ ((eof-object? elt) elts)
+ (set! elts (cons elt elts))))))
+ (if (not (file-exists? file))
+ (system (string-append "wget -c -O" file " " url)))
+ (call-with-input-file file
+ (lambda (iprt)
+ (define lines '())
+ (do ((line (read-line iprt) (read-line iprt)))
+ ((eof-object? line)
+ (let ((nra (create-array (Ar64)
+ (length lines)
+ (length (car lines)))))
+ (do ((lns lines (cdr lns))
+ (idx (+ -1 (length lines)) (+ -1 idx)))
+ ((null? lns) nra)
+ (do ((kdx (+ -1 (length (car lines))) (+ -1 kdx))
+ (lst (car lns) (cdr lst)))
+ ((null? lst))
+ (array-set! nra (car lst) idx kdx)))))
+ (if (and (positive? (string-length line))
+ (char-numeric? (string-ref line 0)))
+ (set! lines (cons (read->list line) lines))))))))
+
+(let ((xrange '(.25 2.5)))
+ (create-postscript-graph
+ "solarad.eps" '(600 300)
+ (whole-page)
+ (setup-plot xrange (column-range irradiance 1))
+ (title-top
+ "Solar Irradiance http://www.pv.unsw.edu.au/am1.5.html")
+ (in-graphic-context
+ (set-font "Helvetica-Oblique" 12)
+ (title-top
+ ""
+ "Key Centre for Photovoltaic Engineering UNSW - Air Mass 1.5 Global Spectrum"))
+ (outline-rect plotrect)
+ (rule-vertical leftedge "W/(m^2.um)" 10)
+ (in-graphic-context (clip-to-rect plotrect)
+ (plot-column irradiance 0 1 'line)
+ (set-color "Bright Sun")
+ (plot-column irradiance 0 1 'mountain)
+ )
+ (rule-horizontal bottomedge "Wavelength in .um" 5)
+ (set-color 'seagreen)
+
+ (setup-plot xrange '(0 1000) graphrect)
+ (in-graphic-context (clip-to-rect plotrect)
+ (set-linedash 5 2)
+ (plot-column irradiance 0 2 'line))
+ (rule-vertical rightedge "Integrated .W/(m^2)" -10)
+ ))
+
+(system "gv solarad.eps")
+@end example