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

Better object-oriented interface for users #1457

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 11 additions & 1 deletion lib/matplotlib/figure.py
Expand Up @@ -318,7 +318,6 @@ def __init__(self,
self.patch.set_aa(False)

self._hold = rcParams['axes.hold']
self.canvas = None

if subplotpars is None:
subplotpars = SubplotParams()
Expand All @@ -327,9 +326,17 @@ def __init__(self,
self.set_tight_layout(tight_layout)

self._axstack = AxesStack() # track all figure axes and current axes
self._axobservers = []
self.canvas = self._setup_canvas()
Copy link
Member

Choose a reason for hiding this comment

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

So the original problem with your first PR was that, if a user wants to setup a figure using a backend that isn't the one in rcParams['backend'] they will have instantiated two different canvases:

For example, suppose my rcParams['backend'] was TkAgg and I wanted to create a PDF canvas for my figure, I would have to create the figure instance (which creates a TkAgg canvas instance) before I can tell it to use my own PDFCanvas instance.

I don't use the OO interface all too much (pyplot is fine for me - I use the helpers it gives me and I don't rely on the state machine too much), so I might be completely off the mark with these comments. Please tell me so in no uncertain terms 😉 .

Cheers,

Copy link
Member Author

Choose a reason for hiding this comment

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

@pelson I don't think that's right. I think the original issue was that I assumed the construction of the canvas was a standard interface. This was not the case for TkAgg, requiring an extra kwarg. In the original PR, I set up the canvas corresponding to the value in rcParams['backend']. The following snippet might help:

import matplotlib
matplotlib.use('gtkagg')  # this sets rcParams['backend'] = 'gtkagg'
from matplotlib.figure import Figure  # set up the canvas defined by the backend above

I do exactly the same here, but now I'm using the manager to bypass a lot of the variation in backend set-up that pyplot makes so opaque.

self.clf()
self._cachedRenderer = None

def _setup_canvas(self):
import matplotlib.backends as mbackends
backend_mod, _, _, _ = mbackends.pylab_setup()
manager = backend_mod.new_figure_manager_given_figure(1, self)
return manager.canvas

def show(self, warn=True):
"""
If using a GUI backend with pyplot, display the figure window.
Expand Down Expand Up @@ -361,6 +368,9 @@ def show(self, warn=True):
"matplotlib is currently using a non-GUI backend, "
"so cannot show the figure")

def update(self):
self.canvas.draw_idle()

def _get_axes(self):
return self._axstack.as_list()

Expand Down