如何使用带有ggplot2和比例的指数格式化轴标签?

时间:2012-05-25 23:05:02

标签: r ggplot2

使用新版ggplot2和scale,我无法弄清楚如何以科学计数法获得轴标签。例如:

x <- 1:4
y <- c(0, 0.0001, 0.0002, 0.0003)

dd <- data.frame(x, y)

ggplot(dd, aes(x, y)) + geom_point()

给了我

Example ggplot with scales

我希望轴标签为0,5 x 10 ^ -5,1 x 10 ^ -4,1.5 x 10 ^ -4等。我无法找出{{1的正确组合和scale_y_continuous()(至少我认为这些是我需要的)。

math_format() log会转换轴,这是我不想要的。 scale_y_log10()只给了我10 ^ 0,10 ^ 5e-5等等。我明白为什么后者会给出结果,但这不是我想要的。

我正在使用ggplot2_0.9.1和scales_0.2.1

7 个答案:

答案 0 :(得分:26)

我改编了Brian的答案,我想我得到了你想要的东西。

只需在scientific_10()函数中添加一个解析()(并将'x'更改为正确的'times'符号),最后就会得到:

x <- 1:4
y <- c(0, 0.0001, 0.0002, 0.0003)

dd <- data.frame(x, y)

scientific_10 <- function(x) {
  parse(text=gsub("e", " %*% 10^", scales::scientific_format()(x)))
}

ggplot(dd, aes(x, y)) + geom_point()+scale_y_continuous(label=scientific_10)

enter image description here

你可能仍然希望改进这个功能,以便更优雅地处理0,但我认为就是这样!

答案 1 :(得分:20)

根据对已接受解决方案的评论,OP希望将指数格式化为指数。可以使用 scale 包中的trans_formattrans_breaks函数完成此操作:

    library(ggplot2)
    library(scales)

    x <- 1:4
    y <- c(0, 0.0001, 0.0002, 0.0003)
    dd <- data.frame(x, y)

    ggplot(dd, aes(x, y)) + geom_point() +
    scale_y_log10("y",
        breaks = trans_breaks("log10", function(x) 10^x),
        labels = trans_format("log10", math_format(10^.x)))

enter image description here

答案 2 :(得分:10)

scale_y_continuous(label=scientific_format())

给e标签而不是10:

enter image description here

我想如果你真的想要10,那么你可以把它包装在另一个函数中。

scientific_10 <- function(x) {
  gsub("e", " x 10^", scientific_format()(x))
}

ggplot(dd, aes(x, y)) + geom_point() + 
  scale_y_continuous(label=scientific_10)

enter image description here

答案 3 :(得分:4)

我写了一个版本的scientific_10,避免了尺度包;它还会删除指数中的前导零(10 ^ 04到10 ^ 4等)。这是根据上面给出的有用答案改编的。

我还在下面包含了包装比例函数。

scientific_10 <- function(x) {
    xout <- gsub("1e", "10^{", format(x),fixed=TRUE)
    xout <- gsub("{-0", "{-", xout,fixed=TRUE)
    xout <- gsub("{+", "{", xout,fixed=TRUE)
    xout <- gsub("{0", "{", xout,fixed=TRUE)
    xout <- paste(xout,"}",sep="")
    return(parse(text=xout))
}

scale_x_log10nice <- function(name=NULL,omag=seq(-10,20),...) {
    breaks10 <- 10^omag
    scale_x_log10(name,breaks=breaks10,labels=scientific_10(breaks10),...)
}

scale_y_log10nice <- function(name=NULL,omag=seq(-10,20),...) {
    breaks10 <- 10^omag
    scale_y_log10(name,breaks=breaks10,labels=scientific_10(breaks10),...)
}

scale_loglog <- function(...) {
    list(scale_x_log10nice(...),scale_y_log10nice(...))
}

qplot(x=exp(5*rnorm(100)),geom="density",kernel="rectangular") + 
    scale_x_log10nice()

答案 4 :(得分:3)

重复汤姆上面的回答,以下删除+符号,并更好地处理0(该函数也是匿名内联的):

scale_y_continuous(label= function(x) {ifelse(x==0, "0", parse(text=gsub("[+]", "", gsub("e", " %*% 10^", scientific_format()(x)))))} ) +

答案 5 :(得分:1)

我认为使用出色的 ggtext 包变得非常容易。 我所做的是:

library(ggplot)
library(ggtext)
ggplot(mtcars, aes(x = log10(mpg), y = wt)) +
  geom_point() +
  scale_x_continuous(labels = function(x){return(paste0("10^", x))}) +
  theme(
    axis.text.x = element_markdown()
  )

enter image description here

答案 6 :(得分:0)

我想使用tidyverse修改解决方案。

library(tidyverse)
library(scales)

scientific_10<-function(x) {
  index_zero<-which(x==0)
  scientific(x,digits=2)%>%
    str_split("e", simplify=TRUE)%>%
    as_tibble(.name_repair="unique")%>%set_names(c("mantissa","exponent"))%>%
    mutate(
      mantissa=as.numeric(mantissa),
      exponent=as.numeric(exponent),
      label=sprintf('"%.1f" %%*%% 10^{"%d"}', mantissa,exponent),
      )%>%
    pull(label)->label
  label[index_zero]<-"0"
  parse(text=label)
}

dd%>%
  ggplot(aes(x,y))+
    geom_point()+ 
    scale_y_continuous(label=scientific_10)