0
# Models and Data Sources
1
2
The low-level building blocks that form the foundation of all Bokeh visualizations. The model system provides 200+ classes for glyphs, tools, widgets, layouts, data sources, and rendering components. These models enable fine-grained control and customization beyond what the high-level plotting interface provides.
3
4
## Capabilities
5
6
### Core Model System
7
8
Base classes and fundamental model infrastructure that all Bokeh objects inherit from.
9
10
```python { .api }
11
class Model:
12
"""
13
Base class for all Bokeh models.
14
15
Provides property system, serialization, and event handling.
16
"""
17
def __init__(self, **kwargs): ...
18
19
# Property access and modification
20
def setattr(self, name, value): ...
21
def getattr(self, name): ...
22
23
# Event handling
24
def on_change(self, attr, *callbacks): ...
25
def trigger(self, attr, old, new): ...
26
27
# Serialization
28
def to_json(self, include_defaults=True): ...
29
def to_json_string(self, include_defaults=True): ...
30
31
# References and relationships
32
def references(self): ...
33
def select(self, selector): ...
34
def select_one(self, selector): ...
35
36
class HasProps(Model):
37
"""Base class with property system."""
38
39
class DocumentCallbackGroup:
40
"""Group for managing document callbacks."""
41
```
42
43
### Data Sources
44
45
Classes for managing and providing data to glyphs and other plot elements.
46
47
```python { .api }
48
class DataSource(Model):
49
"""Base class for data sources."""
50
selected: Selection
51
callback: Optional[Callback]
52
53
class ColumnDataSource(DataSource):
54
"""
55
Primary data source storing data in column format.
56
57
Data is stored as a dictionary mapping column names to lists/arrays.
58
Most commonly used data source in Bokeh.
59
"""
60
def __init__(self, data=None, **kwargs):
61
"""
62
Parameters:
63
- data: Dict mapping column names to sequences
64
"""
65
66
data: Dict[str, Any] # Column data dictionary
67
68
# Data manipulation methods
69
def add(self, data, rollover=None): ...
70
def remove(self, indices): ...
71
def patch(self, patches, rollover=None): ...
72
def stream(self, new_data, rollover=None): ...
73
74
# Conversion methods
75
def to_df(self): ...
76
@classmethod
77
def from_df(cls, df): ...
78
79
class CDSView(Model):
80
"""
81
View into a ColumnDataSource with filtering and indexing.
82
83
Allows different glyphs to show different subsets of the same data source.
84
"""
85
source: ColumnDataSource
86
filters: List[Filter]
87
indices: Optional[List[int]]
88
89
class GeoJSONDataSource(DataSource):
90
"""Data source for GeoJSON data."""
91
geojson: str # GeoJSON string
92
93
class AjaxDataSource(DataSource):
94
"""Data source that loads data from URLs via AJAX."""
95
data_url: str
96
polling_interval: Optional[int]
97
mode: str # 'replace', 'append'
98
method: str # 'POST', 'GET'
99
if_modified: bool
100
101
class WebDataSource(DataSource):
102
"""Base class for web-based data sources."""
103
data_url: str
104
```
105
106
### Selection and Filtering
107
108
Classes for managing data selection and filtering.
109
110
```python { .api }
111
class Selection(Model):
112
"""Represents a selection of data points."""
113
indices: List[int]
114
line_indices: List[int]
115
multiline_indices: Dict[int, List[int]]
116
117
class Filter(Model):
118
"""Base class for data filters."""
119
120
class IndexFilter(Filter):
121
"""Filter based on explicit indices."""
122
indices: List[int]
123
124
class BooleanFilter(Filter):
125
"""Filter based on boolean array."""
126
booleans: List[bool]
127
128
class GroupFilter(Filter):
129
"""Filter based on group membership."""
130
column_name: str
131
group: str
132
133
class CustomJSFilter(Filter):
134
"""JavaScript-based custom filter."""
135
code: str
136
args: Dict[str, Any]
137
```
138
139
### Glyph Models
140
141
Low-level glyph classes that correspond to the high-level plotting methods.
142
143
```python { .api }
144
class Glyph(Model):
145
"""Base class for all glyph models."""
146
visible: bool
147
x_range_name: str
148
y_range_name: str
149
150
# Line glyphs
151
class Line(Glyph):
152
"""Line glyph connecting points."""
153
x: str
154
y: str
155
line_color: str
156
line_width: int
157
line_alpha: float
158
line_join: LineJoin # 'miter', 'round', 'bevel'
159
line_cap: LineCap # 'butt', 'round', 'square'
160
line_dash: List[int]
161
162
class MultiLine(Glyph):
163
"""Multiple disconnected lines."""
164
xs: str
165
ys: str
166
167
class Step(Glyph):
168
"""Step line glyph."""
169
x: str
170
y: str
171
mode: StepMode # 'before', 'after', 'center'
172
173
# Marker glyphs
174
class Marker(Glyph):
175
"""Base class for marker glyphs."""
176
x: str
177
y: str
178
size: str
179
angle: str
180
fill_color: str
181
fill_alpha: float
182
line_color: str
183
line_width: int
184
line_alpha: float
185
186
class Circle(Marker):
187
"""Circle marker glyph."""
188
radius: Optional[str]
189
radius_dimension: RadiusDimension # 'x', 'y', 'max', 'min'
190
191
class Scatter(Marker):
192
"""Scatter marker with configurable shape."""
193
marker: str # Marker type name
194
195
# All specific marker classes
196
class Asterisk(Marker): ...
197
class CircleCross(Marker): ...
198
class CircleDot(Marker): ...
199
class CircleX(Marker): ...
200
class CircleY(Marker): ...
201
class Cross(Marker): ...
202
class Dash(Marker): ...
203
class Diamond(Marker): ...
204
class DiamondCross(Marker): ...
205
class DiamondDot(Marker): ...
206
class Dot(Marker): ...
207
class Hex(Marker): ...
208
class HexDot(Marker): ...
209
class InvertedTriangle(Marker): ...
210
class Plus(Marker): ...
211
class Square(Marker): ...
212
class SquareCross(Marker): ...
213
class SquareDot(Marker): ...
214
class SquarePin(Marker): ...
215
class SquareX(Marker): ...
216
class Star(Marker): ...
217
class StarDot(Marker): ...
218
class Triangle(Marker): ...
219
class TriangleDot(Marker): ...
220
class TrianglePin(Marker): ...
221
class X(Marker): ...
222
class Y(Marker): ...
223
224
# Shape glyphs
225
class Rect(Glyph):
226
"""Rectangular glyph."""
227
x: str
228
y: str
229
width: str
230
height: str
231
angle: str
232
dilate: bool
233
234
class Quad(Glyph):
235
"""Quadrilateral glyph using explicit boundaries."""
236
left: str
237
right: str
238
top: str
239
bottom: str
240
241
class Ellipse(Glyph):
242
"""Elliptical glyph."""
243
x: str
244
y: str
245
width: str
246
height: str
247
angle: str
248
249
class Wedge(Glyph):
250
"""Wedge/pie slice glyph."""
251
x: str
252
y: str
253
radius: str
254
start_angle: str
255
end_angle: str
256
direction: Direction # 'clock', 'anticlock'
257
258
class AnnularWedge(Glyph):
259
"""Annular wedge glyph."""
260
x: str
261
y: str
262
inner_radius: str
263
outer_radius: str
264
start_angle: str
265
end_angle: str
266
direction: Direction
267
268
class Annulus(Glyph):
269
"""Ring/annulus glyph."""
270
x: str
271
y: str
272
inner_radius: str
273
outer_radius: str
274
275
# Area glyphs
276
class VArea(Glyph):
277
"""Vertical area glyph."""
278
x: str
279
y1: str
280
y2: str
281
282
class HArea(Glyph):
283
"""Horizontal area glyph."""
284
y: str
285
x1: str
286
x2: str
287
288
class VBar(Glyph):
289
"""Vertical bar glyph."""
290
x: str
291
top: str
292
width: str
293
bottom: str
294
295
class HBar(Glyph):
296
"""Horizontal bar glyph."""
297
y: str
298
left: str
299
right: str
300
height: str
301
302
# Image glyphs
303
class Image(Glyph):
304
"""2D image glyph."""
305
image: str
306
x: str
307
y: str
308
dw: str
309
dh: str
310
palette: Optional[str]
311
dilate: bool
312
313
class ImageRGBA(Glyph):
314
"""RGBA image glyph."""
315
image: str
316
x: str
317
y: str
318
dw: str
319
dh: str
320
dilate: bool
321
322
class ImageURL(Glyph):
323
"""Image from URL glyph."""
324
url: str
325
x: str
326
y: str
327
w: str
328
h: str
329
angle: str
330
dilate: bool
331
anchor: Anchor # Position anchor point
332
retry_attempts: int
333
retry_timeout: int
334
335
# Patch glyphs
336
class Patch(Glyph):
337
"""Single polygon patch."""
338
x: str
339
y: str
340
341
class Patches(Glyph):
342
"""Multiple polygon patches."""
343
xs: str
344
ys: str
345
346
class MultiPolygons(Glyph):
347
"""Complex polygonal shapes."""
348
xs: str
349
ys: str
350
351
# Text glyphs
352
class Text(Glyph):
353
"""Text glyph."""
354
x: str
355
y: str
356
text: str
357
angle: str
358
x_offset: str
359
y_offset: str
360
text_font: str
361
text_font_size: str
362
text_font_style: FontStyle # 'normal', 'italic', 'bold'
363
text_color: str
364
text_alpha: float
365
text_align: TextAlign # 'left', 'right', 'center'
366
text_baseline: TextBaseline # 'top', 'middle', 'bottom', 'alphabetic', 'hanging'
367
368
class MathMLGlyph(Glyph):
369
"""MathML text glyph."""
370
x: str
371
y: str
372
text: str
373
374
class TeXGlyph(Glyph):
375
"""TeX/LaTeX text glyph."""
376
x: str
377
y: str
378
text: str
379
```
380
381
### Renderer Models
382
383
Classes that manage the rendering of glyphs and other plot elements.
384
385
```python { .api }
386
class Renderer(Model):
387
"""Base class for all renderers."""
388
level: RenderLevel # 'image', 'underlay', 'glyph', 'annotation', 'overlay'
389
visible: bool
390
391
class GlyphRenderer(Renderer):
392
"""Renders glyphs with data."""
393
data_source: DataSource
394
glyph: Glyph
395
nonselection_glyph: Optional[Glyph]
396
selection_glyph: Optional[Glyph]
397
hover_glyph: Optional[Glyph]
398
muted_glyph: Optional[Glyph]
399
view: CDSView
400
muted: bool
401
402
class GraphRenderer(Renderer):
403
"""Renders network graphs."""
404
node_renderer: GlyphRenderer
405
edge_renderer: GlyphRenderer
406
layout_provider: LayoutProvider
407
selection_policy: GraphHitTestPolicy
408
inspection_policy: GraphHitTestPolicy
409
410
class GuideRenderer(Renderer):
411
"""Base class for axis and grid renderers."""
412
413
class ContourRenderer(Renderer):
414
"""Renders contour plots."""
415
levels: Union[int, List[float]]
416
fill_color: str
417
line_color: str
418
```
419
420
### Range Models
421
422
Classes for defining axis ranges and data bounds.
423
424
```python { .api }
425
class Range(Model):
426
"""Base class for ranges."""
427
bounds: Optional[Tuple[float, float]]
428
min_interval: Optional[float]
429
max_interval: Optional[float]
430
431
class Range1d(Range):
432
"""Explicit numeric range with fixed start and end."""
433
start: float
434
end: float
435
reset_start: Optional[float]
436
reset_end: Optional[float]
437
438
class DataRange1d(Range):
439
"""Automatic numeric range computed from data."""
440
names: List[str] # Data source column names
441
renderers: List[Renderer]
442
only_visible: bool
443
follow: Optional[StartEnd] # 'start', 'end'
444
follow_interval: Optional[float]
445
default_span: float
446
range_padding: float
447
range_padding_units: PaddingUnits # 'percent', 'absolute'
448
flipped: bool
449
450
class FactorRange(Range):
451
"""Categorical range for string/factor data."""
452
factors: List[Union[str, Tuple[str, ...]]] # Hierarchical factors supported
453
range_padding: float
454
range_padding_units: PaddingUnits
455
group_padding: float
456
subgroup_padding: float
457
```
458
459
### Scale Models
460
461
Classes for mapping between data space and screen space.
462
463
```python { .api }
464
class Scale(Model):
465
"""Base class for scales."""
466
source_range: Range
467
target_range: Range
468
469
class LinearScale(Scale):
470
"""Linear scaling transformation."""
471
472
class LogScale(Scale):
473
"""Logarithmic scaling transformation."""
474
base: float # Default: 10
475
476
class CategoricalScale(Scale):
477
"""Scale for categorical/factor data."""
478
```
479
480
## Usage Examples
481
482
### Custom Data Source with Filtering
483
484
```python
485
from bokeh.models import ColumnDataSource, CDSView, IndexFilter
486
from bokeh.plotting import figure, show
487
import numpy as np
488
489
# Create data
490
n = 1000
491
x = np.random.random(n)
492
y = np.random.random(n)
493
colors = np.random.choice(['red', 'green', 'blue'], n)
494
495
# Create data source
496
source = ColumnDataSource(data=dict(x=x, y=y, colors=colors))
497
498
# Create filtered view (show only first 500 points)
499
view = CDSView(source=source, filters=[IndexFilter(indices=list(range(500)))])
500
501
p = figure(width=400, height=400)
502
503
# Use the filtered view
504
p.circle(x='x', y='y', color='colors', source=source, view=view, size=8)
505
506
show(p)
507
```
508
509
### Custom Glyph with Multiple Visual States
510
511
```python
512
from bokeh.models import Circle, ColumnDataSource, GlyphRenderer
513
from bokeh.plotting import figure, show
514
from bokeh.palettes import Category10
515
import numpy as np
516
517
# Data
518
n = 300
519
x = np.random.random(n)
520
y = np.random.random(n)
521
source = ColumnDataSource(data=dict(x=x, y=y))
522
523
# Create custom glyph renderers with different visual states
524
glyph = Circle(x='x', y='y', size=15, fill_color='blue', line_color='black')
525
selection_glyph = Circle(x='x', y='y', size=20, fill_color='red', line_color='black')
526
nonselection_glyph = Circle(x='x', y='y', size=10, fill_color='gray', fill_alpha=0.3)
527
528
p = figure(width=400, height=400, tools="box_select,reset")
529
530
# Add renderer with custom visual states
531
renderer = p.add_glyph(source, glyph,
532
selection_glyph=selection_glyph,
533
nonselection_glyph=nonselection_glyph)
534
535
show(p)
536
```
537
538
### Dynamic Data Updates
539
540
```python
541
from bokeh.models import ColumnDataSource
542
from bokeh.plotting import figure, curdoc
543
import numpy as np
544
545
# Initial data
546
source = ColumnDataSource(data=dict(x=[1, 2, 3], y=[1, 4, 2]))
547
548
p = figure(width=400, height=400)
549
p.line(x='x', y='y', source=source, line_width=2)
550
551
def update_data():
552
"""Callback to update data source."""
553
new_data = dict(
554
x=np.random.random(10),
555
y=np.random.random(10)
556
)
557
source.data = new_data
558
559
# Add periodic callback for live updates
560
curdoc().add_periodic_callback(update_data, 1000) # Update every 1000ms
561
```