Geo projections, aspect ratio, and imshow

Hi there,

I'm plotting some images in latitude/longitude space. These are
images generated using the HEALpix method for discretizing the sphere,
but I have resampled them to a regular grid of phi, theta, and the
resultant image is contained in a variable img. This is a fully-self
contained snippet:

import matplotlib.figure
import matplotlib.backends.backend_agg
import numpy
from numpy import pi

img = numpy.random.random((800, 800))
fig = matplotlib.figure.Figure((10, 4.9))
ax = fig.add_subplot(1,1,1,projection='mollweide')
image = ax.imshow(img, extent=(-pi,pi,-pi/2,pi/2), clip_on=False, aspect=0.5)
cb = fig.colorbar(image, orientation='horizontal')
canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig)
canvas.print_figure("hi.png")

This makes a very nice looking figure, basically as expected: a black
oval outline for the map projection with the image inside it, the
lat/lon axes identified, etc. What I'm running into here is that I
would like to fiddle with the size of the figure, to adjust the
whitespace and the position of the colorbar and so on, but any
adjustment to the height of the figure instantiation, for instance:

fig = matplotlib.figure.Figure((10, 4.9))

(and the rest unchanged) results in the black oval, the axes, but the
image content is completely blank. Is this a bug, or just a subtlety
I'm missing?

Thanks for any ideas!

Best,

Matt

I am curious, why are you saving the figure using canvas.print_figure()? How is it different from fig.savefig()? If you, for some reason, must use canvas.print_figure(), then it seems like you are creating a new canvas from the figure (I don’t know, maybe it grabs figure’s existing canvas object?). In other words, you could just simply do:

fig.savefig(“hi.png”)

or, if you must use canvas.print_figure(), you could do:

fig.canvas.print_figure()

instead of the two lines you have right now.

See if that makes a difference.

Ben Root

···

On Thu, Feb 10, 2011 at 1:38 PM, Matthew Turk <matthewturk@…878…287…> wrote:

Hi there,

I’m plotting some images in latitude/longitude space. These are

images generated using the HEALpix method for discretizing the sphere,

but I have resampled them to a regular grid of phi, theta, and the

resultant image is contained in a variable img. This is a fully-self

contained snippet:

import matplotlib.figure

import matplotlib.backends.backend_agg

import numpy

from numpy import pi

img = numpy.random.random((800, 800))

fig = matplotlib.figure.Figure((10, 4.9))

ax = fig.add_subplot(1,1,1,projection=‘mollweide’)

image = ax.imshow(img, extent=(-pi,pi,-pi/2,pi/2), clip_on=False, aspect=0.5)

cb = fig.colorbar(image, orientation=‘horizontal’)

canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig)

canvas.print_figure(“hi.png”)

This makes a very nice looking figure, basically as expected: a black

oval outline for the map projection with the image inside it, the

lat/lon axes identified, etc. What I’m running into here is that I

would like to fiddle with the size of the figure, to adjust the

whitespace and the position of the colorbar and so on, but any

adjustment to the height of the figure instantiation, for instance:

fig = matplotlib.figure.Figure((10, 4.9))

(and the rest unchanged) results in the black oval, the axes, but the

image content is completely blank. Is this a bug, or just a subtlety

I’m missing?

Thanks for any ideas!

Best,

Matt

Hi Ben,

Hi there,

I'm plotting some images in latitude/longitude space. These are
images generated using the HEALpix method for discretizing the sphere,
but I have resampled them to a regular grid of phi, theta, and the
resultant image is contained in a variable img. This is a fully-self
contained snippet:

import matplotlib.figure
import matplotlib.backends.backend_agg
import numpy
from numpy import pi

img = numpy.random.random((800, 800))
fig = matplotlib.figure.Figure((10, 4.9))
ax = fig.add_subplot(1,1,1,projection='mollweide')
image = ax.imshow(img, extent=(-pi,pi,-pi/2,pi/2), clip_on=False,
aspect=0.5)
cb = fig.colorbar(image, orientation='horizontal')
canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig)
canvas.print_figure("hi.png")

This makes a very nice looking figure, basically as expected: a black
oval outline for the map projection with the image inside it, the
lat/lon axes identified, etc. What I'm running into here is that I
would like to fiddle with the size of the figure, to adjust the
whitespace and the position of the colorbar and so on, but any
adjustment to the height of the figure instantiation, for instance:

fig = matplotlib.figure.Figure((10, 4.9))

(and the rest unchanged) results in the black oval, the axes, but the
image content is completely blank. Is this a bug, or just a subtlety
I'm missing?

Thanks for any ideas!

Best,

Matt

