Skip to main content
v2026.11,858 entries · CC-BY 4.0
LAC HealthMedical & Research SuppliesReagents, PPE & instruments — chain-of-custody documented.Fast, traceable sourcing built for regulated research environments, from bench consumables to instrumentation.Shop lac.us CodeCASRAIlac.us

Bad Data Visualization Example: Truncated Axes and How to Fix Them in Code

A bad data visualization example in matplotlib and ggplot2: how a truncated y-axis exaggerates effects, the fix, and a pre-publication checklist.

Written and maintained by CASRAI Editorial Board

Last updated

The most common bad data visualization example in research papers is a bar chart whose y-axis does not start at zero. Peer-reviewed work on this pattern finds that such axes can visually exaggerate effect sizes, and that adding explicit cues does not remove the effect. This guide shows how a truncated chart is built in matplotlib and ggplot2 (both free), how to rebuild it honestly, and how to audit any figure before it goes into a manuscript or report.

What bad data visualization examples are used for in research

Researchers meet bad data visualization examples in two places: when reviewing their own figures before submission, and when judging figures in work they cite. The usual examples (also searched as bad examples of data visualization or examples of bad data visualization) are truncated axes, dual axes with unrelated scales, cherry-picked time ranges, too many pie slices, 3D effects and missing labels or units. This page ties one distortion, the truncated y-axis, to published evidence and to the exact plotting calls that create and fix it.

What the evidence says about truncated axes

Correll, Bertini and Franconeri, in “Truncating the Y-Axis: Threat or Menace?” (CHI 2020, arXiv 1907.02035), report that bar charts with y-axes that do not begin at zero can visually exaggerate effect sizes. They also report that the subjective impact of axis truncation is persistent across visualization designs. They note that advice on whether to truncate the y-axis can be equivocal for other visualization types, and suggest designers consider the scale of the meaningful effect sizes and variation they intend to communicate. Treat a zero baseline as the default for bars, and justify any exception in the figure legend.

Access the tools (official sources)

Both tools below are free and open. Use only the official documentation for installation steps.

Step by step: build a truncated bar chart, then fix it

The values below are made-up demonstration numbers, not data from any study. Two groups differ by only 2%, which is the situation where truncation misleads most.

In matplotlib

  1. Create the bars: fig, ax = plt.subplots() then ax.bar(["Control", "Treatment"], [1000, 1020]).
  2. Make the distortion: ax.set_ylim(990, 1030). The bottom argument is in data coordinates, so the bars now start at 990 and the 20-unit difference fills half of the plot height. Calling set_ylim also switches autoscaling off for that axis (the auto argument defaults to False).
  3. Fix it: replace that call with ax.set_ylim(0, 1100). Both bars now start at a zero baseline and the 2% difference looks like a 2% difference.
  4. If a zoomed view is genuinely needed, keep the zero-based chart as the main panel and add a labelled inset or a second panel, with the axis range stated in the legend.

In ggplot2

  1. Create the bars: ggplot(df, aes(group, value)) + geom_col().
  2. Make the distortion with a zoom: add + coord_cartesian(ylim = c(990, 1030)).
  3. Fix it: use coord_cartesian(ylim = c(0, 1100)), or remove the call so the bars start at zero.
  4. Check which mechanism you used. coord_cartesian() zooms without changing the underlying data. Setting limits on a scale instead (for example scale_y_continuous(limits = ...)) converts all values outside the range to NA, so data is dropped, with warnings.

Output and how to read it

Read a bar chart in this order: where does the baseline sit, what are the units, how many observations are behind each bar, and is there an error bar or interval? If the lowest tick label is not zero, the bar heights cannot be compared as ratios. For distributions, use a chart type that shows the shape rather than a single bar, such as a histogram; for relationships, see scatterplot interpretation. To judge whether a visible gap matters, compare it with the effect size and its interval, not with how tall the bars look.

Other bad data visualization examples to check for

  • Dual axes: two y-axes with unrelated scales can make unrelated series appear to move together. Label both axes and consider two stacked panels.
  • Cherry-picked time ranges: a line chart that starts or ends at a convenient point. State the full range used and why.
  • Too many pie slices, and 3D effects: they make magnitudes hard to compare. A sorted bar chart or a Pareto chart is easier to read.
  • Missing context: no units, no n, no source, no indication of uncertainty.

For positive design practice, see the CASRAI guide on designing effective scientific figures.

Pre-publication audit checklist for a research figure

  1. Do bar charts start at zero? If not, is the exception stated in the legend?
  2. Are units, sample size and the source of the data given?
  3. Are error bars or intervals shown, and is their meaning (standard deviation, standard error, confidence interval) defined?
  4. Is the full time range shown, or is the choice of range explained?
  5. If both axes are scaled, is each labelled and is the scaling choice justified?
  6. In R, were limits applied with coord_cartesian() (zoom) rather than a scale limit (drops data)?

Troubleshooting

  • Bars disappear or a warning about removed rows appears in ggplot2: you likely set scale limits rather than coordinate limits. Switch to coord_cartesian(ylim = ...) so no data is converted to NA.
  • A small margin appears below zero: ggplot2’s expand argument defaults to TRUE and adds a small expansion; set expand = FALSE to use the limits exactly.
  • The matplotlib axis does not update after new data is added: set_ylim turned autoscaling off for that axis, so call it again with the new range.
  • The axis appears upside down: in matplotlib, bottom may be greater than top, which inverts the axis. Swap the two arguments.

Free alternatives

Tool Language Call that sets the axis range Source
matplotlib Python Axes.set_ylim(bottom, top) matplotlib.org documentation
ggplot2 R coord_cartesian(ylim = …) for zoom; scale limits drop data ggplot2.tidyverse.org documentation

FAQ

What is an example of bad data visualization?

A bar chart with a y-axis that does not begin at zero is the standard example, because it can visually exaggerate effect sizes. Dual axes with unrelated scales, cherry-picked time ranges, crowded pie charts and 3D effects are the other frequent ones.

Is a truncated y-axis always wrong?

Not always. Correll, Bertini and Franconeri note that advice on truncating the y-axis can be equivocal for visualization types other than bar charts. For bar charts, a zero baseline is the safe default, and any truncation should be disclosed.

Does labelling the axis fix a truncated bar chart?

Not reliably. The same study reports that the subjective impact of truncation is persistent across visualization designs.

How do I zoom a plot in R without losing data?

Use coord_cartesian(ylim = ...). Setting limits on a scale converts values outside the range to NA; the ggplot2 documentation says this converts them to NA, so those data are dropped.

Sources (official documentation and research, checked 2026-10-29)

  • Correll, M., Bertini, E., Franconeri, S. “Truncating the Y-Axis: Threat or Menace?” arxiv.org/abs/1907.02035 (CHI 2020, DOI 10.1145/3313831.3376222). Checked 2026-10-29.
  • matplotlib, Axes.set_ylim. Checked 2026-10-29.
  • ggplot2, coord_cartesian. Checked 2026-10-29.

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about Bad Data Visualization Example: Truncated Axes and How to Fix Them in Code

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →