叠加密度图不包括直方图值
Overlay density plot excludes histogram values
我想将密度曲线叠加到我构建的频率直方图上。对于我使用 aes(y=..counts../40)
的频率直方图,因为 40 是我的总样本数。我使用 aes(y=..density..*0.1)
强制密度在 0 和 1 之间,因为我的 binwidth 是 0.1。但是,密度曲线不适合我的数据,它排除了等于 1.0 的值(请注意,直方图显示 bin=(1.0,1.1) 的累积值,但密度曲线以 1.0 结束)
这是我的数据
data<-structure(list(variable = structure(c(1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("E1", "test"
), class = "factor"), value = c(0.288888888888889, 0.0817901234567901,
0.219026548672566, 0.584795321637427, 0.927554980595084, 0.44661095636026,
1, 0.653780942692438, 1, 0.806451612903226, 1, 0.276794335371741,
1, 0.930109557990178, 0.776864728192162, 0.824909747292419, 1,
1, 1, 1, 1, 0.0875912408759124, 0.308065494238933, 1, 0.0258064516129032,
0.0167322834645669, 1, 1, 0.355605889014723, 0.310344827586207,
0.106598984771574, 0.364447494852436, 0.174724342663274, 0.77491961414791,
1, 0.856026785714286, 0.680759275237274, 0.850657108721625, 1,
1, 0, 0.851851851851852, 1, 0, 0.294954721862872, 0.819870009285051,
0, 0.734147168531706, 0.0135424091233072, 0.0189098998887653,
0.0101010101010101, 0, 0.296905222437137, 0.706837929731772,
0.269279393173198, 0.135379061371841, 0.158969804618117, 0.0902981940361193,
0.00423131170662906, 0, 0.374880611270296, 0.0425790754257908,
0.145542753183748, 0, 0.129032258064516, 0.260334645669291, 0,
0, 1, 0.175505350772889, 0.08248730964467, 0, 0.317217981340119,
0.614147909967846, 0, 0.264508928571429, 0.883520276100086, 0.0657108721624851,
0, 0.560229445506692)), row.names = c(NA, -80L), .Names = c("variable",
"value"), class = "data.frame")
情节
q<-ggplot(data, aes(value, fill = variable))
q + geom_density(alpha = 0.6,aes(y=..density..*0.1),binwidth=0.1)
+ theme_minimal()+scale_fill_manual(values =c("#D7191C","#2B83BA"))
+ theme(legend.position="bottom")+ guides(fill=guide_legend(nrow=1))
+ labs(title="Density Plot GrupoB",x="Respuesta",y="Density")
+scale_x_continuous(breaks=seq(from=0,to=1.2,by=0.1))
+geom_histogram(alpha = 0.6,aes(y=..count../40),binwidth=0.1,position="dodge")
我得到的输出是这样的
您的绘图完全符合您的数据预期:
- 您绘制了
data$value
,其中包含 0 到 1 之间的数值,因此您应该期望密度曲线也从 0 到 1 到 运行。
- 您绘制了一个 binwidth 为 0.1 的直方图。垃圾箱在下端关闭,在上端打开。所以你得到的分箱是 [0,0.1), [0.1, 0.2), ..., [0.9,1.0), [1.0,1.1)。您的数据中有 17 个值为 1,因此进入最后一个 bin,该 bin 是从 1 到 1.1 绘制的。
我认为按照您的方式绘制直方图是个坏主意。原因是对于直方图,x 轴是连续的,这意味着覆盖 x 轴范围从 0.1 到 0.2 的条代表(包括)0.1 和 0.2 之间的值的计数(不包括后者)。在这种情况下使用闪避会导致图片失真,因为条形现在不再覆盖正确的 x 轴范围。两个柱共享应该被它们完全覆盖的范围。这种失真是密度曲线似乎与直方图不匹配的原因之一。
那么,你能做些什么呢?我可以给你一些建议,但也许其他人有更好的想法...
不是使用 position="dodge"
绘制彼此相邻的直方图,您可以使用分面,即将直方图(和相应的密度曲线)绘制成单独的图。这可以通过在您的绘图中添加 + facet_grid(variable~.)
来实现。
你可以稍微作弊以获得最后一个 bin,即 [0.9,1],包括 1(即让它成为 [0.9,1.0])。只需将数据中的 1 替换为 0.999,如下所示:data$value[data$value==1]<-0.999
。重要的是,您对绘图执行此 only,这实际上仅意味着您稍微重新定义分箱。对于您打算执行的所有数字评估,您不应该进行此替换! (例如,它会改变 data$value
的平均值。)
关于密度曲线和直方图的归一化:密度曲线不需要位于0和1之间。限制是密度曲线上的积分应为1。因此,为了使密度曲线和直方图具有可比性,直方图也应该具有积分 1,这也是通过将 y 值除以绑定宽度来实现的。所以,你应该使用 geom_density(alpha = 0.6,aes(y=..density..))
(我也删除了 bindwith=0.1
,因为它对 geom_density
没有影响)和 geom_histogram(alpha = 0.6,aes(y=..count../40/.1),binwidth=0.1)
(不需要 position="dodge"
,一旦你使用面)。当然,这会导致您的相对归一化,但它更有意义,因为密度曲线和直方图的积分为 1,正如它们应该的那样。
密度曲线仍然不能完全匹配直方图,这与密度估计器的计算方式有关。我不太了解这一点,因此很遗憾无法进一步解释。但是你可以通过使用参数 adjust
到 geom_density
来更好地理解它是如何工作的。对于较小的数字,它会使曲线不那么平滑,并且曲线将更接近直方图。
为了将所有内容放在一起,我已将所有建议构建到您的代码中,在 geom_density
中使用了 adjust=0.2
并绘制了结果:
data$value[data$value==1]<-0.999
q<-ggplot(data, aes(value, fill = variable))
q + geom_density(alpha = 0.6,aes(y=..density..),adjust=0.2) +
theme_minimal()+scale_fill_manual(values =c("#D7191C","#2B83BA")) +
theme(legend.position="bottom")+ guides(fill=guide_legend(nrow=1)) +
labs(title="Density Plot GrupoB",x="Respuesta",y="Density")+
scale_x_continuous(breaks=seq(from=0,to=1.2,by=0.1))+
geom_histogram(alpha = 0.6,aes(y=..count../40/.1),binwidth=0.1) +
facet_grid(variable~.)
很遗憾,我不能给你一个更完整的答案,但我希望这些想法能给你一个好的开始。
我想将密度曲线叠加到我构建的频率直方图上。对于我使用 aes(y=..counts../40)
的频率直方图,因为 40 是我的总样本数。我使用 aes(y=..density..*0.1)
强制密度在 0 和 1 之间,因为我的 binwidth 是 0.1。但是,密度曲线不适合我的数据,它排除了等于 1.0 的值(请注意,直方图显示 bin=(1.0,1.1) 的累积值,但密度曲线以 1.0 结束)
这是我的数据
data<-structure(list(variable = structure(c(1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("E1", "test"
), class = "factor"), value = c(0.288888888888889, 0.0817901234567901,
0.219026548672566, 0.584795321637427, 0.927554980595084, 0.44661095636026,
1, 0.653780942692438, 1, 0.806451612903226, 1, 0.276794335371741,
1, 0.930109557990178, 0.776864728192162, 0.824909747292419, 1,
1, 1, 1, 1, 0.0875912408759124, 0.308065494238933, 1, 0.0258064516129032,
0.0167322834645669, 1, 1, 0.355605889014723, 0.310344827586207,
0.106598984771574, 0.364447494852436, 0.174724342663274, 0.77491961414791,
1, 0.856026785714286, 0.680759275237274, 0.850657108721625, 1,
1, 0, 0.851851851851852, 1, 0, 0.294954721862872, 0.819870009285051,
0, 0.734147168531706, 0.0135424091233072, 0.0189098998887653,
0.0101010101010101, 0, 0.296905222437137, 0.706837929731772,
0.269279393173198, 0.135379061371841, 0.158969804618117, 0.0902981940361193,
0.00423131170662906, 0, 0.374880611270296, 0.0425790754257908,
0.145542753183748, 0, 0.129032258064516, 0.260334645669291, 0,
0, 1, 0.175505350772889, 0.08248730964467, 0, 0.317217981340119,
0.614147909967846, 0, 0.264508928571429, 0.883520276100086, 0.0657108721624851,
0, 0.560229445506692)), row.names = c(NA, -80L), .Names = c("variable",
"value"), class = "data.frame")
情节
q<-ggplot(data, aes(value, fill = variable))
q + geom_density(alpha = 0.6,aes(y=..density..*0.1),binwidth=0.1)
+ theme_minimal()+scale_fill_manual(values =c("#D7191C","#2B83BA"))
+ theme(legend.position="bottom")+ guides(fill=guide_legend(nrow=1))
+ labs(title="Density Plot GrupoB",x="Respuesta",y="Density")
+scale_x_continuous(breaks=seq(from=0,to=1.2,by=0.1))
+geom_histogram(alpha = 0.6,aes(y=..count../40),binwidth=0.1,position="dodge")
我得到的输出是这样的
您的绘图完全符合您的数据预期:
- 您绘制了
data$value
,其中包含 0 到 1 之间的数值,因此您应该期望密度曲线也从 0 到 1 到 运行。 - 您绘制了一个 binwidth 为 0.1 的直方图。垃圾箱在下端关闭,在上端打开。所以你得到的分箱是 [0,0.1), [0.1, 0.2), ..., [0.9,1.0), [1.0,1.1)。您的数据中有 17 个值为 1,因此进入最后一个 bin,该 bin 是从 1 到 1.1 绘制的。
我认为按照您的方式绘制直方图是个坏主意。原因是对于直方图,x 轴是连续的,这意味着覆盖 x 轴范围从 0.1 到 0.2 的条代表(包括)0.1 和 0.2 之间的值的计数(不包括后者)。在这种情况下使用闪避会导致图片失真,因为条形现在不再覆盖正确的 x 轴范围。两个柱共享应该被它们完全覆盖的范围。这种失真是密度曲线似乎与直方图不匹配的原因之一。
那么,你能做些什么呢?我可以给你一些建议,但也许其他人有更好的想法...
不是使用
position="dodge"
绘制彼此相邻的直方图,您可以使用分面,即将直方图(和相应的密度曲线)绘制成单独的图。这可以通过在您的绘图中添加+ facet_grid(variable~.)
来实现。你可以稍微作弊以获得最后一个 bin,即 [0.9,1],包括 1(即让它成为 [0.9,1.0])。只需将数据中的 1 替换为 0.999,如下所示:
data$value[data$value==1]<-0.999
。重要的是,您对绘图执行此 only,这实际上仅意味着您稍微重新定义分箱。对于您打算执行的所有数字评估,您不应该进行此替换! (例如,它会改变data$value
的平均值。)关于密度曲线和直方图的归一化:密度曲线不需要位于0和1之间。限制是密度曲线上的积分应为1。因此,为了使密度曲线和直方图具有可比性,直方图也应该具有积分 1,这也是通过将 y 值除以绑定宽度来实现的。所以,你应该使用
geom_density(alpha = 0.6,aes(y=..density..))
(我也删除了bindwith=0.1
,因为它对geom_density
没有影响)和geom_histogram(alpha = 0.6,aes(y=..count../40/.1),binwidth=0.1)
(不需要position="dodge"
,一旦你使用面)。当然,这会导致您的相对归一化,但它更有意义,因为密度曲线和直方图的积分为 1,正如它们应该的那样。密度曲线仍然不能完全匹配直方图,这与密度估计器的计算方式有关。我不太了解这一点,因此很遗憾无法进一步解释。但是你可以通过使用参数
adjust
到geom_density
来更好地理解它是如何工作的。对于较小的数字,它会使曲线不那么平滑,并且曲线将更接近直方图。
为了将所有内容放在一起,我已将所有建议构建到您的代码中,在 geom_density
中使用了 adjust=0.2
并绘制了结果:
data$value[data$value==1]<-0.999
q<-ggplot(data, aes(value, fill = variable))
q + geom_density(alpha = 0.6,aes(y=..density..),adjust=0.2) +
theme_minimal()+scale_fill_manual(values =c("#D7191C","#2B83BA")) +
theme(legend.position="bottom")+ guides(fill=guide_legend(nrow=1)) +
labs(title="Density Plot GrupoB",x="Respuesta",y="Density")+
scale_x_continuous(breaks=seq(from=0,to=1.2,by=0.1))+
geom_histogram(alpha = 0.6,aes(y=..count../40/.1),binwidth=0.1) +
facet_grid(variable~.)
很遗憾,我不能给你一个更完整的答案,但我希望这些想法能给你一个好的开始。