Наложение гистограмм с помощью ggplot2 в R

124

Я новичок в R и пытаюсь построить 3 гистограммы на одном графике. Все работало нормально, но моя проблема в том, что вы не видите, где перекрываются две гистограммы - они выглядят довольно обрезанными.

Когда я делаю графики плотности, это выглядит идеально: каждая кривая окружена черной рамкой, и цвета выглядят по-разному там, где кривые перекрываются.

Может ли кто-нибудь сказать мне, можно ли добиться чего-то подобного с гистограммами на первом изображении? Это код, который я использую:

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)

сообщает, что ggplotнужно построить одну гистограмму, используя все значения, f0а затем раскрасить столбцы этой отдельной гистограммы в соответствии с переменной utt.

Вместо этого вы хотите создать три отдельные гистограммы с альфа-смешиванием, чтобы они были видны друг через друга. Поэтому вы, вероятно, захотите использовать три отдельных вызова 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)

что производит что-то вроде этого:

введите описание изображения здесь

Отредактировано для исправления опечаток; вам нужна заливка, а не цвет.

Joran
источник
7
Это не работает, если подмножество имеет другой размер. Есть идеи, как это решить? (Например, используйте данные со 100 точками на «a», 50 на «b»).
Хорхе Лейтао,
3
Одним из недостатков этого подхода является то, что мне было трудно заставить его отображать легенду (хотя это могло быть просто из-за моего незнания). Другой ответ ниже @kohske по умолчанию будет отображать легенду, которую затем можно изменить (вместе с определенными цветами, отображаемыми на гистограмме), например scale_fill_manual().
Майкл Олрогге
1
собственно, как мы можем добавить к этому легенду ??
shenglih
1
@shenglih Для легенды ответ Коске ниже лучше. Его ответ также в целом лучше.
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

kohske
источник
30
Я думаю, что это должен быть лучший ответ, поскольку он позволяет избежать повторения кода
kfor
6
position = 'identity'это не просто более читаемый ответ, он лучше подходит для более сложных графиков, таких как смешанные вызовы aes()и aes_string().
rensa
2
Этот ответ также автоматически отобразит легенду для цветов, тогда как ответ @joran не будет. Легенда может быть изменена с помощью, например scale_fill_manual(). Эту функцию также можно использовать для изменения цветов гистограмм.
Майкл Ольрогге
4
Также убедитесь, что переменная, используемая в, fillявляется фактором.
чч
9
Лично я думаю, что stackoverflow должен сначала перечислить ответ, за который проголосовали больше всего. «Правильный ответ» отражает мнение только одного человека.
daknowles
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 Совершенно верно. Хотел бы я проголосовать за это больше одного раза!
ayePete