gnuplot 与 Matplotlib
我开始了一个项目,目的是用Tomcat的日志来绘图,使用的是gnuplot-py,特别是想把特定的请求和内存分配、垃圾回收联系起来。大家对gnuplot-py和Matplotlib在Python绘图方面有什么看法?有没有更好的绘图库是我没听说过的?
我考虑的主要问题有:
- 虽然gnuplot有很多文档,但gnuplot-py的文档就少得多。Matplotlib的社区文档怎么样?
- 有没有gnuplot能做但gnuplot-py做不了的事情?
- Matplotlib对Python的支持更好吗?
- 这两个库有没有严重的bug或者让人烦恼的问题?
- 现在gnuplot能处理十万的数据点,我打算把这个规模扩大到几百万。这样会有问题吗?Matplotlib处理这个的能力怎么样?
- 使用的方便程度,gnuplot和Matplotlib的响应时间如何?
- 把现有的gnuplot-py代码移植到Matplotlib上会有多难?
你会怎么处理这个任务呢?
8 个回答
50
Matplotlib = 使用简单,Gnuplot = (稍微更好一点的)性能
我知道这篇文章已经很旧了,也有人回答过,但我路过的时候想说说我的看法。我的结论是:如果你的数据集不大,建议使用Matplotlib。它更简单,效果也更好。不过,如果你真的需要更好的性能,可以试试Gnuplot。我还加了一些代码,供你在自己电脑上测试,看看是否真的有区别(这不是一个真正的性能测试,但可以给你一个初步的印象)。
下面的图表显示了绘制一个随机散点图所需的时间(以秒为单位):
- 绘制随机散点图
- 将图表保存为png文件
配置:
- gnuplot: 5.2.2
- gnuplot-py: 1.8
- matplotlib: 2.1.2
我记得在旧电脑上运行旧版本的库时,性能差距更大(对于一个大散点图,差不多有30秒的差距)。
而且,正如评论中提到的,你可以用Gnuplot得到相同质量的图表。但你需要花更多的时间和精力去实现这一点。
# -*- coding: utf-8 -*-
from timeit import default_timer as timer
import matplotlib.pyplot as plt
import Gnuplot, Gnuplot.funcutils
import numpy as np
import sys
import os
def mPlotAndSave(x, y):
plt.scatter(x, y)
plt.savefig('mtmp.png')
plt.clf()
def gPlotAndSave(data, g):
g("set output 'gtmp.png'")
g.plot(data)
g("clear")
def cleanup():
try:
os.remove('gtmp.png')
except OSError:
pass
try:
os.remove('mtmp.png')
except OSError:
pass
begin = 2
end = 500000
step = 10000
numberOfPoints = range(begin, end, step)
n = len(numberOfPoints)
gnuplotTime = []
matplotlibTime = []
progressBarWidth = 30
# Init Gnuplot
g = Gnuplot.Gnuplot()
g("set terminal png size 640,480")
# Init matplotlib to avoid a peak in the beginning
plt.clf()
for idx, val in enumerate(numberOfPoints):
# Print a nice progress bar (crucial)
sys.stdout.write('\r')
progress = (idx+1)*progressBarWidth/n
bar = "▕" + "▇"*progress + "▁"*(progressBarWidth-progress) + "▏" + str(idx) + "/" + str(n-1)
sys.stdout.write(bar)
sys.stdout.flush()
# Generate random data
x = np.random.randint(sys.maxint, size=val)
y = np.random.randint(sys.maxint, size=val)
gdata = zip(x,y)
# Generate string call to a matplotlib plot and save, call it and save execution time
start = timer()
mPlotAndSave(x, y)
end = timer()
matplotlibTime.append(end - start)
# Generate string call to a gnuplot plot and save, call it and save execution time
start = timer()
gPlotAndSave(gdata, g)
end = timer()
gnuplotTime.append(end - start)
# Clean up the files
cleanup()
del g
sys.stdout.write('\n')
plt.plot(numberOfPoints, gnuplotTime, label="gnuplot")
plt.plot(numberOfPoints, matplotlibTime, label="matplotlib")
plt.legend(loc='upper right')
plt.xlabel('Number of points in the scatter graph')
plt.ylabel('Execution time (s)')
plt.savefig('execution.png')
plt.show()
54
- 你可以自己查看 matplotlib的文档,我觉得内容非常全面。
- 我对gnuplot-py的了解很少,所以不能确定它是否能做所有gnuplot能做的事情。
- Matplotlib是专门为Python编写和设计的,所以它和Python的用法非常契合。
- Matplotlib是一个成熟的项目,甚至NASA也在用它做一些事情。
- 我在Matplotlib中绘制了数千万个点,效果依然很美观,响应也很快。
- 除了面向对象的使用方式,Matplotlib还有一个叫pylab的接口,让绘图变得像在MATLAB中一样简单——也就是说,非常简单。
- 至于从gnuplot-py迁移到matplotlib,我就不太清楚了。