Subscribe:

# Making Mirror Plots with Gnuplot

Lee Phillips
August 13th, 2021

The usual way to represent two data series on one plot is to plot two curves on one set of axes. You can use different scales for the dependent variables, and even two different independent variable axes, if required. Here is a graph of two curves that use different dependent axis scales but share the independent axis scale. This type of plot is standard gnuplot bread and butter. Below is an example:

One sometimes sees another type of plot of two (usually) timeseries. This style is usually used for some kind of demographic or “statistical” data; it is not typically used in science. The data is non-negative in the examples I’ve seen, and my script here will only work properly for this kind of data.

I’ll call this a “mirror plot,” as I don’t know if there is a commonly accepted name for it. You can see an example below:

This is a plot of the same data as in the first plot. Some people find this a good way two compare two sets of data. However, this plot style is not built in to gnuplot.

The only tricky thing there is the axis ticks and tick labels. If we didn’t need any ticks on the vertical axes, it would be trivial to create this plot with gnuplot. The filled-curve style is built in, and we could plot the reflection of one of the curves simply by plotting its negative.

If, however, we want numbers and tics on the vertical axes, we have to do something else. That’s because, although you can format tick labels, there is no way to remove the negative sign from negative numbers (that I know of). So we have to plot the reflection while keeping the data positive.

Reflecting a curve is easy: we just need to reverse the yrange on the axis its plotted against. Then we need to push the reflected curve down below the right-side-up curve, which we can do by recording its maximum, then shifting it down by that amount in the plot command. Except that we need to shift it up, by that amount, because we flipped it.

Of course, when we do that, we’ll be pushing the reflected curve outside of the plotting box unless we first set the yrange to be large enough to hold both curves. Then we also need to shift the unreflected curve up, so it sits in the top part of the box.

Next we need to shift the tick labels identically to the data, so they remain correct. Our final trick is to eliminate the tick marks themselves, and replace them with “typographic” tic marks that are part of the tick labels. This makes everything line up perfectly.

Just looking at the script may be less confusing than my attempt to explain it. Here is the gnuplot script that makes the mirror plot above:

set term svg
set out "mirror.svg"
unset key
set tics front
set ylab "Some data" offset 5, graph 0.25 font ",18"
set y2lab "Some more data" offset -7, graph -0.25 font ",18"
# Plot just to get data maximums
plot "mirror.dat" u 1:2, "" u 1:3 axes x1y2
y1max = GPVAL_DATA_Y_MAX
y2max = GPVAL_DATA_Y2_MAX
set ytics format "%0.2g  –" scale 0
set y2tics format "–  %0.2g" scale 0

set out "mirror.svg"
set xr [GPVAL_DATA_X_MIN : GPVAL_DATA_X_MAX]
set yr [0 : 2*y1max]
set y2r [2*y2max : 0]
set ytics nomirror
set ytics offset 1.8, first y1max
set y2tics offset -1.8, second y2max
plot "mirror.dat" u 1:(\$2+y1max) w filledcurve y=y1max axes x1y1,\
"" u 1:(\$3+y2max) w filledcurve y2=y2max axes x1y2

If you want to use the data file that I used to make these plots, here it is.

For more fun with gnuplot, have a look at my book.

lee-phillips.org is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to amazon.com.