Skip to content
ML Academy

Core day 8 of 60 · Week 2 · Part I · application depth

Visualization and Executive Storytelling

The weekly deck has a chart called "Bookings by month, 2023 vs 2024" and the two lines look almost identical from March onward. What chart and title would tell the commercial director what actually happened, and what limit on that reading must be on the slide?

By the end: For a given analysis you choose the chart that fits the comparison, write a title that states the finding with a number, and add one interpretation limit that a careful reader would otherwise miss.

At a glance

Pick the chart for the comparison the reader must make, write the finding as the title, and check that the encoding and the aggregate do not change the reader's sentence.

  • Comparison first

    Time, ranking, distribution, relationship or parts of a change: each has a default chart.

  • Title = finding

    Finding + number + scope, as a sentence a director could repeat.

  • Honest encoding

    Bars start at zero; small multiples share one axis.

  • Hidden splits

    A flat total can be a fall and a rise; split by the segment you suspect.

  • SCIIA

    Situation, complication, insight, implication, action, with the limit stated.

Recall · 5 min

Without notes: a report joined flight results to all 13 booking-curve snapshots. Which of its tiles were wrong - total passengers, average load factor, revenue per passenger - and why did the others survive?

Open due reviews

Sign in to record this block.

Concept · 10 min

A chart is an argument with a picture attached. The reader gets about five seconds: they read the title, glance at the shape, and leave with one sentence. If the title only names the axes ("Bookings by month"), the reader writes their own sentence, often the wrong one. Start from the comparison the reader must make, then pick the chart.

The same booking data support "flat year", "two opposite segments" or "summer demand capped", depending on the chart

Predict first

The network total is flat from March. What is the most likely reason the deck missed a story?

Text description of the figure

A chart editor with a chart-type selector, an axis-baseline toggle and a choice of titles for the same airline booking data. Switching from a single total line to small multiples by route group reveals opposite movements; starting a bar axis above zero visibly exaggerates a 6% drop. The widget uses its own seeded table, so its percentages differ slightly from the query's (for example -5.5% rather than -5.6%).

Start from the comparison, then pick the chart Hierarchy
over timea rankinga distributiona relationshipa breakdownby segmentWhat must the readercompare?before choosing a chartLineindexed lines (base = 100)when levels differSorted bars or dotshorizontal, largest firstHistogram, box, ECDFtry several bin widthsScatterwith a reference lineWaterfall or drivertreewhere it sits, not whySmall multiplesone shared axis
  • What must the reader compare?before choosing a chart
    • over timeLineindexed lines (base = 100) when levels differ
    • a rankingSorted bars or dotshorizontal, largest first
    • a distributionHistogram, box, ECDFtry several bin widths
    • a relationshipScatterwith a reference line
    • a breakdownWaterfall or driver treewhere it sits, not why
    • by segmentSmall multiplesone shared axis

One comparison per chart. When the reader needs two, draw two panels rather than one chart that serves neither.

Is the network growing? From one line to two panels Diagram
Total by monthtwo lines, almostidenticalSegments maydiffer?Split by routegroupcompetitor routesvs the restSmall multiplesYoY bars, shared axis, 1March markerCheck capacityshare of flightsat the limitState the limit+3.8% is a floor fordemandKeep one lineand say the segmentsagreeyesnorise capped?
  1. Total by monthtwo lines, almost identical
  2. Segments may differ?
    • yes: to Split by route group
  3. Keep one lineand say the segments agree
  4. Split by route groupcompetitor routes vs the rest
    • to Small multiples
  5. Check capacityshare of flights at the limit
    • to State the limit
  6. Small multiplesYoY bars, shared axis, 1 March marker
  7. State the limit+3.8% is a floor for demand
A flat total over two opposite segments Illustration
050k100k136912The deck: network bookings by monthdashed 2023 and solid 2024lie almost on top of each othermonthbookings

From March the network moved +0.4%. The reader concludes "flat".

-505136912Year-on-year change by segment (%)1 March: rival seatsother routescompetitor routesmonth% vs same month 2023

