Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 24 additions & 7 deletions proplot/axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,15 @@ def colorbar(
self.add_child_axes(ax)

# Location
# NOTE: May change loc='_fill' to 'fill' so users can manually
# fill axes but maintain proplot colorbar() features. For now
# this is just used internally by show_cmaps() and show_cycles()
if side is None: # manual
orientation = kwargs.pop('orientation', None)
if orientation == 'vertical':
side = 'left'
else:
side = 'bottom'
if side in ('bottom', 'top'):
outside, inside = 'bottom', 'top'
if side == 'top':
Expand All @@ -992,13 +1001,21 @@ def colorbar(
orientation = 'vertical'

# Keyword args and add as child axes
orient = kwargs.get('orientation', None)
if orient is not None and orient != orientation:
_warn_proplot(f'Overriding input orientation={orient!r}.')
ticklocation = kwargs.pop('tickloc', None) or ticklocation
ticklocation = kwargs.pop('ticklocation', None) or ticklocation
kwargs.update({'orientation': orientation,
'ticklocation': ticklocation})
orientation_user = kwargs.get('orientation', None)
if orientation_user and orientation_user != orientation:
_warn_proplot(
f'Overriding input orientation={orientation_user!r}.'
)
ticklocation = _notNone(
kwargs.pop('ticklocation', None),
kwargs.pop('tickloc', None),
ticklocation,
names=('ticklocation', 'tickloc')
)
kwargs.update({
'orientation': orientation,
'ticklocation': ticklocation
})

# Inset colorbar
else:
Expand Down
20 changes: 8 additions & 12 deletions proplot/styletools.py
Original file line number Diff line number Diff line change
Expand Up @@ -3194,8 +3194,6 @@ def _draw_bars(names, *, source, unknown='User', length=4.0, width=0.2):
)
iax = -1
nheads = nbars = 0 # for deciding which axes to plot in
a = np.linspace(0, 1, 257).reshape(1, -1)
a = np.vstack((a, a))
for cat, names in cmapdict.items():
nheads += 1
for imap, name in enumerate(names):
Expand All @@ -3207,18 +3205,16 @@ def _draw_bars(names, *, source, unknown='User', length=4.0, width=0.2):
iax += 1
ax.set_visible(False)
ax = axs[iax]
cmap = mcm.cmap_d[name]
ax.imshow(
a, cmap=name, origin='lower', aspect='auto',
levels=cmap.N
ax.colorbar( # TODO: support this in public API
mcm.cmap_d[name], loc='_fill',
orientation='horizontal', locator='null', linewidth=0
)
ax.format(
ylabel=name,
ylabel_kw={'rotation': 0, 'ha': 'right', 'va': 'center'},
xticks='none', yticks='none', # no ticks
xloc='neither', yloc='neither', # no spines
title=(cat if imap == 0 else None)
ax.text(
0 - (rcParams['axes.labelpad'] / 72) / length, 0.45, name,
ha='right', va='center', transform='axes',
)
if imap == 0:
ax.set_title(cat)
nbars += len(names)


Expand Down
22 changes: 10 additions & 12 deletions proplot/wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2588,7 +2588,7 @@ def colorbar_wrapper(
4. A `~matplotlib.colors.Colormap` instance. In this case, a colorbar
will be drawn using this colormap and with levels determined by
`values`. If `values` is ``None``, it is set to
``np.linspace(0, 1, cmap._N)``.
``np.linspace(0, 1, cmap.N)``.

values : list of float, optional
Ignored if `mappable` is a mappable object. This maps each color or
Expand Down Expand Up @@ -2749,8 +2749,7 @@ def colorbar_wrapper(
except (TypeError, KeyError):
pass
# List of handles
if (hasattr(obj, 'get_color') or hasattr(
obj, 'get_facecolor')): # simplest approach
if hasattr(obj, 'get_color') or hasattr(obj, 'get_facecolor'):
# Make colormap
colors = []
for obj in mappable:
Expand All @@ -2776,21 +2775,20 @@ def colorbar_wrapper(
tick_all = True
# Any colormap spec, including a list of colors, colormap name, or
# colormap instance
else:
try:
cmap = styletools.Colormap(mappable, listmode='listed')
except Exception:
raise ValueError(
'Input mappable must be a matplotlib artist, '
'list of objects, list of colors, or colormap. '
f'Got {mappable!r}.'
)
elif isinstance(mappable, mcolors.Colormap):
cmap = mappable
if values is None:
if np.iterable(mappable) and not isinstance(
mappable, str): # e.g. list of colors
values = np.linspace(0, 1, len(mappable))
else:
values = np.linspace(0, 1, cmap.N)
else:
raise ValueError(
'Input mappable must be a matplotlib artist, '
'list of objects, list of colors, or colormap. '
f'Got {mappable!r}.'
)

# Build new ad hoc mappable object from handles
# NOTE: Need to use wrapped contourf but this might be native matplotlib
Expand Down