As mentioned, the module doesn't work with Python 3.
But it isn't all that hard to write a custom plot function using gnuplot
in Python. Below is an example that I wrote to make a graph of the infusion of carbon fiber laminates with epoxy resin. During the infusion, the pail of resin is placed on a scale, so I can write down the remaining weight every couple of minutes.
The main input for the plot
function is a numpy
array where I have recorded the time and amount of resin still in the bucket. This amount goes down over time, so I use this data to calculate the total amount of injected resin at every point and the speed with which the resin flows. That's where numpy
comes in handy!
Basically this function creates a list of lines containing gnuplot commands and inline data, which is then joined into a single string and fed to gnuplot
running as a subprocess
.
import subprocess
import numpy as np
def plot(rawdata, filename, maxy=None, labels=False, n=2):
"""Plot injection data with gnuplot.
Arguments:
data: numpy array of shape (N,2)
(Time, weight) pairs as written down during the injection. The time
in minutes increases and the weight in grams decreases.
filename: string
Name to write the output figure to.
maxy: Maximum y coordinate for the left axis (injected weight).
The right axis (injection speed) is 1/10th of the left axis.
When set to None, automatic scaling is used.
labels: Label every n-th data point when true.
n: Print every n-th value as a label.
"""
gtype = 'lines'
if labels:
gtype = 'linespoints'
delta = rawdata[1:] - rawdata[:-1]
totals = np.array([[0, 0]] + [[dt, -dm] for dt, dm in delta])
som = np.cumsum(totals, axis=0)
print('harshoeveelheid "{}": {} g'.format(filename, som[-1, 1]))
if maxy is None:
maxy = round(som[-1, 1], -2)
dm = np.array([[0]] + [[-dm/dt] for dt, dm in delta])
newdata = np.hstack((som, dm))
newdata[0, 2] = newdata[1, 2]
l1 = 'set label "{:.0f} g" at {},{} center offset 0,0.5'
l2 = 'set label "{:.0f} g/min" at {},second {} center offset 0,0.5'
p1 = 'plot "-" with {gt} ls 1 title "harshoeveelheid", ' \
'"-" with {gt} axes x1y2 ls 2 title "injectiesnelheid"'
lp1 = ', "-" using 1:2:2 with labels right offset character 0.4,0.7' \
'font "Alegreya, 8" tc ls 1 notitle'
lp2 = ', "-" using 1:2:2 axis x1y2 with labels left offset character ' \
'0.5,0.7 font "Alegreya, 8" tc ls 2 notitle'
text = ['set terminal pdfcairo enhanced color dashed font "Alegreya, 11" '
'rounded size 12.8 cm, 7.0 cm',
'set xlabel "tijd [min]"',
'set ylabel "harshoeveelheid [g]"',
'set y2label "injectiesnelheid [g/min]"',
'set y2tics',
'set yrange [0:{:.0f}]'.format(maxy),
'set y2range [0:{:.0f}]'.format(maxy/10),
'set key left bottom',
'set grid']
if not labels:
text.append(l1.format(newdata[-1, 1], newdata[-1, 0], newdata[-1, 1]))
text.append(l2.format(newdata[-1, 2], newdata[-1, 0], newdata[-1, 2]))
text.append('set output "{}"'.format(filename + '.pdf'))
text.append(p1.format(gt=gtype))
if labels:
text[-1] += lp1 + lp2
data1 = ['{:2.0f} {:4.0f}'.format(a, b) for a, b, _ in newdata]
data2 = ['{:2.0f} {:4.0f}'.format(a, b) for a, _, b in newdata]
text += data1
text.append('e')
text += data2
text.append('e')
if labels:
data1 = ['{:2.0f} {:4.0f}'.format(a, b) for a, b, _ in newdata[n-1::n]]
data2 = ['{:2.0f} {:4.0f}'.format(a, b) for a, _, b in newdata[n-1::n]]
text += data1
text.append('e')
text += data2
text.append('e')
p = subprocess.Popen(['gnuplot'], stdin=subprocess.PIPE)
_, _ = p.communicate(input='\n'.join(text).encode('utf-8'))
The output looks something like this:

Note that the style of the graph is determined by the settings in my gnuplotrc
file.