Skip to content

Commit a4218e0

Browse files
committed
Improve default colormap names
1 parent 4c9121c commit a4218e0

1 file changed

Lines changed: 41 additions & 38 deletions

File tree

proplot/colors.py

Lines changed: 41 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,21 @@ def _get_data(self, ext, alpha=True):
688688
)
689689
return data
690690

691+
def _make_name(self, suffix=None):
692+
"""
693+
Generate a default colormap name. Do not append more than one
694+
leading underscore or more than one identical suffix.
695+
"""
696+
name = self.name
697+
name = name or ''
698+
if name[:1] != '_':
699+
name = '_' + name
700+
suffix = suffix or 'copy'
701+
suffix = '_' + suffix
702+
if name[-len(suffix):] != suffix:
703+
name = name + suffix
704+
return name
705+
691706
def _parse_path(self, path, ext=None, subfolder=None):
692707
"""
693708
Parse the user input path.
@@ -874,14 +889,6 @@ def _warn_or_raise(descrip, error=RuntimeError):
874889
data = [(x, color) for x, color in zip(x, data)]
875890
return ContinuousColormap.from_list(name, data)
876891

877-
@property
878-
def _copy_name(self):
879-
# The name used when making copies
880-
name = self.name or ''
881-
if name and name[0] != '_':
882-
name = '_' + name
883-
return name + '_copy'
884-
885892

886893
class ContinuousColormap(mcolors.LinearSegmentedColormap, _Colormap):
887894
r"""
@@ -1130,11 +1137,9 @@ def cut(self, cut=None, name=None, left=None, right=None, **kwargs):
11301137

11311138
# Decompose cut into two truncations followed by concatenation
11321139
if 0.5 - offset < left or 0.5 + offset > right:
1133-
raise ValueError(
1134-
f'Invalid combination cut={cut} for left={left} and right={right}.'
1135-
)
1140+
raise ValueError(f'Invalid cut={cut} for left={left} and right={right}.')
11361141
if name is None:
1137-
name = self._copy_name
1142+
name = self._make_name()
11381143
cmap_left = self.truncate(left, 0.5 - offset)
11391144
cmap_right = self.truncate(0.5 + offset, right)
11401145

@@ -1184,14 +1189,14 @@ def reversed(self, name=None, **kwargs):
11841189
}
11851190

11861191
# Reverse gammas
1192+
if name is None:
1193+
name = self._make_name(suffix='r')
11871194
for key in ('gamma1', 'gamma2'):
11881195
if key in kwargs:
11891196
continue
11901197
gamma = getattr(self, '_' + key, None)
11911198
if gamma is not None and np.iterable(gamma):
11921199
kwargs[key] = gamma[::-1]
1193-
if name is None:
1194-
name = '_' + self.name + '_r'
11951200

11961201
cmap = self.copy(name, segmentdata, **kwargs)
11971202
cmap._rgba_under, cmap._rgba_over = cmap._rgba_over, cmap._rgba_under
@@ -1294,8 +1299,7 @@ def shifted(self, shift=180, name=None, **kwargs):
12941299
Parameters
12951300
----------
12961301
shift : float, optional
1297-
The number of degrees to shift, out of 360 degrees.
1298-
The default is ``180``.
1302+
The number of degrees to shift, out of 360 degrees. Default is ``180``.
12991303
name : str, optional
13001304
The new colormap name. Default is ``'_name_s'``.
13011305
@@ -1308,24 +1312,23 @@ def shifted(self, shift=180, name=None, **kwargs):
13081312
--------
13091313
DiscreteColormap.shifted
13101314
"""
1311-
shift = ((shift or 0) / 360) % 1
1315+
shift = shift or 0
1316+
shift %= 360
1317+
shift /= 360
13121318
if shift == 0:
13131319
return self
13141320
if name is None:
1315-
name = '_' + self.name + '_s'
1321+
name = self._make_name(suffix='s')
13161322
if not self._cyclic:
13171323
warnings._warn_proplot(
1318-
f'Shifting non-cyclic colormap {self.name!r}. Use cmap.set_cyclic(True)'
1319-
' or Colormap(..., cyclic=True) to suppress this warning.'
1324+
f'Shifting non-cyclic colormap {self.name!r}. To suppress this '
1325+
'warning use cmap.set_cyclic(True) or Colormap(..., cyclic=True).'
13201326
)
13211327
self._cyclic = True
1322-
1323-
# Decompose shift into two truncations followed by concatenation
1328+
ratios = (1 - shift, shift)
13241329
cmap_left = self.truncate(shift, 1)
13251330
cmap_right = self.truncate(0, shift)
1326-
return cmap_left.append(
1327-
cmap_right, ratios=(1 - shift, shift), name=name, **kwargs
1328-
)
1331+
return cmap_left.append(cmap_right, ratios=ratios, name=name, **kwargs)
13291332

13301333
def truncate(self, left=None, right=None, name=None, **kwargs):
13311334
"""
@@ -1358,7 +1361,7 @@ def truncate(self, left=None, right=None, name=None, **kwargs):
13581361
if left == 0 and right == 1:
13591362
return self
13601363
if name is None:
1361-
name = self._copy_name
1364+
name = self._make_name()
13621365

