Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1""" 

2A color and gradient management system. 

3 

4*Do not pick colors yourself*. A lot of research has gone into color 

5palettes. Specifically, for: 

6 

7Numeric data 

8 use `ColorBrewer <http://colorbrewer2.org/>`_ themes 

9 

10Non-numeric data 

11 use `ColorBrewer <http://colorbrewer2.org/>`_ 

12 or `Microsoft Office themes`_ 

13 

14Page design 

15 use `kuler.adobe.com <https://kuler.adobe.com/#create/fromanimage>`_ 

16 *from an image* (not directly). 

17 

18 

19Microsoft office themes 

20----------------------- 

21 

22The following color palettes based on Microsoft Office are available: 

23 

24Office, Adjacency, Apex, Apothecary, Aspect, Austin, BlackTie, Civic, Clarity, 

25Composite, Concourse, Couture, Elemental, Equity, Essential, Executive, Flow, 

26Foundry, Grid, Hardcover, Horizon, Median, Metro, Module, Newsprint, Opulent, 

27Oriel, Origin, Paper, Perspective, Pushpin, SlipStream, Solstice, Technic, 

28Thatch, Trek, Urban, Verve, Waveform 

29 

30A palette's colours can be accessed as an array or as an attribute. For e.g.: 

31 

32>>> Office[0] # The first element 

33u'#4f81bd' 

34>>> Office.accent_1 # ... is called .accent_1 

35u'#4f81bd' 

36>>> Office[1] # The next element 

37u'#c0504d' 

38>>> Office.accent_2 # ... is called .accent_2 

39u'#c0504d' 

40 

41The following 10 attributes are available (in order): 

42 

430. accent_1 

441. accent_2 

452. accent_3 

463. accent_4 

474. accent_5 

485. accent_6 

496. light_2 

507. dark_2 

518. light_1 

529. dark_1 

53 

54""" 

55 

56import os 

57import re 

58import six 

59import json 

60import operator 

61import colorsys 

62import warnings 

63import numpy as np 

64from io import open 

65 

66 

67BASE_0 = 0 

68BASE_1 = 1 

69BASE_2 = 2 

70BASE_3 = 3 

71BASE_4 = 4 

72BASE_5 = 5 

73BASE_7 = 7 

74BASE_9 = 9 

75BASE_15 = 15 

76BASE_16 = 16 

77BASE_255 = 255 

78BASE_256 = 256 

79 

80 

81class _MSO(object): 

82 """ 

83 Microsoft office themes. Refer to colors in any of these ways: 

84 

85 color['accent_1'] 

86 color[0] 

87 color.accent_1 

88 color[:1] 

89 """ 

90 

91 _lookup = { 

92 'accent_1': 0, 

93 'accent_2': 1, 

94 'accent_3': 2, 

95 'accent_4': 3, 

96 'accent_5': 4, 

97 'accent_6': 5, 

98 'light_2': 6, 

99 'dark_2': 7, 

100 'light_1': 8, 

101 'dark_1': 9, 

102 } 

103 

104 def __init__(self, *values): 

105 self.values = values 

106 

107 def __getitem__(self, key): 

108 if isinstance(key, slice) or type(key) is int: 

109 return self.values.__getitem__(key) 

110 elif key in self._lookup: 

111 return self.values[self._lookup[key]] 

112 

113 def __getattr__(self, key): 

114 if key in self._lookup: 

115 return self.values[self._lookup[key]] 

116 

117 def __len__(self): 

118 return len(self.values) 

119 

120 def __str__(self): 

121 return ' '.join(self.values) 

122 

123 def __repr__(self): 

124 return '_MSO' + repr(self.values) 

125 

126 

127def _rgb(color): 

128 """ 

129 .. deprecated:: 0.1 

130 Use :func:`rgba` instead 

131 """ 

132 warnings.warn('Use color.rgba instead of color._rgb', 

133 FutureWarning, stacklevel=2) 

134 return (int(color[-6:-4], BASE_16), int(color[-4:-2], BASE_16), 

135 int(color[-2:], BASE_16)) 

136 

137 

138def gradient(value, grad, opacity=1, sort=True): 

