Coverage for src/colorspace/hcl_palettes.py: 100%

52 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-08-23 19:54 +0000

1 

2 

3def divergingx_palettes(n = 5, **kwargs): 

4 """Diverging X HCL Palettes 

5 

6 Returns pre-defined 'diverging xtra' color palettes based on the HCL 

7 (Hue-Chroma-Luminance) color model. 

8 

9 Args: 

10 n (int): number of colors used when plotting, defaults to `5`. 

11 **kwargs: forwarded to :py:func:`hcl_palettes`. For a list and description 

12 of available arguments see the description of :py:func:`hcl_palettes`. 

13 

14 Return: 

15 See :py:func:`hcl_palettes`. 

16 

17 Examples: 

18 >>> from colorspace import divergingx_palettes 

19 >>> 

20 >>> # Get palettes 

21 >>> divergingx_palettes() 

22 >>> 

23 >>> #: Visualize palettes 

24 >>> divergingx_palettes(n = 15, ncol = 2, plot = True, figsize = (7, 5)); 

25 """ 

26 

27 from .hcl_palettes import hcl_palettes 

28 return hcl_palettes(n = n, **kwargs, files_regex = ".*divergingx.*") 

29 

30 

31def hcl_palettes(n = 5, type_ = None, name = None, plot = False, custom = None, ncol = 4, **kwargs): 

32 """Pre-Defined HCL Palettes 

33 

34 Function to retrieve and/or display pre-defined color palettes based on the 

35 HCL (Hue-Chroma-Luminance) color model, excludes 'diverging xtra' 

36 (see :py:func:`divergingx_palettes`). 

37 

38 The inputs `type_` and `name` can be used to retrieve a custom subset, 

39 `custom` can be used to add custom palettes if if needed. 

40 

41 If `plot = True`, `**kwargs` can be used to specify the figure size of the resulting 

42 image by specifying `figsize = (height, width)` where both, `height` 

43 and `width` must be int/float, specifying the height and width in inches. 

44 Note that `matplotlib` must be installed when `plot = True`. 

45 

46 

47 Args: 

48 n (int): The number of colors to be plotted, defaults to `7`. 

49 Only used if `plot = True`. 

50 type_ (None, str, list): Given a str or a list of str, 

51 only a subset of all available default color maps will 

52 returned/displayed. Can be used in combination with input argument 

53 `name`. Uses partial matching, not case sensitive. 

54 name (None, str, list): Similar to `type_`. If not specified 

55 all palettes will be returned. Can be set to a str or a list of 

56 str containing the names of the palettes which should be 

57 returned/plotted. 

58 plot (bool): If `False` (default) an object of type 

59 :py:class:`hclpalettes <colorspace.palettes.hclpalettes>` is returned, containing the 

60 (subset) of pre-defined HCL color palettes. 

61 custom (defaultpalette): One or multiple 

62 defaultpalettes can be provided in addition. 

63 ncol (int): Positive int, number of columns, defaults to `4`. 

64 **kwargs: Forwarded to the main 

65 :py:func:`swatchplot <colorspace.swatchplot.swatchplot>`  

66 function if `plot = True`. 

67 

68 Returns: 

69 Object of type `hclpalettes` or a `matplotlib.figure.Figure` object. If `plot = True` 

70 a plot will be created and the figure handler returned. If `plot = False` (default) 

71 an object of class :py:class:`hclpalettes <colorspace.palettes.hclpalettes>` is returned. 

72 

73 Raises: 

74 TypeError: If `n`/`ncol` not of type int. 

75 TypeError: If `type_` is not None or str. 

76 TypeError: If not is bool `plot`. 

77 TypeError: In case `custom` is an invalid input. 

78 ValueError: If `n` or `ncol` are not positive. 

79 Exception: If no palettes can be found matching the `type_` argument. 

80 

81 Examples: 

82 

83 Basic usage: 

84 

85 >>> from colorspace import hcl_palettes 

86 >>> # Get all pre-defined HCL palettes shipped with the package 

87 >>> hcl_palettes() 

88 >>> #: Get all diverging HCL palettes (basic and advanced) 

89 >>> hcl_palettes(type_ = "Diverging") 

90 >>> #: Get only basic diverging HCL palettes 

91 >>> hcl_palettes(type_ = "Basic: Diverging") 

92 >>> #: Get specific HCL palettes by name 

93 >>> hcl_palettes(name = ["Oranges", "Tropic"])  

94 >>> 

95 >>> #: Visualize all diverging HCL palettes 

96 >>> hcl_palettes(type_ = "Diverging", ncol = 2, 

97 >>> plot = True, figsize = (6, 4)); 

98 >>> #: Visualize specific palettes selected by name 

99 >>> hcl_palettes(name = ["Oranges", "Tropic"], 

100 >>> plot = True, ncol = 1, figsize = (6, 2)); 

101 >>> 

102 >>> #: Specify number of colors shown 

103 >>> hcl_palettes(n = 5, type_ = "Basic: Diverging", 

104 >>> plot = True, ncol = 1, figsize = (6, 3)); 

105 >>> #: 

106 >>> hcl_palettes(n = 51, type_ = "Advanced: Diverging", 

107 >>> plot = True, ncol = 1, figsize = (6, 8)); 

108 >>> 

109 >>> #: Extract specific palettes after loading 

110 >>> palettes = hcl_palettes() 

111 >>> c1 = palettes.get_palette("Oranges") 

112 >>> c1 

113 >>> #: 

114 >>> c2 = palettes.get_palette("Greens") 

115 >>> c2 

116 >>> 

117 >>> #: Modify palettes by overwriting palette settings 

118 >>> c1.set(h1 = 99, l2 = 30, l1 = 30) 

119 >>> c1.rename("Custom Palette #1") 

120 >>> c2.set(h1 = -30, l1 = 40, l2 = 30, c1 = 30, c2 = 40) 

121 >>> c2.rename("Custom Palette #2") 

122 >>>  

123 >>> # Visualize customized palettes 

124 >>> hcl_palettes(type_ = "Custom", custom = [c1, c2], 

125 >>> plot = True, ncol = 1, figsize = (6, 1)); 

126 

127 """ 

