如何用ggplot2绘制分国家的NUTS2层级水平条形分面网格图?
ggplot2实现分面水平条形图及数据年份差异展示
原始数据
data <- data.frame( nuts = c("AT11", "AT11", "AT11", "AT12", "AT12", "AT12", "AT13", "AT13", "AT13", "AT21", "AT21", "AT21", "DE11", "DE11", "DE11", "DE12", "DE12", "DE12"), type = c("all", "flat", "house", "all", "flat", "house", "all", "flat", "house", "all", "flat", "house", "all", "flat", "house", "all", "flat", "house"), year = c(2007, 2007, 2007, 2007, 2007, 2007, 2000, 2000, 2000, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007))
第一步:数据预处理
从nuts编码中提取国家代码(前两位),为后续分面做准备:
library(ggplot2) # 提取国家代码(AT=奥地利,DE=德国) data$country <- substr(data$nuts, 1, 2)
第二步:绘制分面水平条形图
按照需求实现每个国家一个分面,y轴为NUTS2编码,x轴为年份,不同建筑类型用颜色区分:
ggplot(data, aes(x = factor(year), y = nuts, fill = type)) + # 同一NUTS2下的不同建筑类型条形并列展示 geom_col(position = position_dodge(width = 0.8), width = 0.7) + # 按国家分面,每个国家的y轴仅显示自身的NUTS2编码 facet_wrap(~country, scales = "free_y", ncol = 1) + # 设置坐标轴标签和标题 labs(x = "数据可用年份", y = "NUTS2区域编码", fill = "建筑类型", title = "不同国家NUTS2区域建筑类型数据年份分布") + # 优化主题提升可读性 theme_minimal() + theme( plot.title = element_text(hjust = 0.5, size = 14, face = "bold"), axis.text = element_text(size = 10), legend.position = "bottom" )
代码说明
position_dodge(width=0.8):避免同一NUTS2下的三种建筑类型条形重叠,实现并列展示facet_wrap(~country, scales="free_y"):每个国家单独成面,且y轴仅显示当前国家的NUTS2编码,排除无关区域干扰factor(year):将年份转为离散值,适配条形图的x轴展示逻辑
展示国家数据年份差异的更优方式
除分面条形图外,以下两种方式能更直观呈现年份差异:
1. 热图(Tile Plot)
用色块展示每个NUTS2区域的可用年份,快速识别年份覆盖差异:
ggplot(data, aes(x = factor(year), y = nuts, fill = type)) + geom_tile(color = "white", size = 0.5) + facet_wrap(~country, scales = "free_y", ncol = 1) + labs(x = "数据可用年份", y = "NUTS2区域编码", fill = "建筑类型", title = "不同国家NUTS2区域数据年份覆盖热图") + theme_minimal() + theme( plot.title = element_text(hjust = 0.5, size = 14, face = "bold"), axis.text = element_text(size = 10), legend.position = "bottom" )
这种方式能一眼看出哪些区域存在年份缺失(比如奥地利AT13仅2000年有数据,其他区域均为2007年)。
2. 带年份汇总标注的分面图
在分面顶部添加国家的年份范围标注,强化差异感知:
# 计算每个国家的年份范围 year_summary <- aggregate(year ~ country, data, function(x) paste(range(x), collapse = " - ")) names(year_summary)[2] <- "year_range" # 绘制带标注的分面图 ggplot(data, aes(x = factor(year), y = nuts, fill = type)) + geom_col(position = position_dodge(width = 0.8), width = 0.7) + facet_wrap(~country, scales = "free_y", ncol = 1) + # 添加年份范围标注 geom_text(data = year_summary, aes(x = Inf, y = Inf, label = year_range), hjust = 1.1, vjust = 1.5, size = 4, fontface = "italic") + labs(x = "数据可用年份", y = "NUTS2区域编码", fill = "建筑类型", title = "不同国家NUTS2区域建筑类型数据年份分布(含年份范围)") + theme_minimal() + theme( plot.title = element_text(hjust = 0.5, size = 14, face = "bold"), axis.text = element_text(size = 10), legend.position = "bottom" )
内容的提问来源于stack exchange,提问作者Tim George
相关产品推荐
相关产品推荐

