gnuplot ~ a non-trivial introduction

Share this:

We are awash in data. Often the best – or only – way to understand the meaning of data is graphic; humans have been extracting meaning from images far longer than from tabular text. Today I’ll present an introduction to graphing (plotting) data with gnuplot, a command-line program that generates two- and three-dimensional graphical plots of functions and data.

The advantages to using a command-line-driven program are that it can be easily scripted into computational workflows and repeated as needed. gnuplot runs on all major computers and operating systems, is free, and is therefore no impediment to creating cross-platform solutions. gnuplot can plot directly on screen, in many graphic file formats, and in LaTeX. It can be used both interactively and in a scripted, batch mode; we explore only the latter.

gnuplot was first released in 1981, so it carries a cachet of longevity, and comes with a large and far-flung user community; things helpful to us.

I call this a “non-trivial introduction” because in contrast with the myriad web pages which present the same basic information, I’ll quickly move to a real-world plotting need that (1) I needed to solve (2) shows off some of gnuplot’s power and ease-of-use.

Righting wrongs

I’m not done. I need the time axis to be on the bottom, as is customary in my world. I want the columns processed as time vs level, so column 2 vs column 1.

plot file using 2:1 with linespoints

For my brain (at least) this is better: I can intuitively see the battery starting full, discharging, then recharging. Done!

A seconds look

While thrilled to have the time axis on the bottom, I’m not loving the time expressed in seconds. I don’t think in terms of seconds for my phone’s battery life. To cause the x axis to show in hours (each of which is 3600 seconds), try:

plot file using ($2/3600):1 with linespoints

Okay, now we’ve got a minimally acceptable plot. With this I could be satisfied.

Don’t label me, bro

One more tweak comes to mind: labeling the data points. Yes, you could trace your finger over and up and figure out each point’s position, but why? Having gnuplot do it will teach two things:

gnuplot can process one dataset multiple times, each with different styles

the “string print function” sprintf() will give you power to create text strings just perfect for your needs

the continuation character \ will make your batch scripts more readable and maintainable

To generate a labeled plot, we first trace the linespoints style seen before, and then process the same data with the labels style.

the continuation character \ makes one long line much easier to understand

notitle prevents the same data appearing twice in the legend

with labels offset 3,0 slides the labels away from the point, for readability

Pretty in pink

We’ve done a decent job of presenting the data in an easier-to-understand way, and we could leave now. There’s a world of difference between the default gnuplot styles and what it can do. Here’s the unlabelled plot all gussied up:

Whoa! This plot commands respect! Okay, the dark gray grid is muted and shows off the plotlines. How did we do it?

Rather than disect this line-by-line, I’ve used the long form of gnuplot commands (linecolor instead of lc) to make it easy for you to research and discover the many ways to customize plots.

Not all points are created equal

Just as you’re leaning back in your chair, supremely satisfied with the results of this compelling plot, the boss walks by and says the charging portion of the plot is distracting; can you display just the discharging downslope, like this:

gnuplot’s stats command will process the data (using the columns we’ve described before) and provide information prefixed with the string “STATS”. (You specify a prefix so you can run statistics on several datasets and keep them seperate.

stats file using ($2/3600):1 prefix "STATS" nooutput

We set the width of the data to be plotted on the x axis to be between 0 (the start of all measurements) and STATS_pos_min_y (the time which corresponds to the minimum battery charge (the y axis)).

set xrange [0:STATS_pos_min_y]

Plot all the points which satisfy a test (or “conditional” in gnuplot-speak).

The conditional is of the form

( test ? success : failure )

Since we’re limiting points shown based upon time, our test will appear in the specification for the second column. It can be read as:

test: is the time of this point less than or equal (&lt;=) to that time when the battery was at its lowest charge (STATS_pos_min_y)”

This was written using gnuplot 5.0p6 on macOS High Sierra (10.13). Thanks to the Internet, especially stackoverflow.

Groundhog Day

The boss is so impressed by how you’ve made the test results so easy to digest that he discloses that there’s been tests run daily; can you plot them all together to expose trends and variances between the datasets?

Colophon

You may have noticed that I use the svg terminal type (because it generates much better output than the other types I’ve tried). The only downside to this is the resulting SVG files, which are not displayable by web browsers. To generate PNG files, which are displayable, I use imagemagick, which I install on macOS by: