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

Skip to content

Commit bb5e68b

Browse files
committed
List-based _process_unit_info API.
Better if multiple datasets need to be converted at once...
1 parent 420edf8 commit bb5e68b

File tree

4 files changed

+66
-67
lines changed

4 files changed

+66
-67
lines changed

lib/matplotlib/axes/_axes.py

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ def axhline(self, y=0, xmin=0, xmax=1, **kwargs):
709709
ymin, ymax = self.get_ybound()
710710

711711
# Strip away the units for comparison with non-unitized bounds.
712-
yy, = self._process_unit_info({"y": y}, kwargs)
712+
yy, = self._process_unit_info([("y", y)], kwargs)
713713
scaley = (yy < ymin) or (yy > ymax)
714714

715715
trans = self.get_yaxis_transform(which='grid')
@@ -776,7 +776,7 @@ def axvline(self, x=0, ymin=0, ymax=1, **kwargs):
776776
xmin, xmax = self.get_xbound()
777777

778778
# Strip away the units for comparison with non-unitized bounds.
779-
xx, = self._process_unit_info({"x": x}, kwargs)
779+
xx, = self._process_unit_info([("x", x)], kwargs)
780780
scalex = (xx < xmin) or (xx > xmax)
781781

782782
trans = self.get_xaxis_transform(which='grid')
@@ -918,7 +918,7 @@ def axhspan(self, ymin, ymax, xmin=0, xmax=1, **kwargs):
918918

919919
# first we need to strip away the units
920920
(xmin, xmax), (ymin, ymax) = self._process_unit_info(
921-
{"x": [xmin, xmax], "y": [ymin, ymax]}, kwargs)
921+
[("x", [xmin, xmax]), ("y", [ymin, ymax])], kwargs)
922922

923923
verts = (xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)
924924
p = mpatches.Polygon(verts, **kwargs)
@@ -976,7 +976,7 @@ def axvspan(self, xmin, xmax, ymin=0, ymax=1, **kwargs):
976976

977977
# first we need to strip away the units
978978
(xmin, xmax), (ymin, ymax) = self._process_unit_info(
979-
{"x": [xmin, xmax], "y": [ymin, ymax]}, kwargs)
979+
[("x", [xmin, xmax]), ("y", [ymin, ymax])], kwargs)
980980