I am curious, why are you saving the figure using canvas.print_figure()?
How is it different from fig.savefig()? If you, for some reason, must use
canvas.print_figure(), then it seems like you are creating a new canvas from
the figure (I don't know, maybe it grabs figure's existing canvas
object?). In other words, you could just simply do:

fig.savefig("hi.png")

Maybe I'm doing something wrong here, but in the example script I gave
the figure does not have a canvas object affiliated with it; it's set
to None until I execute this operation:

canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig)

At that point, fig.canvas is not None, and is the same canvas that I
just created:

print fig.canvas

None

canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig)
canvas.print_figure("hi.png")
fig.canvas

<matplotlib.backends.backend_agg.FigureCanvasAgg instance at 0x10263d3b0>

canvas is fig.canvas

True

or, if you must use canvas.print_figure(), you could do:

fig.canvas.print_figure()

instead of the two lines you have right now.

See if that makes a difference.

Unfortunately it didn't end up making a difference. The image is
still printed, with colorbar, with lat/lon lines, but no image in the
center of the black oval for the projection.

Thanks,

Matt

···

On Thu, Feb 10, 2011 at 5:06 PM, Benjamin Root <ben.root@...1304...> wrote:

On Thu, Feb 10, 2011 at 1:38 PM, Matthew Turk <matthewturk@...287...> wrote:

Ben Root

I just figured out why you don’t have a canvas object. It is because you aren’t creating your figure object correctly. Try this:

import matplotlib.pyplot as plt
import numpy

from numpy import pi

img = numpy.random.random((800, 800))
fig = plt.figure(figsize=(10, 4.9))
ax = fig.add_subplot(1,1,1,projection=‘mollweide’)
image = ax.imshow(img, extent=(-pi,pi,-pi/2,pi/2), clip_on=False, aspect=0.5)

cb = fig.colorbar(image, orientation=‘horizontal’)
fig.savefig(“hi.png”)

Notice that the figure is created through the pyplot’s figure() method. Because pyplot knows the backend, it is able to assign the correct canvas object when making the figure object. This can’t be done from the Figure constructor alone. Once a proper figure object is made, it can then properly call savefig().

See if that helps!
Ben Root

···

On Thu, Feb 10, 2011 at 4:13 PM, Matthew Turk <matthewturk@…287…> wrote:

Hi Ben,

On Thu, Feb 10, 2011 at 5:06 PM, Benjamin Root <ben.root@…1304…> wrote:

On Thu, Feb 10, 2011 at 1:38 PM, Matthew Turk <matthewturk@…287…> wrote:

Hi there,

I’m plotting some images in latitude/longitude space. These are

images generated using the HEALpix method for discretizing the sphere,

but I have resampled them to a regular grid of phi, theta, and the

resultant image is contained in a variable img. This is a fully-self

contained snippet:

import matplotlib.figure

import matplotlib.backends.backend_agg

import numpy

from numpy import pi

img = numpy.random.random((800, 800))

fig = matplotlib.figure.Figure((10, 4.9))

ax = fig.add_subplot(1,1,1,projection=‘mollweide’)

image = ax.imshow(img, extent=(-pi,pi,-pi/2,pi/2), clip_on=False,

aspect=0.5)

cb = fig.colorbar(image, orientation=‘horizontal’)

canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig)

canvas.print_figure(“hi.png”)

This makes a very nice looking figure, basically as expected: a black

oval outline for the map projection with the image inside it, the

lat/lon axes identified, etc. What I’m running into here is that I

would like to fiddle with the size of the figure, to adjust the

whitespace and the position of the colorbar and so on, but any

adjustment to the height of the figure instantiation, for instance:

fig = matplotlib.figure.Figure((10, 4.9))

(and the rest unchanged) results in the black oval, the axes, but the

image content is completely blank. Is this a bug, or just a subtlety

I’m missing?

Thanks for any ideas!

Best,

Matt

I am curious, why are you saving the figure using canvas.print_figure()?

How is it different from fig.savefig()? If you, for some reason, must use

canvas.print_figure(), then it seems like you are creating a new canvas from

the figure (I don’t know, maybe it grabs figure’s existing canvas

object?). In other words, you could just simply do:

fig.savefig(“hi.png”)

Maybe I’m doing something wrong here, but in the example script I gave

the figure does not have a canvas object affiliated with it; it’s set

to None until I execute this operation:

canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig)

At that point, fig.canvas is not None, and is the same canvas that I

just created:

print fig.canvas

None

canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig)

canvas.print_figure(“hi.png”)

fig.canvas

<matplotlib.backends.backend_agg.FigureCanvasAgg instance at 0x10263d3b0>

canvas is fig.canvas

True

or, if you must use canvas.print_figure(), you could do:

fig.canvas.print_figure()

instead of the two lines you have right now.

See if that makes a difference.

