Interactive plots and applications in the browser from Python
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
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.
Base classes and fundamental model infrastructure that all Bokeh objects inherit from.
class Model:
"""
Base class for all Bokeh models.
Provides property system, serialization, and event handling.
"""
def __init__(self, **kwargs): ...
# Property access and modification
def setattr(self, name, value): ...
def getattr(self, name): ...
# Event handling
def on_change(self, attr, *callbacks): ...
def trigger(self, attr, old, new): ...
# Serialization
def to_json(self, include_defaults=True): ...
def to_json_string(self, include_defaults=True): ...
# References and relationships
def references(self): ...
def select(self, selector): ...
def select_one(self, selector): ...
class HasProps(Model):
"""Base class with property system."""
class DocumentCallbackGroup:
"""Group for managing document callbacks."""Classes for managing and providing data to glyphs and other plot elements.
class DataSource(Model):
"""Base class for data sources."""
selected: Selection
callback: Optional[Callback]
class ColumnDataSource(DataSource):
"""
Primary data source storing data in column format.
Data is stored as a dictionary mapping column names to lists/arrays.
Most commonly used data source in Bokeh.
"""
def __init__(self, data=None, **kwargs):
"""
Parameters:
- data: Dict mapping column names to sequences
"""
data: Dict[str, Any] # Column data dictionary
# Data manipulation methods
def add(self, data, rollover=None): ...
def remove(self, indices): ...
def patch(self, patches, rollover=None): ...
def stream(self, new_data, rollover=None): ...
# Conversion methods
def to_df(self): ...
@classmethod
def from_df(cls, df): ...
class CDSView(Model):
"""
View into a ColumnDataSource with filtering and indexing.
Allows different glyphs to show different subsets of the same data source.
"""
source: ColumnDataSource
filters: List[Filter]
indices: Optional[List[int]]
class GeoJSONDataSource(DataSource):
"""Data source for GeoJSON data."""
geojson: str # GeoJSON string
class AjaxDataSource(DataSource):
"""Data source that loads data from URLs via AJAX."""
data_url: str
polling_interval: Optional[int]
mode: str # 'replace', 'append'
method: str # 'POST', 'GET'
if_modified: bool
class WebDataSource(DataSource):
"""Base class for web-based data sources."""
data_url: strClasses for managing data selection and filtering.
class Selection(Model):
"""Represents a selection of data points."""
indices: List[int]
line_indices: List[int]
multiline_indices: Dict[int, List[int]]
class Filter(Model):
"""Base class for data filters."""
class IndexFilter(Filter):
"""Filter based on explicit indices."""
indices: List[int]
class BooleanFilter(Filter):
"""Filter based on boolean array."""
booleans: List[bool]
class GroupFilter(Filter):
"""Filter based on group membership."""
column_name: str
group: str
class CustomJSFilter(Filter):
"""JavaScript-based custom filter."""
code: str
args: Dict[str, Any]Low-level glyph classes that correspond to the high-level plotting methods.
class Glyph(Model):
"""Base class for all glyph models."""
visible: bool
x_range_name: str
y_range_name: str
# Line glyphs
class Line(Glyph):
"""Line glyph connecting points."""
x: str
y: str
line_color: str
line_width: int
line_alpha: float
line_join: LineJoin # 'miter', 'round', 'bevel'
line_cap: LineCap # 'butt', 'round', 'square'
line_dash: List[int]
class MultiLine(Glyph):
"""Multiple disconnected lines."""
xs: str
ys: str
class Step(Glyph):
"""Step line glyph."""
x: str
y: str
mode: StepMode # 'before', 'after', 'center'
# Marker glyphs
class Marker(Glyph):
"""Base class for marker glyphs."""
x: str
y: str
size: str
angle: str
fill_color: str
fill_alpha: float
line_color: str
line_width: int
line_alpha: float
class Circle(Marker):
"""Circle marker glyph."""
radius: Optional[str]
radius_dimension: RadiusDimension # 'x', 'y', 'max', 'min'
class Scatter(Marker):
"""Scatter marker with configurable shape."""
marker: str # Marker type name
# All specific marker classes
class Asterisk(Marker): ...
class CircleCross(Marker): ...
class CircleDot(Marker): ...
class CircleX(Marker): ...
class CircleY(Marker): ...
class Cross(Marker): ...
class Dash(Marker): ...
class Diamond(Marker): ...
class DiamondCross(Marker): ...
class DiamondDot(Marker): ...
class Dot(Marker): ...
class Hex(Marker): ...
class HexDot(Marker): ...
class InvertedTriangle(Marker): ...
class Plus(Marker): ...
class Square(Marker): ...
class SquareCross(Marker): ...
class SquareDot(Marker): ...
class SquarePin(Marker): ...
class SquareX(Marker): ...
class Star(Marker): ...
class StarDot(Marker): ...
class Triangle(Marker): ...
class TriangleDot(Marker): ...
class TrianglePin(Marker): ...
class X(Marker): ...
class Y(Marker): ...
# Shape glyphs
class Rect(Glyph):
"""Rectangular glyph."""
x: str
y: str
width: str
height: str
angle: str
dilate: bool
class Quad(Glyph):
"""Quadrilateral glyph using explicit boundaries."""
left: str
right: str
top: str
bottom: str
class Ellipse(Glyph):
"""Elliptical glyph."""
x: str
y: str
width: str
height: str
angle: str
class Wedge(Glyph):
"""Wedge/pie slice glyph."""
x: str
y: str
radius: str
start_angle: str
end_angle: str
direction: Direction # 'clock', 'anticlock'
class AnnularWedge(Glyph):
"""Annular wedge glyph."""
x: str
y: str
inner_radius: str
outer_radius: str
start_angle: str
end_angle: str
direction: Direction
class Annulus(Glyph):
"""Ring/annulus glyph."""
x: str
y: str
inner_radius: str
outer_radius: str
# Area glyphs
class VArea(Glyph):
"""Vertical area glyph."""
x: str
y1: str
y2: str
class HArea(Glyph):
"""Horizontal area glyph."""
y: str
x1: str
x2: str
class VBar(Glyph):
"""Vertical bar glyph."""
x: str
top: str
width: str
bottom: str
class HBar(Glyph):
"""Horizontal bar glyph."""
y: str
left: str
right: str
height: str
# Image glyphs
class Image(Glyph):
"""2D image glyph."""
image: str
x: str
y: str
dw: str
dh: str
palette: Optional[str]
dilate: bool
class ImageRGBA(Glyph):
"""RGBA image glyph."""
image: str
x: str
y: str
dw: str
dh: str
dilate: bool
class ImageURL(Glyph):
"""Image from URL glyph."""
url: str
x: str
y: str
w: str
h: str
angle: str
dilate: bool
anchor: Anchor # Position anchor point
retry_attempts: int
retry_timeout: int
# Patch glyphs
class Patch(Glyph):
"""Single polygon patch."""
x: str
y: str
class Patches(Glyph):
"""Multiple polygon patches."""
xs: str
ys: str
class MultiPolygons(Glyph):
"""Complex polygonal shapes."""
xs: str
ys: str
# Text glyphs
class Text(Glyph):
"""Text glyph."""
x: str
y: str
text: str
angle: str
x_offset: str
y_offset: str
text_font: str
text_font_size: str
text_font_style: FontStyle # 'normal', 'italic', 'bold'
text_color: str
text_alpha: float
text_align: TextAlign # 'left', 'right', 'center'
text_baseline: TextBaseline # 'top', 'middle', 'bottom', 'alphabetic', 'hanging'
class MathMLGlyph(Glyph):
"""MathML text glyph."""
x: str
y: str
text: str
class TeXGlyph(Glyph):
"""TeX/LaTeX text glyph."""
x: str
y: str
text: strClasses that manage the rendering of glyphs and other plot elements.
class Renderer(Model):
"""Base class for all renderers."""
level: RenderLevel # 'image', 'underlay', 'glyph', 'annotation', 'overlay'
visible: bool
class GlyphRenderer(Renderer):
"""Renders glyphs with data."""
data_source: DataSource
glyph: Glyph
nonselection_glyph: Optional[Glyph]
selection_glyph: Optional[Glyph]
hover_glyph: Optional[Glyph]
muted_glyph: Optional[Glyph]
view: CDSView
muted: bool
class GraphRenderer(Renderer):
"""Renders network graphs."""
node_renderer: GlyphRenderer
edge_renderer: GlyphRenderer
layout_provider: LayoutProvider
selection_policy: GraphHitTestPolicy
inspection_policy: GraphHitTestPolicy
class GuideRenderer(Renderer):
"""Base class for axis and grid renderers."""
class ContourRenderer(Renderer):
"""Renders contour plots."""
levels: Union[int, List[float]]
fill_color: str
line_color: strClasses for defining axis ranges and data bounds.
class Range(Model):
"""Base class for ranges."""
bounds: Optional[Tuple[float, float]]
min_interval: Optional[float]
max_interval: Optional[float]
class Range1d(Range):
"""Explicit numeric range with fixed start and end."""
start: float
end: float
reset_start: Optional[float]
reset_end: Optional[float]
class DataRange1d(Range):
"""Automatic numeric range computed from data."""
names: List[str] # Data source column names
renderers: List[Renderer]
only_visible: bool
follow: Optional[StartEnd] # 'start', 'end'
follow_interval: Optional[float]
default_span: float
range_padding: float
range_padding_units: PaddingUnits # 'percent', 'absolute'
flipped: bool
class FactorRange(Range):
"""Categorical range for string/factor data."""
factors: List[Union[str, Tuple[str, ...]]] # Hierarchical factors supported
range_padding: float
range_padding_units: PaddingUnits
group_padding: float
subgroup_padding: floatClasses for mapping between data space and screen space.
class Scale(Model):
"""Base class for scales."""
source_range: Range
target_range: Range
class LinearScale(Scale):
"""Linear scaling transformation."""
class LogScale(Scale):
"""Logarithmic scaling transformation."""
base: float # Default: 10
class CategoricalScale(Scale):
"""Scale for categorical/factor data."""from bokeh.models import ColumnDataSource, CDSView, IndexFilter
from bokeh.plotting import figure, show
import numpy as np
# Create data
n = 1000
x = np.random.random(n)
y = np.random.random(n)
colors = np.random.choice(['red', 'green', 'blue'], n)
# Create data source
source = ColumnDataSource(data=dict(x=x, y=y, colors=colors))
# Create filtered view (show only first 500 points)
view = CDSView(source=source, filters=[IndexFilter(indices=list(range(500)))])
p = figure(width=400, height=400)
# Use the filtered view
p.circle(x='x', y='y', color='colors', source=source, view=view, size=8)
show(p)from bokeh.models import Circle, ColumnDataSource, GlyphRenderer
from bokeh.plotting import figure, show
from bokeh.palettes import Category10
import numpy as np
# Data
n = 300
x = np.random.random(n)
y = np.random.random(n)
source = ColumnDataSource(data=dict(x=x, y=y))
# Create custom glyph renderers with different visual states
glyph = Circle(x='x', y='y', size=15, fill_color='blue', line_color='black')
selection_glyph = Circle(x='x', y='y', size=20, fill_color='red', line_color='black')
nonselection_glyph = Circle(x='x', y='y', size=10, fill_color='gray', fill_alpha=0.3)
p = figure(width=400, height=400, tools="box_select,reset")
# Add renderer with custom visual states
renderer = p.add_glyph(source, glyph,
selection_glyph=selection_glyph,
nonselection_glyph=nonselection_glyph)
show(p)from bokeh.models import ColumnDataSource
from bokeh.plotting import figure, curdoc
import numpy as np
# Initial data
source = ColumnDataSource(data=dict(x=[1, 2, 3], y=[1, 4, 2]))
p = figure(width=400, height=400)
p.line(x='x', y='y', source=source, line_width=2)
def update_data():
"""Callback to update data source."""
new_data = dict(
x=np.random.random(10),
y=np.random.random(10)
)
source.data = new_data
# Add periodic callback for live updates
curdoc().add_periodic_callback(update_data, 1000) # Update every 1000ms