Gri
A command-driven language for scientific illustration, written by oceanographer Dan Kelley to make publication-quality PostScript graphs reproducibly from a text file rather than from a mouse.
Created by Dan E. Kelley, an oceanographer at Dalhousie University in Halifax, Nova Scotia. Peter S. Galbraith, a research scientist with the Canadian Department of Fisheries and Oceans, wrote the Emacs mode and did the Debian packaging
Gri is a language for drawing scientific graphs. You do not point at anything, drag anything or open a dialog box; you write a text file of English-like drawing commands, run gri over it, and get a PostScript figure. It makes x-y plots, contour plots and image plots, and it gives the author control over every line width, grayscale, colour and font on the page. It was written by Dan E. Kelley, an oceanographer at Dalhousie University, for the figures in his own papers, and its copyright notice runs from 1991 to 2020 - close to thirty years of one person’s maintenance of a tool built to solve one person’s problem.
The comparison the author reaches for, and that users repeat, is TeX. Both take a plain-text source file and emit a typeset artefact. Both ask for a real if modest learning investment and then repay it indefinitely. Both are at their best when the same document must be regenerated many times as the underlying material changes, and at their worst when you just want to see something quickly.
A Note on Dating
Language catalogues frequently list Gri as appearing in 1989. That date is difficult to support from primary sources. Every copyright notice the author attaches to the program - in the manual, the man page, the FAQ and the GitHub README - begins in 1991, and the versions differ only in the closing year as the project aged - the FAQ in the released source still reads 1991-2000, while the README reads 1991-2020.
A 1989 origin is plausible for gr, the predecessor. The FAQ is explicit that “Gri started out as a set of subroutines” called gr, and that the name Gri means gr-interactive. The author has said he has not used gr in years and is not aware of anybody else who ever did. So the honest statement is that the tooling lineage may well reach back to the late 1980s, but the language called Gri dates from approximately 1991. This page uses 1991.
Design Philosophy
Gri is built around a small number of decisions that were unfashionable when it was written and have aged remarkably well.
The figure is source code. A Gri command file is a complete, human-readable, version-controllable description of a figure. Reviewers ask for the axis limits to change; you change one line and re-run. Six months later a referee asks what exactly was plotted, and the answer is in the file. This is the same argument that would later be made for R scripts, matplotlib and ggplot2, and it was Gri’s central premise from the start.
It must run unattended. Because there is no interactive step, Gri can sit inside a cron job or a forecast pipeline. The author’s own example is a storm-surge forecast system that regenerates its graphics automatically. An interactive plotting program cannot be used this way at all.
Output is PostScript, not a screen. Gri targets the printed page rather than a window. That decision cost it the instant feedback that made competing tools feel friendlier, and bought precise typographic control and platform independence in exchange.
Sensible defaults, total override. A three-line command file produces a reasonable graph. The set family of commands then lets the author override essentially every aspect of the drawing, down to individual dash patterns and font encodings. The gap between “quick look” and “camera-ready” is a series of small edits rather than a change of tool.
Deliberate omissions. The FAQ says it plainly: Gri “has few frills; e.g., it does not do 3D mesh plots, because the author dislikes them.” A tool with one maintainer and an opinion is a coherent tool.
How It Reads
The syntax is unusual among programming languages: commands are multi-word English phrases, and there is very little punctuation. The minimal complete program from the author’s Linux Journal article is three commands - open a file, read two columns, draw the curve:
open linegraph.dat
read columns x y
draw curve
Everything beyond that is refinement: naming the axes, fixing the ranges, setting symbol shapes, adding a second dataset. Commands are grouped into recognisable families - open and read for input, draw for marks on the page, set for state, query for interaction - and the multi-word form means the command name usually reads as documentation of itself.
Beneath the drawing commands sits a real if small programming layer. Gri has scalar variables and string synonyms, an RPN expression syntax for arithmetic, if and while constructs, and the ability to define new commands - so a lab can build a house style as a library of draw my_standard_axes-style commands and use it across every figure in a paper.
Data Model
Gri’s data kinds map onto the shapes that physical-science data actually takes:
| Kind | What it holds | Typical use |
|---|---|---|
| Scalar | A single number | Limits, offsets, loop counters |
| Synonym | A string | Filenames, labels, reusable text |
| Column | A one-dimensional series | x-y plots, time series, profiles |
| Grid | Values on a regular or irregular mesh | Contour plots |
| Image | A raster of intensity values | Satellite imagery, sonar, photographs |
The conversions between them are commands in their own right - grids can be converted to images, columns gridded into grids - which is what makes the language feel purpose-built rather than general. Data comes from ASCII files, native binary, or netCDF, the standard container for climate and ocean data; NSF Unidata’s netCDF software directory lists Gri on exactly that basis.
Text uses a subset of TeX syntax, so mathematical symbols and Greek letters in axis labels are written the way a physical scientist already writes them.
Implementation
Gri is written in C++ - roughly 44,000 lines across the src directory of the current source tree, a figure that includes a pared-down copy of the popt option-parsing library - and has needed a compiler with templates and the STL since a time when that was a real constraint; the FAQ gives g++ 2.7.2 as the documented minimum. It builds with the conventional ./configure && make && make install. The FAQ reports ports to “several Unix machines (e.g. Sun solaris and sunOS; IBM RISC; HP RISC; SGI; DEC alpha; and x86 linux)” and to x86 MS-DOS, and notes that an old version was available for DEC VAX VMS; the vendor Unix names there are presumably AIX and HP-UX, though the FAQ does not say so. macOS is not in that list, but the source tree carries fink and darwinport packaging directories and a --enable-OSX_BUNDLE configure flag, so some Mac support clearly exists. For most users, though, the installation story is simply the Debian or Ubuntu package.
Two companion utilities ship with it: gri_merge, which merges several Gri output files into a single PostScript file - optionally tiled onto one page in a given number of columns and rows - and gri_unpage, which splits a multi-page Gri PostScript document into one file per page.
Evolution
Gri’s version history follows a clear and slightly poignant arc. The versioning rule is explicit in the manual: an even middle number is a stable stream, an odd one is unstable, and within a stable stream only the release ending in .0 introduces features while the rest fix flaws. The stable streams run 2.2, 2.4, 2.6, 2.8, 2.10, 2.12 - and stop.
The 2.2 stream arrives in March 1999 with the first Debian release. The 2.12 stream opens on 15 September 2002 and never closes. Features keep trickling in through the point releases for a while - hexadecimal colour names in 2003, an age RPN function for testing file ages the same year, GNU readline support for interactive mode in 2008, axis labelling options in 2010 - but no 2.14 is ever begun. The 2.12 line simply continues, absorbing fixes, through 2.12.23 in July 2011 and 2.12.26 in January 2017 - the last entry in the manual’s history - to the 2.12.27 that Debian carries now.
There was one attempt at succession. From the late 1990s the author worked on Gre, which its repository describes as a “perl-like variant of gri scientific graphics language”: a rewrite around a new parser, shipped with a gri2gre script for converting existing command files. The earliest dated file in it is stamped August 1998, its parser sources run from 1999 to 2000, and its ChangeLog stops at July 2003 with the version numbered 0.3.2. The README now states flatly that “Gre has not been updated in over a decade, as the author (Dan Kelley) started using R for both data processing and plotting, many years ago.” The older language outlived its replacement - a common ending for a rewrite undertaken by the sole maintainer of a working tool.
Current Relevance
Gri is dormant in the precise sense: not abandoned, not developed. The GitHub repository saw its most recent commit in April 2024, addressing a time_t compilation problem on Debian. That is the signature of a maintainer keeping an old C++ program building against modern toolchains rather than one adding features. The Wikipedia article on Gri carries notability and maintenance tags, which is its own kind of evidence about the size of the community.
Its niche has been comprehensively occupied. Everything Gri does, gnuplot does with a larger community, matplotlib does inside a general-purpose language, and ggplot2 does with a grammar-of-graphics vocabulary and a statistics ecosystem attached. Notably, the author himself moved on: Dan Kelley went on to write the oce package for R and a book on oceanographic analysis in R, which is where a scientist with his problem would now most naturally be pointed.
What remains is a working, packaged, documented tool that will still render a figure exactly as it did in 2002 from a command file written in 2002. For anyone maintaining an old analysis pipeline, that is not a small thing.
Why It Matters
Gri is the clearest early expression of an idea that is now simply how scientific graphics is done: a figure should be the output of a script, not the output of an afternoon. When Gri was written, the dominant paradigm for making a graph was to load data into an interactive application and adjust it by hand until it looked right - a process that is unreproducible, unautomatable, and forgotten by the time the referee’s comments arrive. Gri’s answer, that the figure specification is a text file you keep, is now the assumption behind matplotlib scripts, ggplot2 pipelines and every reproducible-research workflow, none of which descend from Gri but all of which arrived at its conclusion.
It is also a good study in the economics of specialist software. One scientist, one problem domain, thirty years of copyright notices, a collaborator who wrote the Emacs mode and did the packaging, and a distribution channel - Debian - that has outlasted the development effort by two decades. Gri never needed a company, a foundation or a conference. It needed a person who kept using it, and it lasted precisely as long as that held.
For a language catalogue, Gri is a reminder that domain-specific languages are not all configuration formats and build files. Some of them are full languages - with variables, loops, RPN arithmetic and user-defined commands - that happen to have been designed by someone who knew exactly one job and wanted it done properly.
Timeline
Notable Uses & Legacy
Debian and Ubuntu
Gri has been packaged for Debian since version 2.2.0 in March 1999, maintained by Peter Galbraith, and is split into the gri program plus gri-el for the Emacs mode and gri-html-doc and gri-pdf-doc for the manual. Version 2.12.27 is present in current Debian suites, which means a language whose last feature release was in 2002 is still one apt install away
Dalhousie University oceanography
Gri was written by a working oceanographer for his own research figures, and Kelley's department at Dalhousie is presumably where it was first used in earnest, though the sources document the authorship rather than any departmental adoption. Its data model - columns, grids and images, with contour and image plots as first-class citizens rather than add-ons - is shaped directly by the needs of gridded ocean and atmospheric data
Unattended storm-surge forecast graphics
In his Linux Journal article the author cites the use of Gri for the graphics of an oceanographic storm-surge forecast system, chosen because the figures must be produced repeatedly and automatically with no human intervention - the case where a command-file language beats an interactive plotting application outright
netCDF data visualization
NSF Unidata's directory of netCDF software lists Gri, describing it as an extensible plotting language for scientific graphs that can read data from netCDF files as well as ASCII and native binary data. netCDF is the standard container for climate, atmospheric and oceanographic data, and reading it natively put Gri directly in that workflow
Emacs as an authoring environment
Peter Galbraith's Gri mode for Emacs, distributed with the language and packaged separately in Debian, provides syntax highlighting, command completion and one-key access to the manual entry for the command under the cursor - a practical answer to a language with several hundred multi-word commands