Skip to content

Commit 9dc3152

Browse files
committed
Inherit figure_size/dpi onto insets and Compose items
An inset_element's `obj` and a Compose's items share the parent's matplotlib figure, but their own theme.figure_size and dpi default independently. That caused the inset's `figure_size` themeable to resize the host figure, the inset's dpi to leak into rcParams during its draw context, and layout sites (`_plot_side_space`, `_composition_side_space`, `margin.setup`) to read inconsistent values. A new `theme._inherit_figure_props` method copies these figure-owner-only values from a parent theme. inset_element._setup calls it on the inset's theme; Compose.draw calls it on every item alongside the existing zorder propagation. Nested cases compose by recursion.
1 parent 208068e commit 9dc3152

3 files changed

Lines changed: 28 additions & 3 deletions

File tree

plotnine/composition/_compose.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -550,11 +550,14 @@ def draw(self, *, show: bool = False) -> Figure:
550550
def _draw(cmp):
551551
figure = cmp._setup()
552552

553-
# Propagate the composition's zorder to its direct children
554-
# before they draw, so axes are created at the right layer.
555-
# Recursion carries the value down sub-compositions.
553+
# Propagate the composition's zorder & figure-owner-only
554+
# theme props to its direct children before they draw, so
555+
# axes are created at the right layer and child layout uses
556+
# the composition's figure_size/dpi. Recursion carries the
557+
# values down sub-compositions.
556558
for item in cmp:
557559
item._zorder = cmp._zorder
560+
item.theme._inherit_figure_props(cmp.theme)
558561

559562
cmp._draw_plots()
560563

plotnine/composition/_inset_element.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ class inset_element:
4747
- ``"plot"`` — the panel plus axes, labels, titles, captions
4848
and legends
4949
- ``"full"`` — everything the host plot occupies plus plot margin
50+
51+
Notes
52+
-----
53+
`figure_size` and `dpi` set on the inset's theme are ignored. The
54+
inset shares the host's figure, so these values come from the host
55+
theme. The canvas size of the inset is determined by the bounding
56+
box and the area it is `align_to`.
5057
"""
5158

5259
obj: ggplot | Compose
@@ -88,6 +95,7 @@ def _setup(self, parent: ggplot, index: int):
8895
"""
8996
self.obj.figure = parent.figure
9097
self.obj._zorder = parent._zorder + index * INSET_ZORDER_STEP
98+
self.obj.theme._inherit_figure_props(parent.theme)
9199

92100
def draw(self):
93101
"""

plotnine/themes/theme.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,20 @@ def to_retina(self) -> theme:
472472
self._is_retina = True
473473
return self
474474

475+
def _inherit_figure_props(self, other: theme) -> None:
476+
"""
477+
Copy themeables that modify the figure
478+
479+
Used when this theme is attached to a plot that does not own
480+
its figure (an inset, or a member of a composition). Such a plot
481+
has no figure to size or DPI; the values must come from the
482+
figure's owner.
483+
"""
484+
self += theme(
485+
figure_size=other.getp("figure_size"),
486+
dpi=other.getp("dpi"),
487+
)
488+
475489
def _smart_title_and_subtitle_ha(
476490
self, title: str | None, subtitle: str | None
477491
):

0 commit comments

Comments
 (0)