Visualizing Longitudinal Data: Spaghetti Plots, Lasagna Plots, and Summary Plots for Repeated Measures
You have eight cohorts of mice measured at five time points, and the line plot of group means hides the story. One mouse in cohort 3 is responsible for the apparent treatment effect; another in cohort 5 is masking a real one. Group-mean plots smooth over individual trajectories — which is exactly the variance you need to see for repeated-measures data.
This guide covers the three plots that actually work for longitudinal designs: spaghetti plots for individual trajectories, lasagna plots for high-density data where spaghetti overplots, and summary plots that show group means with appropriate uncertainty. Pick the right one for your sample size and what you are trying to show; the choice is decided in seconds once the rule is clear.
Why Group-Mean Line Plots Mislead for Repeated Measures
A standard line plot shows mean ± SEM per group at each time point. For independent observations this is fine. For repeated measures — the same subject measured multiple times — it discards the within-subject correlation that defines the design. Two scenarios that produce identical group-mean plots:
- Scenario A: every subject increases steadily over time. Tight individual trajectories, real treatment effect.
- Scenario B: half the subjects increase sharply, half decrease slightly. The mean trends up but the data show wide individual variation.
The mean plot is the same in both. The treatment is real in A and uncertain in B. Spaghetti plots reveal the difference; mean plots hide it.
Spaghetti Plots: Show Individual Trajectories
A spaghetti plot draws one line per subject across the time points. Between-subject variability is the spread of the lines; within-subject change is the slope of each line. The two are visually separable in a way that mean plots do not allow.
Spaghetti plots work well at n ≤ 30 subjects per group. Beyond that, individual lines overplot and the figure becomes the “tangled spaghetti” that gives the format its name. At higher density, switch to lasagna plots or layered summaries (below).
Building a Spaghetti Plot in R (ggplot2)
library(ggplot2)
ggplot(data, aes(x = time, y = outcome, group = subject_id, color = treatment)) +
geom_line(alpha = 0.4, linewidth = 0.5) +
geom_point(alpha = 0.6, size = 1.5) +
scale_color_manual(values = c('control' = '#888888', 'treated' = '#D55E00')) +
labs(x = 'Day', y = 'Outcome (units)', color = 'Group') +
theme_classic(base_size = 8)
The group = subject_id aesthetic is what makes lines connect within-subject. Without it, ggplot will draw one line per group at each time, which is the mean-line plot you were trying to escape.
Alpha at 0.3–0.5 lets overlapping lines remain readable; full opacity makes a wall of color. UCLA OARC’s ggplot2 longitudinal-visualization guide walks through additional layouts including faceting by group and overlay of group means.
Adding the Group-Mean Layer
Spaghetti plots are most informative when you overlay the group means as a heavier line on top of the individual trajectories. The reader sees both the trend and the variance:
ggplot(data, aes(x = time, y = outcome, color = treatment)) +
geom_line(aes(group = subject_id), alpha = 0.3, linewidth = 0.4) +
stat_summary(fun = mean, geom = 'line', linewidth = 1.5) +
stat_summary(fun.data = mean_se, geom = 'ribbon', alpha = 0.2, color = NA) +
theme_classic(base_size = 8)
The stat_summary layer with fun = mean draws the group-mean line; mean_se draws a SEM ribbon around it. Use mean_cl_normal if you want a 95% CI ribbon instead.
Lasagna Plots: When Spaghetti Overplots
Lasagna plots arrange one row per subject and use color to encode the outcome at each time point. Where spaghetti plots reveal trajectory shapes, lasagna plots reveal patterns across many subjects. They are especially useful for:
- n > 50 subjects — spaghetti plots become unreadable; lasagna plots stay legible at n > 1000
- Missing data patterns — missingness shows as gaps in the heat map, making dropout visible
- Cohort effects — sorting rows by baseline value or cohort surfaces sub-population structure
The 2010 paper that named the format (Swihart et al., “Lasagna plots: a saucy alternative to spaghetti plots”) gives the full layout rationale and several worked examples on real cohort data.
When converting spaghetti to lasagna, sort rows by a meaningful variable — baseline outcome value, cluster assignment from a mixed model, or cohort. An unsorted lasagna plot shows nothing useful; a sorted one immediately surfaces the dominant pattern.
Summary Plots: When You Want Group-Level Story
For papers where individual trajectories are too dense to show or are not the point, present group means with proper uncertainty. The choice of error bar matters:
| Error bar type | What it shows | Use when |
|---|---|---|
| SEM | Precision of the group mean estimate | You are comparing group means and the test statistic uses SEM |
| SD | Spread of individual values around the mean | You want to show variability of individuals, not precision |
| 95% CI of mean | Range likely to contain the true mean | Reviewers prefer this; visually equivalent to non-overlapping = significant (approximately) |
| IQR / range | Distribution of values, not parametric assumption | Skewed data; mixed-effects model output |
Pick the error bar before you pick the plot. The choice is governed by what claim the figure supports, not by aesthetic preference.
The Wide-vs-Long Data Format Trap
Repeated-measures data usually arrives in wide format: one row per subject, with separate columns for each time point (day1, day7, day30). Most plotting tools want long format: one row per observation, with subject ID, time, and value as columns. Reshaping is the #1 data-prep task that blocks longitudinal analysis.
In R: tidyr::pivot_longer(). In pandas: df.melt(id_vars=['subject_id'], var_name='time', value_name='outcome'). In Stata: reshape long. In SPSS: the Restructure Data Wizard, which is notoriously difficult; UCLA OARC and McGill maintain dedicated tutorials because the built-in help is insufficient.
Do this once at data import; never plot from wide format directly. Most longitudinal-plot bugs trace back to a missed reshape.
Connecting the Plot to the Model
The plot you choose should match the model you are running. If your analysis is a repeated-measures ANOVA or linear mixed model with random intercepts, the model fits subject-specific intercepts — and a spaghetti plot shows them. If your model has random slopes, a spaghetti plot shows the slope variation directly.
Showing a group-mean line plot for an analysis whose statistical justification rests on within-subject correlation is a common reviewer note: “The figure does not visualize the variance structure your model assumes.” If the reviewers have to ask whether your data look repeated-measures, your figure is hiding the structure that makes the model defensible.
What This Looks Like in Practice
For a typical pre-clinical longitudinal study (10 mice per group, 4 groups, 5 time points): use a spaghetti plot with group-mean overlays. The 200 individual lines (40 mice × 5 points) are within readable range, group means are visible, and individual variability is preserved. Cox proportional hazards or mixed-model results referenced from the figure caption tell the rest of the story — the figure’s job is to show what the model is fitting, not to be the analysis.
For larger studies (n > 50 per group, multi-cohort, multi-site): start with a lasagna plot to find subgroup structure, then switch to spaghetti or summary plots once you have selected the comparison that matters. Trying to put 500 lines on one panel makes the figure illegible regardless of styling.
If your longitudinal analysis ends in a survival model rather than a repeated-measures comparison, the visualization conventions are different: a worked example of Cox proportional hazards covers the survival-curve and forest-plot conventions for that case.