对于大多数用例来说,ggplot2 能够很好地缩放以适应不同大小的视口,这是其最大的资产之一。然而,在这种情况下,您实际上希望主绘图面板中的对象大小固定,这会让生活变得更加困难。其原因是面板尺寸本身不固定。相反,它根据设备尺寸增大和缩小,从而允许绘图的某些其他元素(例如轴元素、文本和标题)保持固定尺寸。
这是可能的,但这并不容易。为此,您需要:
- 修复整个图的大小(以像素为单位)
- 将绘图面板的大小固定为总绘图宽度的比例
- 根据 x 轴上的项目数量自动计算条形宽度。
如果您认为这一切听起来太麻烦,那么我可能会同意。如果你想制作很多情节,这是值得做的。对于这里或那里的奇怪情况,我可能会沿 x 轴添加虚拟因子水平以保持绘图一致,然后使用成像软件剪掉轴上的额外空间。
然而,它is可能,所以就其价值而言,这里是一个使用编程方法将条形固定为 51 像素宽、6 像素间隙的示例:
library(ggplot2)
library(dplyr)
p_all_bars <-
mpg %>%
ggplot(aes(x = class)) +
geom_bar() +
scale_x_discrete(expand = expansion(0, 1/7))
p_two_bars <-
mpg %>%
filter(class == "compact" | class == "suv") %>%
ggplot(aes(x = class)) +
geom_bar() +
scale_x_discrete(expand = expansion(mult = 0, 1/2))
two_bars <- ggplot_gtable(ggplot_build(p_two_bars))
all_bars <- ggplot_gtable(ggplot_build(p_all_bars))
all_bars$widths[5] <- unit(14, "cm")
all_bars$widths[1] <- unit(1, "null")
two_bars$widths[5] <- unit(4, "cm")
two_bars$widths[1] <- unit(1, "null")
png("twobars.png", width = 500, height = 500)
plot(two_bars)
dev.off()
png("allbars.png", width = 500, height = 500)
plot(all_bars)
dev.off()
两栏.png
![enter image description here](https://i.stack.imgur.com/GgztV.png)
所有栏.png
![enter image description here](https://i.stack.imgur.com/nKZRF.png)
EDIT
另一种方法是将面板保持固定宽度并使用coord_cartesian
保持条形宽度恒定。
取以下函数:
library(ggplot2)
library(dplyr)
fixed_bars <- function(data, var, ncols = 6) {
ncols <- ncols + 2
data <- mutate(data, {{var}} := as.factor({{var}}))
levs <- length(levels(pull(data, {{var}})))
extra <- ncols - levs
x_range <- range(as.numeric(pull(data, {{var}}))) + c(-0.5, 0.5) * extra
ggplot(data, aes(x = {{var}})) +
geom_bar() +
coord_cartesian(xlim = x_range)
}
这允许以下行为:
mpg %>%
fixed_bars(class)
![](https://i.stack.imgur.com/6VSQa.png)
mpg %>%
filter(class == "compact" | class == "suv") %>%
fixed_bars(class)
![](https://i.stack.imgur.com/BE8K9.png)
Created on 2020-12-24 by the reprex package (v0.3.0)