Skip to content

Commit a11d181

Browse files
committed
Fix bugs with error bound legend entries, passing 'labels' to legend_kw'
1 parent 02417c8 commit a11d181

File tree

1 file changed

+35
-17
lines changed

1 file changed

+35
-17
lines changed

proplot/axes/plot.py

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2184,6 +2184,23 @@ def text_wrapper(
21842184
return obj
21852185

21862186

2187+
def _iter_legend_objects(objs):
2188+
"""
2189+
Retrieve the (object, label) pairs for objects with actual labels
2190+
from nested lists and tuples of objects.
2191+
"""
2192+
# Account for (1) multiple columns of data, (2) functions that return
2193+
# multiple values (e.g. hist() returns (bins, values, patches)), and
2194+
# (3) matplotlib.Collection list subclasses.
2195+
if isinstance(objs, (list, tuple)):
2196+
for obj in objs:
2197+
yield from _iter_legend_objects(obj)
2198+
elif hasattr(objs, 'get_label'):
2199+
label = objs.get_label()
2200+
if label and label[:1] != '_':
2201+
yield (objs, label)
2202+
2203+
21872204
def cycle_changer(
21882205
self, func, *args,
21892206
cycle=None, cycle_kw=None,
@@ -2253,18 +2270,29 @@ def cycle_changer(
22532270
proplot.constructor.Cycle
22542271
proplot.constructor.Colors
22552272
"""
2256-
# Parse input args
2273+
# Parse positional args
22572274
# NOTE: Requires standardize_1d wrapper before reaching this. Also note
22582275
# that the 'x' coordinates are sometimes ignored below.
22592276
name = func.__name__
2260-
autoformat = rc['autoformat'] # possibly manipulated by standardize_[12]d
22612277
if not args:
22622278
return func(self, *args, **kwargs)
22632279
x, y, *args = args
22642280
ys = (y,)
22652281
if len(args) >= 1 and name in ('fill_between', 'fill_betweenx'):
22662282
ys, args = (y, args[0]), args[1:]
2283+
# Parse keyword args
2284+
autoformat = rc['autoformat'] # possibly manipulated by standardize_[12]d
22672285
barh = stacked = False
2286+
cycle_kw = cycle_kw or {}
2287+
legend_kw = legend_kw or {}
2288+
colorbar_kw = colorbar_kw or {}
2289+
labels = _not_none(
2290+
values=values,
2291+
labels=labels,
2292+
label=label,
2293+
legend_kw_labels=legend_kw.pop('labels', None),
2294+
)
2295+
colorbar_legend_label = None # for colorbar or legend
22682296
if name in ('pie',): # add x coordinates as default pie chart labels
22692297
kwargs['labels'] = _not_none(labels, x) # TODO: move to pie wrapper?
22702298
if name in ('bar', 'fill_between', 'fill_betweenx'):
@@ -2274,9 +2302,6 @@ def cycle_changer(
22742302
width = kwargs.pop('width', 0.8) # 'width' for bar *and* barh (see bar_wrapper)
22752303
bottom = 'x' if barh else 'bottom'
22762304
kwargs.setdefault(bottom, 0) # 'x' required even though 'y' isn't for bar plots
2277-
cycle_kw = cycle_kw or {}
2278-
legend_kw = legend_kw or {}
2279-
colorbar_kw = colorbar_kw or {}
22802305

22812306
# Determine and temporarily set cycler
22822307
# NOTE: Axes cycle has no getter, only set_prop_cycle, which sets a
@@ -2348,13 +2373,10 @@ def cycle_changer(
23482373
# assumed! This is fixed in parse_1d by converting to values.
23492374
y1 = ys[0]
23502375
ncols = 1
2351-
labels = _not_none(values=values, labels=labels, label=label)
2352-
colorbar_legend_label = None # for colorbar or legend
23532376
if name in ('pie', 'boxplot', 'violinplot'):
2354-
# Pass labels directly to functions
2377+
# Functions handle multiple labels on their own
23552378
if labels is not None:
23562379
kwargs['labels'] = labels # error raised down the line
2357-
23582380
else:
23592381
# Get column count and sanitize labels
23602382
ncols = 1 if y.ndim == 1 else y.shape[1]
@@ -2497,14 +2519,10 @@ def cycle_changer(
24972519
if errobjs_join:
24982520
legobjs = [(*legobjs, *errobjs_join)[::-1]]
24992521
legobjs.extend(errobjs_separate)
2500-
for _ in range(3):
2501-
# Account for (1) multiple columns of data, (2) functions that return
2502-
# multiple values (e.g. hist() returns (bins, values, patches)), and
2503-
# (3) matplotlib.Collection list subclasses.
2504-
legobjs = [
2505-
obj[-1] if isinstance(obj, (list, tuple)) else obj
2506-
for obj in legobjs
2507-
]
2522+
try:
2523+
legobjs, labels = list(zip(*_iter_legend_objects(legobjs)))
2524+
except ValueError:
2525+
legobjs = labels = ()
25082526

25092527
# Add handles and labels
25102528
# NOTE: Important to add labels as *keyword* so users can override

0 commit comments

Comments
 (0)