Skip to main content
v2026.11,610 entries · CC-BY 4.0

Box Plots in Stata: graph box and over-Groups

How to build grouped box plots in Stata with graph box and graph hbox: the over() option for categorical breakdowns, and marker()/mlabel() for labeling outlier observations by case ID.

Ask about Box Plots in Stata: graph box and over-Groups

Answers are drawn from this guide and the rest of the CASRAI corpus, with a link to every source.

Answers are AI-generated from CASRAI’s own published pages and can be wrong, so check the linked sources before relying on one; your question is logged without personal data — never sold, never used to train a third-party model — to show us what CASRAI is missing, so please do not type personal or confidential details. How we use this

Written and maintained by CASRAI Editorial Board

Last updated

graph box draws vertical box plots and graph hbox draws the identical chart rotated onto its side — every option covered here works the same way in both. over(groupvar) is the option that turns a single overall box plot into one box per category, and Stata marks points beyond the whiskers as outside values using diamond markers by default; marker() and its label sub-options are what let you attach an identifying label — a case ID, a subject number — to those specific outlier points.

This page covers the syntax specifically: what a Stata box plot actually draws, building grouped and nested box plots with over(), and labeling outlier observations so you can trace a flagged point back to a row in your dataset. For the underlying statistics — medians, quartiles, and how to report a distribution in prose — see CASRAI’s guide to descriptive statistics first if you need that background.

What a Stata box plot draws

Both commands draw the standard Tukey box plot: a box spanning the 25th to 75th percentile (the interquartile range, IQR) with a line at the median, whiskers extending to the most extreme non-outlying values, and separate markers — diamonds, by default — for any observation more than 1.5 times the IQR beyond the box edges. Stata calls these outside values, not “outliers,” in its own documentation, and that’s the term used in the marker()/nooutsides options below.

graph box score
graph hbox score

With one variable and no over(), you get a single box summarizing the whole sample. That’s rarely the useful case — most box plots exist specifically to compare a distribution across groups, which is what over() is for.

graph box vs. graph hbox: which one to use

The two commands take identical syntax; only the orientation differs. graph box puts categories along the horizontal axis with boxes running vertically — the familiar default. graph hbox puts categories along the vertical axis with boxes running horizontally.

Use graph hbox when category labels are long or there are more than five or six over() levels: rotated labels under vertical boxes become unreadable, but the same labels read cleanly down the left margin of a horizontal chart. Use graph box for short labels (a handful of treatment arms, yes/no, a few departments) where the vertical default is more familiar to readers.

graph box score, over(department)
graph hbox score, over(department)

Grouped box plots with over()

over(groupvar) is what turns one overall box into one box per category — it does almost all the real work in a Stata box plot, the same role it plays in graph bar:

graph box score, over(group)

You can stack multiple over() specifications to nest categories. The first over() becomes the outer grouping (shown spanning several boxes on the outer axis), and each subsequent over() nests inside it:

graph box score, over(treatment) over(site)

That draws one cluster of boxes per site, with treatment levels as the boxes inside each cluster. Order matters for readability — put the grouping variable with fewer categories on the outside so the labels stay legible.

You can also plot several separate y-variables side by side without over() at all — useful for comparing distributions of genuinely different variables rather than one variable split by group:

graph box pretest posttest

The two forms don’t combine cleanly by default: with multiple y-variables, add over() only if you also want each of those variables broken out further by group, which produces a busier chart than most guides recommend starting with.

Identifying outlier observations

By default a box plot shows you that a point is an outside value without telling you which observation it is. Stata’s marker() option is what attaches a label. Its syntax is marker(#, marker_options marker_label_options), where # numbers the plotted y-variable (almost always 1 when you’re plotting a single variable with over()) and the sub-options come from Stata’s general marker_options and marker_label_options — the same suboption families used on scatter and every other twoway plot. The one that matters here is mlabel(), which names the variable whose values should label each point:

graph box score, over(group) marker(1, mlabel(subject_id))

subject_id should be a variable that uniquely identifies each row — a case number, a participant ID — so that when you see a diamond sitting outside the whiskers, the label next to it tells you exactly which observation to go pull up with list or browse. mlabel() labels every plotted point on box 1, not only the outside values, so an uncluttered box plot with a handful of visible labels is the intended reading: the labels on points inside the whiskers are simply easy to ignore, and the ones that matter are attached to the diamonds sitting outside the box.

Two related options worth knowing:

  • nooutsides suppresses outside-value markers entirely, drawing whiskers out to the full min/max instead — useful if you want a clean box-and-whisker for a presentation and plan to discuss outliers separately.
  • marker_options inside the same marker() call also control the outside-value marker’s symbol, size, and color (e.g. marker(1, msymbol(Oh) mcolor(red) mlabel(subject_id))), which is worth doing whenever the default diamonds are easy to miss against a busy chart.

If you’re plotting multiple y-variables (graph box pretest posttest) rather than one variable with over(), each variable is its own numbered box: marker(1, ...) styles/labels outside values for the first variable, marker(2, ...) for the second, and so on.

A worked example

graph box score, over(department, label(angle(45))) ///
    marker(1, msymbol(Oh) mcolor(red) mlabel(subject_id)) ///
    ytitle("Score") title("Score by Department")

This draws one box per department, angles the category labels 45 degrees so longer department names don’t overlap, styles outside-value markers as hollow red circles instead of the default diamonds, and labels each one with subject_id so a reviewer can trace any flagged point straight back to a specific row.

Frequently asked questions

What counts as an outside value in a Stata box plot?

Any observation more than 1.5 times the interquartile range beyond the nearer box edge (the 75th percentile plus 1.5×IQR on the high side, the 25th percentile minus 1.5×IQR on the low side) — the standard Tukey rule. Stata draws these as separate markers rather than extending the whisker to them.

Can I label only the outside values, not every point?

mlabel() inside marker() labels every point plotted on that box, including ones inside the whiskers — there’s no built-in switch that labels outside values only. In practice this is rarely a problem: labels on interior points sit close to a busy cluster of other marks and are easy to visually ignore, while labels on the isolated diamonds beyond the whiskers stand out on their own.

How is graph box different from graph bar for comparing groups?

graph bar plots a single summary statistic per group (typically the mean) and hides the underlying spread entirely. graph box plots the full distribution — median, IQR, range, and outside values — which is the better choice whenever skew or outliers could be masked by a mean-only bar chart. See CASRAI’s guide to bar charts in Stata for the graph bar syntax.

Does over() work the same way in graph box as in graph bar?

Yes — over() plays an identical role in both commands: it turns one overall plot into one plot per category, and stacking multiple over() options nests categories the same way in both.

Related CASRAI guides

Follow CASRAI

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

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 →

Regulatory Radar

Stop finding out after the fact

$29/month, cancel anytime. Daily digest updates from our analysis, a dashboard holding the same items, and a cited assistant for everything they raise.

  • Federal Register, Federal Register+, Grants.gov, Regulations.gov, NSF News, UKRI, plus CASRAI’s own published content.
  • 44,322 indexed passages, and every answer cites the ones it drew on.