简体   繁体   English

使用ggplot2渐变填充小提琴图

[英]gradient fill violin plots using ggplot2

I want to gradient fill a violin plot based on the density of points in the bins (blue for highest density and red for lowest).我想根据箱中点的密度渐变填充小提琴图(蓝色代表最高密度,红色代表最低)。

I have generated a plot using the following commands but failed to color it based on density (in this case the width of the violin. I also would like to generate box plots with similar coloring).我使用以下命令生成了一个图,但未能根据密度(在这种情况下是小提琴的宽度)对其进行着色。我也想生成具有相似着色的箱线图。

library("ggplot2")
data(diamonds)

ggplot(diamonds, aes(x=cut,y=carat)) + geom_violin() 

to change the colour of the violin plot you use fill = variable, like this:要更改小提琴图的颜色,请使用 fill = variable,如下所示:

ggplot(diamonds, aes(x=cut,y=carat)) + geom_violin(aes(fill=cut)) 

same goes for boxplot箱线图也一样

ggplot(diamonds, aes(x=cut,y=carat)) + geom_boxplot(aes(fill=cut)) 

在此处输入图片说明

but whatever value you have has to have the same value for each cut, that is, if you wanted to use for example mean depth/cut as the color variable you would have to code it.但是无论您拥有什么值,每次切割都必须具有相同的值,也就是说,如果您想使用例如平均深度/切割作为颜色变量,则必须对其进行编码。

with dplyr group your diamonds by cut and with summarize get the mean depth (or any other variable)使用 dplyr 将您的钻石按切割分组,并使用汇总获得平均深度(或任何其他变量)

library(dplyr)
diamonds_group <- group_by(diamonds, cut)
diamonds_group <- summarize(diamonds_group, Mean_Price = mean(price))

Then I used diamonds2 as a copy of diamonds to then manipulate the dataset然后我使用 diamonds2 作为钻石的副本然后操作数据集

diamonds2 <- diamonds

I merge both dataframes to get the Mean_Depth as a variable in diamonds2我合并两个数据帧以获得 Mean_Depth 作为 diamonds2 中的变量

diamonds2 <- merge(diamonds2, diamonds_group)

And now I can plot it with mean depth as a color variable现在我可以用平均深度作为颜色变量来绘制它

ggplot(diamonds2, aes(x=cut,y=carat)) + geom_boxplot(aes(fill=Mean_Price)) + scale_fill_gradient2(midpoint = mean(diamonds2$price))

在此处输入图片说明

Just answered this for another thread , but believe it's possibly more appropriate for this thread.刚刚为另一个线程回答了这个问题,但相信它可能更适合这个线程。 You can create a pseudo-fill by drawing many segments.您可以通过绘制许多段来创建伪填充。 You can get those directly from the underlying data in the ggplot_built object.您可以直接从 ggplot_built 对象中的基础数据中获取这些。

If you want an additional polygon outline ("border"), you'd need to create this from the x/y coordinates.如果你想要一个额外的多边形轮廓(“边界”),你需要从 x/y 坐标创建它。 Below one option.下面一种选择。

library(tidyverse)

p <- ggplot(diamonds, aes(x=cut,y=carat)) + geom_violin() 

mywidth <- .35 # bit of trial and error

# all you need for the gradient fill 
vl_fill <- data.frame(ggplot_build(p)$data) %>%
  mutate(xnew = x- mywidth*violinwidth, xend = x+ mywidth*violinwidth) 

# the outline is a bit more convoluted, as the order matters
vl_poly <- vl_fill %>%
  select(xnew, xend, y, group) %>%
  pivot_longer(-c(y, group), names_to = "oldx", values_to = "x") %>% 
  arrange(y) %>%
  split(., .$oldx) %>%
  map(., function(x) {
    if(all(x$oldx == "xnew")) x <- arrange(x, desc(y))
    x
    }) %>%
  bind_rows()

ggplot() +
  geom_polygon(data = vl_poly, aes(x, y, group = group), 
               color= "black", size = 1, fill = NA) +  
  geom_segment(data = vl_fill, aes(x = xnew, xend = xend, y = y, yend = y,
                                   color = violinwidth))  

Created on 2021-04-14 by the reprex package (v1.0.0)reprex 包(v1.0.0) 于 2021 年 4 月 14 日创建

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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