Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Reduce object-oriented boilerplate for users#1125

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
pelson merged 5 commits intomatplotlib:masterfromdmcdougall:oo
Sep 4, 2012

Conversation

dmcdougall
Copy link
Member

Now, one can work with the default backend to create figures, without
the need to attach a canvas manually. For example:

importmatplotlibmatplotlib.use('agg')frommatplotlib.figureimportFigurefig=Figure()ax=fig.add_subplot(1,1,1)ax.plot([1,2,3], [1,2,3])fig.savefig('oo.png')

This is an attempt at resolving issue#1094.

Disclaimer: I have no idea what implications this has onpyplot andpylab, but 'it just works' for me, and I tried theMacOSX,Agg andPDF backends.

@mdboom
Copy link
Member

This is very handy. +1.

@efiring
Copy link
Member

The basic idea seems good. Ideally, I would think that each backend should provide a canvas in way that does not require the huge if...elif structure, but this would require a larger change, so perhaps it should be left until later. figure.py should not need to know about all possible backends; it should be able to do something like "import matplotlib.backends; matplotlib.backends.get_current_canvas()".

In any case, all backends supported by rcsetup.validate_backends (and listed in rcsetup.all_backends) should be included; some are missing at present.

@@ -323,6 +323,48 @@ def __init__(self,
self.clf()
self._cachedRenderer = None

def _current_figure_canvas(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Perhaps this could be a function inbackend_bases?pylab_setup pretty much does this for you. Something like:

import matplotlib.backends as mbackends # NOTE: requires a change from #1020backend_mod, _, _, _ = mbackends.pylab_setup()# NOTE: would require all backend modules to have # a FigureCanvas rather than say a FigureCanvasGTKAggbackend_mod.FigureCanvas(self)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Also, needs a docstring, and the name of the method is misleading.

@pelson
Copy link
Member

Ah. I've only just read@efiring 's comment. It seems we agree on this issue. I definitely think this should be done properly at this stage, and would think it was cleaner to do this via the "backend_bases" module. Other than that, I think this is a great idea and will make working in a full OO way much easier.

@mdboom
Copy link
Member

@pelson: Thanks for finding the way to avoid the largeelif statement. I hadn't seen this earlier, so thought it was the best we could do for now. That's definitely preferable.

@dmcdougall
Copy link
MemberAuthor

Yes@pelson! Good spot. I didn't think it was possible. I will obviously update to reflect this. Awesome! :D

@dmcdougall
Copy link
MemberAuthor

Also, thanks@efiring,@pelson and@mdboom for looking through the code. You are all heroes.

Now, one can work with the default backend to create figures, withoutthe need to attach a canvas manually. For example:import matplotlibmatplotlib.use('agg')from matplotlib.figure import Figurefig = Figure()ax = fig.add_subplot(1, 1, 1)ax.plot([1, 2, 3], [1, 2, 3])fig.savefig('oo.png')
@dmcdougall
Copy link
MemberAuthor

I've rebased this against master to get theawesome changes from#1175. This will save me from conflicts with the changes I'm about to make.

@astrofrog
Copy link
Contributor

I wonder whether as part of this PR, it would make sense to also update the documentation to add clearer information about the pure-OO API? At the moment, it's very hard to find any information about it. Maybe there should be a top-level section under 'User guide' that talks about the pure-OO API and the pros and cons compared to using pyplot or th hybrid pyplot-OO?

@dmcdougall
Copy link
MemberAuthor

@astrofrog That's a great suggestion.

Would any of the wider community appreciate a couple of example scripts that use the object-oriented interface? I'd be happy to write some.

@dmcdougall
Copy link
MemberAuthor

Ok, 3e4dea3 is a rather large commit.@pelson's suggestion of making each backend have aFigureCanvas as opposed to, say, aFigureCanvasAgg is a backwards incompatible change. Instead, I though it was better to just write an alias for each backend. That's the main crux of the new commit, just in case anybody didn't have the stamina to scroll through a colossal diff. In fact, I think one of the backends already had this alias, which is nice.

I'm still a newbie when it comes to the codebase, which is why I need you guys to tell me if I've put something in a sub-optimal place. You've been really helpful with all of my suggestions. So thank you.

Please test it out. Specifically, I don't want this to break anything inpylab. So if any of you arepylab users, your feedback is very welcome.

@@ -330,6 +330,12 @@ def __init__(self,
self.clf()
self._cachedRenderer = None

def _setup_canvas(self):
# TODO: docstring
Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I will do it. I promise.

@travisbot
Copy link

This pull requestfails (merged 3e4dea3a intocadd152).

@@ -268,7 +268,6 @@ class TimerMac(_macosx.Timer, TimerBase):
'''
# completely implemented at the C-level (in _macosx.Timer)


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Double new line was intentional here.

@pelson
Copy link
Member

Looks good. I would be happy to merge this once there was a docstring on_setup_canvas.

I know I'm always picky with newlines [and I hate myself for it ;-) ] but normally one would put a double new line between top level objects in a module (classes, functions, groups of constants etc.) and a single new line for the rest (in particular methods). I don't this doing this should block this PR though - I think this is a really helpful change.

@astrofrog 's suggestion of adding a section on pure OO & its benefits is a good idea, but lets keep this implementation and PR separate - there is no need to hold up one with the other.

figure.py now uses pylab_setup() to probe for the backend module to setup the figure canvas.
@astrofrog
Copy link
Contributor

@pelson - agree, the docs can be worked on in a different PR.

@astrofrog
Copy link
Contributor

Should there be a way to optionally make it behave like before, i.e. to disable setting the canvas? e.g. something likeset_canvas or something like that? (that would default toTrue)

EDIT: alternatively, acanvas argument that defaults toauto but can be set toNone or a canvas instance?

@travisbot
Copy link

This pull requestfails (mergedf83fbc9 intocadd152).

@travisbot
Copy link

This pull requestfails (merged88e299b intocadd152).

@pelson
Copy link
Member

Should there be a way to optionally make it behave like before, i.e. to disable setting the canvas?

I'm not that worried by it. The easy answer is for users to simply dofigure.canvas = None if they don't want the canvas which has been given to them. Maybe other have concerns about this?

Unless anybody has any concerns, I will merge this in 18 hours. Good stuff@dmcdougall.

@astrofrog
Copy link
Contributor

@pelson - ok, I don't have a strong opinion about that, so we can just address it if people ask for it. I might open a PR if I run into issues with this some day.

Looking forward to using this! :-)

@dmcdougall
Copy link
MemberAuthor

@astrofrog Thanks for the interest :) Glad I could help make someone's life easier.

@pelson
Copy link
Member

Ah. I'm sorry@dmcdougall - I was a bit eager. Would you mind adding an entry in the what's new section?

@dmcdougall
Copy link
MemberAuthor

@pelson And the changelog, too?

@pelson
Copy link
Member

@pelson And the changelog, too?

My feeling is not. Your notbreaking anything, simply making one use case easier. We only need one entry: whichever you choose will be fine in this case.

@dmcdougall
Copy link
MemberAuthor

I also added a nice example exposing the new change, just because there's no example anywhere else.

@travisbot
Copy link

This pull requestfails (merged8738c1c intocadd152).

pelson added a commit that referenced this pull requestSep 4, 2012
Reduce object-oriented boilerplate for users
@pelsonpelson merged commitdd9cfa4 intomatplotlib:masterSep 4, 2012
@pelson
Copy link
Member

Thanks to@dmcdougall for doing the work & to@astrofrog for suggesting it. This is a real nice addition.

@@ -33,6 +33,7 @@ def _get_toolbar(self, canvas):
toolbar = None
return toolbar

FigureCanvas = FigureManagerGTKAgg
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Shouldn't this be FigureCanvasGTKAgg (and moved after the definition of FigureCanvasGTKAgg). At least this doesn't work.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Oops. Yes. Good spot. I will open another PR to address this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Yes, GtkAgg backend currently does not work, which I believe is due to this.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Sorry! Fixed in#1201.

"""
import matplotlib.backends as mbackends # lazy import
backend_mod = mbackends.pylab_setup()[0]
return backend_mod.FigureCanvas(self)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@verbit made a comment on this line on the commit8bd1d57.@verbit : Would you mind re-iterating your comments here?

Thanks

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

What if the module frompylab_setup()[0] doesn't have a FigureCanvas class. Then the linereturn backend_mod.FigureCanvas(self) would result in an error. So it does with IPython that uses his own backend module but without aFigureCanvas class.

The olddef _current_figure_canvas(self)works because in case it doesn't find the rightFigureCanvas it returnsNone.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@verbit Line 508 oflib/matplotlib/backends/backend_tkagg is

FigureCanvas=FigureCanvasTkAgg

so the return value ofpylab_setup[0] does indeed have aFigureCanvas for this backend. Do you see this behaviour withqt4agg orgtk3agg?

Perhaps this is actually a bug in thetkagg backend?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I saw this behaviour with IPython's custom backend (see:backend_inline.py) that doesn't return aFigureCanvas.
I'm just concerned about the fact, that this new_setup_canvas function might break other applications that don't provide aFigureCanvas class as they are used to the old way.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Fixed in#1214.

efiring added a commit to efiring/matplotlib that referenced this pull requestSep 8, 2012
The attempt to make OO use easier broke the Tkagg and Wx* backends.
efiring added a commit that referenced this pull requestSep 8, 2012
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers
No reviews
Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
v1.2.x
Development

Successfully merging this pull request may close these issues.

9 participants
@dmcdougall@mdboom@efiring@pelson@astrofrog@travisbot@leejjoon@jenshnielsen@verbit

[8]ページ先頭

©2009-2025 Movatter.jp