Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion galleries/examples/event_handling/resample.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ def __init__(self, xdata, y1data, y2data):
def plot(self, ax):
x, y1, y2 = self._downsample(self.origXData.min(), self.origXData.max())
(self.line,) = ax.plot(x, y1, 'o-')
self.poly_collection = ax.fill_between(x, y1, y2, step="pre", color="r")
self.poly_collection = ax.fill_between(x, y1, y2,
drawstyle="steps-pre", color="r")

def _downsample(self, xstart, xend):
# get the points in the view range
Expand Down
43 changes: 27 additions & 16 deletions lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6074,7 +6074,7 @@ def fill(self, *args, data=None, **kwargs):

def _fill_between_x_or_y(
self, ind_dir, ind, dep1, dep2=0, *,
where=None, interpolate=False, step=None, **kwargs):
where=None, interpolate=False, drawstyle=None, step=None, **kwargs):
# Common implementation between fill_between (*ind_dir*="x") and
# fill_betweenx (*ind_dir*="y"). *ind* is the independent variable,
# *dep* the dependent variable. The docstring below is interpolated
Expand Down Expand Up @@ -6126,18 +6126,26 @@ def _fill_between_x_or_y(
Setting *interpolate* to *True* will calculate the actual
intersection point and extend the filled region up to this point.

step : {{'pre', 'post', 'mid'}}, optional
Define *step* if the filling should be a step function,
i.e. constant in between *{ind}*. The value determines where the
drawstyle : {{'steps', 'steps-pre', 'steps-post', 'steps-mid'}}, optional
Define *drawstyle* if the filling should be a step function,
i.e. constant in between *t*. The value determines where the
step will occur:

- 'pre': The {dep} value is continued constantly to the left from
every *{ind}* position, i.e. the interval ``({ind}[i-1], {ind}[i]]``
has the value ``{dep}[i]``.
- 'post': The y value is continued constantly to the right from
every *{ind}* position, i.e. the interval ``[{ind}[i], {ind}[i+1])``
has the value ``{dep}[i]``.
- 'mid': Steps occur half-way between the *{ind}* positions.
- 'steps-pre' or 'steps': The f value is continued constantly to the left
from every *t* position, i.e. the interval ``(t[i-1], t[i]]`` has the
value ``f[i]``.
- 'steps-post': The y value is continued constantly to the right from
every *x* position, i.e. the interval ``[t[i], t[i+1])`` has the
value ``f[i]``.
- 'steps-mid': Steps occur half-way between the *t* positions.

step : {{'pre', 'post', 'mid'}}, optional

.. admonition:: Discouraged

This parameter is discouraged in favor of *drawstyle*. The effect is the
same as the corresponding *drawstyle* value; e.g. ``step='pre'`` is the
same as ``drawstyle='steps-pre'``.

Returns
-------
Expand Down Expand Up @@ -6172,7 +6180,8 @@ def _fill_between_x_or_y(

collection = mcoll.FillBetweenPolyCollection(
ind_dir, ind, dep1, dep2,
where=where, interpolate=interpolate, step=step, **kwargs)
where=where, interpolate=interpolate,
drawstyle=drawstyle, step=step, **kwargs)

self.add_collection(collection)
return collection
Expand All @@ -6183,10 +6192,11 @@ def _fill_between_process_units(self, ind_dir, dep_dir, ind, dep1, dep2, **kwarg
[(ind_dir, ind), (dep_dir, dep1), (dep_dir, dep2)], kwargs))

def fill_between(self, x, y1, y2=0, where=None, interpolate=False,
step=None, **kwargs):
drawstyle=None, step=None, **kwargs):
return self._fill_between_x_or_y(
"x", x, y1, y2,
where=where, interpolate=interpolate, step=step, **kwargs)
where=where, interpolate=interpolate, drawstyle=drawstyle, step=step,
**kwargs)

if _fill_between_x_or_y.__doc__:
fill_between.__doc__ = _fill_between_x_or_y.__doc__.format(
Expand All @@ -6197,10 +6207,11 @@ def fill_between(self, x, y1, y2=0, where=None, interpolate=False,
replace_names=["x", "y1", "y2", "where"])

def fill_betweenx(self, y, x1, x2=0, where=None,
step=None, interpolate=False, **kwargs):
drawstyle=None, step=None, interpolate=False, **kwargs):
return self._fill_between_x_or_y(
"y", y, x1, x2,
where=where, interpolate=interpolate, step=step, **kwargs)
where=where, interpolate=interpolate, drawstyle=drawstyle, step=step,
**kwargs)

