add_axes

I feel like I'm doing this right, but it doesn't work. Any clues?

from matplotlib import pyplot as pp

pp.plot((1,2,3))
ax = pp.gca()
f = pp.figure(num=2)
print 'first: %i' % ax.figure.number
print 'second: %i' % f.number
f.add_axes(ax)

yields:

Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "C:\Python27\lib\site-packages\matplotlib\figure.py", line 606, in add_axes
     assert(a.get_figure() is self)
AssertionError

···

--
Christopher Brown, Ph.D.
Associate Research Professor
Department of Speech and Hearing Science
Arizona State University
http://pal.asu.edu

Yes, you are making it harder on yourself…

I feel like I’m doing this right, but it doesn’t work. Any clues?

from matplotlib import pyplot as pp

pp.plot((1,2,3))
ax = pp.gca()

At this point, a figure is implicitly created because none exists at this point. The ax object is implicitly added to that.

f = pp.figure(num=2)

This will be a completely new figure.

print ‘first: %i’ % ax.figure.number
print ‘second: %i’ % f.number
f.add_axes(ax)

Since ax was already attached, it can’t be in two figures at once, so the assertion fails.

yields:

Traceback (most recent call last):
File “”, line 1, in
File “C:\Python27\lib\site-packages\matplotlib\figure.py”, line 606,
in add_axes
assert(a.get_figure() is self)
AssertionError

So, just simply create your figure first, and call ax = f.gca() after. There should be no need to call add_axes except in very special situations.

I hope that helps!

Ben Root

···

On Friday, August 12, 2011, Christopher Brown <c-b@…1861…> wrote:

Christopher Brown, on 2011-08-12 16:56, wrote:

I feel like I'm doing this right, but it doesn't work. Any clues?

from matplotlib import pyplot as pp

pp.plot((1,2,3))
ax = pp.gca()
f = pp.figure(num=2)
print 'first: %i' % ax.figure.number
print 'second: %i' % f.number
f.add_axes(ax)

yields:

Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "C:\Python27\lib\site-packages\matplotlib\figure.py", line 606,
in add_axes
     assert(a.get_figure() is self)
AssertionError

Right now, matplotlib allows an axes to participate in only one
figure. You can get part-way to what you want by setting
ax.figure=f before calling f.add_axes(ax). Then, you'll have ax
in both figures, but its transforms are still rooted in the first
figure, so resizing the first figure, you'll see changes to the
size of the plot in the second figure.

best,

···

--
Paul Ivanov
314 address only used for lists, off-list direct email at:
http://pirsquared.org | GPG/PGP key id: 0x0F3E28F7

I feel like I'm doing this right, but it doesn't work. Any clues?

from matplotlib import pyplot as pp

pp.plot((1,2,3))
ax = pp.gca()
f = pp.figure(num=2)
print 'first: %i' % ax.figure.number
print 'second: %i' % f.number
f.add_axes(ax)

That looks pretty convoluted. What are you really trying to do, and why? It looks like you are trying to transplant an Axes from one figure to another; add_axes doesn't do that. I'm not sure add_axes should even include a signature in which an axes instance is the argument; it is part of the behavior in which add_axes returns an existing Axes if it can find one that matches the requested args and kwargs. There was probably a good reason for this, but it looks to me like excessive overloading of add_axes--making it do something other than what its name clearly states it should do.

The Figure instance is a required argument when creating an Axes instance. Axes are not designed to be copied or moved between figures, as far as I can see.

Eric

···

On 08/12/2011 01:56 PM, Christopher Brown wrote:

yields:

Traceback (most recent call last):
    File "<stdin>", line 1, in<module>
    File "C:\Python27\lib\site-packages\matplotlib\figure.py", line 606,
in add_axes
      assert(a.get_figure() is self)
AssertionError

Thanks Ben,

I should have been more clear. In fact I do want to create an entirely new
figure containing the already created axes. This might not be the best way to
do what I want to do, but the docs for add_axes states that passing an axes
instance will add that instance to the figure. I must be misunderstanding
something.

-Chris

···

On Friday, August 12, 2011 05:57:17 PM Benjamin Root wrote:

Yes, you are making it harder on yourself...

On Friday, August 12, 2011, Christopher Brown <c-b@...1861...> wrote:
> I feel like I'm doing this right, but it doesn't work. Any clues?
>
> from matplotlib import pyplot as pp
>
> pp.plot((1,2,3))
> ax = pp.gca()

At this point, a figure is implicitly created because none exists at this
point. The ax object is implicitly added to that.

> f = pp.figure(num=2)

This will be a completely new figure.

> print 'first: %i' % ax.figure.number
> print 'second: %i' % f.number
> f.add_axes(ax)

Since ax was already attached, it can't be in two figures at once, so the
assertion fails.

> yields:
>
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> File "C:\Python27\lib\site-packages\matplotlib\figure.py", line 606,
>
> in add_axes
>
> assert(a.get_figure() is self)
>
> AssertionError

So, just simply create your figure first, and call ax = f.gca() after.
There should be no need to call add_axes except in very special
situations.

I hope that helps!

Ben Root

So, are you specifically wanting the same axes object in two figures? If so, as Paul said, it is technically possible (using the method that Eric mentioned), but that mode is currently unsupported and we can not guarantee that things will work as expected. Matplotlib assumes that an axes object has a single parent, and breaking that assumption can cause issues down the line.

