Not scaling patches.

Hello, I’ve used matplotlib for a while but never had cause to ask a question until now. I am trying to add a patch to an axis, but would like the patch to remain the same size when, interactively, I resize the resulting figure. I am using TkAgg, and trying the following:

import matplotlib.pyplot as plt

import matplotlib.patches as patches

ax = plt.gca()

cp = patches.Circle((.5,.5),.025)

ax.add_patch(cp)

ax.set_aspect(‘equal’)

plt.draw()

plt.show()

This gives me a nice blue circle in the middle of the plot, and using ax.set_aspect(‘equal’) I know that it will not be distorted into an ellipse. But is there a way to ensure that when I make the Tk window bigger, that the circle appears to be the same size as it was previously? I assume this would entail some sort of transform, but I don’t quite understand how they work…

Ben

I haven’t tried using this tool myself, and it might not be what you want, but there is an AnchoredArtist tool that might interest you:

http://matplotlib.sourceforge.net/mpl_toolkits/axes_grid/users/overview.html#anchoredartists

I think this means that it wouldn’t move at all, and I don’t know if that is what you want. I hope this helps!

Ben Root

···

On Thu, Aug 26, 2010 at 2:24 PM, Ben Edwards <bedwards@…3253…> wrote:

Hello, I’ve used matplotlib for a while but never had cause to ask a question until now. I am trying to add a patch to an axis, but would like the patch to remain the same size when, interactively, I resize the resulting figure. I am using TkAgg, and trying the following:

import matplotlib.pyplot as plt

import matplotlib.patches as patches

ax = plt.gca()

cp = patches.Circle((.5,.5),.025)

ax.add_patch(cp)

ax.set_aspect(‘equal’)

plt.draw()

plt.show()

This gives me a nice blue circle in the middle of the plot, and using ax.set_aspect(‘equal’) I know that it will not be distorted into an ellipse. But is there a way to ensure that when I make the Tk window bigger, that the circle appears to be the same size as it was previously? I assume this would entail some sort of transform, but I don’t quite understand how they work…

Ben

That doesn’t quite work the way I want. I guess a good example of the behavior I am looking for is what ‘scatter’ does. It seems that regardless of the size of the figure the points stay the same size. I would use scatter but would like to have access to the individual patches later to modify them. Is there a way to access individual patches in scatter, or how does scatter manage to scale its Collection correctly?

I’ve dug around in the source code a bit, but can’t find an obvious solution…

Ben

···

On Fri, Aug 27, 2010 at 9:04 AM, Benjamin Root <ben.root@…1304…> wrote:

On Thu, Aug 26, 2010 at 2:24 PM, Ben Edwards <bedwards@…3250…> wrote:

Hello, I’ve used matplotlib for a while but never had cause to ask a question until now. I am trying to add a patch to an axis, but would like the patch to remain the same size when, interactively, I resize the resulting figure. I am using TkAgg, and trying the following:

import matplotlib.pyplot as plt

import matplotlib.patches as patches

ax = plt.gca()

cp = patches.Circle((.5,.5),.025)

ax.add_patch(cp)

ax.set_aspect(‘equal’)

plt.draw()

plt.show()

This gives me a nice blue circle in the middle of the plot, and using ax.set_aspect(‘equal’) I know that it will not be distorted into an ellipse. But is there a way to ensure that when I make the Tk window bigger, that the circle appears to be the same size as it was previously? I assume this would entail some sort of transform, but I don’t quite understand how they work…

Ben

I haven’t tried using this tool myself, and it might not be what you want, but there is an AnchoredArtist tool that might interest you:

http://matplotlib.sourceforge.net/mpl_toolkits/axes_grid/users/overview.html#anchoredartists

I think this means that it wouldn’t move at all, and I don’t know if that is what you want. I hope this helps!

Ben Root

You can make the circle this way, specifying everything in axes coordinates:

cp = patches.Circle((.5,.5),.025, transform=ax.transAxes)

