diff --git a/examples/lines_bars_and_markers/curve_error_band.py b/examples/lines_bars_and_markers/curve_error_band.py index 56d95977a54c..e55b467849a8 100644 --- a/examples/lines_bars_and_markers/curve_error_band.py +++ b/examples/lines_bars_and_markers/curve_error_band.py @@ -10,7 +10,6 @@ # sphinx_gallery_thumbnail_number = 2 import numpy as np -from scipy.interpolate import splprep, splev import matplotlib.pyplot as plt from matplotlib.path import Path @@ -22,8 +21,8 @@ x, y = r * np.cos(t), r * np.sin(t) fig, ax = plt.subplots() -ax.plot(x, y) -plt.show() +ax.plot(x, y, "k") +ax.set(aspect=1) ############################################################################# # An error band can be used to indicate the uncertainty of the curve. @@ -39,34 +38,43 @@ # `~.Axes.fill_between` method (see also # :doc:`/gallery/lines_bars_and_markers/fill_between_demo`). -# Error amplitudes depending on the curve parameter *t* -# (actual values are arbitrary and only for illustrative purposes): -err = 0.05 * np.sin(2 * t) ** 2 + 0.04 + 0.02 * np.cos(9 * t + 2) -# calculate normals via derivatives of splines -tck, u = splprep([x, y], s=0) -dx, dy = splev(u, tck, der=1) -l = np.hypot(dx, dy) -nx = dy / l -ny = -dx / l +def draw_error_band(ax, x, y, err, **kwargs): + # Calculate normals via centered finite differences (except the first point + # which uses a forward difference and the last point which uses a backward + # difference). + dx = np.concatenate([[x[1] - x[0]], x[2:] - x[:-2], [x[-1] - x[-2]]]) + dy = np.concatenate([[y[1] - y[0]], y[2:] - y[:-2], [y[-1] - y[-2]]]) + l = np.hypot(dx, dy) + nx = dy / l + ny = -dx / l -# end points of errors -xp = x + nx * err -yp = y + ny * err -xn = x - nx * err -yn = y - ny * err + # end points of errors + xp = x + nx * err + yp = y + ny * err + xn = x - nx * err + yn = y - ny * err -vertices = np.block([[xp, xn[::-1]], - [yp, yn[::-1]]]).T -codes = Path.LINETO * np.ones(len(vertices), dtype=Path.code_type) -codes[0] = codes[len(xp)] = Path.MOVETO -path = Path(vertices, codes) + vertices = np.block([[xp, xn[::-1]], + [yp, yn[::-1]]]).T + codes = np.full(len(vertices), Path.LINETO) + codes[0] = codes[len(xp)] = Path.MOVETO + path = Path(vertices, codes) + ax.add_patch(PathPatch(path, **kwargs)) -patch = PathPatch(path, facecolor='C0', edgecolor='none', alpha=0.3) -fig, ax = plt.subplots() -ax.plot(x, y) -ax.add_patch(patch) +axs = (plt.figure(constrained_layout=True) + .subplots(1, 2, sharex=True, sharey=True)) +errs = [ + (axs[0], "constant error", 0.05), + (axs[1], "variable error", 0.05 * np.sin(2 * t) ** 2 + 0.04), +] +for i, (ax, title, err) in enumerate(errs): + ax.set(title=title, aspect=1, xticks=[], yticks=[]) + ax.plot(x, y, "k") + draw_error_band(ax, x, y, err=err, + facecolor=f"C{i}", edgecolor="none", alpha=.3) + plt.show() ############################################################################# 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