@@ -2043,7 +2043,8 @@ def xcorr(self, x, y, normed=True, detrend=mlab.detrend_none,
20432043 #### Specialized plotting
20442044
20452045 # @_preprocess_data() # let 'plot' do the unpacking..
2046- def step (self , x , y , * args , where = 'pre' , data = None , ** kwargs ):
2046+ def step (self , x , y , * args , where = 'pre' , data = None ,
2047+ bottom = 0 , ** kwargs ):
20472048 """
20482049 Make a step plot.
20492050
@@ -2079,7 +2080,8 @@ def step(self, x, y, *args, where='pre', data=None, **kwargs):
20792080 An object with labelled data. If given, provide the label names to
20802081 plot in *x* and *y*.
20812082
2082- where : {'pre', 'post', 'mid'}, optional, default 'pre'
2083+ where : {'pre', 'post', 'mid', 'between', 'edges'}, optional
2084+ Default 'pre'
20832085 Define where the steps should be placed:
20842086
20852087 - 'pre': The y value is continued constantly to the left from
@@ -2089,6 +2091,14 @@ def step(self, x, y, *args, where='pre', data=None, **kwargs):
20892091 every *x* position, i.e. the interval ``[x[i], x[i+1])`` has the
20902092 value ``y[i]``.
20912093 - 'mid': Steps occur half-way between the *x* positions.
2094+ - 'between': Expects len(x) = len(y) + 1, steps have y[i] value on
2095+ the interval ``[x[i], x[i+1])``
2096+ - 'edges': Expects len(x) = len(y) + 1, steps have y[i] value on
2097+ the interval ``[x[i], x[i+1]), shape is closed at x[0], x[-1]``
2098+
2099+ bottom : scalar, optional, default : 0
2100+ If plotting with 'edges', sets low bound.
2101+
20922102
20932103 Returns
20942104 -------
@@ -2104,7 +2114,31 @@ def step(self, x, y, *args, where='pre', data=None, **kwargs):
21042114 -----
21052115 .. [notes section required to get data note injection right]
21062116 """
2107- cbook ._check_in_list (('pre' , 'post' , 'mid' ), where = where )
2117+ cbook ._check_in_list (('pre' , 'post' , 'mid' , 'between' , 'edges' ),
2118+ where = where )
2119+
2120+ if where in ['between' , 'edges' ]:
2121+ if len (x ) == len (y ) or abs (len (x )- len (y )) > 1 :
2122+ raise ValueError (f"When plotting with 'between' or 'edges'"
2123+ f"input sizes have to be have to satisfy "
2124+ f"len(x) + 1 == len(y) or "
2125+ f"len(x) == len(y) + 1 but x "
2126+ f"and y have size { len (x )} and { len (y )} " )
2127+
2128+ if where == 'edges' :
2129+ if len (x ) + 1 == len (y ):
2130+ self .add_line (
2131+ mlines .Line2D ([bottom , x [0 ]], [y [0 ], y [0 ]]))
2132+ self .add_line (
2133+ mlines .Line2D ([bottom , x [- 1 ]], [y [- 1 ], y [- 1 ]]))
2134+ elif len (x ) == len (y ) + 1 :
2135+ self .add_line (
2136+ mlines .Line2D ([x [0 ], x [0 ]], [bottom , y [0 ]]))
2137+ self .add_line (
2138+ mlines .Line2D ([x [- 1 ], x [- 1 ]], [bottom , y [- 1 ]]))
2139+
2140+ where = 'between'
2141+
21082142 kwargs ['drawstyle' ] = 'steps-' + where
21092143 return self .plot (x , y , * args , data = data , ** kwargs )
21102144
@@ -5130,11 +5164,23 @@ def fill_between(self, x, y1, y2=0, where=None, interpolate=False,
51305164 kwargs ['facecolor' ] = \
51315165 self ._get_patches_for_fill .get_next_color ()
51325166
5167+ if step in ['between' ]:
5168+ if not len (x ) == len (y1 ) + 1 :
5169+ raise ValueError (f"When plotting with 'between' "
5170+ f"input sizes have to be have to satisfy "
5171+ f"len(x) == len(y1) + 1, but x "
5172+ f"and y1 have size { len (x )} and { len (y1 )} " )
5173+ else :
5174+ histlike = True
5175+ else :
5176+ histlike = False
5177+
51335178 # Handle united data, such as dates
51345179 self ._process_unit_info (xdata = x , ydata = y1 , kwargs = kwargs )
51355180 self ._process_unit_info (ydata = y2 )
51365181
51375182 # Convert the arrays so we can work with them
5183+
51385184 x = ma .masked_invalid (self .convert_xunits (x ))
51395185 y1 = ma .masked_invalid (self .convert_yunits (y1 ))
51405186 y2 = ma .masked_invalid (self .convert_yunits (y2 ))
@@ -5154,10 +5200,16 @@ def fill_between(self, x, y1, y2=0, where=None, interpolate=False,
51545200 message = "The parameter where must have the same size as x "
51555201 "in fill_between(). This will become an error in "
51565202 "future versions of Matplotlib." )
5157- where = where & ~ functools .reduce (np .logical_or ,
5158- map (np .ma .getmask , [x , y1 , y2 ]))
51595203
5160- x , y1 , y2 = np .broadcast_arrays (np .atleast_1d (x ), y1 , y2 )
5204+ if histlike :
5205+ y_arrays = [np .r_ [y1 , np .nan ],
5206+ np .r_ [y2 , np .nan ] if not y2 .shape == () else y2 ]
5207+ else :
5208+ y_arrays = [y1 , y2 ]
5209+
5210+ where = where & ~ functools .reduce (np .logical_or , map (np .ma .getmask ,
5211+ [x , * y_arrays ]))
5212+ x , y1 , y2 = np .broadcast_arrays (np .atleast_1d (x ), * y_arrays )
51615213
51625214 polys = []
51635215 for ind0 , ind1 in cbook .contiguous_regions (where ):
@@ -5319,6 +5371,17 @@ def fill_betweenx(self, y, x1, x2=0, where=None,
53195371 kwargs ['facecolor' ] = \
53205372 self ._get_patches_for_fill .get_next_color ()
53215373
5374+ if step in ['between' ]:
5375+ if not len (y ) == len (x1 ) + 1 :
5376+ raise ValueError (f"When plotting with 'between' "
5377+ f"input sizes have to be have to satisfy "
5378+ f"len(y) == len(x1) + 1, but y "
5379+ f"and x1 have size { len (y )} and { len (x1 )} " )
5380+ else :
5381+ histlike = True
5382+ else :
5383+ histlike = False
5384+
53225385 # Handle united data, such as dates
53235386 self ._process_unit_info (ydata = y , xdata = x1 , kwargs = kwargs )
53245387 self ._process_unit_info (xdata = x2 )
@@ -5343,10 +5406,16 @@ def fill_betweenx(self, y, x1, x2=0, where=None,
53435406 message = "The parameter where must have the same size as y "
53445407 "in fill_between(). This will become an error in "
53455408 "future versions of Matplotlib." )
5346- where = where & ~ functools .reduce (np .logical_or ,
5347- map (np .ma .getmask , [y , x1 , x2 ]))
53485409
5349- y , x1 , x2 = np .broadcast_arrays (np .atleast_1d (y ), x1 , x2 )
5410+ if histlike :
5411+ x_arrays = [np .r_ [x1 , np .nan ],
5412+ np .r_ [x2 , np .nan ] if not x2 .shape == () else x2 ]
5413+ else :
5414+ x_arrays = [x1 , x2 ]
5415+
5416+ where = where & ~ functools .reduce (np .logical_or , map (np .ma .getmask ,
5417+ [y , * x_arrays ]))
5418+ y , x1 , x2 = np .broadcast_arrays (np .atleast_1d (y ), * x_arrays )
53505419
53515420 polys = []
53525421 for ind0 , ind1 in cbook .contiguous_regions (where ):
0 commit comments