Written and maintained by CASRAI Editorial Board
Last updated
An axis in R is the scale along the bottom or side of a plot: its title, its range, where the tick marks sit and what they are labelled. R has two common ways to draw plots, base R graphics (plot(), axis()) and the ggplot2 package (scale_x_continuous(), coord_cartesian()). Both let you set a title, limits, breaks and labels; they differ in what happens to data that falls outside the limits, which is the most common source of confusing results.
What it is used for in research
Axes decide how a reader judges a figure. A research figure usually needs a title that names the variable and its unit, a range that shows all of the data (or a clearly labelled zoom), tick marks at meaningful values, and sometimes a logarithmic scale for values that span orders of magnitude. For wider figure practice, see the guide on building, styling and saving plots with ggplot2; this page covers the axis itself.
Install or access
Base R graphics ship with R, so plot() and axis() need no extra installation. The ggplot2 functions come from the ggplot2 package, installed from CRAN once and loaded in each session:
install.packages("ggplot2")
library(ggplot2)
The function arguments below follow the R graphics manual and the ggplot2 reference site, both listed under Sources.
Step-by-step: set the axis title, limits, breaks and labels
The examples use mtcars, a data set included with R.
- Set the axis titles. In base R, pass
xlabandylabtoplot(); the R manual says each is a label for the axis and defaults to a description of the plotted data. In ggplot2, thenameargument of a scale is “used as the axis or legend title”.# base R plot(mtcars$wt, mtcars$mpg, xlab = "Weight (1000 lb)", ylab = "Miles per gallon") # ggplot2 ggplot(mtcars, aes(wt, mpg)) + geom_point() + scale_x_continuous(name = "Weight (1000 lb)") + scale_y_continuous(name = "Miles per gallon") - Set the limits. In base R,
xlimandylimare the limits (x1, x2) of the plot, and the manual notes that x1 > x2 is allowed and gives a reversed axis. In ggplot2,limitsis “a numeric vector of length two”, withNAstanding for the existing minimum or maximum;xlim()andylim()are shortcuts.# base R plot(mtcars$wt, mtcars$mpg, xlim = c(0, 6), ylim = c(0, 40)) # ggplot2 ggplot(mtcars, aes(wt, mpg)) + geom_point() + scale_x_continuous(limits = c(0, 6)) + scale_y_continuous(limits = c(0, NA))See the decision table in the next section before using ggplot2 limits on a plot that also draws a summary layer.
- Set the breaks and labels. In ggplot2,
breakssets the tick positions andlabelsis “a character vector giving labels (must be same length as breaks)”;n.breaksasks for an approximate number of ticks instead. In base R,axis()takesat(tick positions) andlabels.# ggplot2 ggplot(mtcars, aes(wt, mpg)) + geom_point() + scale_x_continuous(breaks = c(2, 3, 4, 5), labels = c("two", "three", "four", "five")) - Use a logarithmic scale. In base R,
log = "x","y"or"xy"inplot()makes the named axes logarithmic. In ggplot2,scale_x_log10()andscale_y_log10()pass their arguments toscale_(x|y)_continuous()and set the transformation. The continuous scales take the transformation intransform; the oldertransargument is deprecated.# base R plot(mtcars$disp, mtcars$mpg, log = "x") # ggplot2 ggplot(mtcars, aes(disp, mpg)) + geom_point() + scale_x_log10() - Hide or replace a base R axis. The graphical parameters
xaxt(sides 1 and 3) andyaxt(sides 2 and 4) control whether an axis is drawn at all. Setxaxt = "n", then add your own axis withaxis(side, at, labels), wheresideis 1 = below, 2 = left, 3 = above and 4 = right.plot(mtcars$wt, mtcars$mpg, xaxt = "n") axis(1, at = c(2, 3, 4, 5), labels = c("two", "three", "four", "five"))If
labelsis not logical, supplyatwith the same length. The orientation of tick labels is controlled bylas.
Output and how to read it
In ggplot2 there are two different ways to change the visible range, and they do not do the same thing to your data.
| Method | What the documentation says | Effect on the data |
|---|---|---|
limits in a scale, xlim(), ylim(), lims() |
“Setting limits on positional scales will remove data outside of the limits”; by default values outside the limits are replaced with NA | Data outside the range is discarded. The documentation warns this “can produce unintended results”. |
oob = scales::squish in a scale |
The default oob is scales::censor(), which replaces out-of-bounds values with NA; scales::squish() squishes them into the range |
Out-of-range values are kept and pulled to the edge of the range instead of becoming NA. |
coord_cartesian(xlim, ylim) |
“Setting limits on the coordinate system will zoom the plot” and “will not change the underlying data like setting limits on a scale will” | A visual zoom; the data is unchanged. |
The ggplot2 documentation recommends coord_cartesian() to change the limits without dropping data observations. Its expand = TRUE default adds a small expansion so data and axes do not overlap; scale limits likewise expand by 5% on each side for continuous variables by default, and expand in the scale changes that.
ggplot(mtcars, aes(wt, mpg)) + geom_point() +
coord_cartesian(xlim = c(2, 4), ylim = c(15, 30))
To read a plot with a changed axis, check three things: the axis title (does it name the variable and unit), the limits (are any observations outside them), and whether the scale is linear or logarithmic, because equal distances on a log axis are equal ratios, not equal differences.
Troubleshooting
Points or bars disappear after setting limits in ggplot2
Scale limits remove data outside the range (replaced with NA by default). If you only want to look at part of the plot, use coord_cartesian() instead; if you want to keep out-of-range values at the edge, set oob = scales::squish in the scale.
Labels and breaks do not match
In scale_x_continuous() and scale_y_continuous(), labels must be the same length as breaks. Supply both with equal lengths, or leave labels unset.
The axis is missing in base R
Check whether xaxt = "n" or yaxt = "n" is set, or axes = FALSE. The R manual states that axes controls both axes, and that xaxt or yaxt suppress just one.
The log scale warns about values
A logarithmic axis cannot show values of zero or below. The R manual’s own example shows plot(y ~ x, log = "x") giving a warning that x values less than or equal to zero are omitted.
An old script uses trans
The trans argument of the continuous scales is deprecated in favour of transform.
Free alternatives
Base R graphics and ggplot2 are the two approaches covered above. Which task maps to which argument:
| Task | Base R | ggplot2 |
|---|---|---|
| Axis title | xlab, ylab in plot() |
name in scale_x_continuous() / scale_y_continuous() |
| Limits | xlim, ylim in plot() |
limits in the scale, xlim() / ylim(), or coord_cartesian() to zoom |
| Tick positions and labels | axis(side, at, labels) |
breaks and labels in the scale |
| Log scale | log = "x", "y" or "xy" |
scale_x_log10(), scale_y_log10(), or transform |
For the look of the axis (text size, lines, grid), see ggplot themes. Axis choices also matter for specific plot types: plotting a line in R, barplot in R and histograms in R.
FAQ
What is an axis in R?
It is the labelled scale along one side of a plot. In base R graphics it is drawn by plot() or axis(); in ggplot2 it is controlled by the x and y scales, such as scale_x_continuous().
How do I change the axis limits in R?
In base R, pass xlim and ylim to plot(). In ggplot2, use limits in a scale or xlim() / ylim() to remove data outside the range, or coord_cartesian(xlim, ylim) to zoom without removing data.
How do I change the axis labels in R?
Use xlab and ylab in base R, or name in the ggplot2 scale for the axis title; use labels (with matching breaks) for the tick labels.
How do I remove an axis in base R?
Set xaxt = "n" or yaxt = "n" in plot(); use axes = FALSE to remove both.
Sources
All pages checked on 2026-10-29.
- ggplot2 reference, Position scales for continuous data (scale_continuous): https://ggplot2.tidyverse.org/reference/scale_continuous.html
- ggplot2 reference, Set scale limits (lims): https://ggplot2.tidyverse.org/reference/lims.html
- ggplot2 reference, Cartesian coordinates (coord_cartesian): https://ggplot2.tidyverse.org/reference/coord_cartesian.html
- R documentation, Add an Axis to a Plot (axis): https://stat.ethz.ch/R-manual/R-devel/library/graphics/html/axis.html
- R documentation, The Default Scatterplot Function (plot.default): https://stat.ethz.ch/R-manual/R-devel/library/graphics/html/plot.default.html







