From b6694f43e5be64b923a4ecb1eb060856af861bf4 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Fri, 15 Sep 2023 19:09:23 +0200 Subject: [PATCH] Fix axh{line,span} on polar axes. For axhline, set the underlying path's _interpolation_steps to GRIDLINE_INTERPOLATION_STEPS (180), which amounts to using the same logic to draw it as for drawing gridlines. This ensures that a polar axhline goes (due to interpolation) around the whole circle, rather than being a trivial line connecting a point to itself. Also update axvline for consistency. (Note that _interpolation_steps has is ignored for rectilinear transforms and thus the change doesn't slow down the common, rectilinear case.) Increase the number of interpolation steps of ax{v,h}span likewise to GRIDLINE_INTERPOLATION_STEPS (again for consistency), and more importantly switch them to using Rectangle rather than Polygon, so that a polar axhspan is drawn as an annulus. This is necessary due to a separate "bug", whereby the CLOSEPOLY step on a Polygon would generate (effectively) a segment that's unfortunately ignored by _interpolation_steps (as it doesn't appear explicitly), whereas Rectangle explicitly includes the closing (4th) segment before emitting a CLOSEPOLY. --- .../next_api_changes/behavior/26788-AL.rst | 6 +++++ doc/users/next_whats_new/polar-line-spans.rst | 5 ++++ lib/matplotlib/axes/_axes.py | 25 ++++++++++++++---- .../test_axes/axhvlinespan_interpolation.png | Bin 0 -> 28240 bytes lib/matplotlib/tests/test_axes.py | 12 +++++++++ lib/matplotlib/tests/test_path.py | 6 ++--- lib/matplotlib/transforms.py | 13 +++++++++ lib/matplotlib/widgets.py | 12 +++------ 8 files changed, 63 insertions(+), 16 deletions(-) create mode 100644 doc/api/next_api_changes/behavior/26788-AL.rst create mode 100644 doc/users/next_whats_new/polar-line-spans.rst create mode 100644 lib/matplotlib/tests/baseline_images/test_axes/axhvlinespan_interpolation.png diff --git a/doc/api/next_api_changes/behavior/26788-AL.rst b/doc/api/next_api_changes/behavior/26788-AL.rst new file mode 100644 index 000000000000..14573e870843 --- /dev/null +++ b/doc/api/next_api_changes/behavior/26788-AL.rst @@ -0,0 +1,6 @@ +``axvspan`` and ``axhspan`` now return ``Rectangle``\s, not ``Polygons`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This change allows using `~.Axes.axhspan` to draw an annulus on polar axes. + +This change also affects other elements built via `~.Axes.axvspan` and +`~.Axes.axhspan`, such as ``Slider.poly``. diff --git a/doc/users/next_whats_new/polar-line-spans.rst b/doc/users/next_whats_new/polar-line-spans.rst new file mode 100644 index 000000000000..47bb382dbdbf --- /dev/null +++ b/doc/users/next_whats_new/polar-line-spans.rst @@ -0,0 +1,5 @@ +``axhline`` and ``axhspan`` on polar axes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +... now draw circles and circular arcs (`~.Axes.axhline`) or annuli and wedges +(`~.Axes.axhspan`). diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 9997e660f40c..0fcabac8c7c0 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -783,6 +783,7 @@ def axhline(self, y=0, xmin=0, xmax=1, **kwargs): trans = self.get_yaxis_transform(which='grid') l = mlines.Line2D([xmin, xmax], [y, y], transform=trans, **kwargs) self.add_line(l) + l.get_path()._interpolation_steps = mpl.axis.GRIDLINE_INTERPOLATION_STEPS if scaley: self._request_autoscale_view("y") return l @@ -851,6 +852,7 @@ def axvline(self, x=0, ymin=0, ymax=1, **kwargs): trans = self.get_xaxis_transform(which='grid') l = mlines.Line2D([x, x], [ymin, ymax], transform=trans, **kwargs) self.add_line(l) + l.get_path()._interpolation_steps = mpl.axis.GRIDLINE_INTERPOLATION_STEPS if scalex: self._request_autoscale_view("x") return l @@ -978,10 +980,17 @@ def axhspan(self, ymin, ymax, xmin=0, xmax=1, **kwargs): self._check_no_units([xmin, xmax], ['xmin', 'xmax']) (ymin, ymax), = self._process_unit_info([("y", [ymin, ymax])], kwargs) - verts = (xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin) - p = mpatches.Polygon(verts, **kwargs) + p = mpatches.Rectangle((xmin, ymin), xmax - xmin, ymax - ymin, **kwargs) p.set_transform(self.get_yaxis_transform(which="grid")) + # For Rectangles and non-separable transforms, add_patch can be buggy + # and update the x limits even though it shouldn't do so for an + # yaxis_transformed patch, so undo that update. + ix = self.dataLim.intervalx + mx = self.dataLim.minposx self.add_patch(p) + self.dataLim.intervalx = ix + self.dataLim.minposx = mx + p.get_path()._interpolation_steps = mpl.axis.GRIDLINE_INTERPOLATION_STEPS self._request_autoscale_view("y") return p @@ -1034,11 +1043,17 @@ def axvspan(self, xmin, xmax, ymin=0, ymax=1, **kwargs): self._check_no_units([ymin, ymax], ['ymin', 'ymax']) (xmin, xmax), = self._process_unit_info([("x", [xmin, xmax])], kwargs) - verts = [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)] - p = mpatches.Polygon(verts, **kwargs) + p = mpatches.Rectangle((xmin, ymin), xmax - xmin, ymax - ymin, **kwargs) p.set_transform(self.get_xaxis_transform(which="grid")) - p.get_path()._interpolation_steps = 100 + # For Rectangles and non-separable transforms, add_patch can be buggy + # and update the y limits even though it shouldn't do so for an + # xaxis_transformed patch, so undo that update. + iy = self.dataLim.intervaly.copy() + my = self.dataLim.minposy self.add_patch(p) + self.dataLim.intervaly = iy + self.dataLim.minposy = my + p.get_path()._interpolation_steps = mpl.axis.GRIDLINE_INTERPOLATION_STEPS self._request_autoscale_view("x") return p diff --git a/lib/matplotlib/tests/baseline_images/test_axes/axhvlinespan_interpolation.png b/lib/matplotlib/tests/baseline_images/test_axes/axhvlinespan_interpolation.png new file mode 100644 index 0000000000000000000000000000000000000000..3937cdf5b34c9a77d8003dd04967ee70ef4ab130 GIT binary patch literal 28240 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 literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index ab9dab03e543..564bf6a86b52 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -8849,3 +8849,15 @@ def test_xylim_changed_shared(): axs[1].callbacks.connect("ylim_changed", events.append) axs[0].set(xlim=[1, 3], ylim=[2, 4]) assert events == [axs[1], axs[1]] + + +@image_comparison(["axhvlinespan_interpolation.png"], style="default") +def test_axhvlinespan_interpolation(): + ax = plt.figure().add_subplot(projection="polar") + ax.set_axis_off() + ax.axvline(.1, c="C0") + ax.axvspan(.2, .3, fc="C1") + ax.axvspan(.4, .5, .1, .2, fc="C2") + ax.axhline(1, c="C0", alpha=.5) + ax.axhspan(.8, .9, fc="C1", alpha=.5) + ax.axhspan(.6, .7, .8, .9, fc="C2", alpha=.5) diff --git a/lib/matplotlib/tests/test_path.py b/lib/matplotlib/tests/test_path.py index 0a1d6c6b5e52..8c0c32dc133b 100644 --- a/lib/matplotlib/tests/test_path.py +++ b/lib/matplotlib/tests/test_path.py @@ -142,11 +142,11 @@ def test_nonlinear_containment(): ax.set(xscale="log", ylim=(0, 1)) polygon = ax.axvspan(1, 10) assert polygon.get_path().contains_point( - ax.transData.transform((5, .5)), ax.transData) + ax.transData.transform((5, .5)), polygon.get_transform()) assert not polygon.get_path().contains_point( - ax.transData.transform((.5, .5)), ax.transData) + ax.transData.transform((.5, .5)), polygon.get_transform()) assert not polygon.get_path().contains_point( - ax.transData.transform((50, .5)), ax.transData) + ax.transData.transform((50, .5)), polygon.get_transform()) @image_comparison(['arrow_contains_point.png'], diff --git a/lib/matplotlib/transforms.py b/lib/matplotlib/transforms.py index d04b59afa9d7..5a7fd125a29b 100644 --- a/lib/matplotlib/transforms.py +++ b/lib/matplotlib/transforms.py @@ -671,6 +671,7 @@ def intersection(bbox1, bbox2): y1 = np.minimum(bbox1.ymax, bbox2.ymax) return Bbox([[x0, y0], [x1, y1]]) if x0 <= x1 and y0 <= y1 else None + _default_minpos = np.array([np.inf, np.inf]) @@ -1011,6 +1012,10 @@ def minpos(self): """ return self._minpos + @minpos.setter + def minpos(self, val): + self._minpos[:] = val + @property def minposx(self): """ @@ -1022,6 +1027,10 @@ def minposx(self): """ return self._minpos[0] + @minposx.setter + def minposx(self, val): + self._minpos[0] = val + @property def minposy(self): """ @@ -1033,6 +1042,10 @@ def minposy(self): """ return self._minpos[1] + @minposy.setter + def minposy(self, val): + self._minpos[1] = val + def get_points(self): """ Get the points of the bounding box as an array of the form diff --git a/lib/matplotlib/widgets.py b/lib/matplotlib/widgets.py index 0a31a9dd2529..771cfd714b91 100644 --- a/lib/matplotlib/widgets.py +++ b/lib/matplotlib/widgets.py @@ -433,8 +433,8 @@ def __init__(self, ax, label, valmin, valmax, valinit=0.5, valfmt=None, Notes ----- Additional kwargs are passed on to ``self.poly`` which is the - `~matplotlib.patches.Polygon` that draws the slider knob. See the - `.Polygon` documentation for valid property names (``facecolor``, + `~matplotlib.patches.Rectangle` that draws the slider knob. See the + `.Rectangle` documentation for valid property names (``facecolor``, ``edgecolor``, ``alpha``, etc.). """ super().__init__(ax, orientation, closedmin, closedmax, @@ -577,16 +577,12 @@ def set_val(self, val): ---------- val : float """ - xy = self.poly.xy if self.orientation == 'vertical': - xy[1] = .25, val - xy[2] = .75, val + self.poly.set_height(val - self.poly.get_y()) self._handle.set_ydata([val]) else: - xy[2] = val, .75 - xy[3] = val, .25 + self.poly.set_width(val - self.poly.get_x()) self._handle.set_xdata([val]) - self.poly.xy = xy self.valtext.set_text(self._format(val)) if self.drawon: self.ax.figure.canvas.draw_idle()