Python matplotlib imshow 速度慢

6 投票
3 回答
18999 浏览
提问于 2025-04-16 12:10

我想用imshow来显示一张图片。这是一张1600x1200的灰度图像,我发现matplotlib使用float32来解码这些值。加载这张图片大约需要2秒钟,我想知道有没有办法让这个过程更快。其实,我并不需要高分辨率的图像,我只是想标记一些点,并把这张图作为背景。

  • 第一个问题:2秒钟的加载时间算不算快?我能不能让它更快?
  • 第二个问题:如果这个速度算快,我该如何通过降低分辨率来加快这个过程?重要的是:我还是希望最后这张图能保持在1600x1200像素的大小。

我的代码:

import matplotlib
import numpy

plotfig     = matplotlib.pyplot.figure()
plotwindow  = plotfig.add_subplot(111)
plotwindow.axis([0,1600,0,1200])
plotwindow.invert_yaxis() 
img = matplotlib.pyplot.imread("lowres.png")
im  = matplotlib.pyplot.imshow(img,cmap=matplotlib.cm.gray,origin='centre')
plotfig.set_figwidth(200.0)
plotfig.canvas.draw()
matplotlib.pyplot.show()

这是我想做的。如果保存在lowres.png中的图片分辨率低于1600x1200(比如说400x300),它会显示在左上角,正如我所希望的那样。我该如何把它放大到整个1600x1200像素的区域呢?

当我运行这个程序时,慢的部分来自下面的canvas.draw()命令。有没有办法加快这个命令的执行速度呢?

谢谢你的帮助!

根据你的建议,我已经更新到了最新版本的matplotlib。

版本 1.1.0svn,检查号8988

我还使用了以下代码:

img = matplotlib.pyplot.imread(pngfile)
img *= 255
img2 = img.astype(numpy.uint8)
im  = self.plotwindow.imshow(img2,cmap=matplotlib.cm.gray, origin='centre')

但显示这张图片仍然需要大约2秒钟……还有其他的建议吗?

补充一下:我发现了以下功能:

zoomed_inset_axes

所以原则上matplotlib应该能完成这个任务。那里也可以以“放大”的方式绘制一张图片……

3 个回答

1

我找到了一种解决办法,只要你需要显示低分辨率的图片就可以。你可以使用这一行代码:

im  = matplotlib.pyplot.imshow(img,cmap=matplotlib.cm.gray, origin='centre',extent=(0,1600,0,1200))

这里的extent参数告诉matplotlib在这个范围内绘制图形。如果使用分辨率较低的图片,这样可以大大加快处理速度。不过,如果有人知道其他技巧,可以让处理速度更快,同时使用更高分辨率的图片,那就太好了。

感谢所有考虑我问题的人,欢迎进一步的建议!!!

2

你可以通过在你的 matplotlibrc 文件中添加以下内容来关闭 imshow 的默认插值功能(这个文件通常在 ~/.matplotlib/matplotlibrc 这个路径下):

image.interpolation : none

这样做的结果是图像渲染速度会更快,图像也会更清晰。

5

数据的大小和最终图像的像素尺寸是没有直接关系的。

既然你说不需要高分辨率的图像,那你可以通过降低数据的分辨率来更快地生成图像。如果你的数据是以numpy数组的形式存在,可以用一种简单粗暴的方法来处理,就是每隔 n 行和 n 列取一个数据,使用 data[::n,::n] 这个方式。

你可以通过 fig.set_size_inchesplt.savefigdpi 参数来控制输出图像的像素尺寸:

import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np

data=np.arange(300).reshape((10,30))
plt.imshow(data[::2,::2],cmap=cm.Greys)

fig=plt.gcf()
# Unfortunately, had to find these numbers through trial and error
fig.set_size_inches(5.163,3.75)  
ax=plt.gca()
extent=ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())

plt.savefig('/tmp/test.png', dpi=400,
            bbox_inches=extent)

在这里输入图片描述

撰写回答