When using knitr
inline, it typos $\Sexpr{2.5e3}$
with $2.5 \times 10^3$
which is pretty nice. However I miss the fact that this does not work for the labels in plots. I guess knitr thinks there are character and not numeric. Is there a way to change that ?

- 4,814
- 1
- 32
- 54
-
this is not going to be easy. You should definitely look into using the tikz device and something like http://stackoverflow.com/questions/11610377/how-do-i-change-the-formatting-of-numbers-on-an-axis-with-ggplot – Ben Bolker Jun 07 '16 at 15:09
-
indeed I was hoping that I could tweek the `knit_hooks$get("inline")` by adding somewhere a `if(!is.na(as.numeric(x)) x <- as.numeric(x)` but I can't find the right place to put this – ClementWalter Jun 07 '16 at 15:27
-
my point is that I seriously doubt there's any *automatic* way to do this for plots. If you want to use scientific notation for plots you'll need to specify a little bit more about how you want to proceed, in particular: (1) native "plotmath" formatting or LaTeX/tikz? (2) base, lattice, or ggplot graphics? `sfsmisc::eaxis` is useful. – Ben Bolker Jun 07 '16 at 15:43
-
I use `ggplot2` and `dev=tikz`; I use Latex notation everywhere in my labels already and works fine – ClementWalter Jun 07 '16 at 15:58
-
But looking at the `.tikz` generated files, I think I got your point about "no automatic solution". I may have a try with `trans_format` functions of `scales` package – ClementWalter Jun 07 '16 at 16:04
2 Answers
As I discussed in the comments, getting this to happen automatically isn't so easy, but it's not too hard to get your scales translated. sfsmisc::eaxis()
is a good solution for base plots. Here are some ggplot
-style solutions:
If you want to use native ?plotmath
-style formatting:
##scale function for plotting y-axis labels
scientific_10 <- function(x) {
s <- scales::scientific_format()(x)
## substitute for exact zeros
s[s=="0e+00"] <- "0"
## regex: [+]? = "zero or one occurrences of '+'"
parse(text=gsub("e[+]?", " %*% 10^", s ))
}
Or if you're using LaTeX/TikZ (I'm using Hmisc::latexSN()
here. It's a 3-line function, so you could just copy it if you wanted to avoid dependencies or hack it):
scientific_latex <- function(x,scipen=-2) {
require(Hmisc)
op <- options(scipen=scipen) ## encourage use of scientific notation
on.exit(options(op)
s <- paste0("$",Hmisc::latexSN(x),"$")
}
Example:
set.seed(101)
d <- data.frame(trait=runif(1000),
time=runif(1000,0,1000))
library(ggplot2); theme_set(theme_bw())
## make plot
breaks.y<-seq(from=0, to=1000, by=200)
g0 <- ggplot(d,aes(trait,time))+
geom_point()
plotmath
style:
g0 + scale_y_continuous(label=scientific_10,
breaks=breaks.y, limits=c(0,1000))
TikZ:
g0 + scale_y_continuous(label=scientific_latex,
breaks=breaks.y, limits=c(0,1000))

- 211,554
- 25
- 370
- 453
-
quite funny indeed I came with sort of the same solution, but copy/pasting the `inline.hook` functions of `knitr` instead of your `scientific_latex` : `scientific_latex <- function (x) { if (is.numeric(x)) { x = knitr:::format_sci(x, "latex") i = grep("[^0-9.,]", x) x[i] = sprintf("\\ensuremath{%s}", x[i]) if (getOption("OutDec") != ".") x = sprintf("\\text{%s}", x) } if (is.numeric(x)) x = round(x, getOption("digits")) x }` – ClementWalter Jun 07 '16 at 17:05
-
1if your solution is better than mine, or different in some way (i.e. an alternative that some future reader might be interested in), feel free to post it as an alternative answer to your own question (self-answering is encouraged on SO) – Ben Bolker Jun 07 '16 at 17:15
Well after @Ben Bolker comment, I add also my solution here, maybe more in the knitr
mood as it is only sort of a hack to apply the knitr
rendering to the axis label. Especially in a knitr
document one often sets in the beginning digits
and scipen
and expects it to be applied everywhere.
So define in the setup chunk the function:
inline_hook <- function (x) {
if (is.numeric(x)) {
x = knitr:::format_sci(x, "latex")
i = grep("[^0-9.,]", x)
x[i] = sprintf("\\ensuremath{%s}", x[i])
if (getOption("OutDec") != ".")
x = sprintf("\\text{%s}", x)
}
if (is.numeric(x)) x = round(x, getOption("digits"))
x
}
which is just a mix of knitr::.inline.hook.tex
and knitr:::.inline.hook
with the final collapse
discarded. Then modify the default behaviour of scale_y_continous
according to this post:
scale_y_continuous <- function(...) ggplot2:::scale_y_continuous(..., labels=inline_hook)
Then from the above example:
set.seed(101)
d <- data.frame(trait=runif(1000),
time=runif(1000,0,1000))
library(ggplot2); theme_set(theme_bw())
## make plot
breaks.y<-seq(from=0, to=1000, by=200)
g0 <- ggplot(d,aes(trait,time))+
geom_point()
g0
I get by default:
which is exactly what knitr
does to number given inline.

- 1
- 1

- 4,814
- 1
- 32
- 54