imsave function

Hi,

I've attached a patch against the mpl head in response to John's suggestion and helpful pointers on the users list. This adds a new function imsave to complement imread in the image module. I've also exposed it in the pyplot interface.
If this is presumptuous, feel free to remove it from the patch or ask me to remove it. This is my first contribution to matplotlib for a while and my first attempt at a patch like this.

Because I don't build matplotlib from source, I've done what testing I can without fully rebuilding matplotlib. I'd be reluctant to have this patch applied without someone else checking it first. It's pretty simple so applying it locally and running the demo file should be a good enough test.

thanks,
Gary Ruben

image_py_patch.diff (5.95 KB)

Hi Gary, I have a couple comments:

1) No need for:

+ ax = fig.add_subplot(111)
+ ax.set_axis_off()

2) It's probably best to have maximum compatibility with imshow().
Therefore, use vmin=None and vmax=None as keyword arguments (rather than
clims).

Otherwise, I tested and it works for me.

-Andrew

Gary Ruben wrote:

···

Hi,

I've attached a patch against the mpl head in response to John's
suggestion and helpful pointers on the users list. This adds a new
function imsave to complement imread in the image module. I've also
exposed it in the pyplot interface.
If this is presumptuous, feel free to remove it from the patch or ask me
to remove it. This is my first contribution to matplotlib for a while
and my first attempt at a patch like this.

Because I don't build matplotlib from source, I've done what testing I
can without fully rebuilding matplotlib. I'd be reluctant to have this
patch applied without someone else checking it first. It's pretty simple
so applying it locally and running the demo file should be a good enough
test.

thanks,
Gary Ruben

------------------------------------------------------------------------

------------------------------------------------------------------------------
Create and Deploy Rich Internet Apps outside the browser with Adobe(R)AIR(TM)
software. With Adobe AIR, Ajax developers can use existing skills and code to
build responsive, highly engaging applications that combine the power of local
resources and data with the reach of the web. Download the Adobe AIR SDK and
Ajax docs to start building applications today-http://p.sf.net/sfu/adobe-com

------------------------------------------------------------------------

_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Thanks for the quick test and comments Andrew. I've made your suggested changes and attached a new patch.

Gary

Andrew Straw wrote:

image_py_patch.diff (5.87 KB)

···

Hi Gary, I have a couple comments:

1) No need for:

+ ax = fig.add_subplot(111)
+ ax.set_axis_off()

2) It's probably best to have maximum compatibility with imshow().
Therefore, use vmin=None and vmax=None as keyword arguments (rather than
clims).

Otherwise, I tested and it works for me.

-Andrew

Gary, this looks fine to me. Do you have commit access? If not, I'll be
happy to check it in for you.

-Andrew

Gary Ruben wrote:

···

Thanks for the quick test and comments Andrew. I've made your suggested
changes and attached a new patch.

Gary

Andrew Straw wrote:

Hi Gary, I have a couple comments:

1) No need for:

+ ax = fig.add_subplot(111)
+ ax.set_axis_off()

2) It's probably best to have maximum compatibility with imshow().
Therefore, use vmin=None and vmax=None as keyword arguments (rather than
clims).

Otherwise, I tested and it works for me.

-Andrew

------------------------------------------------------------------------

------------------------------------------------------------------------------
Create and Deploy Rich Internet Apps outside the browser with Adobe(R)AIR(TM)
software. With Adobe AIR, Ajax developers can use existing skills and code to
build responsive, highly engaging applications that combine the power of local
resources and data with the reach of the web. Download the Adobe AIR SDK and
Ajax docs to start building applications today-http://p.sf.net/sfu/adobe-com

------------------------------------------------------------------------

_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Hi Andrew,

I don't have commit access. If you would check it in, that would be great.

thanks for offering,
Gary

Andrew Straw wrote:

···

Gary, this looks fine to me. Do you have commit access? If not, I'll be
happy to check it in for you.

-Andrew

Gary Ruben wrote:

Hi Andrew,

I don't have commit access. If you would check it in, that would be great.

Committed to the trunk in r6899... Thanks!

And, sheesh, SourceForge's SVN server is slooow today for me, although
it seems to have finally improved.

Hey all,

2009/2/10 Andrew Straw <strawman@...36...>:

Gary Ruben wrote:

Hi Andrew,

I don't have commit access. If you would check it in, that would be great.

Committed to the trunk in r6899... Thanks!

And, sheesh, SourceForge's SVN server is slooow today for me, although
it seems to have finally improved.

While trying to write a matplotlib plugin for scikits.image, we
noticed that `imsave` isn't currently working (that goes for the one
in Ubuntu [0.99 I think] as well as the latest SVN):

Traceback (most recent call last):
  File "test_imsave.py", line 6, in <module>
    plt.imsave('test.jpg', img)
  File "/Users/stefan/lib/python2.6/site-packages/matplotlib/pyplot.py",
line 1412, in imsave
    return _imsave(*args, **kwargs)
  File "/Users/stefan/lib/python2.6/site-packages/matplotlib/image.py",
line 1025, in imsave
    fig = Figure(figsize=arr.shape[::-1], dpi=1, frameon=False)
  File "/Users/stefan/lib/python2.6/site-packages/matplotlib/figure.py",