Split by the segment you suspect, plot the change from a zero line, and mark the date that matters.

Where the change sits, Mar-Deccompetitor-18,369other+22,327network+3,958bookings vs 2023

Contributions add up to the total: bookkeeping, not causes. Each bar says where the change sits, not why.

Seeded monthly bookings from the Day 8 chart critic (3 competitor routes, 8 other routes). The sample database tells the same story with slightly different numbers.

The deck's chart, the same data as change by segment on one axis, and where the change sits. Same numbers, three different first sentences.

Anatomy of an insight-led title Stack
  1. FindingBookings fell on three routes and rose on the rest.
  2. Number-5.6% and +3.8%.
  3. ScopeFrom March 2024; the three routes where competitors added seats.
  4. LimitUnder the chart: +3.8% is a floor, because more flights hit their limit.

The title is a claim, so it must be one the data support and no stronger. Timing is not a cause (Day 5).

One comparison, one knob - the axis start Illustration
Axis from zero0k334k2023316k2024bar ratio 1.06 for a data ratio of 1.06
Axis from 250k250k334k2023316k2024bar ratio 1.28 for a data ratio of 1.06
Axis from 310k310k334k2023316k2024bar ratio 4.18 for a data ratio of 1.06
Lie factor = change shown ÷ change in the data1 = honest10×100×1000×from 250k: 4.8×from 310k: 54.6×2024 value 316kwhere the bar axis starts (bookings)

Log scale: the exaggeration is not linear; it explodes as the axis start approaches the smaller bar.

Honest alternative: plot the change0% = no changecompetitor routes-5.5%other routes+3.7%

A change metric has a natural zero. Bars from it are honest at any zoom, and both segments fit one axis.

Seeded monthly bookings from the Day 8 chart critic, March-December, competitor routes; the sample database gives slightly different totals.

Bars encode value by length, so moving the baseline changes the story. The lie factor grows without limit as the baseline approaches the smaller bar.

  • Title = finding + number + scope: an insight-led title no stronger than the evidence.
  • Honest encoding: bar axes start at zero (proportional ink); small multiples share one axis.
  • Distortions need no bad axis: aggregation, selection, the calendar and capacity censoring.
  • Structure the message with SCIIA: situation, complication, insight, implication, action.

Assumptions

  • The underlying numbers are already correct at the right grain (Days 6-7); design cannot rescue a fan-out or a data gap.

  • The reader's comparison is known; a chart designed for "which route grew most" fails a reader asking "is the network growing".

  • A title states an association unless a design supports a causal claim (Day 5); timing alone is not a cause.

Sign in to record this block.

Application and workplace decision · 10 min

The deck's chart sums all routes by month. Run the query, which splits 2024 vs 2023 bookings by route group and period and adds how often flights hit their booking limit. Then (a) choose the chart, (b) rewrite "Bookings by month" as an insight-led title, and (c) write one interpretation limit for the slide.

SQL (airline sample database)

