@@ -3282,10 +3282,34 @@ def errorbar(self, x, y, yerr=None, xerr=None,
32823282 x = np .asarray (x , dtype = object )
32833283 if not isinstance (y , np .ndarray ):
32843284 y = np .asarray (y , dtype = object )
3285+
3286+ def _upcast_err (err ):
3287+ """
3288+ Safely handle tuple of containers that carry units.
3289+
3290+ If the units are carried on the values then casting to object
3291+ arrays preserves the units, but if the units are on the containers
3292+ this will not work.
3293+
3294+ This function covers the case where the input to the xerr/yerr is a
3295+ length 2 tuple of equal length ndarray-subclasses that carry the
3296+ unit information in the container.
3297+
3298+ We defer coercing the units to be consistent to the underlying unit
3299+ library (and implicitly the broadcasting).
3300+
3301+ If we do not have a tuple of nested numpy array (subclasses),
3302+ fallback to casting to an object array.
3303+
3304+ """
3305+ if np .iterable (err ) and isinstance (err [0 ], np .ndarray ):
3306+ return type (err [0 ])(err )
3307+ return np .asarray (err , dtype = object )
3308+
32853309 if xerr is not None and not isinstance (xerr , np .ndarray ):
3286- xerr = np . asarray (xerr , dtype = object )
3310+ xerr = _upcast_err (xerr )
32873311 if yerr is not None and not isinstance (yerr , np .ndarray ):
3288- yerr = np . asarray (yerr , dtype = object )
3312+ yerr = _upcast_err (yerr )
32893313 x , y = np .atleast_1d (x , y ) # Make sure all the args are iterable.
32903314 if len (x ) != len (y ):
32913315 raise ValueError ("'x' and 'y' must have the same size" )
0 commit comments