981981
verts = [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)]
982982
p = mpatches.Polygon(verts, **kwargs)
@@ -1022,11 +1022,8 @@ def hlines(self, y, xmin, xmax, colors=None, linestyles='solid',
10221022
"""
10231023

10241024
# We do the conversion first since not all unitized data is uniform
1025-
self._process_unit_info(
1026-
{"x": [xmin, xmax], "y": y}, kwargs, convert=False)
1027-
y = self.convert_yunits(y)
1028-
xmin = self.convert_xunits(xmin)
1029-
xmax = self.convert_xunits(xmax)
1025+
xmin, xmax, y = self._process_unit_info(
1026+
[("x", xmin), ("x", xmax), ("y", y)], kwargs)
10301027

10311028
if not np.iterable(y):
10321029
y = [y]
@@ -1102,11 +1099,8 @@ def vlines(self, x, ymin, ymax, colors=None, linestyles='solid',
11021099
"""
11031100

11041101
# We do the conversion first since not all unitized data is uniform
1105-
self._process_unit_info(
1106-
{"x": x, "y": [ymin, ymax]}, kwargs, convert=False)
1107-
x = self.convert_xunits(x)
1108-
ymin = self.convert_yunits(ymin)
1109-
ymax = self.convert_yunits(ymax)
1102+
x, ymin, ymax = self._process_unit_info(
1103+
[("x", x), ("y", ymin), ("y", ymax)], kwargs)
11101104

11111105
if not np.iterable(x):
11121106
x = [x]
@@ -1245,8 +1239,8 @@ def eventplot(self, positions, orientation='horizontal', lineoffsets=1,
12451239
.. plot:: gallery/lines_bars_and_markers/eventplot_demo.py
12461240
"""
12471241
# We do the conversion first since not all unitized data is uniform
1248-
positions, (lineoffsets, linelengths) = self._process_unit_info(
1249-
{"x": positions, "y": [lineoffsets, linelengths]}, kwargs)
1242+
positions, lineoffsets, linelengths = self._process_unit_info(
1243+
[("x", positions), ("y", lineoffsets), ("y", linelengths)], kwargs)
12501244

12511245
if not np.iterable(positions):
12521246
positions = [positions]
@@ -2269,12 +2263,12 @@ def bar(self, x, height, width=0.8, bottom=None, *, align="center",
22692263

22702264
if orientation == 'vertical':
22712265
self._process_unit_info(
2272-
{"x": x, "y": height}, kwargs, convert=False)
2266+
[("x", x), ("y", height)], kwargs, convert=False)
22732267
if log:
22742268
self.set_yscale('log', nonpositive='clip')
22752269
elif orientation == 'horizontal':
22762270
self._process_unit_info(
2277-
{"x": width, "y": y}, kwargs, convert=False)
2271+
[("x", width), ("y", y)], kwargs, convert=False)
22782272
if log:
22792273
self.set_xscale('log', nonpositive='clip')
22802274

@@ -2555,7 +2549,7 @@ def broken_barh(self, xranges, yrange, **kwargs):
25552549
else:
25562550
ydata = None
25572551
self._process_unit_info(
2558-
{"x": xdata, "y": ydata}, kwargs, convert=False)
2552+
[("x", xdata), ("y", ydata)], kwargs, convert=False)
25592553
xranges_conv = []
25602554
for xr in xranges:
25612555
if len(xr) != 2:
@@ -2675,9 +2669,9 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0,
26752669
locs, heads, *args = args
26762670

26772671
if orientation == 'vertical':
2678-
locs, heads = self._process_unit_info({"x": locs, "y": heads})
2672+
locs, heads = self._process_unit_info([("x", locs), ("y", heads)])
26792673
else:
2680-
heads, locs = self._process_unit_info({"x": heads, "y": locs})
2674+
heads, locs = self._process_unit_info([("x", heads), ("y", locs)])
26812675

26822676
# defaults for formats
26832677
if linefmt is None:
@@ -3161,7 +3155,7 @@ def errorbar(self, x, y, yerr=None, xerr=None,
31613155
if int(offset) != offset:
31623156
raise ValueError("errorevery's starting index must be an integer")
31633157

3164-
self._process_unit_info({"x": x, "y": y}, kwargs, convert=False)
3158+
self._process_unit_info([("x", x), ("y", y)], kwargs, convert=False)
31653159

31663160
# Make sure all the args are iterable; use lists not arrays to preserve
31673161
# units.
@@ -4328,7 +4322,7 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
43284322
"""
43294323
# Process **kwargs to handle aliases, conflicts with explicit kwargs:
43304324

4331-
x, y = self._process_unit_info({"x": x, "y": y}, kwargs)
4325+
x, y = self._process_unit_info([("x", x), ("y", y)], kwargs)
43324326

43334327
# np.ma.ravel yields an ndarray, not a masked array,
43344328
# unless its argument is a masked array.
@@ -4557,7 +4551,7 @@ def reduce_C_function(C: array) -> float
45574551
%(PolyCollection)s
45584552
45594553
"""
4560-
self._process_unit_info({"x": x, "y": y}, kwargs, convert=False)
4554+
self._process_unit_info([("x", x), ("y", y)], kwargs, convert=False)
45614555

45624556
x, y, C = cbook.delete_masked_points(x, y, C)
45634557

@@ -4906,7 +4900,7 @@ def quiverkey(self, Q, X, Y, U, label, **kw):
49064900
def _quiver_units(self, args, kw):
49074901
if len(args) > 3:
49084902
x, y = args[0:2]
4909-
x, y = self._process_unit_info({"x": x, "y": y}, kw)
4903+
x, y = self._process_unit_info([("x", x), ("y", y)], kw)
49104904
return (x, y) + args[2:]
49114905
return args
49124906

@@ -5092,9 +5086,9 @@ def _fill_between_x_or_y(
50925086
self._get_patches_for_fill.get_next_color()
50935087

50945088
# Handle united data, such as dates
5095-
self._process_unit_info({ind_dir: ind, dep_dir: dep1}, kwargs,
5096-
convert=False)
5097-
self._process_unit_info({dep_dir: dep2}, convert=False)
5089+
self._process_unit_info(
5090+
[(ind_dir, ind), (dep_dir, dep1), (dep_dir, dep2)], kwargs,
5091+
convert=False)
50985092

50995093
# Convert the arrays so we can work with them
51005094
ind = ma.masked_invalid(getattr(self, f"convert_{ind_dir}units")(ind))
@@ -5716,7 +5710,7 @@ def pcolor(self, *args, shading=None, alpha=None, norm=None, cmap=None,
57165710
Ny, Nx = X.shape
57175711

57185712
# unit conversion allows e.g. datetime objects as axis values
5719-
X, Y = self._process_unit_info({"x": X, "y": Y}, kwargs)
5713+
X, Y = self._process_unit_info([("x", X), ("y", Y)], kwargs)
57205714

57215715
# convert to MA, if necessary.
57225716
C = ma.asarray(C)
@@ -5991,7 +5985,7 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
59915985
X = X.ravel()
59925986
Y = Y.ravel()
59935987
# unit conversion allows e.g. datetime objects as axis values
5994-
X, Y = self._process_unit_info({"x": X, "y": Y}, kwargs)
5988+
X, Y = self._process_unit_info([("x", X), ("y", Y)], kwargs)
59955989

59965990
# convert to one dimensional arrays
59975991
C = C.ravel()
@@ -6475,11 +6469,11 @@ def hist(self, x, bins=None, range=None, density=False, weights=None,
64756469
# one at a time.
64766470
if orientation == "vertical":
64776471
convert_units = self.convert_yunits
6478-
x = [*self._process_unit_info({"x": x[0]}, kwargs),
6472+
x = [*self._process_unit_info([("x", x[0])], kwargs),
64796473
*map(convert_units, x[1:])]
64806474
else: # horizontal
64816475
convert_units = self.convert_yunits
6482-
x = [*self._process_unit_info({"y": x[0]}, kwargs),
6476+
x = [*self._process_unit_info([("y", x[0])], kwargs),
64836477
*map(convert_units, x[1:])]
64846478

64856479
if bin_range is not None:
@@ -6768,7 +6762,7 @@ def stairs(self, values, edges=None, *,
67686762
edges = np.arange(len(values) + 1)
67696763

67706764
edges, values = self._process_unit_info(
6771-
{"x": edges, "y": values}, kwargs)
6765+
[("x", edges), ("y", values)], kwargs)
67726766

67736767
patch = mpatches.StepPatch(values,
67746768
edges,

lib/matplotlib/axes/_base.py

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2215,8 +2215,9 @@ def _process_unit_info(self, datasets=None, kwargs=None, *, convert=True):
22152215
22162216
Parameters
22172217
----------
2218-
datasets : dict
2219-
Mapping of axis names (per `._get_axis_map`) to datasets.
2218+
datasets : list
2219+
List of (axis_name, dataset) pairs (where the axis name is defined
2220+
as in `._get_axis_map`.
22202221
kwargs : dict
22212222
Other parameters from which unit info (i.e., the *xunits*,
22222223
*yunits*, *zunits* (for 3D axes), *runits* and *thetaunits* (for
@@ -2228,39 +2229,43 @@ def _process_unit_info(self, datasets=None, kwargs=None, *, convert=True):
22282229
Returns
22292230
-------
22302231
list
2231-
Either the original datasets (``datasets.values()``) if *convert*
2232-
is False, or the converted ones if *convert* is True (the default).
2233-
"""
2234-
datasets = datasets or {}
2235-
retval = []
2232+
Either the original datasets if *convert* is False, or the
2233+
converted ones if *convert* is True (the default).
2234+
"""
2235+
# The API makes datasets a list of pairs rather than an axis_name to
2236+
# dataset mapping because it is sometimes necessary to process multiple
2237+
# datasets for a single axis, and concatenating them may be tricky
2238+
# (e.g. if some are scalars, etc.).
2239+
datasets = datasets or []
2240+
kwargs = kwargs or {}
22362241
axis_map = self._get_axis_map()
2237-
for axis_name in datasets:
2238-
if axis_name not in axis_map:
2239-
raise ValueError(f"Invalid axis name: {axis_name!r}")
2242+
for axis_name, data in datasets:
2243+
try:
2244+
axis = axis_map[axis_name]
2245+
except KeyError:
2246+
raise ValueError(f"Invalid axis name: {axis_name!r}") from None
2247+
# Update from data if axis is already set but no unit is set yet.
2248+
if axis is not None and data is not None and not axis.have_units():
2249+
axis.update_units(data)
22402250
for axis_name, axis in axis_map.items():
22412251
# Return if no axis is set.
22422252
if axis is None:
22432253
continue
2244-
data = datasets.get(axis_name)
2245-
# Update from data if no unit is set yet.
2246-
if data is not None and not axis.have_units():
2247-
axis.update_units(data)
22482254
# Check for units in the kwargs, and if present update axis.
2249-
if kwargs is not None:
2250-
units = kwargs.pop(f"{axis_name}units", axis.units)
2251-
if self.name == "polar":
2252-
# Special case: polar supports "thetaunits"/"runits".
2253-
polar_units = {"x": "thetaunits", "y": "runits"}
2254-
units = kwargs.pop(polar_units[axis_name], units)
2255-
if units != axis.units and units is not None:
2256-
axis.set_units(units)
2257-
# If the units being set imply a different converter,
2258-
# we need to update.
2259-
if data is not None:
2255+
units = kwargs.pop(f"{axis_name}units", axis.units)
2256+
if self.name == "polar":
2257+
# Special case: polar supports "thetaunits"/"runits".
2258+
polar_units = {"x": "thetaunits", "y": "runits"}
2259+
units = kwargs.pop(polar_units[axis_name], units)
2260+
if units != axis.units and units is not None:
2261+
axis.set_units(units)
2262+
# If the units being set imply a different converter,
2263+
# we need to update again.
2264+
for dataset_axis_name, data in datasets:
2265+
if dataset_axis_name == axis_name and data is not None:
22602266
axis.update_units(data)
2261-
if data is not None:
2262-
retval.append(axis.convert_units(data) if convert else data)
2263-
return retval
2267+
return [axis_map[axis_name].convert_units(data) if convert else data
2268+
for axis_name, data in datasets]
22642269

22652270
def in_axes(self, mouseevent):
22662271
"""
@@ -3412,7 +3417,7 @@ def set_xlim(self, left=None, right=None, emit=True, auto=False,
34123417
raise TypeError('Cannot pass both `xmax` and `right`')
34133418
right = xmax
34143419

3415-
self._process_unit_info({"x": (left, right)}, convert=False)
3420+
self._process_unit_info([("x", (left, right))], convert=False)
34163421
left = self._validate_converted_limits(left, self.convert_xunits)
34173422
right = self._validate_converted_limits(right, self.convert_xunits)
34183423

@@ -3737,7 +3742,7 @@ def set_ylim(self, bottom=None, top=None, emit=True, auto=False,
37373742
raise TypeError('Cannot pass both `ymax` and `top`')
37383743
top = ymax
37393744

3740-
self._process_unit_info({"y": (bottom, top)}, convert=False)
3745+
self._process_unit_info([("y", (bottom, top))], convert=False)
37413746
bottom = self._validate_converted_limits(bottom, self.convert_yunits)
37423747
top = self._validate_converted_limits(top, self.convert_yunits)
37433748

lib/matplotlib/contour.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1476,7 +1476,7 @@ def _check_xyz(self, args, kwargs):
14761476
"""
14771477
x, y = args[:2]
14781478
x, y = self.axes._process_unit_info(
1479-
{"x": x, "y": y}, kwargs, convert=True)
1479+
[("x", x), ("y", y)], kwargs, convert=True)
14801480

14811481
x = np.asarray(x, dtype=np.float64)
14821482
y = np.asarray(y, dtype=np.float64)

lib/mpl_toolkits/mplot3d/axes3d.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,7 @@ def set_xlim3d(self, left=None, right=None, emit=True, auto=False,
724724
raise TypeError('Cannot pass both `xmax` and `right`')
725725
right = xmax
726726

727-
self._process_unit_info({"x": (left, right)}, convert=False)
727+
self._process_unit_info([("x", (left, right))], convert=False)
728728
left = self._validate_converted_limits(left, self.convert_xunits)
729729
right = self._validate_converted_limits(right, self.convert_xunits)
730730

@@ -778,7 +778,7 @@ def set_ylim3d(self, bottom=None, top=None, emit=True, auto=False,
778778
raise TypeError('Cannot pass both `ymax` and `top`')
779779
top = ymax
780780

781-
self._process_unit_info({"y": (bottom, top)}, convert=False)
781+
self._process_unit_info([("y", (bottom, top))], convert=False)
782782
bottom = self._validate_converted_limits(bottom, self.convert_yunits)
783783
top = self._validate_converted_limits(top, self.convert_yunits)
784784

@@ -833,7 +833,7 @@ def set_zlim3d(self, bottom=None, top=None, emit=True, auto=False,
833833
raise TypeError('Cannot pass both `zmax` and `top`')
834834
top = zmax
835835

836-
self._process_unit_info({"z": (bottom, top)}, convert=False)
836+
self._process_unit_info([("z", (bottom, top))], convert=False)
837837
bottom = self._validate_converted_limits(bottom, self.convert_zunits)
838838
top = self._validate_converted_limits(top, self.convert_zunits)
839839

0 commit comments

Comments
 (0)