From 04308356fd73c4d3bb511f73943f1b8482b10e60 Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Mon, 2 Aug 2021 16:37:25 -0700 Subject: [PATCH] FIX: calculate dpi instead of relying on it being passed down properly for subfigures. --- .../deprecations/20777-JMK.rst | 7 +++++++ lib/matplotlib/collections.py | 11 +++++++---- .../test_subfigure_scatter_size.png | Bin 0 -> 4605 bytes lib/matplotlib/tests/test_figure.py | 17 +++++++++++++++++ lib/mpl_toolkits/mplot3d/art3d.py | 5 +++-- 5 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 doc/api/next_api_changes/deprecations/20777-JMK.rst create mode 100644 lib/matplotlib/tests/baseline_images/test_figure/test_subfigure_scatter_size.png diff --git a/doc/api/next_api_changes/deprecations/20777-JMK.rst b/doc/api/next_api_changes/deprecations/20777-JMK.rst new file mode 100644 index 000000000000..6214205f966f --- /dev/null +++ b/doc/api/next_api_changes/deprecations/20777-JMK.rst @@ -0,0 +1,7 @@ +dpi keyword argument of collections.set_sizes is removed +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The *dpi* argument of `.PathCollection.set_sizes`, `.PolyCollection.set_sizes`, +`.RegularPolyCollection.set_sizes`, `.CircleCollection.set_sizes` no longer has +an effect. The dpi is determined by *dpi_scale_trans* property of `.FigureBase`, +which works with subfigures. \ No newline at end of file diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py index 736b1f016331..e490b7c907f3 100644 --- a/lib/matplotlib/collections.py +++ b/lib/matplotlib/collections.py @@ -947,6 +947,7 @@ def get_sizes(self): """ return self._sizes + @_api.delete_parameter("3.5", "dpi") def set_sizes(self, sizes, dpi=72.0): """ Set the sizes of each member of the collection. @@ -956,8 +957,6 @@ def set_sizes(self, sizes, dpi=72.0): sizes : ndarray or None The size to set for each element of the collection. The value is the 'area' of the element. - dpi : float, default: 72 - The dpi of the canvas. """ if sizes is None: self._sizes = np.array([]) @@ -965,6 +964,10 @@ def set_sizes(self, sizes, dpi=72.0): else: self._sizes = np.asarray(sizes) self._transforms = np.zeros((len(self._sizes), 3, 3)) + dpi = 72.0 + if self.figure is not None: + trans = self.figure.dpi_scale_trans + dpi = trans.transform(np.array([1, 1]))[0] scale = np.sqrt(self._sizes) * dpi / 72.0 * self._factor self._transforms[:, 0, 0] = scale self._transforms[:, 1, 1] = scale @@ -973,7 +976,7 @@ def set_sizes(self, sizes, dpi=72.0): @artist.allow_rasterization def draw(self, renderer): - self.set_sizes(self._sizes, self.figure.dpi) + self.set_sizes(self._sizes) super().draw(renderer) @@ -1335,7 +1338,7 @@ def get_rotation(self): @artist.allow_rasterization def draw(self, renderer): - self.set_sizes(self._sizes, self.figure.dpi) + self.set_sizes(self._sizes) self._transforms = [ transforms.Affine2D(x).rotate(-self._rotation).get_matrix() for x in self._transforms 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 0000000000000000000000000000000000000000..6e46999e7e2a86f8bc9582ff1d6ea412abdc7561 GIT binary patch literal 4605 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 a_tskHhTy;X6+-{DfNh(-+{(VfefI~Je0wMW literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/test_figure.py b/lib/matplotlib/tests/test_figure.py index ccb1381fa5b5..97f975356854 100644 --- a/lib/matplotlib/tests/test_figure.py +++ b/lib/matplotlib/tests/test_figure.py @@ -1031,6 +1031,23 @@ def test_subfigure_spanning(): np.testing.assert_allclose(sub_figs[2].bbox.max, [w, h / 3]) +@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() diff --git a/lib/mpl_toolkits/mplot3d/art3d.py b/lib/mpl_toolkits/mplot3d/art3d.py index 5c1825b255b2..f9ad0e2ce7cf 100644 --- a/lib/mpl_toolkits/mplot3d/art3d.py +++ b/lib/mpl_toolkits/mplot3d/art3d.py @@ -568,8 +568,9 @@ def set_3d_properties(self, zs, zdir): self._vzs = None self.stale = True + @_api.delete_parameter("3.5", "dpi") def set_sizes(self, sizes, dpi=72.0): - super().set_sizes(sizes, dpi) + super().set_sizes(sizes) if not self._in_draw: self._sizes3d = sizes @@ -607,7 +608,7 @@ def do_3d_projection(self, renderer=None): # we have to special case the sizes because of code in collections.py # as the draw method does - # self.set_sizes(self._sizes, self.figure.dpi) + # self.set_sizes(self._sizes) # so we can not rely on doing the sorting on the way out via get_* if len(self._sizes3d) > 1: