poner - r ggplot title legend
ggplot2: histograma con curva normal (4)
He estado tratando de superponer una curva normal sobre mi histograma con ggplot 2.
Mi fórmula:
data <- read.csv (path...)
ggplot(data, aes(V2)) +
geom_histogram(alpha=0.3, fill=''white'', colour=''black'', binwidth=.04)
Intenté varias cosas:
+ stat_function(fun=dnorm)
.... no cambió nada
+ stat_density(geom = "line", colour = "red")
... me dio una línea roja recta en el eje x.
+ geom_density()
no funciona para mí porque quiero mantener mis valores de frecuencia en el eje y, y no quiero valores de densidad.
¿Alguna sugerencia?
Gracias de antemano por cualquier consejo!
Solución encontrada!
+geom_density(aes(y=0.045*..count..), colour="black", adjust=4)
Esto ha sido respondido aquí y parcialmente aquí .
Si desea que el eje y tenga recuentos de frecuencia, entonces la curva normal debe escalarse de acuerdo con el número de observaciones y el ancho de banda.
# 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))
EDITAR
O bien, para un enfoque más flexible que permita el uso de facetas y se basa en un enfoque enumerado aquí , cree un conjunto de datos por separado que contenga los datos de las curvas normales y superponga estos.
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)
Este código debería hacerlo:
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")
Nota: utilicé qplot pero puedes usar el ggplot más versátil.
Este es un comentario extendido sobre la respuesta de JWilliman. Encontré la respuesta de J muy útil. Mientras jugaba descubrí una forma de simplificar el código. No digo que sea una mejor manera, pero pensé que lo mencionaría. Si hay inconvenientes del tipo "R infierno", eliminaré este comentario extendido como se recomienda.
Tenga en cuenta que la respuesta de JWilliman proporciona la cuenta en el eje y y un "truco" para escalar la aproximación normal de densidad correspondiente (que de lo contrario cubriría un área total de 1 y, por lo tanto, tendría un pico mucho más bajo).
El punto principal de este comentario: sintaxis más simple dentro de stat_function
, pasando los parámetros necesarios a la función estética, por ejemplo
aes(x = x, mean = 0, sd = 1, binwidth = 0.3, n = 1000)
Esto evita tener que pasar args =
a stat_function
y, por lo tanto, es más fácil de usar. De acuerdo, no es muy diferente, pero con suerte alguien lo encontrará interesante.
# 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)