Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
label=None, labels=None, values=None,
**kwargs,
):
# Parse input args
name = func.__name__
autoformat = rc['autoformat']
legend_kw = legend_kw or {}
colorbar_kw = colorbar_kw or {}
labels = _not_none(
values=values,
labels=labels,
label=label,
legend_kw_labels=legend_kw.pop('labels', None),
)
if name in ('pie',): # add x coordinates as default pie chart labels
labels = _not_none(labels, x) # TODO: move to pie wrapper?
colorbar_legend_label = None # for colorbar or legend
# Handle legend labels. Several scenarios:
# 1. Always prefer input labels
# 2. Always add labels if this is a *named* dimension.
# 3. Even if not *named* dimension add labels if labels are string
# WARNING: Most methods that accept 2D arrays use columns of data, but when
# pandas DataFrame passed to hist, boxplot, or violinplot, rows of data
# assumed! This is fixed in parse_1d by converting to values.
sample = args[-1]
ncols = 1
if name in ('pie', 'boxplot', 'violinplot'):
# Functions handle multiple labels on their own
if labels is not None:
kwargs['labels'] = labels # error raised down the line
else:
else:
kw = rc.fill(
{
'fontsize': 'suptitle.size',
'weight': 'suptitle.weight',
'color': 'suptitle.color',
'fontfamily': 'font.family'
},
context=True,
)
if suptitle or kw:
fig._update_super_title(suptitle, **kw)
# Labels
rlabels = _not_none(rightlabels=rightlabels, rlabels=rlabels)
blabels = _not_none(bottomlabels=bottomlabels, blabels=blabels)
llabels = _not_none(
rowlabels=rowlabels, leftlabels=leftlabels, llabels=llabels,
)
tlabels = _not_none(
collabels=collabels, toplabels=toplabels, tlabels=tlabels,
)
for side, labels in zip(
('left', 'right', 'top', 'bottom'),
(llabels, rlabels, tlabels, blabels)
):
kw = rc.fill(
{
'fontsize': side + 'label.size',
'weight': side + 'label.weight',
'color': side + 'label.color',
'fontfamily': 'font.family'
ygridminor = _not_none(
ygridminor, grid and axis in ('y', 'both')
and which in ('minor', 'both')
)
# Sensible defaults for spine, tick, tick label, and label locs
# NOTE: Allow tick labels to be present without ticks! User may
# want this sometimes! Same goes for spines!
xspineloc = _not_none(xloc=xloc, xspineloc=xspineloc,)
yspineloc = _not_none(yloc=yloc, yspineloc=yspineloc,)
xtickloc = _not_none(xtickloc, xspineloc, _parse_rcloc('x', 'xtick'))
ytickloc = _not_none(ytickloc, yspineloc, _parse_rcloc('y', 'ytick'))
xspineloc = _not_none(xspineloc, _parse_rcloc('x', 'axes.spines'))
yspineloc = _not_none(yspineloc, _parse_rcloc('y', 'axes.spines'))
if xtickloc != 'both':
xticklabelloc = _not_none(xticklabelloc, xtickloc)
xlabelloc = _not_none(xlabelloc, xticklabelloc)
if xlabelloc not in (None, 'bottom', 'top'): # e.g. "both"
xlabelloc = 'bottom'
if ytickloc != 'both':
yticklabelloc = _not_none(yticklabelloc, ytickloc)
ylabelloc = _not_none(ylabelloc, yticklabelloc)
if ylabelloc not in (None, 'left', 'right'):
ylabelloc = 'left'
# Begin loop
for (
x, axis,
label, color,
linewidth, gridcolor,
ticklen,
margin, bounds,
# pass a scatter plot or contourf or whatever, and legend is generated by
# drawing patch rectangles or markers using data values and their
# corresponding cmap colors! For scatterplots just test get_facecolor()
# to see if it contains more than one color.
# TODO: It is *also* often desirable to label a colormap object with
# one data value. Maybe add a legend option for the *number of samples*
# or the *sample points* when drawing legends for colormap objects.
# Look into "legend handlers", might just want to add own handlers by
# passing handler_map to legend() and get_legend_handles_labels().
if order not in ('F', 'C'):
raise ValueError(
f'Invalid order {order!r}. Choose from '
'"C" (row-major, default) and "F" (column-major).'
)
ncol = _not_none(ncols=ncols, ncol=ncol)
title = _not_none(label=label, title=title)
frameon = _not_none(
frame=frame, frameon=frameon, default=rc['legend.frameon']
)
if handles is not None and not np.iterable(handles): # e.g. a mappable object
handles = [handles]
if labels is not None and (not np.iterable(labels) or isinstance(labels, str)):
labels = [labels]
if title is not None:
kwargs['title'] = title
if frameon is not None:
kwargs['frameon'] = frameon
if fontsize is not None:
kwargs['fontsize'] = rc._scale_font(fontsize)
# Handle and text properties that are applied after-the-fact
# NOTE: Set solid_capstyle to 'butt' so line does not extend past error bounds
lw = _not_none(kwargs.get('linewidth', None), kwargs.get('lw', None))
elif name == 'violinplot':
lw = _not_none(kwargs.pop('linewidth', None), kwargs.pop('lw', None))
lw = _not_none(lw, 0.8)
barlw = _not_none(barlinewidth=barlinewidth, barlw=barlw, default=lw)
boxlw = _not_none(boxlinewidth=boxlinewidth, boxlw=boxlw, default=4 * barlw)
capsize = _not_none(capsize, 3.0)
# Infer color for error bars
edgecolor = None
if name == 'bar':
edgecolor = kwargs.get('edgecolor', None)
elif name == 'violinplot':
edgecolor = kwargs.pop('edgecolor', None)
edgecolor = _not_none(edgecolor, 'k')
barcolor = _not_none(barcolor, edgecolor)
boxcolor = _not_none(boxcolor, barcolor)
# Infer color for shading
shadecolor_infer = shadecolor is None
shadecolor = _not_none(
shadecolor, kwargs.get('color', None), kwargs.get('facecolor', None), edgecolor
)
fadecolor_infer = fadecolor is None
fadecolor = _not_none(fadecolor, shadecolor)
# Draw dark and light shading
vert = kwargs.get('vert', kwargs.get('orientation', 'vertical') == 'vertical')
axis = 'y' if vert else 'x' # yerr
errargs = (x, y) if vert else (y, x)
errobjs = []
means_or_medians = means or medians
# instead of levels. (see: https://stackoverflow.com/q/40116968/4970632).
# NOTE: Often want levels instead of vmin/vmax, while simultaneously
# using a Normalize (for example) to determine colors between the levels
# (see: https://stackoverflow.com/q/42723538/4970632). Workaround makes
# sure locators are in vmin/vmax range exclusively; cannot match values.
# NOTE: In legend_wrapper() we try to add to the objects accepted by
# legend() using handler_map. We can't really do anything similar for
# colorbars; input must just be insnace of mixin class cm.ScalarMappable
# Mutable args
norm_kw = norm_kw or {}
formatter_kw = formatter_kw or {}
locator_kw = locator_kw or {}
minorlocator_kw = minorlocator_kw or {}
# Parse input args
label = _not_none(title=title, label=label)
locator = _not_none(ticks=ticks, locator=locator)
minorlocator = _not_none(minorticks=minorticks, minorlocator=minorlocator)
ticklocation = _not_none(tickloc=tickloc, ticklocation=ticklocation)
formatter = _not_none(ticklabels=ticklabels, formatter=formatter)
# Colorbar kwargs
# WARNING: PathCollection scatter objects have an extend method!
# WARNING: Matplotlib 3.3 deprecated 'extend' parameter passed to colorbar()
# but *also* fails to read 'extend' parameter when added to a pcolor mappable!
# Need to figure out workaround!
grid = _not_none(grid, rc['colorbar.grid'])
if extend is None:
if isinstance(getattr(mappable, 'extend', None), str):
extend = mappable.extend or 'neither'
else:
extend = 'neither'
def wrapper(
self, *args, fmt=None, labels=None, labels_kw=None, precision=None, **kwargs,
):
# Call main funtion
name = func.__name__
obj = func(self, *args, **kwargs)
if not labels:
return obj
# Default formatter
labels_kw = labels_kw or {}
fmt = _not_none(labels_kw.pop('fmt', None), fmt, 'simple')
fmt = constructor.Formatter(fmt, precision=precision)
# Add contour labels
if name in ('contour', 'tricontour', 'contourf', 'tricontourf'):
cobj = obj
cmap = obj.get_cmap()
norm = obj.get_norm()
levels = obj.levels
colors = None
if name in ('contourf', 'tricontourf'):
lums = [to_xyz(cmap(norm(level)), 'hcl')[2] for level in levels]
cobj = self.contour(*args, levels=levels, linewidths=0)
colors = ['w' if lum < 50 else 'k' for lum in lums]
text_kw = {}
for key in tuple(labels_kw): # allow dict to change size
if key in (
xtickdir = _not_none(xtickdir, rc.get('xtick.direction', context=True))
ytickdir = _not_none(ytickdir, rc.get('ytick.direction', context=True))
xformatter = _not_none(xformatter=xformatter, xticklabels=xticklabels)
yformatter = _not_none(yformatter=yformatter, yticklabels=yticklabels)
xlocator = _not_none(xlocator=xlocator, xticks=xticks)
ylocator = _not_none(ylocator=ylocator, yticks=yticks)
xtickminor = _not_none(
xtickminor, rc.get('xtick.minor.visible', context=True)
)
ytickminor = _not_none(
ytickminor, rc.get('ytick.minor.visible', context=True)
)
xminorlocator = _not_none(
xminorlocator=xminorlocator, xminorticks=xminorticks,
)
yminorlocator = _not_none(
yminorlocator=yminorlocator, yminorticks=yminorticks,
)
# Grid defaults are more complicated
grid = rc.get('axes.grid', context=True)
which = rc.get('axes.grid.which', context=True)
if which is not None or grid is not None: # if *one* was changed
axis = rc['axes.grid.axis'] # always need this property
if grid is None:
grid = rc['axes.grid']
elif which is None:
which = rc['axes.grid.which']
xgrid = _not_none(
xgrid, grid and axis in ('x', 'both')
and which in ('major', 'both')
)