@@ -2011,6 +2011,58 @@ def step(self, x, y, *args, where='pre', data=None, **kwargs):
20112011 kwargs ['drawstyle' ] = 'steps-' + where
20122012 return self .plot (x , y , * args , data = data , ** kwargs )
20132013
2014+ @staticmethod
2015+ def _convert_dx (dx , x0 , xconv , convert ):
2016+ """
2017+ Small helper to do logic of width conversion flexibly.
2018+
2019+ *dx* and *x0* have units, but *xconv* has already been converted
2020+ to unitless (and is an ndarray). This allows the *dx* to have units
2021+ that are different from *x0*, but are still accepted by the
2022+ ``__add__`` operator of *x0*.
2023+ """
2024+
2025+ # x should be an array...
2026+ assert type (xconv ) is np .ndarray
2027+
2028+ if xconv .size == 0 :
2029+ # xconv has already been converted, but maybe empty...
2030+ return convert (dx )
2031+
2032+ try :
2033+ # attempt to add the width to x0; this works for
2034+ # datetime+timedelta, for instance
2035+
2036+ # only use the first element of x and x0. This saves
2037+ # having to be sure addition works across the whole
2038+ # vector. This is particularly an issue if
2039+ # x0 and dx are lists so x0 + dx just concatenates the lists.
2040+ # We can't just cast x0 and dx to numpy arrays because that
2041+ # removes the units from unit packages like `pint` that
2042+ # wrap numpy arrays.
2043+ try :
2044+ x0 = x0 [0 ]
2045+ except (TypeError , IndexError , KeyError ):
2046+ x0 = x0
2047+
2048+ try :
2049+ x = xconv [0 ]
2050+ except (TypeError , IndexError , KeyError ):
2051+ x = xconv
2052+
2053+ delist = False
2054+ if not np .iterable (dx ):
2055+ dx = [dx ]
2056+ delist = True
2057+ dx = [convert (x0 + ddx ) - x for ddx in dx ]
2058+ if delist :
2059+ dx = dx [0 ]
2060+ except (TypeError , AttributeError ) as e :
2061+ # but doesn't work for 'string' + float, so just
2062+ # see if the converter works on the float.
2063+ dx = convert (dx )
2064+ return dx
2065+
20142066 @_preprocess_data ()
20152067 @docstring .dedent_interpd
20162068 def bar (self , x , height , width = 0.8 , bottom = None , * , align = "center" ,
@@ -2175,16 +2227,17 @@ def bar(self, x, height, width=0.8, bottom=None, *, align="center",
21752227 # lets do some conversions now since some types cannot be
21762228 # subtracted uniformly
21772229 if self .xaxis is not None :
2178- x = self .convert_xunits (x )
2179- width = self .convert_xunits (width )
2230+ x0 = x
2231+ x = np .asarray (self .convert_xunits (x ))
2232+ width = self ._convert_dx (width , x0 , x , self .convert_xunits )
21802233 if xerr is not None :
2181- xerr = self .convert_xunits (xerr )
2182-
2234+ xerr = self ._convert_dx (xerr , x0 , x , self .convert_xunits )
21832235 if self .yaxis is not None :
2184- y = self .convert_yunits (y )
2185- height = self .convert_yunits (height )
2236+ y0 = y
2237+ y = np .asarray (self .convert_yunits (y ))
2238+ height = self ._convert_dx (height , y0 , y , self .convert_yunits )
21862239 if yerr is not None :
2187- yerr = self .convert_yunits (yerr )
2240+ yerr = self ._convert_dx (yerr , y0 , y , self . convert_yunits )
21882241
21892242 x , height , width , y , linewidth = np .broadcast_arrays (
21902243 # Make args iterable too.
@@ -2465,10 +2518,19 @@ def broken_barh(self, xranges, yrange, **kwargs):
24652518 self ._process_unit_info (xdata = xdata ,
24662519 ydata = ydata ,
24672520 kwargs = kwargs )
2468- xranges = self .convert_xunits (xranges )
2469- yrange = self .convert_yunits (yrange )
2470-
2471- col = mcoll .BrokenBarHCollection (xranges , yrange , ** kwargs )
2521+ xranges_conv = []
2522+ for xr in xranges :
2523+ if len (xr ) != 2 :
2524+ raise ValueError ('each range in xrange must be a sequence '
2525+ 'with two elements (i.e. an Nx2 array)' )
2526+ # convert the absolute values, not the x and dx...
2527+ x_conv = np .asarray (self .convert_xunits (xr [0 ]))
2528+ x1 = self ._convert_dx (xr [1 ], xr [0 ], x_conv , self .convert_xunits )
2529+ xranges_conv .append ((x_conv , x1 ))
2530+
2531+ yrange_conv = self .convert_yunits (yrange )
2532+
2533+ col = mcoll .BrokenBarHCollection (xranges_conv , yrange_conv , ** kwargs )
24722534 self .add_collection (col , autolim = True )
24732535 self .autoscale_view ()
24742536
0 commit comments