繁体   English   中英

如何使用 ggplot2 中的 position_dodge() 为 geom_col() 中的每个条获得相同的宽度?

[英]How to get the same width for every bar in this geom_col() with position_dodge() in ggplot2?

我正在尝试重现以下情节:

在此处输入图片说明

到目前为止,我已经在 R 中生成了以下代码:

library(tidyverse)

tribble(~attribute, ~level, ~importance_score,
        "Price", "$70 per month", -0.18,
        "Price", "$50 per month", 0,
        "Price", "$30 per month", 0.18,
        "Data included", "500MB", -0.25,
        "Data included", "1GB", -0.10,
        "Data included", "10GB", 0.11,
        "Data included", "Unlimited", 0.23,
        "International minutes included", "0 min", -0.01,
        "International minutes included", "90 min", -0.01,
        "International minutes included", "300 min", 0.02,
        "SMS included", "300 messages", -0.06,
        "SMS included", "Unlimited text", 0.06) %>% 
  mutate(id = 1:nrow(.)) %>% 
  arrange(desc(id)) %>% 
  mutate(attribute = as_factor(attribute),
         level = as_factor(level)) %>%
  ggplot(aes(attribute, importance_score, fill = level)) +
  geom_col(width = 0.5, position = position_dodge(0.75)) +
  coord_flip() +
  scale_y_continuous(breaks = seq(-0.4, 0.4, by = 0.1), limits = c(-0.35, 0.35)) +
  scale_fill_manual(values = c("$70 per month" = "#721817",
                               "$50 per month" = "#721817",
                               "$30 per month" = "#721817",
                               "500 MB" = "#fa9f42",
                               "1GB" = "#fa9f42",
                               "10GB" = "#fa9f42",
                               "Unlimited" = "#fa9f42",
                               "0 min" = "#2b4162",
                               "90 min" = "#2b4162",
                               "300 min" = "#2b4162",
                               "300 messages" = "#0b6e4f",
                               "Unlimited text" = "#0b6e4f")) +
  labs(y = "Relative value", x = "Levels by attribute") +
  theme(panel.grid.minor = element_blank(),
        panel.grid.major.y = element_blank(),
        panel.grid.major.x = element_line(color = "gray95", linetype = 1, size = 1),
        panel.grid.major = element_blank(),
        panel.background = element_blank(),
        legend.position = "none",
        text = element_text(size = 15))

输出以下图:

在此处输入图片说明

我的问题是,您将如何在不搞乱position = position_dodge()参数的情况下控制geom_col()width参数,这允许绘图按“属性”变量进行分组? 我想要的是该图中的每个条具有相同的宽度,并且每个分组变量之间的距离也相同。

当我使用position = position_dodge(0.75, preserve = "single") ,我得到:

在此处输入图片说明

在这种情况下,在这个图中看的不是很清楚,但是:我在图顶部绘制的两个绿色括号之间的长度不一样。 我该如何解决这个问题

实现您想要的结果的一种选择是像这样使用facet_grid

  1. y上映射factor(id)而不是atrribute
  2. attribute面。 添加scales="free_y"space=free_y
  3. 通过theme选项设置条形文本的样式并去除轴标签和刻度。
  4. 要在条形组之间添加一些空间,您可以调整y比例的扩展

注意:据我所知,您可以在fill上映射attribute ,这将简化您的scale_fill_manual因为您只需要设置四种颜色。

library(tidyverse)

dd <- dd %>% 
  mutate(id = 1:nrow(.)) %>% 
  arrange(desc(id)) %>% 
  mutate(attribute = forcats::fct_rev(as_factor(attribute)),
          level = as_factor(level))

ggplot(dd, aes(importance_score, factor(id), fill = attribute)) +
  geom_col() +
  scale_x_continuous(breaks = seq(-0.4, 0.4, by = 0.1), limits = c(-0.35, 0.35), expand = c(0, 0)) +
  scale_y_discrete(expand = expansion(add = c(1, 1))) +
  scale_fill_manual(values = c("Price" = "#721817", 
                               "Data included" = "#fa9f42",
                               "International minutes included" = "#2b4162",
                               "SMS included" = "#0b6e4f")) +
  labs(y = "Relative value", x = "Levels by attribute") +
  facet_grid(attribute ~ ., scales = "free_y", space = "free_y", switch = "y") +
  theme(panel.grid.minor = element_blank(),
        panel.grid.major.y = element_blank(),
        panel.grid.major.x = element_line(color = "gray95", linetype = 1, size = 1),
        panel.grid.major = element_blank(),
        panel.background = element_blank(),
        legend.position = "none",
        text = element_text(size = 15),
        strip.text.y.left = element_text(angle = 360, hjust = 1),
        strip.background.y = element_blank(),
        axis.text.y = element_blank(),
        axis.ticks.y = element_blank(),
        axis.ticks.length.y = unit(0, "pt"),
        panel.spacing.y = unit(0, "pt")
        )

数据

dd <- tribble(~attribute, ~level, ~importance_score,
        "Price", "$70 per month", -0.18,
        "Price", "$50 per month", 0,
        "Price", "$30 per month", 0.18,
        "Data included", "500MB", -0.25,
        "Data included", "1GB", -0.10,
        "Data included", "10GB", 0.11,
        "Data included", "Unlimited", 0.23,
        "International minutes included", "0 min", -0.01,
        "International minutes included", "90 min", -0.01,
        "International minutes included", "300 min", 0.02,
        "SMS included", "300 messages", -0.06,
        "SMS included", "Unlimited text", 0.06)

暂无
暂无

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

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