line 180, in __init__
    self.bbox_inches = Bbox.from_bounds(0, 0, *figsize)
TypeError: from_bounds() takes exactly 4 arguments (5 given)

The commands needed to reproduce the error are:

import matplotlib.pyplot as plt
import numpy as np

img = np.ones((50, 50, 3), dtype=np.uint8)

plt.imsave('test.jpg', img)

Regards
Stéfan

Currently imsave (implemented in the image.py file) only deals with greyscale single-plane images, i.e. 2D arrays, and in my defence, it's in the docstring, so I wouldn't call it a bug. However, it's a reasonable expectation that it support rgb and rgba since it is basically a thin wrapper around figimage.

My first try at this was to change the line

fig = Figure(figsize=arr.shape[::-1], dpi=1, frameon=False)

to

fig = Figure(figsize=(arr.shape[1],arr.shape[0]), dpi=1, frameon=False)

since we just want to take the first two shape values.

(note figsize=arr.shape[:2][::-1] also works)

This may be all you need. My tests (in the attached test.py) appear to work. However, I don't think it's what you want. By default, figimage even expects NxMx3 and NxMx4 arrays to be float arrays nominally ranging from 0-1. What you probably want is a raw RGB mapping where pixel planes are unsigned 8 bit values. I thought calling figimage with a norm=no_norm(0,255) instance achieved this but it doesn't work as I expect. So the first question is, what is the expected behaviour here, and a follow-up is does anyone here understand how to do the colour mapping to achieve it?

Gary

St�fan van der Walt wrote:

my_plottools.py (1.98 KB)

test.py (937 Bytes)

···

Hey all,

2009/2/10 Andrew Straw <strawman@...36...>:

Gary Ruben wrote:

Hi Andrew,

I don't have commit access. If you would check it in, that would be great.

Committed to the trunk in r6899... Thanks!

And, sheesh, SourceForge's SVN server is slooow today for me, although
it seems to have finally improved.

While trying to write a matplotlib plugin for scikits.image, we
noticed that `imsave` isn't currently working (that goes for the one
in Ubuntu [0.99 I think] as well as the latest SVN):

Traceback (most recent call last):
  File "test_imsave.py", line 6, in <module>
    plt.imsave('test.jpg', img)
  File "/Users/stefan/lib/python2.6/site-packages/matplotlib/pyplot.py",
line 1412, in imsave
    return _imsave(*args, **kwargs)
  File "/Users/stefan/lib/python2.6/site-packages/matplotlib/image.py",
line 1025, in imsave
    fig = Figure(figsize=arr.shape[::-1], dpi=1, frameon=False)
  File "/Users/stefan/lib/python2.6/site-packages/matplotlib/figure.py",
line 180, in __init__
    self.bbox_inches = Bbox.from_bounds(0, 0, *figsize)
TypeError: from_bounds() takes exactly 4 arguments (5 given)

The commands needed to reproduce the error are:

import matplotlib.pyplot as plt
import numpy as np

img = np.ones((50, 50, 3), dtype=np.uint8)

plt.imsave('test.jpg', img)

Regards
St�fan

Hi Gary

Sorry, I didn't even read the docstring since I have been using
SciPy's "imsave" so far.

2009/11/8 Gary Ruben <gruben@...1...>:

This may be all you need. My tests (in the attached test.py) appear to
work. However, I don't think it's what you want. By default, figimage
even expects NxMx3 and NxMx4 arrays to be float arrays nominally ranging
from 0-1. What you probably want is a raw RGB mapping where pixel planes
are unsigned 8 bit values. I thought calling figimage with a
norm=no_norm(0,255) instance achieved this but it doesn't work as I
expect. So the first question is, what is the expected behaviour here,
and a follow-up is does anyone here understand how to do the colour
mapping to achieve it?

We assume that arrays of dtype uint8 represent intensities 0 through
255, and that floating point arrays are between 0-1.

Regards
Stéfan

So I think the change I suggested takes care of the floating point case, except that the vmin and vmax values don't default to 0.0 and 1.0. I wonder whether this is enough of a surprise to warrant some logic to set vmin and vmax in some cases, such as iff all array values are floats in the range 0.0-1.0 and neither vmin nor vmax have been specified as arguments, then use vmin=0.0 and vmax=1.0. Should we aim to replicate the scipy imsave behaviour exactly? Another possible problem with the current behaviour is that single bit plane arrays currently get saved as RGB - I don't know if this can be changed easily.

Gary

St�fan van der Walt wrote:

···

Hi Gary

Sorry, I didn't even read the docstring since I have been using
SciPy's "imsave" so far.

2009/11/8 Gary Ruben <gruben@...1...>:

This may be all you need. My tests (in the attached test.py) appear to
work. However, I don't think it's what you want. By default, figimage
even expects NxMx3 and NxMx4 arrays to be float arrays nominally ranging
from 0-1. What you probably want is a raw RGB mapping where pixel planes
are unsigned 8 bit values. I thought calling figimage with a
norm=no_norm(0,255) instance achieved this but it doesn't work as I
expect. So the first question is, what is the expected behaviour here,
and a follow-up is does anyone here understand how to do the colour
mapping to achieve it?

We assume that arrays of dtype uint8 represent intensities 0 through
255, and that floating point arrays are between 0-1.

Regards
St�fan