在密度图下方添加箱线图 [英] Adding boxplot below density plot

查看:235
本文介绍了在密度图下方添加箱线图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是ggplot的新手,正在尝试创建此图:

I'm new to ggplot and I'm trying to create this graph:

但是实际上,我只是停留在这里:

But actually, I'm just stuck here:

这是我的代码:

ggplot(diamonds)  + 
  aes(x = carat, group = cut) + 
  geom_line(stat = "density", size = 1) + 
  theme_grey() + 
  facet_wrap(~cut, nrow = 5, strip.position = "right") + 
  geom_boxplot(aes())

有人知道我下一步可以做什么吗?

Does someone know what I can do next?

推荐答案

自ggplot2 3.3.0起,可以在ggplot2中完成此操作,而无需任何扩展包.

在包裹的新闻下,功能:

所有具有方向(即x和y轴在哪里)的几何和统计 有不同的解释),现在可以自由选择方向了, 而不是依赖coord_flip().方向从 美观的贴图,但也可以直接使用新的贴图指定 orientation参数(@ thomasp85,#3506).

All geoms and stats that had a direction (i.e. where the x and y axes had different interpretation), can now freely choose their direction, instead of relying on coord_flip(). The direction is deduced from the aesthetic mapping, but can also be specified directly with the new orientation argument (@thomasp85, #3506).

以下内容现在将直接起作用(将原始答案中所有对geom_boxploth/stat_boxploth的引用替换为geom_boxplot/stat_boxplot:

The following will now work directly (replacing all references to geom_boxploth / stat_boxploth in the original answer with geom_boxplot / stat_boxplot:

library(ggplot2)

ggplot(diamonds, aes(x = carat, y = -0.5)) +

  # horizontal boxplots & density plots
  geom_boxplot(aes(fill = cut)) +
  geom_density(aes(x = carat), inherit.aes = FALSE) +
  
  # vertical lines at Q1 / Q2 / Q3
  stat_boxplot(geom = "vline", aes(xintercept = ..xlower..)) +
  stat_boxplot(geom = "vline", aes(xintercept = ..xmiddle..)) +
  stat_boxplot(geom = "vline", aes(xintercept = ..xupper..)) +
  
  facet_grid(cut ~ .) +
  scale_fill_discrete()


原始答案

可以使用水平箱线图geom_boxploth()/stat_boxploth()轻松完成此操作,该图可在 ggstance 包:

This can be done easily with a horizontal boxplot geom_boxploth() / stat_boxploth(), found in the ggstance package:

library(ggstance)

ggplot(diamonds, aes(x = carat, y = -0.5)) +

  # horizontal box plot
  geom_boxploth(aes(fill = cut)) +

  # normal density plot
  geom_density(aes(x = carat), inherit.aes = FALSE) +

  # vertical lines at Q1 / Q2 / Q3
  stat_boxploth(geom = "vline", aes(xintercept = ..xlower..)) +
  stat_boxploth(geom = "vline", aes(xintercept = ..xmiddle..)) +
  stat_boxploth(geom = "vline", aes(xintercept = ..xupper..)) +
  
  facet_grid(cut ~ .) +
  
  # reproduce original chart's color scale (o/w ordered factors will result
  # in viridis scale by default, using the current version of ggplot2)
  scale_fill_discrete()

如果由于某种原因而仅限于ggplot2软件包,则仍然可以这样做,但是由于geom_boxplot()geom_density()朝着不同的方向发展,因此它会变得不那么直接.

If you are limited to the ggplot2 package for one reason or another, it can still be done, but it would be less straightforward, since geom_boxplot() and geom_density() go in different directions.

替代1 :计算箱形图的坐标,将结果传递到ggplot()之前,请先手动翻转它们.以常规方式添加密度层:

Alternative 1: calculate the box plot's coordinates, & flip them manually before passing the results to ggplot(). Add a density layer in the normal way:

library(dplyr)
library(tidyr)

p.box <- ggplot(diamonds, aes(x = cut, y = carat)) + geom_boxplot()    
p.box.data <- layer_data(p.box) %>%
  select(x, ymin, lower, middle, upper, ymax, outliers) %>%
  mutate(cut = factor(x, labels = levels(diamonds$cut), ordered = TRUE)) %>%
  select(-x)

ggplot(p.box.data) +
  
  # manually plot flipped boxplot
  geom_segment(aes(x = ymin, xend = ymax, y = -0.5, yend = -0.5)) +
  geom_rect(aes(xmin = lower, xmax = upper, ymin = -0.75, ymax = -0.25, fill = cut),
            color = "black") +
  geom_point(data = . %>% unnest(outliers),
             aes(x = outliers, y = -0.5)) +
  
  # vertical lines at Q1 / Q2 / Q3
  geom_vline(data = . %>% select(cut, lower, middle, upper) %>% gather(key, value, -cut),
             aes(xintercept = value)) +
  
  # density plot
  geom_density(data = diamonds, aes(x = carat)) +

  facet_grid(cut ~ .) +
  labs(x = "carat") +
  scale_fill_discrete()

替代2 :计算密度图的坐标&将结果传递到ggplot()之前,请先手动翻转它们.以常规方式添加箱形图图层.翻转整个图表:

Alternative 2: calculate the density plot's coordinates, & flip them manually before passing the results to ggplot(). Add a box plot layer in the normal way. Flip the whole chart:

p.density <- ggplot(diamonds, aes(x = carat, group = cut)) + geom_density()    
p.density.data <- layer_data(p.density) %>%
  select(x, y, group) %>%
  mutate(cut = factor(group, labels = levels(diamonds$cut), ordered = TRUE)) %>%
  select(-group)
p.density.data <- p.density.data %>%
  rbind(p.density.data %>% 
          group_by(cut) %>% 
          filter(x == min(x)) %>% 
          mutate(y = 0) %>% 
          ungroup())

ggplot(diamonds, aes(x = -0.5, y = carat)) +

  # manually flipped density plot
  geom_polygon(data = p.density.data, aes(x = y, y = x), 
               fill = NA, color = "black") +

  # box plot
  geom_boxplot(aes(fill = cut, group = cut)) +

  # vertical lines at Q1 / Q2 / Q3
  stat_boxplot(geom = "hline", aes(yintercept = ..lower..)) +
  stat_boxplot(geom = "hline", aes(yintercept = ..middle..)) +
  stat_boxplot(geom = "hline", aes(yintercept = ..upper..)) +

  facet_grid(cut ~ .) +
  scale_fill_discrete() +
  coord_flip()

这篇关于在密度图下方添加箱线图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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