Skip to content

Commit b61e76a

Browse files
authored
Merge pull request #20771 from jklymak/fix-tickspacing-sublayout
FIX: tickspacing for subfigures
2 parents 030ca97 + 8a3ce1d commit b61e76a

File tree

4 files changed

+61
-5
lines changed

4 files changed

+61
-5
lines changed

lib/matplotlib/axis.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -2252,8 +2252,10 @@ def set_default_intervals(self):
22522252
self.stale = True
22532253

22542254
def get_tick_space(self):
2255-
ends = self.axes.transAxes.transform([[0, 0], [1, 0]])
2256-
length = ((ends[1][0] - ends[0][0]) / self.axes.figure.dpi) * 72
2255+
ends = mtransforms.Bbox.from_bounds(0, 0, 1, 1)
2256+
ends = ends.transformed(self.axes.transAxes -
2257+
self.figure.dpi_scale_trans)
2258+
length = ends.width * 72
22572259
# There is a heuristic here that the aspect ratio of tick text
22582260
# is no more than 3:1
22592261
size = self._get_tick_label_size('x') * 3
@@ -2512,8 +2514,10 @@ def set_default_intervals(self):
25122514
self.stale = True
25132515

25142516
def get_tick_space(self):
2515-
ends = self.axes.transAxes.transform([[0, 0], [0, 1]])
2516-
length = ((ends[1][1] - ends[0][1]) / self.axes.figure.dpi) * 72
2517+
ends = mtransforms.Bbox.from_bounds(0, 0, 1, 1)
2518+
ends = ends.transformed(self.axes.transAxes -
2519+
self.figure.dpi_scale_trans)
2520+
length = ends.height * 72
25172521
# Having a spacing of at least 2 just looks good.
25182522
size = self._get_tick_label_size('y') * 2
25192523
if size > 0:

lib/matplotlib/figure.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -1995,7 +1995,6 @@ def __init__(self, parent, subplotspec, *,
19951995
self.subplotpars = parent.subplotpars
19961996
self.dpi_scale_trans = parent.dpi_scale_trans
19971997
self._axobservers = parent._axobservers
1998-
self.dpi = parent.dpi
19991998
self.canvas = parent.canvas
20001999
self.transFigure = parent.transFigure
20012000
self.bbox_relative = None
@@ -2016,6 +2015,14 @@ def __init__(self, parent, subplotspec, *,
20162015
if parent._layoutgrid is not None:
20172016
self.init_layoutgrid()
20182017

2018+
@property
2019+
def dpi(self):
2020+
return self._parent.dpi
2021+
2022+
@dpi.setter
2023+
def dpi(self, value):
2024+
self._parent.dpi = value
2025+
20192026
def _redo_transform_rel_fig(self, bbox=None):
20202027
"""
20212028
Make the transSubfigure bbox relative to Figure transform.

lib/matplotlib/tests/test_figure.py

+45
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,51 @@ def test_subfigure_spanning():
10311031
np.testing.assert_allclose(sub_figs[2].bbox.max, [w, h / 3])
10321032

10331033

1034+
@mpl.style.context('mpl20')
1035+
def test_subfigure_ticks():
1036+
# This tests a tick-spacing error that only seems applicable
1037+
# when the subfigures are saved to file. It is very hard to replicate
1038+
fig = plt.figure(constrained_layout=True, figsize=(10, 3))
1039+
# create left/right subfigs nested in bottom subfig
1040+
(subfig_bl, subfig_br) = fig.subfigures(1, 2, wspace=0.01,
1041+
width_ratios=[7, 2])
1042+
1043+
# put ax1-ax3 in gridspec of bottom-left subfig
1044+
gs = subfig_bl.add_gridspec(nrows=1, ncols=14)
1045+
1046+
ax1 = subfig_bl.add_subplot(gs[0, :1])
1047+
ax1.scatter(x=[-56.46881504821776, 24.179891162109396], y=[1500, 3600])
1048+
1049+
ax2 = subfig_bl.add_subplot(gs[0, 1:3], sharey=ax1)
1050+
ax2.scatter(x=[-126.5357270050049, 94.68456736755368], y=[1500, 3600])
1051+
ax3 = subfig_bl.add_subplot(gs[0, 3:14], sharey=ax1)
1052+
1053+
fig.set_dpi(120)
1054+
fig.draw_no_output()
1055+
ticks120 = ax2.get_xticks()
1056+
fig.set_dpi(300)
1057+
fig.draw_no_output()
1058+
ticks300 = ax2.get_xticks()
1059+
np.testing.assert_allclose(ticks120, ticks300)
1060+
1061+
1062+
@image_comparison(['test_subfigure_scatter_size.png'], style='mpl20',
1063+
remove_text=True)
1064+
def test_subfigure_scatter_size():
1065+
# markers in the left- and right-most subplots should be the same
1066+
fig = plt.figure()
1067+
gs = fig.add_gridspec(1, 2)
1068+
ax0 = fig.add_subplot(gs[1])
1069+
ax0.scatter([1, 2, 3], [1, 2, 3], s=30, marker='s')
1070+
ax0.scatter([3, 4, 5], [1, 2, 3], s=[20, 30, 40], marker='s')
1071+
1072+
sfig = fig.add_subfigure(gs[0])
1073+
axs = sfig.subplots(1, 2)
1074+
for ax in [ax0, axs[0]]:
1075+
ax.scatter([1, 2, 3], [1, 2, 3], s=30, marker='s', color='r')
1076+
ax.scatter([3, 4, 5], [1, 2, 3], s=[20, 30, 40], marker='s', color='g')
1077+
1078+
10341079
def test_add_subplot_kwargs():
10351080
# fig.add_subplot() always creates new axes, even if axes kwargs differ.
10361081
fig = plt.figure()

0 commit comments

Comments
 (0)