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

Label Boxplot: Add Group, Size and Value Labels

Learn how to label boxplot charts in R and ggplot2 with custom group names, dynamic sample sizes (n), and summary values for publication-ready figures.

Written and maintained by CASRAI Editorial Board

Last updated

In scientific research, generating a clear boxplot with labels ensures that empirical distributions, group cohorts, and sample variations are immediately interpretable to readers and peer reviewers. While a default box plot provides a five-number statistical summary, adding explicit boxplot labels—including informative category names, dynamic sample sizes, and summary statistics—transforms raw exploratory charts into publication-ready figures. For general foundations on constructing box plots in R, see our companion guide on box plots in R.

What it is used for in research

In observational and experimental studies, researchers use box plots to compare continuous response variables across categorical treatment groups or experimental conditions. However, standard plotting functions often render abbreviated factor codes or obscure group sample sizes. Properly labeling a boxplot serves three essential functions in research communication:

  • Communicating cohort sample sizes: Displaying exact sample sizes (such as n = 45) directly on or above each box informs readers of statistical power and sample balance across conditions.
  • Disambiguating experimental conditions: Replacing terse data frame variable names with formatted labels (for example, “Control (Vehicle)” versus “Treated (10 mg/kg)”) prevents misinterpretation in multi-arm studies.
  • Annotating statistical summaries and outliers: Labeling exact median values or flagging specific extreme observations highlights key findings without requiring readers to cross-reference data tables. To manage extreme data points effectively, review our walkthrough on outliers in R.

Install or access

Box plots can be labeled using Base R graphics or the ggplot2 package within the R statistical computing environment. R is an open-source environment available from the Comprehensive R Archive Network (CRAN). The ggplot2 package is installed directly from CRAN within an active R session:

install.packages("ggplot2")
library(ggplot2)

For broader styling conventions, such as thematic elements and legend adjustments, refer to our tutorials on ggplots in R and how to label legend in ggplot2.

Step-by-step task

The following steps walk through the standard tasks for labeling box plots in R, covering Base R configuration, custom category scales in ggplot2, dynamic sample size calculation, and individual value labeling.

1. Set group and axis labels in Base R

In Base R, the boxplot() function provides dedicated arguments for axis titles (xlab, ylab) and category labels (names). To add text labels at specific plot coordinates, use the text() function:

# Sample research dataset
df <- data.frame(
  group = rep(c("A", "B"), each = 25),
  response = c(rnorm(25, mean = 50, sd = 10), rnorm(25, mean = 65, sd = 12))
)

# Draw boxplot with custom category and axis labels
boxplot(response ~ group, data = df,
        names = c("Vehicle Control", "Active Treatment"),
        xlab = "Study Condition",
        ylab = "Biomarker Concentration (ng/mL)",
        col = c("#E69F00", "#56B4E9"))

# Add sample size labels beneath each box using text()
# pos = 3 places text above coordinates; pos = 1 places text below
text(x = 1:2, y = c(min(df$response[df$group == "A"]), min(df$response[df$group == "B"])),
     labels = c("n = 25", "n = 25"), pos = 1, cex = 0.8)

2. Customize category and axis labels in ggplot2

In ggplot2, axis titles are set with labs(), while discrete group labels on the x-axis are configured using scale_x_discrete(). This enables formatted group descriptions without modifying the underlying raw data frame:

p <- ggplot(df, aes(x = group, y = response, fill = group)) +
  geom_boxplot(alpha = 0.8, outlier.colour = "red", outlier.size = 2) +
  scale_x_discrete(labels = c("A" = "Vehicle Control", "B" = "Active Treatment")) +
  labs(
    title = "Biomarker Response across Study Cohorts",
    x = "Study Condition",
    y = "Biomarker Concentration (ng/mL)",
    fill = "Cohort"
  ) +
  theme_classic()
print(p)

3. Annotate dynamic sample size counts

In empirical studies with unequal group numbers or missing values, hardcoding sample sizes risks reporting errors. The stat_summary() function computes summary statistics dynamically and maps them directly to a text geom:

# Define function to return sample size and y-coordinate for placement
give_n <- function(x) {
  return(data.frame(
    y = max(x) + (max(x) * 0.05),
    label = paste0("n = ", length(x))
  ))
}

# Add dynamic sample size labels above upper whiskers
p + stat_summary(fun.data = give_n, geom = "text", size = 3.5, vjust = 0)

4. Label median values and outlier observations

To display the exact numerical median on top of each box, call stat_summary() using geom = "label" or geom = "text":

# Display median value formatted to one decimal place
p + stat_summary(
  fun = median,
  geom = "label",
  aes(label = sprintf("%.1f", after_stat(y))),
  vjust = -0.5,
  fill = "white",
  size = 3.2
)

