geom_bar(position = "dodge") 中条的宽度相同 [英] The same width of the bars in geom_bar(position = "dodge")

查看:37
本文介绍了geom_bar(position = "dodge") 中条的宽度相同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用相同宽度的条形绘制绘图.这是我的最小示例代码:

data <- data.frame(A = 字母 [1:17],B = 样本(1:500, 17),C = c(rep(1, 5), rep(2, 6), rep(c(3,4,5), each = 2)))ggplot(数据,aes(x = C, y = B, 标签 = A,填充 = A)) +geom_bar(stat = "identity", position = "dodge") +geom_text(位置= position_dodge(宽度= 0.9),角度= 90)

结果如上图所示:

条形的宽度取决于变量 C 中给定的组中观察的数量.我想让每个条具有相同的宽度.

facet_grid(~C) 有效(条形宽度相同)这不是我的意思:

ggplot(data,aes(x = C, y = B, 标签 = A,填充 = A)) +geom_bar(stat = "identity", position = "dodge") +geom_text(position = position_dodge(width = 0.9), angle = 90) +facet_grid(~C)

我想要的是像第一张图片中那样的情节,但条形的宽度与 C 列中每个级别的观察次数无关.我该怎么做?

geom_bar(width) 改变了条形组的宽度,但第五组中的条形仍然比第一组中的条形宽,所以这不是我问题的答案.

解决方案

更新

ggplot2_3.0.0 版本开始,您现在可以使用 position_dodge2preserve = c("total", "single")

ggplot(data,aes(x = C, y = B, label = A, fill = A)) +geom_col(position = position_dodge2(width = 0.9, preserve = "single")) +geom_text(位置= position_dodge2(宽度= 0.9,保留=单个"),角度= 90,vjust=0.25)

原答案

正如已经评论过的,你可以像在这个

或者使用交互术语:

数据%>%ggplot(aes(x = 交互(C,A),y = B,填充 = A))+geom_col(位置=闪避")

通过最终将交互转换为数字,您可以根据所需的输出设置 x 轴.通过分组 (group_by),您可以计算匹配的中断.ggplot 参数周围带有 {} 的花哨的东西很容易在管道中直接使用变量 BreaksC.

数据%>%变异(gr=as.numeric(interaction(C, A))) %>%group_by(C)%>%变异(Breaks=mean(gr))%>%{ggplot(data=.,aes(x = gr, y = B, 填充 = A, 标签 = A)) +geom_col(position = "dodge") +geom_text(position = position_dodge(width = 0.9), angle = 90) +scale_x_continuous(breaks = unique(.$Breaks),标签 = 唯一(.$C))}

另一种方法是使用方面.使用 space = "free_x" 允许设置与 x 比例的长度成比例的宽度.

图书馆(tidyverse)数据%>%ggplot(aes(x = A, y = B, 填充 = A)) +geom_col(position = "dodge") +facet_grid(~C, scales = "free_x", space = "free_x")

您还可以使用 switch 在底部绘制刻面标签并删除 x 轴标签

数据%>%ggplot(aes(x = A, y = B, 填充 = A)) +geom_col(position = "dodge") +facet_grid(~C, scales = "free_x", space = "free_x", switch = "x") +主题(axis.text.x = element_blank(),axis.ticks.x = element_blank(),strip.background = element_blank())

I would like to draw plot with the same width of the bars. Here's my minimal example code:

data <- data.frame(A = letters[1:17],
                   B = sample(1:500, 17),
                   C = c(rep(1, 5), rep(2, 6), rep(c(3,4,5), each = 2)))

ggplot(data,
       aes(x = C,  y = B, label = A,
           fill = A)) +
  geom_bar(stat = "identity", position = "dodge") +
  geom_text(position = position_dodge(width = 0.9), angle = 90)

The result is shown in the picture above:

The width of the bars is dependent on numbers of observation in group given in variable C. I want to have each bar to have the same width.

The facet_grid(~C) works (bars are the same width) it's not what I mean:

ggplot(data,
       aes(x = C,  y = B, label = A,
           fill = A)) +
  geom_bar(stat = "identity", position = "dodge") +
  geom_text(position = position_dodge(width = 0.9), angle = 90) +
  facet_grid(~C)

What I want is to have plot like in the first picture but with bars's width independent on number of observation in each level from column C. How can I do it?

[EDIT] geom_bar(width) changes width of the bars'group but still bars in fifth group are wider than in the first group, so it's not the answer to my question.

解决方案

Update

Since ggplot2_3.0.0 version you are now be able to use position_dodge2 with preserve = c("total", "single")

ggplot(data,aes(x = C,  y = B, label = A, fill = A)) +
  geom_col(position = position_dodge2(width = 0.9, preserve = "single")) +
  geom_text(position = position_dodge2(width = 0.9, preserve = "single"), angle = 90, vjust=0.25)

Original answer

As already commented you can do it like in this answer: Transform A and C to factors and add unseen variables using tidyr's complete. Since the recent ggplot2 version it is recommended to use geom_col instead of geom_bar in cases of stat = "identity":

data %>% 
  as.tibble() %>% 
  mutate_at(c("A", "C"), as.factor) %>% 
  complete(A,C) %>% 
  ggplot(aes(x = C,  y = B, fill = A)) +
  geom_col(position = "dodge")

Or work with an interaction term:

data %>% 
  ggplot(aes(x = interaction(C, A),  y = B, fill = A)) +
  geom_col(position = "dodge")

And by finally transforming the interaction to numeric you can setup the x-axis according to your desired output. By grouping (group_by) you can calculate the matching breaks. The fancy stuff with the {} around the ggplot argument is neseccary to directly use the vaiables Breaks and C within the pipe.

data %>% 
  mutate(gr=as.numeric(interaction(C, A))) %>% 
  group_by(C) %>% 
  mutate(Breaks=mean(gr)) %>% 
  {ggplot(data=.,aes(x = gr,  y = B, fill = A, label = A)) +
   geom_col(position = "dodge") +
   geom_text(position = position_dodge(width = 0.9), angle = 90 ) +
   scale_x_continuous(breaks = unique(.$Breaks),
                     labels = unique(.$C))}

Edit:

Another approach would be to use facets. Using space = "free_x" allows to set the width proportional to the length of the x scale.

library(tidyverse)
data %>% 
  ggplot(aes(x = A,  y = B, fill = A))  +  
   geom_col(position = "dodge") +
   facet_grid(~C, scales = "free_x", space = "free_x")

You can also plot the facet labels on the bottom using switch and remove x axis labels

data %>% 
  ggplot(aes(x = A,  y = B, fill = A))  +  
  geom_col(position = "dodge") +
  facet_grid(~C, scales = "free_x", space = "free_x", switch = "x") + 
  theme(axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        strip.background = element_blank())

这篇关于geom_bar(position = "dodge") 中条的宽度相同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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