Interactive plots and applications in the browser from Python
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
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.
Classes for representing and manipulating colors in different color spaces.
class Color:
"""
Base color class.
Provides common interface for all color representations.
"""
def to_hex(self):
"""Convert to hexadecimal color string."""
def to_rgb(self):
"""Convert to RGB color object."""
def to_hsl(self):
"""Convert to HSL color object."""
class RGB(Color):
"""
RGB color representation.
Parameters:
- r: Red component (0-255)
- g: Green component (0-255)
- b: Blue component (0-255)
- a: Alpha/transparency (0.0-1.0, default: 1.0)
"""
def __init__(self, r, g, b, a=1.0): ...
r: int
g: int
b: int
a: float
class HSL(Color):
"""
HSL color representation.
Parameters:
- h: Hue (0-360 degrees)
- s: Saturation (0.0-1.0)
- l: Lightness (0.0-1.0)
- a: Alpha/transparency (0.0-1.0, default: 1.0)
"""
def __init__(self, h, s, l, a=1.0): ...
h: float
s: float
l: float
a: float
# Type hint for color-like objects
ColorLike = Union[str, RGB, HSL, Color]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.
# Categorical palettes (for discrete data)
Category10: Dict[int, List[str]] # Dictionary mapping sizes (3-10) to color lists
Category20: Dict[int, List[str]] # Dictionary mapping sizes (3-20) to color lists
Category20b: Dict[int, List[str]] # Alternative 20-color palette dictionary
Category20c: Dict[int, List[str]] # Alternative 20-color palette dictionary
Bokeh8: List[str] # 8 Bokeh brand colors
# Sequential palettes (for continuous data, low to high)
# Available in sizes 3-9 (e.g., Blues3, Blues4, ..., Blues9)
Blues3: List[str] # Light to dark blue (3 colors)
Blues9: List[str] # Light to dark blue (9 colors)
BuGn3: List[str] # Blue to green
BuPu3: List[str] # Blue to purple
GnBu3: List[str] # Green to blue
Greens3: List[str] # Light to dark green
Greys3: List[str] # Light to dark grey
Oranges3: List[str] # Light to dark orange
OrRd3: List[str] # Orange to red
PuBu3: List[str] # Purple to blue
PuBuGn3: List[str] # Purple to blue to green
PuRd3: List[str] # Purple to red
Purples3: List[str] # Light to dark purple
RdPu3: List[str] # Red to purple
Reds3: List[str] # Light to dark red
YlGn3: List[str] # Yellow to green
YlGnBu3: List[str] # Yellow to green to blue
YlOrBr3: List[str] # Yellow to orange to brown
YlOrRd3: List[str] # Yellow to orange to red
# Diverging palettes (for data with meaningful center point)
BrBG3: List[str] # Brown to blue-green
PiYG3: List[str] # Pink to yellow-green
PRGn3: List[str] # Purple to green
PuOr3: List[str] # Purple to orange
RdBu3: List[str] # Red to blue
RdGy3: List[str] # Red to grey
RdYlBu3: List[str] # Red to yellow to blue
RdYlGn3: List[str] # Red to yellow to green
Spectral3: List[str] # Spectral colors
# Matplotlib-inspired palettes (256 colors each)
Viridis256: List[str] # Perceptually uniform, colorblind-friendly
Plasma256: List[str] # Purple to pink to yellow
Inferno256: List[str] # Black to red to yellow
Magma256: List[str] # Black to purple to white
Cividis256: List[str] # Blue to yellow, colorblind-friendly
# High-resolution palettes
Turbo256: List[str] # Rainbow-like, improved over jetFunctions that create color mapping transformations based on data values.
def linear_cmap(field_name, palette, low, high, low_color=None, high_color=None,
nan_color='gray'):
"""
Linear color mapping transformation.
Maps numeric data values to colors using linear interpolation.
Parameters:
- field_name: Name of data source column
- palette: List of colors for interpolation
- low: Minimum data value for mapping
- high: Maximum data value for mapping
- low_color: Color for values below 'low' (default: first palette color)
- high_color: Color for values above 'high' (default: last palette color)
- nan_color: Color for NaN values
Returns:
Transform: Linear color mapper transform
"""
def log_cmap(field_name, palette, low, high, low_color=None, high_color=None,
nan_color='gray'):
"""
Logarithmic color mapping transformation.
Maps numeric data values to colors using logarithmic scaling.
Parameters:
- field_name: Name of data source column
- palette: List of colors for interpolation
- low: Minimum data value for mapping (must be > 0)
- high: Maximum data value for mapping
- low_color: Color for values below 'low'
- high_color: Color for values above 'high'
- nan_color: Color for NaN values
Returns:
Transform: Logarithmic color mapper transform
"""
def factor_cmap(field_name, palette, factors, start=0, end=None, nan_color='gray'):
"""
Categorical color mapping transformation.
Maps categorical data values to colors from a palette.
Parameters:
- field_name: Name of data source column
- palette: List of colors (cycled if fewer than factors)
- factors: List of categorical values to map
- start: Starting index in palette
- end: Ending index in palette (None = use all)
- nan_color: Color for values not in factors
Returns:
Transform: Categorical color mapper transform
"""
def eqhist_cmap(field_name, palette, bins=256, rescale_discrete_levels=True):
"""
Equal-histogram color mapping transformation.
Maps data values to colors using histogram equalization for uniform
color distribution regardless of data distribution.
Parameters:
- field_name: Name of data source column
- palette: List of colors for mapping
- bins: Number of histogram bins
- rescale_discrete_levels: Rescale for discrete data
Returns:
Transform: Equal-histogram color mapper transform
"""Functions for mapping data to other visual properties like markers and hatch patterns.
def factor_mark(field_name, markers, factors, start=0, end=None, default='circle'):
"""
Categorical marker mapping transformation.
Maps categorical data values to different marker shapes.
Parameters:
- field_name: Name of data source column
- markers: List of marker names ('circle', 'square', 'triangle', etc.)
- factors: List of categorical values to map
- start: Starting index in markers list
- end: Ending index in markers list
- default: Default marker for unmapped values
Returns:
Transform: Categorical marker mapper transform
"""
def factor_hatch(field_name, patterns, factors, start=0, end=None, default=' '):
"""
Categorical hatch pattern mapping transformation.
Maps categorical data values to different fill patterns.
Parameters:
- field_name: Name of data source column
- patterns: List of hatch patterns (' ', '/', '\\', '|', '-', '+', 'x', 'o', 'O', '.', '*')
- factors: List of categorical values to map
- start: Starting index in patterns list
- end: Ending index in patterns list
- default: Default pattern for unmapped values
Returns:
Transform: Categorical hatch mapper transform
"""Functions for transforming data positions, particularly useful for categorical data and bar charts.
def dodge(field_name, value, range=None):
"""
Dodge transformation for categorical data.
Shifts positions to avoid overlapping in grouped categorical plots.
Parameters:
- field_name: Name of data source column containing categories
- value: Amount to dodge (shift) positions
- range: FactorRange to use for dodging (auto-detected if None)
Returns:
Transform: Dodge transform for position adjustment
"""
def jitter(field_name, width, range=None, mean=0.0, distribution='uniform'):
"""
Jitter transformation for position randomization.
Adds random noise to positions to separate overlapping points.
Parameters:
- field_name: Name of data source column
- width: Maximum jitter amount
- range: Range object for scaling jitter
- mean: Mean of jitter distribution
- distribution: 'uniform' or 'normal'
Returns:
Transform: Jitter transform for position randomization
"""Functions for transforming data values, particularly useful for stacked charts and cumulative displays.
def stack(*fields):
"""
Stack transformation for creating stacked bar/area charts.
Computes cumulative positions for stacking data series on top of each other.
Parameters:
- fields: Names of data source columns to stack
Returns:
Tuple[List[Transform], List[Transform]]: (start_transforms, end_transforms)
Each list contains transforms for computing stack start and end positions.
Usage:
start, end = stack('series1', 'series2', 'series3')
# Use start[0], end[0] for bottom series
# Use start[1], end[1] for middle series
# Use start[2], end[2] for top series
"""
def cumsum(field_name, include_zero=False):
"""
Cumulative sum transformation.
Computes running cumulative sum of data values.
Parameters:
- field_name: Name of data source column
- include_zero: Whether to include zero as first value
Returns:
Transform: Cumulative sum transform
"""Generic transformation function for custom transformations.
def transform(field_name, transform_obj):
"""
General transformation function.
Applies a transform object to a data source field.
Parameters:
- field_name: Name of data source column
- transform_obj: Transform object (e.g., from bokeh.models.transforms)
Returns:
Transform: The specified transform applied to the field
"""from bokeh.plotting import figure, show
from bokeh.transform import linear_cmap
from bokeh.palettes import Viridis256
from bokeh.models import ColumnDataSource, ColorBar
import numpy as np
# Generate data
n = 500
x = np.random.random(n)
y = np.random.random(n)
colors = x + y # Color based on sum
source = ColumnDataSource(data=dict(x=x, y=y, colors=colors))
# Create color mapping
color_mapper = linear_cmap(field_name='colors', palette=Viridis256,
low=min(colors), high=max(colors))
p = figure(width=500, height=500, title="Linear Color Mapping")
scatter = p.circle(x='x', y='y', size=12, color=color_mapper, source=source)
# Add color bar
color_bar = ColorBar(color_mapper=color_mapper['transform'], width=8,
location=(0,0), title="Color Scale")
p.add_layout(color_bar, 'right')
show(p)from bokeh.plotting import figure, show
from bokeh.transform import factor_cmap
from bokeh.palettes import Category10
from bokeh.models import ColumnDataSource
# Sample data
categories = ['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B']
values = [1, 2, 3, 2, 1, 4, 3, 2]
x_pos = list(range(len(categories)))
source = ColumnDataSource(data=dict(x=x_pos, top=values, cat=categories))
# Create categorical color mapping
color_map = factor_cmap('cat', palette=Category10[3], factors=['A', 'B', 'C'])
p = figure(x_range=(-0.5, 7.5), height=400, title="Categorical Colors")
p.vbar(x='x', top='top', width=0.8, color=color_map, source=source)
show(p)from bokeh.plotting import figure, show
from bokeh.transform import stack
from bokeh.models import ColumnDataSource
from bokeh.palettes import RdYlBu3
# Data for stacked bars
fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
years = ['2015', '2016', '2017']
data = {
'fruits': fruits,
'2015': [2, 1, 4, 3, 2, 4],
'2016': [5, 3, 4, 2, 4, 6],
'2017': [3, 2, 4, 4, 5, 3]
}
source = ColumnDataSource(data=data)
# Create stack transforms
stack_transforms = stack('2015', '2016', '2017')
p = figure(x_range=fruits, height=400, title="Fruit Sales by Year")
# Create stacked bars
p.vbar_stack(years, x='fruits', width=0.9, color=RdYlBu3, source=source,
legend_label=years)
p.y_range.start = 0
p.legend.location = "top_left"
p.legend.orientation = "horizontal"
show(p)from bokeh.plotting import figure, show
from bokeh.transform import dodge
from bokeh.models import ColumnDataSource
from bokeh.palettes import Category20c
# Data for grouped bars
quarters = ['Q1', 'Q2', 'Q3', 'Q4']
products = ['Product A', 'Product B', 'Product C']
data = {
'quarters': quarters,
'Product A': [10, 12, 16, 9],
'Product B': [8, 15, 12, 11],
'Product C': [12, 8, 14, 13]
}
source = ColumnDataSource(data=data)
p = figure(x_range=quarters, height=400, title="Quarterly Sales by Product")
# Create grouped bars using dodge
p.vbar(x=dodge('quarters', -0.25, range=p.x_range), top='Product A',
width=0.2, source=source, color=Category20c[6][0], legend_label="Product A")
p.vbar(x=dodge('quarters', 0.0, range=p.x_range), top='Product B',
width=0.2, source=source, color=Category20c[6][1], legend_label="Product B")
p.vbar(x=dodge('quarters', 0.25, range=p.x_range), top='Product C',
width=0.2, source=source, color=Category20c[6][2], legend_label="Product C")
p.legend.location = "top_left"
show(p)from bokeh.plotting import figure, show
from bokeh.transform import jitter
from bokeh.models import ColumnDataSource
import numpy as np
# Create data with overlapping points
categories = ['A'] * 50 + ['B'] * 50 + ['C'] * 50
values = np.concatenate([
np.random.normal(2, 0.5, 50), # Group A around 2
np.random.normal(5, 0.7, 50), # Group B around 5
np.random.normal(8, 0.4, 50) # Group C around 8
])
source = ColumnDataSource(data=dict(cat=categories, val=values))
p = figure(x_range=['A', 'B', 'C'], height=400, title="Jittered Points")
# Add jitter to x-positions to separate overlapping points
p.circle(x=jitter('cat', width=0.6, range=p.x_range), y='val',
source=source, alpha=0.6, size=8)
show(p)from bokeh.plotting import figure, show
from bokeh.colors import RGB
import numpy as np
# Create custom RGB colors
n = 100
x = np.random.random(n)
y = np.random.random(n)
# Generate colors programmatically
colors = []
for i in range(n):
r = int(255 * x[i]) # Red based on x
g = int(255 * y[i]) # Green based on y
b = int(255 * (1-x[i])) # Blue inverse of x
colors.append(RGB(r, g, b))
p = figure(width=500, height=500, title="Custom RGB Colors")
p.circle(x, y, size=15, color=colors, alpha=0.8)
show(p)