29

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

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

dd <- data.frame(x, y)

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

给我

带有刻度的示例 ggplot

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

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

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

4

7 回答 7

47

我改编了布赖恩的回答,我想我得到了你想要的。

只需将 parse() 添加到 science_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)

在此处输入图像描述

您可能仍然希望使函数更智能,以便更优雅地处理 0,但我认为就是这样!

于 2013-08-30T10:20:24.663 回答
31

根据对已接受解决方案的评论,OP 正在寻求将指数格式化为指数。这可以通过scales包中的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)))

在此处输入图像描述

于 2013-08-30T06:48:12.853 回答
13
scale_y_continuous(label=scientific_format())

给出带有 e 而不是 10 的标签:

在此处输入图像描述

我想如果你真的想要 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)

在此处输入图像描述

于 2012-05-25T23:23:15.100 回答
10

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

scale_y_continuous(label= function(x) {ifelse(x==0, "0", parse(text=gsub("[+]", "", gsub("e", " %*% 10^", scientific_format()(x)))))} ) +
于 2017-08-24T16:49:57.000 回答
6

我写了一个避免使用 scales 包的 science_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()
于 2015-05-22T19:27:07.283 回答
3

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

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()
  )

在此处输入图像描述

于 2021-05-26T09:48:10.473 回答
1

合并前面的答案,我创建了一个函数,可以将 x 和 y 的任意十倍幂作为乘法因子,然后创建在轴附近添加因子的图

在此处输入图像描述

library(ggplot2)
x <- seq(1,25)
y <- rnorm(25)/10000
dd <- data.frame(x, y)

trim10 <- function(x) {
  parse(text=gsub(".*e", "x10^", scales::scientific_format()(x)))
}


ggplot_trim10 <- function(x,y,xfac,yfac,...){
        
    xnew    <- x*xfac 
    ynew    <- y*yfac 
    
    dd      <- data.frame(xnew,ynew)
    
    xunit   <- abs(max(xnew) - min(xnew))
    yunit   <- abs(max(ynew) - min(ynew))
    
    x_min_label <- min(xnew) - xunit*0.1
    x_max_label <- max(xnew) - xunit*0.1
    y_min_label <- min(ynew) - yunit*0.1
    y_max_label <- max(ynew) - yunit*0.1
    
    ggplot(data=dd, aes(x=xnew, y=ynew),...) +
    geom_line() +
    annotate("text", x = x_max_label, y = y_min_label, label = trim10(xfac)) +
    annotate("text", x = x_min_label, y = y_max_label, label = trim10(yfac)) +
    coord_cartesian(xlim = c(min(xnew), max(xnew)),ylim = c(min(ynew),max(ynew)), clip = "off")
    }

ggplot_trim10(x,y,10,10)

作为注释,我知道“x”不是正确的符号,但我有点疯狂地混合expression等等paste。如果有人能修复它,那就太好了

于 2021-09-15T14:28:45.647 回答