2011-08-06 113 views
17

我一直想在我的直方圖上疊加一個正態曲線與ggplot 2.GGPLOT2:直方圖正態曲線

我的公式:

data <- read.csv (path...) 

ggplot(data, aes(V2)) + 
    geom_histogram(alpha=0.3, fill='white', colour='black', binwidth=.04) 

我試過幾件事情:

+ stat_function(fun=dnorm) 

....沒有任何改變

+ stat_density(geom = "line", colour = "red") 

......在x軸上給了我一條紅色的直線。

+ geom_density() 

對我不起作用,因爲我想保持我的頻率值在y軸上,並且不需要密度值。

有什麼建議嗎?

在此先感謝您的任何提示!

找到解決方案!

+geom_density(aes(y=0.045*..count..), colour="black", adjust=4)

+0

檢查上一個相關的問題,在這裏我已經寫了一個泛型函數疊加在密度圖直方圖這個答案我的。 http://stackoverflow.com/questions/6847450/r-how-to-plot-gumbel-distribution-using-ggplot2s-stat-function/6848958#6848958 – Ramnath

+0

但是,該功能需要在Y軸上的密度值,對吧?我希望保持我的頻率計數!我不想要一個密度圖,而是一個簡單的正態曲線。 – Bloomy

+0

但正常曲線有密度。所以我很困惑。你想要一個具有頻率計數的正態曲線嗎? – Ramnath

回答

7

此代碼應該這樣做:

set.seed(1) 
z <- rnorm(1000) 

qplot(z, geom = "blank") + 
geom_histogram(aes(y = ..density..)) + 
stat_density(geom = "line", aes(colour = "bla")) + 
stat_function(fun = dnorm, aes(x = z, colour = "blabla")) + 
scale_colour_manual(name = "", values = c("red", "green"), 
           breaks = c("bla", "blabla"), 
           labels = c("kernel_est", "norm_curv")) + 
theme(legend.position = "bottom", legend.direction = "horizontal") 

enter image description here

注:我用qplot但是你可以用更靈活ggplot。

+1

這不正是我正在尋找的,因爲它給我的y軸密度值,我想保持我的頻率計數! – Bloomy

+2

我明白了,但頻率和密度之間的「真正」差異究竟是什麼,它畢竟不是同一個信息......再加上由於PDF的定義密度更容易實現。 – dickoa

10

想我明白了:

set.seed(1) 
df <- data.frame(PF = 10*rnorm(1000)) 
ggplot(df, aes(x = PF)) + 
    geom_histogram(aes(y =..density..), 
        breaks = seq(-50, 50, by = 10), 
        colour = "black", 
        fill = "white") + 
stat_function(fun = dnorm, args = list(mean = mean(df$PF), sd = sd(df$PF))) 

enter image description here

+2

歡迎來到Stack Overflow,你能詳細解釋一下你的答案嗎? –

+3

最好使用'ggsave()' - 更少的代碼和更少的錯誤傾向。 – MERose

+0

添加了屏幕截圖+添加的數據(基於dickoa的回答),以便代碼可以運行。還刪除了繪圖保存部分,因爲這是一個分心。你可以回滾當然的變化。 – PatrickT

12

這已經回答了here和部分here

如果你想Y軸有頻率計數,那麼正常曲線需要根據觀測值的數量和binwidth進行縮放。

# Simulate some data. Individuals' heights in cm. 
n  <- 1000 
mean  <- 165 
sd  <- 6.6 
binwidth <- 2 
height <- rnorm(n, mean, sd) 


qplot(height, geom = "histogram", breaks = seq(130, 200, binwidth), 
     colour = I("black"), fill = I("white"), 
     xlab = "Height (cm)", ylab = "Count") + 
    # Create normal curve, adjusting for number of observations and binwidth 
    stat_function( 
    fun = function(x, mean, sd, n, bw){ 
     dnorm(x = x, mean = mean, sd = sd) * n * bw 
    }, 
    args = c(mean = mean, sd = sd, n = n, bw = binwidth)) 

Histogram with normal curve

EDIT

或者,對於更靈活的方法,允許使用小面的並且在列出here的方法繪製,創建包含該數據用於正常曲線的單獨的數據集和覆蓋這些。

library(plyr) 

dd <- data.frame(
    predicted = rnorm(720, mean = 2, sd = 2), 
    state = rep(c("A", "B", "C"), each = 240) 
) 

binwidth <- 0.5 

grid <- with(dd, seq(min(predicted), max(predicted), length = 100)) 
normaldens <- ddply(dd, "state", function(df) { 
    data.frame( 
    predicted = grid, 
    normal_curve = dnorm(grid, mean(df$predicted), sd(df$predicted)) * length(df$predicted) * binwidth 
) 
}) 

ggplot(dd, aes(predicted)) + 
    geom_histogram(breaks = seq(-3,10, binwidth), colour = "black", fill = "white") + 
    geom_line(aes(y = normal_curve), data = normaldens, colour = "red") + 
    facet_wrap(~ state) 
4

這是對JWilliman的回答的擴展評論。我發現J的答案非常有用。在玩遊戲時,我發現了一種簡化代碼的方法。我不是說這是一種更好的方式,但我想我會提到它。如果有「R的地獄」類型的缺點,我會建議刪除這個擴展的評論。請注意,JWilliman的答案提供了y軸上的計數和「hack」來縮放相應的密度法線近似(否則將覆蓋總面積1,因此具有更低的峯值)。

此評論的要點:通過將所需參數傳遞給美學功能(例如,美學功能)來簡化stat_function中的語法。

aes(x = x, mean = 0, sd = 1, binwidth = 0.3, n = 1000)

這避免了必須通過args =stat_function到,因此是更加用戶友好的。好吧,這不是很不一樣,但希望有人會覺得它很有趣。

# parameters that will be passed to ``stat_function`` 
n = 1000 
mean = 0 
sd = 1 
binwidth = 0.3 # passed to geom_histogram and stat_function 
set.seed(1) 
df <- data.frame(x = rnorm(n, mean, sd)) 

ggplot(df, aes(x = x, mean = mean, sd = sd, binwidth = binwidth, n = n)) + 
    theme_bw() + 
    geom_histogram(binwidth = binwidth, 
     colour = "white", fill = "cornflowerblue", size = 0.1) + 
stat_function(fun = function(x) dnorm(x, mean = mean, sd = sd) * n * binwidth, 
    color = "darkred", size = 1) 

enter image description here

+0

我認爲''ggplot2''是一個新穎的特性,可以將這些參數傳遞給''aes()'',而不在數據框中。我可能是錯的。 – PatrickT