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

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

Comments

Projects
None yet
8 participants
Contributor

astrofrog commented Aug 16, 2012

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?

Member

WeatherGod commented Aug 16, 2012

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.

Member

dmcdougall commented Aug 21, 2012

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?

Contributor

astrofrog commented Aug 21, 2012

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

Member

dmcdougall commented Aug 21, 2012

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...

@pelson pelson closed this Sep 4, 2012

Member

dmcdougall commented Sep 8, 2012

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

@efiring efiring reopened this Sep 8, 2012

Owner

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 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.

Owner

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 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)

Owner

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

Member

dmcdougall commented Oct 31, 2012

@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 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?

Member

dmcdougall commented Oct 31, 2012

@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.

Member

dmcdougall commented Oct 31, 2012

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

demitri commented Nov 7, 2012

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

Member

dmcdougall commented Nov 7, 2012

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

@berr Did you try out my branch?

Member

dmcdougall commented Feb 19, 2013

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

@dmcdougall dmcdougall closed this Feb 19, 2013

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