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

Appearance settings

Commit 7f3738d

Browse filesBrowse files
authored
Merge pull request #28550 from rcomer/remove-figure-use
Remove internal use of `Artist.figure`
2 parents 4310fff + 0c911b3 commit 7f3738d
Copy full SHA for 7f3738d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Dismiss banner
Expand file treeCollapse file tree

45 files changed

+294
-245
lines changed

‎lib/matplotlib/_constrained_layout.py

Copy file name to clipboardExpand all lines: lib/matplotlib/_constrained_layout.py
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ def get_pos_and_bbox(ax, renderer):
634634
bbox : `~matplotlib.transforms.Bbox`
635635
Tight bounding box in figure coordinates.
636636
"""
637-
fig = ax.figure
637+
fig = ax.get_figure(root=False)
638638
pos = ax.get_position(original=True)
639639
# pos is in panel co-ords, but we need in figure for the layout
640640
pos = pos.transformed(fig.transSubfigure - fig.transFigure)
@@ -706,7 +706,7 @@ def reposition_colorbar(layoutgrids, cbax, renderer, *, offset=None):
706706

707707
parents = cbax._colorbar_info['parents']
708708
gs = parents[0].get_gridspec()
709-
fig = cbax.figure
709+
fig = cbax.get_figure(root=False)
710710
trans_fig_to_subfig = fig.transFigure - fig.transSubfigure
711711

712712
cb_rspans, cb_cspans = get_cb_parent_spans(cbax)

‎lib/matplotlib/artist.py

Copy file name to clipboardExpand all lines: lib/matplotlib/artist.py
+9-8Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ def draw_wrapper(artist, renderer):
7474
renderer.stop_filter(artist.get_agg_filter())
7575
if artist.get_rasterized():
7676
renderer._raster_depth -= 1
77-
if (renderer._rasterizing and artist.figure and
78-
artist.figure.suppressComposite):
77+
if (renderer._rasterizing and (fig := artist.get_figure(root=True)) and
78+
fig.suppressComposite):
7979
# restart rasterizing to prevent merging
8080
renderer.stop_rasterizing()
8181
renderer.start_rasterizing()
@@ -247,9 +247,9 @@ def remove(self):
247247
self.axes = None # decouple the artist from the Axes
248248
_ax_flag = True
249249

250-
if self.figure:
250+
if (fig := self.get_figure(root=False)) is not None:
251251
if not _ax_flag:
252-
self.figure.stale = True
252+
fig.stale = True
253253
self._parent_figure = None
254254

255255
else:
@@ -472,8 +472,9 @@ def _different_canvas(self, event):
472472
return False, {}
473473
# subclass-specific implementation follows
474474
"""
475-
return (getattr(event, "canvas", None) is not None and self.figure is not None
476-
and event.canvas is not self.figure.canvas)
475+
return (getattr(event, "canvas", None) is not None
476+
and (fig := self.get_figure(root=True)) is not None
477+
and event.canvas is not fig.canvas)
477478

478479
def contains(self, mouseevent):
479480
"""
@@ -503,7 +504,7 @@ def pickable(self):
503504
--------
504505
.Artist.set_picker, .Artist.get_picker, .Artist.pick
505506
"""
506-
return self.figure is not None and self._picker is not None
507+
return self.get_figure(root=False) is not None and self._picker is not None
507508