128 

129 # Loading pre-defined palettes from within the package 

130 from . import hclpalettes 

131 # Loading palettes. Ignore all files labeled 'divergingx' in some way as long 

132 # as no files_regex is provided on **kwargs 

133 files_regex = "(?!.*divergingx.*)" if not "files_regex" in kwargs.keys() else kwargs["files_regex"] 

134 pals = hclpalettes(files_regex = files_regex) 

135 

136 # Sanity type checks 

137 if not isinstance(n, int): raise TypeError("argument `n` must be int") 

138 if not isinstance(ncol, int): raise TypeError("argument `ncol` must be int") 

139 if not isinstance(type_, (type(None), str)): 

140 raise TypeError("Argument 'type_' must be None (default) or str.") 

141 if not isinstance(plot, bool): raise TypeError("argument `plot` must be bool") 

142 

143 # Sanity value checks 

144 if not n > 0 or not ncol > 0: raise ValueError("arguments `n` and `ncol` must be positive int") 

145 

146 # If custom palettes have been added: add them as well (if 

147 # the types are correct, of course). 

148 if not custom is None: 

149 from numpy import all 

150 from .palettes import defaultpalette 

151 def customerror(): 

152 import inspect 

153 str = "List with custom palettes provided to {:s}".format(inspect.stack()[0][3]) 

154 str += " but not all elements are of type defaultpalette" 

155 raise TypeError(str) 

156 

157 if isinstance(custom, defaultpalette): 

158 pals._palettes_["Custom"] = [custom] 

159 # Check if all inputs are of correct type 

160 elif isinstance(custom, list): 

161 if not all([isinstance(x, defaultpalette) for x in custom]): customerror() 

162 pals._palettes_["Custom"] = custom 

163 # Else append pals._palettes_["Custom"] = custom 

164 else: 

165 raise TypeError("argument `custom` not one of the allowed types") 

166 

167 

168 if not type_ is None: 

169 if isinstance(type_, str): type_ = [type_] 

170 

171 # Drop palettes from hclpalettes object not requested 

172 # by the user. 

173 for t in pals.get_palette_types(): 

174 if not any([x.upper() in t.upper() for x in type_]): 

175 del pals._palettes_[t] 

176 else: 

177 type_ = pals.get_palette_types() 

178 

179 # Now dropping all color maps not matching a name, if the 

180 # user has set a name. 

181 if not name is None: 

182 if isinstance(name, str): name = [name] 

183 # Looping over palette types 

184 for t in pals.get_palette_types(): 

185 palettenames = [p.name() for p in pals.get_palettes(t)] 

186 drop = [] 

187 for i in range(0, len(palettenames)): 

188 if not palettenames[i] in name: drop.append(i) 

189 # Drop all? 

190 if len(drop) == len(palettenames): 

191 del pals._palettes_[t] 

192 else: 

193 drop.sort(reverse = True) 

194 for i in drop: del pals._palettes_[t][i] 

195 

196 # No palettes survived the selection above? 

197 if len(pals.get_palettes()) == 0: 

198 raise Exception(f"no palettes found matching one of: {', '.join(type_)}") 

199 

200 # Return if plot is not required 

201 if not plot: 

202 return pals 

203 else: 

204 from .swatchplot import swatchplot 

205 from numpy import ceil 

206 nrow = int(ceil((pals.length() + len(pals.get_palette_types())) / ncol)) 

207 return swatchplot(pals, nrow = nrow, n = n, **kwargs) 

208 

209 

210