Source code for cmweather.cm
"""
Radar related colormaps.
Available colormaps, reversed versions (_r) are also provided, these
colormaps are available within matplotlib:
* BlueBrown10
* BlueBrown11
* BrBu10
* BrBu12
* Bu10
* Bu7
* BuDOr12
* BuDOr18
* BuDRd12
* BuDRd18
* BuGr14
* BuGy8
* BuOr10
* BuOr12
* BuOr8
* BuOrR14
* Carbone11
* Carbone17
* Carbone42
* Cat12
* EWilson17
* GrMg16
* Gray5
* Gray9
* NWSRef
* NWSVel
* NWS_SPW
* NWS_CC
* PD17
* RRate11
* RdYlBu11b
* RefDiff
* SCook18
* StepSeq25
* SymGray12
* Theodore16
* Wild25
* LangRainbow12
"""
# This file was adapted from the cm.py file of the matplotlib project,
# http://matplotlib.org/.
# Copyright (c) 2012-2013 Matplotlib Development Team; All Rights Reserved
import warnings
import matplotlib as mpl
import matplotlib.colors as colors
from ._cm import datad
cmap_d = dict()
# reverse all the colormaps.
# reversed colormaps have '_r' appended to the name.
def _reverser(f):
"""perform reversal."""
def freversed(x):
"""f specific reverser."""
return f(1 - x)
return freversed
[docs]def revcmap(data):
"""Can only handle specification *data* in dictionary format."""
data_r = {}
for key, val in data.items():
if callable(val):
valnew = _reverser(val)
# This doesn't work: lambda x: val(1-x)
# The same "val" (the first one) is used
# each time, so the colors are identical
# and the result is shades of gray.
else:
# Flip x and exchange the y values facing x = 0 and x = 1.
valnew = [(1.0 - x, y1, y0) for x, y0, y1 in reversed(val)]
data_r[key] = valnew
return data_r
def _reverse_cmap_spec(spec):
"""Reverses cmap specification *spec*, can handle both dict and tuple
type specs."""
with warnings.catch_warnings():
warnings.simplefilter('ignore', FutureWarning)
if isinstance(spec, dict) and 'red' in spec.keys():
return revcmap(spec)
else:
revspec = list(reversed(spec))
if len(revspec[0]) == 2: # e.g., (1, (1.0, 0.0, 1.0))
revspec = [(1.0 - a, b) for a, b in revspec]
return revspec
def _generate_cmap(name, lutsize):
"""Generates the requested cmap from it's name *name*. The lut size is
*lutsize*."""
spec = datad[name]
# Generate the colormap object.
if isinstance(spec, dict) and 'red' in spec.keys():
return colors.LinearSegmentedColormap(name, spec, lutsize)
else:
return colors.LinearSegmentedColormap.from_list(name, spec, lutsize)
LUTSIZE = mpl.rcParams['image.lut']
# need this list because datad is changed in loop
_cmapnames = list(datad.keys())
# Generate the reversed specifications ...
for cmapname in _cmapnames:
spec = datad[cmapname]
spec_reversed = _reverse_cmap_spec(spec)
datad[cmapname + '_r'] = spec_reversed
# Precache the cmaps with ``lutsize = LUTSIZE`` ...
# Use datad.keys() to also add the reversed ones added in the section above:
for cmapname in datad.keys():
cmap_d[cmapname] = _generate_cmap(cmapname, LUTSIZE)
locals().update(cmap_d)
# register the colormaps so that can be accessed with the names pyart_XXX
for name, cmap in cmap_d.items():
# Matplotlib 3.6.0 colormap registering changed.
try:
mpl.colormaps.register(name=name, cmap=cmap, force=True)
except AttributeError:
mpl.cm.register_cmap(name=name, cmap=cmap)
def _get_cmap_gallery_html(cmaps, sort_d=False):
"""
return a html str representation of a colormap dictionary
use with either cmap_d from either .cm or .cm_colorblind,
reversed colormaps are excluded. The html repr of
individual colormaps is based on what the base
matplotlib.colors.Colormap._repr_html_() returns but
without the "over", "under" and "bad" labels.
Parameters
----------
cmaps: dict
a dictionary of colormaps
sort_d: bool
if True (default False), will sort the cmaps by name
Returns
-------
str
the concatenated html str for the input colormap dict
"""
import base64
def _get_cmap_div(cmap):
png_bytes = cmap._repr_png_()
png_base64 = base64.b64encode(png_bytes).decode('ascii')
return (
'<div style="vertical-align: middle;">'
f'<strong>{cmap.name}</strong> '
'</div>'
'<div class="cmap"><img '
f'alt="{cmap.name} colormap" '
f'title="{cmap.name}" '
'style="border: 1px solid #555;" '
f'src="data:image/png;base64,{png_base64}"></div>'
)
cm_names = [cnm for cnm in cmaps.keys() if not cnm.endswith('_r')]
if sort_d:
cm_names.sort()
html_str = ''
for cm_name in cm_names:
html_str += _get_cmap_div(cmaps[cm_name])
return html_str