ggplot2 scale_y_log10() in R: Log-Transform the Y Axis

The scale_y_log10() function in ggplot2 log10-transforms the Y axis. It is the y-axis sister of scale_x_log10() and essential for visualizing skewed dependent variables.

⚡ Quick Answer
+ scale_y_log10()
+ scale_y_log10(labels = scales::comma)
+ scale_y_log10(breaks = c(1, 10, 100, 1000))
+ scale_y_continuous(trans = "log10")     # equivalent
+ scale_y_log10(labels = scales::dollar)

Need explanation? Read on for examples and pitfalls.

📊 Is scale_y_log10() the right tool?
STARTlog10 y axisscale_y_log10()natural logscale_y_continuous(trans = "log")sqrtscale_y_sqrt()both axes logscale_x_log10() + scale_y_log10()arbitraryscale_y_continuous(trans = "...")

What scale_y_log10() does in one sentence

scale_y_log10() log10-transforms the Y axis values, equivalent to scale_y_continuous(trans = "log10"). Useful for skewed positive y values like revenue, prices, or counts.

Syntax

scale_y_log10(name = waiver(), breaks = waiver(), labels = waiver(), ...). Same as scale_y_continuous.

Run live
Run live, no install needed. Every R block on this page runs in your browser. Click Run, edit the code, re-run instantly. No setup.
RLog y for diamond price
library(ggplot2) library(scales) ggplot(diamonds, aes(carat, price)) + geom_point(alpha = 0.1) + scale_y_log10(labels = dollar)

  
Tip
For revenue, prices, populations, and counts, scale_y_log10 often reveals patterns that linear y hides. Skewed positive data is the natural use case.

Five common patterns

1. Standard log y

RLog scale
+ scale_y_log10()

  

2. Dollar-formatted log labels

RMoney on log scale
+ scale_y_log10(labels = scales::dollar)

  

3. Custom breaks

RPowers of 10
+ scale_y_log10(breaks = c(1, 10, 100, 1000))

  

4. Combined with x log

RLog-log plot
+ scale_x_log10() + scale_y_log10()

  

5. Pseudo-log for zero values

RWhen data includes 0
+ scale_y_continuous(trans = scales::pseudo_log_trans(base = 10))

  

pseudo_log handles 0 and negatives; pure log10 cannot.

Key Insight
Log y is the standard fix for skewed dependent variables. If a histogram has a long right tail, log-transforming reveals patterns hidden by the spread.

scale_y_log10() vs scale_y_continuous(trans=) vs pseudo_log

Function Transform Handles 0
scale_y_log10() Log10 No
scale_y_continuous(trans = "log10") Same No
scale_y_sqrt() Sqrt Yes
scales::pseudo_log_trans() Log near zeros, linear at 0 Yes

A practical workflow

For skewed y, log10 is the default. For data with zeros, pseudo_log is a safer fallback.

RInteractive R
ggplot(events, aes(date, count)) + geom_line() + scale_y_log10(labels = scales::comma)

  

For revenue charts:

RInteractive R
ggplot(sales, aes(month, revenue)) + geom_col() + scale_y_log10(labels = scales::dollar)

  

Common pitfalls

Pitfall 1: zeros and negatives drop. Log fails on non-positive y. Use pseudo_log_trans or filter zeros.

Pitfall 2: misleading bar charts. Bar charts on log y axis distort proportions; readers easily misinterpret. Avoid log y on bar charts when possible.

Warning
scale_y_log10() transforms the data BEFORE stats run. Regression / smoothers fit on log values. If you only want log VISUAL, use coord_trans(y = "log10") instead.

Try it yourself

Try it: Plot mtcars hp vs disp on log y. Save to ex_plot.

RYour turn: log y
ex_plot <- mtcars |> ggplot(aes(disp, hp)) + geom_point() + # your code here

  
Click to reveal solution
RSolution
ex_plot <- ggplot(mtcars, aes(disp, hp)) + geom_point() + scale_y_log10()

  

Explanation: Log10 transforms the y axis.

After mastering scale_y_log10, look at:

  • scale_x_log10(): same for x
  • scale_y_sqrt(): square root y
  • coord_trans(y = "log10"): visual-only transform
  • scales::pseudo_log_trans(): handles zero
  • scales::label_log(): 10^N labels

FAQ

What does scale_y_log10 do in ggplot2?

scale_y_log10() log10-transforms the Y axis. Shortcut for scale_y_continuous(trans = "log10").

Can I use scale_y_log10 with zero values?

No. Log fails on 0 and negatives. Use scale_y_continuous(trans = scales::pseudo_log_trans()) to handle zeros.

What is the difference between scale_y_log10 and coord_trans(y = "log10")?

scale_y_log10 transforms data before stats. coord_trans transforms only the visual after stats. Different for regression and smoothers.

Why does my bar chart on log y look weird?

Log scales distort bar proportions. Readers misinterpret heights. Avoid log y on bars; use it for points and lines.

Can I add log y on top of an existing plot?

Yes. + scale_y_log10() after the geoms. Or chain with other scale modifications.