Skip to content

Commit d459a89

Browse files
committed
Fix saving to pdf and aspect_ratios
fixes #885
1 parent 5646c8d commit d459a89

File tree

3 files changed

+27
-30
lines changed

3 files changed

+27
-30
lines changed

doc/changelog.qmd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ title: Changelog
1212
- In quarto documents make the output `retina` even if the `fig-format` is
1313
`png`.
1414

15+
- Fixed bug where you could not save as pdf if also specifying the
16+
`aspect_ratio`. ({{< issue 885 >}})
17+
1518
## v0.14.0
1619
(2024-10-28)
1720

plotnine/_mpl/_plot_side_space.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ class WHSpaceParts:
6767
wspace: float # mpl.subplotpars.wspace
6868
hspace: float # mpl.subplotpars.hspace
6969

70+
@property
71+
def aspect_ratio(self) -> float:
72+
"""
73+
Aspect ratio of the panels
74+
"""
75+
return (self.h * self.H) / (self.w * self.W)
76+
7077

7178
@dataclass
7279
class _side_spaces(ABC):

plotnine/_mpl/_plotnine_tight_layout.py

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
from __future__ import annotations
1313

1414
import typing
15-
from copy import deepcopy
1615
from dataclasses import dataclass
1716

1817
from ._plot_side_space import LRTBSpaces, WHSpaceParts, calculate_panel_spacing
@@ -56,6 +55,7 @@ class TightParams:
5655
All parameters computed for the plotnine tight layout engine
5756
"""
5857

58+
facet: facet
5959
sides: LRTBSpaces
6060
gullies: WHSpaceParts
6161

@@ -69,32 +69,26 @@ def __post_init__(self):
6969
hspace=self.gullies.hspace,
7070
)
7171

72-
def to_aspect_ratio(
73-
self, facet: facet, ratio: float, parts: WHSpaceParts
74-
) -> TightParams:
75-
"""
76-
Modify TightParams to get a given aspect ratio
77-
"""
78-
current_ratio = (parts.h * parts.H) / (parts.w * parts.W)
79-
increase_aspect_ratio = ratio > current_ratio
80-
if increase_aspect_ratio: # Taller panel
81-
return self._reduce_width(facet, ratio, parts)
82-
else:
83-
return self._reduce_height(facet, ratio, parts)
84-
85-
def _reduce_height(
86-
self, facet: facet, ratio: float, parts: WHSpaceParts
87-
) -> TightParams:
72+
if (ratio := self.facet._aspect_ratio()) is not None:
73+
current_ratio = self.gullies.aspect_ratio
74+
if ratio > current_ratio:
75+
# Increase aspect ratio, taller panels
76+
self._reduce_width(ratio)
77+
elif ratio < current_ratio:
78+
# Increase aspect ratio, wider panels
79+
self._reduce_height(ratio)
80+
81+
def _reduce_height(self, ratio: float):
8882
"""
8983
Reduce the height of axes to get the aspect ratio
9084
"""
91-
self = deepcopy(self)
85+
parts = self.gullies
9286

9387
# New height w.r.t figure height
9488
h1 = ratio * parts.w * (parts.W / parts.H)
9589

9690
# Half of the total vertical reduction w.r.t figure height
97-
dh = (parts.h - h1) * facet.nrow / 2
91+
dh = (parts.h - h1) * self.facet.nrow / 2
9892

9993
# Reduce plot area height
10094
self.params.top -= dh
@@ -104,21 +98,18 @@ def _reduce_height(
10498
# Add more vertical plot margin
10599
self.sides.t.plot_margin += dh
106100
self.sides.b.plot_margin += dh
107-
return self
108101

109-
def _reduce_width(
110-
self, facet: facet, ratio: float, parts: WHSpaceParts
111-
) -> TightParams:
102+
def _reduce_width(self, ratio: float):
112103
"""
113104
Reduce the width of axes to get the aspect ratio
114105
"""
115-
self = deepcopy(self)
106+
parts = self.gullies
116107

117108
# New width w.r.t figure width
118109
w1 = (parts.h * parts.H) / (ratio * parts.W)
119110

120111
# Half of the total horizontal reduction w.r.t figure width
121-
dw = (parts.w - w1) * facet.ncol / 2
112+
dw = (parts.w - w1) * self.facet.ncol / 2
122113

123114
# Reduce width
124115
self.params.left += dw
@@ -128,7 +119,6 @@ def _reduce_width(
128119
# Add more horizontal margin
129120
self.sides.l.plot_margin += dw
130121
self.sides.r.plot_margin += dw
131-
return self
132122

133123

134124
def get_plotnine_tight_layout(pack: LayoutPack) -> TightParams:
@@ -137,10 +127,7 @@ def get_plotnine_tight_layout(pack: LayoutPack) -> TightParams:
137127
"""
138128
sides = LRTBSpaces(pack)
139129
gullies = calculate_panel_spacing(pack, sides)
140-
tight_params = TightParams(sides, gullies)
141-
ratio = pack.facet._aspect_ratio()
142-
if ratio is not None:
143-
tight_params = tight_params.to_aspect_ratio(pack.facet, ratio, gullies)
130+
tight_params = TightParams(pack.facet, sides, gullies)
144131
return tight_params
145132

146133

0 commit comments

Comments
 (0)