139 """ 

140 Converts a number or list ``x`` into a color using a gradient. 

141 

142 

143 :arg number value: int, float, list, numpy array or any iterable. 

144 If an iterable is passed, a list of colors is returned. 

145 :arg list grad: tuple/list of ``(value, color)`` tuples 

146 For example, ``((0, 'red'), (.5, 'yellow'), (1, 'green'))``. 

147 Values will be sorted automatically 

148 :arg float opacity: optional alpha to be added to the returned color 

149 :arg bool sort: optional. If ``grad`` is already sorted, set ``sort=False`` 

150 

151 These gradients are available: 

152 

153 **divergent gradients** : on a ``[-1, 1]`` scale 

154 multi-color 

155 ``RdGy``, ``RdYlGn``, ``Spectral`` 

156 ... also print-friendly and color-blind safe 

157 ``BrBG``, ``PiYG``, ``PRGn``, ``RdBu``, ``RdYlBu`` 

158 ... and also photocopyable 

159 ``PuOr`` 

160 **sequential gradients** : on a ``[0, 1]`` scale 

161 one-color 

162 ``Reds``, ``Blues``, ``Greys``, ``Greens``, ``Oranges``, 

163 ``Purples``, ``Browns``, ``Yellows`` 

164 two-color 

165 ``BuGn``, ``BuPu``, ``GnBu``, ``OrRd``, ``PuBu``, ``PuRd``, 

166 ``RdPu``, ``YlGn`` 

167 three-color 

168 ``YlGnBu``, ``YlOrBr``, ``YlOrRd``, ``PuBuGn`` 

169 

170 The following are also available, but do not use them. 

171 

172 - ``RYG`` maps ``[0, 1]`` to Red-Yellow-Green 

173 - ``RWG`` maps ``[0, 1]`` to Red-White-Green 

174 - ``RYG_1`` maps ``[-1, -1]`` to Red-Yellow-Green 

175 - ``RWG_1`` maps ``[-1, -1]`` to Red-White-Green 

176 

177 Examples:: 

178 

179 # Get a value that is 40% blue and 60% white, use: 

180 >>> gradient(0.4, ((0, 'blue'), (1, 'white'))) 

181 '#66f' 

182 

183 # A list (or any iterable) input returns a list of colors 

184 >>> gradient([0.2, 0.6, 0.8], ((0, 'blue'), (1, 'white'))) 

185 ['#33f', '#99f', '#ccf'] 

186 

187 # Values out of range are truncated. 

188 >>> gradient([-10, +10], ((0, 'blue'), (1, 'white'))) 

189 ['blue', 'white'] 

190 

191 # Use a pre-defined gradient to classify a value between -1 to 1 on a 

192 # Red-Yellow-Green scale. (Returns a value between Yellow and Green). 

193 >>> gradient(0.5, RdYlGn) 

194 '#8ccb87' 

195 """ 

196 if sort: 

197 grad = sorted(grad, key=operator.itemgetter(BASE_0)) 

198 

199 # If value is iterable, apply gradient to each value (recursively) 

200 if np.ndim(value) > BASE_0: 

201 return [gradient(val, grad, opacity=opacity, sort=False) 

202 for val in value] 

203 

204 value = float(value) if not np.isnan(value) else BASE_0 

205 if value <= grad[BASE_0][BASE_0]: 

206 return grad[BASE_0][BASE_1] 

207 

208 grd_idx = -1 

209 if value >= grad[grd_idx][BASE_0]: 209 ↛ 210line 209 didn't jump to line 210, because the condition on line 209 was never true

210 return grad[grd_idx][BASE_1] 

211 i = BASE_0 

212 for i, (start, color1) in enumerate(grad): 212 ↛ 215line 212 didn't jump to line 215, because the loop on line 212 didn't complete

213 if value <= start: 

214 break 

215 dist1 = (value - grad[i - BASE_1][BASE_0]) / ( 

216 grad[i][BASE_0] - grad[i - BASE_1][BASE_0]) 

217 

218 sec_dist = 1.0 

219 dist2 = sec_dist - dist1 

220 color1 = rgba(grad[i - BASE_1][BASE_1]) 

221 color2 = rgba(grad[i][BASE_1]) 

222 return name(color1[BASE_0] * dist2 + color2[BASE_0] * dist1, 

223 color1[BASE_1] * dist2 + color2[BASE_1] * dist1, 

224 color1[BASE_2] * dist2 + color2[BASE_2] * dist1, 

225 opacity) 

