Skip to course content
Free data visualization course

Data Visualization and Dashboard Storytelling

Unit 04.01: Bars, and the zero baseline argument

Bars encode length, and that single fact settles the zero-baseline argument.

Length must be proportional to value

Three values drawn at two baselines, as text bars you can measure.

The code renders both.

VALUES = {"A": 102, "B": 108, "C": 96}

print("bars encode LENGTH, so length must be proportional to value:")
for floor in (0, 90):
    print(f"\n  baseline at {floor}:")
    for name, value in VALUES.items():
        bar = "#" * int((value - floor) / (max(VALUES.values()) - floor) * 30)
        print(f"    {name} {bar}")

print("""
At a baseline of 90 the bars suggest C is a third of B. It is 89% of B.

Lines are different: they encode POSITION, not length, so a truncated axis is
legitimate for a line chart -- provided the axis is labelled and the truncation
is visible.
""")

At a baseline of 90 the bars suggest C is about a third of B. It is 89% of B. The reader is not making an error - they are correctly reading a length that was drawn wrongly.

Lines are genuinely different. They encode position rather than length, so a truncated axis is legitimate - which is why "never truncate" is wrong as a blanket rule and "never truncate bars" is right.

The mistake this prevents

The mistake is applying the rule to everything or to nothing. Both positions are common and both are wrong: the rule follows from what the mark encodes, so it applies to bars and areas and not to lines and points.

Takeaway

Bars and areas start at zero because they encode length. Lines and points encode position and may be truncated with a labelled axis.