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

ggplot Log Scale: scale_y_log10() vs coord_transform()

How to put a ggplot2 axis on a log scale: scale_y_log10() versus coord_transform(), log tick marks, zeros, and deprecated arguments.

Written and maintained by CASRAI Editorial Board

Last updated

In ggplot2 there are two ways to put an axis on a log scale, and they are not interchangeable. scale_x_log10() and scale_y_log10() transform the data before any statistics are computed; coord_transform() transforms the plot after the statistics. For most plots, use the scale. This guide shows both, the current function names (several older ones are deprecated or superseded), and how to draw log-spaced tick marks.

What it is used for in research

A log axis is used when values span several orders of magnitude, so that small and large values can be read on one plot. On a log axis, equal distances are equal ratios, not equal differences. That is why log axes are common for concentrations, counts, and fold changes. For the wider axis toolkit (limits, breaks, labels), see the guide to axes in R; this page goes deeper on the log case only.

Install or access

ggplot2 is an R package distributed through CRAN and documented at ggplot2.tidyverse.org. Install it once and load it in each session:

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

The transformation objects used by scales are provided by the scales package, documented at scales.r-lib.org. For the basics of building and saving plots, see the guide to ggplot2 plots in R.

Step-by-step: put an axis on a log scale

1. Log the y axis with scale_y_log10()

Add the scale to the plot. The same call works for x with scale_x_log10().

ggplot(mtcars, aes(disp, mpg)) +
  geom_point() +
  scale_y_log10()

According to the ggplot2 reference, scale_x_log10() and scale_y_log10() are variants of the continuous scales that set the transform argument, and any other arguments are passed on to scale_(x|y)_continuous(). So breaks, labels, limits and name work as they do on any continuous scale.

2. Make a log-log plot

Add both scales:

ggplot(mtcars, aes(disp, mpg)) +
  geom_point() +
  scale_x_log10() +
  scale_y_log10()

3. Use another base or transformation

The transform argument of the continuous scales accepts a transformation name. The built-in names include “log”, “log10”, “log1p” and “log2”, and the default is “identity”.

ggplot(mtcars, aes(disp, mpg)) +
  geom_point() +
  scale_x_continuous(transform = "log2")

The older argument name trans is deprecated in favour of transform. A custom transformation can be built with scales::new_transform().

4. Alternative: coord_transform()

The coordinate version transforms the plot space after the statistics have run:

ggplot(diamonds, aes(carat, price)) +
  geom_point() +
  coord_transform(x = "log10", y = "log10")

The ggplot2 reference for coord_transform() uses the same transformation of both axes. The older function coord_trans() is deprecated; use coord_transform().

5. Draw log-spaced tick marks

To replace ordinary tick marks with ticks at intervals in log10 space, use guide_axis_logticks() through the guide argument:

ggplot(diamonds, aes(carat, price)) +
  geom_point() +
  scale_x_log10(guide = "axis_logticks") +
  scale_y_log10(guide = "axis_logticks")

The function takes long, mid and short arguments (defaults 2.25, 1.5 and 0.75) for the three tick lengths. With coord_transform(x = "log10", y = "log10") you set the guides through guides() instead.

Scale or coordinate transform: which to use

The difference is when the transformation happens. The ggplot2 reference states that coord_transform() occurs after statistical transformation, while scale transformations are applied before it. Anything computed by a stat (a fitted smoother, bin counts, a density) is therefore computed on the transformed values when you use a scale, and on the original values when you use a coordinate transform. The reference also warns that with a coordinate transform there is no guarantee that straight lines will continue to be straight.

Setup When the transformation happens Log tick setting
scale_y_log10() Before statistics guide = "axis_logticks" on the scale; annotation_logticks, if you use it, needs scaled = TRUE (the default)
coord_transform(y = "log10") After statistics Set the guide through guides(); annotation_logticks needs scaled = FALSE
Data already passed through log10() by you Before ggplot2 sees it annotation_logticks with scaled = TRUE; for guide_axis_logticks() set prescale.base

Sources for the table: the reference pages for coord_transform, guide_axis_logticks and annotation_logticks, listed under Sources.

Output and how to read it

Read a log axis as ratios. Moving the same distance along the axis always multiplies the value by the same factor. Gridlines and ticks are therefore not evenly spaced in value, and the lowest visible value is not zero. Label the axis so the reader knows it is logarithmic, and say which base you used when it is not 10.

Troubleshooting

Values of zero or below do not appear

A logarithm is not defined for zero or negative numbers, so those observations cannot be placed on a log axis. If your data contain zeros, one documented alternative is the pseudo-log transformation, which the scales documentation describes as defined for all real numbers: scale_y_continuous(transform = scales::transform_pseudo_log()). When an axis includes zero or negative limits, guide_axis_logticks() has a negative.small argument that sets the smallest absolute value that gets ticks, with mirrored ticks for negative values.

An old script uses trans = “log10” and warns

The trans argument is deprecated. Replace it with transform, for example scale_y_continuous(transform = "log10"). Likewise replace coord_trans() with coord_transform().

A fitted line looks curved after coord_transform()

This is the documented behaviour of a coordinate transform: straight lines are not guaranteed to stay straight, because the transformation is applied after the stat. If you want the fit computed on logged values, use scale_x_log10() or scale_y_log10() instead.

Log ticks are in the wrong place on pre-logged data

The documentation says to set prescale.base in guide_axis_logticks() only if the data have already been log-transformed. For data transformed with log2(), use guide_axis_logticks(prescale.base = 2); the reference notes that this axis uses log10 space for placement, not log2.

annotation_logticks() is superseded

The ggplot2 reference states that annotation_logticks() is superseded by guide_axis_logticks(). If you still use it, scaled = TRUE is for data passed through log10() or scale_y_log10(), and scaled = FALSE is for coord_transform(y = "log10"). Its base argument is described as probably sensible only for base 10, and ticks drawn outside the panel need coord_cartesian(clip = "off").

Free alternatives in base R

Base R graphics ship with R, so no package is needed. The two approaches map as follows:

Task Base R ggplot2
Log x axis plot(x, y, log = "x") scale_x_log10()
Log y axis plot(x, y, log = "y") scale_y_log10()
Both axes plot(x, y, log = "xy") scale_x_log10() + scale_y_log10()

The log argument of base R plot() takes “x”, “y” or “xy” (see the R manual page for plot.default). For the plot types this is most often applied to, see scatterplots in R and histograms in R, and for text on the plot see labels and legends in ggplot2.

FAQ

How do I make the y axis logarithmic in ggplot2?

Add scale_y_log10() to the plot. It is a variant of scale_y_continuous() with the transform argument set to log10.

What is the difference between scale_y_log10() and coord_transform(y = “log10”)?

The scale transforms the data before statistics are computed; the coordinate transform is applied after them, and straight lines may not stay straight.

Is trans still valid in scale_y_continuous()?

It is deprecated in favour of transform.

Can I use a base other than 10?

Yes. The continuous scales accept transformation names including “log2” and “log”; the dedicated shortcut is for base 10 only.

Sources

Follow CASRAI

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

Ask CASRAI · free to try

Ask about ggplot Log Scale: scale_y_log10() vs coord_transform()

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 →