【问题标题】:matplotlib very slow. Is it normal?matplotlib 很慢。正常吗?
【发布时间】:2012-10-14 07:27:36
【问题描述】:

我正在使用由 400 个子图组成的 matplotlib 创建几个 pdf 图。每个只有 5 个数据点。在一台好电脑上保存 5 张 pdf 图片需要 420 秒。有什么办法可以优化代码还是matplotlib正常?

绘图部分代码:

plot_cnt = 1
for k in np.arange(K_min, K_max + 1):
    for l in np.arange(L_min, L_max + 1):
        ax = plt.subplot(grid[0], grid[1], plot_cnt)
        plot_cnt += 1
        plt.setp(ax, 'frame_on', False)
        ax.set_ylim([-0.1, 1.1])
        ax.set_xlabel('K={},L={}'.format(k, l), size=3)
        ax.set_xlim([-0.1, 4.1])
        ax.set_xticks([])
        ax.set_yticks([])
        ax.grid('off')
        ax.plot(np.arange(5), (data['S1']['Azimuth'][:, k - 1, l + offset_l] + \
                data['S1']['Delta Speed'][:, k - 1, l + offset_l] + \
                data['S1']['Speed'][:, k - 1, l + offset_l]) / 3,
                'r-o', ms=1, mew=0, mfc='r')
        ax.plot(np.arange(5), data['S2'][case][:, k - 1, l + offset_l],
                'b-o', ms=1, mew=0, mfc='b')
plt.savefig(os.path.join(os.getcwd(), 'plot-average.pdf'))
plt.clf()
print 'Final plot created.'

最终图片:

【问题讨论】:

  • 400 个子图对我来说似乎很多。即使你没有很多数据,matplotlib 也可能不会被优化来显示这种网格。
  • @Simon,是否可以使用单个大子图进行绘图?然后每五个应该连接。有什么想法吗?
  • 我没有合适的环境来运行测试,但是您可以做一些事情。第一步是在您的代码上运行分析器(有关更多信息,请参阅here)。有了这个,你可以找到时间花在哪里。您可以尝试的两件事是在每个步骤中找到一些要释放的资源,或者使用multiprocessing 在多个进程中创建图。如果我有时间我会试试这个,但现阶段我不能保证任何事情
  • @rowman 我实现了你的想法,即使用一个大的axes

标签: python performance matplotlib


【解决方案1】:

根据@rowman 所说,您可以在一个轴上完成所有操作(当您关闭所有刻度等时)。比如:

K_max = 20
K_min = 0
L_max = 20
L_min = 0
ax = plt.subplot(111)
x_offset = 7 # tune these
y_offset = 7 # tune these
plt.setp(ax, 'frame_on', False)
ax.set_ylim([0, (K_max-K_min +1)*y_offset ])
ax.set_xlim([0, (L_max - L_min+1)*x_offset])
ax.set_xticks([])
ax.set_yticks([])
ax.grid('off')



for k in np.arange(K_min, K_max + 1):
    for l in np.arange(L_min, L_max + 1):
        ax.plot(np.arange(5) + l*x_offset, 5+rand(5) + k*y_offset,
                'r-o', ms=1, mew=0, mfc='r')
        ax.plot(np.arange(5) + l*x_offset, 3+rand(5) + k*y_offset,
                'b-o', ms=1, mew=0, mfc='b')
        ax.annotate('K={},L={}'.format(k, l), (2.5+ (k)*x_offset,l*y_offset), size=3,ha='center')
plt.savefig(os.path.join(os.getcwd(), 'plot-average.pdf'))

print 'Final plot created.'

运行大约一两秒。我认为所有时间都花在设置内部相当复杂的axes 对象上。

【讨论】:

  • 非常好。只是出于好奇,可以使用here 提到的技术吗?只需使用线路的set_ydata。不过应该找到一种方法来复制 ax 对象。
  • @rowman 您能否更具体地了解该链接中的哪种方法?如果您想制作 400 个单独的数字,set_ydata 会很有用,但我不认为它在这种情况下会有用。
  • 对于 GUI 应用程序,我只需创建一条线并更新 Y 以加快速度,而不是每次都重新绘制整个图形。在这种情况下,我只是想而不是创建 400 个图形,复制一个对象 400 次,更新 Y 和图形轴的位置。不过可能需要同样的时间。
  • @rowman 见docs.python.org/library/copy.html。我对速度没有猜测。但是您仍然需要手动设置网格,因为 axesfigure 中的位置是轴的属性。
猜你喜欢
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
  • 2019-02-13
  • 2012-11-29
  • 2012-02-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多