226 

227 

228_DISTINCTS = [ 

229 "#1f77b4", "#aec7e8", 

230 "#ff7f0e", "#ffbb78", 

231 "#2ca02c", "#98df8a", 

232 "#d62728", "#ff9896", 

233 "#9467bd", "#c5b0d5", 

234 "#8c564b", "#c49c94", 

235 "#e377c2", "#f7b6d2", 

236 "#7f7f7f", "#c7c7c7", 

237 "#bcbd22", "#dbdb8d", 

238 "#17becf", "#9edae5" 

239] 

240 

241 

242def distinct(count): 

243 """ 

244 Generates a list of ``count`` distinct colors, for up to 20 colors. 

245 

246 :arg int count: number of colors to return 

247 

248 Examples:: 

249 

250 >>> distinct(4) 

251 ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728'] 

252 

253 Notes: 

254 

255 - Colour conversion between RGB and HCL are available on 

256 `color.py <http://2sn.org/python/color.py>`_ and 

257 `python-colormath <http://python-colormath.readthedocs.org/>`_ 

258 - People seem to struggle with about 

259 `26 colours 

260 <http://eleanormaclure.files.wordpress.com/2011/03/colour-coding.pdf>`_ 

261 so this may be an upper bound 

262 - A good starting point for resources is on 

263 `stackoverflow <http://stackoverflow.com/q/470690/100904>`_ and the 

264 `graphic design <http://graphicdesign.stackexchange.com/q/3682>`_ 

265 stackexchange 

266 - More palettes are available from 

267 `Kenneth Kelly (22) <http://www.iscc.org/pdf/PC54_1724_001.pdf>`_ and 

268 `ggplot2 <http://learnr.wordpress.com/2009/04/15/ggplot2/>`_ 

269 - See also: http://epub.wu.ac.at/1692/1/document.pdf 

270 """ 

271 tens_count = 10 

272 twenty_count = 20 

273 _distinct = 2 

274 if count <= tens_count: 

275 return [_DISTINCTS[_distinct * i] for i in range(count)] 

276 elif count <= twenty_count: 

277 return _DISTINCTS[:count] 

278 else: 

279 return _DISTINCTS[:] 

280 

281 

282def contrast(color, white='#ffffff', black='#000000'): 

283 """ 

284 Returns the colour (white or black) that contrasts best with a given 

285 color. 

286 

287 :arg color color: color string recognied by :func:`rgba`. 

288 If this color is dark, returns white. Else, black 

289 :arg color white: color string, optional. 

290 Replace this with any light colour you want to use instead of white 

291 :arg color black: color string, optional. 

292 Replace this with any dark colour you want to use instead of black 

293 

294 Examples:: 

295 

296 >>> contrast('blue') 

297 '#fff' 

298 >>> contrast('lime') 

299 '#000' 

300 

301 Note: `Decolorize <http://www.eyemaginary.com/Rendering/TurnColorsGray.pdf>`_ 

302 algorithm used. Appears to be the most preferred 

303 (`ref <http://dcgi.felk.cvut.cz/home/cadikm/color_to_gray_evaluation/>`_). 

304 """ 

305 idx = 3 

306 red, green, blue = rgba(color)[:idx] 

307 red_opac = 0.299 

308 blue_opac = 0.114 

309 green_opac = 0.582 

310 cut_off = .5 

311 

312 luminosity = red_opac * red + green_opac * green + blue_opac * blue 

313 return black if luminosity > cut_off else white 

314 

315 

316def brighten(color, percent): 

317 """ 

318 Brighten or darken a color by percentage. If ``percent`` is positive, 

319 brighten the color. Else darken the color. 

320 

321 :arg str color: color string recognied by :func:`rgba` 

322 :arg float percent: -1 indicates black, +1 indicates white. Rest are interpolated. 

323 

324 Examples:: 

325 

326 >>> brighten('lime', -1) # 100% darker, i.e. black 

327 '#000' 

328 >>> brighten('lime', -0.5) # 50% darker 

329 '#007f00' 

330 >>> brighten('lime', 0) # Returns the color as-is 

331 '#0f0' 

332 >>> brighten('lime', 0.5) # 50% brighter 

333 '#7fff7f' 

334 >>> brighten('lime', 1) # 100% brighter, i.e. white 

335 '#fff' 

336 >>> brighten('lime', 2) # Values beyond +1 or -1 are truncated 

337 '#fff' 

338 """ 

