如何增加ggplot2条形图中条形之间的间距?

发布于 2024-10-11 21:40:15 字数 72 浏览 5 评论 0原文

如何增加 ggplot2 条形图中条形之间的间距?

How can I increase the space between the bars in a bar plot in ggplot2 ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

情深如许 2024-10-18 21:40:15

您始终可以使用 width 参数,如下所示:

df <- data.frame(x=factor(LETTERS[1:4]), y=sample(1:100, 4))
library(ggplot2)
ggplot(data=df, aes(x=x, y=y, width=.5)) + 
  geom_bar(stat="identity", position="identity") +
  opts(title="width = .5") + labs(x="", y="") +
  theme_bw()

与以下 width 的其他设置进行比较:

alt text

到目前为止,一切顺利。现在,假设我们有两个因素。如果您想使用均匀间隔的并置条形(例如在 barplot() 中将 spacebeside=TRUE 一起使用时),可以使用使用 geom_bar(position="dodge") 不太容易:您可以更改条形宽度,但不能在相邻条形之间添加空间(我在 Google 上没有找到方便的解决方案)。我最终得到了类似的结果:

df <- data.frame(g=gl(2, 1, labels=letters[1:2]), y=sample(1:100, 4))
x.seq <- c(1,2,4,5)
ggplot(data=transform(df, x=x.seq), aes(x=x, y=y, width=.85)) +
  geom_bar(stat="identity", aes(fill=g)) + labs(x="", y="") + 
  scale_x_discrete(breaks = NA) + 
  geom_text(aes(x=c(sum(x.seq[1:2])/2, sum(x.seq[3:4])/2), y=0, 
                label=c("X","Y")), vjust=1.2, size=8)

用于 $x$ 轴的向量被“注入”到 data.frame 中,这样您就可以根据需要更改外部间距,而 width 允许控制内部间距。 $x$ 轴的标签可以通过使用 scale_x_discrete() 来增强。

替代文本

You can always play with the width parameter, as shown below:

df <- data.frame(x=factor(LETTERS[1:4]), y=sample(1:100, 4))
library(ggplot2)
ggplot(data=df, aes(x=x, y=y, width=.5)) + 
  geom_bar(stat="identity", position="identity") +
  opts(title="width = .5") + labs(x="", y="") +
  theme_bw()

Compare with the following other settings for width:

alt text

So far, so good. Now, suppose we have two factors. In case you would like to play with evenly spaced juxtaposed bars (like when using space together with beside=TRUE in barplot()), it's not so easy using geom_bar(position="dodge"): you can change bar width, but not add space in between adjacent bars (and I didn't find a convenient solution on Google). I ended up with something like that:

df <- data.frame(g=gl(2, 1, labels=letters[1:2]), y=sample(1:100, 4))
x.seq <- c(1,2,4,5)
ggplot(data=transform(df, x=x.seq), aes(x=x, y=y, width=.85)) +
  geom_bar(stat="identity", aes(fill=g)) + labs(x="", y="") + 
  scale_x_discrete(breaks = NA) + 
  geom_text(aes(x=c(sum(x.seq[1:2])/2, sum(x.seq[3:4])/2), y=0, 
                label=c("X","Y")), vjust=1.2, size=8)

The vector used for the $x$-axis is "injected" in the data.frame, so that so you change the outer spacing if you want, while width allows to control for inner spacing. Labels for the $x$-axis might be enhanced by using scale_x_discrete().

alt text

如梦 2024-10-18 21:40:15

对于因子条之间的空间,使用

ggplot(data = d, aes(x=X, y=Y, fill=F)) 
 + geom_bar(width = 0.8, position = position_dodge(width = 0.9))

geom_bar 中的宽度控制相对于 x 轴的条宽度,而position_dodge 中的宽度控制给予两个条的空间宽度(也相对于 x 轴)。尝试调整宽度,找到您喜欢的宽度。

For space between factor bars use

ggplot(data = d, aes(x=X, y=Y, fill=F)) 
 + geom_bar(width = 0.8, position = position_dodge(width = 0.9))

The width in geom_bar controls the bar width in relation to the x-axis while the width in position_dodge control the width of the space given to both bars also in relation to the x-axis. Play around with the width to find one that you like.

超可爱的懒熊 2024-10-18 21:40:15

ggplot 3.0.0 开始,您可以使用 position_dodge2。它需要一个 padding 参数来在条之间添加空间。

library(ggplot2) # version >= 3.0.0
set.seed(1530676800) # 
tib <- tibble(
  group=rep(LETTERS[1:4], each=3), 
  subgroup=rep(letters[24:26], 4),
  y=sample(1:100, 4*3)
)
ggplot(tib, aes(x=group, fill=subgroup, y=y)) + 
  geom_col(position=position_dodge2()) 

ggplot2 geom_col 与position_dodge2 默认内边距

默认内边距为 0.1。因为我知道您想看到不同的填充选项:

