Bubble
Overview
A bubble chart is a scatter plot whose marker sizes encode a third variable. Use it to compare items on two measures at once while showing how big each one is, such as countries by income and life expectancy sized by population. A numeric marker.color adds a fourth variable. A bubble chart is a scatter trace with one marker.size value per point.
Pick a different chart when:
- the size values need to be compared precisely: people judge areas poorly, so use a bar chart for the third variable, or a second chart;
- you have thousands of points: large bubbles overlap into a blob. Use a plain scatter plot with small markers;
- the x values are ordered and the trend matters: use a line chart.
Minimal example
import { bubbleSizeref, createChart } from '@mk7s/holochart';
const size = [120, 480, 60, 950];
const chart = createChart(document.getElementById('chart')!, {
data: [
{
type: 'scatter',
mode: 'markers',
x: [1, 2, 3, 4],
y: [10, 14, 9, 16],
marker: { size, sizemode: 'area', sizeref: bubbleSizeref(size, 60) },
},
],
});sizemode: 'area' makes each bubble's area proportional to its value, and bubbleSizeref(size, 60) scales the sizes so that the largest bubble is 60 px across. The live example has three groups sharing one scale:
bubble/basicData format
xandy: the bubble centers, as for any scatter trace.marker.size: one number per point. The values are scaled to pixels withmarker.sizemodeandmarker.sizeref, exactly as in Plotly:sizemode: 'area': a valuevdraws a bubble2·sqrt(v / 2 / sizeref)px across, so the area is proportional to the value.sizemode: 'diameter'(the default): the bubble isv / sizerefpx across.sizerefdefaults to 1.sizemin(px) sets a lower bound on the drawn size, so tiny values stay visible.
marker.color: one color, one CSS color per point, or numbers mapped throughmarker.colorscale.- Zero, negative,
null, orNaNsizes draw no bubble. Points are drawn in array order, so sort them largest first if small bubbles should be drawn on top of large ones. - Several traces don't share a scale on their own. Give them the same
sizeref, computed over all their sizes, so bubble sizes compare across traces.
Variations
Color by value
A numeric marker.color maps through marker.colorscale, so one bubble shows two values: size and color. marker.showscale: true draws a colorbar; marker.colorbar takes a title and the axis tick API (ticksuffix, dtick, tickformat, …).
bubble/colorscaleScaling large values with bubbleSizeref
Data such as populations runs far beyond pixel sizes. bubbleSizeref(sizes, maxPx) returns the sizeref that draws the largest value maxPx px across. For sizemode: 'area' that is Plotly's documented 2 · max(size) / maxPx²; pass { sizemode: 'diameter' } for diameter scaling. It ignores non-numeric and non-positive sizes. Import it from @mk7s/holochart (or @mk7s/holochart-traces-basic).
bubble/sizerefArea vs diameter
With sizemode: 'diameter', a value twice as large draws a bubble twice as wide, which is four times the area, so large values look far larger than they are. Use 'area' for data. The default stays 'diameter' for Plotly compatibility.
bubble/sizemodeLabels inside bubbles
mode: 'markers+text' with textposition: 'middle center' centers each text label on its bubble. Choose sizeref and sizemin so the smallest bubble fits its label, and a textfont.color that contrasts with the fill.
bubble/labelsBubbles with a diverging scale
Bubbles combine with everything else a scatter trace does. This example pairs area-scaled bubbles with a second trace colored on a diverging scale around cmid: 0.
scatter/colorscaleStyling
marker.size,marker.sizemode,marker.sizeref, andmarker.sizemin, as above.marker.opacity: bubbles default to 0.7, so overlapping bubbles stay visible.marker.line.color/marker.line.width: with Plotly's look (plotly-classic), bubbles default to a 1 px white outline, which separates overlapping bubbles. The defaultholochartlook draws markers without outlines; setmarker.line.width: 1and amarker.line.colorto add one.marker.color,marker.colorscale,cmin,cmax,cmid, andreversescalefor numeric colors;marker.coloraxisshares one scale and colorbar between traces.marker.symbolworks too, though circles are the norm for bubbles.- Every marker attribute accepts per-point arrays. See the scatter styling section.
Interactivity
- Hover. Hovering anywhere over a bubble picks it, not only its center.
%{marker.size}and%{marker.color}inhovertemplateshow the raw values, for example'%{text}: %{marker.size:,} people<extra></extra>'. - Selection. Box and lasso select bubbles by their center. Selected and unselected styles work as on the scatter page.
- Zoom and pan keep the bubble sizes in pixels: zooming spreads bubbles apart without growing them.
- Events.
hover,click, andselectedevents carrypointNumber,x,y, andcustomdata. See the events reference.
Performance notes
- Bubbles are instanced markers on the GPU, like every scatter marker. The cost grows with the pixels they cover, so thousands of large, overlapping, semi-transparent bubbles cost more fill time than the same number of small markers.
- Changing
marker.sizeorsizerefrecomputes the trace, because sizes pad the axis autorange. Changingmarker.coloronly rewrites a color buffer. - Pass typed arrays (
Float64Array) forx,y, andmarker.sizewith large data.
Accessibility notes
- Screen readers: a chart is a single
<canvas>, and the DOM mirror that describes points to assistive technology is not built yet (planned for M2, see the accessibility guide). Add a caption oraria-label, and a table with the size values: they are the hardest part of a bubble chart to read. - Keyboard: Tab moves into the plot area; ← / → then step through the points and ↑ / ↓ move to the trace above or below, each stop showing its hover label. See the keys.
- Color and size: don't encode the key message in bubble size alone. Label the important bubbles, state the size scale in a caption, and pick a colorscale that reads in grayscale (such as
'Viridis').
Attribute reference
Bubble charts use the scatter trace. See the scatter attribute reference, especially marker.size, marker.sizemode, marker.sizeref, and marker.sizemin. bubbleSizeref is documented in the API reference.
Related charts
- Scatter: the same trace with a fixed marker size
- Line: ordered data where the trend matters
- Bar: when the size values need a precise comparison
Plotly migration notes
- A Plotly bubble chart is a
scattertrace with arraymarker.size, and carries over unchanged.sizemode,sizeref, andsizeminuse Plotly's exact formula. bubbleSizeref(sizes, maxPx)is a Holochart helper for Plotly's documented recipesizeref = 2 · max(size) / maxPx².- As in Plotly, bubbles (array
marker.size) default tomarker.opacity: 0.7and, withplotly-classic, a 1 px white outline. The defaultholochartlook draws them without an outline; see Default look. - Not supported yet: a size legend (
marker.sizelegend).