2016-11-14 82 views
2

想要繪製一個疊加柱狀圖:ggplot的scale_y_log10行爲

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

但我想日誌10 + 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軸上的刻度線沒有意義。

我得到同樣的行爲,如果我日誌10變換,而不是日誌10 + 1:

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

任何想法是怎麼回事?

+0

1.爲什麼不刻度線是有意義的嗎? 2.在最後一行代碼中我看不到任何轉換。 –

+0

抱歉,最後一行代碼已更正。關於y軸刻度值,我認爲它應該顯示第一個圖中顯示的計數的log10,所以它們應該是:2.69,3,3.17,3.30而不是1,000。 10,000,000,100,000,000,000 – dan

+0

y軸仍將以實際計數爲單位,而不是這些計數的日誌,但是y尺度會進行轉換,以便每個因子10的物理距離相同。 – eipi10

回答

2

它看起來像一個疊加柱狀圖調用scale_y_log10是造成ggplot繪製計數的產品每個x倉內堆棧的各個組件。下面是一個演示。我們創建一個名爲product.of.counts的數據框,其中包含每個param.range bin的每個x bin內的產品。我們使用geom_text將這些值添加到圖中,並看到它們與每個直方圖條堆棧的頂部一致。

起初我以爲這是一個bug,但在bit of searching後,我想起了ggplot做日誌轉換的方式。如鏈接答案中所述,「scale_y_log10」會計數,將它們轉換爲日誌,然後堆疊這些日誌,然後以反日誌形式顯示比例。但是,堆積日誌不是線性轉換,因此您詢問了什麼這樣做沒有任何意義。「

作爲一個更簡單的例子,假設一個堆棧條的五個組件中的每一個都有100個計數。然後log10(100)= 2,所有五個日誌的總和將是10.然後ggplot將採用anti-記錄刻度,即使實際高度爲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