CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-bokeh

Interactive plots and applications in the browser from Python

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

layouts.mddocs/

Layouts

Functions and classes for arranging multiple plots, widgets, and other components into complex layouts. The layout system enables creation of dashboards, multi-panel displays, and sophisticated interactive applications with precise control over component positioning and sizing.

Capabilities

Basic Layout Functions

Core functions for arranging components horizontally and vertically.

def row(*children, **kwargs):
    """
    Arrange plots/widgets horizontally in a row.
    
    Parameters:
    - children: Plot objects, widgets, or other layoutable components
    - sizing_mode: 'fixed', 'stretch_width', 'stretch_height', 'stretch_both', 'scale_width', 'scale_height', 'scale_both'
    - width: Total width in pixels (when sizing_mode='fixed')
    - height: Total height in pixels (when sizing_mode='fixed')
    - margin: Margin around the layout (int or tuple)
    - spacing: Spacing between children in pixels
    - css_classes: List of CSS class names
    - name: Optional name for the layout
    - tags: List of arbitrary values for user annotation
    
    Returns:
    Row: Layout object containing the arranged components
    """

def column(*children, **kwargs):
    """
    Arrange plots/widgets vertically in a column.
    
    Parameters:
    - children: Plot objects, widgets, or other layoutable components
    - sizing_mode: Layout sizing behavior
    - width: Total width in pixels
    - height: Total height in pixels
    - margin: Margin around the layout
    - spacing: Spacing between children in pixels
    - css_classes: List of CSS class names
    - name: Optional name for the layout
    - tags: List of arbitrary values
    
    Returns:
    Column: Layout object containing the arranged components
    """

Grid Layouts

Functions for creating grid-based arrangements of plots and components.

def gridplot(children, sizing_mode='fixed', toolbar_location='above',
             ncols=None, plot_width=None, plot_height=None,
             toolbar_options=None, merge_tools=True, **kwargs):
    """
    Create grid of plots with optional shared tools.
    
    Parameters:
    - children: 2D list/array of plot objects (None for empty cells)
    - sizing_mode: Layout sizing behavior
    - toolbar_location: 'above', 'below', 'left', 'right', None
    - ncols: Number of columns (if children is 1D list)
    - plot_width: Width for plots without explicit width
    - plot_height: Height for plots without explicit height
    - toolbar_options: Dict of toolbar configuration options
    - merge_tools: Whether to merge plot tools into shared toolbar
    
    Returns:
    GridBox: Grid layout containing the plots
    
    Example children format:
    [[plot1, plot2], [plot3, None]]  # 2x2 grid with empty bottom-right
    """

def grid(children, sizing_mode='fixed', **kwargs):
    """
    Create flexible grid layout without plot-specific features.
    
    Parameters:
    - children: 2D list of any layoutable components
    - sizing_mode: Layout sizing behavior
    
    Returns:
    GridBox: Grid layout containing the components
    """

Advanced Layout Function

Function for creating complex nested layouts.

def layout(children, sizing_mode='fixed', **kwargs):
    """
    Create flexible nested layout from lists and tuples.
    
    Parameters:
    - children: Nested structure of lists/tuples containing components
                Lists create columns, tuples create rows
    - sizing_mode: Layout sizing behavior
    
    Returns:
    LayoutDOM: Appropriate layout object based on structure
    
    Examples:
    layout([plot1, plot2])           # Column of two plots
    layout([[plot1, plot2]])         # Row of two plots  
    layout([plot1, [plot2, plot3]])  # plot1 above horizontal row
    """

Layout Model Classes

Classes for programmatic layout construction and advanced configuration.

class LayoutDOM(Model):
    """Base class for all layout components."""
    width: Optional[int]
    height: Optional[int]
    min_width: Optional[int]
    min_height: Optional[int]
    max_width: Optional[int]
    max_height: Optional[int]
    margin: Margin  # int or (top, right, bottom, left) tuple
    width_policy: SizingPolicy  # 'auto', 'min', 'fit', 'max'
    height_policy: SizingPolicy
    aspect_ratio: Optional[Union[float, str]]  # float or 'auto'
    sizing_mode: SizingMode
    visible: bool
    disabled: bool
    css_classes: List[str]
    name: Optional[str]
    tags: List[Any]

class Row(LayoutDOM):
    """Horizontal arrangement of components."""
    children: List[LayoutDOM]
    spacing: int  # Spacing between children in pixels

class Column(LayoutDOM):
    """Vertical arrangement of components."""  
    children: List[LayoutDOM]
    spacing: int

class GridBox(LayoutDOM):
    """Grid arrangement of components."""
    children: List[Tuple[LayoutDOM, int, int]]  # (component, row, col)
    nrows: int
    ncols: int
    spacing: Union[int, Tuple[int, int]]  # (row_spacing, col_spacing)

class Spacer(LayoutDOM):
    """Empty space component for layouts."""
    # Inherits all sizing properties from LayoutDOM
    # Used to create flexible spacing in layouts

Tabbed Layouts

Classes for creating tabbed interfaces.

class Panel(Model):
    """Individual tab panel."""
    child: LayoutDOM  # Content of the tab
    title: str        # Tab title text
    closable: bool    # Whether tab can be closed

class Tabs(LayoutDOM):
    """Tabbed layout container."""
    tabs: List[Panel]
    active: int       # Index of active tab
    tabs_location: Location  # 'above', 'below', 'left', 'right'
    
    # Callback hooks
    def on_change(self, attr, *callbacks): ...

Usage Examples

Basic Row and Column Layouts

