diff --git a/examples/api/radar_chart.py b/examples/api/radar_chart.py index 814f79425405..06b2fb1acb06 100644 --- a/examples/api/radar_chart.py +++ b/examples/api/radar_chart.py @@ -36,7 +36,7 @@ def radar_factory(num_vars, frame='circle'): """ # calculate evenly-spaced axis angles - theta = np.linspace(0, 2*np.pi, num_vars, endpoint=False) + theta = np.linspace(0, 2 * np.pi, num_vars, endpoint=False) def draw_poly_patch(self): # rotate theta such that the first axis is at the top @@ -60,18 +60,13 @@ class RadarAxes(PolarAxes): draw_patch = patch_dict[frame] def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) + super(RadarAxes, self).__init__(*args, **kwargs) # rotate plot such that the first axis is at the top self.set_theta_zero_location('N') - def fill(self, *args, **kwargs): - """Override fill so that line is closed by default""" - closed = kwargs.pop('closed', True) - return super().fill(closed=closed, *args, **kwargs) - def plot(self, *args, **kwargs): """Override plot so that line is closed by default""" - lines = super().plot(*args, **kwargs) + lines = super(RadarAxes, self).plot(*args, **kwargs) for line in lines: self._close_line(line) @@ -116,7 +111,7 @@ def unit_poly_verts(theta): This polygon is circumscribed by a unit circle centered at (0.5, 0.5) """ x0, y0, r = [0.5] * 3 - verts = [(r*np.cos(t) + x0, r*np.sin(t) + y0) for t in theta] + verts = [(r * np.cos(t) + x0, r * np.sin(t) + y0) for t in theta] return verts diff --git a/lib/matplotlib/projections/polar.py b/lib/matplotlib/projections/polar.py index 1493d7b3fc02..047941628eb0 100644 --- a/lib/matplotlib/projections/polar.py +++ b/lib/matplotlib/projections/polar.py @@ -858,6 +858,34 @@ def __init__(self, *args, **kwargs): self.cla() __init__.__doc__ = Axes.__init__.__doc__ + def add_patch(self, patch): + """ + Override the existing add_patch() method from _AxesBase class. + The _interpolation_steps field should be revised prior to drawing. + + :param patch: `~matplotlib.patches.Patch` + :return: `~matplotlib.patches.Patch` + """ + patch.get_path()._interpolation_steps = \ + max(patch.get_path()._interpolation_steps, # default 1 + maxis.GRIDLINE_INTERPOLATION_STEPS) # 180 + return super().add_patch(patch) + + def fill(self, *args, **kwargs): + ''' + Override the existing fill() method from _AxesBase class. + Filling a polygon to a polar axis, the edge of the polygon should + produce a straight line in polar space, thus the edges should not be + interpolated. + + :return: list of `~matplotlib.patches.Patch` + ''' + patches = super().fill(*args, **kwargs) + for polygon in patches: + polygon.get_path()._interpolation_steps = \ + min(polygon.get_path()._interpolation_steps, 1) + return patches + def cla(self): Axes.cla(self) diff --git a/lib/matplotlib/tests/baseline_images/test_patches/polar_polygon_filling.png b/lib/matplotlib/tests/baseline_images/test_patches/polar_polygon_filling.png new file mode 100644 index 000000000000..1d2f3216478d Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_patches/polar_polygon_filling.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_patches/transform_rectangle.png b/lib/matplotlib/tests/baseline_images/test_patches/transform_rectangle.png new file mode 100644 index 000000000000..167e8f046c61 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_patches/transform_rectangle.png differ diff --git a/lib/matplotlib/tests/test_patches.py b/lib/matplotlib/tests/test_patches.py index ff1abb9c64f4..f82ae3602c13 100644 --- a/lib/matplotlib/tests/test_patches.py +++ b/lib/matplotlib/tests/test_patches.py @@ -363,6 +363,29 @@ def test_connection_patch(): ax2.add_artist(con) +@image_comparison(baseline_images=['transform_rectangle'], extensions=['png'], + style='mpl20', remove_text=True) +def test_polar_rectangle_transform_patch(): + # Rectangle patch not transformed correctly in polar plot (#8521) + rectangle = mpatches.Rectangle((0, 1), width=np.pi * 0.5, height=1) + fig = plt.figure(figsize=(6, 8)) + ax = fig.add_subplot(1, 1, 1, polar=True) + ax.add_patch(rectangle) + ax.set_rmax(2.5) + + +@image_comparison(baseline_images=['polar_polygon_filling'], + extensions=['png'], style='mpl20', remove_text=True) +def test_polar_polygon_filling(): + x = np.linspace(0, np.pi, 5) + y = np.abs(np.sin(x)) + fig = plt.figure(figsize=(6.4, 4.8)) + ax = fig.add_subplot(1, 1, 1, polar=True) + # ax.set_rmax(1.5) + ax.plot(x, y) + ax.fill(x, y) + + def test_datetime_rectangle(): # Check that creating a rectangle with timedeltas doesn't fail from datetime import datetime, timedelta