ggplot的scale_y_log10行为

时间:2016-11-14 02:04:39

标签: r ggplot2 scale

尝试使用ggplot绘制堆积直方图:

set.seed(1)
my.df <- data.frame(param = runif(10000,0,1), 
                    x = runif(10000,0.5,1))
my.df$param.range <- cut(my.df$param, breaks = 5)

require(ggplot2)

不记录y轴:

ggplot(my.df,aes_string(x = "x", fill = "param.range")) + 
    geom_histogram(binwidth = 0.1, pad = TRUE) + 
    scale_fill_grey()

给出: enter image description here

但是我想log10 + 1转换y轴以便于阅读:

ggplot(my.df, aes_string(x = "x", y = "..count..+1", fill = "param.range")) + 
    geom_histogram(binwidth = 0.1, pad = TRUE) + 
    scale_fill_grey() + 
    scale_y_log10()

给出:

enter image description here

y轴上的刻度标记没有意义。

如果我使用log10转换而不是log10 + 1:

,我会得到相同的行为
ggplot(my.df, aes_string(x = "x", fill = "param.range")) + 
    geom_histogram(binwidth = 0.1, pad = TRUE) + 
    scale_fill_grey() + 
    scale_y_log10()

知道发生了什么事吗?

1 个答案:

答案 0 :(得分:3)

看起来使用堆叠直方图调用scale_y_log10会导致ggplot在每个x bin中绘制堆栈中每个组件的计数的 product 。以下是演示。我们创建了一个名为product.of.counts的数据框,其中包含每个x bin的计数的每个param.range bin中的产品。我们使用geom_text将这些值添加到绘图中,并看到它们与每个直方图条形图的顶部重合。

起初我认为这是一个错误,但在bit of searching之后,我被提醒ggplot进行日志转换的方式。如链接答案中所述,&#34; scale_y_log10进行计数,将它们转换为日志,堆叠这些日志,然后以反日志形式显示比例。但是,堆叠日志不是线性转换,因此您要求它做的事情没有任何意义。&#34;

作为一个更简单的例子,假设堆叠条的五个组件中的每一个都有100个。然后log10(100)= 2表示所有五个,并且日志的总和将是10.然后ggplot采用反日志对于比例尺,即使实际高度为100x5 = 500,也会给出条的总高度10 ^ 10(即100 ^ 5)。这正是你的情节所发生的事情。

library(dplyr)
library(ggplot2)

# Data
set.seed(1)
my.df <- data.frame(param=runif(10000,0,1),x=runif(10000,0.5,1))
my.df$param.range <- cut(my.df$param,breaks=5)

# Calculate product of counts within each x bin
product.of.counts = my.df %>% 
  group_by(param.range, breaks=cut(x, breaks=seq(-0.05, 1.05, 0.1), labels=seq(0,1,0.1))) %>%
  tally %>%
  group_by(breaks) %>% 
  summarise(prod = prod(n),
            param.range=NA) %>%
  ungroup %>%
  mutate(breaks = as.numeric(as.character(breaks)))

ggplot(my.df, aes(x, fill=param.range)) + 
  geom_histogram(binwidth = 0.1, colour="grey30") + 
  scale_fill_grey() + 
  scale_y_log10(breaks=10^(0:14)) +
  geom_text(data=product.of.counts, size=3.5, 
            aes(x=breaks, y=prod, label=format(prod, scientific=TRUE, digits=3)))

enter image description here