@@ -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
886893class 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