ggplot:根据相对位置在密度线之间着色区域 [英] ggplot: colouring areas between density lines according to relative position

查看:134
本文介绍了ggplot:根据相对位置在密度线之间着色区域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个情节

  set.seed(28100)
df< - data.frame(value =样本(1:10000,1000,替换= TRUE),
性别=样本(c(男性,女性),1000,替换= TRUE))

ggplot df,aes(value))+
geom_density()+
geom_density(data = subset(df,gender =='male'),aes(value),color =blue)+
geom_density(data = subset(df,gender =='female'),aes(value),color =red)

我想知道是否可以用两种颜色填充红色和蓝色密度线之间的区域:当蓝线位于红线之上时为一种颜色,蓝线之下时为不同颜色。

解决方案

除非您自己明确计算区域,否则没有简单的方法可以在不同的重叠区域进行着色。这里有一个函数可以帮助计算密度交换位置的区域。
$ b $ pre $ densitysplit < - function(val,grp,N = 200, x = seq(min(val),max(val),length.out = N)){
grp < - factor(grp)
den < - Map b $ b dx< -density(val [grp == z])
approxfun(dx $ x,dx $ y)(x)
},levels(grp))
maxcat< ; - 应用(do.call(cbind,den),1,which.max)
data.frame(x = x,ymin = do.call(pmin,den),ymax = do。呼叫(pmax,den),
top =级别(grp)[maxcat],
group = cumsum(c(1,diff(maxcat)!= 0))




$ b $ p
$ b

对于你的数据,你可以做这样的事情。

  head(densitysplit(df $ value,df $ gender))
#x ymin ymax top group
#1 8.00000 4.214081e- 05 5.198326e-05男性1
#2 58.17085 4.485596e-05 5.433638e-05男性1
#3 108.34171 4.760983e-05 5.665547e-05男性1
# 4 158.51256 5.039037e-05 5.893143e-05男1
#5 208.68342 5.318724e-05 6.115595e-05男1
#6 258.85427 5.598707e-05 6.332672e-05男1

这给你提供了使用 geom_ribbon 来绘制的数据数据。你可以这样做:

pre $ g $ p $ ggplot(df,aes(value))+
geom_ribbon(data = densitysplit(df $ value ,df $ gender),aes(x,ymin = ymin,ymax = ymax,fill = top,group = group))+
geom_density()+
geom_density(data = subset(df,gender = ='male'),aes(value),color =blue)+
geom_density(data = subset(df,gender =='female'),aes(value),color =red)


I have this plot

set.seed(28100)
df <- data.frame(value = sample(1:10000,1000,replace=TRUE),
                 gender = sample(c("male","female"),1000,replace=TRUE))

ggplot(df, aes(value)) + 
  geom_density() +
  geom_density(data=subset(df, gender=='male'), aes(value), colour="blue") +
  geom_density(data=subset(df, gender=='female'), aes(value), colour="red")

I wonder if it's conceivable to fill the areas between the red and blue density lines with two colours: one colour when the blue line is above the red line and a different colour when the blue line is below.

解决方案

There's no easy way to color in different overlapping regions unless you explicitly calculate the regions yourself. Here's a function that can help calculate regions where densities swap places

densitysplit <- function(val, grp, N=200, x=seq(min(val), max(val), length.out=N)) {
    grp <- factor(grp)
    den <- Map(function(z) {
        dx<-density(val[grp==z])
          approxfun(dx$x, dx$y)(x)
    }, levels(grp))
    maxcat <- apply(do.call("cbind",den), 1, which.max)
    data.frame(x=x, ymin=do.call("pmin", den), ymax=do.call("pmax", den), 
        top = levels(grp)[maxcat],
        group = cumsum(c(1,diff(maxcat)!=0))
    )
}

For your data, you would do something like this

head(densitysplit(df$value, df$gender))
#           x         ymin         ymax  top group
# 1   8.00000 4.214081e-05 5.198326e-05 male     1
# 2  58.17085 4.485596e-05 5.433638e-05 male     1
# 3 108.34171 4.760983e-05 5.665547e-05 male     1
# 4 158.51256 5.039037e-05 5.893143e-05 male     1
# 5 208.68342 5.318724e-05 6.115595e-05 male     1
# 6 258.85427 5.598707e-05 6.332672e-05 male     1

This gives you the data you need to use geom_ribbon to plot the data. You can do

ggplot(df, aes(value)) + 
  geom_ribbon(data=densitysplit(df$value, df$gender), aes(x, ymin=ymin, ymax=ymax, fill=top, group=group)) + 
  geom_density() +
  geom_density(data=subset(df, gender=='male'), aes(value), colour="blue") +
  geom_density(data=subset(df, gender=='female'), aes(value), colour="red")

这篇关于ggplot:根据相对位置在密度线之间着色区域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