splited plot 中的自动调整大小和固定宽度条
auto-size and fixed width bars in spited plot
我遇到了麻烦,我不知道该如何解释,所以提前道歉。
我有一个脚本,因为它很大,所以我不会放在这里,所以让我们直接进入问题。
由于脚本生成的徽标是一种直方图,我将尝试用一个示例来模拟该问题。
我正在使用一个函数根据柱数拆分直方图,最后,它生成了一个带有各种 grob 的图,每个 grob 都包含一个直方图。
myranges <- function(start, end, step){
starts <- seq(start, end, step+1)
ends <- pmin(starts + step, end)
data.frame(a = starts, b = ends)
}
d <- data.frame(a = letters[1:10] , b = seq(1, 20, by =2 ))
num_bar_per_hist <- 2
p_list <- apply(
myranges(1, nrow(d), num_bar_per_hist - 1),
1,
function(x){
#as.matrix(d[x[1]:x[2]],)
ggplot(d[x[1]:x[2] , ], aes(x=a, y=b)) +
geom_bar(stat = "identity") +
ylim(0,22) +
theme_classic()
}
)
do.call(gridExtra::grid.arrange, c(p_list, ncol=2))
以上,生成情节的脚本片段。
我更改 var num_bar_per_hist
以拆分直方图。
在这个例子中,我得到了这个:
如果我将 num_bar_per_hist
的值更改为 5 我得到:
这两个例子表明每个图的宽度保持不变,条形的宽度也保持不变。
但是,如果我将 num_bar_per_hist
更改为 3,我会得到:
我想要的是保持条形宽度相同。这意味着,条 j
应该对齐,并且与正上方的条 d
具有相同的宽度。
此外,如果可能的话,我不想更改脚本的结构(太多),或者 easy/small 更改。
在此先感谢您。
谢谢
编辑:
使用cowplot
我可以解决部分问题。 (与第 3 个图的参数相同)
num_bar_per_hist <- 3
p_list <- apply(
myranges(1, nrow(d), num_bar_per_hist - 1),
1,
function(x){
ggdraw() +
draw_plot(
ggplot(d[x[1]:x[2] , ], aes(x=a, y=b)) +
geom_bar(stat = "identity") +
ylim(0, 22),
width = (x[2] - x[1] + 1) / num_bar_per_hist
)
}
)
do.call(gridExtra::grid.arrange, c(p_list, ncol=2))
这样我得到了:
这样我就接近解决方案了。 j
的宽度仍然与其他的不一样,但比第三个图好太多了。
我仍然需要一些技巧或 "magic number" 来改善栏的宽度。由于该策略,导致最后一个 grob 变得比其他人更薄。而且我只想让所有条形保持相同的宽度,而不管每个地块的条形数量差异如何。
你可以挖掘出中断的数量,并从那里修改每个图,通过在 x 尺度上添加虚拟的中断来确保它们都有尽可能多的中断,
how_many <- function(p){
gb <- ggplot_build(p)
length(gb$layout$panel_params[[1]][['x.major']])
}
raxe <- function(p, n){
gb <- ggplot_build(p)
x_params <- gb$layout$panel_params[[1]]
ni <- length(x_params[['x.major']])
labels <- x_params[['x.labels']]
if(ni < n){
dummy <- c(labels, paste0("__",letters[seq_len(n-ni)]))
print(dummy)
phantom <- c(labels, rep('', n-ni))
return(p + scale_x_discrete(lim=dummy, labels=phantom))
}
p
}
n_breaks <- sapply(p_list, how_many)
p_list <- lapply(p_list, raxe, max(n_breaks))
egg::ggarrange(plots = p_list, ncol=2)
我遇到了麻烦,我不知道该如何解释,所以提前道歉。
我有一个脚本,因为它很大,所以我不会放在这里,所以让我们直接进入问题。
由于脚本生成的徽标是一种直方图,我将尝试用一个示例来模拟该问题。
我正在使用一个函数根据柱数拆分直方图,最后,它生成了一个带有各种 grob 的图,每个 grob 都包含一个直方图。
myranges <- function(start, end, step){
starts <- seq(start, end, step+1)
ends <- pmin(starts + step, end)
data.frame(a = starts, b = ends)
}
d <- data.frame(a = letters[1:10] , b = seq(1, 20, by =2 ))
num_bar_per_hist <- 2
p_list <- apply(
myranges(1, nrow(d), num_bar_per_hist - 1),
1,
function(x){
#as.matrix(d[x[1]:x[2]],)
ggplot(d[x[1]:x[2] , ], aes(x=a, y=b)) +
geom_bar(stat = "identity") +
ylim(0,22) +
theme_classic()
}
)
do.call(gridExtra::grid.arrange, c(p_list, ncol=2))
以上,生成情节的脚本片段。
我更改 var num_bar_per_hist
以拆分直方图。
在这个例子中,我得到了这个:
如果我将 num_bar_per_hist
的值更改为 5 我得到:
这两个例子表明每个图的宽度保持不变,条形的宽度也保持不变。
但是,如果我将 num_bar_per_hist
更改为 3,我会得到:
我想要的是保持条形宽度相同。这意味着,条 j
应该对齐,并且与正上方的条 d
具有相同的宽度。
此外,如果可能的话,我不想更改脚本的结构(太多),或者 easy/small 更改。
在此先感谢您。 谢谢
编辑:
使用cowplot
我可以解决部分问题。 (与第 3 个图的参数相同)
num_bar_per_hist <- 3
p_list <- apply(
myranges(1, nrow(d), num_bar_per_hist - 1),
1,
function(x){
ggdraw() +
draw_plot(
ggplot(d[x[1]:x[2] , ], aes(x=a, y=b)) +
geom_bar(stat = "identity") +
ylim(0, 22),
width = (x[2] - x[1] + 1) / num_bar_per_hist
)
}
)
do.call(gridExtra::grid.arrange, c(p_list, ncol=2))
这样我得到了:
这样我就接近解决方案了。 j
的宽度仍然与其他的不一样,但比第三个图好太多了。
我仍然需要一些技巧或 "magic number" 来改善栏的宽度。由于该策略,导致最后一个 grob 变得比其他人更薄。而且我只想让所有条形保持相同的宽度,而不管每个地块的条形数量差异如何。
你可以挖掘出中断的数量,并从那里修改每个图,通过在 x 尺度上添加虚拟的中断来确保它们都有尽可能多的中断,
how_many <- function(p){
gb <- ggplot_build(p)
length(gb$layout$panel_params[[1]][['x.major']])
}
raxe <- function(p, n){
gb <- ggplot_build(p)
x_params <- gb$layout$panel_params[[1]]
ni <- length(x_params[['x.major']])
labels <- x_params[['x.labels']]
if(ni < n){
dummy <- c(labels, paste0("__",letters[seq_len(n-ni)]))
print(dummy)
phantom <- c(labels, rep('', n-ni))
return(p + scale_x_discrete(lim=dummy, labels=phantom))
}
p
}
n_breaks <- sapply(p_list, how_many)
p_list <- lapply(p_list, raxe, max(n_breaks))
egg::ggarrange(plots = p_list, ncol=2)