Skip to content

Commit 8b3a96b

Browse files
committed
Introduce parameter drawstyle as a replacement for step in fill_between
() Closes matplotlib#29653. For now, I'm just discouraging step in favor of the new drawstyle. It's not important enough to warrant a direct deprecation. However, I anticipate that we may deprecate and eventually remove on a timescale of years.
1 parent bcec6e7 commit 8b3a96b

6 files changed

Lines changed: 63 additions & 33 deletions

File tree

galleries/examples/event_handling/resample.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ def __init__(self, xdata, y1data, y2data):
3232
def plot(self, ax):
3333
x, y1, y2 = self._downsample(self.origXData.min(), self.origXData.max())
3434
(self.line,) = ax.plot(x, y1, 'o-')
35-
self.poly_collection = ax.fill_between(x, y1, y2, step="pre", color="r")
35+
self.poly_collection = ax.fill_between(x, y1, y2,
36+
drawstyle="steps-pre", color="r")
3637

3738
def _downsample(self, xstart, xend):
3839
# get the points in the view range

lib/matplotlib/axes/_axes.py

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6074,7 +6074,7 @@ def fill(self, *args, data=None, **kwargs):
60746074

60756075
def _fill_between_x_or_y(
60766076
self, ind_dir, ind, dep1, dep2=0, *,
6077-
where=None, interpolate=False, step=None, **kwargs):
6077+
where=None, interpolate=False, drawstyle=None, step=None, **kwargs):
60786078
# Common implementation between fill_between (*ind_dir*="x") and
60796079
# fill_betweenx (*ind_dir*="y"). *ind* is the independent variable,
60806080
# *dep* the dependent variable. The docstring below is interpolated
@@ -6126,18 +6126,26 @@ def _fill_between_x_or_y(
61266126
Setting *interpolate* to *True* will calculate the actual
61276127
intersection point and extend the filled region up to this point.
61286128
6129-
step : {{'pre', 'post', 'mid'}}, optional
6130-
Define *step* if the filling should be a step function,
6131-
i.e. constant in between *{ind}*. The value determines where the
6129+
drawstyle : {{'steps', 'steps-pre', 'steps-post', 'steps-mid'}}, optional
6130+
Define *drawstyle* if the filling should be a step function,
6131+
i.e. constant in between *t*. The value determines where the
61326132
step will occur:
61336133
6134-
- 'pre': The {dep} value is continued constantly to the left from
6135-
every *{ind}* position, i.e. the interval ``({ind}[i-1], {ind}[i]]``
6136-
has the value ``{dep}[i]``.
6137-
- 'post': The y value is continued constantly to the right from
6138-
every *{ind}* position, i.e. the interval ``[{ind}[i], {ind}[i+1])``
6139-
has the value ``{dep}[i]``.
6140-
- 'mid': Steps occur half-way between the *{ind}* positions.
6134+
- 'steps-pre' or 'steps': The f value is continued constantly to the left
6135+
from every *t* position, i.e. the interval ``(t[i-1], t[i]]`` has the
6136+
value ``f[i]``.
6137+
- 'steps-post': The y value is continued constantly to the right from
6138+
every *x* position, i.e. the interval ``[t[i], t[i+1])`` has the
6139+
value ``f[i]``.
6140+
- 'steps-mid': Steps occur half-way between the *t* positions.
6141+
6142+
step : {{'pre', 'post', 'mid'}}, optional
6143+
6144+
.. admonition:: Discouraged
6145+
6146+
This parameter is discouraged in favor of *drawstyle*. The effect is the
6147+
same as the corresponding *drawstyle* value; e.g. ``step='pre'`` is the
6148+
same as ``drawstyle='steps-pre'``.
61416149
61426150
Returns
61436151
-------
@@ -6172,7 +6180,8 @@ def _fill_between_x_or_y(
61726180

61736181
collection = mcoll.FillBetweenPolyCollection(
61746182
ind_dir, ind, dep1, dep2,
6175-
where=where, interpolate=interpolate, step=step, **kwargs)
6183+
where=where, interpolate=interpolate,
6184+
drawstyle=drawstyle, step=step, **kwargs)
61766185

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

61856194
def fill_between(self, x, y1, y2=0, where=None, interpolate=False,
6186-
step=None, **kwargs):
6195+
drawstyle=None, step=None, **kwargs):
61876196
return self._fill_between_x_or_y(
61886197
"x", x, y1, y2,
6189-
where=where, interpolate=interpolate, step=step, **kwargs)
6198+
where=where, interpolate=interpolate, drawstyle=drawstyle, step=step,
6199+
**kwargs)
61906200

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

