简体   繁体   中英

Shading (faceted) density plots between two points ggplot2

I am attempting to create a plot that shades the area under the curve of a density plot between two points. Here's what I have so far:

df.ind <- data.frame(x=rnorm(1000))
df.group <- data.frame(group = factor(1:20))
df.group$gr.mean <- rnorm(20)
df.group$width <- 1 + abs(rnorm(20))
df.group$upper <- df.group$gr.mean + df.group$width
df.group$lower <- df.group$gr.mean - df.group$width

I can then create a ggplot where I use the density of x from df.ind and plot it 20 different times (by each group). I then overlay the vertical lines. What I want to do is shade the area between the lines.

ggplot(df.group) + 
  stat_density(data=df.ind, mapping=aes(x), 
               geom="line", position="dodge") +
  facet_wrap(~group) + 
  geom_vline(aes(xintercept=lower)) +
  geom_vline(aes(xintercept=upper))

I'm aware of a similar question here: ggplot2 shade area under density curve by group and here: Shading a kernel density plot between two points.

But my data come from two different data.frame objects. Therefore, I can't use the clever trick they use to aggregate the data...

Like I mentioned in the comments, you are going to have to do the work of creating data specifically for each panel yourself. Here's one way

# calculate density
dx<-density(df.ind$x)

#define areas for each group
mm <- do.call(rbind, Map(function(g, l,u) {
    data.frame(group=g, x=dx$x, y=dx$y, below=dx$x<l, above= dx$x > u)
}, df.group$group, df.group$lower, df.group$upper))

#plot data
p2<-ggplot(mm) + 
   geom_area(aes(x, y, fill=interaction(below,above))) + 
   geom_vline(data=df.group, aes(xintercept=lower)) +
   geom_vline(data=df.group, aes(xintercept=upper)) +
   facet_wrap(~group)

在此输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM