Skip to content

Commit da4ccb0

Browse files
committed
Make 'grays' idential to 'greys', clean CmapDict
1 parent ce4ef6a commit da4ccb0

File tree

1 file changed

+71
-86
lines changed

1 file changed

+71
-86
lines changed

proplot/styletools.py

Lines changed: 71 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,16 +1096,19 @@ def shifted(self, shift=None, name=None, **kwargs):
10961096
the original colormap is returned.
10971097
name : str, optional
10981098
The name of the new colormap. Default is
1099-
``self.name + '_shifted'``.
1099+
``self.name + '_s'``.
1100+
1101+
Other parameters
1102+
----------------
11001103
**kwargs
1101-
Passed to `LinearSegmentedColormap.updated`
1102-
or `PerceptuallyUniformColormap.updated`.
1104+
Passed to `LinearSegmentedColormap.copy`
1105+
or `PerceptuallyUniformColormap.copy`.
11031106
"""
11041107
shift = ((shift or 0) / 360) % 1
11051108
if shift == 0:
11061109
return self
11071110
if name is None:
1108-
name = self.name + '_shifted'
1111+
name = self.name + '_s'
11091112
if not self._cyclic:
11101113
_warn_proplot(
11111114
f'Shifting non-cyclic colormap {self.name!r}. '
@@ -1413,12 +1416,12 @@ def shifted(self, shift=None, name=None):
14131416
The number of places to shift, between ``-self.N`` and ``self.N``.
14141417
If ``None``, the original colormap is returned.
14151418
name : str, optional
1416-
The new colormap name. Default is ``self.name + '_shifted'``.
1419+
The new colormap name. Default is ``self.name + '_s'``.
14171420
"""
14181421
if not shift:
14191422
return self
14201423
if name is None:
1421-
name = self.name + '_shifted'
1424+
name = self.name + '_s'
14221425
shift = shift % len(self.colors)
14231426
colors = [*self.colors] # ensure list
14241427
colors = colors[shift:] + colors[:shift]
@@ -1847,7 +1850,9 @@ class CmapDict(dict):
18471850
"""
18481851
Dictionary subclass used to replace the `matplotlib.cm.cmap_d`
18491852
colormap dictionary. See `~CmapDict.__getitem__` and
1850-
`~CmapDict.__setitem__` for details.
1853+
`~CmapDict.__setitem__` for details. This class also handles the
1854+
`colormaps` and `cycles` variables, meant to provide users with an
1855+
easily accessible list of all registered colormap and cycle names.
18511856
"""
18521857
def __init__(self, kwargs):
18531858
"""
@@ -1857,28 +1862,16 @@ def __init__(self, kwargs):
18571862
The source dictionary.
18581863
"""
18591864
for key, value in kwargs.items():
1860-
if not isinstance(key, str):
1861-
raise KeyError(f'Invalid key {key}. Must be string.')
18621865
self.__setitem__(key, value, sort=False)
1863-
try:
1864-
for record in (cmaps, cycles):
1865-
record[:] = sorted(record)
1866-
except NameError:
1867-
pass
1866+
self._record_update(kwargs, sort=True)
18681867

18691868
def __delitem__(self, key):
18701869
"""
18711870
Delete the item from the list records.
18721871
"""
1872+
key = self._sanitize_key(key)
1873+
self._record_delete(key)
18731874
super().__delitem__(self, key)
1874-
try:
1875-
for record in (cmaps, cycles):
1876-
try:
1877-
record.remove(key)
1878-
except ValueError:
1879-
pass
1880-
except NameError:
1881-
pass
18821875

