As a workaround you could do your own normalization and color mapping
and pass a uint8 RGB image to imshow. That avoids matplotlib's norm
function. The following example saves almost 500 MB for plotting a 16 MB
uint8 greyscale image, as compared to passing img directly to imshow:
import numpy
from matplotlib import pyplot
img = numpy.random.randint(0, 255, (4096, 4096)).astype('uint8')
lut = pyplot.cm.gray(numpy.arange(255), bytes=True)
rgb = lut.take(img, axis=0)
del img
pyplot.imshow(rgb)
pyplot.show()
Christoph
On 2/2/2011 11:00 PM, gary ruben wrote:
> Christoph, if you're looking at special casing uint8's, you might want
> to keep in mind that uint16 greyscale images are also quite common as
> camera outputs in experimental setups. I think that the solution to
> this should ideally minimise memory usage for any greyscale image, be
> it uint8, uint16, float32 or float64. i.e. avoiding conversion to RGBA
> for any single-plane 2D array type would be best IMHO,
>
> Gary R.
>
> On Thu, Feb 3, 2011 at 5:38 PM, Robert Abiad<[email protected]> wrote:
>>
>>
>> On 2/2/2011 6:06 PM, Eric Firing wrote:
>>> On 02/02/2011 03:08 PM, Robert Abiad wrote:
>>>> On 2/2/2011 3:59 PM, Christoph Gohlke wrote:
>>>>> On 2/2/2011 3:33 PM, Robert Abiad wrote:
>>>>>> Hello All,
>>>>>>
>>>>>> I'm very new to python, so bear with me.
>>>>>>
>>>>>> I'd like to use python to do my image processing, but I'm running into
>>>>>> behavior that doesn't make
>>>>>> sense to me. I'm using Windows 7 Pro (64-bit) with 4 gigs of memory,
>>>>>> python 2.6.6, and the newest
>>>>>> versions of ipython, pyfits, matplotlib (1.0.1), numpy (1.5.1), scipy.
>>>>>> I'm loading in a fits file
>>>>>> that's 26 MB (~16 Mpixels). When I load my image in ImageJ, I can see
>>>>>> memory usage go up by 50MB,
>>>>>> but when I try displaying the image using imshow(), my memory usage goes
>>>>>> up by around 500MB, each
>>>>>> time. If I close the figure and replot it, imshow() crashes. I don't
>>>>>> know if I'm doing something
>>>>>> wrong, or if it's a new or known bug. I tried the same thing on Linux
>>>>>> and got the same result.
>>>>>> Here's a transcript.
>>>>>>
>>>>>> Welcome to pylab, a matplotlib-based Python environment.
>>>>>> For more information, type 'help(pylab)'.
>>>>>>
>>>>>> In [1]: import pyfits
>>>>>>
>>>>>> In [2]: from Tkinter import *
>>>>>>
>>>>>> In [3]: import tkFileDialog
>>>>>>
>>>>>> In [4]: image=pyfits.getdata(tkFileDialog.askopenfilename())
>>>>>>
>>>>>> In [5]: imshow(image)
>>>>>> Out[5]:<matplotlib.image.AxesImage object at 0x03BCA170>
>>>>>>
>>>>>> In [6]: close()
>>>>>>
>>>>>> In [7]: imshow(image,origin='lower')
>>>>>> Out[7]:<matplotlib.image.AxesImage object at 0x0440E170>
>>>>>>
>>>>>> In [8]: close()
>>>>>>
>>>>>> In [9]: imshow(image[100:3600,100:3600],origin='lower')
>>>>>> Out[9]:<matplotlib.image.AxesImage object at 0x045D9FB0>
>>>>>>
>>>>>> In [10]: Exception in Tkinter callback
>>>>>> Traceback (most recent call last):
>>>>>> File "C:\app\Python2.6\lib\lib-tk\Tkinter.py", line 1410, in
>>>>>> __call__
>>>>>> return self.func(*args)
>>>>>> File "C:\app\Python2.6\lib\lib-tk\Tkinter.py", line 495, in
>>>>>> callit
>>>>>> func(*args)
>>>>>> File
>>>>>> "C:\app\Python2.6\lib\site-packages\matplotlib\backends\backend_tkagg.py",
>>>>>> line 263, in
>>>>>> idle_draw
>>>>>> self.draw()
>>>>>> File
>>>>>> "C:\app\Python2.6\lib\site-packages\matplotlib\backends\backend_tkagg.py",
>>>>>> line 248, in draw
>>>>>> FigureCanvasAgg.draw(self)
>>>>>> File
>>>>>> "C:\app\Python2.6\lib\site-packages\matplotlib\backends\backend_agg.py",
>>>>>> line 394, in draw
>>>>>> self.figure.draw(self.renderer)
>>>>>> File "C:\app\Python2.6\lib\site-packages\matplotlib\artist.py",
>>>>>> line 55, in draw_wrapper
>>>>>> draw(artist, renderer, *args, **kwargs)
>>>>>> File "C:\app\Python2.6\lib\site-packages\matplotlib\figure.py",
>>>>>> line 798, in draw
>>>>>> func(*args)
>>>>>> File "C:\app\Python2.6\lib\site-packages\matplotlib\artist.py",
>>>>>> line 55, in draw_wrapper
>>>>>> draw(artist, renderer, *args, **kwargs)
>>>>>> File "C:\app\Python2.6\lib\site-packages\matplotlib\axes.py",
>>>>>> line 1946, in draw
>>>>>> a.draw(renderer)
>>>>>> File "C:\app\Python2.6\lib\site-packages\matplotlib\artist.py",
>>>>>> line 55, in draw_wrapper
>>>>>> draw(artist, renderer, *args, **kwargs)
>>>>>> File "C:\app\Python2.6\lib\site-packages\matplotlib\image.py",
>>>>>> line 354, in draw
>>>>>> im = self.make_image(renderer.get_image_magnification())
>>>>>> File "C:\app\Python2.6\lib\site-packages\matplotlib\image.py",
>>>>>> line 569, in make_image
>>>>>> transformed_viewLim)
>>>>>> File "C:\app\Python2.6\lib\site-packages\matplotlib\image.py",
>>>>>> line 201, in _get_unsampled_image
>>>>>> x = self.to_rgba(self._A, self._alpha)
>>>>>> File "C:\app\Python2.6\lib\site-packages\matplotlib\cm.py", line
>>>>>> 193, in to_rgba
>>>>>> x = self.norm(x)
>>>>>> File "C:\app\Python2.6\lib\site-packages\matplotlib\colors.py",
>>>>>> line 820, in __call__
>>>>>> result = (val-vmin) / (vmax-vmin)
>>>>>> File "C:\app\Python2.6\lib\site-packages\numpy\ma\core.py", line
>>>>>> 3673, in __div__
>>>>>> return divide(self, other)
>>>>>> File "C:\app\Python2.6\lib\site-packages\numpy\ma\core.py", line
>>>>>> 1077, in __call__
>>>>>> m |= filled(domain(da, db), True)
>>>>>> File "C:\app\Python2.6\lib\site-packages\numpy\ma\core.py", line
>>>>>> 772, in __call__
>>>>>> return umath.absolute(a) * self.tolerance>= umath.absolute(b)
>>>>>> MemoryError
>>>>>>
>>>>>>
>>>>>> Thanks for any help,
>>>>>> -robert
>>>>>>
>>>>>
>>>>> These are previous discussions on the issue:
>>>>>
>>>>> <http://www.mail-archive.com/[email protected]/msg14727.html>
>>>>> <http://www.mail-archive.com/[email protected]/msg19815.html>
>>>>> <http://www.mail-archive.com/[email protected]/msg19614.html>
>>>>>
>>>>> Christoph
>>>>>
>>>> The first 2 discussions lead to suggestions of more memory on a 64-bit
>>>> installation, but that
>>>> doesn't seem like a great solution. I use other image processing software
>>>> (ImageJ and IDL) and
>>>> neither has any trouble with my images. As I mentioned ImageJ uses 1/10th
>>>> the memory for the same
>>>> display, or about 1 byte of memory for 1 byte of image. I think
>>>> matplotlib should aim for the same.
>>>> I also think it should free up memory when the image is closed, but
>>>> maybe I'm not doing the right
>>>> thing. Is there something else I should be doing to free up memory?
>>>>
>>>> Things are even worse with plot.
>>>>
>>>> I'll file a bug report as Benjamin suggests.
>>> Please file it in the "enhancement" category, not as a "bug". The
>>> difficulty that mpl has with images is the result of a design decision
>>> long ago; as Christoph notes, mpl works primarily with float64 rgba,
>>> which is horribly memory inefficient, but is very general and works fine
>>> so long as the image is not too large. uint8 is already used in some
>>> circumstances. I don't know how hard it would be to simply switch to
>>> uint8 for images, or to make that an option, perhaps for all color
>>> specification. It may involve getting into arcana of the extension code
>>> and the agg library, which is a daunting prospect for most of us,
>>> certainly for me. I agree entirely that a major reduction in memory
>>> usage would be good; patches, or a mpl branch to achieve that, are welcome.
>>>
>>> Eric
>> I'll put it in as an enhancement, but I'm still unsure if there is a bug in
>> there as well. Is there something I should be doing to clear memory after
>> the
>> first figure is closed other than close()? I don't understand why memory
>> usage
>> grows each time I replot, but I'm pretty sure it isn't desireable behavior.
>> As
>> I mentioned, this effect is worse with plot.
>>
>> So is this a bug or improper usage?
>>
>> As for how to implement a fix for memory usage, I'll let you folks figure
>> that
>> out. But it seems that if I want a grayscale image, I could reduce memory
>> usage
>> by 4 if matplotlib could turn rgba into intensity.
>>
>> -robert
>>
>> ------------------------------------------------------------------------------
>> Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
>> Finally, a world-class log management solution at an even better price-free!
>> Download using promo code Free_Logger_4_Dev2Dev. Offer expires
>> February 28th, so secure your free ArcSight Logger TODAY!
>> http://p.sf.net/sfu/arcsight-sfd2d
>> _______________________________________________
>> Matplotlib-users mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>>
>
> ------------------------------------------------------------------------------
> Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
> Finally, a world-class log management solution at an even better price-free!
> Download using promo code Free_Logger_4_Dev2Dev. Offer expires
> February 28th, so secure your free ArcSight Logger TODAY!
> http://p.sf.net/sfu/arcsight-sfd2d
> _______________________________________________
> Matplotlib-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>
>
------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires
February 28th, so secure your free ArcSight Logger TODAY!
http://p.sf.net/sfu/arcsight-sfd2d
_______________________________________________
Matplotlib-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-users