Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit eca26d0

Browse filesBrowse files
authored
Merge pull request #23340 from oscargus/arcfix
Set correct path for Arc
2 parents 1fd71a5 + a651e73 commit eca26d0
Copy full SHA for eca26d0

File tree

Expand file treeCollapse file tree

6 files changed

+395
-41
lines changed
Filter options
Expand file treeCollapse file tree

6 files changed

+395
-41
lines changed

‎lib/matplotlib/patches.py

Copy file name to clipboardExpand all lines: lib/matplotlib/patches.py
+53-37Lines changed: 53 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1958,6 +1958,9 @@ def __init__(self, xy, width, height, angle=0.0,
19581958

19591959
self.theta1 = theta1
19601960
self.theta2 = theta2
1961+
(self._theta1, self._theta2, self._stretched_width,
1962+
self._stretched_height) = self._theta_stretch()
1963+
self._path = Path.arc(self._theta1, self._theta2)
19611964

19621965
@artist.allow_rasterization
19631966
def draw(self, renderer):
@@ -2010,36 +2013,7 @@ def draw(self, renderer):
20102013

20112014
self._recompute_transform()
20122015

2013-
width = self.convert_xunits(self.width)
2014-
height = self.convert_yunits(self.height)
2015-
2016-
# If the width and height of ellipse are not equal, take into account
2017-
# stretching when calculating angles to draw between
2018-
def theta_stretch(theta, scale):
2019-
theta = np.deg2rad(theta)
2020-
x = np.cos(theta)
2021-
y = np.sin(theta)
2022-
stheta = np.rad2deg(np.arctan2(scale * y, x))
2023-
# arctan2 has the range [-pi, pi], we expect [0, 2*pi]
2024-
return (stheta + 360) % 360
2025-
2026-
theta1 = self.theta1
2027-
theta2 = self.theta2
2028-
2029-
if (
2030-
# if we need to stretch the angles because we are distorted
2031-
width != height
2032-
# and we are not doing a full circle.
2033-
#
2034-
# 0 and 360 do not exactly round-trip through the angle
2035-
# stretching (due to both float precision limitations and
2036-
# the difference between the range of arctan2 [-pi, pi] and
2037-
# this method [0, 360]) so avoid doing it if we don't have to.
2038-
and not (theta1 != theta2 and theta1 % 360 == theta2 % 360)
2039-
):
2040-
theta1 = theta_stretch(self.theta1, width / height)
2041-
theta2 = theta_stretch(self.theta2, width / height)
2042-
2016+
self._update_path()
20432017
# Get width and height in pixels we need to use
20442018
# `self.get_data_transform` rather than `self.get_transform`
20452019
# because we want the transform from dataspace to the
@@ -2048,12 +2022,13 @@ def theta_stretch(theta, scale):
20482022
# `self.get_transform()` goes from an idealized unit-radius
20492023
# space to screen space).
20502024
data_to_screen_trans = self.get_data_transform()
2051-
pwidth, pheight = (data_to_screen_trans.transform((width, height)) -
2052-
data_to_screen_trans.transform((0, 0)))
2025+
pwidth, pheight = (
2026+
data_to_screen_trans.transform((self._stretched_width,
2027+
self._stretched_height)) -
2028+
data_to_screen_trans.transform((0, 0)))
20532029
inv_error = (1.0 / 1.89818e-6) * 0.5
20542030

20552031
if pwidth < inv_error and pheight < inv_error:
2056-
self._path = Path.arc(theta1, theta2)
20572032
return Patch.draw(self, renderer)
20582033

20592034
def line_circle_intersect(x0, y0, x1, y1):
@@ -2107,10 +2082,11 @@ def segment_circle_intersect(x0, y0, x1, y1):
21072082
# arctan2 return [-pi, pi), the rest of our angles are in
21082083
# [0, 360], adjust as needed.
21092084
theta = (np.rad2deg(np.arctan2(y, x)) + 360) % 360
2110-
thetas.update(theta[(theta1 < theta) & (theta < theta2)])
2111-
thetas = sorted(thetas) + [theta2]
2112-
last_theta = theta1
2113-
theta1_rad = np.deg2rad(theta1)
2085+
thetas.update(
2086+
theta[(self._theta1 < theta) & (theta < self._theta2)])
2087+
thetas = sorted(thetas) + [self._theta2]
2088+
last_theta = self._theta1
2089+
theta1_rad = np.deg2rad(self._theta1)
21142090
inside = box_path.contains_point(
21152091
(np.cos(theta1_rad), np.sin(theta1_rad))
21162092
)
@@ -2129,6 +2105,46 @@ def segment_circle_intersect(x0, y0, x1, y1):
21292105
# restore original path
21302106
self._path = path_original
21312107

2108+
def _update_path(self):
2109+
# Compute new values and update and set new _path if any value changed
2110+
stretched = self._theta_stretch()
2111+
if any(a != b for a, b in zip(
2112+
stretched, (self._theta1, self._theta2, self._stretched_width,
2113+
self._stretched_height))):
2114+
(self._theta1, self._theta2, self._stretched_width,
2115+
self._stretched_height) = stretched
2116+
self._path = Path.arc(self._theta1, self._theta2)
2117+
2118+
def _theta_stretch(self):
2119+
# If the width and height of ellipse are not equal, take into account
2120+
# stretching when calculating angles to draw between
2121+
def theta_stretch(theta, scale):
2122+
theta = np.deg2rad(theta)
2123+
x = np.cos(theta)
2124+
y = np.sin(theta)
2125+
stheta = np.rad2deg(np.arctan2(scale * y, x))
2126+
# arctan2 has the range [-pi, pi], we expect [0, 2*pi]
2127+
return (stheta + 360) % 360
2128+
2129+
width = self.convert_xunits(self.width)
2130+
height = self.convert_yunits(self.height)
2131+
if (
2132+
# if we need to stretch the angles because we are distorted
2133+
width != height
2134+
# and we are not doing a full circle.
2135+
#
2136+
# 0 and 360 do not exactly round-trip through the angle
2137+
# stretching (due to both float precision limitations and
2138+
# the difference between the range of arctan2 [-pi, pi] and
2139+
# this method [0, 360]) so avoid doing it if we don't have to.
2140+
and not (self.theta1 != self.theta2 and
2141+
self.theta1 % 360 == self.theta2 % 360)
2142+
):
2143+
theta1 = theta_stretch(self.theta1, width / height)
2144+
theta2 = theta_stretch(self.theta2, width / height)
2145+
return theta1, theta2, width, height
2146+
return self.theta1, self.theta2, width, height
2147+
21322148

21332149
def bbox_artist(artist, renderer, props=None, fill=True):
21342150
"""
Loading

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.