1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 """
28 Create color scales.
29 """
30
31 import numpy.oldnumeric as N
32
33 from Errors import BiskitError
34
35
37 pass
38
40 """
41 Translate a range of numeric values into a range of color codes.
42
43 Example::
44 >>> p = ColorSpectrum( 'grey', 1, 500 )
45 >>> single_color= p.color( 250 )
46 >>> color_range = p.colors( range(25,250), resetLimits=0 )
47
48 Available palettes are:
49 * grey
50 * plasma
51 * plasma2 (default)
52 * sausage (seems to have a discontinuity at 50%, see example below)
53 """
54
55 MAX_COL = {'grey': 3 * 255,
56 'plasma': 3 * 255,
57 'plasma2': 3 * 255,
58 'sausage': 2 * 255}
59
60
61 - def __init__(self, palette="plasma2", vmin=0., vmax=1. ):
62 """
63 Create a new palette of given type and value range.
64
65 @param palette: palette type (grey, sausage, plasma, plasma2)
66 (default: plasma2)
67 @type palette: str
68 @param vmin: smallest value covered by the color range (default: 0.)
69 @type vmin: float
70 @param vmax: largest value covered by the color range (default: 1.)
71 @type vmax: float
72
73 @raise ColorError: if palette unknown
74 """
75
76 try:
77 self.col_func = eval( 'self._ColorSpectrum__' + palette )
78
79 self.vmin = vmin * 1.0
80 self.vmax = vmax * 1.0
81 self.col_max = self.MAX_COL[ palette ]
82
83 except AttributeError:
84 raise ColorError, 'Unknown palette: ' + str(palette)
85
86 except IndexError, why:
87 raise ColorError, 'Undefined palette: ' + str(why)
88
89
91 """
92 Create color.
93
94 @param red: rgb color, 0-255
95 @type red: int
96 @param green: rgb color, 0-255
97 @type green: int
98 @param blue: rgb color, 0-255
99 @type blue: int
100
101 @return: color
102 @rtype: int
103 """
104 return ((red << 16) + (green << 8) + blue)
105
106
108 """
109 Normalize values
110
111 @param value: normalization value
112 @type value: float
113
114 @return: normalized color
115 @rtype: int
116 """
117 if self.vmax == self.vmin:
118 return self.col_max
119 return (value - self.vmin) / ( self.vmax - self.vmin ) * self.col_max
120
121
122 - def color(self, value ):
123 """
124 Translate a single value into a color.
125
126 @param value: value to be translated into color
127 @type value: float
128 @return: color code for value
129 @rtype: int
130 """
131 r = self.__make_col( *self.col_func(self.__normalize(value)) )
132
133 return r
134
135
136 - def colors( self, values, resetLimits=1 ):
137 """
138 Translate a list of values into a list of colors.
139
140 @param values: values to be translated into colors
141 @type values: [float]
142 @param resetLimits: re-define color range on max and min of values
143 (default: 1)
144 @type resetLimits: 1|0
145
146 @return: color codes
147 @rtype: [int]
148 """
149 if resetLimits:
150 self.vmax = max( values ) * 1.
151 self.vmin = min( values ) * 1.
152
153 return [ self.color(v) for v in values ]
154
155
157 """
158 @param a: array of float
159 @type a: array of float
160 @param resetLimits: re-define color range on max and min of values
161 (default: 1)
162 @type resetLimits: 1|0
163
164 @return: matrix of color codes with same dimensions as a
165 @rtype: array of float
166 """
167 s = N.shape( a )
168 v = N.ravel( a )
169
170 r = self.colors( v, resetLimits=resetLimits )
171
172 r = N.reshape( r, s )
173
174 return r
175
176
178 """
179 @return: color mapping for each color
180 @rtype: [ (float,int) ], value
181 """
182 r = []
183 step = (self.vmax - self.vmin) / self.col_max
184
185 for i in range( self.col_max ):
186
187 v = i*step + self.vmin
188 c = self.color( v )
189
190 r.append( (v,c) )
191
192 return r
193
195 return int(min(255, round(x)))
196
197
198
199
200
202 x = self.__map(255 * x / self.col_max)
203 return x, x, x
204
206
207 blue_range = 150
208 red_range = 255
209 green_range = 255
210
211 if x <= blue_range:
212 red = 0
213 green = self.__map(x)
214 blue = self.__map(blue_range - x)
215
216 elif x <= 255:
217 red = 0
218 blue = 0
219 green = self.__map(x)
220
221 elif x > 255 + green_range:
222 x -= 255 + green_range
223 blue = 0
224 red = 255
225 green = self.__map(255 - x)
226 else:
227 x -= 255
228 blue = 0
229 red = self.__map(x)
230 green = 255
231
232 return red, green, blue
233
235
236 blue_range = 255
237 red_range = 255
238 green_range = 255
239
240 if x <= blue_range:
241 red = 0
242 green = self.__map(x)
243 blue = self.__map(blue_range - x)
244
245 elif x > 255 + green_range:
246 x -= 255 + green_range
247 blue = 0
248 red = 255
249 green = self.__map(255 - x)
250 else:
251 x -= 255
252 blue = 0
253 red = self.__map(x)
254 green = 255
255
256 return red, green, blue
257
259
260 first_half = 255
261
262 if x <= first_half:
263 red = self.__map(x)
264 green = 0
265 blue = self.__map(first_half - x)
266
267 else:
268 x -= 255
269 red = 255
270 green = self.__map(x)
271 blue = int(0.3 * 255)
272
273 return red, green, blue
274
275
277 """Quick access to a range of colors.
278
279 @param nColors: number of colors needed
280 @type nColors: int
281 @param palette: type of color spectrum
282 @type palette: str
283 @return: a range of color values
284 @rtype: [ int ]
285 """
286 c = ColorSpectrum( palette=palette, vmin=0, vmax=1. )
287
288 r = 1. * N.arange( 0, nColors ) / nColors
289
290 return c.colors( r )
291
292
293
294
295
296
297 import Biskit.test as BT
298
299 -class Test(BT.BiskitTest):
300 """ColorSpectrum test"""
301
303 """ColorSpectrum test"""
304 import biggles as B
305
306 c_grey = ColorSpectrum( 'grey', 0, 100 )
307 c_sausage = ColorSpectrum( 'sausage', 0, 100 )
308 c_plasma = ColorSpectrum( 'plasma', 0, 100 )
309 c_plasma2 = ColorSpectrum( 'plasma2', 0, 100 )
310
311 self.p = B.FramedPlot()
312
313
314
315 self.result = []
316 for i in range( 100 ):
317
318 x = (i, i+1 )
319 self.p.add( B.FillBelow( x, (1., 1.),
320 color = c_grey.color( i ) ) )
321 self.result += [ c_grey.color( i ) ]
322
323 self.p.add( B.FillBelow( x, (0.75, 0.75),
324 color = c_sausage.color( i ) ) )
325 self.p.add( B.FillBelow( x, (0.5, 0.5),
326 color = c_plasma.color( i ) ) )
327 self.p.add( B.FillBelow( x, (0.25, 0.25),
328 color = c_plasma2.color( i ) ) )
329
330
331
332
333 self.p.add( B.Curve( (0,100), (1.,1.)) )
334 self.p.add( B.Curve( (0,100), (.75,.75)) )
335 self.p.add( B.Curve( (0,100), (.5,.5) ))
336 self.p.add( B.Curve( (0,100), (0.25, 0.25)) )
337 self.p.add( B.Curve( (0,100), (0.0, 0.0)) )
338
339 self.p.add( B.PlotLabel( 0.5 ,0.9, 'grey') )
340 self.p.add( B.PlotLabel( 0.5 ,0.65, 'sausage') )
341 self.p.add( B.PlotLabel( 0.5 ,0.4, 'plasma') )
342 self.p.add( B.PlotLabel( 0.5 ,0.15, 'plasma2') )
343
344 if self.local or self.VERBOSITY > 2:
345 self.p.show()
346
347 self.assertEqual(self.result, self.EXPECTED)
348
349
350 EXPECTED = [0, 197379, 328965, 526344, 657930, 855309, 986895, 1184274, 1315860, 1513239, 1710618, 1842204, 2039583, 2171169, 2368548, 2500134, 2697513, 2829099, 3026478, 3158064, 3355443, 3552822, 3684408, 3881787, 4013373, 4210752, 4342338, 4539717, 4671303, 4868682, 5066061, 5197647, 5395026, 5526612, 5723991, 5855577, 6052956, 6184542, 6381921, 6513507, 6710886, 6908265, 7039851, 7237230, 7368816, 7566195, 7697781, 7895160, 8026746, 8224125, 8421504, 8553090, 8750469, 8882055, 9079434, 9211020, 9408399, 9539985, 9737364, 9868950, 10066329, 10263708, 10395294, 10592673, 10724259, 10921638, 11053224, 11250603, 11382189, 11579568, 11776947, 11908533, 12105912, 12237498, 12434877, 12566463, 12763842, 12895428, 13092807, 13224393, 13421772, 13619151, 13750737, 13948116, 14079702, 14277081, 14408667, 14606046, 14737632, 14935011, 15132390, 15263976, 15461355, 15592941, 15790320, 15921906, 16119285, 16250871, 16448250, 16579836]
351
352 if __name__ == '__main__':
353
354 BT.localTest()
355