339 _min = -1 

340 _mid = 0 

341 _max = +1 

342 black = '#0000000' 

343 white = '#ffffff' 

344 return gradient(percent, ((_min, black), (_mid, color), (_max, white))) 

345 

346 

347def msrgb(value, grad=None): 

348 """ 

349 Returns the Microsoft 

350 `RGB color <http://msdn.microsoft.com/en-in/library/dd355244.aspx>`_ 

351 corresponding to a given a color. This is used for Microsoft office 

352 output (e.g. Excel, PowerPoint, etc.) 

353 

354 :arg color value: color or int/float. If ``grad`` is not specified, this 

355 should be a color that will get converted into a Microsoft RGB value. If 

356 ``grad`` is specified, this should be a number. It will be converted into 

357 a color using the gradient, and then into a Microsoft RGB value. 

358 :arg tuple grad: tuple/list of ``(value, color)`` tuples For example, ``((0, 

359 'red'), (.5, 'yellow'), (1, 'green'))``. This is passed as an input to 

360 :func:`gradient` 

361 

362 Examples:: 

363 

364 >>> msrgb('#fff') 

365 16777215 

366 >>> msrgb('red') 

367 255 

368 >>> msrgb(0.5, RYG) # == msrgb(gradient(0.5, RYG)) 

369 65535 

370 """ 

371 idx = 3 

372 red, green, blue = rgba(gradient(value, grad) if grad else value)[:idx] 

373 return int((blue * BASE_255 * BASE_256 + green * BASE_255) * BASE_256 + red * BASE_255) 

374 

375 

376def msrgbt(value, grad=None): 

377 """ 

378 Returns the Microsoft RGB value (same as :func:`msrgbt`) and transparency 

379 as a tuple. 

380 

381 For example:: 

382 

383 color, transparency = msrgbt('rgba(255, 0, 0, .5)') 

384 shp.Fill.ForeColor.RGB, shp.Fill.Transparency = color, transparency 

385 

386 See :func:`msrgbt`. The parameters are identical. 

387 

388 Examples:: 

389 

390 >>> msrgbt('rgba(255,0,0,.5)') 

391 (255, 0.5) 

392 >>> msrgbt('red') 

393 (255, 0.0) 

394 """ 

395 _alpha = 1 

396 red, green, blue, alpha = rgba(gradient(value, grad) if grad else value) 

397 alpha = _alpha - alpha 

398 col = (blue * BASE_255 * BASE_256 + green * BASE_255) * BASE_256 + red * BASE_255 

399 return int(col), alpha 

400 

401 

402def rgba(color): 

403 """ 

404 Returns red, green, blue and alpha values (as a 0-1 float) of a color. 

405 

406 :arg color color: a string representing the color. 

407 Most color formats defined in 

408 `CSS3 <http://dev.w3.org/csswg/css3-color/>`_ are allowed. 

409 

410 Examples:: 

411 

412 >>> rgba('#f00') 

413 (1.0, 0.0, 0.0, 1.0) 

414 >>> rgba('#f003') 

415 (1.0, 0.0, 0.0, 0.2) 

416 >>> rgba('#ff0000') 

417 (1.0, 0.0, 0.0, 1.0) 

418 >>> rgba('#ff000033') 

419 (1.0, 0.0, 0.0, 0.2) 

420 >>> rgba('rgb(255,0,0)') 

421 (1.0, 0.0, 0.0, 1.0) 

422 >>> rgba('rgba(255,0,0,.2)') 

423 (1.0, 0.0, 0.0, 0.2) 

424 >>> rgba('red') 

425 (1.0, 0.0, 0.0, 1.0) 

426 >>> rgba('white') 

427 (1.0, 1.0, 1.0, 1.0) 

428 >>> rgba('hsl(0,1,1)') 

429 (1.0, 0.0, 0.0, 1.0) 

430 >>> rgba('hsla(0,1,1,.2)') 

431 (1.0, 0.0, 0.0, 0.2) 

432 >>> rgba('hsl(0, 100%, 50%)') 

433 (0.5, 0.0, 0.0, 1.0) 

434 >>> rgba('hsla(0, 100%, 100%, .9)') 

435 (1.0, 0.0, 0.0, 0.9) 

436 >>> rgba('hsla(360, 100%, 100%, 1.9)') 

437 (1.0, 0.0, 0.0, 1.0) 

438 >>> rgba('hsla(360, 0%, 50%, .5)') 

439 (0.5, 0.5, 0.5, 0.5) 

440 >>> rgba('hsla(0, 0%, 50%, .5)') 

441 (0.5, 0.5, 0.5, 0.5) 

442 """ 

