This chapter is concerned with positioning a graph on the screen or hardcopy page, and controlling its scale. In simple applications, the position and scale of the graph are controlled more-or-less automatically by the routine PGENV, but in order to obtain complete control of positioning and scaling, it is necessary to understand the concepts of the View Surface, the Window, and the Viewport, and two coordinate systems: World Coordinates and Device Coordinates.
A simple PGPLOT picture might be a two-dimensional graph showing the dependence of one variable on another. A typical graph has data points, represented by error bars or special markers such as dots or diamonds, possibly connected by lines, or perhaps plotted on the same scale as a theoretical model drawn as a smooth curve. The graph must be labeled with two axes to indicate the coordinate scales.
The programmer must describe to PGPLOT the various elements of
the graph in terms of rectangular Cartesian coordinates. The only
limitation on the coordinates is that they be represented as
floating-point (Fortran REAL
or REAL*4
,
or C float
) numbers; otherwise we are totally free to
choose the meaning of the coordinates. For example, in a graph
showing the temporal variation of a quasar, the abscissa
(x-coordinate) might be Epoch (in years) and the ordinate
(y-coordinate) Flux Density (in Jy).
In accordance with common practice in graphics programming, these coordinates, chosen by the programmer, are termed world coordinates. PGPLOT maps a selected rectangular region of the world-coordinate space (termed the window) onto a specified rectangle (termed the viewport) on the view surface (the screen of an interactive display or a sheet of paper on a hardcopy plotter). The program must make calls to PGPLOT routines to define both the window and the viewport. For complete descriptions of the routines and their arguments, refer to the subroutine synopses.
After it has opened a graphics device by calling PGOPEN, a program has access to a view surface. This is, for example, a window on the workstation screen, or a piece of paper on a printer. The size of the view surface depends on the device. Each device type has a default size, but on some devices the size can be changed by calling PGPAP after opening the device, and some workstations allow the user to change the size of a PGPLOT window by using the functions of the window manager. A program can determine the size of the view surface by calling PGQVSZ.
Note that when the graphics device is subdivided into panels, as described in the preceding chapter, the view surface is the current panel.
A viewport is a rectangular portion of the plotting surface onto which the graph is mapped. PGPLOT has a default viewport which is centered on the plotting surface and leaves sufficient space around it for annotation. The application program can redefine the viewport by calling routine PGSVP or PGVSIZ, or reset the default by calling PGVSTD.
PGSVP defines the viewport in a device-independent manner, using a coordinate system whose coordinates run from 0 to 1 in both x and y. This coordinate system is called normalized device coordinate space. For example, if we wish to divide the view surface into four quadrants and map a different plot onto each quadrant, we can define a new viewport before starting each plot. PGSVP has the format:
CALL PGSVP(XMIN, XMAX, YMIN, YMAX)
cpgsvp(xmin, xmax, ymin, ymax);For example, to map the viewport onto the upper left quadrant of the view surface:
CALL PGSVP(0.0, 0.5, 0.5, 1.0)
cpgsvp(0.0, 0.5, 0.5, 1.0);
(Note that this does not leave room around the edge of the viewport for annotation.)
PGVSIZ defines the viewport in absolute coordinates (inches); it should only be used when it is known how big the view surface is and a definite plot scale is required. The arguments are the same as for PGSVP, but measured in inches from the bottom left corner of the view surface (1 inch = 25.4 mm). For example:
CALL PGVSIZ(1.5, 9.5, 1.5, 6.5)
cpgvsiz(1.5, 9.5, 1.5, 6.5);
defines a rectangular viewport 8 by 5 inches, offset 1.5 inches from the bottom and left edges of the view surface.
PGVSTD defines a standard viewport, the size of which depends on the particular device being used, and on the current character size (it uses the whole view surface excluding a margin of four character heights all around):
CALL PGVSTD
cpgvstd();
This is the default viewport set up by PGOPEN.
Note that the viewport must be defined before calling any routines that would actually generate a display. The viewport may, however, be changed at any time: this will affect the appearance of objects drawn later in the program.
The program defines the window by calling routine PGSWIN, whose arguments specify the world-coordinate limits of the window along each coordinate axis, e.g.
CALL PGSWIN(1975.0, 1984.0, 5.0, 20.0)
cpgswin(1975.0, 1984.0, 5.0, 20.0);
specifies that the x-axis (epoch) is going to run (left to
right) from 1975 to 1984, and the y-axis (flux density) is
going to run (bottom to top) from 5 to 20~Jy. Note that the
arguments are floating-point numbers (Fortran REAL
or
C float
variables or constants), and require decimal
points. If the order of either the x pair or the y
pair is reversed, the corresponding axis will point in the opposite
sense, i.e., right to left for x or top to bottom for
y. PGPLOT uses the window specification to construct a mapping
that causes the image of the window to coincide with the viewport
on the view surface. Furthermore, PGPLOT ``clips'' lines so that
only those portions of objects that lie within the window are
displayed on the view surface.
Like the viewport, the window must be defined before drawing any objects. The window can be defined either before or after the viewport: the effect will be the same. The default window, set up by PGOPEN, has x limits 0.0 - 1.0 and y limits 0.0 - 1.0.
If the ratio of the sides of the window does not equal the ratio of the sides of the viewport, the mapping of the world coordinates onto the view surface results in an image whose shape is compressed in either x or y. One way to avoid this compression is to carefully choose the viewport to have the same aspect ratio as the window. Routine PGWNAD can do this: it defines the window and simultaneously adjusts the viewport to have the same aspect ratio as the window. The new viewport is the largest that can fit inside the old one, and is centered in the old one.
For a simple graph, it is usually necessary to draw a frame around the viewport and label the frame with tick marks and numeric labels. This can be done with the routine PGBOX. For our sample graph, the call might be:
CALL PGBOX('BCTN', 0.0, 0, 'BCNST', 0.0, 0)
cpgbox("BCTN", 0.0, 0, "BCNST", 0.0, 0);
PGBOX has many options for controlling the appearance of the box or graph axes, and there is another routine PGAXIS which provides further capabilities (see Chapter 8).
Another routine, PGLAB, provides text labels for the bottom, left hand side, and top of the viewport:
CALL PGLAB('Epoch', 'Flux Density (Jy)', 'Variation of 3C345 at 10.7 GHz')
cpglab("Epoch", "Flux Density (Jy)", "Variation of 3C345 at 10.7 GHz");
The first two arguments provide explanations for the two axes; the third provides a title for the whole plot. Note that unlike all the other plotting routines, the lines and characters drawn by PGBOX and PGLAB are not clipped at the boundaries of the window. PGLAB actually calls a more general routine, PGMTXT, which can be used for plotting labels at any point relative to the viewport.
The amount of space needed outside the viewport for annotation depends on the exact options specified in PGBOX; usually four character heights will be sufficient, and this is the amount allowed when the standard viewport (created by PGVSTD) is used. The character height can be changed by using routine PGSCH (see Chapter 7).
Having to specify calls to PGPAGE, PGSVP, PGSWIN, and PGBOX is excessively cumbersome for drawing simple graphs. Routine PGENV (for PGplot ENVironment) combines all four of these in one subroutine, using the standard viewport, and a limited set of the capabilities of PGBOX. For example, the graph described above could be initiated by the following call:
CALL PGENV(1975.0, 1984.0, 5.0, 20.0, 0, 0)
cpgenv(1975.0, 1984.0, 5.0, 20.0, 0, 0);
which is equivalent to the following series of calls:
CALL PGPAGE CALL PGVSTD CALL PGSWIN(1975.0, 1984.0, 5.0, 20.0) CALL PGBOX('BCNST', 0.0, 0, 'BCNST', 0.0, 0)
cpgpage(); cpgvstd(); cpgswin(1975.0, 1984.0, 5.0, 20.0); cpgbox("BCNST", 0.0, 0, "BCNST", 0.0, 0);
PGENV uses the standard viewport. The first four arguments define the world-coordinate limits of the window. The fifth argument can be 0 or 1; if it is 1, PGENV calls PGWNAD instead of PGSWIN so that the plot has equal scales in x and y. The sixth argument controls the amount of annotation.