However, if you don’t intend to have the same axes appear twice, then the question becomes why do you need to create the figure after the axes?

Ben Root

···

On Friday, August 12, 2011, Christopher Brown <c-b@…1861…> wrote:

Thanks Ben,

I should have been more clear. In fact I do want to create an entirely new

figure containing the already created axes. This might not be the best way to
do what I want to do, but the docs for add_axes states that passing an axes
instance will add that instance to the figure. I must be misunderstanding

something.

-Chris

Christopher Brown, on 2011-08-12 16:56, wrote:

I feel like I'm doing this right, but it doesn't work. Any clues?

from matplotlib import pyplot as pp

pp.plot((1,2,3))
ax = pp.gca()
f = pp.figure(num=2)
print 'first: %i' % ax.figure.number
print 'second: %i' % f.number
f.add_axes(ax)

yields:

Traceback (most recent call last):
    File "<stdin>", line 1, in<module>
    File "C:\Python27\lib\site-packages\matplotlib\figure.py", line 606,
in add_axes
      assert(a.get_figure() is self)
AssertionError

Right now, matplotlib allows an axes to participate in only one
figure. You can get part-way to what you want by setting
ax.figure=f before calling f.add_axes(ax). Then, you'll have ax
in both figures, but its transforms are still rooted in the first
figure, so resizing the first figure, you'll see changes to the
size of the plot in the second figure.

It's worse than that; it really just doesn't work in any useful way, and it was never intended to do so. Try it:

In [1]: fig = gcf()

In [2]: fig.add_axes?

In [3]: plot([1,2,3])
Out[3]: [<matplotlib.lines.Line2D at 0x335cf10>]

In [4]: ax = gca()

In [5]: fig2 = figure()

In [6]: ax.set_figure(fig2)

In [7]: fig2.add_axes(ax)
Out[7]: <matplotlib.axes.AxesSubplot at 0x333b250>

In [8]: ax.plot([3,4,5])
Out[8]: [<matplotlib.lines.Line2D at 0x3368890>]

In [9]: draw()

Eric

···

On 08/12/2011 03:00 PM, Paul Ivanov wrote:

best,

------------------------------------------------------------------------------
FREE DOWNLOAD - uberSVN with Social Coding for Subversion.
Subversion made easy with a complete admin console. Easy
to use, easy to manage, easy to install, easy to extend.
Get a Free download of the new open ALM Subversion platform now.
http://p.sf.net/sfu/wandisco-dev2dev

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

Thanks Ben,

I should have been more clear. In fact I do want to create an entirely new
figure containing the already created axes. This might not be the best way to
do what I want to do, but the docs for add_axes states that passing an axes
instance will add that instance to the figure. I must be misunderstanding
something.

The docstring is seriously misleading; I will fix it.

Eric

···

On 08/12/2011 03:58 PM, Christopher Brown wrote:

-Chris

On Friday, August 12, 2011 05:57:17 PM Benjamin Root wrote:

Yes, you are making it harder on yourself...

On Friday, August 12, 2011, Christopher Brown<c-b@...1861...> wrote:

I feel like I'm doing this right, but it doesn't work. Any clues?

from matplotlib import pyplot as pp

pp.plot((1,2,3))
ax = pp.gca()

At this point, a figure is implicitly created because none exists at this
point. The ax object is implicitly added to that.

f = pp.figure(num=2)

This will be a completely new figure.

print 'first: %i' % ax.figure.number
print 'second: %i' % f.number
f.add_axes(ax)

Since ax was already attached, it can't be in two figures at once, so the
assertion fails.

yields:

Traceback (most recent call last):
   File "<stdin>", line 1, in<module>
   File "C:\Python27\lib\site-packages\matplotlib\figure.py", line 606,

in add_axes

     assert(a.get_figure() is self)

AssertionError

So, just simply create your figure first, and call ax = f.gca() after.
  There should be no need to call add_axes except in very special
situations.

I hope that helps!

Ben Root

------------------------------------------------------------------------------
FREE DOWNLOAD - uberSVN with Social Coding for Subversion.
Subversion made easy with a complete admin console. Easy
to use, easy to manage, easy to install, easy to extend.
Get a Free download of the new open ALM Subversion platform now.
http://p.sf.net/sfu/wandisco-dev2dev
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Hi Ben, Eric and Paul,

Paul's partial solution is actually exactly what I need. Thanks!

-Chris

···

On Friday, August 12, 2011 07:26:22 PM Benjamin Root wrote:

On Friday, August 12, 2011, Christopher Brown <c-b@...1861...> wrote:
> Thanks Ben,
>
> I should have been more clear. In fact I do want to create an entirely
> new figure containing the already created axes. This might not be the
> best way

to

> do what I want to do, but the docs for add_axes states that passing an

axes

> instance will add that instance to the figure. I must be misunderstanding
> something.
>
> -Chris

So, are you specifically wanting the same axes object in two figures? If
so, as Paul said, it is technically possible (using the method that Eric
mentioned), but that mode is currently unsupported and we can not guarantee
that things will work as expected. Matplotlib assumes that an axes object
has a single parent, and breaking that assumption can cause issues down the
line.

However, if you don't intend to have the same axes appear twice, then the
question becomes why do you need to create the figure after the axes?

Ben Root