Output and how to read it

A properly labeled box plot displays several critical visual components that convey distributional characteristics:

  • Center line: The thick horizontal line indicates the median (second quartile, Q2), representing the central tendency of the group distribution.
  • Box hinges: The lower and upper edges of the box mark the first quartile (Q1, 25th percentile) and third quartile (Q3, 75th percentile). The distance between hinges represents the interquartile range (IQR).
  • Whiskers: The lines extend to the most extreme data point that falls within 1.5 × IQR from each hinge.
  • Outlier markers: Individual points plotted beyond the whiskers represent potential outliers exceeding the 1.5 × IQR boundary.
  • Integrated labels: Cohort labels on the x-axis identify experimental treatments, while sample size annotations (n) quantify observational depth, enabling immediate assessment of statistical power.

Troubleshooting

When creating labeled box plots, researchers frequently encounter visual overlapping or mapping inconsistencies. Address common issues using these documented adjustments:

  • Labels overlap box lines or points: Adjust vertical positioning using vjust (e.g. vjust = -0.5 to place text above, or vjust = 1.5 below the target coordinate). Alternatively, use geom_label() to render a solid background behind the text.
  • Group labels appear in the wrong order: R orders character factors alphabetically by default. Convert the grouping variable to an explicit factor with designated levels using df$group <- factor(df$group, levels = c("Control", "Treatment_Low", "Treatment_High")) prior to plotting.
  • Outliers appear duplicated when adding data points: If overlaying raw observations using geom_jitter() or geom_point(), set geom_boxplot(outlier.shape = NA) to suppress the default boxplot outlier glyphs.
  • Labels clipped at plot boundaries: If sample size labels at the top of the plot are cut off by the plot margin, expand the vertical scale using scale_y_continuous(expand = expansion(mult = c(0.05, 0.15))) or set coord_cartesian(clip = "off").

Free alternatives

Several free and open-source software libraries support programmatic generation of labeled box plots for research analysis:

Tool / Environment Primary Boxplot Function Labeling Approach Key Strength for Research
R (Base Graphics) boxplot() Arguments names, xlab, ylab; text() for arbitrary coordinates Zero dependencies; built directly into core R runtime
R (ggplot2) geom_boxplot() scale_x_discrete(), labs(), stat_summary(), geom_text() Layered grammar of graphics with dynamic data-driven annotations
Python (Matplotlib) plt.boxplot() / ax.boxplot() ax.set_xticklabels(), ax.text() Low-level control over figure canvases and custom axes
Python (Seaborn) sns.boxplot() ax.set_xticklabels(), Matplotlib ax.text() annotations Integrated statistical plotting with automated categorical palettes (seaborn boxplot guide)

FAQ

How do I add sample size (n) labels to each box in a boxplot?

In ggplot2, use stat_summary() with a custom function returning the count and vertical coordinate, mapping to geom = "text". In Base R, calculate group counts with table() or tapply() and position text beneath or above the boxes using the text() function.

How do I change x-axis category labels in ggplot2 boxplots?

Use scale_x_discrete(labels = c("old_name" = "New Name")) to rename categorical levels on the x-axis without modifying the raw data frame. Ensure that all levels in the dataset are correctly mapped.

How do I display value labels on boxplot outliers without duplicating points?

Filter the dataset for values exceeding 1.5 × IQR from the upper or lower quartile, then overlay them using geom_text() with matching aesthetic mappings. Set outlier.shape = NA inside geom_boxplot() to avoid rendering duplicate outlier points.

Can I add median value labels directly to a boxplot in R?

Yes. In ggplot2, pass fun = median and geom = "text" (or geom = "label") to stat_summary() with aes(label = sprintf("%.1f", after_stat(y))). In Base R, calculate the medians using tapply() and overlay them with text() at the box midpoint coordinates.

Sources

  • R Core Team. “R: Box Plots (boxplot).” CRAN R Graphics Package Documentation, R version 4.4, https://stat.ethz.ch/R-manual/R-patched/library/graphics/html/boxplot.html
  • Wickham, Hadley, et al. “A box and whiskers plot (in the style of Tukey) — geom_boxplot.” ggplot2 Documentation, https://ggplot2.tidyverse.org/reference/geom_boxplot.html
  • Wickham, Hadley, et al. “Summarise y values at unique/binned x — stat_summary.” ggplot2 Documentation, https://ggplot2.tidyverse.org/reference/stat_summary.html
  • Wickham, Hadley, et al. “Text — geom_text, geom_label.” ggplot2 Documentation, https://ggplot2.tidyverse.org/reference/geom_text.html

Follow CASRAI

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

Ask CASRAI · free to try

Ask about Label Boxplot: Add Group, Size and Value Labels

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 →