Unfortunately it didn’t end up making a difference. The image is

still printed, with colorbar, with lat/lon lines, but no image in the

center of the black oval for the projection.

Thanks,

Matt

Hi Ben,

Hi Ben,

>>
>> Hi there,
>>
>> I'm plotting some images in latitude/longitude space. These are
>> images generated using the HEALpix method for discretizing the sphere,
>> but I have resampled them to a regular grid of phi, theta, and the
>> resultant image is contained in a variable img. This is a fully-self
>> contained snippet:
>>
>> import matplotlib.figure
>> import matplotlib.backends.backend_agg
>> import numpy
>> from numpy import pi
>>
>> img = numpy.random.random((800, 800))
>> fig = matplotlib.figure.Figure((10, 4.9))
>> ax = fig.add_subplot(1,1,1,projection='mollweide')
>> image = ax.imshow(img, extent=(-pi,pi,-pi/2,pi/2), clip_on=False,
>> aspect=0.5)
>> cb = fig.colorbar(image, orientation='horizontal')
>> canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig)
>> canvas.print_figure("hi.png")
>>
>> This makes a very nice looking figure, basically as expected: a black
>> oval outline for the map projection with the image inside it, the
>> lat/lon axes identified, etc. What I'm running into here is that I
>> would like to fiddle with the size of the figure, to adjust the
>> whitespace and the position of the colorbar and so on, but any
>> adjustment to the height of the figure instantiation, for instance:
>>
>> fig = matplotlib.figure.Figure((10, 4.9))
>>
>> (and the rest unchanged) results in the black oval, the axes, but the
>> image content is completely blank. Is this a bug, or just a subtlety
>> I'm missing?
>>
>> Thanks for any ideas!
>>
>> Best,
>>
>> Matt
>>
>
> I am curious, why are you saving the figure using canvas.print_figure()?
> How is it different from fig.savefig()? If you, for some reason, must
> use
> canvas.print_figure(), then it seems like you are creating a new canvas
> from
> the figure (I don't know, maybe it grabs figure's existing canvas
> object?). In other words, you could just simply do:
>
> fig.savefig("hi.png")

Maybe I'm doing something wrong here, but in the example script I gave
the figure does not have a canvas object affiliated with it; it's set
to None until I execute this operation:

canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig)

At that point, fig.canvas is not None, and is the same canvas that I
just created:

>>> print fig.canvas
None
>>> canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig)
>>> canvas.print_figure("hi.png")
>>> fig.canvas
<matplotlib.backends.backend_agg.FigureCanvasAgg instance at 0x10263d3b0>
>>> canvas is fig.canvas
True

>
> or, if you must use canvas.print_figure(), you could do:
>
> fig.canvas.print_figure()
>
> instead of the two lines you have right now.
>
> See if that makes a difference.

Unfortunately it didn't end up making a difference. The image is
still printed, with colorbar, with lat/lon lines, but no image in the
center of the black oval for the projection.

Thanks,

Matt

I just figured out why you don't have a canvas object. It is because you
aren't creating your figure object correctly. Try this:

import matplotlib.pyplot as plt
import numpy
from numpy import pi

img = numpy.random.random((800, 800))
fig = plt.figure(figsize=(10, 4.9))
ax = fig.add_subplot(1,1,1,projection='mollweide')
image = ax.imshow(img, extent=(-pi,pi,-pi/2,pi/2), clip_on=False,
aspect=0.5)
cb = fig.colorbar(image, orientation='horizontal')
fig.savefig("hi.png")

Notice that the figure is created through the pyplot's figure() method.
Because pyplot knows the backend, it is able to assign the correct canvas
object when making the figure object. This can't be done from the Figure
constructor alone. Once a proper figure object is made, it can then
properly call savefig().

See if that helps!
Ben Root

This script does work, but it gives exactly the same results as my
original script -- which is that if the figure size is set to (10,5.0)
it will include the image plot inside the black oval for the
projection, but if the figure size is (10,4.9) it will not. I've
placed two images here:

http://imgur.com/CApcml&hc4ES
http://imgur.com/CApcm&hc4ESl

The first image was created with figsize (10,5). The second was with
figsize (10,4.9). The image plot does not appear in the second one,
although its bounding box does. Any ideas?

Thanks!

Matt

···

On Thu, Feb 10, 2011 at 5:27 PM, Benjamin Root <ben.root@...1304...> wrote:

On Thu, Feb 10, 2011 at 4:13 PM, Matthew Turk <matthewturk@...287...> wrote:

On Thu, Feb 10, 2011 at 5:06 PM, Benjamin Root <ben.root@...1304...> wrote:
> On Thu, Feb 10, 2011 at 1:38 PM, Matthew Turk <matthewturk@...287...> >> > wrote: