如前所述,该模块不适用于 Python 3。
但在 Python 中使用 gnuplot 编写 自定义绘图函数 并不难。下面是我写的一个例子,用来制作碳纤维层压板与环氧树脂的灌注图。在输液过程中,将一桶树脂放在秤上,这样我可以每隔几分钟记下剩余的重量。
plot 函数的主要输入是一个numpy 数组,我在其中记录了树脂在桶中的时间和数量。这个数量会随着时间的推移而下降,所以我使用这些数据来计算每个点的注入树脂总量和树脂流动的速度。这就是numpy 派上用场的地方!
基本上,这个函数会创建一个包含 gnuplot 命令和内联数据的行列表,然后将其连接成一个字符串并作为subprocess 运行给gnuplot。
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'))
输出看起来像这样:
请注意,图表的样式由我的gnuplotrc 文件中的设置决定。