ClementWalter
ClementWalter

Reputation: 5292

Make ggplot2 write the order of magnitude of the axis label only once at the top

I would like to make ggplot2 write only the first part of the scientific notation onto the axis and then add a $x 10^n$ atop the axis for the order of magnitude. Is there a function to do this?

Here is a MWE with a hack to show what I mean:

ggplot(data = data.frame(x = 1:10, y = seq(1, 2, l = 10)*1000), aes(x,y)) + geom_line()

not scaled y axis

while I'd something like:

ggplot(data = data.frame(x = 1:10, y = seq(1, 2, l = 10)*1000), aes(x,y)) + geom_line() +
  scale_y_continuous(breaks = c(1, 1.25, 1.5, 1.75, 2, 2.05)*1000, label = c(1, 1.25, 1.5, 1.75, 2, "x 10^3"))

scaled y axis

As a side question, I have noticed that the axis label becomes quickly to close to the tick labels when they are large. Is there a way to set an automatic spacing in between them ?

Upvotes: 5

Views: 890

Answers (1)

Jon Spring
Jon Spring

Reputation: 66825

Here's a more automated way to execute your hack, in case you want to use similar labeling rules for different data. It will figure out an appropriate power of 10 to use and apply that to the labeling:

y_breaks  = pretty_breaks()(data$y)
y_max_exp = floor(log10(max(y_breaks)))
y_breaks  = c(y_breaks, max(y_breaks) * 1.025)
y_labels  = if_else(y_breaks == max(y_breaks),
                   paste0("x 10^", y_max_exp),
                   as.character(y_breaks / (10^y_max_exp)))

ggplot(data, aes(x,y)) + geom_line() +
  scale_y_continuous(breaks = y_breaks, label = y_labels, minor_breaks = NULL)

enter image description here

Upvotes: 2

Related Questions