508509
def pick(self, mouseevent):
509510
"""
@@ -525,7 +526,7 @@ def pick(self, mouseevent):
525526
else:
526527
inside, prop = self.contains(mouseevent)
527528
if inside:
528-
PickEvent("pick_event", self.figure.canvas,
529+
PickEvent("pick_event", self.get_figure(root=True).canvas,
529530
mouseevent, self, **prop)._process()
530531

531532
# Pick children

‎lib/matplotlib/artist.pyi

Copy file name to clipboardExpand all lines: lib/matplotlib/artist.pyi
+6-1Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ from .transforms import (
1515
import numpy as np
1616

1717
from collections.abc import Callable, Iterable
18-
from typing import Any, NamedTuple, TextIO, overload, TypeVar
18+
from typing import Any, Literal, NamedTuple, TextIO, overload, TypeVar
1919
from numpy.typing import ArrayLike
2020

2121
_T_Artist = TypeVar("_T_Artist", bound=Artist)
@@ -88,6 +88,11 @@ class Artist:
8888
) -> None: ...
8989
def set_path_effects(self, path_effects: list[AbstractPathEffect]) -> None: ...
9090
def get_path_effects(self) -> list[AbstractPathEffect]: ...
91+
@overload
92+
def get_figure(self, root: Literal[True]) -> Figure | None: ...
93+
@overload
94+
def get_figure(self, root: Literal[False]) -> Figure | SubFigure | None: ...
95+
@overload
9196
def get_figure(self, root: bool = ...) -> Figure | SubFigure | None: ...
9297
def set_figure(self, fig: Figure | SubFigure) -> None: ...
9398
def set_clip_box(self, clipbox: BboxBase | None) -> None: ...

‎lib/matplotlib/axes/_axes.py

Copy file name to clipboardExpand all lines: lib/matplotlib/axes/_axes.py
+4-3Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -406,8 +406,9 @@ def inset_axes(self, bounds, *, transform=None, zorder=5, **kwargs):
406406
# This puts the rectangle into figure-relative coordinates.
407407
inset_locator = _TransformedBoundsLocator(bounds, transform)
408408
bounds = inset_locator(self, None).bounds
409-
projection_class, pkw = self.figure._process_projection_requirements(**kwargs)
410-
inset_ax = projection_class(self.figure, bounds, zorder=zorder, **pkw)
409+
fig = self.get_figure(root=False)
410+
projection_class, pkw = fig._process_projection_requirements(**kwargs)
411+
inset_ax = projection_class(fig, bounds, zorder=zorder, **pkw)
411412

412413
# this locator lets the axes move if in data coordinates.
413414
# it gets called in `ax.apply_aspect() (of all places)
@@ -517,7 +518,7 @@ def indicate_inset(self, bounds, inset_ax=None, *, transform=None,
517518

518519
# decide which two of the lines to keep visible....
519520
pos = inset_ax.get_position()
520-
bboxins = pos.transformed(self.figure.transSubfigure)
521+
bboxins = pos.transformed(self.get_figure(root=False).transSubfigure)
521522
rectbbox = mtransforms.Bbox.from_bounds(
522523
*bounds
523524
).transformed(transform)

‎lib/matplotlib/axes/_base.py

Copy file name to clipboardExpand all lines: lib/matplotlib/axes/_base.py
+35-24Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ def __call__(self, ax, renderer):
115115
# time as transSubfigure may otherwise change after this is evaluated.
116116
return mtransforms.TransformedBbox(
117117
mtransforms.Bbox.from_bounds(*self._bounds),
118-
self._transform - ax.figure.transSubfigure)
118+
self._transform - ax.get_figure(root=False).transSubfigure)
119119

120120

121121
def _process_plot_format(fmt, *, ambiguous_fmt_datakey=False):
@@ -788,7 +788,7 @@ def get_subplotspec(self):
788788
def set_subplotspec(self, subplotspec):
789789
"""Set the `.SubplotSpec`. associated with the subplot."""
790790
self._subplotspec = subplotspec
791-
self._set_position(subplotspec.get_position(self.figure))
791+
self._set_position(subplotspec.get_position(self.get_figure(root=False)))
792792

793793
def get_gridspec(self):
794794
"""Return the `.GridSpec` associated with the subplot, or None."""
@@ -959,8 +959,9 @@ def get_xaxis_text1_transform(self, pad_points):
959959
"""
960960
labels_align = mpl.rcParams["xtick.alignment"]
961961
return (self.get_xaxis_transform(which='tick1') +
962-
mtransforms.ScaledTranslation(0, -1 * pad_points / 72,
963-
self.figure.dpi_scale_trans),
962+
mtransforms.ScaledTranslation(
963+
0, -1 * pad_points / 72,
964+
self.get_figure(root=False).dpi_scale_trans),
964965
"top", labels_align)
965966