if _fill_between_x_or_y.__doc__:
fill_betweenx.__doc__ = _fill_between_x_or_y.__doc__.format(
Expand Down
4 changes: 3 additions & 1 deletion lib/matplotlib/axes/_axes.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ from matplotlib.patches import Rectangle, FancyArrow, Polygon, StepPatch
from matplotlib.quiver import Quiver, QuiverKey, Barbs
from matplotlib.text import Annotation, Text
from matplotlib.transforms import Transform
from matplotlib.typing import CoordsType
from matplotlib.typing import CoordsType, DrawStyleType
import matplotlib.tri as mtri
import matplotlib.table as mtable
import matplotlib.stackplot as mstack
Expand Down Expand Up @@ -483,6 +483,7 @@ class Axes(_AxesBase):
y2: ArrayLike | float = ...,
where: Sequence[bool] | None = ...,
interpolate: bool = ...,
drawstyle: DrawStyleType | None = ...,
step: Literal["pre", "post", "mid"] | None = ...,
*,
data=...,
Expand All @@ -494,6 +495,7 @@ class Axes(_AxesBase):
x1: ArrayLike | float,
x2: ArrayLike | float = ...,
where: Sequence[bool] | None = ...,
drawstyle: DrawStyleType | None = ...,
step: Literal["pre", "post", "mid"] | None = ...,
interpolate: bool = ...,
*,
Expand Down
35 changes: 25 additions & 10 deletions lib/matplotlib/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -1384,7 +1384,7 @@ class FillBetweenPolyCollection(PolyCollection):
"""
def __init__(
self, t_direction, t, f1, f2, *,
where=None, interpolate=False, step=None, **kwargs):
where=None, interpolate=False, drawstyle=None, step=None, **kwargs):
"""
Parameters
----------
Expand Down Expand Up @@ -1426,18 +1426,26 @@ def __init__(
Setting *interpolate* to *True* will calculate the actual
intersection point and extend the filled region up to this point.

step : {{'pre', 'post', 'mid'}}, optional
Define *step* if the filling should be a step function,
drawstyle : {'steps', 'steps-pre', 'steps-post', 'steps-mid'}, optional
Define *drawstyle* if the filling should be a step function,
i.e. constant in between *t*. The value determines where the
step will occur:

- 'pre': The f value is continued constantly to the left from
every *t* position, i.e. the interval ``(t[i-1], t[i]]`` has the
- 'steps-pre' or 'steps': The f value is continued constantly to the left
from every *t* position, i.e. the interval ``(t[i-1], t[i]]`` has the
value ``f[i]``.
- 'post': The y value is continued constantly to the right from
- 'steps-post': The y value is continued constantly to the right from
every *x* position, i.e. the interval ``[t[i], t[i+1])`` has the
value ``f[i]``.
- 'mid': Steps occur half-way between the *t* positions.
- 'steps-mid': Steps occur half-way between the *t* positions.

step : {{'pre', 'post', 'mid'}}, optional

.. admonition:: Discouraged

This parameter is discouraged in favor of *drawstyle*. The effect is the
same as the corresponding *drawstyle* value; e.g. ``step='pre'`` is the
same as ``drawstyle='steps-pre'``.

**kwargs
Forwarded to `.PolyCollection`.
Expand All @@ -1448,7 +1456,14 @@ def __init__(
"""
self.t_direction = t_direction
self._interpolate = interpolate
self._step = step
if drawstyle is not None and step is not None:
raise ValueError(
"Using drawstyle and step simultaneously is not supported as they "
"specify the same behavior. It is recommended the more modern "
"parameter drawstype for new code.")
self._drawstyle = drawstyle
if step is not None:
self._drawstyle = f"steps-{step}"
verts = self._make_verts(t, f1, f2, where)
super().__init__(verts, **kwargs)

Expand Down Expand Up @@ -1572,8 +1587,8 @@ def _make_verts_for_region(self, t, f1, f2, idx0, idx1):
t_slice = t[idx0:idx1]
f1_slice = f1[idx0:idx1]
f2_slice = f2[idx0:idx1]
if self._step is not None:
step_func = cbook.STEP_LOOKUP_MAP["steps-" + self._step]
if self._drawstyle is not None:
step_func = cbook.STEP_LOOKUP_MAP[self._drawstyle]
t_slice, f1_slice, f2_slice = step_func(t_slice, f1_slice, f2_slice)

if self._interpolate:
Expand Down
3 changes: 2 additions & 1 deletion lib/matplotlib/collections.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ from .path import Path
from .patches import Patch
from .ticker import Locator, Formatter
from .tri import Triangulation
from .typing import ColorType, LineStyleType, CapStyleType, JoinStyleType
from .typing import ColorType, DrawStyleType, LineStyleType, CapStyleType, JoinStyleType

class Collection(colorizer.ColorizingArtist):
def __init__(
Expand Down Expand Up @@ -124,6 +124,7 @@ class FillBetweenPolyCollection(PolyCollection):
*,
where: Sequence[bool] | None = ...,
interpolate: bool = ...,
drawstyle: DrawStyleType | None = ...,
step: Literal["pre", "post", "mid"] | None = ...,
**kwargs,
) -> None: ...
Expand Down
8 changes: 4 additions & 4 deletions lib/matplotlib/tests/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2709,15 +2709,15 @@ def test_stairs_fill(fig_test, fig_ref):

# # Ref
ref_axes = fig_ref.subplots(2, 2).flatten()
ref_axes[0].fill_between(bins, np.append(h, h[-1]), step='post', lw=0)
ref_axes[0].fill_between(bins, np.append(h, h[-1]), drawstyle='steps-post', lw=0)
ref_axes[0].set_ylim(0, None)
ref_axes[1].fill_betweenx(bins, np.append(h, h[-1]), step='post', lw=0)
ref_axes[1].fill_betweenx(bins, np.append(h, h[-1]), drawstyle='steps-post', lw=0)
ref_axes[1].set_xlim(0, None)
ref_axes[2].fill_between(bins, np.append(h, h[-1]),
np.ones(len(h)+1)*bs, step='post', lw=0)
np.ones(len(h)+1)*bs, drawstyle='steps-post', lw=0)
ref_axes[2].set_ylim(bs, None)
ref_axes[3].fill_betweenx(bins, np.append(h, h[-1]),
np.ones(len(h)+1)*bs, step='post', lw=0)
np.ones(len(h)+1)*bs, drawstyle='steps-post', lw=0)
ref_axes[3].set_xlim(bs, None)


Expand Down
Loading