Menghamparkan histogram dengan ggplot2 di R

124

Saya baru mengenal R dan mencoba memplot 3 histogram ke grafik yang sama. Semuanya bekerja dengan baik, tetapi masalah saya adalah Anda tidak melihat di mana 2 histogram tumpang tindih - mereka terlihat agak terpotong.

Saat saya membuat plot kepadatan, itu terlihat sempurna: setiap kurva dikelilingi oleh garis bingkai hitam, dan warna terlihat berbeda di tempat kurva tumpang tindih.

Bisakah seseorang memberi tahu saya jika sesuatu yang serupa dapat dicapai dengan histogram pada gambar pertama? Ini adalah kode yang saya gunakan:

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)
Berbunga
sumber
3
Hyperlink ke histogram dan plot kepadatan rusak
Daghan ---

Jawaban:

115

Kode Anda saat ini:

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

memberitahu ggplotuntuk membangun satu histogram menggunakan semua nilai di f0dan kemudian mewarnai batang histogram tunggal ini sesuai dengan variabel utt.

Yang Anda inginkan adalah membuat tiga histogram terpisah, dengan pencampuran alfa sehingga terlihat satu sama lain. Jadi Anda mungkin ingin menggunakan tiga panggilan terpisah ke geom_histogram, di mana masing-masing mendapatkan bingkai datanya sendiri dan mengisi:

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) +

Berikut adalah contoh konkret dengan beberapa keluaran:

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)

yang menghasilkan sesuatu seperti ini:

masukkan deskripsi gambar di sini

Diedit untuk memperbaiki kesalahan ketik; Anda menginginkan isi, bukan warna.

joran
sumber
7
Ini tidak berfungsi jika subset memiliki ukuran yang berbeda. Tahu bagaimana mengatasi ini? (Misalnya, gunakan data dengan 100 poin di "a", 50 di "b").
Jorge Leitao
3
Satu kelemahan dari pendekatan ini adalah saya kesulitan membuatnya menampilkan legenda (meskipun ini mungkin saja karena kurangnya pengetahuan saya). Jawaban lain di bawah oleh @kohske secara default akan menampilkan legenda yang kemudian dapat dimodifikasi (bersama dengan warna tertentu yang ditampilkan pada histogram) dengan, mis scale_fill_manual().
Michael Ohlrogge
1
tepatnya, bagaimana kita bisa menambahkan legenda ke ini ??
shenglih
1
@shenglih Untuk seorang legenda, jawaban kohske di bawah ini lebih baik. Jawabannya juga secara umum lebih baik.
joran
darimana f0 berasal?
Alan
256

Menggunakan data sampel @ joran,

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

perhatikan bahwa posisi default geom_histogramadalah "stack."

lihat "penyesuaian posisi" halaman ini:

docs.ggplot2.org/current/geom_histogram.html

kohske
sumber
30
Saya pikir ini harus menjadi jawaban teratas karena menghindari pengulangan kode
k untuk
6
position = 'identity'bukan hanya jawaban yang lebih mudah dibaca, tetapi juga lebih bagus dengan plot yang lebih rumit, seperti panggilan campuran ke aes()dan aes_string().
rensa
2
Jawaban ini juga akan secara otomatis menampilkan legenda warna, sedangkan jawaban oleh @joran tidak. Legenda kemudian dapat dimodifikasi menggunakan, mis scale_fill_manual(). Fungsi ini juga dapat digunakan untuk mengubah warna dalam histogram.
Michael Ohlrogge
4
Juga, pastikan bahwa variabel yang digunakan filladalah faktor.
hhh
9
Secara pribadi saya pikir stackoverflow harus mencantumkan jawaban yang paling banyak dipilih terlebih dahulu. "Jawaban yang benar" hanya mewakili pendapat satu orang.
daknowles
25

Meskipun hanya beberapa baris yang diperlukan untuk memplot beberapa / histogram yang tumpang tindih di ggplot2, hasilnya tidak selalu memuaskan. Batas dan pewarnaan harus digunakan dengan benar untuk memastikan mata dapat membedakan histogram .

Fungsi berikut menyeimbangkan warna batas, kekeruhan, dan plot kepadatan yang dilapiskan untuk memungkinkan pengamat membedakan di antara distribusi .

Histogram tunggal :

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)
}

Beberapa histogram :

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))
}

Pemakaian :

Cukup berikan bingkai data Anda ke fungsi di atas bersama dengan argumen yang diinginkan:

plot_histogram(iris, 'Sepal.Width')

masukkan deskripsi gambar di sini

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

masukkan deskripsi gambar di sini

The parameter tambahan di plot_multi_histogram adalah nama kolom yang berisi label kategori.

Kita dapat melihat ini secara lebih dramatis dengan membuat kerangka data dengan berbagai cara distribusi :

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))

Meneruskan bingkai data seperti sebelumnya (dan grafik pelebaran menggunakan opsi):

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

masukkan deskripsi gambar di sini

Berhubung dgn sibernetika
sumber
1
Hal ini sangat bermanfaat, semoga mendapat perhatian lebih.
Edward Tyler
2
@EwardTy Sangat benar. Saya berharap saya dapat meningkatkan ini lebih dari sekali!
ayePete