|
| 1 | +""" |
| 2 | +===================== |
| 3 | +Curve with error band |
| 4 | +===================== |
| 5 | +
|
| 6 | +This example illustrates how to draw an error band around a parametrized curve. |
| 7 | +
|
| 8 | +A parametrized curve x(t), y(t) can directly be drawn using `~.Axes.plot`. |
| 9 | +""" |
| 10 | +# sphinx_gallery_thumbnail_number = 2 |
| 11 | + |
| 12 | +import numpy as np |
| 13 | +from scipy.interpolate import splprep, splev |
| 14 | + |
| 15 | +import matplotlib.pyplot as plt |
| 16 | +from matplotlib.path import Path |
| 17 | +from matplotlib.patches import PathPatch |
| 18 | + |
| 19 | +N = 400 |
| 20 | +t = np.linspace(0, 2 * np.pi, N) |
| 21 | +r = 0.5 + np.cos(t) |
| 22 | +x, y = r * np.cos(t), r * np.sin(t) |
| 23 | + |
| 24 | +fig, ax = plt.subplots() |
| 25 | +ax.plot(x, y) |
| 26 | +plt.show() |
| 27 | + |
| 28 | +############################################################################# |
| 29 | +# An error band can be used to indicate the uncertainty of the curve. |
| 30 | +# In this example we assume that the error can be given as a scalar *err* |
| 31 | +# that describes the uncertainty perpendicular to the curve in every point. |
| 32 | +# |
| 33 | +# We visualize this error as a colored band around the path using a |
| 34 | +# `.PathPatch`. The patch is created from two path segments *(xp, yp)*, and |
| 35 | +# *(xn, yn)* that are shifted by +/- *err* perpendicular to the curve *(x, y)*. |
| 36 | +# |
| 37 | +# Note: This method of using a `.PathPatch` is suited to arbitrary curves in |
| 38 | +# 2D. If you just have a standard y-vs.-x plot, you can use the simpler |
| 39 | +# `~.Axes.fill_between` method (see also |
| 40 | +# :doc:`/gallery/lines_bars_and_markers/fill_between_demo`). |
| 41 | + |
| 42 | +# Error amplitudes depending on the curve parameter *t* |
| 43 | +# (actual values are arbitrary and only for illustrative purposes): |
| 44 | +err = 0.05 * np.sin(2 * t) ** 2 + 0.04 + 0.02 * np.cos(9 * t + 2) |
| 45 | + |
| 46 | +# calculate normals via derivatives of splines |
| 47 | +tck, u = splprep([x, y], s=0) |
| 48 | +dx, dy = splev(u, tck, der=1) |
| 49 | +l = np.hypot(dx, dy) |
| 50 | +nx = dy / l |
| 51 | +ny = -dx / l |
| 52 | + |
| 53 | +# end points of errors |
| 54 | +xp = x + nx * err |
| 55 | +yp = y + ny * err |
| 56 | +xn = x - nx * err |
| 57 | +yn = y - ny * err |
| 58 | + |
| 59 | +vertices = np.block([[xp, xn[::-1]], |
| 60 | + [yp, yn[::-1]]]).T |
| 61 | +codes = Path.LINETO * np.ones(len(vertices), dtype=Path.code_type) |
| 62 | +codes[0] = codes[len(xp)] = Path.MOVETO |
| 63 | +path = Path(vertices, codes) |
| 64 | + |
| 65 | +patch = PathPatch(path, facecolor='C0', edgecolor='none', alpha=0.3) |
| 66 | + |
| 67 | +fig, ax = plt.subplots() |
| 68 | +ax.plot(x, y) |
| 69 | +ax.add_patch(patch) |
| 70 | +plt.show() |
| 71 | + |
| 72 | +############################################################################# |
| 73 | +# |
| 74 | +# ------------ |
| 75 | +# |
| 76 | +# References |
| 77 | +# """""""""" |
| 78 | +# |
| 79 | +# The use of the following functions, methods and classes is shown |
| 80 | +# in this example: |
| 81 | + |
| 82 | +import matplotlib |
| 83 | +matplotlib.patches.PathPatch |
| 84 | +matplotlib.path.Path |
0 commit comments