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")