Rでのggplot2によるヒストグラムのオーバーレイ


124

私はRを初めて使用し、3つのヒストグラムを同じグラフにプロットしようとしています。すべてうまくいきましたが、私の問題は、2つのヒストグラムが重なっているところが見えないことです。

密度プロットを作成すると、完璧に見えます。各曲線は黒い枠線で囲まれており、曲線が重なると色が異なって見えます。

1番目の画像のヒストグラムで同様のことが達成できるかどうか誰かに教えてもらえますか?これは私が使用しているコードです:

lowf0 <-read.csv (....)
mediumf0 <-read.csv (....)
highf0 <-read.csv(....)
lowf0$utt<-'low f0'
mediumf0$utt<-'medium f0'
highf0$utt<-'high f0'
histogram<-rbind(lowf0,mediumf0,highf0)
ggplot(histogram, aes(f0, fill = utt)) + geom_histogram(alpha = 0.2)

3
ヒストグラムへのハイパーリンクと密度プロットが壊れている
ダガン---

回答:


115

あなたの現在のコード:

ggplot(histogram, aes(f0, fill = utt)) + geom_histogram(alpha = 0.2)

はすべての値を使用して1つのヒストグラムを作成し、変数に従ってこの単一のヒストグラムのバーに色を付けるように指示ggplotしています。f0utt

代わりに、アルファブレンディングを使用して3つの個別のヒストグラムを作成し、相互に見えるようにします。そのため、おそらくへの3つの個別の呼び出しを使用する必要がありますgeom_histogram。それぞれの呼び出しは、独自のデータフレームを取得して埋めます。

ggplot(histogram, aes(f0)) + 
    geom_histogram(data = lowf0, fill = "red", alpha = 0.2) + 
    geom_histogram(data = mediumf0, fill = "blue", alpha = 0.2) +
    geom_histogram(data = highf0, fill = "green", alpha = 0.2) +

これは、いくつかの出力を含む具体的な例です。

dat <- data.frame(xx = c(runif(100,20,50),runif(100,40,80),runif(100,0,30)),yy = rep(letters[1:3],each = 100))

ggplot(dat,aes(x=xx)) + 
    geom_histogram(data=subset(dat,yy == 'a'),fill = "red", alpha = 0.2) +
    geom_histogram(data=subset(dat,yy == 'b'),fill = "blue", alpha = 0.2) +
    geom_histogram(data=subset(dat,yy == 'c'),fill = "green", alpha = 0.2)

これは次のようなものを生成します:

ここに画像の説明を入力してください

タイプミスを修正するために編集。色ではなく塗りたい


7
サブセットのサイズが異なる場合、これは機能しません。これに対処する方法はありますか?(たとえば、「a」で100ポイント、「b」で50ポイントのデータを使用します)。
ホルヘレイタオ、2015

3
このアプローチの欠点の1つは、凡例を表示するのに苦労したことです(これは、私の知識が不足しているためと考えられます)。@kohskeによる以下の他の回答では、デフォルトで凡例が表示されます。凡例は(たとえば、ヒストグラムに表示される特定の色とともに)で変更できscale_fill_manual()ます。
Michael Ohlrogge

1
正確には、これに凡例を追加するにはどうすればよいですか?
shenglih 2017

1
@shenglih伝説については、以下のkohskeの回答の方が適しています。彼の答えも一般的にはましだ。
joran

f0はどこから来たのですか?
アラン

256

@joranのサンプルデータを使用して、

ggplot(dat, aes(x=xx, fill=yy)) + geom_histogram(alpha=0.2, position="identity")

のデフォルトの位置geom_histogramは「スタック」であることに注意してください。

このページの「位置調整」をご覧ください。

docs.ggplot2.org/current/geom_histogram.html


30
コードの繰り返しを避けるので、これが一番の答えになるはずだと思う
kfor

6
position = 'identity'は、より読みやすい回答であるだけでなく、aes()およびへの混合呼び出しなど、より複雑なプロットとうまく調和しますaes_string()
レンサ16

2
この回答では、色の凡例も自動的に表示されますが、@ joranの回答では表示されません。凡例は、たとえばを使用して変更できscale_fill_manual()ます。この関数は、ヒストグラムの色を変更するためにも使用できます。
Michael Ohlrogge

4
また、で使用される変数fillが要因であることを確認してください。
HHH

9
個人的には、stackoverflowは最も賛成された回答を最初にリストするべきだと思います。「正解」は一人の意見のみを表します。
daknowles 2017

25

ggplot2で複数の/重複するヒストグラムをプロットするのに必要な線は数本だけですが、結果は常に満足できるものではありません。目がヒストグラム区別できるようにするには、境界線とカラーリング適切に使用する必要があります。

次の関数は、境界線の色、不透明度、重ね合わせた密度プロットのバランスをとって、ビューアが分布区別できるようにします。

単一のヒストグラム

plot_histogram <- function(df, feature) {
    plt <- ggplot(df, aes(x=eval(parse(text=feature)))) +
    geom_histogram(aes(y = ..density..), alpha=0.7, fill="#33AADE", color="black") +
    geom_density(alpha=0.3, fill="red") +
    geom_vline(aes(xintercept=mean(eval(parse(text=feature)))), color="black", linetype="dashed", size=1) +
    labs(x=feature, y = "Density")
    print(plt)
}

複数のヒストグラム

plot_multi_histogram <- function(df, feature, label_column) {
    plt <- ggplot(df, aes(x=eval(parse(text=feature)), fill=eval(parse(text=label_column)))) +
    geom_histogram(alpha=0.7, position="identity", aes(y = ..density..), color="black") +
    geom_density(alpha=0.7) +
    geom_vline(aes(xintercept=mean(eval(parse(text=feature)))), color="black", linetype="dashed", size=1) +
    labs(x=feature, y = "Density")
    plt + guides(fill=guide_legend(title=label_column))
}

使用法

必要な引数とともにデータフレームを上記の関数渡すだけです。

plot_histogram(iris, 'Sepal.Width')

ここに画像の説明を入力してください

plot_multi_histogram(iris, 'Sepal.Width', 'Species')

ここに画像の説明を入力してください

plot_multi_histogram の追加パラメーターは、カテゴリーラベルを含む列の名前です。

これは、さまざまな分散手段を備えたデータフレームを作成することで、より劇的にわかります

a <-data.frame(n=rnorm(1000, mean = 1), category=rep('A', 1000))
b <-data.frame(n=rnorm(1000, mean = 2), category=rep('B', 1000))
c <-data.frame(n=rnorm(1000, mean = 3), category=rep('C', 1000))
d <-data.frame(n=rnorm(1000, mean = 4), category=rep('D', 1000))
e <-data.frame(n=rnorm(1000, mean = 5), category=rep('E', 1000))
f <-data.frame(n=rnorm(1000, mean = 6), category=rep('F', 1000))
many_distros <- do.call('rbind', list(a,b,c,d,e,f))

以前と同様にデータフレームを渡す(およびオプションを使用してチャートを拡大する):

options(repr.plot.width = 20, repr.plot.height = 8)
plot_multi_histogram(many_distros, 'n', 'category')

ここに画像の説明を入力してください


1
これは非常に便利です。
エドワードタイラー

2
@EdwardTyler非常に真実です。これを2回以上賛成できるといいのですが。
ayePete
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.