443 result = [] 

444 if color.startswith('#'): 444 ↛ 466line 444 didn't jump to line 466, because the condition on line 444 was never false

445 if len(color) == BASE_9: 445 ↛ 446line 445 didn't jump to line 446, because the condition on line 445 was never true

446 result = [int(color[BASE_1:BASE_3], BASE_16) / float(BASE_255), 

447 int(color[BASE_3:BASE_5], BASE_16) / float(BASE_255), 

448 int(color[BASE_5:BASE_7], BASE_16) / float(BASE_255), 

449 int(color[BASE_7:BASE_9], BASE_16) / float(BASE_255)] 

450 elif len(color) == BASE_7: 450 ↛ 454line 450 didn't jump to line 454, because the condition on line 450 was never false

451 result = [int(color[BASE_1:BASE_3], BASE_16) / float(BASE_255), 

452 int(color[BASE_3:BASE_5], BASE_16) / float(BASE_255), 

453 int(color[BASE_5:BASE_7], BASE_16) / float(BASE_255)] 

454 elif len(color) == BASE_5: 

455 result = [int(color[BASE_1:BASE_2], BASE_16) / float(BASE_15), 

456 int(color[BASE_2:BASE_3], BASE_16) / float(BASE_15), 

457 int(color[BASE_3:BASE_4], BASE_16) / float(BASE_15), 

458 int(color[BASE_4:BASE_5], BASE_16) / float(BASE_15)] 

459 elif len(color) == BASE_4: 

460 result = [int(color[BASE_1:BASE_2], BASE_16) / float(BASE_15), 

461 int(color[BASE_2:BASE_3], BASE_16) / float(BASE_15), 

462 int(color[BASE_3:BASE_4], BASE_16) / float(BASE_15)] 

463 else: 

464 result = [] 

465 

466 elif color.startswith('rgb(') or color.startswith('rgba('): 

467 for i, val in enumerate(re.findall(r'[0-9\.%]+', color.split('(')[1])): 

468 if val.endswith('%'): 

469 result.append(float(val[:-1]) / 100) 

470 elif i < 3: 

471 result.append(float(val) / float(BASE_255)) 

472 else: 

473 result.append(float(val)) 

474 

475 elif color.startswith('hsl(') or color.startswith('hsla('): 

476 for i, val in enumerate(re.findall(r'[0-9\.%]+', color.split('(')[BASE_1])): 

477 if val.endswith('%'): 

478 val_idx = -1 

479 div = 100 

480 result.append(float(val[:val_idx]) / div) 

481 elif i == BASE_0: 

482 div_base = 360 

483 result.append(float(val) / div_base % BASE_1) 

484 else: 

485 result.append(float(val)) 

486 result[BASE_0], result[BASE_1], result[BASE_2] = colorsys.hsv_to_rgb( 

487 result[BASE_0], result[BASE_1], result[BASE_2]) 

488 

489 elif color in _COLORNAMES: 

490 result = [val / float(BASE_255) for val in _COLORNAMES[color]] 

491 

492 if len(result) == BASE_3: 492 ↛ 495line 492 didn't jump to line 495, because the condition on line 492 was never false

493 result.append(float(BASE_1)) 

494 

495 if len(result) != BASE_4: 495 ↛ 496line 495 didn't jump to line 496, because the condition on line 495 was never true

496 raise ValueError('%s: invalid color' % color) 

497 

498 return tuple( 

499 float(BASE_0) if val < BASE_0 else float( 

500 BASE_1) if val > BASE_1 else val for val in result) 

501 

502 

503def hsla(color): 

