Drawing a Curve With Error Band

PythonPythonBeginner
Practice Now

This tutorial is from open-source community. Access the source code

Introduction

This tutorial will guide you on how to draw a curve with an error band using Python Matplotlib. An error band is used to indicate the uncertainty of the curve. In this example, we assume that the error can be given as a scalar err that describes the uncertainty perpendicular to the curve in every point. We visualize this error as a colored band around the path using a .PathPatch. The patch is created from two path segments (xp, yp), and (xn, yn) that are shifted by +/- err perpendicular to the curve (x, y).

VM Tips

After the VM startup is done, click the top left corner to switch to the Notebook tab to access Jupyter Notebook for practice.

Sometimes, you may need to wait a few seconds for Jupyter Notebook to finish loading. The validation of operations cannot be automated because of limitations in Jupyter Notebook.

If you face issues during learning, feel free to ask Labby. Provide feedback after the session, and we will promptly resolve the problem for you.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("`Python`")) -.-> python/BasicConceptsGroup(["`Basic Concepts`"]) python(("`Python`")) -.-> python/FunctionsGroup(["`Functions`"]) matplotlib(("`Matplotlib`")) -.-> matplotlib/BasicConceptsGroup(["`Basic Concepts`"]) matplotlib(("`Matplotlib`")) -.-> matplotlib/PlottingDataGroup(["`Plotting Data`"]) python(("`Python`")) -.-> python/ControlFlowGroup(["`Control Flow`"]) python(("`Python`")) -.-> python/DataStructuresGroup(["`Data Structures`"]) python(("`Python`")) -.-> python/ModulesandPackagesGroup(["`Modules and Packages`"]) python(("`Python`")) -.-> python/ErrorandExceptionHandlingGroup(["`Error and Exception Handling`"]) python(("`Python`")) -.-> python/PythonStandardLibraryGroup(["`Python Standard Library`"]) python(("`Python`")) -.-> python/DataScienceandMachineLearningGroup(["`Data Science and Machine Learning`"]) python/BasicConceptsGroup -.-> python/comments("`Comments`") python/FunctionsGroup -.-> python/keyword_arguments("`Keyword Arguments`") matplotlib/BasicConceptsGroup -.-> matplotlib/importing_matplotlib("`Importing Matplotlib`") matplotlib/BasicConceptsGroup -.-> matplotlib/figures_axes("`Understanding Figures and Axes`") matplotlib/PlottingDataGroup -.-> matplotlib/line_plots("`Line Plots`") python/BasicConceptsGroup -.-> python/variables_data_types("`Variables and Data Types`") python/BasicConceptsGroup -.-> python/booleans("`Booleans`") python/ControlFlowGroup -.-> python/for_loops("`For Loops`") python/DataStructuresGroup -.-> python/lists("`Lists`") python/DataStructuresGroup -.-> python/tuples("`Tuples`") python/DataStructuresGroup -.-> python/sets("`Sets`") python/FunctionsGroup -.-> python/function_definition("`Function Definition`") python/ModulesandPackagesGroup -.-> python/importing_modules("`Importing Modules`") python/ModulesandPackagesGroup -.-> python/using_packages("`Using Packages`") python/ErrorandExceptionHandlingGroup -.-> python/catching_exceptions("`Catching Exceptions`") python/PythonStandardLibraryGroup -.-> python/data_collections("`Data Collections`") python/DataScienceandMachineLearningGroup -.-> python/numerical_computing("`Numerical Computing`") python/DataScienceandMachineLearningGroup -.-> python/data_visualization("`Data Visualization`") python/FunctionsGroup -.-> python/build_in_functions("`Build-in Functions`") subgraph Lab Skills python/comments -.-> lab-48637{{"`Drawing a Curve With Error Band`"}} python/keyword_arguments -.-> lab-48637{{"`Drawing a Curve With Error Band`"}} matplotlib/importing_matplotlib -.-> lab-48637{{"`Drawing a Curve With Error Band`"}} matplotlib/figures_axes -.-> lab-48637{{"`Drawing a Curve With Error Band`"}} matplotlib/line_plots -.-> lab-48637{{"`Drawing a Curve With Error Band`"}} python/variables_data_types -.-> lab-48637{{"`Drawing a Curve With Error Band`"}} python/booleans -.-> lab-48637{{"`Drawing a Curve With Error Band`"}} python/for_loops -.-> lab-48637{{"`Drawing a Curve With Error Band`"}} python/lists -.-> lab-48637{{"`Drawing a Curve With Error Band`"}} python/tuples -.-> lab-48637{{"`Drawing a Curve With Error Band`"}} python/sets -.-> lab-48637{{"`Drawing a Curve With Error Band`"}} python/function_definition -.-> lab-48637{{"`Drawing a Curve With Error Band`"}} python/importing_modules -.-> lab-48637{{"`Drawing a Curve With Error Band`"}} python/using_packages -.-> lab-48637{{"`Drawing a Curve With Error Band`"}} python/catching_exceptions -.-> lab-48637{{"`Drawing a Curve With Error Band`"}} python/data_collections -.-> lab-48637{{"`Drawing a Curve With Error Band`"}} python/numerical_computing -.-> lab-48637{{"`Drawing a Curve With Error Band`"}} python/data_visualization -.-> lab-48637{{"`Drawing a Curve With Error Band`"}} python/build_in_functions -.-> lab-48637{{"`Drawing a Curve With Error Band`"}} end

Import Required Libraries

The first step is to import the required libraries. We will be using Matplotlib, NumPy, PathPatch, and Path.

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import PathPatch
from matplotlib.path import Path

Define the Curve

Next, we define the curve that we want to draw the error band around. In this example, we will be using a parametrized curve. A parametrized curve x(t), y(t) can directly be drawn using ~.Axes.plot.

N = 400
t = np.linspace(0, 2 * np.pi, N)
r = 0.5 + np.cos(t)
x, y = r * np.cos(t), r * np.sin(t)

Define the Error Band

We will now define the error band that we want to draw around the curve. In this example, we will be assuming that the error can be given as a scalar err that describes the uncertainty perpendicular to the curve in every point.

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

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

Draw the Error Band

We can now draw the error band by calling the draw_error_band function and passing in the appropriate parameters.

fig, axs = plt.subplots(1, 2, layout='constrained', 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()

View the Error Band

The error band should now be visible around the curve.

Summary

In this tutorial, we have learned how to draw a curve with an error band using Python Matplotlib. We started by importing the required libraries, defining the curve, defining the error band, drawing the error band, and viewing the error band.

Other Python Tutorials you may like