Choosing the right chart
The hardest part of a chart is not the code. It is deciding what question the chart answers and choosing a form that answers it honestly.
Start from the question
| Question | Chart |
|---|---|
| Trend over time | Line (dates on x) |
| Compare categories | Bar, sorted by value |
| Distribution of one number | Histogram or box plot |
| Relationship between two numbers | Scatter |
| Part of a whole (up to 5 parts) | Stacked bar (prefer over pie) |
| Composition changing over time | Stacked area or 100% stacked bar |
| Many groups, same metric | Small multiples with a shared y axis |
| One number vs a target | Bar with a target line, or a plain big number |
If you cannot write the question as a sentence — "which three cities lost revenue this quarter?" — no chart type will rescue the slide.
Sort, and label what matters
An unsorted bar chart forces the reader to rank the bars themselves. Sort it, and highlight the bar you are actually talking about.
import matplotlib.pyplot as plt
s = df.groupby("city")["revenue_lakh"].sum().sort_values()
colors = ["#C8CDD4"] * len(s)
colors[list(s.index).index("Coimbatore")] = "#D64545" # the one under discussion
fig, ax = plt.subplots(figsize=(7, 4))
bars = ax.barh(s.index, s.values, color=colors)
ax.bar_label(bars, fmt="%.1f", padding=3)
ax.set_xlabel("Revenue (₹ lakh)")
ax.set_title("Coimbatore is the only market below last year")
ax.spines[["top", "right", "bottom"]].set_visible(False)
ax.xaxis.set_visible(False) # the labels already give the numbers
Notice the title: it states the finding, not the data. "Revenue by city" wastes the most-read line on the slide.
Keep the axes honest
- Bars must start at zero. Truncating the axis triples a 4% difference visually.
- Lines may start away from zero, but say so in the label.
- Use the same scale when panels are meant to be compared.
- Do not plot percentages and rupees on twin y-axes unless you are prepared to explain both scales; two axes let anyone "prove" a correlation.
- Show the denominator. "Conversion up 50%" on 6 orders is noise.
Remove chart junk
Every pixel should carry information. Drop 3-D effects, heavy gridlines, dark backgrounds, borders around everything, and legends that repeat what direct labels already say. Rely on colour for one thing only — and never on red-vs-green alone, since roughly 1 in 12 men cannot separate them; add a marker shape, a label or a pattern.
Common mistakes
- Pie charts with 9 slices. Humans compare angles badly. A sorted bar is nearly always clearer.
- Dual axes used to imply a relationship that a scatter would test properly.
- Too many colours. One accent colour plus grey beats a rainbow.
- Line charts over categories, which invent a trend that does not exist.
- Raw counts across unequal groups. Normalise per 1,000 customers or per store before comparing Mumbai with Nashik.
- Averages hiding a skew. Median bill value plus a histogram tells the real story for retail spend.
Practice
Take any dashboard screenshot you have and list its charts. For each, write the question it answers in one sentence, then decide whether a different chart type would answer it better. Rebuild the weakest one in Matplotlib with a sorted bar, an insight-style title, a highlighted category and no chart junk.