如何用R的ggplot2合理创建条形图?解决温度变量显示问题
优化条形图可视化的几种方案
由于temperature变量的数值量级(0.6左右)远小于precipitation和radiation(100-300区间),直接绘制分组条形图会导致前者的柱子几乎不可见,以下是几种可行的优化方法:
方法1:使用双Y轴适配不同量级
通过设置两个Y轴,分别对应小数值的temperature和大数值的另外两个变量,同时用不同视觉元素区分:
library(tidyverse) df <- tibble( type = c('grass','forest','desert','crop'), temperature = c(0.6206,0.6132,0.6235,0.6134), precipitation = c(252,290,198,337), radiation = c(156,177,123,205) ) # 拆分数据集:温度和其他变量 temp_df <- df %>% select(type, temperature) %>% rename(v = temperature) %>% mutate(n = "temperature") other_df <- df %>% select(type, precipitation, radiation) %>% pivot_longer(cols = -type, names_to = 'n', values_to = 'v') ggplot() + # 绘制大数值变量的条形图(左侧Y轴) geom_bar(data = other_df, aes(x = type, y = v, fill = n), stat = 'identity', position = 'dodge', width = 0.7) + # 绘制温度的点和折线(右侧Y轴,缩放数值适配轴范围) geom_point(data = temp_df, aes(x = type, y = v * 500, color = n), size = 3) + geom_line(data = temp_df, aes(x = type, y = v * 500, color = n), group = 1) + # 设置双Y轴 scale_y_continuous( name = "Precipitation/Radiation", sec.axis = sec_axis(~ . / 500, name = "Temperature") ) + scale_fill_manual(values = c("precipitation" = "#1f77b4", "radiation" = "#ff7f0e")) + scale_color_manual(values = c("temperature" = "#2ca02c")) + labs(title = "环境指标按土地类型分布", fill = "", color = "") + theme_minimal()
方法2:拆分变量为子图(分面展示)
将三个变量分别绘制在独立子图中,每个子图使用自身的Y轴范围,彻底避免量级干扰:
dff <- df %>% pivot_longer(cols = -type, names_to = 'n', values_to = 'v') ggplot(data = dff) + geom_bar(aes(x = type, y = v, fill = n), stat = 'identity', position = 'dodge') + facet_wrap(~n, scales = "free_y") + # 每个子图使用独立Y轴 labs(title = "环境指标按土地类型分布", x = "土地类型", y = "数值") + theme_minimal()
方法3:对变量做标准化处理
将所有变量缩放至同一范围(如Z-score标准化,均值为0、标准差为1),直观比较各变量在不同类型中的相对变化:
dff <- df %>% pivot_longer(cols = -type, names_to = 'n', values_to = 'v') %>% group_by(n) %>% mutate(v_scaled = scale(v)) %>% # 按变量分组标准化 ungroup() ggplot(data = dff) + geom_bar(aes(x = type, y = v_scaled, fill = n), stat = 'identity', position = 'dodge') + labs(title = "标准化环境指标按土地类型分布", x = "土地类型", y = "Z分数") + theme_minimal()
方法4:添加数值标签强化小数值展示
如果坚持使用单Y轴,给temperature的柱子添加数值标签,让观众直接读取具体数值:
dff <- df %>% pivot_longer(cols = -type, names_to = 'n', values_to = 'v') ggplot(data = dff) + geom_bar(aes(x = type, y = v, fill = n), stat = 'identity', position = 'dodge') + geom_text( data = filter(dff, n == "temperature"), aes(x = type, y = v + 5, label = round(v, 4)), # 标签位置略高于柱子 color = "red", size = 3 ) + labs(title = "环境指标按土地类型分布", x = "土地类型", y = "数值") + theme_minimal()
内容的提问来源于stack exchange,提问作者jackywang
相关产品推荐
相关产品推荐

