整合直方图和密度曲线,一个轴用于频率,另一个轴用于密度

时间:2016-07-24 22:59:06

标签: r plot histogram

我使用hist()lines()函数创建了一个密度叠加的直方图,并希望y-axis显示频率而不是密度。

有没有办法使用hist()并且不使用ggplot来执行此操作?将频率轴作为右侧的第二个y轴甚至更好。这是我的代码:

g <- rnorm(2000,5,1)
h<-hist(g, breaks=50, col="bisque",     
        border="black",ylab="Frequeny",yaxt='n',
        main="Title",xlab=paste0("Cr","(mg/dL)"),prob=TRUE) 
Axis(side=2, at=seq(0, 200, by=20))
lines(density(g),col="dimgray") #For Overlay

设置prob = FALSE没有帮助,因为线条不适用于密度叠加。

1 个答案:

答案 0 :(得分:6)

让我们首先生成数据和hist对象:

set.seed(0)  ## added for reproducibility
g <- rnorm(2000, 5, 1)
h <- hist(g, breaks = 50, plot = FALSE)

我暂时按plot = FALSE限制了投标。

问题是,我们希望有两个y轴:

  • 左边的那个显示计数/频率;
  • 右边的那个显示密度。

基本上我们在两个轴的密度值上添加刻度线,但是

  • 在左侧显示相应的计数/频率;
  • 在右边显示密度值。

hist对象中的密度值为h$density。对于漂亮的图表,我们申请 pretty()获得刻度标记位置:

pos <- pretty(h$density, n = 5)
# [1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6

要在pos找到相应的计数,我们会这样做:

freq <- round(pos * length(g) * with(h, breaks[2] - breaks[1]))
# [1]   0  20  40  60  80 100 120

这里使用的round()只是为了确保有限精度计算引入的数字被删除,以便最终得到整数。

现在我们准备生成我们的集成直方图。请记住增加右边距以为右轴的轴名称保留一些空间。在下文中,我们将右边距设置为与左边距相同。

new.mai <- old.mai <- par("mai")
new.mai[4] <- old.mai[2]
par(mai = new.mai)

graphics:::plot.histogram(h, freq = FALSE, col="bisque", main="Integrated Histogram",
                          xlab = paste0("Cr","(mg/dL)"), ylab="Frequeny",
                          border="black", yaxt='n')
Axis(side = 2, at = pos, labels = freq)
Axis(side = 4, at = pos, labels = pos)
mtext("Density", side = 4, line = 3)
lines(density(g), col="dimgray")

par(mai = old.mai)

请注意我使用graphics:::plot.histogram绘制hist对象的方式,以及mtext在边距上添加文字的方法。请阅读?plot.histogram?mtext了解更多信息。

enter image description here