diff --git a/doc/users/next_whats_new/steppatch_and_stairs.rst b/doc/users/next_whats_new/steppatch_and_stairs.rst index 268130ff9d1e..f5d76c5fd99b 100644 --- a/doc/users/next_whats_new/steppatch_and_stairs.rst +++ b/doc/users/next_whats_new/steppatch_and_stairs.rst @@ -1,7 +1,11 @@ New StepPatch artist and a stairs method ---------------------------------------- -New `~.matplotlib.patches.StepPatch` artist and `.pyplot.stairs` method. -For both the artist and the function, the x-like edges input is one +`.pyplot.stairs` and the underlying artist `~.matplotlib.patches.StepPatch` +provide a cleaner interface for plotting stepwise constant functions for the +common case that you know the step edges. This superseeds many use cases of +`.pyplot.step`, for instance when plotting the output of `numpy.histogram`. + +For both the artist and the function, the x-like edges input is one element longer than the y-like values input .. plot:: @@ -10,12 +14,12 @@ longer than the y-like values input import matplotlib.pyplot as plt np.random.seed(0) - h, bins = np.histogram(np.random.normal(5, 2, 5000), - bins=np.linspace(0,10,20)) + h, edges = np.histogram(np.random.normal(5, 2, 5000), + bins=np.linspace(0,10,20)) fig, ax = plt.subplots(constrained_layout=True) - ax.stairs(h, bins) + ax.stairs(h, edges) plt.show() diff --git a/examples/lines_bars_and_markers/stairs_demo.py b/examples/lines_bars_and_markers/stairs_demo.py index d9f8cce98326..8667ddefa42b 100644 --- a/examples/lines_bars_and_markers/stairs_demo.py +++ b/examples/lines_bars_and_markers/stairs_demo.py @@ -3,13 +3,10 @@ Stairs Demo =========== -This example demonstrates the use of `~.matplotlib.pyplot.stairs` -for histogram and histogram-like data visualization and an associated -underlying `.StepPatch` artist, which is a specialized version of -`.PathPatch` specified by its bins and edges. +This example demonstrates the use of `~.matplotlib.pyplot.stairs` for stepwise +constant functions. A common use case is histogram and histogram-like data +visualization. -The primary difference to `~.matplotlib.pyplot.step` is that ``stairs`` -x-like edges input is one longer than its y-like values input. """ import numpy as np @@ -17,13 +14,13 @@ from matplotlib.patches import StepPatch np.random.seed(0) -h, bins = np.histogram(np.random.normal(5, 3, 5000), - bins=np.linspace(0, 10, 20)) +h, edges = np.histogram(np.random.normal(5, 3, 5000), + bins=np.linspace(0, 10, 20)) fig, axs = plt.subplots(3, 1, figsize=(7, 15)) -axs[0].stairs(h, bins, label='Simple histogram') -axs[0].stairs(h, bins+5, baseline=50, label='Modified baseline') -axs[0].stairs(h, bins+10, baseline=None, label='No edges') +axs[0].stairs(h, edges, label='Simple histogram') +axs[0].stairs(h, edges + 5, baseline=50, label='Modified baseline') +axs[0].stairs(h, edges + 10, baseline=None, label='No edges') axs[0].set_title("Step Histograms") axs[1].stairs(np.arange(1, 6, 1), fill=True, @@ -47,22 +44,30 @@ plt.show() ############################################################################# -# Comparison of `.pyplot.step` and `.pyplot.stairs`. +# Comparison of `.pyplot.step` and `.pyplot.stairs` +# ------------------------------------------------- +# +# `.pyplot.step` defines the positions of the steps as single values. The steps +# extend left/right/both ways from these reference values depending on the +# parameter *where*. The number of *x* and *y* values is the same. +# +# In contrast, `.pyplot.stairs` defines the positions of the steps via their +# bounds *edges*, which is one element longer than the step values. bins = np.arange(14) -centers = bins[:-1] + np.diff(bins)/2 +centers = bins[:-1] + np.diff(bins) / 2 y = np.sin(centers / 2) -plt.step(bins[:-1], y, where='post', label='Step(where="post")') +plt.step(bins[:-1], y, where='post', label='step(where="post")') plt.plot(bins[:-1], y, 'o--', color='grey', alpha=0.3) -plt.stairs(y - 1, bins, baseline=None, label='Stairs') +plt.stairs(y - 1, bins, baseline=None, label='stairs()') plt.plot(centers, y - 1, 'o--', color='grey', alpha=0.3) plt.plot(np.repeat(bins, 2), np.hstack([y[0], np.repeat(y, 2), y[-1]]) - 1, 'o', color='red', alpha=0.2) plt.legend() -plt.title('plt.step vs plt.stairs') +plt.title('step() vs. stairs()') plt.show() ############################################################################# diff --git a/examples/lines_bars_and_markers/step_demo.py b/examples/lines_bars_and_markers/step_demo.py index 46b370eefd4d..c079ef05daad 100644 --- a/examples/lines_bars_and_markers/step_demo.py +++ b/examples/lines_bars_and_markers/step_demo.py @@ -7,6 +7,11 @@ curves. In particular, it illustrates the effect of the parameter *where* on the step position. +.. note:: + + For the common case that you know the edge positions, use `.pyplot.stairs` + instead. + The circular markers created with `.pyplot.plot` show the actual data positions so that it's easier to see the effect of *where*. diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 30b2b6a4dfb4..f13980bfc28a 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -2036,6 +2036,15 @@ def step(self, x, y, *args, where='pre', data=None, **kwargs): formatting options. Most of the concepts and parameters of plot can be used here as well. + .. note:: + + This method uses a standard plot with a step drawstyle: The *x* + values are the reference positions and steps extend left/right/both + directions depending on *where*. + + For the common case where you know the values and edges of the + steps, use `~.Axes.stairs` instead. + Parameters ---------- x : array-like @@ -6744,24 +6753,27 @@ def hist(self, x, bins=None, range=None, density=False, weights=None, def stairs(self, values, edges=None, *, orientation='vertical', baseline=0, fill=False, **kwargs): """ - A histogram-like line or filled plot. + A stepwise constant line or filled plot. Parameters ---------- values : array-like - An array of y-values. + The step heights. - edges : array-like, default: ``range(len(vals)+1)`` - A array of x-values, with ``len(edges) == len(vals) + 1``, + edges : array-like + The edge positions, with ``len(edges) == len(vals) + 1``, between which the curve takes on vals values. orientation : {'vertical', 'horizontal'}, default: 'vertical' + The direction of the steps. Vertical means that *values* are along + the y-axis, and edges are along the x-axis. baseline : float or None, default: 0 Determines starting value of the bounding edges or when ``fill=True``, position of lower edge. fill : bool, default: False + Whether the area under the step curve should be filled. Returns ------- diff --git a/lib/matplotlib/patches.py b/lib/matplotlib/patches.py index a616e3d77281..5caa3c7af009 100644 --- a/lib/matplotlib/patches.py +++ b/lib/matplotlib/patches.py @@ -990,7 +990,11 @@ def set_path(self, path): class StepPatch(PathPatch): - """An unclosed step path patch.""" + """ + A path patch describing a stepwise constant function. + + The path is unclosed. It starts and stops at baseline. + """ @docstring.dedent_interpd def __init__(self, values, edges, *, @@ -999,13 +1003,15 @@ def __init__(self, values, edges, *, Parameters ---------- values : array-like - An array of y-values. + The step heights. edges : array-like - A array of x-value edges, with ``len(edges) == len(vals) + 1``, + The edge positions, with ``len(edges) == len(vals) + 1``, between which the curve takes on vals values. orientation : {'vertical', 'horizontal'}, default: 'vertical' + The direction of the steps. Vertical means that *values* are along + the y-axis, and edges are along the x-axis. baseline : float or None, default: 0 Determines starting value of the bounding edges or when 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