Как я могу форматировать метки оси с показателями с ggplot2 и шкалами?

В новой версии 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()

дает мне

Example ggplot with scales

Я хотел бы, чтобы метки осей были 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 ^ 5е-5 и т.д. Я понимаю, почему последний дает этот результат, но это не то, что я ищу.

Я использую ggplot2_0.9.1 и scales_0.2.1

Ответы

Ответ 1

Я адаптировал ответ Брайана, и я думаю, что получил то, что тебе нужно.

Просто добавив функцию 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)

enter image description here

Вы все еще можете поднять функцию, поэтому она имеет дело с 0 немного более элегантно, но я думаю, что это!

Ответ 2

В соответствии с комментариями к принятому решению OP ищет форматирование экспонентов в качестве показателей. Это можно сделать с помощью функций trans_format и trans_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)))

введите описание изображения здесь

Ответ 3

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

Ответ 4

Я написал версию 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()

Ответ 5

Повторяя ответ Tom, выше, удаляет + знаки и обрабатывает 0 лучше (функция также анонимно включена):

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

Ответ 6

Я хотел бы изменить решение с помощью 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)