如何用for循环批量绘制ggplot?动态传列名适配geom_histogram怎么做?
解决方案
ggplot2现在推荐用**整洁评估(tidy evaluation)**语法实现动态列名传入,完全兼容批量绘图需求,不需要使用已经被弃用的aes_string,也不要直接提取数据框列传入aes映射。
场景1:直接传入未加引号的列名
适合手动调用函数的场景,用卷曲运算符{{ }}实现:
# 封装绘图函数 plot_hist <- function(data, x_col, group_col) { ggplot(data, aes(x = {{ x_col }})) + geom_histogram( # 新版本ggplot2可将y = ..density..替换为y = after_stat(density) aes(y = ..density.., color = {{ group_col }}, fill = {{ group_col }}), alpha = 0.4, position = "identity" ) + geom_density(aes(color = {{ group_col }}), size = 1) + labs( x = rlang::as_name(rlang::enquo(x_col)), color = rlang::as_name(rlang::enquo(group_col)), fill = rlang::as_name(rlang::enquo(group_col)) ) } # 调用示例 plot_hist(t1, Flight.Distance, satisfaction)
场景2:传入字符串格式列名(适配for循环批量绘图)
适合批量循环时传字符串列名的场景,用.data[[ ]]语法实现:
# 封装绘图函数 plot_hist_str <- function(data, x_col_str, group_col_str) { ggplot(data, aes(x = .data[[x_col_str]])) + geom_histogram( aes(y = ..density.., color = .data[[group_col_str]], fill = .data[[group_col_str]]), alpha = 0.4, position = "identity" ) + geom_density(aes(color = .data[[group_col_str]]), size = 1) + labs( x = x_col_str, color = group_col_str, fill = group_col_str ) } # 单图调用示例 plot_hist_str(t1, "Flight.Distance", "satisfaction")
for循环批量绘图示例
# 定义要批量绘制的X轴列列表 x_cols <- c("Flight.Distance", "Departure.Delay.in.Minutes", "Arrival.Delay.in.Minutes") # 定义分组列 group_col <- "satisfaction" # 批量生成并保存图片 plot_list <- list() for (i in seq_along(x_cols)) { current_plot <- plot_hist_str(t1, x_cols[i], group_col) plot_list[[i]] <- current_plot # 直接保存到本地 ggsave(paste0("直方图_", x_cols[i], ".png"), current_plot, width = 8, height = 6) }
之前代码的问题说明
- 直接用
t1[['列名']]传入aes:相当于将列作为独立外部向量传入,ggplot不会将其识别为数据框的内置列,容易出现映射错位、图例标签异常的问题 - 先设置
theme(legend.position="none")再补充guides:前者已经全局关闭图例展示,后续的图例配置不会生效 - 之前用的
aes_string已经在ggplot2 v3.0.0版本后被正式弃用,后续版本存在兼容性风险,不建议继续使用
内容的提问来源于stack exchange,提问作者JImmy
相关产品推荐
相关产品推荐