-- "Bookings by month" hides two segments. Compare 2024 with 2023 by route group and period.
-- Booking limit = capacity x 1.06 (the simulated airline's overbooking limit = max bookings seen per aircraft size)
WITH t AS (
  SELECT CASE WHEN route IN ('IST-ADB', 'IST-AYT', 'IST-FRA') THEN 'competitor-added-seats'
              ELSE 'other-routes' END AS route_group,
         CASE WHEN substr(date, 6, 2) IN ('01', '02') THEN '1 Jan-Feb' ELSE '2 Mar-Dec' END AS period,
         date >= '2024-01-01' AS is_2024,
         bookings_final,
         bookings_final >= CAST(capacity * 1.06 AS INTEGER) AS at_limit
  FROM flight_day
  WHERE date >= '2023-01-01'
)
SELECT route_group, period,
       SUM(CASE WHEN is_2024 = 0 THEN bookings_final END) AS bookings_2023,
       SUM(CASE WHEN is_2024 = 1 THEN bookings_final END) AS bookings_2024,
       ROUND(100.0 * SUM(CASE WHEN is_2024 = 1 THEN bookings_final END)
             / SUM(CASE WHEN is_2024 = 0 THEN bookings_final END) - 100, 1) AS yoy_pct,
       ROUND(100.0 * AVG(CASE WHEN is_2024 = 0 THEN at_limit END), 1) AS pct_at_limit_2023,
       ROUND(100.0 * AVG(CASE WHEN is_2024 = 1 THEN at_limit END), 1) AS pct_at_limit_2024
FROM t
GROUP BY route_group, period
ORDER BY route_group, period;

This code is executed in the repository's checks (pnpm lesson:py / lesson:sql). It is not run on this site; copy it into your notebook.

Sign in to record this block.

Mini-assessment · 8 min

Your first answer is your evidence. You can re-answer later in practice mode; that is labelled practice.

Question 1 · easy

Which title should go above the small-multiples chart from today's query?
Options

How confident are you? (optional, used for calibration)

Question 2 · medium

A bar chart shows March-December bookings on the competitor routes: 333,898 in 2023 and 315,271 in 2024. The y-axis starts at 300,000. How many times longer is the 2023 bar than the 2024 bar on the page? (Two decimals.)
ratio of bar lengths

How confident are you? (optional, used for calibration)

Question 3 · hard

A bar chart compares average load factor of routes launched since 2020 (0.84) with older routes (0.78); the figures are illustrative. Its draft title is "New routes outperform the legacy network". You learn that five routes launched since 2020 were closed within a year for weak loads and are not in the data. What do you put on the slide?
Options

How confident are you? (optional, used for calibration)

Question 4 · medium

Bookings on the three competitor-seat routes rose from 59,018 in January-February 2023 to 63,285 in January-February 2024 (+7.2%). The 2023 period has 59 days; the 2024 period has 60 (29 February). What is the growth in bookings per calendar day, in percent? (One decimal.)
percent

How confident are you? (optional, used for calibration)

Question 5 · hard

On the eight other routes, bookings from March rose 3.8% year on year, and the share of flights at their booking limit rose from 23.3% to 30.5%. The director asks: "So demand grew 3.8%?" What can the data support?
Options

How confident are you? (optional, used for calibration)

Sign in to complete lessons and keep your progress.

Technical depth · optional · 30 min in total

Open only what you need. Nothing here is required to complete the day; the assessment covers the core above.

Perceptual encoding theory: why position beats length beats area6 minThe ranking of elementary perceptual tasks, Stevens' power law and Weber's law, and what each implies for the chart you draw.
Elementary perceptual tasks, most to least accurate Scale
  1. 1. Position, common scaledot plot, aligned bars: conversion rate by channel
  2. 2. Position, nonalignedsmall multiples, stacked segments: claims by region
  3. 3. Length, direction, angleunaligned bars, slopes, pies: fine for 2-3 slices only
  4. 4. Areabubbles, treemaps: store revenue as bubble size
  5. 5. Volume, curvature3D columns of telecom subscribers
  6. 6. Shading, saturationheatmaps, choropleths: patterns yes, values no

Cleveland and McGill (1984); their experiments supported position over length and angle, the rest is a hypothesis, and spacing is schematic. Position wins because two points are read against one ruler; each step down the ranking adds a judgment. Put the title's comparison as high in the ranking as the data allow; use colour to group or highlight.

Two laws of perception behind the ranking Formula
p=k aα  ⇒  p1p2=(a1a2)αdp(x)=kp x\begin{gathered}p = k\,a^{\alpha} \;\Rightarrow\; \frac{p_1}{p_2} = \left(\frac{a_1}{a_2}\right)^{\alpha} \\ d_p(x) = k_p\, x\end{gathered}
aa
the physical magnitude drawn: a length, an area, a volume
pp
the magnitude the reader perceives (Stevens' power law)
α\alpha
close to 1 for length (judgments roughly unbiased), below 1 for area and lower still for volume: big marks look smaller than they are
dp(x)d_p(x)
Weber's law: the difference detected with probability p grows in proportion to the length x being judged
kpk_p
a constant that does not depend on x; small differences between long bars are therefore hard to see

Both laws as summarised by Cleveland and McGill (1984). With alpha below 1 an area chart understates ratios; Weber's law is why you plot a small change from a zero line instead of asking readers to compare two long bars.

Same numbers, four encodings, and how big a ratio looks Illustration
One set of numbers, four encodingsPositionrank 1Lengthrank 3Arearank 4Radiusa mistakeNorthCentreSouthradius x2 draws area x4: lie factor 3.0

Values 2, 4, 8 in every row. Dots and bars are read against one scale; circles must be compared by area, the weakest of the four tasks drawn.

Perceived ratio = (true ratio) ^ alpha4.002.642.00alpha = 1 (length)alpha = 0.7alpha = 0.5true ratio of the two values

A mark 4 times larger is perceived 2.64 times larger at alpha = 0.7 and 2.00 times at 0.5. Length judgments sit near alpha = 1, which is why bars and dots carry the number the title is about.

Illustrative values. The power law and the ordering of tasks are from Cleveland and McGill (1984); the alpha values 0.7 and 0.5 are examples of “below 1”, not measured constants - they vary by person and experiment.

Left: values 2, 4, 8 as dots, bars, area-scaled and radius-scaled circles. Right: the power law turns a true ratio into a perceived one; only alpha near 1 reads true.

The same difference of 6, on top of 300 and on its own Illustration
0100200300Two long bars: compare the topsMay: 300June: 306difference 6: 2% of the barvalue

The eye compares two lengths of about 300; a 2% step at the top is close to the threshold of what anyone notices.

02468The change itself, from a zero line+6June minus Maychange vs May

Same data, same honest zero baseline; now the finding is the length being judged, not a sliver on top of it.

Illustrative values 300 and 306. Weber’s law as summarised by Cleveland and McGill (1984): the just-noticeable difference grows in proportion to the length judged.

Weber's law in practice. Between two long bars the 6 is 2% of the length and nearly invisible; drawn as its own bar from a zero line it is the whole mark. Chart the change when the change is the finding.

The lie factor, derived and computed4 minTufte's definition, the one-line derivation for a truncated bar axis, and two charts worked by hand: a SaaS line of users and a clinic bubble chart.
Tufte's lie factor, and its closed form for a truncated bar axis Formula
LF=effect showneffect in dataeffect=∣v2−v1∣v1bars from c:LF=∣v2−v1∣/(v1−c)∣v2−v1∣/v1=v1v1−c\begin{gathered}\text{LF} = \frac{\text{effect shown}}{\text{effect in data}} \\ \text{effect} = \frac{|v_2 - v_1|}{v_1} \\ \text{bars from } c: \\ \text{LF} = \frac{|v_2-v_1|/(v_1-c)}{|v_2-v_1|/v_1} = \frac{v_1}{v_1 - c}\end{gathered}
v1,v2v_1, v_2
the first and second value in the data; each effect is measured relative to the first one
cc
where the bar axis starts; the drawn lengths are v_1 - c and v_2 - c
LF=1\text{LF} = 1
the graphic changes exactly as much as the data; c = 0 always gives 1 for bars
v1/(v1−c)v_1/(v_1 - c)
the size of the difference cancels: distortion depends only on how close the axis start sits to the first bar, and explodes as c approaches v_1
c>v1/2c > v_1 / 2
a quick review test: once the axis starts above half the first value, a bar chart's lie factor is already above 2

The derivation is two lines: the numerator and denominator share |v_2 - v_1|, so what is left is the ratio of the first bar's true value to its drawn length.

Worked by hand: a SaaS active-user chart and a clinic bubble chart Table
StepBy handValue
Data: monthly active users48,000 in May, 52,000 in June-
Effect in data(52,000 - 48,000) / 48,0008.3%
Axis from 45,000: drawn lengths48,000 - 45,000 and 52,000 - 45,0003,000 and 7,000
Effect shown(7,000 - 3,000) / 3,000133.3%
Lie factor133.3 / 8.3, or directly 48,000 / (48,000 - 45,000)16.0
Bar-length ratio, same chart7,000 / 3,000: compares the two drawn bars, not the drawn change with the real one2.33 - a different number; say which you report
Axis from zerolengths 48,000 and 52,0001.0
Clinic visits 100 vs 200, circle radius set to the valuearea grows 4x: effect shown 300% for a 100% effect3.0
Same clinics, circle area set to the valuearea grows 2x1.0 drawn, still under-read (alpha < 1)

Hypothetical numbers, verified in Python. A chart can be numerically honest (LF = 1) and still be decoded badly: the last row is the case for position and length over area. Lines and dots encode by position, so a zoomed line has no lie factor; it only needs a labelled range.

Choosing the chart3 minThe comparison decides the chart; the encoding decides how precisely it can be read.
Encodings and their rules Comparison
CriterionBarsLinesDots
Encodes value byLength from a baselinePosition and slopePosition
Axis mustStart at zeroMay zoom, labelled clearlyMay zoom, labelled clearly
Best forComparing amounts and changes from zeroChange over timeRankings and many categories

Direct labels beat legends; units go in the axis title; remove ink that carries no data.

Honest axes3 minWhy a truncated bar axis inflates a 6% drop several times over, and when a zoom is fine.
A bar axis starting at 310,000 bookings Chart
  • Ratio in the data (2023 / 2024)1.059 x
  • Ratio of bar lengths drawna 6% drop drawn as a 4.5x one4.53 x

Bars encode value by length, so a truncated axis multiplies the visual difference. Lines and dots may zoom, if the axis says so.

When may the axis not start at zero? Table
ChartStart at zero?Why
Bars, areasalwayslength and area are the value; a cut baseline multiplies differences
Lines, dotsnot required; label the rangeposition is read relative to other points, not to zero
Change or differencethe zero line is the referencedraw bars from it; signs stay visible
Ratios and growth over orders of magnitudelog scaleequal distances mean equal ratios
Two series, two unitsavoid dual axestwo free scales let any two lines cross where the designer wants

Practitioner rules consistent with proportional ink (Wilke, chapter 17). The question is never zoom or no zoom; it is whether the encoding is length.

Show the distribution, not only its mean3 minIdentical summaries can hide a tail, a second group or a few disasters.
Same mean, same SD, four different stations Illustration
Mean ± SD: four identical barsA18.0 ± 9.0B18.0 ± 9.0C18.0 ± 9.0D18.0 ± 9.0station; delay in minutes

A summary chart answers only the question its summary answers. Here it says “the stations are alike”.

The same data as dots, with mediansStation A: symmetric; median 18.2Station B: long tail; median 15.5Station C: two regimes; median 14.6Station D: mostly on time, a few disasters; median 16.2-103070delay (minutes)

Show the distribution when the reader’s question is about typical cases, tails or groups; a mean bar hides all three.

Seeded synthetic delays, 120 flights per station, each rescaled to mean 18 and SD 9 minutes exactly; red tick: median.

Bars of a summary statistic answer one question. Dots show whether the typical flight, the tail or a second group is the story: few points, show every dot; many, a box or violin per group. Anscombe (1973) and Matejka and Fitzmaurice (2017) built whole datasets on this trick.

One sample, three bin widths, three shapes Illustration
01382750183654Bin width 18 min0.0-18.0 min: 38 orders18.0-36.0 min: 226 orders36.0-54.0 min: 36 orders1 peak visibledelivery time (minutes)orders

one lump: the two groups merge

033650183654Bin width 3 min9.0-12.0 min: 3 orders12.0-15.0 min: 12 orders15.0-18.0 min: 23 orders18.0-21.0 min: 52 orders21.0-24.0 min: 45 orders24.0-27.0 min: 42 orders27.0-30.0 min: 16 orders30.0-33.0 min: 29 orders33.0-36.0 min: 42 orders36.0-39.0 min: 29 orders39.0-42.0 min: 7 orders2 peaks visibledelivery time (minutes)orders

two peaks: the real structure

010200183654Bin width 0.5 min11.0-11.5 min: 1 orders11.5-12.0 min: 2 orders13.0-13.5 min: 1 orders13.5-14.0 min: 6 orders14.0-14.5 min: 3 orders14.5-15.0 min: 2 orders15.0-15.5 min: 2 orders15.5-16.0 min: 4 orders16.0-16.5 min: 4 orders16.5-17.0 min: 6 orders17.0-17.5 min: 3 orders17.5-18.0 min: 4 orders18.0-18.5 min: 8 orders18.5-19.0 min: 12 orders19.0-19.5 min: 4 orders19.5-20.0 min: 11 orders20.0-20.5 min: 11 orders20.5-21.0 min: 6 orders21.0-21.5 min: 6 orders21.5-22.0 min: 13 orders22.0-22.5 min: 5 orders22.5-23.0 min: 6 orders23.0-23.5 min: 5 orders23.5-24.0 min: 10 orders24.0-24.5 min: 10 orders24.5-25.0 min: 10 orders25.0-25.5 min: 8 orders25.5-26.0 min: 5 orders26.0-26.5 min: 5 orders26.5-27.0 min: 4 orders27.0-27.5 min: 4 orders27.5-28.0 min: 2 orders28.0-28.5 min: 2 orders28.5-29.0 min: 5 orders29.0-29.5 min: 2 orders29.5-30.0 min: 1 orders30.0-30.5 min: 5 orders30.5-31.0 min: 5 orders31.0-31.5 min: 2 orders31.5-32.0 min: 7 orders32.0-32.5 min: 5 orders32.5-33.0 min: 5 orders33.0-33.5 min: 5 orders33.5-34.0 min: 10 orders34.0-34.5 min: 11 orders34.5-35.0 min: 3 orders35.0-35.5 min: 8 orders35.5-36.0 min: 5 orders36.0-36.5 min: 5 orders36.5-37.0 min: 6 orders37.0-37.5 min: 4 orders37.5-38.0 min: 5 orders38.0-38.5 min: 5 orders38.5-39.0 min: 4 orders39.0-39.5 min: 2 orders39.5-40.0 min: 2 orders40.5-41.0 min: 1 orders41.5-42.0 min: 2 orders8 peaks visibledelivery time (minutes)orders

spikes: noise that looks like shape

Seeded synthetic delivery times: 300 orders from two groups (60% around 21 minutes, 40% around 34). "Peaks visible" counts bins that stand clearly above both neighbours.

Histogram shape depends on the bin width: too wide merges two groups into one lump, too narrow turns noise into peaks. Try several widths before you trust or report a shape (Wilke, chapter 7).

Distortions without a bad axis3 minAggregation, selection, calendar and capacity, each with today's example.
Four distortions that need no bad axis Overview
  • Aggregation

    A flat total over a rise and a fall; split before concluding.

  • Selection

    Only stores that survived, only loans that were approved, only routes still flown.

  • Calendar

    A leap day or a moved holiday fakes growth: about 1.7 points in Jan-Feb 2024.

  • Capacity censoring

    Sales are a floor for demand when shelves empty, clinics book out or flights fill.

Today's run: bookings, March-December 2024 vs 2023 Chart
  • Competitor routes (3)333,898 to 315,271-5.6 %
  • Other routes (8)609,761 to 633,1103.8 %
  • Network totalwhat the deck showed0.5 %

Bar length shows size; the value shows the sign. A flat total hid a fall and a rise (airline sample database, synthetic).

Share of flights at their booking limit, other routes, March-December Chart
  • 202323.3 %
  • 2024more demand turned away30.5 %

When more flights fill, bookings understate demand growth (Day 28 estimates unconstrained demand).

Writing the title and the limit3 minFinding, number, scope, and a verb no stronger than the evidence.
Match the verb in the title to the evidence Sequence
  1. Describe: rose, fell, flat

    Any correct aggregate supports it, at the stated grain and scope.

  2. Compare: higher on, lower than

    Needs a like-for-like comparison: same days, same mix, same population.

  3. Associate: moved with, coincided with

    Timing or correlation; say so, and name the obvious alternative.

  4. Cause: drove, caused, because

    Needs a design (Day 5): randomization, a credible control group, a break.

  5. Bound: a floor or a ceiling

    When the measure is capped or incomplete, say on which side the truth lies.

  6. Rule out: changed by less than

    A null result says what the data exclude: 'changed by less than 2 points' is a finding; 'no impact' is not.

Most overclaiming titles are one rung too high on this ladder. Lowering the verb keeps the finding and drops the unsupported part.

Uncertainty and colouradvanced3 minError bars that say what they are, and colour that every reader can decode.
Showing uncertainty without misleading Overview
  • Say what the bars are

    SD shows spread of the units (patients, orders); SE or a CI shows precision of an estimate. Label which.

  • Error bars read as limits

    Readers often take them as minimum and maximum. Prefer a sentence plus a band.

  • Dots for many points

    Overplotting hides density: transparency or binning, and jitter only a little.

  • Null results

    Show the interval and the decision threshold on one axis.

From Wilke, chapters 16 and 18.

Colour and labels Overview
  • About 8% of men

    have a colour-vision deficiency, most often red-green: never encode good or bad by red versus green alone.

  • Few categories

    Beyond about eight colours the legend becomes a lookup task; label lines directly.

  • Diverging scales

    Need a meaningful midpoint, such as zero change or a 50% threshold.

  • Rainbow scales

    Are not ordered in lightness and invent boundaries in smooth data.

From Wilke, chapters 4, 19 and 20. Redundant coding (colour plus a label or shape) survives greyscale printing and every viewer.

The two-minute story2 minSCIIA applied to "is the network growing?".
SCIIA for the two-minute answer Sequence
  1. Situation

    Network bookings +1.3% in 2024.

  2. Complication

    Flat from March.

  3. Insight

    Competitor routes -5.6%, the other eight +3.8% and increasingly capped.

  4. Implication

    Lost share on three routes; unserved demand on the rest.

  5. Action

    Pricing review on the three routes; unconstrained demand before the summer plan.

Memory anchor

Comparison first, chart second, finding in the title, limit next to the claim.

Useful for

  • Weekly and monthly business reviews where a chart must change a decision in a few seconds - retail sales, SaaS activation, hospital capacity.

  • Turning an analysis into a one-page note or slide with a defensible headline and its limit, for example a churn or claims-cost update.

  • Reviewing a colleague's deck for axis, aggregation and selection distortions before it goes to leadership.

Not suitable for

  • Exploratory analysis - EDA charts are for you, can be many and rough, and should not carry polished headlines too early.

  • Settling a causal question - a clear chart of a timing association still needs a design (Day 5) to support "because".

Traps

A title stronger than the evidence

"Demand stopped growing" from capped bookings or out-of-stock retail sales, or "the competitor's price cut took our customers" from timing alone, gets repeated as fact and drives capacity or pricing decisions.

How to avoid it

Write what the data show (bookings, association, segment), then the limit; reserve causal verbs for causal designs.

The flat total

Opposite movements in segments cancel in the aggregate, and the deck reports stability while both segments need action.

How to avoid it

Before calling a total flat, split it by the one or two segments most likely to move differently.

Senior reasoning

A senior starts from the decision and the reader's comparison, not from the chart library. They write the headline first, test it against the strongest objection ("is that demand or bookings?", "which routes are missing?"), and put the limit next to the claim rather than in a footnote. They prefer two plain panels on a shared axis to one clever chart, and they say what a null or mixed result rules out instead of calling it "no change".

Interview question

"Present this analysis to our CFO in two minutes." What structure do you use, and what do you leave out?

Recall cards scheduled after completion

  • Name the default chart for change over time, ranking, distribution, relationship, parts of a change, and the same comparison across segments.
  • Name four ways a correctly drawn chart can still mislead.

Reviewed on a 1 · 3 · 7 · 14 · 30-day schedule; a miss returns the card to 1 day.

References

Optional sections

Deep dive · 10 min

Driver analysis and waterfalls. When the question is "what made the total change", decompose: total change = sum of segment contributions (here -18,627 bookings on the competitor routes and +23,349 on the others from March). A waterfall shows each contribution as a step from the old total to the new one; a driver tree splits a KPI into multiplicative parts (revenue = flights x seats x load factor x fare). Both are additive bookkeeping, not causal attribution - each bar says where the change sits, not why it happened.

Indexed trends. To compare routes of very different size, index each series to 100 in a base period. Choose the base deliberately: an unusual base month makes every later point look like growth or decline.

Null and mixed results. "The new booking page had no effect" is rarely what a test shows. Say what it rules out: "the conversion change was +0.4 points, and the data are consistent with anything from -0.6 to +1.4 points; we can rule out the +2-point lift the business case assumed." That keeps a useful result from being filed as a failure, and it ties back to interval reading on Day 4.

Executive structure without frameworks. Situation-Complication-Insight-Implication-Action is a generic narrative order, not a proprietary method. Its value is discipline: every slide must say what is known, what is surprising, what explains it, what it means and who does what next. If a slide cannot fill "Action", it is backup.

Hands-on lab: Build the small multiples and measure an axis distortion · 15 min

The script draws the two-panel chart in memory (no file is written) from the monthly year-on-year changes the sample database gives for each route group, then measures how much a truncated bar axis would exaggerate the March-December drop. Then:

  1. Change sharey=True to False. What false impression does the right panel now create?
  2. Replace the bars with one line per group on a single panel. Which comparison gets easier and which harder?
  3. Write the one-sentence limit you would put directly under the title.
import io
import matplotlib.pyplot as plt

# Monthly 2024-vs-2023 booking change (%) from the sample DB (synthetic airline), by route group
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
yoy = {
    "Competitor added seats (ADB, AYT, FRA)": [6.0, 8.6, -8.4, -4.7, -3.1, -2.4, -5.5, -3.4, -8.4, -7.2, -8.0, -5.3],
    "Other 8 routes": [4.7, 4.9, 4.5, 6.1, 1.6, 2.6, 2.8, 3.2, 5.2, 3.9, 6.6, 2.3],
}

fig, axes = plt.subplots(1, 2, figsize=(10, 3.5), sharey=True)  # small multiples on ONE shared y-axis
for ax, (name, values) in zip(axes, yoy.items()):
    ax.bar(months, values, color=["#b5b5b5" if v >= 0 else "#c0392b" for v in values])
    ax.axhline(0, color="black", linewidth=0.8)  # zero line: the reference for a change metric
    ax.axvline(1.5, color="grey", linestyle=":", linewidth=1)  # 1 March: competitor capacity step
    ax.set_title(name, fontsize=10, loc="left")
    ax.tick_params(axis="x", labelsize=8)
    ax.spines[["top", "right"]].set_visible(False)
axes[0].set_ylabel("Bookings vs same month 2023 (%)")
fig.suptitle("From March, bookings fell on the three routes where competitors added seats and grew elsewhere",
             fontsize=11, x=0.01, ha="left")
buf = io.BytesIO()
fig.savefig(buf, format="png", dpi=100)  # rendered in memory, no file written
lo, hi = axes[0].get_ylim()
print(f"rendered small multiples ({buf.getbuffer().nbytes > 0}); shared y-axis from {lo:.1f} to {hi:.1f} %")

# How much would a truncated bar chart exaggerate the Mar-Dec drop on the competitor routes?
b23, b24, axis_start = 333898, 315271, 300000
data_ratio = b23 / b24
ink_ratio = (b23 - axis_start) / (b24 - axis_start)
print(f"data ratio 2023/2024: {data_ratio:.3f}; bar-length ratio with axis at {axis_start:,}: {ink_ratio:.2f}")
print(f"exaggeration factor: {ink_ratio / data_ratio:.1f}x")
Interview practice · 10 min

A retail stakeholder wants a dual-axis chart: units sold (bars, left axis) and average selling price (line, right axis) by month, "to show that higher prices cause lower sales". How do you respond?

Content version 6 · last verified 2026-10-11 · depends on sqlite, matplotlib