두 점 사이의 커널 밀도 플롯 음영.
분포를 설명하기 위해 커널 밀도 플롯을 자주 사용합니다. 다음과 같이 R에서 쉽고 빠르게 만들 수 있습니다.
set.seed(1)
draws <- rnorm(100)^2
dens <- density(draws)
plot(dens)
#or in one line like this: plot(density(rnorm(100)^2))
이 멋진 작은 PDF를 제공합니다.
75 번째 백분위 수에서 95 번째 백분위 수까지 PDF 아래 영역을 음영 처리하고 싶습니다. quantile
함수를 사용하여 포인트를 계산하는 것은 쉽습니다 .
q75 <- quantile(draws, .75)
q95 <- quantile(draws, .95)
그러나 어떻게 I 그늘 사이의 영역을 수행 q75
하고 q95
?
이 polygon()
기능을 사용하면 도움말 페이지를 참조하십시오. 여기에서도 비슷한 질문이 있다고 생각합니다.
실제 (x,y)
쌍 을 얻으려면 분위수 값의 인덱스를 찾아야합니다 .
편집 : 여기 있습니다 :
x1 <- min(which(dens$x >= q75))
x2 <- max(which(dens$x < q95))
with(dens, polygon(x=c(x[c(x1,x1:x2,x2)]), y= c(0, y[x1:x2], 0), col="gray"))
출력 (JDL에 의해 추가됨)
또 다른 해결책 :
dd <- with(dens,data.frame(x,y))
library(ggplot2)
qplot(x,y,data=dd,geom="line")+
geom_ribbon(data=subset(dd,x>q75 & x<q95),aes(ymax=y),ymin=0,
fill="red",colour=NA,alpha=0.5)
결과:
확장 된 솔루션 :
두 꼬리를 모두 음영 처리하고 (Dirk 코드 복사 및 붙여 넣기) 알려진 x 값을 사용하려면 다음을 수행하십시오.
set.seed(1)
draws <- rnorm(100)^2
dens <- density(draws)
plot(dens)
q2 <- 2
q65 <- 6.5
qn08 <- -0.8
qn02 <- -0.2
x1 <- min(which(dens$x >= q2))
x2 <- max(which(dens$x < q65))
x3 <- min(which(dens$x >= qn08))
x4 <- max(which(dens$x < qn02))
with(dens, polygon(x=c(x[c(x1,x1:x2,x2)]), y= c(0, y[x1:x2], 0), col="gray"))
with(dens, polygon(x=c(x[c(x3,x3:x4,x4)]), y= c(0, y[x3:x4], 0), col="gray"))
결과:
이 질문에는 lattice
답 이 필요합니다 . 다음은 Dirk와 다른 사람들이 사용하는 방법을 간단히 적용한 매우 기본적인 것입니다.
#Set up the data
set.seed(1)
draws <- rnorm(100)^2
dens <- density(draws)
#Put in a simple data frame
d <- data.frame(x = dens$x, y = dens$y)
#Define a custom panel function;
# Options like color don't need to be hard coded
shadePanel <- function(x,y,shadeLims){
panel.lines(x,y)
m1 <- min(which(x >= shadeLims[1]))
m2 <- max(which(x <= shadeLims[2]))
tmp <- data.frame(x1 = x[c(m1,m1:m2,m2)], y1 = c(0,y[m1:m2],0))
panel.polygon(tmp$x1,tmp$y1,col = "blue")
}
#Plot
xyplot(y~x,data = d, panel = shadePanel, shadeLims = c(1,3))
다음 ggplot2
은 원래 데이터 값에서 커널 밀도를 근사화하는 함수를 기반으로 한 또 다른 변형입니다.
approxdens <- function(x) {
dens <- density(x)
f <- with(dens, approxfun(x, y))
f(x)
}
밀도 추정치의 x 및 y 값으로 새 데이터 프레임을 생성하는 대신 원래 데이터를 사용하면 분위수 값이 데이터가 그룹화되는 변수에 따라 달라지는면 처리 된 플롯에서도 작업 할 수있는 이점이 있습니다.
사용 된 코드
library(tidyverse)
library(RColorBrewer)
# dummy data
set.seed(1)
n <- 1e2
dt <- tibble(value = rnorm(n)^2)
# function that approximates the density at the provided values
approxdens <- function(x) {
dens <- density(x)
f <- with(dens, approxfun(x, y))
f(x)
}
probs <- c(0.75, 0.95)
dt <- dt %>%
mutate(dy = approxdens(value), # calculate density
p = percent_rank(value), # percentile rank
pcat = as.factor(cut(p, breaks = probs, # percentile category based on probs
include.lowest = TRUE)))
ggplot(dt, aes(value, dy)) +
geom_ribbon(aes(ymin = 0, ymax = dy, fill = pcat)) +
geom_line() +
scale_fill_brewer(guide = "none") +
theme_bw()
# dummy data with 2 groups
dt2 <- tibble(category = c(rep("A", n), rep("B", n)),
value = c(rnorm(n)^2, rnorm(n, mean = 2)))
dt2 <- dt2 %>%
group_by(category) %>%
mutate(dy = approxdens(value),
p = percent_rank(value),
pcat = as.factor(cut(p, breaks = probs,
include.lowest = TRUE)))
# faceted plot
ggplot(dt2, aes(value, dy)) +
geom_ribbon(aes(ymin = 0, ymax = dy, fill = pcat)) +
geom_line() +
facet_wrap(~ category, nrow = 2, scales = "fixed") +
scale_fill_brewer(guide = "none") +
theme_bw()
2018-07-13 reprex 패키지 (v0.2.0)에 의해 생성되었습니다 .
참고 URL : https://stackoverflow.com/questions/3494593/shading-a-kernel-density-plot-between-two-points
'developer tip' 카테고리의 다른 글
ES6 템플릿 리터럴은 런타임에 대체 (또는 재사용) 할 수 있습니까? (0) | 2020.09.01 |
---|---|
기하 평균 : 내장 기능이 있습니까? (0) | 2020.09.01 |
Matplotlib-X 축 레이블을 아래쪽으로 이동하지만 X 축 눈금은 이동하지 않습니다. (0) | 2020.09.01 |
충돌 해결 : "자신의"변경 사항을 자동으로 수락하는 방법은 무엇입니까? (0) | 2020.09.01 |
Jupyter 노트북의 tqdm (0) | 2020.09.01 |