⚙️ Setup¶
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
rng = np.random.default_rng(177)
INK="#1a2138"; INK_SOFT="#4a5578"; CYAN="#0891b2"; PURPLE="#7c3aed"; AMBER="#d97706"; GREEN="#059669"; PINK="#db2777"; GRID="#e6e9f2"; GRAY="#c7ccda"
plt.rcParams.update({"figure.facecolor":"white","axes.facecolor":"white","figure.dpi":110,"font.size":11,
"axes.edgecolor":GRID,"axes.grid":True,"grid.color":GRID,"axes.axisbelow":True,"axes.spines.top":False,
"axes.spines.right":False,"axes.titlesize":12,"axes.titleweight":"bold","legend.frameon":False})
print("Ready.")
Ready.
rows = [
("(a) highest of 6 stores", "Comparison/Ranking", "sorted bar chart"),
("(b) traffic over 24 months", "Trend over time", "line chart"),
("(c) distribution of ages", "Distribution", "histogram (or box plot)"),
("(d) study hours vs scores", "Relationship", "scatter plot"),
]
for q,p,c in rows: print(f"{q:30} | {p:18} -> {c}")
(a) highest of 6 stores | Comparison/Ranking -> sorted bar chart (b) traffic over 24 months | Trend over time -> line chart (c) distribution of ages | Distribution -> histogram (or box plot) (d) study hours vs scores | Relationship -> scatter plot
Answer: (a) comparison/ranking → sorted bar; (b) trend over time → line; (c) distribution → histogram (box plot if comparing groups); (d) relationship → scatter. Name the purpose first and the chart follows.
tickets = pd.Series({"Alpha":58,"Bravo":41,"Carol":73,"Delta":39,"Echo":62,"Foxtrot":47}).sort_values()
fig, ax = plt.subplots(figsize=(7.5,4))
ax.barh(tickets.index, tickets.values, color=CYAN, edgecolor="white"); ax.grid(axis="y", visible=False)
ax.set_xlabel("tickets resolved"); ax.set_title("Resolved tickets by team")
for i,v in enumerate(tickets.values): ax.text(v+0.6, i, str(v), va="center", fontweight="bold")
plt.tight_layout(); plt.show()
Answer: A sorted horizontal bar chart: every value sits on a common scale, so the ranking and the near-ties read instantly. A pie would force the eye to compare six similar angles, which we judge far worse than bar lengths, and six slices is already past the comfortable pie limit.
months = ["Jan","Feb","Mar","Apr","May","Jun"]
defects = np.array([2.1, 2.4, 2.0, 6.8, 2.2, 2.3])
worst = int(np.argmax(defects))
colors = [AMBER if i==worst else GRAY for i in range(len(months))]
fig, ax = plt.subplots(figsize=(8,4.3))
ax.bar(months, defects, color=colors, edgecolor="white")
ax.set_title("April defects spiked to 3x the normal rate", loc="left", color=INK)
ax.grid(False); ax.set_yticks([])
for i,v in enumerate(defects): ax.text(i, v+0.12, f"{v}%", ha="center", fontweight="bold", color=INK_SOFT)
plt.tight_layout(); plt.show()
Answer: Keep the bar chart (comparison across months) but make it argue: gray every normal month, color April in amber, drop the gridlines and y-axis clutter, label the bars directly, and replace an axis-only title with the takeaway ("April defects spiked..."). The reader now sees the conclusion, not just the data.
print("(a) EXPLORATORY (for you): many quick, rough charts; defaults are fine; goal = find what matters.")
print("(b) EXPLANATORY (for execs): a few polished charts; ONE takeaway each; declutter + highlight + annotate.")
print("\nGood explanatory title states the CONCLUSION, e.g.")
print(" weak : 'Revenue by quarter'")
print(" strong: 'Revenue grew 18% after the April relaunch'")
(a) EXPLORATORY (for you): many quick, rough charts; defaults are fine; goal = find what matters. (b) EXPLANATORY (for execs): a few polished charts; ONE takeaway each; declutter + highlight + annotate. Good explanatory title states the CONCLUSION, e.g. weak : 'Revenue by quarter' strong: 'Revenue grew 18% after the April relaunch'
Answer: Exploratory work is for you: make many fast, rough charts and see everything. Explanatory work is for an audience: a few polished charts, each with one clear takeaway, decluttered, with the key element highlighted. A good explanatory title states the conclusion ("Revenue grew 18% after the April relaunch"), not just the axes ("Revenue by quarter").
choices = {
"(a) single KPI 4.6/5": "NUMBER (one value -> just show it big)",
"(b) 4 exact revenue figures": "TABLE (precise look-up values)",
"(c) shape of 10,000 amounts": "CHART (a histogram -> distribution)",
}
for q,a in choices.items(): print(f"{q:34} -> {a}")
(a) single KPI 4.6/5 -> NUMBER (one value -> just show it big) (b) 4 exact revenue figures -> TABLE (precise look-up values) (c) shape of 10,000 amounts -> CHART (a histogram -> distribution)
Answer: (a) a number, one KPI is clearest shown big; (b) a table, when readers must look up exact values a table beats a chart; (c) a chart (histogram), because the shape of 10,000 values is exactly what a chart reveals and a table never could. Always gate a chart with "would a number or table say this more clearly?"