Как заштриховать часть кривой плотности в ggplot (без данных оси y)

Я пытаюсь создать кривую плотности в R, используя набор случайных чисел от 1000, и заштриховать ту часть, которая меньше или равна определенному значению. Существует множество решений, включающих geom_area или geom_ribbon, но все они требуют yval, которого у меня нет (это просто вектор из 1000 чисел). Есть идеи, как я могу это сделать?

Два других связанных вопроса:

  1. Можно ли сделать то же самое для функции совокупной плотности (в настоящее время я использую stat_ecdf для ее создания) или вообще затенять ее?
  2. Есть ли способ отредактировать geom_vline, чтобы он поднимался только до высоты кривой плотности, а не всей оси y?

Код: (geom_area - это неудачная попытка отредактировать какой-то код, который я нашел. Если я установлю ymax вручную, я просто получу столбец, занимающий весь график, а не только область под кривой)

set.seed(100)

amount_spent <- rnorm(1000,500,150)
amount_spent1<- data.frame(amount_spent)
rand1 <- runif(1,0,1000)
amount_spent1$pdf <- dnorm(amount_spent1$amount_spent)

mean1 <- mean(amount_spent1$amount_spent)

#density/bell curve
ggplot(amount_spent1,aes(amount_spent)) +
   geom_density( size=1.05, color="gray64", alpha=.5, fill="gray77") +
   geom_vline(xintercept=mean1, alpha=.7, linetype="dashed", size=1.1, color="cadetblue4")+
   geom_vline(xintercept=rand1, alpha=.7, linetype="dashed",size=1.1, color="red3")+
   geom_area(mapping=aes(ifelse(amount_spent1$amount_spent > rand1,amount_spent1$amount_spent,0)), ymin=0, ymax=.03,fill="red",alpha=.3)+
   ylab("")+ 
   xlab("Amount spent on lobbying (in Millions USD)")+
   scale_x_continuous(breaks=seq(0,1000,100))

person user3711502    schedule 04.07.2015    source источник
comment
Я думаю, что в этом случае может быть проще либо рассчитать плотность вне ggplot, либо использовать внутренние компоненты th eplot. Если p - ваш основной график плотности: d <- ggplot_build(p)$data[[1]] ; p + geom_area(data = subset(d, x > rand1), aes(x=x, y=y), fill="red")   -  person user20650    schedule 04.07.2015


Ответы (1)


Есть несколько вопросов, подтверждающих это ... здесь и здесь, но они вычисляют плотность перед нанесением на график.

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

# Your data
set.seed(100)
amount_spent1 <- data.frame(amount_spent=rnorm(1000, 500, 150))

mean1 <- mean(amount_spent1$amount_spent)
rand1 <- runif(1,0,1000)

График базовой плотности

p <- ggplot(amount_spent1, aes(amount_spent)) +
          geom_density(fill="grey") +
          geom_vline(xintercept=mean1) 

Вы можете извлечь позиции x и y для области, которую нужно затенять, из графического объекта, используя ggplot_build. Для получения значения y при x=rand1 использовалась линейная интерполяция.

# subset region and plot
d <- ggplot_build(p)$data[[1]]

p <- p + geom_area(data = subset(d, x > rand1), aes(x=x, y=y), fill="red") +
          geom_segment(x=rand1, xend=rand1, 
                       y=0, yend=approx(x = d$x, y = d$y, xout = rand1)$y,
                       colour="blue", size=3)

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

person user20650    schedule 04.07.2015
comment
Есть дюжина вопросов, задающих одно и то же, и это самый точный ответ. - person kmm; 16.02.2017