Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
Register colormaps packaged with ProPlot or saved to the
``~/.proplot/cmaps`` folder. This is called on import.
Colormaps are registered according to their filenames -- for example,
``name.xyz`` will be registered as ``'name'``.
%(register.ext_table)s
To visualize the registered colormaps, use `~proplot.demos.show_cmaps`.
Parameters
----------
%(register_cmaps.params)s
"""
for i, dirname, filename in _iter_data_paths('cmaps', user=user, default=default):
path = os.path.join(dirname, filename)
cmap = pcolors.LinearSegmentedColormap.from_file(path, warn_on_failure=True)
if not cmap:
continue
if i == 0 and cmap.name.lower() in (
'phase', 'graycycle', 'romao', 'broco', 'corko', 'viko',
):
cmap.set_cyclic(True)
pcolors._cmap_database[cmap.name] = cmap
def _mod_colormap(cmap, *, cut, left, right, shift, reverse, samples):
"""
Modify colormap in a variety of ways.
"""
if cut is not None or left is not None or right is not None:
if isinstance(cmap, pcolors.ListedColormap):
if cut is not None:
warnings._warn_proplot(
"Invalid argument 'cut' for ListedColormap. Ignoring."
)
cmap = cmap.truncate(left=left, right=right)
else:
cmap = cmap.cut(cut, left=left, right=right)
if shift is not None:
cmap = cmap.shifted(shift)
if reverse:
cmap = cmap.reversed()
if samples is not None:
if isinstance(cmap, pcolors.ListedColormap):
cmap = cmap.copy(N=samples)
else:
cmap = cmap.to_listed(samples)
arg = pcolors.ListedColormap.from_file(arg)
else:
arg = pcolors.LinearSegmentedColormap.from_file(arg)
else:
try:
arg = pcolors._cmap_database[arg]
except KeyError:
pass
# Convert matplotlib colormaps to subclasses
if isinstance(arg, mcolors.Colormap):
cmap = pcolors._to_proplot_colormap(arg)
# Dictionary of hue/sat/luminance values or 2-tuples
elif isinstance(arg, dict):
cmap = pcolors.PerceptuallyUniformColormap.from_hsl(tmp, **arg)
# List of color tuples or color strings, i.e. iterable of iterables
elif (
not isinstance(arg, str) and np.iterable(arg)
and all(np.iterable(color) for color in arg)
):
colors = [to_rgba(color, cycle=cycle) for color in arg]
if listmode == 'listed':
cmap = pcolors.ListedColormap(colors, tmp)
elif listmode == 'linear':
cmap = pcolors.LinearSegmentedColormap.from_list(tmp, colors)
else:
cmap = pcolors.PerceptuallyUniformColormap.from_list(tmp, colors) # noqa: E501
# Monochrome colormap from input color
else:
import cartopy.crs as ccrs
import cartopy.mpl.ticker as cticker
from cartopy.crs import CRS
except ModuleNotFoundError:
CRS = ccrs = cticker = object
__all__ = [
'Colormap', 'Colors', 'Cycle', 'Norm',
'Formatter', 'Locator', 'Scale', 'Proj',
]
# Dictionary of possible normalizers. See `Norm` for a table.
NORMS = {
'none': mcolors.NoNorm,
'null': mcolors.NoNorm,
'div': pcolors.DivergingNorm,
'diverging': pcolors.DivergingNorm,
'segmented': pcolors.LinearSegmentedNorm,
'log': mcolors.LogNorm,
'linear': mcolors.Normalize,
'power': mcolors.PowerNorm,
'symlog': mcolors.SymLogNorm,
'zero': pcolors.DivergingNorm, # deprecated
'midpoint': pcolors.DivergingNorm, # deprecated
'segments': pcolors.LinearSegmentedNorm, # deprecated
}
if hasattr(mcolors, 'TwoSlopeNorm'):
NORMS['twoslope'] = mcolors.TwoSlopeNorm
# Mapping of strings to `~matplotlib.ticker.Locator` classes. See
# `Locator` for a table."""
LOCATORS = {
def _get_cycle_colors(cycle):
"""
Update the color cycle.
"""
try:
colors = pcolors._cmap_database[cycle].colors
except (KeyError, AttributeError):
cycles = sorted(
name for name, cmap in pcolors._cmap_database.items()
if isinstance(cmap, pcolors.ListedColormap)
)
raise ValueError(
f'Invalid cycle name {cycle!r}. Options are: '
+ ', '.join(map(repr, cycles)) + '.'
)
return colors
def _draw_bars(
cmaps, *, source, unknown='User', categories=None,
length=4.0, width=0.2, N=None
):
"""
Draw colorbars for "colormaps" and "color cycles". This is called by
`show_cycles` and `show_cmaps`.
"""
# Translate local names into database of colormaps
# NOTE: Custom cmap database raises nice error if colormap name is unknown
i = 1
database = pcolors.ColormapDatabase({}) # subset to be drawn
for cmap in cmaps:
if isinstance(cmap, cycler.Cycler):
name = getattr(cmap, 'name', '_no_name')
cmap = mcolors.ListedColormap(cmap.by_key()['color'], name)
elif isinstance(cmap, (list, tuple)):
name = '_no_name'
cmap = mcolors.ListedColormap(cmap, name)
elif isinstance(cmap, mcolors.Colormap):
name = cmap.name
else:
name = cmap
cmap = pcolors._cmap_database[cmap]
if name in database:
name = f'{name}_{i}' # e.g. _no_name_2
i += 1
if name.lower()[-2:] == '_r':
inorm = constructor.Norm(norm, **norm_kw)
levels = inorm.inverse(edges(inorm(values)))
elif values is not None:
raise ValueError(
f'Unexpected input values={values!r}. '
'Must be integer or list of numbers.'
)
# Get default normalizer
# Only use LinearSegmentedNorm if necessary, because it is slow
descending = False
if np.iterable(levels):
if len(levels) == 1:
norm = mcolors.Normalize(vmin=levels[0] - 1, vmax=levels[0] + 1)
else:
levels, descending = pcolors._check_levels(levels)
if norm is None:
norm = 'linear'
if np.iterable(levels) and len(levels) > 2:
steps = np.abs(np.diff(levels))
eps = np.mean(steps) / 1e3
if np.any(np.abs(np.diff(steps)) >= eps):
norm = 'segmented'
if norm == 'segmented':
if not np.iterable(levels):
norm = 'linear' # has same result
else:
norm_kw['levels'] = levels
norm = constructor.Norm(norm, **norm_kw)
# Use the locator to determine levels
# Mostly copied from the hidden contour.ContourSet._autolev
To visualize the registered colormaps, use `~proplot.demos.show_cmaps`.
Parameters
----------
%(register_cmaps.params)s
"""
for i, dirname, filename in _iter_data_paths('cmaps', user=user, default=default):
path = os.path.join(dirname, filename)
cmap = pcolors.LinearSegmentedColormap.from_file(path, warn_on_failure=True)
if not cmap:
continue
if i == 0 and cmap.name.lower() in (
'phase', 'graycycle', 'romao', 'broco', 'corko', 'viko',
):
cmap.set_cyclic(True)
pcolors._cmap_database[cmap.name] = cmap
will be registered as ``'name'``.
%(register.ext_table)s
To visualize the registered color cycles, use `~proplot.demos.show_cycles`.
Parameters
----------
%(register_cycles.params)s
"""
for _, dirname, filename in _iter_data_paths('cycles', user=user, default=default):
path = os.path.join(dirname, filename)
cmap = pcolors.ListedColormap.from_file(path, warn_on_failure=True)
if not cmap:
continue
pcolors._cmap_database[cmap.name] = cmap
olevels = norm(levels)
nlevels = []
for i in range(len(levels) - 1):
l1, l2 = olevels[i], olevels[i + 1]
nlevels.extend(np.linspace(l1, l2, nn + 1)[:-1])
nlevels.append(olevels[-1])
levels = norm.inverse(nlevels)
# Use auto-generated levels for ticks if still None
if ticks is None:
ticks = levels
# Generate DiscreteNorm and update "child" norm with vmin and vmax from
# levels. This lets the colorbar set tick locations properly!
if not isinstance(norm, mcolors.BoundaryNorm) and len(levels) > 1:
norm = pcolors.DiscreteNorm(
levels, cmap=cmap, norm=norm, descending=descending
)
if descending:
cmap = cmap.reversed()
return norm, cmap, levels, ticks