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

Strip Plot: What It Is and How to Make One in Python and R

What a strip (jitter) plot shows, when to use it, and equivalent seaborn, Plotly and ggplot2 code, plus strip vs swarm plots.

Written and maintained by CASRAI Editorial Board

Last updated

A strip plot (also called a strip chart or jitter plot) is a scatterplot in which one variable is categorical: every observation is drawn as its own point, and the points in each category are spread slightly sideways so they do not sit on top of each other. It is used to show all the raw data for each group, alone or beside a box plot or violin plot. This guide covers what the chart shows, how to build it in Python (seaborn and Plotly Express) and R (ggplot2), and how to read it.

What is a strip plot? (strip chart meaning)

The seaborn documentation describes stripplot as a categorical scatterplot that uses jitter to reduce overplotting. It can be drawn on its own or alongside a box or violin plot to show each observation together with a summary of the underlying distribution. Plotly’s documentation calls a strip chart a box plot with the points showing and no box.

What is a chart strip?

“Chart strip” is a loose search phrase for the same thing: the strip chart. Each category gets a narrow vertical (or horizontal) band, and each data value in that category is one marker within the band. The value axis carries the data; the position across the band is random jitter and carries no information.

Jitter plot

“Jitter plot” names the technique rather than a different chart. Jitter is a small random displacement applied to each point to handle overplotting caused by discrete positions (ggplot2 documents geom_jitter in exactly these terms). In seaborn, jitter is applied along the categorical axis only.

When to use a strip plot

  • You want every observation visible. Unlike a box plot, nothing is summarised away, so sample size, gaps and outliers are all apparent.
  • You are comparing a numeric outcome across a few groups (for example, one numeric measurement per condition).
  • You want to annotate a summary plot with the raw data. Seaborn’s documentation presents the strip plot as a companion to violin plots and box plots; see also box plots in R.

If both axes are numeric and continuous, use an ordinary scatterplot instead (see scatterplots in R); jitter is meant for a categorical axis.

Strip plot vs swarm plot

Seaborn offers two related categorical scatterplots. stripplot jitters points randomly. swarmplot instead adjusts points, only along the categorical axis, so that they do not overlap. The swarmplot documentation notes that it does not scale well to large numbers of observations; when space runs out, points are forced to overlap in the “gutters” of each swarm and a warning is issued suggesting smaller markers or stripplot.

Question Strip plot Swarm plot
How points are separated Random jitter along the categorical axis Adjustment along the categorical axis so points do not overlap
Large numbers of observations Points may still overlap Does not scale well; may warn that points cannot be placed

Install or access

All three libraries are free, open-source packages from their own projects: seaborn (built on matplotlib), Plotly for Python and ggplot2 (part of the tidyverse). For base R, see stripchart() in R.

How to make a strip plot in Python

Seaborn

  1. Import the library and load an example dataset: import seaborn as sns, then tips = sns.load_dataset("tips").
  2. Draw the plot: sns.stripplot(data=tips, x="day", y="total_bill").
  3. To split by a second variable, add hue and dodge=True: sns.stripplot(data=tips, x="total_bill", y="day", hue="sex", dodge=True).
  4. To turn jitter off, pass jitter=False.
  5. To facet, use sns.catplot(data=tips, x="time", y="total_bill", hue="sex", col="day", aspect=.5) rather than a FacetGrid.

How do I create a strip chart in Python with Plotly?

  1. import plotly.express as px
  2. df = px.data.tips()
  3. fig = px.strip(df, x='day', y='tip')
  4. fig.show()

How to make a strip plot in R

In ggplot2, a jittered strip plot is a geom_point with jittered position. geom_jitter() is documented as a shortcut for geom_point(position = "jitter"). The signature is geom_jitter(mapping = NULL, data = NULL, stat = "identity", position = "jitter", ..., width = NULL, height = NULL, na.rm = FALSE, show.legend = NA, inherit.aes = TRUE). The documentation’s example is:

library(ggplot2)
ggplot(mpg, aes(cyl, hwy)) + geom_jitter(width = 0.25)

Jitter is added in both directions, so the total spread is twice the width or height value; the default is 40% of the data resolution. For the base R function, with its jitter, overplot and stack methods, see stripchart() in R.

Equivalent calls across tools

Tool Call Separation method
seaborn sns.stripplot(data=tips, x="day", y="total_bill") Random jitter (default jitter=True)
Plotly Express px.strip(df, x='day', y='tip') Strip chart of points without a box
ggplot2 geom_jitter(width = 0.25) Random jitter via position = "jitter"
Base R stripchart() See the stripchart guide

Output and how to read it

  • Read the value axis only. Position within a strip, across the category axis, is random jitter, so two points side by side are not “closer” in any data sense.
  • Density shows as crowding. Dense stretches of a strip mean many observations at those values; with heavy overlap, reduce marker size or pair the plot with a violin or box plot.
  • Jitter is random. Two runs can differ in point positions. geom_jitter has no seed argument, so set a random seed in your own code if you need identical figures each run.

Troubleshooting

  • Points have no outline in seaborn. The linewidth default is 0, so marker edges are invisible; set linewidth and edgecolor to see them.
  • Legend duplicates the axis when hue repeats the category. Use legend=False, as in sns.stripplot(data=tips, x="total_bill", y="day", hue="day", legend=False).
  • Numeric categories are evenly spaced. By default, seaborn places categorical values at ordinal positions 0..n. Set native_scale=True to keep numeric or datetime values on their original scale (this parameter, with log_scale, formatter and legend, arrived in seaborn 0.13.0; the documentation read is 0.13.2).
  • Orientation. orient accepts “v”, “h”, “x” or “y” (“x”/”y” added in 0.13.0).
  • Points overlap too much. Lower size (marker radius in points, default 5) or, in ggplot2, adjust width.

Free alternatives and companions

Chart What it adds or changes Source
Swarm plot Points adjusted so they do not overlap; does not scale well to large samples seaborn swarmplot docs
Box plot Plotly describes a strip chart as a box plot with points and no box Plotly box plot docs
Violin plot Documented as a companion to strip points seaborn stripplot docs; seaborn violin plots
Scatterplot For two numeric variables, no categorical axis scatterplots in R

FAQ

When to use a strip plot?

Use it when you have a numeric measurement across a small number of categories and want every observation visible, either alone or on top of a box or violin plot.

What is a chart strip?

It is usually a strip chart: a categorical scatterplot where each category is a narrow band containing one point per observation.

How to make a strip plot in R?

With ggplot2, use geom_jitter() (a shortcut for geom_point(position = "jitter")), for example ggplot(mpg, aes(cyl, hwy)) + geom_jitter(width = 0.25). In base R, use stripchart().

How do I create a strip chart in Python?

Use sns.stripplot(data=tips, x="day", y="total_bill") in seaborn or px.strip(df, x='day', y='tip') in Plotly Express.

Strip plot vs swarm plot: which should I use?

Swarm plots avoid overlap but do not scale well to large samples; strip plots use random jitter and can overlap.

Sources

Follow CASRAI

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

Ask CASRAI · free to try

Ask about Strip Plot: What It Is and How to Make One in Python and R

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 →