from bokeh.layouts import row, column
from bokeh.plotting import figure, show
import numpy as np

# Create some plots
x = np.linspace(0, 4*np.pi, 100)

p1 = figure(width=300, height=300, title="sin(x)")
p1.line(x, np.sin(x))

p2 = figure(width=300, height=300, title="cos(x)")  
p2.line(x, np.cos(x), color='red')

p3 = figure(width=300, height=300, title="tan(x)")
p3.line(x, np.tan(x), color='green')

# Arrange in row
layout1 = row(p1, p2, p3)

# Arrange in column
layout2 = column(p1, p2, p3)

# Mixed arrangement
layout3 = column(
    row(p1, p2),  # Top row with two plots
    p3            # Bottom plot spanning full width
)

show(layout3)

Grid Layout

from bokeh.layouts import gridplot
from bokeh.plotting import figure, show
import numpy as np

# Create 2x2 grid of plots
plots = []
for i in range(4):
    p = figure(width=250, height=250, title=f"Plot {i+1}")
    x = np.linspace(0, 4*np.pi, 50)
    y = np.sin(x + i*np.pi/4)
    p.line(x, y, line_width=2)
    plots.append(p)

# Arrange in 2x2 grid
grid = gridplot([
    [plots[0], plots[1]], 
    [plots[2], plots[3]]
], sizing_mode='stretch_width')

show(grid)

Flexible Layout with Spacers

from bokeh.layouts import column, row
from bokeh.models import Spacer
from bokeh.plotting import figure, show

p1 = figure(width=200, height=200)
p1.circle([1, 2, 3], [1, 2, 3])

p2 = figure(width=200, height=200)
p2.square([1, 2, 3], [3, 2, 1])

# Create layout with flexible spacing
layout = column(
    p1,
    Spacer(height=50),  # Fixed 50px spacing
    row(
        Spacer(width_policy='max'),  # Flexible left space
        p2,
        Spacer(width_policy='max')   # Flexible right space (centers p2)
    )
)

show(layout)

Tabbed Interface

from bokeh.models import Panel, Tabs
from bokeh.plotting import figure, show
import numpy as np

# Create plots for different tabs
tab1_plot = figure(width=400, height=400, title="Line Plot")
x = np.linspace(0, 4*np.pi, 100)
tab1_plot.line(x, np.sin(x))

tab2_plot = figure(width=400, height=400, title="Scatter Plot")
tab2_plot.scatter(np.random.random(50), np.random.random(50), size=10)

tab3_plot = figure(width=400, height=400, title="Bar Chart")
categories = ['A', 'B', 'C', 'D']
values = [1, 3, 2, 4]
tab3_plot.vbar(x=categories, top=values, width=0.5)

# Create tabs
tab1 = Panel(child=tab1_plot, title="Sine Wave")
tab2 = Panel(child=tab2_plot, title="Random Data")
tab3 = Panel(child=tab3_plot, title="Categories")

tabs = Tabs(tabs=[tab1, tab2, tab3])

show(tabs)

Responsive Dashboard Layout

from bokeh.layouts import column, row
from bokeh.plotting import figure, show
from bokeh.models import Div
import numpy as np

# Create title
title = Div(text="<h1>Sales Dashboard</h1>", 
           sizing_mode='stretch_width')

# Create plots with responsive sizing
p1 = figure(height=300, title="Revenue Trend", 
           sizing_mode='stretch_width')
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
revenue = [100, 120, 140, 110, 160, 180]
p1.line(range(len(months)), revenue, line_width=3)
p1.xaxis.ticker = list(range(len(months)))
p1.xaxis.major_label_overrides = dict(zip(range(len(months)), months))

p2 = figure(width=300, height=300, title="Regional Sales")
regions = ['North', 'South', 'East', 'West']
sales = [45, 30, 35, 25]  
p2.vbar(x=regions, top=sales, width=0.5, color='navy')

p3 = figure(width=300, height=300, title="Customer Satisfaction")
satisfaction = np.random.normal(8.5, 1.2, 1000)
hist, edges = np.histogram(satisfaction, bins=20)
p3.quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:], 
        fill_color='lightblue', line_color='black')

# Create responsive layout
dashboard = column(
    title,
    p1,  # Full width trend chart
    row(p2, p3, sizing_mode='stretch_width'),  # Side-by-side bottom charts
    sizing_mode='stretch_width'
)

show(dashboard)

Programmatic Layout Construction

from bokeh.models import Column, Row, GridBox
from bokeh.plotting import figure, show

# Create plots
plots = []
for i in range(6):
    p = figure(width=200, height=200, title=f"Plot {i+1}")
    p.circle([1, 2, 3], [i, i+1, i+2])
    plots.append(p)

# Programmatically create complex layout
main_row = Row(children=[
    Column(children=plots[0:3], spacing=10),
    Column(children=plots[3:6], spacing=10)
], spacing=20)

# Alternative: Using GridBox for precise control
grid = GridBox(children=[
    (plots[0], 0, 0), (plots[1], 0, 1), (plots[2], 0, 2),
    (plots[3], 1, 0), (plots[4], 1, 1), (plots[5], 1, 2)
], nrows=2, ncols=3, spacing=15)

show(grid)

Install with Tessl CLI

npx tessl i tessl/pypi-bokeh

docs

client-server.md

colors-transforms.md

command-line.md

document-management.md

embedding-integration.md

events-interactivity.md

index.md

io-operations.md

layouts.md

models-data-sources.md

plotting-interface.md

server-applications.md

widgets.md

tile.json