504 """ 

505 Returns hue, saturation, luminosity and alpha values (as a 0-1 float) for 

506 a color. 

507 

508 :arg color color: a string representing the color. 

509 Most color formats defined in 

510 `CSS3 <http://dev.w3.org/csswg/css3-color/>`_ are allowed. 

511 

512 Examples:: 

513 

514 >>> hsla('#f00') 

515 (0.0, 1.0, 1.0, 1.0) 

516 >>> hsla('#f003') 

517 (0.0, 1.0, 1.0, 0.2) 

518 >>> hsla('#ff0000') 

519 (0.0, 1.0, 1.0, 1.0) 

520 >>> hsla('#ff000033') 

521 (0.0, 1.0, 1.0, 0.2) 

522 >>> hsla('rgb(255,0,0)') 

523 (0.0, 1.0, 1.0, 1.0) 

524 >>> hsla('rgba(255,0,0,.2)') 

525 (0.0, 1.0, 1.0, 0.2) 

526 >>> hsla('red') 

527 (0.0, 1.0, 1.0, 1.0) 

528 >>> hsla('hsl(0,1,1)') 

529 (0.0, 1.0, 1.0, 1.0) 

530 >>> hsla('hsla(0,1,1,.2)') 

531 (0.0, 1.0, 1.0, 0.2) 

532 """ 

533 result = rgba(color) 

534 return colorsys.rgb_to_hsv( 

535 result[BASE_0], result[BASE_1], result[BASE_2]) + (result[BASE_3], ) 

536 

537 

538def name(red, green, blue, alpha=1): 

539 """ 

540 Returns a short color string 

541 

542 :arg float red: red color value (0-1) 

543 :arg float green: green color value (0-1) 

544 :arg float blue: blue color value (0-1) 

545 :arg float alpha: float, optional transparency value between 0-1. 

546 ``alpha=1`` produces color strings like ``#abc`` 

547 Lower values produce ``rgba(...)```. 

548 

549 Examples:: 

550 

551 >>> name(1, 0, 0) # Short color versions preferred 

552 '#f00' 

553 >>> name(1, 0, 0, .2) # Alpha creates rgba() with 2 decimals 

554 'rgba(255,0,0,0.20)' 

555 >>> name(.5, .25, .75) # Multiply by 255 and round to nearest 

556 '#8040bf' 

557 >>> name(-1, 2, 0) # Values are truncated to 0-1 

558 '#0f0' 

559 """ 

560 red = int(round( 

561 BASE_255 * (BASE_0 if red < BASE_0 else BASE_1 if red > BASE_1 else red), 

562 BASE_0)) 

563 

564 green = int(round( 

565 BASE_255 * (BASE_0 if green < BASE_0 else BASE_1 if green > BASE_1 else green), 

566 BASE_0)) 

567 

568 blue = int(round( 

569 BASE_255 * (BASE_0 if blue < BASE_0 else BASE_1 if blue > BASE_1 else blue), 

570 BASE_0)) 

571 

572 alpha = BASE_0 if alpha < BASE_0 else BASE_1 if alpha > BASE_1 else alpha 

573 if alpha == BASE_1: 573 ↛ 576line 573 didn't jump to line 576, because the condition on line 573 was never false

574 return '#%02x%02x%02x' % (red, green, blue) 

575 else: 

576 return 'rgba(%d,%d,%d,%0.2f)' % (red, green, blue, alpha) 

577 

578 

579def _add_gradients(target, data): 

580 """Add gradients to the module""" 

581 mid_val = 0.5 

582 min_val = -1.0 

583 for grad, colors in six.iteritems(data['sequential']): 

584 target[grad] = [[float(BASE_0), colors[BASE_0]], 

585 [mid_val, colors[BASE_1]], 

586 [float(BASE_1), colors[BASE_2]]] 

587 for grad, colors in six.iteritems(data['divergent']): 

588 target[grad] = [[min_val, colors[BASE_0]], 

589 [float(BASE_0), colors[BASE_1]], 

590 [float(BASE_1), colors[BASE_2]]] 

591 for grad, colors in six.iteritems(data['office']): 

592 target[grad] = _MSO(*colors) 

593 

594 

595_DATA = json.load(open(os.path.join(os.path.dirname( 

596 os.path.realpath(__file__)), 'colors.json'), encoding='utf-8')) 

597_COLORNAMES = _DATA['names'] 

598_add_gradients(globals(), _DATA)