Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request - make it simpler to use full OO interface #1094

Closed
astrofrog opened this issue Aug 16, 2012 · 17 comments
Closed

Feature request - make it simpler to use full OO interface #1094

astrofrog opened this issue Aug 16, 2012 · 17 comments

Comments

@astrofrog
Copy link
Contributor

I would like to start using the matplotlib OO interface more, as I would prefer to use this when interactive plotting is not needed. It it slightly faster, and behaves more intuitively in terms of reference counting (pyplot keeps a reference to each figure, meaning that if figures are not closed by pyplot, memory goes out of control).

The reason I don't use it is because it's not easy to remember all the set-up of the canvas and figure:

from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure

fig = Figure()
canvas = FigureCanvas(fig)
ax = fig.add_subplot(1, 1, 1)
ax.scatter(np.random.random(10), np.random.random(10))
fig.savefig('test.png')

So I was wondering whether it would be possible to make Figure more intelligent in terms of canvas? The 'ideal' API in my mind would be:

from matplotlib.figure import Figure

fig = Figure()
ax = fig.add_subplot(1, 1, 1)
ax.scatter(np.random.random(10), np.random.random(10))
fig.savefig('test.png')

i.e. I want the figure to just use the default backend (since this is set at the root level of matplotlib, not pyplot). So I would expect the following to work:

import matplotlib
matplotlib.use('Agg')
from matplotlib.figure import Figure

fig = Figure()
ax = fig.add_subplot(1, 1, 1)
ax.scatter(np.random.random(10), np.random.random(10))
fig.savefig('test.png')

and to use the non-interactive Agg backend.

Is this something that has been considered before?

@WeatherGod
Copy link
Member

It would probably be cleaner this way. Currently, pyplot.figure() invokes the new_figure_manager function that is (somehow) established by the init.py module in matplotlib.backends. It would probably be wise to look at this area of code again to see how we can clean this up anyway.

@dmcdougall
Copy link
Member

Setting pyplot aside for the moment, is there anything to stop the canvas being set up in the Figure constructor? At the moment, Figure.__init__ has the line:

self.canvas = None

Which is evidenced by:

In [1]: from matplotlib.figure import Figure

In [2]: fig = Figure()

In [3]: print fig.canvas
None

One way to work around this is to retrieve the default backend in the __init__ method in the constructor, which should exist either from a matplotlib.use('mybackend') or from rcParams. This can be done using a matplotlib.get_backend() call.

Is there something deeper I am missing?

@astrofrog
Copy link
Contributor Author

@dmcdougall - this is exactly what I mean, and I believe it would make it a lot easier for people to use this API.

@dmcdougall
Copy link
Member

So I tried this out, and it seems to work ok. I can't say anything for pyplot. Though, if you're using pyplot, you're probably not interested in the OO interface. I can submit a PR if any of the more experienced mpl developers would like to give some input...

@dmcdougall
Copy link
Member

@efiring Should this be re-opened because of #1221?

@efiring efiring reopened this Sep 8, 2012
@efiring
Copy link
Member

efiring commented Sep 8, 2012

This might have worked if carefully restricted to non-interactive backends. I think it requres some careful thought and experimentation, though. It may be that the way to handle it is via a kwarg to the Figure constructor, explicitly designating a non-interactive backend; or maybe in the code as you had it, attaching the canvas to the figure upon Figure initialization would be done only if the default backend is non-interactive. All of the messy figure management machinery is needed only for screen display, not for savefig, I believe.
A problem with this approach is that although it simplifies some things, it adds overall complexity in that something that works for a non-interactive backend fails if the default backend is interactive. So, it might cause more trouble (puzzled users, mailing list traffic) than it is worth.

@berr
Copy link

berr commented Oct 30, 2012

@efiring Do you think we can find a way to implement this issue without changing the interactive workflow? I have some spare time on the next few weeks and would like to work on that.

@efiring
Copy link
Member

efiring commented Oct 31, 2012

You are certainly welcome to try. I'm out on a ship until mid-Nov., and then busy into December, so I probably won't be much help. If you can come up with something that makes the whole Figure/Canvas dance simpler and easier to understand at the lowest code level as well as at the user level--and that doesn't break anything--that will be very good.

@berr
Copy link

berr commented Oct 31, 2012

I'll sure give it a try.
Is there a dev mailing list / irc channel that I can use to find someone if I need guidance? (couldn't find anything on the site)

@mdboom
Copy link
Member

mdboom commented Oct 31, 2012

matplotlib-devel is a good place to reach other developers:

https://sourceforge.net/mailarchive/forum.php?forum_name=matplotlib-devel

@dmcdougall
Copy link
Member

@berr I've been working on an alternative solution to this, and currently have an implementation illustrating some degree of success. That said, I would be interested to see if you come up with a similar approach. Do you have a branch I can take a cheeky fork of?

@berr
Copy link

berr commented Oct 31, 2012

@dmcdougall Not yet. I'm planning to start this on the next week. Since you've already started, I can use your work as a starting point or even just continue it. Do you have it on a branch that I could see?

@dmcdougall
Copy link
Member

@berr Yes, but don't let it pollute your train of thought. I tried this once before and failed epicly. This new approach is a better version, and I haven't worked on it for a while so I'm not sure if it still works... The branch is here. I hope it's helpful.

@dmcdougall
Copy link
Member

IIRC, I had problems with the Qt4 backend...

@demitri
Copy link

demitri commented Nov 7, 2012

Just want to add my +1 to strongly support a fully OO plotting interface.

@dmcdougall
Copy link
Member

@demitri Thanks. Good to know this would be used.

@berr Did you try out my branch?

@dmcdougall
Copy link
Member

Turns out this is rather hard to implement without a significant backend redesign and/or refactor. See discussion in #1457.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants