Как да покажа точно SI префикса за числа в скалата на оста y на графиката, направена с ggplot2 в R?

Имам следния график, генериран с помощта на този код

plt <- ggplot(d2, aes_string(x=names(same_df)[1],y= "value")) + 
    geom_point(aes(color = variable), size = 1)+ theme_bw()+
    theme(legend.text=element_text(size=14), legend.title=element_text(size=14))+
    theme(axis.text=element_text(size=20)) +
    theme(axis.title=element_text(size=20,face="bold")) + scale_color_discrete(name = "title", labels = c("1", "2", "3", "4","5","6","7","8","9")) + labs(x = "x", y = "y")+ guides(colour = guide_legend(override.aes = list(size=4),ncol=2,title.hjust=0.5))+theme(plot.margin=unit(c(0,0,0,0),"mm"))

въведете описание на изображението тук

Въпреки това имам нужда от нотация с префикс SI за числата в оста y, за да получа, че направих следните стъпки,

library("sos")

За да използвате findFn в пакета sitools

findFn("{SI prefix}") 

След това използвам f2si в етикетите, за да конвертирам число с плаваща запетая в число със SI префикс

plt2 <- plt + scale_y_continuous(labels=f2si)

Полученият график изглежда така,

въведете описание на изображението тук

Докато f2si точно промени оста y за -1e^-0.8 до -10 n, той не показва точно стойността за 0 и 1e^-0.8, която би била съответно 0 и 10 n. Може ли някой да предложи какво трябва да се коригира тук, така че числата да се показват така, както трябва да бъдат навсякъде.

Благодаря.


person Amm    schedule 10.01.2014    source източник
comment
Вижте тук.   -  person MYaseen208    schedule 10.01.2014


Отговори (1)


Не успях да възпроизведа поведението ви. Виж това:

df <- data.frame(x=runif(100), y=(runif(100)-1/2)/1e8)
p <- ggplot(df, aes(x, y)) + geom_point()
p + scale_y_continuous(labels=f2si)

въведете описание на изображението тук

Също така намерих друга подобна функция, ако не харесвате етикета "0 n":

  format_si <- function(...) {
  # Based on code by Ben Tupper
  # https://stat.ethz.ch/pipermail/r-help/2012-January/299804.html

  function(x) {
    limits <- c(1e-24, 1e-21, 1e-18, 1e-15, 1e-12,
                1e-9,  1e-6,  1e-3,  1e0,   1e3,
                1e6,   1e9,   1e12,  1e15,  1e18,
                1e21,  1e24)
    prefix <- c("y",   "z",   "a",   "f",   "p",
                "n",   "µ",   "m",   " ",   "k",
                "M",   "G",   "T",   "P",   "E",
                "Z",   "Y")

    # Vector with array indices according to position in intervals
    i <- findInterval(abs(x), limits)

    # Set prefix to " " for very small values < 1e-24
    i <- ifelse(i==0, which(limits == 1e0), i)

    paste(format(round(x/limits[i], 1),
                 trim=TRUE, scientific=FALSE, ...),
          prefix[i])
  }
}

p + scale_y_continuous(labels=format_si())

въведете описание на изображението тук

person tonytonov    schedule 13.01.2014
comment
Благодаря за вашето предложение, сега работи, предполагам, че имате предвид p + scale_y_continuous(labels=format_si()) в последния ред на кода за премахване на n близо до 0. - person Amm; 14.01.2014
comment
Наистина харесвам функцията format_si(), която сте написали, тъй като е лесна за персонализиране, като замяна на B с G за представяне на милиарди, ако желаете. - person coip; 21.09.2016
comment
@coip Благодаря, за мен е удоволствие. - person tonytonov; 21.09.2016