@@ -2795,14 +2795,14 @@ def _get_rgba(self, arg, alpha):
27952795 """
27962796 key = (arg , alpha )
27972797 if isinstance (arg , str ) or not np .iterable (arg ) or len (arg ) != 2 :
2798- return super () .__getitem__ (key )
2798+ return dict .__getitem__ (self , key )
27992799 if not isinstance (arg [0 ], str ) or not isinstance (arg [1 ], Number ):
2800- return super () .__getitem__ (key )
2800+ return dict .__getitem__ (self , key )
28012801 # Try to get the colormap
28022802 try :
28032803 cmap = _cmap_database [arg [0 ]]
28042804 except (KeyError , TypeError ):
2805- return super () .__getitem__ (key )
2805+ return dict .__getitem__ (self , key )
28062806 # Read the colormap value
28072807 if isinstance (cmap , DiscreteColormap ):
28082808 if not 0 <= arg [1 ] < len (cmap .colors ):
@@ -2824,22 +2824,36 @@ def _get_rgba(self, arg, alpha):
28242824 return (* rgba [:3 ], a )
28252825
28262826
2827- class ColorDatabase (dict ):
2827+ class ColorDatabase (MutableMapping , dict ):
28282828 """
28292829 Dictionary subclass used to replace the builtin matplotlib color database.
28302830 See `~ColorDatabase.__getitem__` for details.
28312831 """
2832- # NOTE: Matplotlib's database also inherits from dict. MutableMapping not needed
2833- # since usage is entirely internal (we just make it public for documentation)
2834- def __init__ (self , mapping ):
2832+ _regex_grey = re .compile ('grey' ) # permit e.g. 'slategrey' and 'greyish'
2833+
2834+ def __iter__ (self ):
2835+ yield from dict .__iter__ (self )
2836+
2837+ def __len__ (self ):
2838+ return dict .__len__ (self )
2839+
2840+ def __delitem__ (self , key ):
2841+ key = self ._parse_key (key )
2842+ dict .__delitem__ (self , key )
2843+ self .cache .clear ()
2844+
2845+ def __init__ (self , mapping = None ):
28352846 """
28362847 Parameters
28372848 ----------
2838- mapping : dict-like
2849+ mapping : dict-like, optional
28392850 The colors.
28402851 """
2841- super (). __init__ ( mapping )
2852+ # NOTE: Tested with and without standardization and speedup is marginal
28422853 self ._cache = _ColorCache ()
2854+ mapping = mapping or {}
2855+ for key , value in mapping .items ():
2856+ self .__setitem__ (key , value )
28432857
28442858 def __getitem__ (self , key ):
28452859 """
@@ -2854,25 +2868,28 @@ def __getitem__(self, key):
28542868 This works with anywhere that colors are used in matplotlib, for example
28552869 as ``'color'``, ``'edgecolor'``, or ``'facecolor'`` arguments.
28562870 """
2857- if isinstance (key , str ):
2858- key = re .sub (r'\bgrey[0-9]?\b' , 'gray' , key )
2859- return super ().__getitem__ (key )
2871+ key = self ._parse_key (key )
2872+ return dict .__getitem__ (self , key )
28602873
28612874 def __setitem__ (self , key , value ):
28622875 """
2863- Add a color and clear the cache.
2876+ Add a color. Translates ``grey`` into ``gray`` and clears the
2877+ cache. The color must be a string.
28642878 """
2865- if not isinstance ( key , str ):
2866- raise ValueError ( f'Invalid color name { key !r } . Must be string.' )
2867- super () .__setitem__ (key , value )
2879+ # Always standardize assignments.
2880+ key = self . _parse_key ( key )
2881+ dict .__setitem__ (self , key , value )
28682882 self .cache .clear ()
28692883
2870- def __delitem__ (self , key ):
2884+ def _parse_key (self , key ):
28712885 """
2872- Delete a color and clear the cache .
2886+ Parse the color key. Currently this just translates grays .
28732887 """
2874- super ().__delitem__ (key )
2875- self .cache .clear ()
2888+ if not isinstance (key , str ):
2889+ raise ValueError (f'Invalid color name { key !r} . Must be string.' )
2890+ if isinstance (key , str ):
2891+ key = self ._regex_grey .sub ('gray' , key .lower ())
2892+ return key
28762893
28772894 @property
28782895 def cache (self ):
0 commit comments