Matplotlib imshow中的内存使用过多 [英] Excessive memory usage in Matplotlib imshow

查看:55
本文介绍了Matplotlib imshow中的内存使用过多的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 PyQT4 应用程序,可以在 Matplotlib 图形中显示中等大小的图像.我要显示的测试图像约为5Mb(2809 x 1241像素).顺便说一下,我使用GDAL读取了数据.图像被读入一个数组,其中的 nodata 值被屏蔽.然后用归一化值和指定的颜色图显示

I've got a PyQT4 application that displays medium size images in a Matplotlib figure. The test image that I'm displaying is about 5Mb (2809 x 1241 pixels). I read in the data using GDAL by the way. The image is read into an array with nodata values masked out. This is then displayed with normalized values and a specified colormap

它似乎使用了过多的内存来显示 5mb 的文件.我看到的是,以全分辨率显示读取的图像需要 140mb 的内存.(带有 imshow 的应用程序注释掉了使用的 60mb 内存,而使用它的内存为 206)随着图像显示在多个图中,因为每个图形都使用额外的 200m 内存,因此问题变得更糟.随着内存使用量进入700-900 mb范围,显示的大约3或4位数字显示应用程序开始陷入困境.

It seems to use an inordinate amount of memory to display a 5mb file. What I'm seeing is that it takes a 140mb of memory to display this image read in at full resolution. (application with imshow commented out used 60mb of memory, vs 206 with it) The problem gets worse as images are displayed in multiple figures as each one uses an additional 200m of memory. At about 3 or 4 figures displayed the applications starts bogging down as the memory usage gets into the 700-900 mb range.

我了解 matplotlib 必须存储所有像素,即使它只显示一个下采样的子集以匹配屏幕分辨率.我可能最终将编写例程以仅读取一定数量的像素以匹配图形尺寸.但是由于这个应用程序将在 8 个单独的屏幕上显示多达 8 个地图,我担心它仍然使用过多的内存.

I understand about matplotlib having to store all the pixels even though it's displaying only a downsampled subset to match the screen resolution. I'll probably end up writing routines to only read in an amount of pixels to match the figure size. But since this application will be displaying up to 8 maps on 8 separate screens I'm concerned about it still using excessive memory.

所以我的问题是:
1) 用于显示简单颜色映射图像的内存量是否过多?对我来说确实如此.

So my questions are:
1) Does this seem like an inordinate amount of memory to be using for displaying a simple colormapped image? It does to me.

2)我可以做些什么来减少这种内存使用?例如使用整数数据类型,释放内存等.

2) Is there something I could be doing to decrease this memory usage? For example using integer datatypes, releasing memory, etc.

3)我还应该使用其他什么策略来处理这种内存使用情况?例如下采样(在全屏分辨率1900x1200下可能效果不佳),切换到64位体系结构等

3) What other strategies should I be using to deal with this memory usage? For example downsampling (might not be very effective at full screen resolution 1900x1200), switching to 64bit architecture, etc

谢谢,下面的代码

import sys, os, random
from PyQt4.QtCore import *
from PyQt4.QtGui import *

import matplotlib
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
from matplotlib.figure import Figure
import matplotlib.colors as colors


import numpy as np
from osgeo import gdal, gdalconst



gridfile = r"i:\vistrails\workingfiles\secondseason\secondseason_workfile_2012_02_28b\brt_1\brt_prob_map.tif"




class AppForm(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)

        self.create_main_frame()

        ds = gdal.Open(gridfile, gdal.GA_ReadOnly)
        ary = ds.GetRasterBand(1).ReadAsArray(buf_ysize=500, buf_xsize=300)
        ndval = ds.GetRasterBand(1).GetNoDataValue()

        rasterdata = np.ma.masked_array(ary, mask=(ary==ndval))
        del ary

        self.axes.imshow(rasterdataint, cmap=matplotlib.cm.jet)

        del rasterdata

    def create_main_frame(self):
        self.main_frame = QWidget()

        # Create the mpl Figure and FigCanvas objects. 
        # 5x4 inches, 100 dots-per-inch
        #
        self.dpi = 100
        self.fig = Figure((5.0, 4.0), dpi=self.dpi)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self.main_frame)

        self.axes = self.fig.add_subplot(111)

        self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame)

        vbox = QVBoxLayout()
        vbox.addWidget(self.canvas)
        vbox.addWidget(self.mpl_toolbar)

        self.main_frame.setLayout(vbox)
        self.setCentralWidget(self.main_frame)



def main():
    app = QApplication(sys.argv)
    form = AppForm()
    form.show()
    app.exec_()


if __name__ == "__main__":
    main()

推荐答案

已注意到使用 imshow() 的内存问题,如 这里.

Memory issue with use of imshow() have been noticed, as here.

1/升级

正如这里提到的,升级到最新mpl的版本可能会解决这个问题.

2/PIL

作为替代方案,您可以使用 PIL 库.

As an alternative, you may make you of the PIL library.

当转到jpg文件时, imshow()使用的是PIL(如果已安装).您可以直接使用PIL模块,如此处所述.

When it goes to jpg files, imshow() is using PIL if installed. You can use PIL module directly, as documented here.

这篇关于Matplotlib imshow中的内存使用过多的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