18831876
def __getitem__(self, key):
18841877
"""
@@ -1887,16 +1880,16 @@ def __getitem__(self, key):
18871880
18881881
* If the key ends in ``'_r'``, the result of ``cmap.reversed()`` is
18891882
returned for the colormap registered under the name ``key[:-2]``.
1890-
* If it ends in ``'_shifted'``, the result of ``cmap.shifted(180)`` is
1883+
* If it ends in ``'_s'``, the result of ``cmap.shifted(180)`` is
18911884
returned for the colormap registered under the name ``cmap[:-8]``.
18921885
* Reversed diverging colormaps can be requested with their "reversed"
18931886
name -- for example, ``'BuRd'`` is equivalent to ``'RdBu_r'``.
18941887
"""
18951888
key = self._sanitize_key(key, mirror=True)
1896-
shift = (key[-8:] == '_shifted')
1889+
shift = key[-2:] == '_s'
18971890
if shift:
1898-
key = key[:-8]
1899-
reverse = (key[-2:] == '_r')
1891+
key = key[:-2]
1892+
reverse = key[-2:] == '_r'
19001893
if reverse:
19011894
key = key[:-2]
19021895
value = super().__getitem__(key) # may raise keyerror
@@ -1925,31 +1918,27 @@ def __setitem__(self, key, item, sort=True):
19251918
`~matplotlib.colors.LinearSegmentedColormap`, it is converted to the
19261919
ProPlot `ListedColormap` or `LinearSegmentedColormap` subclass.
19271920
"""
1921+
if not isinstance(key, str):
1922+
raise KeyError(f'Invalid key {key!r}. Must be string.')
19281923
if isinstance(item, (ListedColormap, LinearSegmentedColormap)):
19291924
pass
19301925
elif isinstance(item, mcolors.LinearSegmentedColormap):
19311926
item = LinearSegmentedColormap(
1932-
item.name, item._segmentdata, item.N, item._gamma)
1927+
item.name, item._segmentdata, item.N, item._gamma
1928+
)
19331929
elif isinstance(item, mcolors.ListedColormap):
19341930
item = ListedColormap(
1935-
item.colors, item.name, item.N)
1936-
elif item is None:
1937-
return
1931+
item.colors, item.name, item.N
1932+
)
19381933
else:
19391934
raise ValueError(
19401935
f'Invalid colormap {item}. Must be instance of '
19411936
'matplotlib.colors.ListedColormap or '
19421937
'matplotlib.colors.LinearSegmentedColormap.'
19431938
)
19441939
key = self._sanitize_key(key, mirror=False)
1945-
try:
1946-
record = cycles if isinstance(item, ListedColormap) else cmaps
1947-
record.append(key)
1948-
if sort:
1949-
record[:] = sorted(record)
1950-
except NameError:
1951-
pass
1952-
return super().__setitem__(key, item)
1940+
self._record_update({key: item}, sort=sort)
1941+
super().__setitem__(key, item)
19531942

19541943
def __contains__(self, item):
19551944
"""
@@ -1961,17 +1950,51 @@ def __contains__(self, item):
19611950
except KeyError:
19621951
return False
19631952

1953+
@staticmethod
1954+
def _record_delete(key):
1955+
"""
1956+
Remove the `colormaps` or `cycles` record.
1957+
"""
1958+
try:
1959+
records = (cmaps, cycles)
1960+
except NameError:
1961+
pass
1962+
else:
1963+
for record in records:
1964+
try:
1965+
record.remove(key)
1966+
except ValueError:
1967+
pass
1968+
1969+
@staticmethod
1970+
def _record_update(kwargs, sort=False):
1971+
"""
1972+
Update the `colormaps` or `cycles` record.
1973+
"""
1974+
record = None
1975+
try:
1976+
cmaps, cycles
1977+
except NameError:
1978+
pass
1979+
else:
1980+
for key, item in kwargs.items():
1981+
record = cycles if isinstance(item, ListedColormap) else cmaps
1982+
record.append(key)
1983+
if sort:
1984+
record[:] = sorted(record)
1985+
19641986
def _sanitize_key(self, key, mirror=True):
19651987
"""
1966-
Return the sanitized colormap name.
1988+
Return the sanitized colormap name. This is used for lookups *and*
1989+
assignments.
19671990
"""
19681991
if not isinstance(key, str):
19691992
raise KeyError(f'Invalid key {key!r}. Key must be a string.')
19701993
key = key.lower()
1971-
reverse = False
1972-
if key[-2:] == '_r':
1994+
key = re.sub(r'\A(grays)(?:_r|_s)?\Z', 'greys', key)
1995+
reverse = key[-2:] == '_r'
1996+
if reverse:
19731997
key = key[:-2]
1974-
reverse = True
19751998
if mirror and not super().__contains__(key): # search for mirrored key
19761999
key_mirror = key
19772000
for pair in CMAPS_DIVERGING:
@@ -1981,47 +2004,12 @@ def _sanitize_key(self, key, mirror=True):
19812004
except (ValueError, KeyError):
19822005
continue
19832006
if super().__contains__(key_mirror):
1984-
reverse = (not reverse)
2007+
reverse = not reverse
19852008
key = key_mirror
19862009
if reverse:
19872010
key = key + '_r'
19882011
return key
19892012

