| | 49 | |
| | 50 | |
| | 51 | def rgb2hsv(r, g, b): |
| | 52 | """Converts a RGB color into a HSV one |
| | 53 | |
| | 54 | See http://en.wikipedia.org/wiki/HSV_color_space |
| | 55 | """ |
| | 56 | maximum = max(r, g, b) |
| | 57 | minimum = min(r, g, b) |
| | 58 | if maximum == minimum: |
| | 59 | h = 0.0 |
| | 60 | elif maximum == r: |
| | 61 | h = 60.0 * ((g - b) / (maximum - minimum)) + 360.0 |
| | 62 | if h >= 360.0: |
| | 63 | h -= 360.0 |
| | 64 | elif maximum == g: |
| | 65 | h = 60.0 * ((b - r) / (maximum - minimum)) + 120.0 |
| | 66 | elif maximum == b: |
| | 67 | h = 60.0 * ((r - g) / (maximum - minimum)) + 240.0 |
| | 68 | |
| | 69 | if maximum == 0.0: |
| | 70 | s = 0.0 |
| | 71 | else: |
| | 72 | s = 1.0 - (minimum / maximum) |
| | 73 | |
| | 74 | v = maximum |
| | 75 | |
| | 76 | return h, s, v |
| | 77 | |
| | 78 | |
| | 79 | def hsv2rgb(h, s, v): |
| | 80 | """Converts a HSV color into a RGB one |
| | 81 | |
| | 82 | See http://en.wikipedia.org/wiki/HSV_color_space |
| | 83 | """ |
| | 84 | hi = int(math.floor(h / 60.0)) % 6 |
| | 85 | f = (h / 60.0) - hi |
| | 86 | p = v * (1 - s) |
| | 87 | q = v * (1 - f * s) |
| | 88 | t = v * (1 - (1 - f) * s) |
| | 89 | |
| | 90 | if hi == 0: |
| | 91 | r, g, b = v, t, p |
| | 92 | elif hi == 1: |
| | 93 | r, g, b = q, v, p |
| | 94 | elif hi == 2: |
| | 95 | r, g, b = p, v, t |
| | 96 | elif hi == 3: |
| | 97 | r, g, b = p, q, v |
| | 98 | elif hi == 4: |
| | 99 | r, g, b = t, p, v |
| | 100 | elif hi == 5: |
| | 101 | r, g, b = v, p, q |
| | 102 | |
| | 103 | return r, g, b |
| | 171 | |
| | 172 | |
| | 173 | class FixedColorScheme(ColorScheme): |
| | 174 | """In this color scheme fixed colors are used. |
| | 175 | |
| | 176 | These colors are provided as a list argument in the constructor. |
| | 177 | """ |
| | 178 | |
| | 179 | def __init__(self, keys, colors=[]): |
| | 180 | super(FixedColorScheme, self).__init__(keys) |
| | 181 | |
| | 182 | if len(keys) != len(colors): |
| | 183 | raise ValueError("You must provide as many colors as datasets " |
| | 184 | "for the fixed color scheme") |
| | 185 | |
| | 186 | for i, key in enumerate(keys): |
| | 187 | self[key] = hex2rgb(colors[i]) |
| | 188 | |
| | 189 | |
| | 190 | class RainbowColorScheme(ColorScheme): |
| | 191 | |
| | 192 | def __init__(self, keys, initialColor=DEFAULT_COLOR): |
| | 193 | super(RainbowColorScheme, self).__init__(keys) |
| | 194 | if initialColor in basicColors: |
| | 195 | initialColor = basicColors[initialColor] |
| | 196 | |
| | 197 | r, g, b = hex2rgb(initialColor) |
| | 198 | h, s, v = rgb2hsv(r, g, b) |
| | 199 | |
| | 200 | angleDelta = 360.0 / (len(keys) + 1) |
| | 201 | for key in keys: |
| | 202 | self[key] = hsv2rgb(h, s, v) |
| | 203 | h += angleDelta |
| | 204 | if h >= 360.0: |
| | 205 | h -= 360.0 |