我用R,我有两个数据帧:胡萝卜和黄瓜。每个数据帧都有一个数字列,列出了所有测量的胡萝卜(总共:100k胡萝卜)和黄瓜(总共:50k黄瓜)的长度。

我希望在同一个图上绘制两个直方图——胡萝卜长度和黄瓜长度。它们重叠了,所以我想我也需要一些透明度。我还需要使用相对频率,而不是绝对频率,因为每个组中的实例数量是不同的。

这样的东西会很好,但我不明白如何从我的两个表创建它:


当前回答

这里是类似于我只以r为基数给出的ggplot2的版本。我从@nullglob复制了一些。

生成数据

carrots <- rnorm(100000,5,2)
cukes <- rnorm(50000,7,2.5)

您不需要像使用ggplot2那样将其放入数据帧中。这种方法的缺点是你必须写出更多的情节细节。这样做的好处是你可以控制更多的情节细节。

## calculate the density - don't plot yet
densCarrot <- density(carrots)
densCuke <- density(cukes)
## calculate the range of the graph
xlim <- range(densCuke$x,densCarrot$x)
ylim <- range(0,densCuke$y, densCarrot$y)
#pick the colours
carrotCol <- rgb(1,0,0,0.2)
cukeCol <- rgb(0,0,1,0.2)
## plot the carrots and set up most of the plot parameters
plot(densCarrot, xlim = xlim, ylim = ylim, xlab = 'Lengths',
     main = 'Distribution of carrots and cucumbers', 
     panel.first = grid())
#put our density plots in
polygon(densCarrot, density = -1, col = carrotCol)
polygon(densCuke, density = -1, col = cukeCol)
## add a legend in the corner
legend('topleft',c('Carrots','Cucumbers'),
       fill = c(carrotCol, cukeCol), bty = 'n',
       border = NA)

其他回答

你链接的图片是密度曲线,不是直方图。

如果您一直在阅读ggplot,那么可能您唯一缺少的是将两个数据帧合并为一个长数据帧。

那么,让我们从你拥有的两组独立的数据开始,并将它们结合起来。

carrots <- data.frame(length = rnorm(100000, 6, 2))
cukes <- data.frame(length = rnorm(50000, 7, 2.5))

# Now, combine your two dataframes into one.  
# First make a new column in each that will be 
# a variable to identify where they came from later.
carrots$veg <- 'carrot'
cukes$veg <- 'cuke'

# and combine into your new data frame vegLengths
vegLengths <- rbind(carrots, cukes)

在那之后,如果你的数据已经是长格式的,这是不必要的,你只需要一行来绘制你的图表。

ggplot(vegLengths, aes(length, fill = veg)) + geom_density(alpha = 0.2)

现在,如果你真的想要直方图,下面的方法就可以了。注意,必须从默认的"stack"参数更改位置。如果您不知道您的数据应该是什么样子,您可能会错过这一点。更高的alpha看起来更好。还要注意,我把它做成了密度直方图。很容易删除y = ..density..把它找回来。

ggplot(vegLengths, aes(length, fill = veg)) + 
   geom_histogram(alpha = 0.5, aes(y = ..density..), position = 'identity')

另外,我评论了Dirk的问题,所有的参数都可以简单地在hist命令中。有人问我怎么才能做到。接下来得出的正是德克的数字。

set.seed(42)
hist(rnorm(500,4), col=rgb(0,0,1,1/4), xlim=c(0,10))
hist(rnorm(500,6), col=rgb(1,0,0,1/4), xlim=c(0,10), add = TRUE)

基本想法很好,但代码可以改进。[需要很长时间解释,因此需要单独回答,而不是评论。]

hist()函数默认绘制图形,因此需要添加plot=FALSE选项。此外,通过plot(0,0,type="n",…)调用可以更清晰地建立plot区域,您可以在其中添加轴标签、plot标题等。最后,我想提一下,还可以使用阴影来区分两个直方图。代码如下:

set.seed(42)
p1 <- hist(rnorm(500,4),plot=FALSE)
p2 <- hist(rnorm(500,6),plot=FALSE)
plot(0,0,type="n",xlim=c(0,10),ylim=c(0,100),xlab="x",ylab="freq",main="Two histograms")
plot(p1,col="green",density=10,angle=135,add=TRUE)
plot(p2,col="blue",density=10,angle=45,add=TRUE)

这里是结果(有点太宽,因为RStudio:-)):

这么多伟大的答案,但由于我刚刚写了一个函数('basicPlotteR'包中的plotMultipleHistograms())函数来做到这一点,我想我会添加另一个答案。

这个函数的优点是,它自动设置适当的X轴和Y轴限制,并定义在所有分布中使用的公共容器集。

下面是如何使用它:

# Install the plotteR package
install.packages("devtools")
devtools::install_github("JosephCrispell/basicPlotteR")
library(basicPlotteR)

# Set the seed
set.seed(254534)

# Create random samples from a normal distribution
distributions <- list(rnorm(500, mean=5, sd=0.5), 
                      rnorm(500, mean=8, sd=5), 
                      rnorm(500, mean=20, sd=2))

# Plot overlapping histograms
plotMultipleHistograms(distributions, nBins=20, 
                       colours=c(rgb(1,0,0, 0.5), rgb(0,0,1, 0.5), rgb(0,1,0, 0.5)), 
                       las=1, main="Samples from normal distribution", xlab="Value")

plotMultipleHistograms()函数可以接受任意数量的分布,并且所有一般的绘图参数都应该与它一起工作(例如:las, main等)。

Plotly的R API可能对你有用。下图在这里。

library(plotly)
#add username and key
p <- plotly(username="Username", key="API_KEY")
#generate data
x0 = rnorm(500)
x1 = rnorm(500)+1
#arrange your graph
data0 = list(x=x0,
         name = "Carrots",
         type='histogramx',
         opacity = 0.8)

data1 = list(x=x1,
         name = "Cukes",
         type='histogramx',
         opacity = 0.8)
#specify type as 'overlay'
layout <- list(barmode='overlay',
               plot_bgcolor = 'rgba(249,249,251,.85)')  
#format response, and use 'browseURL' to open graph tab in your browser.
response = p$plotly(data0, data1, kwargs=list(layout=layout))

url = response$url
filename = response$filename

browseURL(response$url)

坦白说,我是队里的。

下面是一个更简单的解决方案,使用基本图形和alpha混合(并不适用于所有图形设备):

set.seed(42)
p1 <- hist(rnorm(500,4))                     # centered at 4
p2 <- hist(rnorm(500,6))                     # centered at 6
plot( p1, col=rgb(0,0,1,1/4), xlim=c(0,10))  # first histogram
plot( p2, col=rgb(1,0,0,1/4), xlim=c(0,10), add=T)  # second

关键是颜色是半透明的。

编辑,两年多后:由于这篇文章刚刚获得了好评,我想我不妨添加一个可视化的代码,因为alpha混合是如此有用: