0
# Colors and Transforms
1
2
Color palettes, color classes, and data transformation functions for enhanced visualizations. Includes 100+ built-in color palettes and transforms for categorical mapping, data stacking, positioning adjustments, and color mapping based on data values.
3
4
## Capabilities
5
6
### Color Classes
7
8
Classes for representing and manipulating colors in different color spaces.
9
10
```python { .api }
11
class Color:
12
"""
13
Base color class.
14
15
Provides common interface for all color representations.
16
"""
17
def to_hex(self):
18
"""Convert to hexadecimal color string."""
19
20
def to_rgb(self):
21
"""Convert to RGB color object."""
22
23
def to_hsl(self):
24
"""Convert to HSL color object."""
25
26
class RGB(Color):
27
"""
28
RGB color representation.
29
30
Parameters:
31
- r: Red component (0-255)
32
- g: Green component (0-255)
33
- b: Blue component (0-255)
34
- a: Alpha/transparency (0.0-1.0, default: 1.0)
35
"""
36
def __init__(self, r, g, b, a=1.0): ...
37
38
r: int
39
g: int
40
b: int
41
a: float
42
43
class HSL(Color):
44
"""
45
HSL color representation.
46
47
Parameters:
48
- h: Hue (0-360 degrees)
49
- s: Saturation (0.0-1.0)
50
- l: Lightness (0.0-1.0)
51
- a: Alpha/transparency (0.0-1.0, default: 1.0)
52
"""
53
def __init__(self, h, s, l, a=1.0): ...
54
55
h: float
56
s: float
57
l: float
58
a: float
59
60
# Type hint for color-like objects
61
ColorLike = Union[str, RGB, HSL, Color]
62
```
63
64
### Color Palettes
65
66
Pre-defined color palettes for different visualization needs. Categorical palettes are dictionaries that map size numbers to color lists (e.g., `Category10[5]` gives 5 colors). Sequential and diverging palettes have specific size variants.
67
68
```python { .api }
69
# Categorical palettes (for discrete data)
70
Category10: Dict[int, List[str]] # Dictionary mapping sizes (3-10) to color lists
71
Category20: Dict[int, List[str]] # Dictionary mapping sizes (3-20) to color lists
72
Category20b: Dict[int, List[str]] # Alternative 20-color palette dictionary
73
Category20c: Dict[int, List[str]] # Alternative 20-color palette dictionary
74
Bokeh8: List[str] # 8 Bokeh brand colors
75
76
# Sequential palettes (for continuous data, low to high)
77
# Available in sizes 3-9 (e.g., Blues3, Blues4, ..., Blues9)
78
Blues3: List[str] # Light to dark blue (3 colors)
79
Blues9: List[str] # Light to dark blue (9 colors)
80
BuGn3: List[str] # Blue to green
81
BuPu3: List[str] # Blue to purple
82
GnBu3: List[str] # Green to blue
83
Greens3: List[str] # Light to dark green
84
Greys3: List[str] # Light to dark grey
85
Oranges3: List[str] # Light to dark orange
86
OrRd3: List[str] # Orange to red
87
PuBu3: List[str] # Purple to blue
88
PuBuGn3: List[str] # Purple to blue to green
89
PuRd3: List[str] # Purple to red
90
Purples3: List[str] # Light to dark purple
91
RdPu3: List[str] # Red to purple
92
Reds3: List[str] # Light to dark red
93
YlGn3: List[str] # Yellow to green
94
YlGnBu3: List[str] # Yellow to green to blue
95
YlOrBr3: List[str] # Yellow to orange to brown
96
YlOrRd3: List[str] # Yellow to orange to red
97
98
# Diverging palettes (for data with meaningful center point)
99
BrBG3: List[str] # Brown to blue-green
100
PiYG3: List[str] # Pink to yellow-green
101
PRGn3: List[str] # Purple to green
102
PuOr3: List[str] # Purple to orange
103
RdBu3: List[str] # Red to blue
104
RdGy3: List[str] # Red to grey
105
RdYlBu3: List[str] # Red to yellow to blue
106
RdYlGn3: List[str] # Red to yellow to green
107
Spectral3: List[str] # Spectral colors
108
109
# Matplotlib-inspired palettes (256 colors each)
110
Viridis256: List[str] # Perceptually uniform, colorblind-friendly
111
Plasma256: List[str] # Purple to pink to yellow
112
Inferno256: List[str] # Black to red to yellow
113
Magma256: List[str] # Black to purple to white
114
Cividis256: List[str] # Blue to yellow, colorblind-friendly
115
116
# High-resolution palettes
117
Turbo256: List[str] # Rainbow-like, improved over jet
118
```
119
120
### Color Mapping Transforms
121
122
Functions that create color mapping transformations based on data values.
123
124
```python { .api }
125
def linear_cmap(field_name, palette, low, high, low_color=None, high_color=None,
126
nan_color='gray'):
127
"""
128
Linear color mapping transformation.
129
130
Maps numeric data values to colors using linear interpolation.
131
132
Parameters:
133
- field_name: Name of data source column
134
- palette: List of colors for interpolation
135
- low: Minimum data value for mapping
136
- high: Maximum data value for mapping
137
- low_color: Color for values below 'low' (default: first palette color)
138
- high_color: Color for values above 'high' (default: last palette color)
139
- nan_color: Color for NaN values
140
141
Returns:
142
Transform: Linear color mapper transform
143
"""
144
145
def log_cmap(field_name, palette, low, high, low_color=None, high_color=None,
146
nan_color='gray'):
147
"""
148
Logarithmic color mapping transformation.
149
150
Maps numeric data values to colors using logarithmic scaling.
151
152
Parameters:
153
- field_name: Name of data source column
154
- palette: List of colors for interpolation
155
- low: Minimum data value for mapping (must be > 0)
156
- high: Maximum data value for mapping
157
- low_color: Color for values below 'low'
158
- high_color: Color for values above 'high'
159
- nan_color: Color for NaN values
160
161
Returns:
162
Transform: Logarithmic color mapper transform
163
"""
164
165
def factor_cmap(field_name, palette, factors, start=0, end=None, nan_color='gray'):
166
"""
167
Categorical color mapping transformation.
168
169
Maps categorical data values to colors from a palette.
170
171
Parameters:
172
- field_name: Name of data source column
173
- palette: List of colors (cycled if fewer than factors)
174
- factors: List of categorical values to map
175
- start: Starting index in palette
176
- end: Ending index in palette (None = use all)
177
- nan_color: Color for values not in factors
178
179
Returns:
180
Transform: Categorical color mapper transform
181
"""
182
183
def eqhist_cmap(field_name, palette, bins=256, rescale_discrete_levels=True):
184
"""
185
Equal-histogram color mapping transformation.
186
187
Maps data values to colors using histogram equalization for uniform
188
color distribution regardless of data distribution.
189
190
Parameters:
191
- field_name: Name of data source column
192
- palette: List of colors for mapping
193
- bins: Number of histogram bins
194
- rescale_discrete_levels: Rescale for discrete data
195
196
Returns:
197
Transform: Equal-histogram color mapper transform
198
"""
199
```
200
201
### Visual Property Transforms
202
203
Functions for mapping data to other visual properties like markers and hatch patterns.
204
205
```python { .api }
206
def factor_mark(field_name, markers, factors, start=0, end=None, default='circle'):
207
"""
208
Categorical marker mapping transformation.
209
210
Maps categorical data values to different marker shapes.
211
212
Parameters:
213
- field_name: Name of data source column
214
- markers: List of marker names ('circle', 'square', 'triangle', etc.)
215
- factors: List of categorical values to map
216
- start: Starting index in markers list
217
- end: Ending index in markers list
218
- default: Default marker for unmapped values
219
220
Returns:
221
Transform: Categorical marker mapper transform
222
"""
223
224
def factor_hatch(field_name, patterns, factors, start=0, end=None, default=' '):
225
"""
226
Categorical hatch pattern mapping transformation.
227
228
Maps categorical data values to different fill patterns.
229
230
Parameters:
231
- field_name: Name of data source column
232
- patterns: List of hatch patterns (' ', '/', '\\', '|', '-', '+', 'x', 'o', 'O', '.', '*')
233
- factors: List of categorical values to map
234
- start: Starting index in patterns list
235
- end: Ending index in patterns list
236
- default: Default pattern for unmapped values
237
238
Returns:
239
Transform: Categorical hatch mapper transform
240
"""
241
```
242
243
### Data Positioning Transforms
244
245
Functions for transforming data positions, particularly useful for categorical data and bar charts.
246
247
```python { .api }
248
def dodge(field_name, value, range=None):
249
"""
250
Dodge transformation for categorical data.
251
252
Shifts positions to avoid overlapping in grouped categorical plots.
253
254
Parameters:
255
- field_name: Name of data source column containing categories
256
- value: Amount to dodge (shift) positions
257
- range: FactorRange to use for dodging (auto-detected if None)
258
259
Returns:
260
Transform: Dodge transform for position adjustment
261
"""
262
263
def jitter(field_name, width, range=None, mean=0.0, distribution='uniform'):
264
"""
265
Jitter transformation for position randomization.
266
267
Adds random noise to positions to separate overlapping points.
268
269
Parameters:
270
- field_name: Name of data source column
271
- width: Maximum jitter amount
272
- range: Range object for scaling jitter
273
- mean: Mean of jitter distribution
274
- distribution: 'uniform' or 'normal'
275
276
Returns:
277
Transform: Jitter transform for position randomization
278
"""
279
```
280
281
### Data Value Transforms
282
283
Functions for transforming data values, particularly useful for stacked charts and cumulative displays.
284
285
```python { .api }
286
def stack(*fields):
287
"""
288
Stack transformation for creating stacked bar/area charts.
289
290
Computes cumulative positions for stacking data series on top of each other.
291
292
Parameters:
293
- fields: Names of data source columns to stack
294
295
Returns:
296
Tuple[List[Transform], List[Transform]]: (start_transforms, end_transforms)
297
Each list contains transforms for computing stack start and end positions.
298
299
Usage:
300
start, end = stack('series1', 'series2', 'series3')
301
# Use start[0], end[0] for bottom series
302
# Use start[1], end[1] for middle series
303
# Use start[2], end[2] for top series
304
"""
305
306
def cumsum(field_name, include_zero=False):
307
"""
308
Cumulative sum transformation.
309
310
Computes running cumulative sum of data values.
311
312
Parameters:
313
- field_name: Name of data source column
314
- include_zero: Whether to include zero as first value
315
316
Returns:
317
Transform: Cumulative sum transform
318
"""
319
```
320
321
### General Transform Function
322
323
Generic transformation function for custom transformations.
324
325
```python { .api }
326
def transform(field_name, transform_obj):
327
"""
328
General transformation function.
329
330
Applies a transform object to a data source field.
331
332
Parameters:
333
- field_name: Name of data source column
334
- transform_obj: Transform object (e.g., from bokeh.models.transforms)
335
336
Returns:
337
Transform: The specified transform applied to the field
338
"""
339
```
340
341
## Usage Examples
342
343
### Color Mapping for Continuous Data
344
345
```python
346
from bokeh.plotting import figure, show
347
from bokeh.transform import linear_cmap
348
from bokeh.palettes import Viridis256
349
from bokeh.models import ColumnDataSource, ColorBar
350
import numpy as np
351
352
# Generate data
353
n = 500
354
x = np.random.random(n)
355
y = np.random.random(n)
356
colors = x + y # Color based on sum
357
358
source = ColumnDataSource(data=dict(x=x, y=y, colors=colors))
359
360
# Create color mapping
361
color_mapper = linear_cmap(field_name='colors', palette=Viridis256,
362
low=min(colors), high=max(colors))
363
364
p = figure(width=500, height=500, title="Linear Color Mapping")
365
scatter = p.circle(x='x', y='y', size=12, color=color_mapper, source=source)
366
367
# Add color bar
368
color_bar = ColorBar(color_mapper=color_mapper['transform'], width=8,
369
location=(0,0), title="Color Scale")
370
p.add_layout(color_bar, 'right')
371
372
show(p)
373
```
374
375
### Categorical Color Mapping
376
377
```python
378
from bokeh.plotting import figure, show
379
from bokeh.transform import factor_cmap
380
from bokeh.palettes import Category10
381
from bokeh.models import ColumnDataSource
382
383
# Sample data
384
categories = ['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B']
385
values = [1, 2, 3, 2, 1, 4, 3, 2]
386
x_pos = list(range(len(categories)))
387
388
source = ColumnDataSource(data=dict(x=x_pos, top=values, cat=categories))
389
390
# Create categorical color mapping
391
color_map = factor_cmap('cat', palette=Category10[3], factors=['A', 'B', 'C'])
392
393
p = figure(x_range=(-0.5, 7.5), height=400, title="Categorical Colors")
394
p.vbar(x='x', top='top', width=0.8, color=color_map, source=source)
395
396
show(p)
397
```
398
399
### Stacked Bar Chart
400
401
```python
402
from bokeh.plotting import figure, show
403
from bokeh.transform import stack
404
from bokeh.models import ColumnDataSource
405
from bokeh.palettes import RdYlBu3
406
407
# Data for stacked bars
408
fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
409
years = ['2015', '2016', '2017']
410
411
data = {
412
'fruits': fruits,
413
'2015': [2, 1, 4, 3, 2, 4],
414
'2016': [5, 3, 4, 2, 4, 6],
415
'2017': [3, 2, 4, 4, 5, 3]
416
}
417
418
source = ColumnDataSource(data=data)
419
420
# Create stack transforms
421
stack_transforms = stack('2015', '2016', '2017')
422
423
p = figure(x_range=fruits, height=400, title="Fruit Sales by Year")
424
425
# Create stacked bars
426
p.vbar_stack(years, x='fruits', width=0.9, color=RdYlBu3, source=source,
427
legend_label=years)
428
429
p.y_range.start = 0
430
p.legend.location = "top_left"
431
p.legend.orientation = "horizontal"
432
433
show(p)
434
```
435
436
### Dodge Transform for Grouped Bars
437
438
```python
439
from bokeh.plotting import figure, show
440
from bokeh.transform import dodge
441
from bokeh.models import ColumnDataSource
442
from bokeh.palettes import Category20c
443
444
# Data for grouped bars
445
quarters = ['Q1', 'Q2', 'Q3', 'Q4']
446
products = ['Product A', 'Product B', 'Product C']
447
448
data = {
449
'quarters': quarters,
450
'Product A': [10, 12, 16, 9],
451
'Product B': [8, 15, 12, 11],
452
'Product C': [12, 8, 14, 13]
453
}
454
455
source = ColumnDataSource(data=data)
456
457
p = figure(x_range=quarters, height=400, title="Quarterly Sales by Product")
458
459
# Create grouped bars using dodge
460
p.vbar(x=dodge('quarters', -0.25, range=p.x_range), top='Product A',
461
width=0.2, source=source, color=Category20c[6][0], legend_label="Product A")
462
463
p.vbar(x=dodge('quarters', 0.0, range=p.x_range), top='Product B',
464
width=0.2, source=source, color=Category20c[6][1], legend_label="Product B")
465
466
p.vbar(x=dodge('quarters', 0.25, range=p.x_range), top='Product C',
467
width=0.2, source=source, color=Category20c[6][2], legend_label="Product C")
468
469
p.legend.location = "top_left"
470
show(p)
471
```
472
473
### Jitter for Overlapping Points
474
475
```python
476
from bokeh.plotting import figure, show
477
from bokeh.transform import jitter
478
from bokeh.models import ColumnDataSource
479
import numpy as np
480
481
# Create data with overlapping points
482
categories = ['A'] * 50 + ['B'] * 50 + ['C'] * 50
483
values = np.concatenate([
484
np.random.normal(2, 0.5, 50), # Group A around 2
485
np.random.normal(5, 0.7, 50), # Group B around 5
486
np.random.normal(8, 0.4, 50) # Group C around 8
487
])
488
489
source = ColumnDataSource(data=dict(cat=categories, val=values))
490
491
p = figure(x_range=['A', 'B', 'C'], height=400, title="Jittered Points")
492
493
# Add jitter to x-positions to separate overlapping points
494
p.circle(x=jitter('cat', width=0.6, range=p.x_range), y='val',
495
source=source, alpha=0.6, size=8)
496
497
show(p)
498
```
499
500
### Custom RGB Colors
501
502
```python
503
from bokeh.plotting import figure, show
504
from bokeh.colors import RGB
505
import numpy as np
506
507
# Create custom RGB colors
508
n = 100
509
x = np.random.random(n)
510
y = np.random.random(n)
511
512
# Generate colors programmatically
513
colors = []
514
for i in range(n):
515
r = int(255 * x[i]) # Red based on x
516
g = int(255 * y[i]) # Green based on y
517
b = int(255 * (1-x[i])) # Blue inverse of x
518
colors.append(RGB(r, g, b))
519
520
p = figure(width=500, height=500, title="Custom RGB Colors")
521
p.circle(x, y, size=15, color=colors, alpha=0.8)
522
523
show(p)
524
```