Skip to content

Commit 5bf999a

Browse files
committed
Attach a FigureCanvasBase by default to Figures.
This is particularly useful for headless cases, where one just wants to take advantage of `print_figure`, which is defined on the base class. For example, one can now do for <loop>: figure = Figure() # do some plotting figure.savefig(...) and let `figure` get gc'd at the next loop iteration; a pyplot-based solution would instead have to explicitly close() the figure or reuse it after clf()'ing it. Also simplifies various places in the codebase where we had to handle the case of `.canvas = None` previously.
1 parent 9cffe0e commit 5bf999a

File tree

5 files changed

+18
-30
lines changed

5 files changed

+18
-30
lines changed

lib/matplotlib/artist.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,9 +446,7 @@ def pickable(self):
446446
--------
447447
set_picker, get_picker, pick
448448
"""
449-
return (self.figure is not None and
450-
self.figure.canvas is not None and
451-
self._picker is not None)
449+
return self.figure is not None and self._picker is not None
452450

453451
def pick(self, mouseevent):
454452
"""

lib/matplotlib/axes/_base.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3191,8 +3191,7 @@ def set_xlim(self, left=None, right=None, emit=True, auto=False,
31913191
if other is not self:
31923192
other.set_xlim(self.viewLim.intervalx,
31933193
emit=False, auto=auto)
3194-
if (other.figure != self.figure and
3195-
other.figure.canvas is not None):
3194+
if other.figure != self.figure:
31963195
other.figure.canvas.draw_idle()
31973196
self.stale = True
31983197
return left, right
@@ -3524,8 +3523,7 @@ def set_ylim(self, bottom=None, top=None, emit=True, auto=False,
35243523
if other is not self:
35253524
other.set_ylim(self.viewLim.intervaly,
35263525
emit=False, auto=auto)
3527-
if (other.figure != self.figure and
3528-
other.figure.canvas is not None):
3526+
if other.figure != self.figure:
35293527
other.figure.canvas.draw_idle()
35303528
self.stale = True
35313529
return bottom, top

lib/matplotlib/figure.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import matplotlib.artist as martist
2626
from matplotlib.artist import Artist, allow_rasterization
27+
from matplotlib.backend_bases import FigureCanvasBase
2728
import matplotlib.cbook as cbook
2829
import matplotlib.colorbar as cbar
2930
import matplotlib.image as mimage
@@ -364,7 +365,7 @@ def __init__(self,
364365
self._set_artist_props(self.patch)
365366
self.patch.set_antialiased(False)
366367

367-
self.canvas = None
368+
FigureCanvasBase(self) # set .canvas.
368369
self._suptitle = None
369370

370371
if subplotpars is None:
@@ -398,8 +399,7 @@ def __init__(self,
398399
def _repr_html_(self):
399400
# We can't use "isinstance" here, because then we'd end up importing
400401
# webagg unconditiionally.
401-
if (self.canvas is not None and
402-
'WebAgg' in self.canvas.__class__.__name__):
402+
if 'WebAgg' in type(self.canvas).__name__:
403403
from matplotlib.backends import backend_webagg
404404
return backend_webagg.ipython_inline_display(self)
405405

lib/matplotlib/widgets.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1759,9 +1759,7 @@ def new_axes(self, ax):
17591759
"""Set SpanSelector to operate on a new Axes"""
17601760
self.ax = ax
17611761
if self.canvas is not ax.figure.canvas:
1762-
if self.canvas is not None:
1763-
self.disconnect_events()
1764-
1762+
self.disconnect_events()
17651763
self.canvas = ax.figure.canvas
17661764
self.connect_default_events()
17671765

lib/mpl_toolkits/mplot3d/axes3d.py

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,7 @@ def set_xlim3d(self, left=None, right=None, emit=True, auto=False,
646646
if other is not self:
647647
other.set_xlim(self.xy_viewLim.intervalx,
648648
emit=False, auto=auto)
649-
if (other.figure != self.figure and
650-
other.figure.canvas is not None):
649+
if other.figure != self.figure:
651650
other.figure.canvas.draw_idle()
652651
self.stale = True
653652
return left, right
@@ -704,8 +703,7 @@ def set_ylim3d(self, bottom=None, top=None, emit=True, auto=False,
704703
if other is not self:
705704
other.set_ylim(self.xy_viewLim.intervaly,
706705
emit=False, auto=auto)
707-
if (other.figure != self.figure and
708-
other.figure.canvas is not None):
706+
if other.figure != self.figure:
709707
other.figure.canvas.draw_idle()
710708
self.stale = True
711709
return bottom, top
@@ -762,8 +760,7 @@ def set_zlim3d(self, bottom=None, top=None, emit=True, auto=False,
762760
if other is not self:
763761
other.set_zlim(self.zz_viewLim.intervalx,
764762
emit=False, auto=auto)
765-
if (other.figure != self.figure and
766-
other.figure.canvas is not None):
763+
if other.figure != self.figure:
767764
other.figure.canvas.draw_idle()
768765
self.stale = True
769766
return bottom, top
@@ -1062,17 +1059,14 @@ def mouse_init(self, rotate_btn=1, zoom_btn=3):
10621059
10631060
"""
10641061
self.button_pressed = None
1065-
canv = self.figure.canvas
1066-
if canv is not None:
1067-
c1 = canv.mpl_connect('motion_notify_event', self._on_move)
1068-
c2 = canv.mpl_connect('button_press_event', self._button_press)
1069-
c3 = canv.mpl_connect('button_release_event', self._button_release)
1070-
self._cids = [c1, c2, c3]
1071-
else:
1072-
warnings.warn(
1073-
"Axes3D.figure.canvas is 'None', mouse rotation disabled. "
1074-
"Set canvas then call Axes3D.mouse_init().")
1075-
1062+
self._cids = [
1063+
self.figure.canvas.mpl_connect(
1064+
'motion_notify_event', self._on_move),
1065+
self.figure.canvas.mpl_connect(
1066+
'button_press_event', self._button_press),
1067+
self.figure.canvas.mpl_connect(
1068+
'button_release_event', self._button_release),
1069+
]
10761070
# coerce scalars into array-like, then convert into
10771071
# a regular list to avoid comparisons against None
10781072
# which breaks in recent versions of numpy.

0 commit comments

Comments
 (0)