1990-
def get(self, key, *args):
1991-
"""
1992-
Retrieve the sanitized colormap name.
1993-
"""
1994-
key = self._sanitize_key(key, mirror=True)
1995-
return super().get(key, *args)
1996-
1997-
def pop(self, key, *args):
1998-
"""
1999-
Pop the sanitized colormap name.
2000-
"""
2001-
key = self._sanitize_key(key, mirror=True)
2002-
try:
2003-
for record in (cmaps, cycles):
2004-
try:
2005-
record.remove(key)
2006-
except ValueError:
2007-
pass
2008-
except NameError:
2009-
pass
2010-
return super().pop(key, *args)
2011-
2012-
def update(self, *args, **kwargs):
2013-
"""
2014-
Update the dictionary with sanitized colormap names.
2015-
"""
2016-
if len(args) == 1:
2017-
kwargs.update(args[0])
2018-
elif len(args) > 1:
2019-
raise TypeError(
2020-
f'update() expected at most 1 arguments, got {len(args)}.'
2021-
)
2022-
for key, value in kwargs.items():
2023-
self[key] = value
2024-
20252013

20262014
class _ColorMappingOverride(mcolors._ColorMapping):
20272015
"""
@@ -2041,16 +2029,15 @@ class ColorDict(dict):
20412029
"""
20422030
def __getitem__(self, key):
20432031
"""
2044-
Allows user to select colors from arbitrary named colormaps and
2045-
color cycles.
2032+
Permit selections from arbitrary named colormaps and color cycles:
20462033
20472034
* For a smooth colormap, usage is e.g. ``color=('Blues', 0.8)``. The
20482035
number is the colormap index, and must be between 0 and 1.
20492036
* For a color cycle, usage is e.g. ``color=('colorblind', 2)``. The
20502037
number is the list index.
20512038
2052-
These examples work with any
2053-
matplotlib command that accepts a `color` keyword arg.
2039+
These examples work with any matplotlib command that accepts a `color`
2040+
keyword arg.
20542041
"""
20552042
# Matplotlib 'color' args are passed to to_rgba, which tries to read
20562043
# directly from cache and if that fails, sanitizes input, which
@@ -2071,16 +2058,14 @@ def __getitem__(self, key):
20712058
f'between 0 and {len(cmap.colors)-1}, '
20722059
f'got {rgb[1]}.'
20732060
)
2074-
# draw color from the list of colors, using index
2075-
rgb = cmap.colors[rgb[1]]
2061+
rgb = cmap.colors[rgb[1]] # draw from list of colors
20762062
else:
20772063
if not 0 <= rgb[1] <= 1:
20782064
raise ValueError(
20792065
f'Colormap sample for {rgb[0]!r} colormap must be '
20802066
f'between 0 and 1, got {rgb[1]}.'
20812067
)
2082-
# interpolate color from colormap, using key in range 0-1
2083-
rgb = cmap(rgb[1])
2068+
rgb = cmap(rgb[1]) # get color selection
20842069
rgba = mcolors.to_rgba(rgb, alpha)
20852070
return rgba
20862071
return super().__getitem__((rgb, alpha))

0 commit comments

Comments
 (0)