However, this puts the circle in the same spot in axes coordinates
[(0.5,0.5) is the middle of the plot]. I'm not sure if that's what you
want. I can't see any way to get Circle to use different transforms
for the center and the size, so from here the only path forward I see
is subclassing Circle. This way you could add code to the draw method
to calculate the center in axes coordinates from the center in data
coords. This needs to be done at draw time since the mapping of data
coords->axes coords changes as you pan and zoom.

Ryan

···

On Thu, Aug 26, 2010 at 2:24 PM, Ben Edwards <bedwards@...3250...> wrote:

Hello, I've used matplotlib for a while but never had cause to ask a
question until now. I am trying to add a patch to an axis, but would like
the patch to remain the same size when, interactively, I resize the
resulting figure. I am using TkAgg, and trying the following:

import matplotlib.pyplot as plt
import matplotlib.patches as patches
ax = plt.gca()
cp = patches.Circle((.5,.5),.025)
ax.add_patch(cp)
ax.set_aspect('equal')
plt.draw()
plt.show()

This gives me a nice blue circle in the middle of the plot, and using
ax.set_aspect('equal') I know that it will not be distorted into an ellipse.
But is there a way to ensure that when I make the Tk window bigger, that the
circle appears to be the same size as it was previously? I assume this would
entail some sort of transform, but I don't quite understand how they work...

--
Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma

Hello, I've used matplotlib for a while but never had cause to ask a
question until now. I am trying to add a patch to an axis, but would like
the patch to remain the same size when, interactively, I resize the
resulting figure. I am using TkAgg, and trying the following:

import matplotlib.pyplot as plt
import matplotlib.patches as patches
ax = plt.gca()
cp = patches.Circle((.5,.5),.025)
ax.add_patch(cp)
ax.set_aspect('equal')
plt.draw()
plt.show()

This gives me a nice blue circle in the middle of the plot, and using
ax.set_aspect('equal') I know that it will not be distorted into an ellipse.
But is there a way to ensure that when I make the Tk window bigger, that the
circle appears to be the same size as it was previously? I assume this would
entail some sort of transform, but I don't quite understand how they work...

You can make the circle this way, specifying everything in axes coordinates:

cp = patches.Circle((.5,.5),.025, transform=ax.transAxes)

However, this puts the circle in the same spot in axes coordinates
[(0.5,0.5) is the middle of the plot]. I'm not sure if that's what you
want. I can't see any way to get Circle to use different transforms
for the center and the size, so from here the only path forward I see
is subclassing Circle. This way you could add code to the draw method
to calculate the center in axes coordinates from the center in data
coords. This needs to be done at draw time since the mapping of data
coords->axes coords changes as you pan and zoom.

A simpler alternative is to use a CircleCollection with a single member. Collections allow separate transforms for the patch and the offset; the latter determines the location of the center.

Eric

···

On 08/27/2010 07:15 AM, Ryan May wrote:

On Thu, Aug 26, 2010 at 2:24 PM, Ben Edwards<bedwards@...3250...> wrote:

Ryan

Why in the world didn't that occur to me?

Ryan

···

On Fri, Aug 27, 2010 at 1:16 PM, Eric Firing <efiring@...202...> wrote:

On 08/27/2010 07:15 AM, Ryan May wrote:

You can make the circle this way, specifying everything in axes coordinates:

cp = patches.Circle((.5,.5),.025, transform=ax.transAxes)

However, this puts the circle in the same spot in axes coordinates
[(0.5,0.5) is the middle of the plot]. I'm not sure if that's what you
want. I can't see any way to get Circle to use different transforms
for the center and the size, so from here the only path forward I see
is subclassing Circle. This way you could add code to the draw method
to calculate the center in axes coordinates from the center in data
coords. This needs to be done at draw time since the mapping of data
coords->axes coords changes as you pan and zoom.

A simpler alternative is to use a CircleCollection with a single member.
Collections allow separate transforms for the patch and the offset;
the latter determines the location of the center.

--
Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma