如何在R语言中使用tmap包在地图上绘制饼图?
用tmap在地图上绘制饼图的解决方案
问题背景
已掌握ggplot2绘制地图饼图的方法,但现有地图均基于tmap包创建,其样式调整更符合需求,希望在tmap底图上实现饼图标注,替代原有的堆叠条形图,且不愿重写现有复杂的地图代码。尝试用geom_scatterpie生成grob对象时出现错误,需要正确的实现方式。
错误原因
geom_scatterpie是专为在ggplot地图上批量绘制饼图设计的,不适合单独生成单个饼图的grob对象。我们可以用基础的geom_bar配合coord_polar来生成单个饼图grob,更适配tmap的tm_symbols调用逻辑。
完整实现代码
library(ggplot2) library(tmap) library(dplyr) library(tidyr) library(sf) library(tmaptools) # 加载数据并整理 data(NLD_prov) origin_data <- NLD_prov %>% st_set_geometry(NULL) %>% select(name, origin_native, origin_west, origin_non_west) %>% gather(key=origin, value=perc, origin_native, origin_west, origin_non_west, factor_key=TRUE) plot_cols <- get_brewer_pal("Dark2", 3) # 生成饼图grob对象(替代原来的堆叠条形图grob) grobs <- lapply(split(origin_data, origin_data$name), function(x) { ggplotGrob( ggplot(x, aes(x="", y=perc, fill=origin)) + geom_bar(width=1, stat="identity") + # 转为饼图 coord_polar("y", start=0) + # 移除多余的轴和扩展空间 scale_x_discrete(expand = c(0, 0)) + scale_y_continuous(expand = c(0, 0)) + scale_fill_manual(values=plot_cols) + # 清空所有主题元素,只保留饼图 theme_void() ) }) # 在tmap中绘制地图+饼图 tm_shape(NLD_prov) + tm_polygons(group = "Provinces") + tm_symbols(shape="name", shapes=grobs, legend.shape.show = FALSE, legend.size.is.portrait = TRUE, shapes.legend = 22) + tm_add_legend(type="fill", col=plot_cols, labels=c("Native", "Western", "Non-western"), title="Origin")
代码关键点说明
- 用
coord_polar("y")将垂直条形图转换为饼图,start=0设置饼图起始角度为0度 theme_void()彻底清空ggplot的主题元素(坐标轴、背景、网格等),避免grob带入多余元素影响tmap显示scale_x_discrete和scale_y_continuous的expand=c(0,0)参数保证饼图占满整个grob空间,避免出现空白边距- 保留原tmap的图层调用逻辑,无需修改现有复杂的地图代码,仅替换grob生成部分即可
内容的提问来源于stack exchange,提问作者kl-higgins
相关产品推荐
相关产品推荐

