Chapter 18 Visualization Fundamentals
A chart should answer a defined question and represent the data honestly. Choose the mark and scale from the analytical task rather than adding visual decoration first.
18.1 Line, scatter, and histogram use cases
- A line chart emphasizes ordered change, commonly over time.
- A scatter plot examines the relationship between two numeric variables.
- A histogram summarizes the distribution of one numeric variable; results depend on the selected bins.
18.2 Build a labeled chart explicitly
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import pandas as pd
monthly = pd.DataFrame(
{
"month": pd.to_datetime(["2026-01-01", "2026-02-01", "2026-03-01"]),
"revenue": [100, 115, 108],
}
)
figure, axis = plt.subplots(figsize=(6, 3))
axis.plot(monthly["month"], monthly["revenue"], marker="o")
axis.set(
title="Monthly revenue",
xlabel="Month",
ylabel="Revenue ($ thousands)",
)
figure.autofmt_xdate()
assert axis.get_ylabel() == "Revenue ($ thousands)"
plt.close(figure)Labels should include units. For time plots, sort chronologically and do not connect observations when a continuous line would imply nonexistent data.
18.3 Scatter plots and encoded groups
campaigns = pd.DataFrame(
{
"spend": [10, 20, 30, 40],
"conversions": [8, 18, 25, 31],
"channel": ["search", "search", "social", "social"],
}
)
figure, axis = plt.subplots(figsize=(5, 3))
for channel, group in campaigns.groupby("channel"):
axis.scatter(group["spend"], group["conversions"], label=channel)
axis.set(xlabel="Spend ($ thousands)", ylabel="Conversions")
axis.legend(title="Channel")
assert len(axis.collections) == 2
plt.close(figure)A visual association does not establish causality. Confounding, selection, and time trends can produce persuasive patterns without a causal effect.
18.4 Histograms and bin sensitivity
values = [1, 2, 2, 3, 3, 3, 8, 9]
figure, axis = plt.subplots(figsize=(5, 3))
counts, bin_edges, _ = axis.hist(values, bins=[0, 2, 4, 6, 8, 10])
axis.set(xlabel="Value", ylabel="Count")
assert counts.sum() == len(values)
assert len(bin_edges) == 6
plt.close(figure)Inspect alternative bin choices when the apparent shape drives a conclusion.
18.5 Communication checklist
- What question does the chart answer?
- Are labels, units, and population clear?
- Does the axis range distort the comparison?
- Are color and shape accessible and meaningful?
- Does aggregation hide important variation?
- Is uncertainty shown when it matters?
- Does the wording avoid implying causality from association alone?