Circle Glyphs
The circle is Bokeh's default marker and the glyph you will reach for most often in scatter plots. It comes in two flavors with one important distinction between them.
Circle versus Circle-Inscribed
p.circle() places circles whose size is measured as the diameter in screen pixels (technically screen units). p.circle_cross(), circle_x(), and the inscribed variants draw interior marks. The key gotcha: when a figure's circular axis is active, or when you want true data-space circles with radius, sizes and radii behave differently under zoom:
from bokeh.plotting import figure
p = figure(width=450, height=300)
# screen-space circles, diameter = 12 px on screen
p.circle(x=[1, 2, 3], y=[3, 6, 9], size=12)
# data-space circles, radius = 0.4 x-units wide, grows with zoom
p.circle(x=[5, 6], y=[2, 4], radius=0.4, fill_alpha=0.4)
Scalar versus Vector Properties
Every visual attribute may be a scalar shared by all points or a column applied per point. This is the heart of expressive scatter plots:
from bokeh.models import ColumnDataSource
source = ColumnDataSource(data=dict(
hours=[10, 22, 6, 12, 8],
caffeine=[80, 10, 95, 45, 70],
energy=[3, 1, 5, 2, 4],
))
p.circle(x="hours", y="caffeine", size="energy", source=source,
color="indigo", alpha=0.6)
Here marker size encodes the energy column directly. Sizes scale linearly with column values, so pre-scalling the column (e.g. mapping 0..1 into 5..30 px) keeps scatters legible:
n = [(30 - 5) * (e - 1) / 4 + 5 for e in [3, 1, 5, 2, 4]]
Colors and Alphas
Bokeh accepts hex strings such as "#fcaaaa", named web colors such as "goldenrod", RGB tuples, and — via a ColorMapper on the source — a per-point color column. Fill lines are controllable independently through fill_color, fill_alpha, line_color, and line_width:
p.circle(x=[1, 2, 3], y=[3, 6, 9], size=14,
fill_color="#1f77b4", fill_alpha=0.55,
line_color="firebrick", line_width=2)
Specialized Circle Variants
circle_cross— a circle with a plus insidecircle_x— a circle with an x insidescatter— a general marker dispatcher (seemarker="hex",marker="star")
p.scatter(x=[1, 2], y=[4, 5], size=13, marker="star", color="chocolate")
p.circle_cross(x=[3], y=[7], size=16, color="teal")
Hover Tooltips on Circles
Hovering reads columns of the attached data source exactly as glyph calls do, so name your columns descriptively:
from bokeh.models import HoverTool
hover = HoverTool(tooltips=[("hours", "@hours"),
("caffeine mg", "@caffeine")])
p.add_tools(hover)
Summary
Circles make expressive scatters because size, color, and alpha can each bind to a data column; remember size means screen pixels while radius means data units, and the circle_cross/circle_x/scatter variants extend the family.