Scripts and Utilities -- Jgraph lecture

  • Jim Plank
  • Directory: /home/cs494/notes/Jgraph
  • This file:
  • Lecture links:
  • Email questions and answers


    Jgraph is a tool for drawing graphs and structured drawings. Unlike most drawing tools, jgraph is non-interactive -- its takes an input file, and produces either plain or encapsulated PostScript as output. This output may be viewed on the screen (using ghostscript or ghostview), printed on a printer (using lpr), embedded into other formatters such as latex or framemaker, or converted into other format (e.g. ppm or gif) files.

    The complete reference for jgraph is its man page. To run jgraph, you usually do

    jgraph in.jgr > out.eps
    jgraph -P in.jgr >
    The eps file is encapsulated postscript, which is used by other programs such as latex. The ps file is plain postscript which may be viewed with gs or printed with lpr.

    If no input filename is given, jgraph will read from standard input.

    Simple Jgraph Examples

    As with most of these programs, it's easiest to get conversant with jgraph by looking at examples. With jgraph, you specify to draw a new graph with the newgraph keyword. You can then add curves to your graph with newcurve, and points to your curve with pts. Here's a simple example (in simp1.jgr):
    newcurve pts 2 3   4 5   1 6
    To take a look at this graph, do:
    UNIX> jgraph -P simp1.jgr >
    UNIX> gs
    Or, just look at the postscript output with netscape.

    What this has done is draw a simple graph with three points: (2,3), (4,5) and (1,6). Jgraph added axes and chose how to plot the points. It's not very pretty, but it's a start.

    Next, take a look at simp2.jgr. This is a slightly more complex jgraph example. Let's break it into pieces:

    xaxis size 2 
    yaxis size 1.5 
    As before, the newgraph starts the graph. Next, the sizes of the two axes (in inches) are set. After that, three curves are drawn:
    newcurve pts 0 6  1 9  2 11  3 14  4 18 5 20
    newcurve marktype triangle linetype solid
             pts 0 3  1 4  2 7  3 9  4 10 5 13
    newcurve marktype none linetype dashed color 1 0 0
             pts 0 0  1 2  2 3  3 5  4 6  5 9
    The first lets jgraph choose the drawing style. The second plots the points with triangles, and connects them with a solid line. The third does not plot the points, but just the line connecting them. The line will be dashed, and its color will be red (colors are specified as rgb values where 1 is full saturation). Take a look at the jgraph output. You'll note that jgraph's axes have been made just large enough to plot all the points.

    The valid marktypes and linetypes are defined in the man page. You may use newline instead of ``newcurve marktype none linetype solid''

    Some Syntax

    Jgraph is not line based. It simply works on words separated by white space. Comments must be surrounded by (* and *). There are a few basic objects in jgraph: You may view jgraph input as editing these objects. Thus, when you say newcurve you are then editing a curve, and may specify curve attributes like the marktype, linetype and points. Most attributes have defaults which you can change. If you specify an attribute more than once, jgraph will only honor the last one, so saying ``newcurve marktype box marktype circle'' is equivalent to ``newcurve marktype circle.''

    There are some exceptions to this. For example, whenever you say pts, you are adding points to the current curve. Therefore

    newcurve pts 0 0   1 1   2 2 
    newcurve pts 0 0 pts 1 1 pts 2 2
    are equivalent.

    You may include files most anywhere in your jgraph input by saying ``include filename.''

    Messing with the axes

    Often you don't like the way that jgraph automatically lays out axes. Axes have the following attributes (among others): So, look at axis.jgr. This flexes some of the above attributes. Take a look at the output.

    Messing with curves

    Jgraph chooses default sizes for your marks. You may set them yourself with marksize width height. The width will be units of the x axis (or inches if the axis is logarithmic), and the height will be in units of the y axis.

    You may say copycurve to create a curve with the same attributes as the previous curve (but not the same points).

    Curve.jgr shows an example. Take a look at the output. Note that cfill fills the inside of a mark with the specified color.


    Jgraph lets you plot strings with newstring. String attributes are the location font, fontsize, color, rotation justification and the text. The location is set by ``x x-position y y-position.'' The font must be a postscript font. Standard fonts are Times-Roman, Times-Italic, Times-Bold, Helvetica, Helvetica-Italic, Helvetica-Bold, Courier, and Symbol. The color is specified with lcolor (lgray lets you specify greyscale). Justifications are specified as follows: You can rotate a string with rotate deg. You set the text of the string with a colon, followed by either a space or a newline, and then the text. If you want multiline text, then end all lines but the last with a backslash.

    Graph labels are strings too and can make use of the above attributes.

    Copystring copies all attributes of a string (including the text).

    Strings.jgr shows an example. Take a look at the output.


    You can add a label to a curve with the label attribute. This specifies to make a legend entry for the curve. See legend1.jgr for an example (here's the output).

    You can change the font and location of the legend as a unit by saying ``legend defaults'' and then specifying string attributes. This will modify all of the legend strings. See legend2.jgr for an example (here's the output). Try modifying it and see what happens. There are other cool things you can do with the legend -- see the man page.


    Like the legend defaults, you may modify the hash labels on an axis as a composite, using the ``hash_labels'' attribute. For example, to change the hash labels in curve.jgr so that the font is Times-Italic, and the font size is 16, you do the following (in hlabels.jgr, output here).
      hash_labels font Times-Italic fontsize 16
      hash_labels font Times-Italic fontsize 16

    Bar Graphs

    You may use the xbar and ybar marktypes to make bar graphs. Xbar means draw the bar to the x-axis, and ybar means draw the bar to the y-axis.

    Bar.jgr shows a fairly nice bar graph. First, take a look at the output. Now, note a few things about the file, which I'll include below:

      min 0.1 max 4.9 
      size 3.5
      hash 1 mhash 0 no_auto_hash_labels
    First, after setting the size and extent of the x-axis, we set it to have hash marks every unit, and no minor hash marks. Moreover, we tell jgraph not to produce hash labels automatically. This is because we want to provide our own hash labels.
      min 0 max .4
      size 2
      precision 3
    There's nothing too fancy here, except that the precision attribute specifies to include three digits behind the decimal point in the hash labels for the y-axis.
    newcurve marktype xbar cfill 1 0 0 marksize .8 
      pts   1 .390
            2 .389
            3 .353 
            4 .343
    This draws the curve, which will be red bars to the x axis.
      hash_label at 1 : Larry Walker
      hash_label at 2 : Tony Gwynn
      hash_label at 3 : Mike Piazza
      hash_label at 4 : Kenny Lofton
      hash_labels hjl vjc font Helvetica rotate -90
    Now we modify the x axis again, putting hash labels at individual points, and then modifying the hash labels so that they're rotated by 90 degrees.
    yaxis label : Batting Average
    title : NL Batting Leaders, August 5, 1997
    Finally, we put a label on the y-axis and a title for the graph.

    This shows some of the power of jgraph -- it lets you do fairly sophisticated graph formatting in a straightforward manner.

    Fancier things: polygons

    Jgraph lets you turn curves into polygons, which helps when you start using jgraph to make drawings. Simply use the poly attribute for the curve. Pfill and pcfill allow you to specify greyscale and color filling for the polygon. linethickness lets you control the thickness of the border line. The units of linethickness are ``absolute postscript units'' -- the default is 1.0. You can fill the polygon with stripes rather than solid color by using ``ppattern stripe slant,'' where slant controls the degree of slanting. Finally, if you use -1 as a fill color, the polygon will just consist of the border -- the inside will not be filled. Sometimes this is desirable.

    Poly.jgr shows an example of some polygons with different fillings. Note that jgraph draws curves in the order specified, so that you know how the overlapping will occur. Take a look at the output.

    Bezier curves

    You can produce curved lines in jgraph by having the points specify control points on a bezier curve. I don't have the time to explain what bezier curves are, but each curve has 4 control points.

    With jgraph you can use 3n+1 points to draw n connected bezier curves. Football.jgr shows an example of drawing a football using bezier curves in jgraph. Take a look at the output. Yes, it's low budget, but it works.

    The Shell

    You can put shell commands into jgraph with
    shell : command
    This is a very powerful feature, becuase it lets you use awk or perl to do function plotting, data extraction, etc. We'll see this used below.

    Postscript marks

    One of the neat features of jgraph is the ability to use an encapsulated postscript file as a marktype. For example, we can use the football above as a mark to make one of those USA Today-style graphs. First, we make football.eps using jgraph without the -P option. You can view this using gv if you want.
    UNIX> jgraph football.jgr > football.eps
    Now, we'll draw a USA Today style graph. It's in fbf.jgr. I'll lay it out below.

    First, the axes are set and a big green box is drawn in the graph:

      min .2 max 2.8 size 5
      no_auto_hash_labels mhash 0 hash 1 shash 1
      min 0 max 10 size 6 
    newcurve marktype box marksize 2.6 10 cfill .5 1 .5 pts 1.5 5
    Next, we're going to draw a football field. First we draw lines at the 10-yard marks. These don't go all the way across the field -- they leave a space in the middle for the yard number:
    shell : echo "" | awk '{ \
              for (i = 1; i < 10; i += 1) { \
                 printf ("newline gray 1 pts 0.2 %d 1.4 %d\n", i, i); \
                 printf ("newline gray 1 pts 1.6 %d 2.8 %d\n", i, i); \
              } }'
    Now, we draw the 10-yard labels. This works by drawing a dummy label, and then copying it with an awk script:
    newstring hjc vjc font Times-Italic lgray 1 fontsize 14 x 1.5
    shell : echo "" | awk '{ \
              for (i = 1; i < 6; i += 1) { \
                 printf "copystring y %d : %d0\n",i, i \
              } }'
    shell : echo "" | awk '{ \
              for (i = 6; i < 10; i += 1) { \
                 printf "copystring y %d : %d0\n",i, 10-i \
              } }'
    Then we draw the one-yard marks up and down the left and right side of the field:
    shell : echo "" | awk '{ \
              for (i = 0; i < 10; i += .1) { \
                 printf "newline gray 1 pts 0.97 %f 1.03 %f\n", i, i \
                 printf "newline gray 1 pts 1.97 %f 2.03 %f\n", i, i \
              } }'
    Next, we draw footballs to represent university budgets, and then label the two ``bar graphs'' -- one for the University of Tennessee and one for Princeton:
    newcurve eps football.eps marksize .35 1 pts
      1 .5
      1 1.5
      1 2.5
      1 3.5
      1 4.5
      1 5.5
      1 6.5
      1 7.5
      1 8.5
      1 9.5
      2 .5
      hash_labels fontsize 20
      hash_label at 1 : University\
      hash_label at 2 : \
    Finally, we put a title on the right-hand side of the graph, and a little key, and we're done.
    newstring fontsize 28 hjc vjt x 3.4 y 9
      : University\
    newcurve eps football.eps marksize .35 1 pts 3.35 3
    newstring fontsize 20 hjl vjc x 3.55 y 3 : =
    copystring hjc vjc x 3.4 y 2 : 1 Gazillion\
    Take a look at the output. Cute, no?

    Other resources

    There is more information about jgraph, and examples, at Make sure you look at jgrtoppm and ctojgr.

    Multiple Graphs

    You can put multiple graphs in one drawing with another newgraph or with a copygraph, to copy the axes of a previous graph. X_translate and y_translate are two attributes of graphs that let you lay out multiple graphs. You can also put graphs on multiple pages with newpage.

    Copygraph.jgr shows an example of using copygraph. Here's the output.