13631366
# Resample the segmentdata arrays
13641367
segmentdata = {}
@@ -1441,7 +1444,7 @@ def copy(
14411444
PerceptualColormap.copy
14421445
"""
14431446
if name is None:
1444-
name = self._copy_name
1447+
name = self._make_name()
14451448
if segmentdata is None:
14461449
segmentdata = self._segmentdata.copy()
14471450
if gamma is None:
@@ -1489,7 +1492,7 @@ def to_discrete(self, samples=10, name=None, **kwargs):
14891492
samples = np.asarray(samples)
14901493
colors = self(samples)
14911494
if name is None:
1492-
name = self._copy_name
1495+
name = self._make_name()
14931496
return DiscreteColormap(colors, name=name, **kwargs)
14941497

14951498
@classmethod
@@ -1732,7 +1735,7 @@ def reversed(self, name=None, **kwargs):
17321735
matplotlib.colors.ListedColormap.reversed
17331736
"""
17341737
if name is None:
1735-
name = '_' + self.name + '_r'
1738+
name = self._make_name(suffix='r')
17361739
colors = self.colors[::-1]
17371740
cmap = self.copy(colors, name, **kwargs)
17381741
cmap._rgba_under, cmap._rgba_over = cmap._rgba_over, cmap._rgba_under
@@ -1745,8 +1748,8 @@ def shifted(self, shift=1, name=None):
17451748
Parameters
17461749
----------
17471750
shift : float, optional
1748-
The number of places to shift, between ``-self.N`` and ``self.N``.
1749-
The default is ``1``.
1751+
The number of places to shift, between ``-len(cmap.colors)``
1752+
and ``len(cmap.colors)``. Default is ``1``.
17501753
name : str, optional
17511754
The new colormap name. Default is ``'_name_s'``.
17521755
@@ -1757,7 +1760,7 @@ def shifted(self, shift=1, name=None):
17571760
if not shift:
17581761
return self
17591762
if name is None:
1760-
name = '_' + self.name + '_s'
1763+
name = self._make_name(suffix='s')
17611764
shift = shift % len(self.colors)
17621765
colors = list(self.colors)
17631766
colors = colors[shift:] + colors[:shift]
@@ -1787,7 +1790,7 @@ def truncate(self, left=None, right=None, name=None):
17871790
if left is None and right is None:
17881791
return self
17891792
if name is None:
1790-
name = self._copy_name
1793+
name = self._make_name()
17911794
colors = self.colors[left:right]
17921795
return self.copy(colors, name, len(colors))
17931796

@@ -1810,7 +1813,7 @@ def copy(self, colors=None, name=None, N=None, *, alpha=None):
18101813
PerceptualColormap.copy
18111814
"""
18121815
if name is None:
1813-
name = self._copy_name
1816+
name = self._make_name()
18141817
if colors is None:
18151818
colors = list(self.colors) # copy
18161819
if N is None:
@@ -2005,7 +2008,7 @@ def copy(
20052008
ContinuousColormap.copy
20062009
"""
20072010
if name is None:
2008-
name = self._copy_name
2011+
name = self._make_name()
20092012
if segmentdata is None:
20102013
segmentdata = self._segmentdata.copy()
20112014
if space is None:
@@ -2054,7 +2057,7 @@ def to_continuous(self, name=None, **kwargs):
20542057
if not self._isinit:
20552058
self._init()
20562059
if name is None:
2057-
name = self._copy_name
2060+
name = self._make_name()
20582061
return ContinuousColormap.from_list(name, self._lut[:-3, :], **kwargs)
20592062

20602063
@classmethod
@@ -2598,8 +2601,8 @@ def __init__(
25982601
Parameters
25992602
----------
26002603
vcenter : float, optional
2601-
The data value corresponding to the central position of the
2602-
colormap. The default is ``0``.
2604+
The data value corresponding to the central position
2605+
of the colormap. Default is ``0``.
26032606
vmin, vmax : float, optional
26042607
The minimum and maximum data values.
26052608
fair : bool, optional

0 commit comments

Comments
 (0)