5 Best Ways to Use Bokeh to Draw Random Rectangles with Specific Alignment in Python

Rate this post

πŸ’‘ Problem Formulation: In data visualization and graphical representation tasks, it’s often useful to generate random shapes to illustrate distributions, anomalies, or simply to create engaging graphics. This article shows how to use the Bokeh library in Python to draw random rectangles that align with specified constraints. For example, we might want to generate rectangles with a fixed width, random heights, and aligned along a common baseline.

Method 1: Using Bokeh’s Quad Glyphs

The Quad glyph in Bokeh is perfect for drawing rectangles with specific top, bottom, left, and right properties. This method will involve creating random data for the dimensions adhering to our alignment constraints and then using the Quad glyph to produce the rectangles on a Bokeh plot.

Here’s an example:

from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource
import random

# Create random data
data = {
    'left': [i for i in range(10)],  # List of x-coordinates for the left side
    'right': [i+0.8 for i in range(10)],  # Add a fixed width to left coordinates
    'top': [random.uniform(0.5, 1) for _ in range(10)],  # Random top y-coordinates
    'bottom': [0 for _ in range(10)]  # Align all rectangles on the same baseline
}

# Create a ColumnDataSource
source = ColumnDataSource(data)

# Create a new plot
p = figure(plot_height=300, plot_width=600, title="Random Rectangles with Specific Alignment")
# Add quads to the plot
p.quad(top='top', bottom='bottom', left='left', right='right', source=source)

show(p)

Output: A Bokeh plot with random rectangles aligned along a common baseline.

This code snippet generates ten rectangles with a fixed width, random heights, and a common alignment along the x-axis (baseline) using the ColumnDataSource for providing data and Quad glyphs for drawing rectangles.

Method 2: Using Bokeh’s Rect Glyphs with Fixed Size

Bokeh’s Rect glyphs enable drawing rectangles that are easier to control for specific dimensions, such as when you want to specify width and height directly. This method allows you to set a fixed width or height and let the other dimensions be randomly generated while keeping the alignment.

Here’s an example:

from bokeh.plotting import figure, show
from random import uniform
from bokeh.models import ColumnDataSource

# Generate random heights and starting positions
heights = [uniform(0.2, 1.0) for _ in range(10)]
y_starts = [h/2 for h in heights]  # Compute y-coordinates to align rectangles at the bottom

# Create plot and data source
p = figure(plot_height=300, title="Random Rectangles with Fixed Size")
source = ColumnDataSource(data=dict(x=range(10), y=y_starts, width=[0.8]*10, height=heights))

# Add rectangles to the plot
p.rect(x='x', y='y', width='width', height='height', source=source)

show(p)

Output: A Bokeh plot displaying rectangles with a fixed width and random heights, all aligned at the bottom.

The above code snippet uses the ‘rect’ glyph to create rectangles with effectively random heights by adjusting the y-coordinate so that all rectangles align at the bottom while having a fixed width.

Method 3: Combine Bokeh with NumPy for Enhanced Randomness

Integrating NumPy with Bokeh can produce a more sophisticated randomness in the rectangles’ dimensions and positions while maintaining a specific alignment. NumPy allows for the generation of random numbers following different distributions or applying vectorized operations for speed.

Here’s an example:

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

width = 0.8
x_positions = np.arange(10)
tops = np.random.rand(10)

p = figure(plot_height=300, title="Random Rectangles with NumPy")
source = ColumnDataSource(data={'x': x_positions, 'top': tops, 'width': [width]*10, 'height': tops})

p.rect(x='x', y='tops/2', width='width', height='tops', source=source)

show(p)

Output: A Bokeh plot with rectangles of varying heights generated with NumPy’s random functionality, all aligned along a common baseline.

By utilizing NumPy’s efficient array processing capabilities, this snippet generates an array of random heights for the rectangles, computes centers for y-coordinates to align them at a baseline, and uses these arrays to draw the aligned rectangles with Bokeh.

Method 4: Applying Transformations for Alignment

Bokeh provides various transformation tools, such as jitter, dodge, and stack. These can help to position rectangles with random widths or heights in a way that aligns them consistently to a specific orientation, such as having all bottoms or tops aligned.

Here’s an example:

from bokeh.transform import jitter
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource

# Data
width = 0.8
x = range(10)
tops = [random.uniform(0, 1) for _ in range(10)]

# Create Bokeh plot
p = figure(plot_height=300, plot_width=600, title="Random Rectangles with Jitter Transformation")
source = ColumnDataSource(data=dict(x=x, tops=tops))

# Add rectangles with jitter transformation for alignment
p.rect(x=jitter('x', width=0.5), y='tops/2', width=width, height='tops', source=source)

show(p)

Output: A Bokeh plot with rectangles randomly distributed along the x-axis, with a fixed width and random heights, all visually centered along a baseline.

This snippet demonstrates the use of the ‘jitter’ transformation to randomly distribute rectangles along the x-axis, providing a visually interesting alignment while keeping a consistent width and random heights for each rectangle.

Bonus One-Liner Method 5: Plotting With Randomly Generated Inline Data

A quick one-liner approach for experienced developers, this method leverages Bokeh’s inline data capability with Python’s random library to generate a plot of rectangles in a single line of code, ideal for concise scripts or interactive sessions.

Here’s an example:

show(figure(plot_height=300, plot_width=600).rect(x=range(10), y=[random.random()/2 for _ in range(10)], width=0.8, height=[random.random() for _ in range(10)]))

Output: A compactly generated Bokeh plot with random rectangles aligned to a common baseline.

This one-liner combines several steps into one by directly creating and showing a figure populated with rectangles, using list comprehensions to quickly produce the random dimensions needed for the rectangles’ alignment.

Summary/Discussion

  • Method 1: Using Bokeh’s Quad Glyphs. Offers precise control of rectangle coordinates. Requires some manual calculations for alignment.
  • Method 2: Bokeh’s Rect Glyphs with Fixed Size. Simplifies width or height consistency. Less random control over the secondary dimension.
  • Method 3: Combine Bokeh with NumPy. Allows for advanced random distributions and efficient operations. Requires understanding of NumPy operations.
  • Method 4: Applying Transformations for Alignment. Good for achieving a unique alignment through transformations. Might need fine-tuning to get exact alignment.
  • Method 5: Bonus One-Liner. Quick and concise. Less readable and offers less control over the plot’s properties.