R에서 ggplot2로 히스토그램 오버레이


124

저는 R을 처음 접했고 같은 그래프에 3 개의 히스토그램을 그리려고합니다. 모든 것이 잘 작동했지만 내 문제는 2 개의 히스토그램이 겹치는 부분을 볼 수 없다는 것입니다.

밀도 플롯을 만들면 완벽 해 보입니다. 각 곡선은 검은 색 프레임 선으로 둘러싸여 있고 곡선이 겹치는 부분에서는 색상이 다르게 보입니다.

누군가가 첫 번째 사진의 히스토그램으로 비슷한 것을 얻을 수 있는지 말해 줄 수 있습니까? 이것은 내가 사용하는 코드입니다.

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
히스토그램과 밀도 플롯에 대한 하이퍼 링크가 깨졌습니다
Daghan ---

답변:


115

현재 코드 :

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

의 모든 값을 사용하여 하나의 히스토그램 ggplot을 구성한 다음 변수에 따라이 단일 히스토그램의 막대에 색을 지정하라고 말합니다 .f0utt

대신 원하는 것은 알파 블렌딩을 사용하여 서로를 통해 볼 수 있도록 세 개의 개별 히스토그램을 만드는 것입니다. 당신은 아마 별도의 세 가지 호출을 사용하고자하는 그래서에 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 점이있는 데이터 사용).
Jorge Leitao

3
이 접근 방식의 한 가지 단점은 범례를 표시하는 데 어려움이 있다는 것입니다 (이는 지식이 부족하기 때문일 수 있음). @kohske의 다른 답변은 기본적으로 다음과 같이 수정할 수있는 범례를 표시합니다 (히스토그램에 표시된 특정 색상과 함께) scale_fill_manual().
Michael Ohlrogge

1
정확히 어떻게 이것에 범례를 추가 할 수 있습니까 ??
shenglih

1
@shenglih 전설의 경우 아래 kohske의 대답이 더 좋습니다. 그의 대답은 일반적으로 더 좋습니다.
joran

f0은 어디에서 왔습니까?
Alan

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().
rensa

2
이 답변은 자동으로 색상에 대한 범례를 표시하지만 @joran의 답변은 그렇지 않습니다. 그런 다음 예를 들어를 사용하여 범례를 수정할 수 있습니다 scale_fill_manual(). 이 기능을 사용하여 히스토그램의 색상을 수정할 수도 있습니다.
Michael Ohlrogge

4
또한에서 사용 된 변수 fill가 요인 인지 확인하십시오 .
hhh

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
이것은 매우 유용하며 더 많은 관심을 끌기를 바랍니다.
Edward Tyler

2
@EdwardTyler 매우 사실입니다. 나는 이것을 두 번 이상 찬성 할 수 있으면 좋겠다!
ayePete 19
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.