966967
def get_xaxis_text2_transform(self, pad_points):
@@ -985,8 +986,9 @@ def get_xaxis_text2_transform(self, pad_points):
985986
"""
986987
labels_align = mpl.rcParams["xtick.alignment"]
987988
return (self.get_xaxis_transform(which='tick2') +
988-
mtransforms.ScaledTranslation(0, pad_points / 72,
989-
self.figure.dpi_scale_trans),
989+
mtransforms.ScaledTranslation(
990+
0, pad_points / 72,
991+
self.get_figure(root=False).dpi_scale_trans),
990992
"bottom", labels_align)
991993

992994
def get_yaxis_transform(self, which='grid'):
@@ -1039,8 +1041,9 @@ def get_yaxis_text1_transform(self, pad_points):
10391041
"""
10401042
labels_align = mpl.rcParams["ytick.alignment"]
10411043
return (self.get_yaxis_transform(which='tick1') +
1042-
mtransforms.ScaledTranslation(-1 * pad_points / 72, 0,
1043-
self.figure.dpi_scale_trans),
1044+
mtransforms.ScaledTranslation(
1045+
-1 * pad_points / 72, 0,
1046+
self.get_figure(root=False).dpi_scale_trans),
10441047
labels_align, "right")
10451048

10461049
def get_yaxis_text2_transform(self, pad_points):
@@ -1065,8 +1068,9 @@ def get_yaxis_text2_transform(self, pad_points):
10651068
"""
10661069
labels_align = mpl.rcParams["ytick.alignment"]
10671070
return (self.get_yaxis_transform(which='tick2') +
1068-
mtransforms.ScaledTranslation(pad_points / 72, 0,
1069-
self.figure.dpi_scale_trans),
1071+
mtransforms.ScaledTranslation(
1072+
pad_points / 72, 0,
1073+
self.get_figure(root=False).dpi_scale_trans),
10701074
labels_align, "left")
10711075

10721076
def _update_transScale(self):
@@ -1173,7 +1177,7 @@ def get_axes_locator(self):
11731177

11741178
def _set_artist_props(self, a):
11751179
"""Set the boilerplate props for artists added to Axes."""
1176-
a.set_figure(self.figure)
1180+
a.set_figure(self.get_figure(root=False))
11771181
if not a.is_transform_set():
11781182
a.set_transform(self.transData)
11791183

@@ -1347,7 +1351,7 @@ def __clear(self):
13471351
# the other artists. We use the frame to draw the edges so we are
13481352
# setting the edgecolor to None.
13491353
self.patch = self._gen_axes_patch()
1350-
self.patch.set_figure(self.figure)
1354+
self.patch.set_figure(self.get_figure(root=False))
13511355
self.patch.set_facecolor(self._facecolor)
13521356
self.patch.set_edgecolor('none')
13531357
self.patch.set_linewidth(0)
@@ -1522,7 +1526,7 @@ def _set_title_offset_trans(self, title_offset_points):
15221526
"""
15231527
self.titleOffsetTrans = mtransforms.ScaledTranslation(
15241528
0.0, title_offset_points / 72,
1525-
self.figure.dpi_scale_trans)
1529+
self.get_figure(root=False).dpi_scale_trans)
15261530
for _title in (self.title, self._left_title, self._right_title):
15271531
_title.set_transform(self.transAxes + self.titleOffsetTrans)
15281532
_title.set_clip_box(None)
@@ -1937,7 +1941,7 @@ def apply_aspect(self, position=None):
19371941
self._set_position(position, which='active')
19381942
return
19391943

1940-
trans = self.get_figure().transSubfigure
1944+
trans = self.get_figure(root=False).transSubfigure
19411945
bb = mtransforms.Bbox.unit().transformed(trans)
19421946
# this is the physical aspect of the panel (or figure):
19431947
fig_aspect = bb.height / bb.width
@@ -2274,7 +2278,7 @@ def add_child_axes(self, ax):
22742278

22752279
self.child_axes.append(ax)
22762280
ax._remove_method = functools.partial(
2277-
self.figure._remove_axes, owners=[self.child_axes])
2281+
self.get_figure(root=False)._remove_axes, owners=[self.child_axes])
22782282
self.stale = True
22792283
return ax
22802284

@@ -3022,7 +3026,8 @@ def _update_title_position(self, renderer):
30223026
axs = set()
30233027
axs.update(self.child_axes)
30243028
axs.update(self._twinned_axes.get_siblings(self))
3025-
axs.update(self.figure._align_label_groups['title'].get_siblings(self))
3029+
axs.update(
3030+
self.get_figure(root=False)._align_label_groups['title'].get_siblings(self))
30263031

30273032
for ax in self.child_axes: # Child positions must be updated first.
30283033
locator = ax.get_axes_locator()
@@ -3108,7 +3113,7 @@ def draw(self, renderer):
31083113
for _axis in self._axis_map.values():
31093114
artists.remove(_axis)
31103115

