首页 > 解决方案 > 在 ggplot 中覆盖离散和连续层 - 对层顺序很重要感到惊讶

问题描述

考虑以下示例数据集:

library(dplyr)
library(ggplot2)

d = mtcars %>% 
 as_tibble(rownames = "name") %>% 
 mutate(wt.cat = cut(wt, seq(1.5, 5.5, by = 1))) %>%
 group_by(wt.cat) %>%
 summarize(
   Mean = mean(mpg),
   Min = min(mpg),
   Max = max(mpg)
 )

假设我想为每个类别的“平均值”值wt.cat和显示范围的功能区绘制点。这有效:

ggplot(d, aes(x = wt.cat)) + 
  geom_point(aes(y= Mean)) +
  geom_ribbon(aes(x = as.numeric(wt.cat), ymin = Min, ymax = Max), fill = "blue") 

示例 1

但是这些点被丝带掩盖了。但是,如果我更改图层的顺序以便将点绘制在功能区顶部,则会出现错误:

ggplot(d, aes(x = wt.cat)) + 
  geom_ribbon(aes(x = as.numeric(wt.cat), ymin = Min, ymax = Max), fill = "blue") +
  geom_point(aes(y= Mean))
## Error: Discrete value supplied to continuous scale

因此,即使我将离散轴指定为“默认”美学,它也会被第一个绘制层的规范覆盖。我能找到的唯一方法是首先绘制一个虚拟点图层:

ggplot(d, aes(x = wt.cat)) + 
  geom_point(aes(y= Mean), shape = NA) +
  geom_ribbon(aes(x = as.numeric(wt.cat), ymin = Min, ymax = Max), fill = "blue") +
  geom_point(aes(y= Mean))
## Warning message:
## Removed 4 rows containing missing values (geom_point). 

示例 2

有没有更“正确”或更正确的方法来组合离散层和连续层?是否有不需要创建虚拟层的解决方案?

标签: rggplot2

解决方案


这样的事情会是一个解决方案吗?

d %>% {
  ggplot(., aes(x = wt.cat)) + 
    scale_x_discrete(labels = levels(.$wt.cat)) +
    geom_ribbon(aes(x =as.numeric(wt.cat), ymin = Min, ymax = Max), fill = "blue")  +
    geom_point(aes(y=Mean)) 
} 

我刚刚了解到您可以用 包裹管道,{ }然后使用 引用整个数据框.

正如卡米尔所说,问题在于geom_ribbon需要一个连续的比例,因为它绘制了与相邻位置相关的值的区域。我相信添加时比例会转换为连续geom_ribbon,但标签会保留。

希望这可以帮助

ggplot2根据我的回复——如果你想处理所有的标签,下面的工作也一样

d %>% 
      ggplot(aes(x = wt.cat)) + 
        scale_x_discrete() +
        geom_ribbon(aes(x =as.numeric(wt.cat), ymin = Min, ymax = Max), fill = "blue")  +
        geom_point(aes(y=Mean)) 

推荐阅读