Ric*_*ard 7 matplotlib python-3.x
快速总结:matplotlib savefig 对于 PNG 来说太慢了。...寻找关于如何加快速度的想法/想法,或替代库(chaco?开罗?)
更新:添加了一些(非常粗略且准备好的)代码以在底部进行说明。
我正在使用 matplotlib (python 3.x,四核 macbook 上最新的 anaconda)通过imshow()
. 我的目标是简单地在磁盘上生成带注释的图像文件(不需要交互式显示)。
轴设置为完全填充图形(因此没有样条线/控制等),并且 dpi/尺寸组合设置为匹配数组的大小 - 因此没有缩放/插值等。
在该单轴之上,我显示 3 个文本区域和一些(~6)矩形块。
...所以没有什么花哨的东西,而且从绘图的角度来看非常简单。
然而,当我将图形(带有savefig
)保存为 PNG 时,大约需要 1.8 秒(!!!)。...保存为 raw 或 jpg 都需要约 0.7 秒。
我尝试将后端切换到 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
Run Code Online (Sandbox Code Playgroud)
我无法(即使经过反复尝试)获得示例代码来重现我在应用程序中看到的 ~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}')
Run Code Online (Sandbox Code Playgroud)
尝试制作一个PIL
图像对象,对我来说它比以下方法快 100 倍以上matplotlib
:
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')
Run Code Online (Sandbox Code Playgroud)
如果您只想要灰度,则可以跳过这get_cmap
一步——只需将数组缩放到 0 到 255 的范围即可。
注释必须添加到PIL
.
与使用的一个重要区别matplotlib
是它是逐像素的。因此,如果您想应用一些缩放,则必须先进行插值。你可以用scipy.ndimage.zoom
它。
归档时间: |
|
查看次数: |
10595 次 |
最近记录: |