Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7c4b000

Browse files
committed
FIX: make robust to units
1 parent 1dfdc29 commit 7c4b000

File tree

1 file changed

+46
-14
lines changed

1 file changed

+46
-14
lines changed

lib/matplotlib/axes/_axes.py

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2012,20 +2012,51 @@ def step(self, x, y, *args, where='pre', data=None, **kwargs):
20122012
return self.plot(x, y, *args, data=data, **kwargs)
20132013

20142014
@staticmethod
2015-
def _convert_dx(dx, x0, x, convert):
2015+
def _convert_dx(dx, x0, xconv, convert):
20162016
"""
20172017
Small helper to do logic of width conversion flexibly.
20182018
2019-
*dx* and *x0* have units, but *x* has already been converted
2020-
to unitless. This allows the *dx* to have units that are
2021-
different from *x0*, but are still accepted by the ``__add__``
2022-
operator of *x0*.
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*.
20232023
"""
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+
20242032
try:
20252033
# attempt to add the width to x0; this works for
20262034
# datetime+timedelta, for instance
2027-
dx = convert(x0 + dx) - x
2028-
except (TypeError, AttributeError):
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`.
2042+
try:
2043+
x0 = x0[0]
2044+
except (TypeError, IndexError, KeyError):
2045+
x0 = x0
2046+
2047+
try:
2048+
x = xconv[0]
2049+
except (TypeError, IndexError, KeyError):
2050+
x = xconv
2051+
2052+
delist = False
2053+
if not np.iterable(dx):
2054+
dx = [dx]
2055+
delist = True
2056+
dx = [convert(x0 + ddx) - x for ddx in dx]
2057+
if delist:
2058+
dx = dx[0]
2059+
except (TypeError, AttributeError) as e:
20292060
# but doesn't work for 'string' + float, so just
20302061
# see if the converter works on the float.
20312062
dx = convert(dx)
@@ -2192,26 +2223,27 @@ def bar(self, x, height, width=0.8, bottom=None, *, align="center",
21922223
else:
21932224
raise ValueError('invalid orientation: %s' % orientation)
21942225

2195-
x, height, width, y, linewidth = np.broadcast_arrays(
2196-
# Make args iterable too.
2197-
np.atleast_1d(x), height, width, y, linewidth)
21982226

21992227
# lets do some conversions now since some types cannot be
22002228
# subtracted uniformly
22012229
if self.xaxis is not None:
22022230
x0 = x
2203-
x = self.convert_xunits(x)
2231+
x = np.asarray(self.convert_xunits(x))
22042232
width = self._convert_dx(width, x0, x, self.convert_xunits)
22052233
if xerr is not None:
22062234
xerr = self._convert_dx(xerr, x0, x, self.convert_xunits)
2207-
22082235
if self.yaxis is not None:
22092236
y0 = y
2210-
y = self.convert_yunits(y)
2237+
y = np.asarray(self.convert_yunits(y))
22112238
height = self._convert_dx(height, y0, y, self.convert_yunits)
22122239
if yerr is not None:
22132240
yerr = self._convert_dx(yerr, y0, y, self.convert_yunits)
22142241

2242+
x, height, width, y, linewidth = np.broadcast_arrays(
2243+
# Make args iterable too.
2244+
np.atleast_1d(x), height, width, y, linewidth)
2245+
2246+
22152247
# Now that units have been converted, set the tick locations.
22162248
if orientation == 'vertical':
22172249
tick_label_axis = self.xaxis
@@ -2493,7 +2525,7 @@ def broken_barh(self, xranges, yrange, **kwargs):
24932525
raise ValueError('each range in xrange must be a sequence '
24942526
'with two elements (i.e. an Nx2 array)')
24952527
# convert the absolute values, not the x and dx...
2496-
x_conv = self.convert_xunits(xr[0])
2528+
x_conv = np.asarray(self.convert_xunits(xr[0]))
24972529
x1 = self._convert_dx(xr[1], xr[0], x_conv, self.convert_xunits)
24982530
xranges_conv.append((x_conv, x1))
24992531

0 commit comments

Comments
 (0)