3111-
if not self.figure.canvas.is_saving():
3116+
if not self.get_figure(root=True).canvas.is_saving():
31123117
artists = [
31133118
a for a in artists
31143119
if not a.get_animated() or isinstance(a, mimage.AxesImage)]
@@ -3136,10 +3141,10 @@ def draw(self, renderer):
31363141
artists = [self.patch] + artists
31373142

31383143
if artists_rasterized:
3139-
_draw_rasterized(self.figure, artists_rasterized, renderer)
3144+
_draw_rasterized(self.get_figure(root=True), artists_rasterized, renderer)
31403145

31413146
mimage._draw_list_compositing_images(
3142-
renderer, self, artists, self.figure.suppressComposite)
3147+
renderer, self, artists, self.get_figure(root=True).suppressComposite)
31433148

31443149
renderer.close_group('axes')
31453150
self.stale = False
@@ -3148,7 +3153,7 @@ def draw_artist(self, a):
31483153
"""
31493154
Efficiently redraw a single artist.
31503155
"""
3151-
a.draw(self.figure.canvas.get_renderer())
3156+
a.draw(self.get_figure(root=True).canvas.get_renderer())
31523157

31533158
def redraw_in_frame(self):
31543159
"""
@@ -3158,7 +3163,7 @@ def redraw_in_frame(self):
31583163
for artist in [*self._axis_map.values(),
31593164
self.title, self._left_title, self._right_title]:
31603165
stack.enter_context(artist._cm_set(visible=False))
3161-
self.draw(self.figure.canvas.get_renderer())
3166+
self.draw(self.get_figure(root=True).canvas.get_renderer())
31623167

31633168
# Axes rectangle characteristics
31643169

@@ -4466,7 +4471,7 @@ def get_tightbbox(self, renderer=None, call_axes_locator=True,
44664471

44674472
bb = []
44684473
if renderer is None:
4469-
renderer = self.figure._get_renderer()
4474+
renderer = self.get_figure(root=True)._get_renderer()
44704475

44714476
if not self.get_visible():
44724477
return None
@@ -4517,9 +4522,9 @@ def _make_twin_axes(self, *args, **kwargs):
45174522
raise ValueError("Twinned Axes may share only one axis")
45184523
ss = self.get_subplotspec()
45194524
if ss:
4520-
twin = self.figure.add_subplot(ss, *args, **kwargs)
4525+
twin = self.get_figure(root=False).add_subplot(ss, *args, **kwargs)
45214526
else:
4522-
twin = self.figure.add_axes(
4527+
twin = self.get_figure(root=False).add_axes(
45234528
self.get_position(True), *args, **kwargs,
45244529
axes_locator=_TransformedBoundsLocator(
45254530
[0, 0, 1, 1], self.transAxes))
@@ -4748,6 +4753,12 @@ def __init__(self, figure, artists):
47484753
self.figure = figure
47494754
self.artists = artists
47504755

4756+
def get_figure(self, root=False):
4757+
if root:
4758+
return self.figure.get_figure(root=True)
4759+
else:
4760+
return self.figure
4761+
47514762
@martist.allow_rasterization
47524763
def draw(self, renderer):
47534764
for a in self.artists:

‎lib/matplotlib/axes/_secondary_axes.py

Copy file name to clipboardExpand all lines: lib/matplotlib/axes/_secondary_axes.py
+3-2Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,14 @@ def __init__(self, parent, orientation, location, functions, transform=None,
2727
self._orientation = orientation
2828
self._ticks_set = False
2929

30+
fig = self._parent.get_figure(root=False)
3031
if self._orientation == 'x':
31-
super().__init__(self._parent.figure, [0, 1., 1, 0.0001], **kwargs)
32+
super().__init__(fig, [0, 1., 1, 0.0001], **kwargs)
3233
self._axis = self.xaxis
3334
self._locstrings = ['top', 'bottom']
3435
self._otherstrings = ['left', 'right']
3536
else: # 'y'
36-
super().__init__(self._parent.figure, [0, 1., 0.0001, 1], **kwargs)
37+
super().__init__(fig, [0, 1., 0.0001, 1], **kwargs)
3738
self._axis = self.yaxis
3839
self._locstrings = ['right', 'left']
3940
self._otherstrings = ['top', 'bottom']

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.