164

I'm using R and ggplot to draw a scatterplot of some data, all is fine except that the numbers on the y-axis are coming out with computer style exponent formatting, i.e. 4e+05, 5e+05, etc. This is unacceptable to me, so I want to get it to display them as 500,000, 400,000, and so on. Getting a proper exponent notation would also be acceptable.

The code for the plot is as follows:

p <- ggplot(valids, aes(x=Test, y=Values)) +
  geom_point(position="jitter") +
  facet_grid(. ~ Facet) +
  scale_y_continuous(name="Fluorescent intensity/arbitrary units") +
  scale_x_discrete(name="Test repeat") +
  stat_summary(fun.ymin=median, fun.ymax=median, fun.y=median, geom="crossbar")

Any help much appreciated.

1
  • 40
    Be careful of describing ggplot default options as "obviously unacceptable". You mean you have a personal preference for a different format. A number in the format 4e+05 is scientific notation, and would be the preferred formatting in a wide variety of applications.
    – Andrie
    Commented Jul 23, 2012 at 10:13

5 Answers 5

168

Another option is to format your axis tick labels with commas is by using the package scales, and add

 scale_y_continuous(name="Fluorescent intensity/arbitrary units", labels = comma)

to your ggplot statement.

If you don't want to load the package, use:

scale_y_continuous(name="Fluorescent intensity/arbitrary units", labels = scales::comma)
3
  • 16
    Amazing that such a trivial issue requires to load a new package.
    – luchonacho
    Commented Jul 5, 2017 at 13:59
  • FYI, this also works with scale_y_log10(labels = scales::comma), and I'm assuming other scales in ggplot2. Great tips! Commented Sep 19, 2017 at 18:46
  • 7
    Very late to this, but you can pass any function to the labels argument so scale_x_continuous(labels = function(x) format(x, big.mark = ",")) Commented Feb 17, 2021 at 12:23
84

I also found another way of doing this that gives proper 'x10(superscript)5' notation on the axes. I'm posting it here in the hope it might be useful to some. I got the code from here so I claim no credit for it, that rightly goes to Brian Diggs.

fancy_scientific <- function(l) {
     # turn in to character string in scientific notation
     l <- format(l, scientific = TRUE)
     # quote the part before the exponent to keep all the digits
     l <- gsub("^(.*)e", "'\\1'e", l)
     # turn the 'e+' into plotmath format
     l <- gsub("e", "%*%10^", l)
     # return this as an expression
     parse(text=l)
}

Which you can then use as

ggplot(data=df, aes(x=x, y=y)) +
   geom_point() +
   scale_y_continuous(labels=fancy_scientific) 
4
  • 11
    If you don't want 0 to be printed as "0 x 10⁺⁰", add the following below the format(...) line: l <- gsub("0e\\+00","0",l) Commented Sep 15, 2015 at 10:12
  • 1
    If you want to special case other things, it's easiest to add more gsub() directly after the format(), while testing what format() returns for your case in a separate console. Commented Sep 15, 2015 at 10:15
  • 5
    add this before last gsub command: # remove + after exponent, if exists. E.g.: (3x10^+2 -> 3x10^2) l <- gsub("e\\+","e",l) and after it: # convert 1x10^ or 1.000x10^ -> 10^ l <- gsub("\\'1[\\.0]*\\'\\%\\*\\%", "", l) to make it in format usually used in papers.
    – John_West
    Commented Feb 23, 2016 at 14:08
  • Asked a followup question to this answer here: stackoverflow.com/questions/63477686/… Commented Aug 19, 2020 at 0:26
47
x <- rnorm(10) * 100000
y <- seq(0, 1, length = 10)
p <- qplot(x, y)
library(scales)
p + scale_x_continuous(labels = comma)
2
  • When I try this I get an error that formatter is an unused argument? Does it need another package or something? Commented Jul 23, 2012 at 12:12
  • 4
    I changed the code to include library(scales) and use comma which should work better than the function that I had before. Commented Jul 23, 2012 at 12:21
18

I'm late to the game here but in-case others want an easy solution, I created a set of functions which can be called like:

 ggplot + scale_x_continuous(labels = human_gbp)

which give you human readable numbers for x or y axes (or any number in general really).

You can find the functions here: Github Repo Just copy the functions in to your script so you can call them.

0
12

I find Jack Aidley's suggested answer a useful one.

I wanted to throw out another option. Suppose you have a series with many small numbers, and you want to ensure the axis labels write out the full decimal point (e.g. 5e-05 -> 0.0005), then:

NotFancy <- function(l) {
 l <- format(l, scientific = FALSE)
 parse(text=l)
}

ggplot(data = data.frame(x = 1:100, 
                         y = seq(from=0.00005,to = 0.0000000000001,length.out=100) + runif(n=100,-0.0000005,0.0000005)), 
       aes(x=x, y=y)) +
     geom_point() +
     scale_y_continuous(labels=NotFancy) 
2
  • 35
    This can be shortened by using an anonymous function: scale_y_continuous(labels=function(n){format(n, scientific = FALSE)}) Why there is no pre-defined formatter like that, hell knows.
    – eMPee584
    Commented Apr 23, 2015 at 20:21
  • 3
    @eMPee584 Sorry for bumping this old reply but please consider making this an answer, so it can be found more easily :) Your comment has more upvotes than some of the actual answers. Commented Aug 27, 2020 at 7:29

Not the answer you're looking for? Browse other questions tagged or ask your own question.