Two advertising campaigns might bring in similar numbers of leads while spending different amounts and reaching markets of very different sizes. We may want to compare their results while keeping those differences in view. That gives us several measures to work with, each answering a slightly different question.
A bubble chart plots two numerical values on horizontal and vertical axes, then uses each circle's area to represent a third. We can compare the relationship between the first two measures while keeping the size of each observation in view.
In this guide, we'll explain how to read those circles, work through bubble chart examples using public data, and build a chart in Deepnote. We'll also show when a simpler view makes the comparison easier.
How it works
A bubble chart compares three numerical variables in one view:
- X-axis (horizontal): Represents the first numerical variable.
- Y-axis (vertical): Represents the second numerical variable.
- Bubble size (area): Represents the third numerical variable. Larger bubbles mean larger values.
For example, a campaign’s position could show advertising spend and leads, while its bubble area shows the size of its potential market. Campaigns with similar spending and results can then be compared in the context of how many customers they could reach.
How to read a bubble chart
First, establish what one bubble represents. It could be a country, a campaign, or a product. Then read the center of the circle against the axes. A large bubble may extend across several grid lines, but its center marks its x and y values.
Read size separately. The largest circle represents the largest value of the size variable. It does not automatically represent the best result. A large population, high cost, or heavy vehicle can mean very different things.
Bubble area vs. radius
The area of a circle grows with the square of its radius. Double the radius and the area becomes four times as large.
For values of 100, 200, and 400, we want areas in the ratio 1:2:4. The corresponding radii are approximately 1:1.41:2. A value of 200 should therefore look twice as large in area as 100, without being twice as wide.
The largest circle above has four times the area of the smallest, although its width only doubles. We use simple values here to make the sizing rule visible; these circles are a mathematical demonstration, not a dataset.
Even correctly scaled circles are difficult to compare precisely. Use labels or hover values to check close differences. If exact ranking is the main task, put that measure in a bar graph or Cleveland dot plot alongside the scatter plot.
Bubble chart use cases
We use bubble charts when the third measurement changes how we interpret the first two. These are useful starting points:
- Portfolio reviews: Compare each product's revenue growth with its profit margin, sizing bubbles by revenue. This brings the scale of each product into a discussion that percentages alone can dominate.
- Market maps: Compare advertising spend with leads, sizing bubbles by estimated market size. Check that every market estimate uses the same definition and period.
- Risk and return comparisons: Plot return against a defined risk measure, such as the variability of returns, with area showing the amount held. Label the period and calculation so the positions have a clear meaning.
The values need to describe the same observation. Combining a campaign's monthly spending with its lifetime leads would make the relationship difficult to interpret, even if the chart rendered perfectly.
A bubble chart is less helpful when:
- Nearly every bubble is the same size.
- Small differences in size matter.
- Overlapping circles hide the observations we need to compare.
Bubble chart vs. scatter plot vs. heatmap
How does a bubble chart compare to a scatter plot?
A scatter plot shows the relationship between two numerical measurements. A bubble chart uses the same positions but adds a third measurement through circle area.
Compare the two charts below. Both use the same country data from 2007, plotting GDP per person against life expectancy. In the scatter plot, every country has an equally sized marker. In the bubble chart, marker area represents population.
The country positions stay the same, but China and India become much more prominent when area represents population. The scatter plot makes the relationship between GDP and life expectancy easier to inspect; the bubble chart adds context about how many people each observation represents.
That extra measure should answer a useful question. Does it help us distinguish a large market from a small one, a major holding from a minor one, or a heavier vehicle from a lighter one? If it adds little to the interpretation, we can keep the scatter plot.
Color can identify a category, such as region. It needs its own key: a blue bubble should not require a guess about what blue means.
When to choose a heatmap
A heatmap takes a different approach: it uses color to show values across a grid or other layout.
Chart | What it makes easy to see | Choose it when |
|---|---|---|
Bubble chart | Two numerical measurements plus the relative size of a third | Scale adds useful context to the relationship |
Scatter plot | The relationship between two numerical measurements | Marker size would add little or obscure the pattern |
Grid heatmap | Higher and lower values across combinations, such as team and day | The combinations matter more than individual x/y positions |
A bubble chart can compare individual stocks by risk and return. It places those measures on the axes and uses area for the amount invested. If the question is simply which holdings gained or lost value, a stock heat map of portfolio performance may be easier to scan. In a treemap-style view, tile area can represent the amount invested and color can show return over a stated period.
Our guide to types of graphs covers other options when the question calls for a ranking, distribution, or change over time.
Bubble chart examples with real data
The following examples use historical public datasets. We keep the dates, units, and exclusions visible because they are part of what each chart means.
Country development: GDP, life expectancy, and population
We use the 2007 observations from the Gapminder data excerpt, covering 142 countries. Each bubble represents one country. The horizontal axis shows GDP per person in inflation-adjusted US dollars, the vertical axis shows life expectancy at birth in years, and bubble area represents population. Color identifies the continent.
GDP per person measures economic output divided by population; it is not a typical person's salary. The horizontal axis uses a logarithmic scale, so equal distances represent equal ratios. Moving from $1,000 to $10,000 covers the same distance as moving from $10,000 to $100,000.
China and India stand out because their populations are large, even though neither sits at the highest GDP or life expectancy values. Size brings the number of people into a comparison that would otherwise give every country the same visual weight.
Japan sits above the United States on life expectancy and to its left on GDP per person. Higher economic output does not produce a strict country-by-country ranking of life expectancy. The chart shows an association to investigate, not evidence that changing one measure alone would change the other.
Vehicle comparisons: power, fuel economy, and weight
The Auto MPG dataset from the UCI Machine Learning Repository contains vehicle records from model years 1970 to 1982. We plot horsepower horizontally and city-cycle fuel economy vertically, measured in miles per gallon. Higher mpg means traveling farther on a gallon of fuel. Bubble area represents vehicle weight in pounds.
Each bubble is one vehicle record. We retain 392 of the dataset's 398 records, excluding six with missing horsepower values.
The larger bubbles tend to appear toward higher horsepower and lower fuel economy. Weight adds context to the downward pattern: the more powerful vehicles in this sample also tend to be heavier. We cannot separate the effects of weight, engine design, and model year from this chart alone.
This example also shows the cost of adding size. Many records overlap in the lower-horsepower part of the chart. Transparency helps us see the crowding, but a comparison within one model year or separate panels by year would be easier to inspect. These historical records illustrate the chart; they do not describe today's vehicle market.
How to make a bubble chart
Start with one row per item and columns for the two axis values and the size value. Include a name or identifier so readers can tell the bubbles apart. A category column is useful when color will distinguish groups.
Prepare the measurements
For the country example, we need country, year, GDP per person, life expectancy, population, and continent. Filter to a single year before plotting. Otherwise, one country could appear several times without the reader knowing why.
Check missing values and duplicate records before charting. Size values must be non-negative, and zero needs attention because a circle with zero area disappears.
Negative values can appear on a linear axis, but a logarithmic axis requires positive values. For the country example, GDP per person must therefore be greater than zero. Bubble areas cannot represent negative values.
Describe the chart you need
Open our bubble chart maker and add your file using the Drag & drop your data area. You can also paste a table. Include the column headings so the chart request can identify each measurement.
For the country example, use the Gapminder Python package directly in a Deepnote notebook:
- Open a notebook and start a conversation with Deepnote Agent.
- Ask Agent to install the
gapminderpackage and load its data withfrom gapminder import gapminder. - Describe the chart and the checks you want Agent to perform.
Then enter:
Load the data from the gapminder Python package and use only the rows for 2007. Create one bubble per country, with gdpPercap on the horizontal axis, lifeExp on the vertical axis, and bubble area proportional to pop. Color by continent. Use a logarithmic horizontal axis labeled ‘GDP per person (inflation-adjusted US$, log scale)’ and a vertical axis labeled ‘Life expectancy at birth (years).’ Show the country and all three numerical values on hover. Title the chart ‘GDP per person and life expectancy, 2007.’ Check for missing values and duplicate countries, and report any excluded rows.
If you’re working in a Deepnote notebook, Deepnote Agent can write and run the SQL or Python that filters records, checks missing values, and produces the chart.
Refine the comparison
Start with the settings that affect interpretation: axis scales, the size calculation, exclusions, and what one row represents. Then adjust colors, labels, and spacing.
For a crowded plot, a useful follow-up is:
Create a second view containing only Asian countries. Keep the same axis ranges and population-to-area scale as the full chart so the two views remain comparable.
Keeping the size scale fixed matters. If each view independently enlarges its biggest bubble to fill the available space, circles from different views cannot be compared directly.
For the Python charts used here, ask Deepnote Agent to update the code when you want to change the axes, labels, or bubble-size scale. When comparing several views, ask it to keep the same population-to-area scale throughout.
If you are still choosing a format, our AI chart generator gives you a starting point: upload the data and describe the comparison you want readers to make.
Common bubble chart mistakes
Scaling radius instead of area
Suppose three products have revenue of $100,000, $200,000, and $400,000. Their bubble areas should have a ratio of 1:2:4. If you double the radius for the second product, its area becomes four times as large, making twice the revenue look like four times the revenue.
Use proportional area so the second bubble has approximately 1.41 times the radius of the first, and the third has twice its radius. In Plotly, use sizemode="area". Keep the same sizeref across groups and views that readers will compare.
Letting large bubbles hide smaller ones
In the vehicle example, several cars have similar horsepower and fuel economy. Large, opaque bubbles can cover smaller ones, making it difficult to see how many vehicles occupy that part of the chart.
Reduce the maximum bubble size, add transparency, and draw larger bubbles first so smaller ones remain visible on top. If the cluster is still crowded, split the data into panels by model year, keeping the same axes and weight-to-area scale. Each vehicle should stay at its measured coordinates.
Adding too many points or encodings
Imagine labeling all 142 countries in the Gapminder chart while also using continent colors, population-sized bubbles, and animation across years. Readers would have to work through overlapping names and changing positions before comparing countries.
Start with one year, move country names into hover details, and label only the countries discussed in the text. Keep continent colors if regional comparisons matter. If the main question is which countries have the largest populations, place a ranked population bar chart beside the scatter plot so readers can compare that third measure more precisely.