A bubble chart is a Scatter plot with a third variable encoded in the size of the dots. Each point has a position given by and and an area proportional to a third value. Interest rate vs. month, with the area of each bubble showing the number of customers is the kind of question a bubble chart answers well.
Image: Bubble chart with three variables, CC BY-SA 1.0
The eye reads area less precisely than position, so the third variable is a soft signal — useful for direction and rough magnitude, not for exact values. This is the inherent tradeoff of bubble charts: they let you put a third dimension on a 2D page, but the third dimension is communicated less precisely than the other two.
A practical note: encode the third variable as area, not radius. The eye reads area roughly linearly, so if the variable is , the bubble area should scale as — not as . The pitfall comes from setting bubble radius (or diameter) proportional to , because area scales as radius squared, so a 5× value difference becomes a 25× visual difference. In Matplotlib the s parameter is already area (in points²), so passing s=value is the correct linear-in-area encoding; passing s=value**2 would exaggerate.
For more than three variables, color and shape can be layered on top of position-and-size, but the chart quickly becomes hard to read. The standard rule applies: each new visual channel costs the reader cognitive effort, and at some point the chart communicates less than two separate charts would.
In Matplotlib, ax.scatter(x, y, s=areas) is the bubble chart — s is the marker size in points squared, which is the area.