From d885c0fa549421dfb5f9d05b1232f50ea72133fb Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Tue, 1 Oct 2019 09:46:04 -0700 Subject: [PATCH 1/2] Merge pull request #14694 from anntzer/arcdraw Vectorize Arc.draw. --- lib/matplotlib/patches.py | 61 +++++++------------ .../test_patches/large_arc.svg | 40 ++++++++++++ lib/matplotlib/tests/test_patches.py | 8 +++ 3 files changed, 69 insertions(+), 40 deletions(-) create mode 100644 lib/matplotlib/tests/baseline_images/test_patches/large_arc.svg diff --git a/lib/matplotlib/patches.py b/lib/matplotlib/patches.py index 42affae91949..a6e3d998ec76 100644 --- a/lib/matplotlib/patches.py +++ b/lib/matplotlib/patches.py @@ -1592,14 +1592,12 @@ def draw(self, renderer): calculation much easier than doing rotated ellipse intersection directly). - This uses the "line intersecting a circle" algorithm - from: + This uses the "line intersecting a circle" algorithm from: Vince, John. *Geometry for Computer Graphics: Formulae, Examples & Proofs.* London: Springer-Verlag, 2005. - 2. The angles of each of the intersection points are - calculated. + 2. The angles of each of the intersection points are calculated. 3. Proceeding counterclockwise starting in the positive x-direction, each of the visible arc-segments between the @@ -1632,33 +1630,25 @@ def theta_stretch(theta, scale): self._path = Path.arc(theta1, theta2) return Patch.draw(self, renderer) - def iter_circle_intersect_on_line(x0, y0, x1, y1): + def line_circle_intersect(x0, y0, x1, y1): dx = x1 - x0 dy = y1 - y0 dr2 = dx * dx + dy * dy D = x0 * y1 - x1 * y0 D2 = D * D discrim = dr2 - D2 - - # Single (tangential) intersection - if discrim == 0.0: - x = (D * dy) / dr2 - y = (-D * dx) / dr2 - yield x, y - elif discrim > 0.0: - # The definition of "sign" here is different from - # np.sign: we never want to get 0.0 - if dy < 0.0: - sign_dy = -1.0 - else: - sign_dy = 1.0 + if discrim >= 0.0: + sign_dy = np.copysign(1, dy) # +/-1, never 0. sqrt_discrim = np.sqrt(discrim) - for sign in (1., -1.): - x = (D * dy + sign * sign_dy * dx * sqrt_discrim) / dr2 - y = (-D * dx + sign * np.abs(dy) * sqrt_discrim) / dr2 - yield x, y + return np.array( + [[(D * dy + sign_dy * dx * sqrt_discrim) / dr2, + (-D * dx + abs(dy) * sqrt_discrim) / dr2], + [(D * dy - sign_dy * dx * sqrt_discrim) / dr2, + (-D * dx - abs(dy) * sqrt_discrim) / dr2]]) + else: + return np.empty((0, 2)) - def iter_circle_intersect_on_line_seg(x0, y0, x1, y1): + def segment_circle_intersect(x0, y0, x1, y1): epsilon = 1e-9 if x1 < x0: x0e, x1e = x1, x0 @@ -1668,13 +1658,10 @@ def iter_circle_intersect_on_line_seg(x0, y0, x1, y1): y0e, y1e = y1, y0 else: y0e, y1e = y0, y1 - x0e -= epsilon - y0e -= epsilon - x1e += epsilon - y1e += epsilon - for x, y in iter_circle_intersect_on_line(x0, y0, x1, y1): - if x0e <= x <= x1e and y0e <= y <= y1e: - yield x, y + xys = line_circle_intersect(x0, y0, x1, y1) + xs, ys = xys.T + return xys[(x0e - epsilon < xs) & (xs < x1e + epsilon) + & (y0e - epsilon < ys) & (ys < y1e + epsilon)] # Transforms the axes box_path so that it is relative to the unit # circle in the same way that it is relative to the desired ellipse. @@ -1686,16 +1673,10 @@ def iter_circle_intersect_on_line_seg(x0, y0, x1, y1): thetas = set() # For each of the point pairs, there is a line segment for p0, p1 in zip(box_path.vertices[:-1], box_path.vertices[1:]): - x0, y0 = p0 - x1, y1 = p1 - for x, y in iter_circle_intersect_on_line_seg(x0, y0, x1, y1): - theta = np.arccos(x) - if y < 0: - theta = 2 * np.pi - theta - # Convert radians to angles - theta = np.rad2deg(theta) - if theta1 < theta < theta2: - thetas.add(theta) + xy = segment_circle_intersect(*p0, *p1) + x, y = xy.T + theta = np.rad2deg(np.arctan2(y, x)) + thetas.update(theta[(theta1 < theta) & (theta < theta2)]) thetas = sorted(thetas) + [theta2] last_theta = theta1 diff --git a/lib/matplotlib/tests/baseline_images/test_patches/large_arc.svg b/lib/matplotlib/tests/baseline_images/test_patches/large_arc.svg new file mode 100644 index 000000000000..96cd6b203314 --- /dev/null +++ b/lib/matplotlib/tests/baseline_images/test_patches/large_arc.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/test_patches.py b/lib/matplotlib/tests/test_patches.py index 32ce5db1cebe..c20fe25e13dc 100644 --- a/lib/matplotlib/tests/test_patches.py +++ b/lib/matplotlib/tests/test_patches.py @@ -490,3 +490,11 @@ def test_fancyarrow_units(): fig, ax = plt.subplots() arrow = FancyArrowPatch((0, dtime), (0.01, dtime)) ax.add_patch(arrow) + + +@image_comparison(["large_arc.svg"], style="mpl20") +def test_large_arc(): + ax = plt.figure().add_subplot() + ax.set_axis_off() + # A large arc that crosses the axes view limits. + ax.add_patch(mpatches.Arc((-100, 0), 201, 201)) From d67550cee52588a9ff3cff49fbc45b0d878bca9a Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Tue, 16 Jun 2020 22:57:17 -0400 Subject: [PATCH 2/2] Backport PR #17564: FIX: correctly handle large arcs Merge pull request #17564 from tacaswell/fix_big_arc FIX: big arc code path Conflicts: lib/matplotlib/patches.py - implicitly backport a change from #15356 (from `- trans ` -> `+ trans.inverted()`) --- lib/matplotlib/patches.py | 63 ++- .../baseline_images/test_axes/arc_angles.png | Bin 25476 -> 25324 bytes .../test_patches/all_quadrants_arcs.svg | 481 ++++++++++++++++++ .../test_patches/large_arc.svg | 63 ++- lib/matplotlib/tests/test_patches.py | 57 ++- 5 files changed, 632 insertions(+), 32 deletions(-) create mode 100644 lib/matplotlib/tests/baseline_images/test_patches/all_quadrants_arcs.svg diff --git a/lib/matplotlib/patches.py b/lib/matplotlib/patches.py index a6e3d998ec76..abf4b97a6c7d 100644 --- a/lib/matplotlib/patches.py +++ b/lib/matplotlib/patches.py @@ -1607,6 +1607,8 @@ def draw(self, renderer): """ if not hasattr(self, 'axes'): raise RuntimeError('Arcs can only be used in Axes instances') + if not self.get_visible(): + return self._recompute_transform() @@ -1619,14 +1621,40 @@ def theta_stretch(theta, scale): theta = np.deg2rad(theta) x = np.cos(theta) y = np.sin(theta) - return np.rad2deg(np.arctan2(scale * y, x)) - theta1 = theta_stretch(self.theta1, width / height) - theta2 = theta_stretch(self.theta2, width / height) - - # Get width and height in pixels - width, height = self.get_transform().transform((width, height)) + stheta = np.rad2deg(np.arctan2(scale * y, x)) + # arctan2 has the range [-pi, pi], we expect [0, 2*pi] + return (stheta + 360) % 360 + + theta1 = self.theta1 + theta2 = self.theta2 + + if ( + # if we need to stretch the angles because we are distorted + width != height + # and we are not doing a full circle. + # + # 0 and 360 do not exactly round-trip through the angle + # stretching (due to both float precision limitations and + # the difference between the range of arctan2 [-pi, pi] and + # this method [0, 360]) so avoid doing it if we don't have to. + and not (theta1 != theta2 and theta1 % 360 == theta2 % 360) + ): + theta1 = theta_stretch(self.theta1, width / height) + theta2 = theta_stretch(self.theta2, width / height) + + # Get width and height in pixels we need to use + # `self.get_data_transform` rather than `self.get_transform` + # because we want the transform from dataspace to the + # screen space to estimate how big the arc will be in physical + # units when rendered (the transform that we get via + # `self.get_transform()` goes from an idealized unit-radius + # space to screen space). + data_to_screen_trans = self.get_data_transform() + pwidth, pheight = (data_to_screen_trans.transform((width, height)) - + data_to_screen_trans.transform((0, 0))) inv_error = (1.0 / 1.89818e-6) * 0.5 - if width < inv_error and height < inv_error: + + if pwidth < inv_error and pheight < inv_error: self._path = Path.arc(theta1, theta2) return Patch.draw(self, renderer) @@ -1660,29 +1688,32 @@ def segment_circle_intersect(x0, y0, x1, y1): y0e, y1e = y0, y1 xys = line_circle_intersect(x0, y0, x1, y1) xs, ys = xys.T - return xys[(x0e - epsilon < xs) & (xs < x1e + epsilon) - & (y0e - epsilon < ys) & (ys < y1e + epsilon)] + return xys[ + (x0e - epsilon < xs) & (xs < x1e + epsilon) + & (y0e - epsilon < ys) & (ys < y1e + epsilon) + ] # Transforms the axes box_path so that it is relative to the unit # circle in the same way that it is relative to the desired ellipse. - box_path = Path.unit_rectangle() box_path_transform = (transforms.BboxTransformTo(self.axes.bbox) - - self.get_transform()) - box_path = box_path.transformed(box_path_transform) + + self.get_transform().inverted()) + box_path = Path.unit_rectangle().transformed(box_path_transform) thetas = set() # For each of the point pairs, there is a line segment for p0, p1 in zip(box_path.vertices[:-1], box_path.vertices[1:]): xy = segment_circle_intersect(*p0, *p1) x, y = xy.T - theta = np.rad2deg(np.arctan2(y, x)) + # arctan2 return [-pi, pi), the rest of our angles are in + # [0, 360], adjust as needed. + theta = (np.rad2deg(np.arctan2(y, x)) + 360) % 360 thetas.update(theta[(theta1 < theta) & (theta < theta2)]) thetas = sorted(thetas) + [theta2] - last_theta = theta1 theta1_rad = np.deg2rad(theta1) - inside = box_path.contains_point((np.cos(theta1_rad), - np.sin(theta1_rad))) + inside = box_path.contains_point( + (np.cos(theta1_rad), np.sin(theta1_rad)) + ) # save original path path_original = self._path diff --git a/lib/matplotlib/tests/baseline_images/test_axes/arc_angles.png b/lib/matplotlib/tests/baseline_images/test_axes/arc_angles.png index 8b81cde703ef54fefaafebcfadc1cccd61eb978b..caa050aed900f637f9bc9087304f96371180727e 100644 GIT binary patch literal 25324 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 literal 25476 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 CMNvWk diff --git a/lib/matplotlib/tests/baseline_images/test_patches/all_quadrants_arcs.svg b/lib/matplotlib/tests/baseline_images/test_patches/all_quadrants_arcs.svg new file mode 100644 index 000000000000..a45712972165 --- /dev/null +++ b/lib/matplotlib/tests/baseline_images/test_patches/all_quadrants_arcs.svg @@ -0,0 +1,481 @@ + + + + + + + + + 2020-06-15T18:44:55.456487 + image/svg+xml + + + Matplotlib v3.2.1.post2847.dev0+g36a8896133, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_patches/large_arc.svg b/lib/matplotlib/tests/baseline_images/test_patches/large_arc.svg index 96cd6b203314..d902870aa7b7 100644 --- a/lib/matplotlib/tests/baseline_images/test_patches/large_arc.svg +++ b/lib/matplotlib/tests/baseline_images/test_patches/large_arc.svg @@ -3,6 +3,20 @@ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> + + + + + 2020-06-15T19:03:05.186353 + image/svg+xml + + + Matplotlib v3.2.1.post2849.dev0+ge5dca476ed, https://matplotlib.org/ + + + + + diff --git a/lib/matplotlib/tests/test_patches.py b/lib/matplotlib/tests/test_patches.py index c20fe25e13dc..c0eda5542927 100644 --- a/lib/matplotlib/tests/test_patches.py +++ b/lib/matplotlib/tests/test_patches.py @@ -494,7 +494,56 @@ def test_fancyarrow_units(): @image_comparison(["large_arc.svg"], style="mpl20") def test_large_arc(): - ax = plt.figure().add_subplot() - ax.set_axis_off() - # A large arc that crosses the axes view limits. - ax.add_patch(mpatches.Arc((-100, 0), 201, 201)) + fig, (ax1, ax2) = plt.subplots(1, 2) + x = 210 + y = -2115 + diameter = 4261 + for ax in [ax1, ax2]: + a = mpatches.Arc((x, y), diameter, diameter, lw=2, color='k') + ax.add_patch(a) + ax.set_axis_off() + ax.set_aspect('equal') + # force the high accuracy case + ax1.set_xlim(7, 8) + ax1.set_ylim(5, 6) + + # force the low accuracy case + ax2.set_xlim(-25000, 18000) + ax2.set_ylim(-20000, 6600) + + +@image_comparison(["all_quadrants_arcs.svg"], style="mpl20") +def test_rotated_arcs(): + fig, ax_arr = plt.subplots(2, 2, squeeze=False, figsize=(10, 10)) + + scale = 10_000_000 + diag_centers = ((-1, -1), (-1, 1), (1, 1), (1, -1)) + on_axis_centers = ((0, 1), (1, 0), (0, -1), (-1, 0)) + skews = ((2, 2), (2, 1/10), (2, 1/100), (2, 1/1000)) + + for ax, (sx, sy) in zip(ax_arr.ravel(), skews): + k = 0 + for prescale, centers in zip((1 - .0001, (1 - .0001) / np.sqrt(2)), + (on_axis_centers, diag_centers)): + for j, (x_sign, y_sign) in enumerate(centers, start=k): + a = mpatches.Arc( + (x_sign * scale * prescale, + y_sign * scale * prescale), + scale * sx, + scale * sy, + lw=4, + color=f"C{j}", + zorder=1 + j, + angle=np.rad2deg(np.arctan2(y_sign, x_sign)) % 360, + label=f'big {j}', + gid=f'big {j}' + ) + ax.add_patch(a) + + k = j+1 + ax.set_xlim(-scale / 4000, scale / 4000) + ax.set_ylim(-scale / 4000, scale / 4000) + ax.axhline(0, color="k") + ax.axvline(0, color="k") + ax.set_axis_off() + ax.set_aspect("equal") pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy