HAHS.
Back to Catalog

Bubble Chart

chart

Also known as: bubble plot, proportional symbol chart, sized scatterplot

Show relationshipCompareShow distribution NumericalCategorical Point/Dot

Description

A bubble chart extends the standard scatterplot by mapping a third quantitative variable to the area of each circle (bubble). The x-axis and y-axis encode two variables as in a regular scatterplot, while circle size adds a third dimension of information. Optionally, a fourth variable can be mapped to bubble color, and a fifth to animation over time, making bubble charts one of the most data-dense single-view chart types available.

The most famous bubble chart is Hans Rosling’s Gapminder visualization, which plots countries’ life expectancy vs. income with population encoded as bubble size and continent as color. This example demonstrates the chart’s greatest strength: it can tell a rich, multi-variable story in a single view that audiences can immediately engage with.

Bubble charts require careful design decisions around size perception. Humans naturally compare diameters rather than areas, which leads to systematic underestimation of differences. To counteract this, bubble size should always scale by area (radius proportional to the square root of the value), and a size legend should be provided. Overlapping bubbles can also be a significant readability challenge, which may require transparency, jittering, or interactive hover states to address.

Bubble Chart — interactive example

When to Use

  • Showing the relationship between two continuous variables with a third variable as context (size)
  • Comparing entities across multiple dimensions simultaneously (e.g., countries by GDP, population, and life expectancy)
  • Highlighting outliers that are extreme in multiple dimensions at once
  • Creating engaging, narrative-driven visualizations for presentations

When NOT to Use

  • When precise size comparison is important — area perception is imprecise; use a bar chart for exact comparisons
  • When you have hundreds of data points that would overlap heavily — consider a scatterplot with color encoding or a heatmap
  • When the third variable has very low variance — all bubbles will appear the same size, adding no information; use a regular scatterplot
  • When categories rather than continuous values define both axes — use a heatmap or grouped bar chart

Anatomy

  • Bubbles (circles): Each data point is a circle positioned by x and y values, with area proportional to a third variable
  • X-axis: Encodes the first continuous variable (horizontal position)
  • Y-axis: Encodes the second continuous variable (vertical position)
  • Size scale: Maps the third variable to circle area; a size legend shows representative values
  • Color encoding: Optionally maps a fourth variable (categorical or continuous) to bubble fill color
  • Labels: Direct labels or tooltip-on-hover for identifying individual bubbles

Variations

  • Packed bubble chart: Removes the x/y axes entirely; bubbles are packed together using force simulation, encoding only size and color
  • Bubble map: Bubbles are placed on geographic coordinates, combining the bubble chart with a map layer
  • Animated bubble chart: Time is encoded as animation, with bubbles moving across the plane as a timeline plays (Gapminder style)
  • Connected bubble chart: Lines connect the same entity’s positions across time steps, showing trajectories
  • Semi-bubble chart: Only size and one axis variable are used, with the other axis used for categorical grouping

Code Reference

// Observable Plot bubble chart
import * as Plot from "@observablehq/plot";

Plot.plot({
  grid: true,
  r: {range: [2, 30], label: "Population"},
  color: {legend: true},
  marks: [
    Plot.dot(countries, {
      x: "gdp_per_capita",
      y: "life_expectancy",
      r: "population",
      fill: "continent",
      fillOpacity: 0.7,
      stroke: "white",
      strokeWidth: 0.5,
      title: d => `${d.name}\nGDP: $${d.gdp_per_capita}\nLife exp: ${d.life_expectancy}`
    })
  ]
})