Choosing the right chart
The question decides the chart: change over time is a line, comparing categories is bars, a relationship between two numbers is a scatter plot, and how values are spread is a histogram.
- Match a question to a chart: trend → line, comparison → bar, relationship → scatter, spread → histogram
- Draw a scatter plot with
ax.scatterand read its points fromax.collections - Explain why a line between unordered categories or a bar chart of a long time series misleads
A chart answers one question. Line: how did a value change over time? The line connects points that have an order. Bar: which category is bigger? Bars compare separate things; their lengths start at 0. Scatter: do two numbers move together (is a bigger budget a bigger revenue)? Each point is one item. Histogram: how are values spread out, where do most fall, are there extremes?
Each kind leaves different objects on the Axes: lines in ax.get_lines(), bars in ax.patches, scatter points in ax.collections (one collection whose get_offsets() are the (x, y) pairs).
Run each example to see what it prints. Running examples doesn't count toward progress.
import matplotlib.pyplot as plt import pandas as pd films = pd.DataFrame({ "title": ["The Country of Glass", "The Harbor on Fire", "The Island at Dawn", "Quiet Orchard", "Last Tide"], "budget_usd": [41100000, 43100000, 9800000, 51600000, 97500000], "revenue_usd": [105800000, 207400000, 10700000, 36600000, 540900000], }) budget = films["budget_usd"] / 1e6 revenue = films["revenue_usd"] / 1e6 fig, ax = plt.subplots() ax.scatter(budget, revenue) ax.set_xlabel("Budget (million USD)") ax.set_ylabel("Revenue (million USD)") points = ax.collections[0].get_offsets() print(len(points), points[4].tolist()) print(round(budget.corr(revenue), 2)) plt.show()
import matplotlib.pyplot as plt fig, ax = plt.subplots() ax.scatter([41.1, 43.1, 9.8], [105.8, 207.4])
import matplotlib.pyplot as plt days = list(range(1, 11)) tmax = [-0.5, 6.7, 9.4, 7.2, 1.7, 5.0, 7.8, 5.6, -0.5, 6.1] # Wichita, 1 to 10 January 2024 fig, axes = plt.subplots(1, 2, sharey=True) axes[0].plot(days, tmax, marker="o") axes[0].set_title("Trend: a line") axes[1].hist(tmax, bins=[-5, 0, 5, 10]) axes[1].set_title("Spread: a histogram") print(len(axes[0].get_lines()), len(axes[0].patches), len(axes[1].patches)) print([int(p.get_height()) for p in axes[1].patches]) plt.show()
Mistakes to avoid: a line through categories (it implies an order and in-between values that don't exist); bar charts of long time series (a line shows the trend with less ink); pie charts for more than a few parts, or for comparing similar sizes (bars compare lengths far more accurately); and a scatter plot without units on both axes.
- Trend over an ordered axis → line; comparison of categories → bars; relationship of two numbers → scatter; spread → histogram.
- Scatter points are in
ax.collections[0].get_offsets(). - One chart per question; a grid of panels can answer several.
- Next: distributions in detail: bins, quantiles and outliers.