与这个问题类似,我想生成几个始终具有相同条形宽度的单独条形图。也就是说,我还希望在每个图中,条形之间的间距是相同的。
我还需要单独保存这些图,并且每个保存的图像大小与条形数量成正比。我不想使用构面或网格(这意味着关于 SO 的类似问题不适用于我)。此外,我需要一个
geom_bar()
解决方案以及 ggsave()
。
可重现的示例
图书馆
library(tidyverse)
library(ggplot2)
模拟数据(实际上,我有数百个变量,某些因素高达 15 个级别)
df <- structure(list(Animal = structure(c(1L, 2L, 2L, 2L, 1L, 1L, 1L,
1L, 3L, 3L), levels = c("Cat", "Dog", "Horse"), class = "factor"),
Sex = structure(c(2L, 1L, 1L, 1L, 2L, 2L, 1L, 2L, 2L, 2L), levels = c("Female",
"Male"), class = "factor")), row.names = c(NA, 10L), class = "data.frame")
生成条形图的函数
# Create counter
counter <- 0
# Function
make_bar_plots <- function(df){
# We loop over the columns
for (col in colnames(df)){
# (1) Preparation ##########################################################
# Store N
N <- sum(!is.na(df[col]))
# Store number of levels
n_levels <- length(unique(df[!is.na(df[col]), col]))[1]
# Update counter at each iteration
counter <- counter + 1
# (2) Basic bar plot #######################################################
# We only plot factors
if (is.factor(df[[col]])) {
p <- ggplot(data = df[col] %>% filter(!is.na(df[col])),
aes(x=fct_rev(fct_infreq(!!sym(col)))))
# Compute percents for bars
p <- p + geom_bar(aes(y = (..count..)/sum(..count..)),
width = 0.35*n_levels/3, # We make column width proportional to number of levels!
fill = 'black',
size = 1.5
)
# (3) Annotations ########################################################
# Add percent as annotation
p <- p + geom_text(aes(label = scales::percent((..count..)/sum(..count..),
accuracy = 0.1L),
y = ((..count..)/sum(..count..))),
stat="count", hjust = -0.1, size=4.2)
# Add a title
p <- p + labs(title = paste(col),
subtitle = paste0('N = ', format(N, big.mark = ',')
))
# (4) Aesthetics #########################################################
p <- p + theme_minimal()
p <- p + theme(axis.title.y = element_blank(),
axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_text(colour='black', size = 12.5),
plot.margin = margin(r=25, l=1, b=0, t=1),
plot.title = element_text(size = 16.5),
plot.subtitle = element_text(size = 12.5),
panel.grid = element_blank()
)
# Flip coordinates
p <- p + coord_flip(clip = 'off')
# (5) Print and export #################################################
print(p)
# Export
ggsave(paste(counter, '_', col, '.png'), path = 'plots/',
bg = 'white'
)
}
}
}
输出
make_bar_plots(df)
讨论
我们看到两个图中的条形宽度相同。这是通过函数中包含的参数
width = 0.35*n_levels/3
实现的。
也就是说,与男性和女性(图 2)相比,猫、狗和马(图 1)的条形之间的间距是不同的。
我尝试过的:
ggsave()
调用中,使用比例调整生成图像的高度(例如,height = 2*n_levels/3
)。也就是说,生成的图具有不同的条形宽度,请参见下图。p + theme(aspect.ratio = 1/4)
)。这也使得各图的条形宽度不同。使用时图解
height = 2*n_levels/3
我的2个问题: