填写geom_violin图中的特定区域

jor*_*ran 5 r ggplot2

如何根据固定的截止值geom_violinggplot2中填充不同颜色的图?

例如,给定设置:

library(ggplot2)

set.seed(123)
dat <- data.frame(x = rep(1:3,each = 100),
                  y = c(rnorm(100,-1),rnorm(100,0),rnorm(100,1)))
dat$f <- with(dat,ifelse(y >= 0,'Above','Below'))
Run Code Online (Sandbox Code Playgroud)

我想采取这个基本情节:

ggplot() + 
    geom_violin(data = dat,aes(x = factor(x),y = y))
Run Code Online (Sandbox Code Playgroud)

并且简单地让每个小提琴在零上下都有不同的颜色.尝试的天真的东西,映射fill美学,分裂和闪避小提琴的情节:

ggplot() + 
    geom_violin(data = dat,aes(x = factor(x),y = y, fill = f))
Run Code Online (Sandbox Code Playgroud)

这不是我想要的.我想在每个x值上都有一个小提琴曲线,但内部充满了零度以上和零度以下的不同颜色.

jor*_*ran 7

这是一种方法.

library(ggplot2)
library(plyr)

#Data setup
set.seed(123)
dat <- data.frame(x = rep(1:3,each = 100),
                  y = c(rnorm(100,-1),rnorm(100,0),rnorm(100,1)))
Run Code Online (Sandbox Code Playgroud)

首先,我们将使用ggplot::ggplot_build捕获绘制小提琴图的所有计算变量:

p <- ggplot() + 
    geom_violin(data = dat,aes(x = factor(x),y = y))
p_build <- ggplot2::ggplot_build(p)$data[[1]]
Run Code Online (Sandbox Code Playgroud)

接下来,如果我们看一下源代码,geom_violin我们会看到它在将其移交geom_polygon给绘制小提琴区域的实际轮廓之前对该计算数据帧进行了一些特定的转换.

因此,我们将模仿该过程并简单地手动绘制填充的多边形:

#This comes directly from the source of geom_violin
p_build <- transform(p_build,
                     xminv = x - violinwidth * (x - xmin),
                     xmaxv = x + violinwidth * (xmax - x))

p_build <- rbind(plyr::arrange(transform(p_build, x = xminv), y),
                 plyr::arrange(transform(p_build, x = xmaxv), -y))
Run Code Online (Sandbox Code Playgroud)

我在源代码中省略了一个关于复制第一行的小细节,以确保关闭多边形.

现在我们做两个最后的修改:

#Add our fill variable
p_build$fill_group <- ifelse(p_build$y >= 0,'Above','Below')
#This is necessary to ensure that instead of trying to draw
# 3 polygons, we're telling ggplot to draw six polygons
p_build$group1 <- with(p_build,interaction(factor(group),factor(fill_group)))
Run Code Online (Sandbox Code Playgroud)

最后的情节:

#Note the use of the group aesthetic here with our computed version,
# group1
p_fill <- ggplot() + 
    geom_polygon(data = p_build,
                 aes(x = x,y = y,group = group1,fill = fill_group))
p_fill
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

请注意,一般情况下,这将破坏对任何分类x轴标签的良好处理.因此,您经常需要使用连续的x轴进行绘图,然后如果需要分类标签,请手动添加.