diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index aa63514c61ff..887cf97ef140 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -2252,8 +2252,10 @@ def set_default_intervals(self): self.stale = True def get_tick_space(self): - ends = self.axes.transAxes.transform([[0, 0], [1, 0]]) - length = ((ends[1][0] - ends[0][0]) / self.axes.figure.dpi) * 72 + ends = mtransforms.Bbox.from_bounds(0, 0, 1, 1) + ends = ends.transformed(self.axes.transAxes - + self.figure.dpi_scale_trans) + length = ends.width * 72 # There is a heuristic here that the aspect ratio of tick text # is no more than 3:1 size = self._get_tick_label_size('x') * 3 @@ -2512,8 +2514,10 @@ def set_default_intervals(self): self.stale = True def get_tick_space(self): - ends = self.axes.transAxes.transform([[0, 0], [0, 1]]) - length = ((ends[1][1] - ends[0][1]) / self.axes.figure.dpi) * 72 + ends = mtransforms.Bbox.from_bounds(0, 0, 1, 1) + ends = ends.transformed(self.axes.transAxes - + self.figure.dpi_scale_trans) + length = ends.height * 72 # Having a spacing of at least 2 just looks good. size = self._get_tick_label_size('y') * 2 if size > 0: diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index 404179341264..3a5f11957ed8 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -1980,7 +1980,6 @@ def __init__(self, parent, subplotspec, *, self.subplotpars = parent.subplotpars self.dpi_scale_trans = parent.dpi_scale_trans self._axobservers = parent._axobservers - self.dpi = parent.dpi self.canvas = parent.canvas self.transFigure = parent.transFigure self.bbox_relative = None @@ -2001,6 +2000,14 @@ def __init__(self, parent, subplotspec, *, if parent._layoutgrid is not None: self.init_layoutgrid() + @property + def dpi(self): + return self._parent.dpi + + @dpi.setter + def dpi(self, value): + self._parent.dpi = value + def _redo_transform_rel_fig(self, bbox=None): """ Make the transSubfigure bbox relative to Figure transform. diff --git a/lib/matplotlib/tests/baseline_images/test_figure/test_subfigure_scatter_size.png b/lib/matplotlib/tests/baseline_images/test_figure/test_subfigure_scatter_size.png new file mode 100644 index 000000000000..c193b5d0ec22 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_figure/test_subfigure_scatter_size.png differ diff --git a/lib/matplotlib/tests/test_figure.py b/lib/matplotlib/tests/test_figure.py index ccb1381fa5b5..c8458a21118c 100644 --- a/lib/matplotlib/tests/test_figure.py +++ b/lib/matplotlib/tests/test_figure.py @@ -1031,6 +1031,51 @@ def test_subfigure_spanning(): np.testing.assert_allclose(sub_figs[2].bbox.max, [w, h / 3]) +@mpl.style.context('mpl20') +def test_subfigure_ticks(): + # This tests a tick-spacing error that only seems applicable + # when the subfigures are saved to file. It is very hard to replicate + fig = plt.figure(constrained_layout=True, figsize=(10, 3)) + # create left/right subfigs nested in bottom subfig + (subfig_bl, subfig_br) = fig.subfigures(1, 2, wspace=0.01, + width_ratios=[7, 2]) + + # put ax1-ax3 in gridspec of bottom-left subfig + gs = subfig_bl.add_gridspec(nrows=1, ncols=14) + + ax1 = subfig_bl.add_subplot(gs[0, :1]) + ax1.scatter(x=[-56.46881504821776, 24.179891162109396], y=[1500, 3600]) + + ax2 = subfig_bl.add_subplot(gs[0, 1:3], sharey=ax1) + ax2.scatter(x=[-126.5357270050049, 94.68456736755368], y=[1500, 3600]) + ax3 = subfig_bl.add_subplot(gs[0, 3:14], sharey=ax1) + + fig.set_dpi(120) + fig.draw_no_output() + ticks120 = ax2.get_xticks() + fig.set_dpi(300) + fig.draw_no_output() + ticks300 = ax2.get_xticks() + np.testing.assert_allclose(ticks120, ticks300) + + +@image_comparison(['test_subfigure_scatter_size.png'], style='mpl20', + remove_text=True) +def test_subfigure_scatter_size(): + # markers in the left- and right-most subplots should be the same + fig = plt.figure() + gs = fig.add_gridspec(1, 2) + ax0 = fig.add_subplot(gs[1]) + ax0.scatter([1, 2, 3], [1, 2, 3], s=30, marker='s') + ax0.scatter([3, 4, 5], [1, 2, 3], s=[20, 30, 40], marker='s') + + sfig = fig.add_subfigure(gs[0]) + axs = sfig.subplots(1, 2) + for ax in [ax0, axs[0]]: + ax.scatter([1, 2, 3], [1, 2, 3], s=30, marker='s', color='r') + ax.scatter([3, 4, 5], [1, 2, 3], s=[20, 30, 40], marker='s', color='g') + + def test_add_subplot_kwargs(): # fig.add_subplot() always creates new axes, even if axes kwargs differ. fig = plt.figure()