One of the most exciting features of your HP 9000 Series computer is its graphics capability. The graphic techniques chapters introduce you to the powerful set of graphics statements in BASIC and teach you how to use them to produce pleasing output.
If you use HP BASIC/WS and you want to know what binary to load for a particular keyword or option, see the HP BASIC Language Reference. Note that you must load the BIN files named GRAPH and GRAPHX before you can enter most graphics statements. You may need to load other BIN files, depending on what computer you have. Refer to the HP BASIC Porting and Globalization manual for information about BIN files. Finally, some of the example graphics programs require BIN files such as MAT that you might not readily associate with graphics.
If you have HP BASIC/WS, you should have a disk called Manual Examples. The part numbers for this disk vary depending on what disk drive you have, but the disk contents are identical. The Manual Examples disk contains many of the programs discussed in the graphics chapters, which you can load and run as you read through the chapters.
If you have HP BASIC/UX, the graphics examples are located in the ``/usr/lib/rmb/demo/manex'' directory.
The file name for an example program is cited when the program is discussed so that you know which program to run. These file names are identical for HP BASIC/WS and HP BASIC/UX.
Some data follow. As quickly as you can, determine if the overall trend is steady, rising or falling. Are there any periodic motions? If so, how many cycles are represented in the 50 points?
Time (sec.) | Voltage | Time (sec.) | Voltage | |
---|---|---|---|---|
1 | 16.10 | 26 | 16.24 | |
2 | 16.25 | 27 | 16.27 | |
3 | 16.25 | 28 | 16.44 | |
4 | 16.28 | 29 | 16.44 | |
5 | 16.36 | 30 | 16.57 | |
6 | 16.31 | 31 | 16.60 | |
7 | 16.27 | 32 | 16.70 | |
8 | 16.08 | 33 | 16.72 | |
9 | 16.10 | 34 | 16.66 | |
10 | 16.06 | 35 | 16.58 | |
11 | 16.07 | 36 | 16.62 | |
12 | 16.17 | 37 | 16.46 | |
13 | 16.14 | 38 | 16.33 | |
14 | 16.26 | 39 | 16.34 | |
15 | 16.34 | 40 | 16.36 | |
16 | 16.40 | 41 | 16.45 | |
17 | 16.56 | 42 | 16.52 | |
18 | 16.60 | 43 | 16.56 | |
19 | 16.44 | 44 | 16.77 | |
20 | 16.51 | 45 | 16.89 | |
21 | 16.35 | 46 | 16.80 | |
22 | 16.41 | 47 | 16.96 | |
23 | 16.28 | 48 | 16.80 | |
24 | 16.19 | 49 | 16.74 | |
25 | 16.30 | 50 | 16.77 |
Following is a graph of the data in the preceding table. Observe that the graphical nature of the data makes the change in voltage over time clearer. Clarity and understandability at a glance is what computer graphics is all about.
Many example programs are included in the pages that follow. Type in and
run them as you progress from simply drawing a jagged line to creating complex
graphics.
To draw lines, you can simply PLOT the X and Y coordinates of the point you want to draw a line to. The following program does just that.
10 GINIT ! Initialize various graphics parameters.
20 PLOTTER IS CRT,"INTERNAL" ! Use the CRT screen
30 GRAPHICS ON ! Turn on the graphics screen
40 FOR X=2 TO 100 STEP 2 ! Points to be plotted...
50 PLOT X,RND+50 ! Get a data point and plot it against X
60 NEXT X ! RND returns a value between 0 and 1
70 END !
The GINIT statement on line 10 means Graphics Initialize. This is almost always the first graphics statement you execute. It sets various graphics parameters to their default values, and it is a shorthand way to execute up to 14 other statements (see the HP BASIC Language Reference manual for details).
The GRAPHICS ON statement on line 30 allows you to see what the program is drawing if you have separate alpha and graphics. On bit-mapped displays, graphics and alpha are always on, unless you have modified the display mask. More on this later.
Line 50 contains the heart of the program. In a loop, the PLOT statement draws to each successive point, which is determined by the loop control variable ``X'' for the X direction and the value returned by the function ``RND+50'' for the Y direction. The constant, 50, centers the line on the screen so it is not displayed in your softkey display area.
The problem with the previous plot is that it doesn't show much information; it's too straight. If we exaggerated the Y direction to the point where we could see the variations, the line would better represent the plotted data.
This problem can be remedied by scaling. Scaling means defining the values the computer considers to be at the edges of the plotting surface. By definition, the left edge is the minimum X, the right edge is the maximum X, the bottom is the minimum Y, and the top is the maximum Y. Thus any point you plot which has X and Y coordinates within these ranges will be visible.
Two statements are available to define your own values for the edges of the plotting surface. The first one is SHOW, which forces X and Y units to be equal. This is called isotropic scaling, and it is often desirable. For example, when drawing a map, you will probably want one mile in the east-west direction to be the same size as a mile in the north-south direction. Here is an example of SHOW:
SHOW 0,100,16,18
This statement defines the plotting area such that there is a rectangle in that area with a minimum X=0, maximum X=100, minimum Y=16, and maximum Y=18, using isotropic units. As mentioned above, isotropic means that one unit in the X direction equals one unit in the Y direction. Thus, if the plotting area were square, the above SHOW statement would define the minimum X to be 0, maximum X to be 100, minimum Y to be -33 (not 16) and maximum Y to be 67 (not 18). This is because the X and Y units must be identical, so the SHOW statement centers the specified area in the plotting area, allowing whatever extra room it needs to ensure that the rectangle is completely contained in the plotting area. There will be extra room in either the X or Y direction, but not both.
Since you defined the unit sizes with the SHOW statement, you were working with user-defined units (UDUs). Both the SHOW statement and the WINDOW statement (covered next) specify user-defined units.
The MAX and MIN functions provide a method for determining the maximum and minimum values of a set of numbers. However, these functions require the MAT binary. For example:
110 Ymin=INT(MIN(Y(*)))
120 Ymax=MAX(Y(*))
130 Ymax=INT(Ymax)+(Ymax<>INT(Ymax))
Line 110 calculates the greatest integer less than or equal to the minimum value in an array of Y values. Lines 120 and 130 calculate the smallest integer greater than or equal to the maximum value in the array of Y values.
The following example uses a SHOW statement to define the edges of the screen to appropriate values. The X values used in the SHOW statement (0 and 100) represent 100 data points and indicate that axes are more meaningful when the origin is at zero and not at 1. The Y values for this type of plot must be determined by you or by the computer itself. We are using a random number function to simulate data received from some device. The Y values used in the example (16 and 18) come from the RND function. In real applications, you probably will not know beforehand what the range of the data will be, in which case you can use the method described above to determine it.
10 GINIT ! Initialize various graphics parameters.
20 PLOTTER IS CRT,"INTERNAL" ! Use the internal screen
30 GRAPHICS ON ! Turn on the graphics screen
40 SHOW 0,100,15,19 ! Isotropic scaling: left, right, bottom, top
50 FOR X=2 TO 100 STEP 2 ! Points to be plotted...
60 PLOT X,RND+17 ! Get a data point and plot it against X
70 NEXT X ! RND returns a value between 0 and 1
80 END !
$ag.gif$
As you can see, SHOW centers the curve on the screen, but since the range of X values is so much larger than the range of Y values (0 to 100 versus 16 to 18), there is still not enough resolution to see what the data is doing.
In this example, we are dealing with data types (seconds and volts) that are not equal. Thus, it would be better to use unequal, or anisotropic, scaling to graph the relationship in the example. To do this, we can use the other scaling statement, WINDOW. WINDOW does not force X units to be equal to Y units. Instead, the axis range determines the scaling.
10 GINIT ! Initialize various graphics parameters.
20 PLOTTER IS CRT,"INTERNAL" ! Use the internal screen
30 GRAPHICS ON ! Turn on the graphics screen
40 WINDOW 0,100,15,19 ! Anisotropic scaling: left,right,bottom,top
50 FOR X=2 TO 100 STEP 2 ! Points to be plotted...
60 PLOT X,RND+17 ! Get a data point and plot it against X
70 NEXT X ! RND returns a value between 0 and 1
80 END !
In this plot, we can easily see variations in the data. To test how the Y axis range, 15-19, affects relative variations in the data, change ``WINDOW 0,100,15,19'' to ``WINDOW 0,100,30,50'' and change ``RND+17'' to ``RND+40''. Run the program again and note that the line is less ragged (remember that RND ranges between 0 and 1).
There is still one problem, though. We can see relative variations in the data, but what units are being used -- microvolts, millivolts, megavolts, dozens of volts, or what? We also need to be able to specify a subset of the screen for plotting the curve and put explanatory notes outside this area. The next section tells you how to do this.
A viewport is a subset of the plotting area called the soft clip area. It is delimited by the soft clip limits. Clip, because line segments which attempt to go outside these limits are cut off at the edge of the subarea. Soft, because we can override these limits by turning off the clipping with the CLIP OFF statement (more about this later). There are hard clip limits also, which are defined to be the absolute limits of the plotting area. There is no way to override the hard clip limits.
Before we define a viewport, we need to know about the two different types of units that exist. These two types of units are UDUs (user-defined units) and GDUs (graphics display units). For viewports to be predictable, they must always be specified in the same units. Since users can change UDUs, GDUs are used when specifying the limits of a VIEWPORT statement. GDUs are fixed for the CRT, so a viewport is associated with the screen, rather than the graphical model used in your program.
The length of a GDU is defined as 1 percent of the shorter edge of the plotting area. The lower left of the plotting area is always 0,0. GDUs are isotropic; that is, one unit in the X direction is the same distance as one unit in the Y direction. For a CRT display, the Y-axis is always shorter, and thus it is 100 GDUs in length.
Unless you specify otherwise, the display screen (but not necessarily an external plotter) has the following expanse:
The RATIO statement returns the ratio of the X-axis hard clip limit to the Y-axis hard clip limit for the current PLOTTER IS device. For a typical CRT this ratio is in the approximate range 1.25 to 1.33. To find this ratio for your display, just type ``RATIO'' [Return]. You can include the RATIO expression in another BASIC statement, for example:
VIEWPORT 0,RATIO*100,20,80
This practice ensures that the clipping limits you specify will work for any display type. Some approximate RATIO values for typical displays follow:
Thus, the length of the X axis is in the range of approximately 125 to 133 GDUs for any of the listed displays.
VIEWPORT defines the extent of the soft clip limits in GDUs. It specifies a subarea of the plotting surface which acts just like the entire plotting surface except you can draw outside the subarea if you turn off clipping (more about clipping later). The VIEWPORT statement in the following program specifies that the lower left-hand corner of the soft clip area is at 10,15 and the upper right-hand corner is at 120,90. This is the area that the WINDOW statement affects. Also note line 50--the FRAME statement. This draws a box around the current soft clip limits so you can see the area specified by VIEWPORT.
10 GINIT ! Initialize various graphics parameters.
20 PLOTTER IS CRT,"INTERNAL" ! Use the internal screen
30 GRAPHICS ON ! Turn on the graphics screen
40 VIEWPORT 10,120,15,90 ! Define subset of screen area
50 FRAME ! Draw a box around defined subset
60 WINDOW 0,100,15,19 ! Anisotropic scaling: left,right,bottom,top
70 FOR X=2 TO 100 STEP 2 ! Points to be plotted...
80 PLOT X,RND+17 ! Get a data point and plot it against X
90 NEXT X ! RND returns a value between 0 and 1
100 END !
By using VIEWPORT, we now have enough room to include labels on the plot. Typically, in a Y-vs.-X plot, a title for the whole plot is centered at the top, a Y-axis title is placed on the left edge, and an X-axis title is placed at the bottom.
LABEL lets you write text onto the graphics screen. You can position the label by using a MOVE or PLOT statement to get to the point at which you want the label to be placed. The lower left corner of the label is at the point to which you moved. In other words, move to the position on the screen at which the lower left corner of the text is placed. Note that the LORG statement will move you to the lower left corner of the label. (The relative origin for labels can be changed with the LORG statement.)
Notice in the following plot that the Y-axis label on the left edge of the screen is created by writing one letter at a time. We only need to move to the position of the first character in that label because each label statement automatically terminates with a carriage return/linefeed. This causes the pen to go one line down, ready for the next line of text. (There is a better way to plot vertical labels; we'll see it in the section titled "Data-Driven Plotting.")
10 GINIT ! Initialize various graphics parameters.
20 PLOTTER IS CRT,"INTERNAL" ! Use the internal screen
30 GRAPHICS ON ! Turn on the graphics screen
40 MOVE 45,95 ! Move to left of middle of top of screen
50 LABEL "VOLTAGE VARIANCE" ! Write title of plot
60 MOVE 0,65 ! Move to center of left edge of screen
70 Label$="Voltage" ! Write Y-axis label
80 FOR I=1 TO 7 ! Seven letters in "Voltage"
90 LABEL Label$[I,I] ! Label one character
100 NEXT I ! et cetera
110 MOVE 45,10 ! X: center of screen; Y: above key labels
120 LABEL "Time (seconds)" ! Write X-axis label
130 VIEWPORT 10,120,15,90 ! Define subset of screen area
140 FRAME ! Draw a box around defined subset
150 WINDOW 0,100,16,18 ! Anisotropic scaling: left/right/bottom/top
160 FOR X=2 TO 100 STEP 2 ! Points to be plotted...
170 PLOT X,RND+16.5 ! Get a data point and plot it against X
180 NEXT X ! et cetera
190 END ! finis
Now we know what we are measuring--voltage versus time--but we still do not know the units being used. We need an X-axis and a Y-axis labeled with numbers in appropriate places. The AXES statement will work here.
The AXES statement draws X and Y axes and short lines perpendicular to the axes to indicate the unit spacing. These short lines are called tick marks. The axes may intersect at any desired point; it need not be the actual origin--0,0. The tick marks may be any distance apart, and you can select the major tick count for each axis. The major tick count is the total number of tick marks drawn for every large one. This makes it convenient to count by fives or tens or whatever you choose. Insert the ``AXES'' statement in your program and rerun it to see the difference.
10 GINIT ! Initialize various graphics parameters.
20 PLOTTER IS CRT,"INTERNAL" ! Use the internal screen
30 GRAPHICS ON ! Turn on the graphics screen
40 MOVE 45,95 ! Move to left of middle of top of screen
50 LABEL "VOLTAGE VARIANCE" ! Write title of plot
60 MOVE 0,65 ! Move to center of left edge of screen
70 Label$="Voltage" ! Write Y-axis label
80 FOR I=1 TO 7 ! Seven letters in "Voltage"
90 LABEL Label$[I,I] ! Label one character
100 NEXT I ! et cetera
110 MOVE 45,10 ! X: center of screen; Y: above key labels
120 LABEL "Time (seconds)" ! Write X-axis label
130 VIEWPORT 10,120,15,90 ! Define subset of screen area
140 FRAME ! Draw a box around defined subset
150 WINDOW 0,100,16,18 ! Anisotropic scaling: left/right/bottom/top
160 AXES 1,.1,0,16,5,5,3 ! Draw X- and Y-axes with appropriate ticks
170 FOR X=2 TO 100 STEP 2 ! Points to be plotted...
180 PLOT X,RND+16.5 ! Get a data point and plot it against X
190 NEXT X ! et cetera
200 END ! finis
Line 160 of the program contains the AXES statement and its parameters. The parameters are explained as follows:
``1,.1'' | The X axis has 1 display unit between tick marks, and the Y axis has .1 display unit between tick marks, in current display units. |
``0,16'' | The Y axis crosses the X axis at X=0. The X axis crosses the Y axis at Y=16. |
``5,5'' | These counts are the number of "minor" (shorter) ticks between "major" (longer) tick marks on the axes. The value of 5 specifies that a major tick mark will appear every fifth tick mark. |
``,3'' | The value of 3 specifies that the major ticks are 3 GDUs long (the default is 2). |
The Manual Examples disk (``/usr/lib/rmb/demo/manex'' for HP BASIC/UX users) contains programs found in this chapter. As you read through the following sections, load the appropriate program and run it. Remember that some of the programs require the MAT (matrix) BIN file. You can also type in the listed programs and run them. Either way, experiment with them until you are familiar with the demonstrated concepts and techniques.
Recall that the VIEWPORT statement defines a subset of the screen in which to plot. More precisely, the VIEWPORT statement defines a rectangular area into which the WINDOW coordinates will be mapped. VIEWPORT immediately rescales the plotting area; thus, it is a good programming practice to follow every VIEWPORT statement with a WINDOW statement. The VIEWPORT also invokes clipping at its edges. There will be more about clipping later in this chapter.
The Y direction edge values default to 0 through 100 in Y. The X direction left edge value is 0. The right edge value can vary depending on what computer you have (approximately 128-133). Technically, these are UDUs, although default UDUs are equivalent to the GDUs until you change the UDUs with a SHOW or a WINDOW. To recap the important characteristics of GDUs:
As mentioned earlier in the section titled "Scaling," it is trivial to determine how long the shorter edge of screen is in GDUs, but substantially more involved to calculate the length of the longer edge in GDUs. Since GDUs have X and Y units of the same length, the length in GDUs of the longer edges of the plotting surface is closely related to the aspect ratio of the plotting surface. The aspect ratio is the ratio of width to height of the plotting surface. A function called RATIO returns the quotient of these values.
Using RATIO, we can derive two formulas which are almost indispensable when writing a general VIEWPORT statement:
X_gdu_max=100*MAX(1,RATIO)
Y_gdu_max=100*MAX(1,1/RATIO)
These two statements define the maximum X and Y in GDUs. This will work no matter what plotting device you are using. Now that we have ``X_gdu_max'' and ``Y_gdu_max'' defined, we have complete control of the subset we want on the plotting surface. Suppose we want:
We would specify:
VIEWPORT .1*X_gdu_max,.99*X_gdu_max,.15*Y_gdu_max,.9*Y_gdu_max
Now, let's return to the program which defined the viewport, and update the VIEWPORT statement. (Run the example program in file ``SinViewprt''.)
100 CLEAR SCREEN ! Clear the alpha display
110 GINIT ! Initialize various graphics parameters.
120 PLOTTER IS CRT,"INTERNAL" ! Use the internal screen
130 GRAPHICS ON ! Turn on the graphics screen
140 X_gdu_max=100*MAX(1,RATIO) ! How many GDUs wide the screen is
150 Y_gdu_max=100*MAX(1,1/RATIO) ! How many GDUs high the screen is
160 VIEWPORT .1*X_gdu_max,.99*X_gdu_max,.15*Y_gdu_max,.9*Y_gdu_max
! Define subset of screen area
170 FRAME ! Draw a box around defined subset
180 WINDOW 0,100,16,18 ! Anisotropic scaling: left/right/bottom/top
190 FOR X=2 TO 100 STEP 2 ! Points to be plotted...
200 PLOT X,RND+16.5 ! Get a data point and plot it against X
210 NEXT X ! RND returns a value between 0 and 1
220 END
If you scale the plotting area with WINDOW or SHOW using "large" coordinates, and then execute a MOVE, PLOT or DRAW command followed by another WINDOW or SHOW using "small" coordinates, a math overflow error may occur. What do we mean by "large" or "small" coordinates? Coordinates greater than 107 are considered large in this case, while coordinates less than 60,000 are considered small.
The following example program produces an overflow error:
10 PLOTTER IS CRT, "INTERNAL"
20 A = 5.4 * 10^7 ! Choose a "large" coordinate value
30 WINDOW 0,10,0,A ! Scale the plotting area
40 MOVE 0,A ! Move to edge of plotting area
50 WINDOW 0,10,0,10 ! Math overflow error occurs here
60 MOVE 5,5
70 END
To avoid this error, add line 45 as shown below:
10 PLOTTER IS CRT, "INTERNAL"
20 A = 5.4 * 10^7 ! Choose a "large" coordinate value
30 WINDOW 0,10,0,A ! Scale the plotting area
40 MOVE 0,A ! Move to edge of plotting area
45 MOVE 0,0 ! Avoids math overflow error
50 WINDOW 0,10,0,10
60 MOVE 5,5
70 END
The graphics system does most of its math with real numbers until it is time to deal with actual pixel locations on the screen. (The word "pixel" is a blend of the two words "picture element." It is the smallest addressable point on a plotting surface.) At this time, it converts the real values to integers. When working with large values (such as 107), overflows can occur.
In the example above, line 40 moves the graphics pen to the edge of a very large plotting area which is defined in REAL coordinates. When the plotting area is rescaled to much smaller (REAL) values in line 50, the location of the graphics pen does not change. In other words, the graphics pen retains its large REAL coordinate values.
When the second WINDOW command is executed in line 50, the graphics system attempts to convert the large REAL coordinate values of the graphics pen position to INTEGERs according to the newly scaled plotting area. Since the original plotting area is much greater than the newly scaled plotting area, these large REAL coordinate values cannot be mapped into INTEGER values (since INTEGERs are limited to the range 0 through 65,535), and a math overflow error occurs.
Three statements complement the LABEL statement. The first is CSIZE, which means character size. CSIZE has two parameters: character cell height (in GDUs) and aspect ratio. The height measures the character cell size. A character cell contains a character and some blank space above, below, left of, and right of the character. The amount of blank space depends on which character is contained in the cell.
This small program shows how the CSIZE statement changes the size of characters. (Run the example program in file ``Csize''.)
100 CLEAR SCREEN ! Clear the alpha display
110 DIM Text$[50] ! Allow the long strings
120 GINIT ! Initialize various graphics parameters
130 PLOTTER IS CRT,"INTERNAL" ! Use the internal screen
140 GRAPHICS ON ! Turn on the graphics screen
150 FRAME ! Draw a box around the screen
160 WINDOW -1,1,10,1 ! Anisotropic units
170 LORG 4 ! Bottom center of labels is ref. pt.
180 FOR I=1 TO 6 ! Six labels total
190 READ Csize,Text$ ! Read the characters cell size and text
200 CSIZE Csize ! Use Csize
210 MOVE 0,SQR(I)*3+1 ! Move to appropriate place
220 LABEL Text$ ! Write the text
230 NEXT I ! Looplooplooplooplooploop
240 DATA 30,T,20,his,10,isjustlike,7,thosecutelittlecharts
250 DATA 5,thatyoualwaysseeinyourfriendly
260 DATA 3,neighborhoodoptometristsoropticiansoffice.
270 END
The FOR..NEXT loop writes lines of text on the screen with different character sizes. The DATA statements contain both pieces of information. Incidentally, notice that the WINDOW statement specifies a Ymin larger than the Ymax. This causes the top of the screen to have a lesser Y-value than the bottom. This is perfectly legal.
The next program deals with the relationship between the size of the character, per se, and the size of the character cell. (Run the example program in file ``CharCell''.)
100 CLEAR SCREEN ! Clear the alpha display
110 GINIT ! Initialize various graphics parameters
120 PLOTTER IS CRT,"INTERNAL" ! Use the internal screen
130 GRAPHICS ON ! Turn on the graphics screen
140 FRAME ! Draw a box around the screen
150 SHOW 0,36,-7.5,22.5 ! Isotropic units; Left/Right/Bottom/Top
160 FOR X=0 TO 36 ! \
170 FOR Y=0 TO 15 ! \
180 MOVE X-.1,Y+.1 ! \
190 DRAW X+.1,Y-.1 ! \
200 MOVE X+.1,Y+.1 ! > Draw all the little Xs.
210 DRAW X-.1,Y-.1 ! /
220 NEXT Y ! /
230 NEXT X ! /
240 FOR I=0 TO 27 STEP 9 ! \
250 CLIP I,I+9,0,15 ! \
260 FRAME ! > Draw boxes around the character cells
270 NEXT I ! /
280 CLIP OFF ! Deactivate clipping so LABELs will work
290 CSIZE 50 ! Character cells half the screen high
300 MOVE 0,0 ! Starting point (LORG 1 by default)
310 LABEL "AbCd" ! Sample letters
320 CSIZE 7,.45 ! \
330 LORG 6 ! \
340 MOVE 18,22 ! > Write the title
350 LABEL "Size of Character in Character Cell" ! /
360 END
As the diagram shows, a character is drawn inside a rectangle, with some space on all four sides. The character's height and width are measured in GDUs and are specified by the CSIZE statement. Program lines 250 through 280 subdivide the rectangle into four 9 wide by 15 high grids. Characters are drawn in this framework, called the symbol coordinate system. Of course, the little Xs in the plot above are not drawn when you label a string of text; they are there solely to show the position of the characters within the character cell.
The definition of aspect ratio for a character is identical to the definition of aspect ratio for the hard clip limits mentioned earlier: the width divided by the height. Thus, if you want short, fat letters, use an aspect ratio of 1.5 or larger. If you want tall, skinny letters, use an aspect ratio less than 0.5.
``CSIZE 3'' | Cell 3 GDUs high, aspect ratio 0.6 (default). |
``CSIZE 6,.3'' | Cell 6 GDUs high, aspect ratio 0.3 (tall and skinny). |
``CSIZE 1,2'' | Cell 1 GDU high, aspect ratio 2 (short and fat). |
Note that you do not have to specify a second parameter (the aspect ratio) in the CSIZE statement since it defaults to 0.6.
The second statement you need is LORG, which means label origin. This lets you specify which point on the label ends up at the point moved to before writing the label. (Run the example program in file ``Lorg''.)
100 CLEAR SCREEN ! Clear the alpha screen
110 GINIT ! Initialize various graphics parameters
120 PLOTTER IS CRT,"INTERNAL" ! Use the internal screen
130 GRAPHICS ON ! Turn on the graphics screen
140 SHOW 0,10,10.5,0 ! Isotropic scaling: Left/Right/Bottom/Top
150 FRAME ! Draw a box around the screen
160 FOR Lorg=1 TO 9 ! Loop on LORG parameters
170 LORG 2 ! Left-center origin for the "LORG n ="
180 CSIZE 4 ! Characters cell 4 GDUs high
190 MOVE 0,Lorg ! Move to position for "LORG n =" label
200 LABEL "LORG";Lorg;"=" ! Write the label
210 MOVE 8+.1,Lorg+.1 ! \
220 DRAW 8-.1,Lorg-.1 ! \
230 MOVE 8-.1,Lorg+.1 ! > Draw an "X" to show where pen is
240 DRAW 8+.1,Lorg-.1 ! /
250 LORG Lorg ! Specify LORG for "TEST",
260 CSIZE 6 ! ...and larger letters
270 MOVE 8,Lorg ! Move the center of the "X"
280 LABEL "TEST" ! Write "TEST", using current LORG
290 NEXT Lorg ! And so forth
300 END
The ×s indicate where the pen was moved to before labeling the word "TEST". This diagram means, for example, that if LORG 1 is in effect and you move to 4,5 to write a label, the lower left of that label would be at 4,5. This automatically compensates for the character size, aspect ratio, and label length. It makes no difference whether there is an odd or even number of characters in the label. If LORG 6 had been in effect, and you had moved to 4,5, the center of the top edge of the label would be at 4,5. You can readily see how useful this statement is in centering labels, both horizontally and vertically.
The third statement you need to know is LDIR, meaning label direction. LDIR specifies the angle at which the subsequent labels will be drawn. The angle is specified in the current angular units, and is either DEG (degrees) or RAD (radians). For example, assuming degrees is the current angular mode:
``LDIR 0'' | Writes label horizontally to the right. |
``LDIR 90'' | Writes label vertically, ascending. |
``LDIR 14'' | Writes label ascending a gentle slope, up and right. |
``LDIR 180'' | Writes label upside down. |
``LDIR 270'' | Writes label vertically, descending. |
In the program below, note that LORG 2 was specified and remained in effect for many LDIRs. Each label is centered on the left edge relative to the label. (Run the example program in file ``Ldir''.)
100 CLEAR SCREEN ! Clear the alpha display
110 GINIT ! Initialize various graphics parameters
120 PLOTTER IS CRT,"INTERNAL" ! Use the internal screen
130 GRAPHICS ON ! Turn on the graphics screen
140 ! (Series 200 computers)
150 FRAME ! Draw a box around the screen
160 WINDOW -1,1,-1.1,1 ! Anisotropic units; Left/Right/Bottom/Top
170 DEG ! Angular mode: Degrees
180 LORG 2 ! Label origin is left center
190 FOR Angle=0 TO 350 STEP 10 ! Every 10 degrees
200 LDIR Angle ! Labeling angle
210 MOVE 0,0 ! Move to center of screen
220 LABEL "-------LDIR";Angle ! Write using the current LDIR
230 NEXT Angle ! And so on
240 END
The label origin specified by LORG is relative to the label, not the plotting surface, and is independent of the current label direction. For example, if you specified
LORG 3
DEG
LDIR 90
MOVE 6,8
and then wrote the label, it would be written going straight up, not horizontally. Therefore, it is the upper left corner of the label which is at point 6,8 relative to the rotated label. Relative to the plotting device, however, it is the lower left corner of the label which is at 6,8 (in this example) because the label has been rotated.
The statement which actually causes labels to be written is LABEL. LABEL accounts for the most recently specified CSIZE, LDIR and LORG when it writes a label. You must position the label, however, by using (for example) a MOVE statement to get to the point at which you want the label to be placed.
All four statements have been utilized in the following program. (Run the example program in file ``SinLabel''.)
100 CLEAR SCREEN ! Clear the alpha display
110 GINIT ! Initialize various graphics parameters.
120 PLOTTER IS CRT,"INTERNAL" ! Use the internal screen
130 GRAPHICS ON ! Turn on the graphics screen
140 X_gdu_max=100*MAX(1,RATIO) ! Determine how many GDUs wide the screen is
150 Y_gdu_max=100*MAX(1,1/RATIO) ! Determine how many GDUs high the screen is
160 LORG 6 ! Reference point: center of top of label
170 MOVE X_gdu_max/2,Y_gdu_max ! Move to middle of top of screen
180 LABEL "VOLTAGE VARIANCE" ! Write title of plot
190 DEG ! Angular mode is degrees (used in LDIR)
200 LDIR 90 ! Specify vertical labels
210 CSIZE 3.5 ! Specify smaller characters
220 MOVE 0,Y_gdu_max/2 ! Move to center of left edge of screen
230 LABEL "Voltage" ! Write Y-axis label
240 LORG 4 ! Reference point: center of bottom of label
250 LDIR 0 ! Horizontal labels again
260 MOVE X_gdu_max/2,.07*Y_gdu_max! X: center of screen; Y: above key labels
270 LABEL "Time (seconds)" ! Write X-axis label
280 VIEWPORT .1*X_gdu_max,.99*X_gdu_max,.15*Y_gdu_max,.9*Y_gdu_max
! Define subset of screen area
290 FRAME ! Draw a box around defined subset
300 WINDOW 0,100,16,18 ! Anisotropic scaling: left/right/bottom/top
310 FOR X=2 TO 100 STEP 2 ! Points to be plotted...
320 PLOT X,RND+16.5 ! Get a data point and plot it against X
330 NEXT X ! et cetera
340 END
Many times it's nice to have bold letters. You can achieve this effect by plotting the label several times, moving the label origin just slightly each time. In the following version of the program, notice lines 180 through 210. The loop variable, ``I'', goes from -.3 to .3 by tenths. This is the offset in the X direction of the label origin. Since this is being labeled with LORG 6 in effect, the label origin (the point moved to immediately prior to labeling) represents the center of the top edge of the label. (Run the example program in file ``SinLabel2''.)
100 CLEAR SCREEN ! Clear the alpha display
110 GINIT ! Initialize various graphics parameters.
120 PLOTTER IS CRT,"INTERNAL" ! Use the internal screen
130 GRAPHICS ON ! Turn on the graphics screen
140 X_gdu_max=100*MAX(1,RATIO) ! Determine how many GDUs wide the screen is
150 Y_gdu_max=100*MAX(1,1/RATIO) ! Determine how many GDUs high the screen is
160 LORG 6 ! Reference point: center of top of label
170 FOR I=-.3 TO .3 STEP .1 ! Offset of X from starting point
180 MOVE X_gdu_max/2+I,Y_gdu_max! Move to about middle of top of screen
190 LABEL "VOLTAGE VARIANCE" ! Write title of plot
200 NEXT I ! Next position for title
210 DEG ! Angular mode is degrees (used in LDIR)
220 LDIR 90 ! Specify vertical labels
230 CSIZE 3.5 ! Specify smaller characters
240 MOVE 0,Y_gdu_max/2 ! Move to center of left edge of screen
250 LABEL "Voltage" ! Write Y-axis label
260 LORG 4 ! Reference point: center of bottom of label
270 LDIR 0 ! Horizontal labels again
280 MOVE X_gdu_max/2,.07*Y_gdu_max! X: center of screen; Y: above key labels
290 LABEL "Time (seconds)" ! Write X-axis label
300 VIEWPORT .1*X_gdu_max,.99*X_gdu_max,.15*Y_gdu_max,.9*Y_gdu_max
! Define subset of screen area
310 FRAME ! Draw a box around defined subset
320 WINDOW 0,100,16,18 ! Anisotropic scaling: left/right/bottom/top
330 FOR X=2 TO 100 STEP 2 ! Points to be plotted...
340 PLOT X,RND+16.5 ! Get a data point and plot it against X
350 NEXT X ! et cetera
360 END
This method can also be used to offset in the Y direction. Or, offset both X and Y. This will give you characters that are thick in a diagonal direction, which makes them look like they are coming out of the page at you. However, a more typical bolding is produced by offsetting only in the X direction.
AXES and GRID do similar operations. We've already seen how to use the AXES statement. The GRID statement causes the major tick marks to extend all the way across the plotting surface.
Once we have the axes drawn, we must label various points along them with numbers designating the values at those points. Once again, we use the LABEL statement. (Run the example program in file ``SinAxes''.)
100 CLEAR SCREEN ! Clear the alpha display
110 GINIT ! Initialize various graphics parameters.
120 PLOTTER IS CRT,"INTERNAL" ! Use the internal screen
130 GRAPHICS ON ! Turn on the graphics screen
140 X_gdu_max=100*MAX(1,RATIO) ! Determine how many GDUs wide the screen is
150 Y_gdu_max=100*MAX(1,1/RATIO) ! Determine how many GDUs high the screen is
160 LORG 6 ! Reference point: center of top of label
170 FOR I=-.3 TO .3 STEP .1 ! Offset of X from starting point
180 MOVE X_gdu_max/2+I,Y_gdu_max! Move to about middle of top of screen
190 LABEL "VOLTAGE VARIANCE" ! Write title of plot
200 NEXT I ! Next position for title
210 DEG ! Angular mode is degrees (used in LDIR)
220 LDIR 90 ! Specify vertical labels
230 CSIZE 3.5 ! Specify smaller characters
240 MOVE 0,Y_gdu_max/2 ! Move to center of left edge of screen
250 LABEL "Voltage" ! Write Y-axis label
260 LORG 4 ! Reference point: center of bottom of label
270 LDIR 0 ! Horizontal labels again
280 MOVE X_gdu_max/2,.07*Y_gdu_max! X: center of screen; Y: above key labels
290 LABEL "Time (seconds)" ! Write X-axis label
300 VIEWPORT .1*X_gdu_max,.98*X_gdu_max,.15*Y_gdu_max,.9*Y_gdu_max
! Define subset of screen area
310 FRAME ! Draw a box around defined subset
320 WINDOW 0,100,16,18 ! Anisotropic scaling: left/right/bottom/top
330 AXES 1,.05,0,16,10,5,3 ! Draw axes with appropriate ticks
340 CLIP OFF ! So labels can be outside VIEWPORT limits
350 CSIZE 2.5,.5 ! Smaller chars for axis labeling
360 LORG 6 ! Ref. pt: Top center |\
370 FOR I=0 TO 100 STEP 10 ! Every 10 units | \
380 MOVE I,15.99 ! A smidgeon below X-axis | > Label X-axis
390 LABEL USING "#,K";I ! Compact; no CR/LF | /
400 NEXT I ! et sequens |/
410 LORG 8 ! Ref. pt: Right center |\
420 FOR I=16 TO 18 STEP .25 ! Every quarter | \
430 MOVE -.5,I ! Smidgeon left of Y-axis | > Label Y-axis
440 LABEL USING "#,DD.DD";I ! DD.DD; no CR/LF | /
450 NEXT I ! et sequens |/
460 PENUP
470 FOR X=2 TO 100 STEP 2 ! Points to be plotted
480 PLOT X,RND+16.5 ! Plot a data point
490 NEXT X
500 END
Note that the tick marks drawn by the AXES statement extend only toward the interior of the graph. Clipping (automatically put into effect by the VIEWPORT statement) was still active at the soft clip limits. If the CLIP OFF statement had been placed before the AXES statement, the tick marks would have extended on both sides of the axes. However, the axes themselves would have extended across the entire width of the hard clip limits and right through the axes' labels.
The CLIP OFF statement was necessary, though. The LABEL statement draws the letters as a series of vectors (lines), and any lines which are outside the current soft clip limits (when CLIP is ON) are cut off. This means that had line 350 (the CLIP OFF) been missing from the program, none of the axis labels would have been drawn, since they are all outside the VIEWPORT area. Of course, the main titles ("VOLTAGE VARIANCE", "Voltage", and "Time (seconds)") would still have been drawn, because they are done before the VIEWPORT is executed.
If your graph needs to be read with more precision than the AXES statement affords, you can use the GRID statement. This is similar to AXES, except the major ticks extend across the entire soft clip area, and the minor ticks for X and Y intersect in little crosses between the grid lines. The previous program has only one change: the AXES statement has been replaced by a GRID statement.
GRID 5,.25,0,16,2,2,1 ! Draw grid with appropriate ticks
Note that not only was AXES replaced by GRID, some of the parameters were changed also because the minor ticks specified in the AXES statement were so close together that the minor tick crosses drawn by the GRID statement would have overlapped. The end result would have been a grid with even the minor ticks extending all the way across the soft clip area.
On many occasions, an application is defined such that there is no question as to which statement to use. Other times, however, you want to weigh the alternatives carefully before setting your program in concrete. To aid you in the decision, here are some advantages and disadvantages to both statements.
Advantages of AXES:
Advantages of GRID:
However, if you want to estimate data points accurately from the finished plot, but also want to prevent the plot from appearing cluttered, it can be done. Below is a plot drawn by a program identical to the previous one except for the GRID statement. The GRID statement used specifies exactly the same parameters as the AXES statement (two programs ago) with one exception: the major tick length parameter is reduced. This causes the tick crosses to be reduced to dots. Using this strategy allows easy interpolation of data points (to the same accuracy previously used in the AXES statement), but does not clutter the graph as much as normal ticks would.
GRID 1,.05,0,16,10,5,.0001 ! Draw grid with appropriate ticks
Be aware that the computer still thinks of these smaller tick marks as crosses, which means that both the horizontal and vertical components must be drawn. This looks to you like drawing and then redrawing each dot. Therefore, you can expect this type of grid to take a while to plot when you send it to a hard-copy plotter.
Another way to compromise between ease of interpolation and lack of clutter is to use both AXES and GRID in the same program. Note the program below. GRID is used for the major tick lines, but since the minor tick crosses are not desired within each rectangle between the major tick lines, AXES is used to specify minor ticks. (Run the example program in file ``SinGrdAxes''.)
100 CLEAR SCREEN ! Clear the alpha display
110 GINIT ! Initialize various graphics parameters.
120 PLOTTER IS CRT,"INTERNAL" ! Use the internal screen
130 GRAPHICS ON ! Turn on the graphics screen
140 LORG 6 ! Reference point: center of top of label
150 X_gdu_max=100*MAX(1,RATIO) ! Determine how many GDUs wide the screen is
160 Y_gdu_max=100*MAX(1,1/RATIO) ! Determine how many GDUs high the screen is
170 FOR I=-.3 TO .3 STEP .1 ! Offset of X from starting point
180 MOVE X_gdu_max/2+I,Y_gdu_max! Move to about middle of top of screen
190 LABEL "VOLTAGE VARIANCE" ! Write title of plot
200 NEXT I ! Next position for title
210 DEG ! Angular mode is degrees (used in LDIR)
220 LDIR 90 ! Specify vertical labels
230 CSIZE 3.5 ! Specify smaller characters
240 MOVE 0,Y_gdu_max/2 ! Move to center of left edge of screen
250 LABEL "Voltage" ! Write Y-axis label
260 LORG 4 ! Reference point: center of bottom of label
270 LDIR 0 ! Horizontal labels again
280 MOVE X_gdu_max/2,.07*Y_gdu_max! X: center of screen; Y: above key labels
290 LABEL "Time (seconds)" ! Write X-axis label
300 VIEWPORT .1*X_gdu_max,.98*X_gdu_max,.15*Y_gdu_max,.9*Y_gdu_max
! Define subset of screen area
310 WINDOW 0,100,16,18 ! Anisotropic scaling: left/right/bottom/top
320 AXES 1,.05,0,16,5,5,3 ! Draw axes intersecting at lower left
330 AXES 1,.05,100,18,5,5,3 ! Draw axes intersecting at upper right
340 GRID 10,.25,0,16,1,1 ! Draw grid with no minor ticks
350 CLIP OFF ! So labels can be outside VIEWPORT limits
360 CSIZE 2.5,.5 ! Smaller chars for axis labeling
370 LORG 6 ! Ref. pt: Top center |\
380 FOR I=0 TO 100 STEP 10 ! Every 10 units | \
390 MOVE I,15.99 ! A smidgeon below X-axis | > Label X-axis
400 LABEL USING "#,K";I ! Compact; no CR/LF | /
410 NEXT I ! et sequens |/
420 LORG 8 ! Ref. pt: Right center |\
430 FOR I=16 TO 18 STEP .25 ! Every quarter | \
440 MOVE -.5,I ! Smidgeon left of Y-axis | > Label Y-axis
450 LABEL USING "#,DD.DD";I ! DD.D; no CR/LF | /
460 NEXT I ! et sequens |/
470 PENUP ! LABEL statement leaves the pen down
480 FOR X=2 TO 100 STEP 2 ! Points to be plotted...
490 PLOT X,RND+16.5 ! Get a data point and plot it against X
500 NEXT X ! et cetera
510 END
Note that two AXES statements were used. The parameters are identical save for the position of the intersection. The first AXES specifies an intersection position of 0,16: the lower left corner of the soft clip area. The second specifies an intersection position of 100,18: the upper right corner of the soft clip area.
Also note that the FRAME statement was removed; the lines around the soft clip limit were being drawn by the AXES statements and the GRID statement anyway.