61996209
def fill_betweenx(self, y, x1, x2=0, where=None,
6200-
step=None, interpolate=False, **kwargs):
6210+
drawstyle=None, step=None, interpolate=False, **kwargs):
62016211
return self._fill_between_x_or_y(
62026212
"y", y, x1, x2,
6203-
where=where, interpolate=interpolate, step=step, **kwargs)
6213+
where=where, interpolate=interpolate, drawstyle=drawstyle, step=step,
6214+
**kwargs)
62046215

62056216
if _fill_between_x_or_y.__doc__:
62066217
fill_betweenx.__doc__ = _fill_between_x_or_y.__doc__.format(

lib/matplotlib/axes/_axes.pyi

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ from matplotlib.patches import Rectangle, FancyArrow, Polygon, StepPatch
2626
from matplotlib.quiver import Quiver, QuiverKey, Barbs
2727
from matplotlib.text import Annotation, Text
2828
from matplotlib.transforms import Transform
29-
from matplotlib.typing import CoordsType
29+
from matplotlib.typing import CoordsType, DrawStyleType
3030
import matplotlib.tri as mtri
3131
import matplotlib.table as mtable
3232
import matplotlib.stackplot as mstack
@@ -483,6 +483,7 @@ class Axes(_AxesBase):
483483
y2: ArrayLike | float = ...,
484484
where: Sequence[bool] | None = ...,
485485
interpolate: bool = ...,
486+
drawstyle: DrawStyleType | None = ...,
486487
step: Literal["pre", "post", "mid"] | None = ...,
487488
*,
488489
data=...,
@@ -494,6 +495,7 @@ class Axes(_AxesBase):
494495
x1: ArrayLike | float,
495496
x2: ArrayLike | float = ...,
496497
where: Sequence[bool] | None = ...,
498+
drawstyle: DrawStyleType | None = ...,
497499
step: Literal["pre", "post", "mid"] | None = ...,
498500
interpolate: bool = ...,
499501
*,

lib/matplotlib/collections.py

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,7 +1384,7 @@ class FillBetweenPolyCollection(PolyCollection):
13841384
"""
13851385
def __init__(
13861386
self, t_direction, t, f1, f2, *,
1387-
where=None, interpolate=False, step=None, **kwargs):
1387+
where=None, interpolate=False, drawstyle=None, step=None, **kwargs):
13881388
"""
13891389
Parameters
13901390
----------
@@ -1426,18 +1426,26 @@ def __init__(
14261426
Setting *interpolate* to *True* will calculate the actual
14271427
intersection point and extend the filled region up to this point.
14281428
1429-
step : {{'pre', 'post', 'mid'}}, optional
1430-
Define *step* if the filling should be a step function,
1429+
drawstyle : {'steps', 'steps-pre', 'steps-post', 'steps-mid'}, optional
1430+
Define *drawstyle* if the filling should be a step function,
14311431
i.e. constant in between *t*. The value determines where the
14321432
step will occur:
14331433
1434-
- 'pre': The f value is continued constantly to the left from
1435-
every *t* position, i.e. the interval ``(t[i-1], t[i]]`` has the
1434+
- 'steps-pre' or 'steps': The f value is continued constantly to the left
1435+
from every *t* position, i.e. the interval ``(t[i-1], t[i]]`` has the
14361436
value ``f[i]``.
1437-
- 'post': The y value is continued constantly to the right from
1437+
- 'steps-post': The y value is continued constantly to the right from
14381438
every *x* position, i.e. the interval ``[t[i], t[i+1])`` has the
14391439
value ``f[i]``.
1440-
- 'mid': Steps occur half-way between the *t* positions.
1440+
- 'steps-mid': Steps occur half-way between the *t* positions.
1441+
1442+
step : {{'pre', 'post', 'mid'}}, optional
1443+
1444+
.. admonition:: Discouraged
1445+
1446+
This parameter is discouraged in favor of *drawstyle*. The effect is the
1447+
same as the corresponding *drawstyle* value; e.g. ``step='pre'`` is the
1448+
same as ``drawstyle='steps-pre'``.
14411449
14421450
**kwargs
14431451
Forwarded to `.PolyCollection`.
@@ -1448,7 +1456,14 @@ def __init__(
14481456
"""
14491457
self.t_direction = t_direction
14501458
self._interpolate = interpolate
1451-
self._step = step
1459+
if drawstyle is not None and step is not None:
1460+
raise ValueError(
1461+
"Using drawstyle and step simultaneously is not supported as they "
1462+
"specify the same behavior. It is recommended the more modern "
1463+
"parameter drawstype for new code.")
1464+
self._drawstyle = drawstyle
1465+
if step is not None:
1466+
self._drawstyle = f"steps-{step}"
14521467
verts = self._make_verts(t, f1, f2, where)
14531468
super().__init__(verts, **kwargs)
14541469

@@ -1572,8 +1587,8 @@ def _make_verts_for_region(self, t, f1, f2, idx0, idx1):
15721587
t_slice = t[idx0:idx1]
15731588
f1_slice = f1[idx0:idx1]
15741589
f2_slice = f2[idx0:idx1]
1575-
if self._step is not None:
1576-
step_func = cbook.STEP_LOOKUP_MAP["steps-" + self._step]
1590+
if self._drawstyle is not None:
1591+
step_func = cbook.STEP_LOOKUP_MAP[self._drawstyle]
15771592
t_slice, f1_slice, f2_slice = step_func(t_slice, f1_slice, f2_slice)
15781593

15791594
if self._interpolate:

lib/matplotlib/collections.pyi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ from .path import Path
1313
from .patches import Patch
1414
from .ticker import Locator, Formatter
1515
from .tri import Triangulation
16-
from .typing import ColorType, LineStyleType, CapStyleType, JoinStyleType
16+
from .typing import ColorType, DrawStyleType, LineStyleType, CapStyleType, JoinStyleType
1717

1818
class Collection(colorizer.ColorizingArtist):
1919
def __init__(
@@ -124,6 +124,7 @@ class FillBetweenPolyCollection(PolyCollection):
124124
*,
125125
where: Sequence[bool] | None = ...,
126126
interpolate: bool = ...,
127+
drawstyle: DrawStyleType | None = ...,
127128
step: Literal["pre", "post", "mid"] | None = ...,
128129
**kwargs,
129130
) -> None: ...

lib/matplotlib/tests/test_axes.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2709,15 +2709,15 @@ def test_stairs_fill(fig_test, fig_ref):
27092709

27102710
# # Ref
27112711
ref_axes = fig_ref.subplots(2, 2).flatten()
2712-
ref_axes[0].fill_between(bins, np.append(h, h[-1]), step='post', lw=0)
2712+
ref_axes[0].fill_between(bins, np.append(h, h[-1]), drawstyle='steps-post', lw=0)
27132713
ref_axes[0].set_ylim(0, None)
2714-
ref_axes[1].fill_betweenx(bins, np.append(h, h[-1]), step='post', lw=0)
2714+
ref_axes[1].fill_betweenx(bins, np.append(h, h[-1]), drawstyle='steps-post', lw=0)
27152715
ref_axes[1].set_xlim(0, None)
27162716
ref_axes[2].fill_between(bins, np.append(h, h[-1]),
2717-
np.ones(len(h)+1)*bs, step='post', lw=0)
2717+
np.ones(len(h)+1)*bs, drawstyle='steps-post', lw=0)
27182718
ref_axes[2].set_ylim(bs, None)
27192719
ref_axes[3].fill_betweenx(bins, np.append(h, h[-1]),
2720-
np.ones(len(h)+1)*bs, step='post', lw=0)
2720+
np.ones(len(h)+1)*bs, drawstyle='steps-post', lw=0)
27212721
ref_axes[3].set_xlim(bs, None)
27222722

27232723

0 commit comments

Comments
 (0)