将空间和宽度参数连接到条形图以对齐2x1绘图窗口

Mic*_*ico 9 plot r bar-chart

我想barplot在下面对齐底部,以便这些在两个图之间垂直排列:

par(mfrow = c(2, 1))
n = 1:5
barplot(-2:2, width = n, space = .2)

barplot(matrix(-10:9, nrow = 4L, ncol = 5L), beside = TRUE,
        width = rep(n/4, each = 5L), space = c(0, .8))
Run Code Online (Sandbox Code Playgroud)

对齐不好

我一直盯着(从)的定义spacewidth论证一段时间,我真的期望上面的工作(但很明显没有):barplot?barplot

width - 条宽的可选矢量.重新循环以延长绘制的条数.指定单个值将没有可见效果......

space - 每个条形之前留下的空间量(作为平均条宽的一部分).每个条形码可以作为单个数字或一个数字给出.如果height是矩阵并且besideTRUE,space可以由两个数,其中第一个是条之间在同一组和组之间的空间中的空间,所述第二指定.如果没有明确给出,则默认为c(0,1)if height是一个矩阵,而且besideTRUE,0.2否则.

当我读到它时,这意味着我们应该能够通过将每个组划分为4(因此n/4)来匹配顶部图中的组宽度.对于space,因为我们将每个栏的宽度由4,平均宽度的意志为好; 因此,我们应该将该分数乘以4来补偿这一点(因此space = c(0, 4*.2)).

然而,它似乎被忽略了.事实上,似乎所有的盒子都有相同的宽度!在摆弄时,我只能让相对的组内宽度发生变化.

是否有可能实现我的想法barplot?如果没有,有人可以说如何做到这一点ggplot2吗?

Len*_*nyy 11

也可以使用基本绘图来执行此操作,但它有助于将矩阵作为第二个绘图的向量传递.随后,您需要意识到空间参数是平均条宽的一小部分.我做了如下:

par(mfrow = c(2, 1))
widthsbarplot1 <- 1:5
spacesbarplot1 <- c(0, rep(.2, 4))

barplot(-2:2, width = widthsbarplot1, space = spacesbarplot1)

widthsbarplot2 <- rep(widthsbarplot1/4, each = 4)
spacesbetweengroupsbarplot2 <- mean(widthsbarplot2)

allspacesbarplot2 <- c(rep(0,4), rep(c(spacesbetweengroupsbarplot2, rep(0,3)), 4))

matrix2 <- matrix(-10:9, nrow = 4L, ncol = 5L)

barplot(c(matrix2),
    width = widthsbarplot2,
    space = allspacesbarplot2,
    col = c("red", "yellow", "green", "blue"))
Run Code Online (Sandbox Code Playgroud)

基础情节


Axe*_*man 6

您实际上也可以将ggplot中的宽度作为向量传递.你需要ggplot2的开发版才能得到正确的躲避:

library(dplyr)
library(ggplot2)

df1 <- data.frame(n = 1:5, y = -2:2)
df1$x <- cumsum(df1$n)
df2 <- data.frame(n = rep(1:5, each = 4), y2 = -10:9)
df2$id <- 1:4                                                    # just for the colors

df3 <- full_join(df1, df2)

p1 <- ggplot(df1, aes(x, y)) + geom_col(width = df1$n, col = 1)
p2 <- ggplot(df3, aes(x, y2, group = y2, fill = factor(id))) + 
  geom_col(width = df3$n, position = 'dodge2', col = 1) +
  scale_fill_grey(guide = 'none')

cowplot::plot_grid(p1, p2, ncol = 1, align = 'v')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Cat*_*ath 6

另一种方式,仅使用base R并且仍然使用barplot(不是"向下" rect)是在几个barplot调用中执行它,使用add=TRUE,space将组的组放在正确的位置.

正如已经强调的那样,问题是space与平均值成正比width.所以你需要纠正这个问题.

这是我的方式:

# draw first barplot, getting back the value
bp <- barplot(-2:2, width = n, space = .2)

# get the xlim
x_rg <- par("usr")[1:2]

# plot the "frame"
plot(0, 0, type="n", axes=FALSE, xlab="", ylab="", xlim=x_rg, xaxs="i", ylim=range(as.vector(pr_bp2)))

# plot the groups of bars, one at a time, specifying space, with a correction according to width, so that each group start where it should
sapply(1:5, function(i) barplot(pr_bp2[, i, drop=FALSE], beside = TRUE, width = n[i]/4, space = c((bp[i, 1]-n[i]/2)/(n[i]/4), rep(0, 3)), add=TRUE))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


eip*_*i10 5

您可以通过明确设置条形的x轴位置并使用geom_rect绘图来在ggplot2中执行此操作.这是一个可能比它需要的更复杂的例子,但希望它将展示基本的想法:

library(tidyverse)

sp = 0.4

d1 = data.frame(value=-2:2) %>% 
  mutate(key=paste0("V", 1:n()),
         width=1:n(),
         spacer = cumsum(rep(sp, n())) - sp,
         xpos = cumsum(width) - 0.5*width + spacer)

d2 = matrix(-10:9, nrow = 4L, ncol = 5L) %>% 
  as.tibble %>% 
  gather(key, value) %>%
  mutate(width = as.numeric(gsub("V","",key))) %>% 
  group_by(key) %>% 
  mutate(width = width/n()) %>% 
  ungroup %>% 
  mutate(spacer = rep(cumsum(rep(sp, length(unique(key)))) - sp, each=4),
         xpos = cumsum(width) - 0.5*width + spacer)

d = bind_rows(list(d1=d1, d2=d2), .id='source') %>% 
  group_by(source, key) %>% 
  mutate(group = LETTERS[1:n()])

ggplot(d, aes(fill=group, colour=group)) +
  geom_rect(aes(xmin=xpos-0.5*width, xmax=xpos+0.5*width, ymin=0, ymax=value)) +
  facet_grid(source ~ ., scales="free_y") +
  theme_bw() +
  guides(fill=FALSE, colour=FALSE) +
  scale_x_continuous(breaks = d1$xpos, labels=d1$key)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 我希望`ggplot`解决方案会更简洁,稍微仔细看看...对于基础,我知道(终极)备份只是用`rect`构建情节,但我宁愿不完全乏味 (2认同)
  • 嗯,已经很晚了.也许我早上醒来后会有一个更优雅的答案! (2认同)