library(purrr)
library(cowplot)
theme_set(theme_cowplot())

n_col <- 2
bottom_row_starts <- 3
plots0 <- purrr::imap(0.1*c(1:4), \(pad, idx) {
  ret <- ggplot(tib, aes(x=group, fill=subgroup, y=y)) + 
    geom_col(position=position_dodge2(padding=pad)) +
    labs(subtitle=paste0("Padding = ", pad)) #+
    #theme(plot.margin = margin(6, 0, 6, 0))
  if (bottom_row_starts > idx) {
    ret <- ret + xlab(NULL)
  }
  if(1 != (idx %% n_col)) {
    ret <- ret + ylab(NULL)
  }
  return(ret)
})
leg <- cowplot::get_legend(plots0[[1]])

plots <- plots0 %>% purrr::map(\(pp) {
  pp + theme(legend.position="none")
})

cowplot::plot_grid(
  plotlist=plots,
  ncol=n_col
) %>% cowplot::plot_grid(
  leg, 
  rel_widths = c(4, 1)
)

ggplot2 geom_col 与position_dodge2 不同的填充与cowplotplot_grid 排列

As of ggplot 3.0.0, you can use position_dodge2. It takes a padding argument that adds space in between the bars.

library(ggplot2) # version >= 3.0.0
set.seed(1530676800) # 
tib <- tibble(
  group=rep(LETTERS[1:4], each=3), 
  subgroup=rep(letters[24:26], 4),
  y=sample(1:100, 4*3)
)
ggplot(tib, aes(x=group, fill=subgroup, y=y)) + 
  geom_col(position=position_dodge2()) 

ggplot2 geom_col with position_dodge2 default padding

Default padding is 0.1. Since I know you want to see different padding options:

library(purrr)
library(cowplot)
theme_set(theme_cowplot())

n_col <- 2
bottom_row_starts <- 3
plots0 <- purrr::imap(0.1*c(1:4), \(pad, idx) {
  ret <- ggplot(tib, aes(x=group, fill=subgroup, y=y)) + 
    geom_col(position=position_dodge2(padding=pad)) +
    labs(subtitle=paste0("Padding = ", pad)) #+
    #theme(plot.margin = margin(6, 0, 6, 0))
  if (bottom_row_starts > idx) {
    ret <- ret + xlab(NULL)
  }
  if(1 != (idx %% n_col)) {
    ret <- ret + ylab(NULL)
  }
  return(ret)
})
leg <- cowplot::get_legend(plots0[[1]])

plots <- plots0 %>% purrr::map(\(pp) {
  pp + theme(legend.position="none")
})

cowplot::plot_grid(
  plotlist=plots,
  ncol=n_col
) %>% cowplot::plot_grid(
  leg, 
  rel_widths = c(4, 1)
)

ggplot2 geom_col with position_dodge2 varied padding arranged with cowplot plot_grid

情徒 2024-10-18 21:40:15

非常感谢chl.!我遇到了同样的问题,你帮我解决了。我没有使用 geom_text 添加 X 标签,而是使用scale_x_continuous(见下文)

geom_text(aes(x=c(sum(x.seq[1:2])/2, sum(x.seq[3:4])/2), y=0, 
            label=c("X","Y")), vjust=1.2, size=8)

替换为

scale_x_continuous(breaks=c(mean(x.seq[1:2]), mean(x.seq[3:4])), labels=c("X", "Y")) 

Thank you very much chl.! I had the same problem and you helped me solving it. Instead of using geom_text to add the X-labels I used scale_x_continuous (see below)

geom_text(aes(x=c(sum(x.seq[1:2])/2, sum(x.seq[3:4])/2), y=0, 
            label=c("X","Y")), vjust=1.2, size=8)

replaced by

scale_x_continuous(breaks=c(mean(x.seq[1:2]), mean(x.seq[3:4])), labels=c("X", "Y")) 
苍风燃霜 2024-10-18 21:40:15

对于 POSIXlt 条之间的空间,您需要根据一天中的秒数调整宽度

# POSIXlt example: full & half width
d <- data.frame(dates = strptime(paste(2016, "01", 1:10, sep = "-"), "%Y-%m-%d"),
            values = 1:10)

ggplot(d, aes(dates, values)) +
  geom_bar(stat = "identity", width = 60*60*24) 

ggplot(d, aes(dates, values)) +
  geom_bar(stat = "identity", width = 60*60*24*0.5) 

For space between POSIXlt bars you need adjust the width from the number of seconds in a day

# POSIXlt example: full & half width
d <- data.frame(dates = strptime(paste(2016, "01", 1:10, sep = "-"), "%Y-%m-%d"),
            values = 1:10)

ggplot(d, aes(dates, values)) +
  geom_bar(stat = "identity", width = 60*60*24) 

ggplot(d, aes(dates, values)) +
  geom_bar(stat = "identity", width = 60*60*24*0.5) 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文