python-3.x 缓慢的matplotlib -将图保存为PNG

8hhllhi2  于 12个月前  发布在  Python
关注(0)|答案(4)|浏览(105)

快速汇总:matplotlib savefig对PNG来说太慢了。.寻找如何加速它的想法/想法,或者替代库(查科?开罗?)

更新:添加了一些(非常粗糙和准备)的代码,以说明在底部。
我使用matplotlib(python 3.x,四核macbook上最新的anaconda)通过imshow()创建一个1024 x1024 np数组(int 16的)的绘图,我的目标是在磁盘上生成一个注解的图像文件(不需要交互式显示)。
轴被设置为完全填充图形(因此没有样条线/tic等),dpi/大小组合被设置为匹配数组的大小-因此没有缩放/插值等。
在单轴的顶部,我显示3个文本区域和一些(~6)矩形补丁。
...所以没有什么花哨和几乎一样简单,你可以从一个阴谋的Angular 。

  • 然而,当我保存图(与savefig)到PNG它需要大约1.8秒(!).

我尝试将后端切换到Agg,但这将savefig()的时间增加到约2.1秒
我认为这太慢了,我错了吗?我更喜欢用PNG保存保存,而不是JPG -但我不明白为什么PNG比JPG慢得多。我的目标是在AWS上部署,所以关心这里的速度。
有没有更快的库?(我不想要交互式UI绘图,只是基本的保存到文件绘图)
下面是一些粗略的代码,大致说明了这一点。我的机器上的输出是:

current backend: MacOSX
default save: 0.4048
default save - float64: 0.3446
full size figure: 0.8105
full size figure - with text/rect: 0.9023
jpg: full size figure - with text/rect: 0.7468
current backend:  agg
AGG: full size figure - with text/rect: 1.3511
AGG: jpg: full size figure - with text/rect: 1.1689

字符串
我无法(即使在反复尝试之后)获得示例代码来重现我在应用程序中看到的~1.7秒(处理时间)savefig(),但我认为下面的代码仍然说明了a)jpg比png快(或者相反,png似乎慢)b)它仍然看起来慢(imo)
那么我不应该期待比这更快的速度吗?.这只是它的速度吗?有没有更快的后端可用?当我在AWS(Linux)上部署时,在那里使用的最好/最快的后端是什么?

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon, Rectangle
import time

def some_text(ax):
    pm = u'\u00b1'
    string = f'blah\nblah {pm}blah\nblah blah blah'
    ax.text(10, 10, string, color='red', ha='left')
    ax.text(990, 990, string, color='green', ha='right')
    ax.text(500, 500, string, color='green', ha='center')
    ax.text(500, 500, string, color='green', ha='center', va='top', fontsize=10)
    ax.text(800, 500, string, color='green', ha='center', multialignment='center', fontsize=16)

def some_rect(ax):
    rect = Rectangle((10,10),width=100, height=100, color='red', fill=False)
    ax.add_patch(rect)
    rect = Rectangle((300,10),width=100, height=100, color='yellow', fill=False)
    ax.add_patch(rect)
    rect = Rectangle((300,600),width=50, height=50, color='yellow', fill=False)
    ax.add_patch(rect)
    rect = Rectangle((800,600),width=50, height=50, color='yellow', fill=False)
    ax.add_patch(rect)

dim = 1024
test = np.arange(dim*dim).reshape((dim, dim))
dpi = 150
inches = test.shape[1]/dpi, test.shape[0]/dpi

print('current backend:', matplotlib.get_backend())

plt.imshow(test)
c0 = time.process_time()
plt.savefig('test.png')
print(f'default save: {(time.process_time()-c0):.4f}')
plt.close()

fig, ax = plt.subplots(figsize=inches, dpi=dpi)
fig.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)
ax.imshow(test)
c0 = time.process_time()
plt.savefig('test3.png')
print(f'full size figure: {(time.process_time()-c0):.4f}')

fig, ax = plt.subplots(figsize=inches, dpi=dpi)
fig.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)
ax.imshow(test)
some_text(ax)
some_rect(ax)
c0 = time.process_time()
plt.savefig('test4.png')
print(f'full size figure - with text/rect: {(time.process_time()-c0):.4f}')

fig, ax = plt.subplots(figsize=inches, dpi=dpi)
fig.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)
ax.imshow(test)
some_text(ax)
some_rect(ax)
c0 = time.process_time()
plt.savefig('test5.jpg')
print(f'jpg: full size figure - with text/rect: {(time.process_time()-c0):.4f}')

backend = 'agg'
matplotlib.use(backend, force=True)
import matplotlib.pyplot as plt
print('current backend: ', matplotlib.get_backend())

fig, ax = plt.subplots(figsize=inches, dpi=dpi)
fig.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)
ax.imshow(test)
some_text(ax)
some_rect(ax)
c0 = time.process_time()
plt.savefig('test6.png')
print(f'AGG: full size figure - with text/rect: {(time.process_time()-c0):.4f}')

fig, ax = plt.subplots(figsize=inches, dpi=dpi)
fig.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)
ax.imshow(test)
some_text(ax)
some_rect(ax)
c0 = time.process_time()
plt.savefig('test7.jpg')
print(f'AGG: jpg: full size figure - with text/rect: {(time.process_time()-c0):.4f}')

f5emj3cl

f5emj3cl1#

尝试创建一个PIL图像对象,对我来说,它比matplotlib快100倍以上:

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

data = np.random.random((100, 100))
cm = plt.get_cmap('viridis')
img = Image.fromarray((cm(data)[:, :, :3] * 255).astype(np.uint8))
img.save('image.png')

字符串
如果您只需要灰度,则可以跳过get_cmap业务-只需将阵列扩展到0到255的范围。
注解必须添加到PIL中。
与使用matplotlib的一个重要区别是它是逐像素的。因此,如果你想应用一些缩放,你必须首先插值。你可以使用scipy.ndimage.zoom

y4ekin9u

y4ekin9u2#

尝试使用

plt.imsave(img, name)

字符串
而不是

plt.imshow(img)
plt.savefig(name)


在我的情况下,它几乎快10倍

sdnqo3pr

sdnqo3pr3#

pip install cv-python Something.
在这种情况下,cv2.imwrite比两者都快。

kzmpq1sx

kzmpq1sx4#

在每次保存无花果后尝试以下操作:

plt.close()

字符串

相关问题