ggplot绘制美国人口地图添加标签失败及交互功能实现求助
ggplot绘制美国人口地图添加标签失败及交互功能实现求助
问题背景
你用ggplot()绘制了美国各州人口地图,想要给地图添加州名标签,或者实现鼠标悬停显示州名的交互效果,但尝试后遇到了报错,在StackOverflow找的方案也没解决,下面帮你分析问题并给出可行方案。
标签添加失败的原因及解决办法
你当前的代码里使用了geom_sf_text(),但报错提示stat_sf_coordinates()需要geometry美学参数,这是因为你的代码混用了基于经纬度(long/lat)的geom_polygon()和需要sf对象的geom_sf_text(),两者不兼容。这里有两种解决思路:
思路1:如果你的数据是sf格式(推荐)
如果pop_usa是sf对象(包含geometry列),可以直接用sf相关的geom函数重构代码,这样添加标签会更简单:
# 重构sf版本的地图代码 scaling_map <- ggplot(pop_usa) + geom_sf(aes(fill = estimated_pop_2020), color = "black") + geom_sf_text(aes(label = state), size = 3, color = "black") + # 直接用geom_sf_text theme(axis.title.x=element_blank(), axis.text.x=element_blank(), axis.ticks.x=element_blank(), axis.title.y=element_blank(), axis.text.y=element_blank(), axis.ticks.y=element_blank(), plot.title = element_text(face = "bold",hjust = 0.5)) + ggtitle("Estimated population by state") + scale_fill_gradient(name ="Estimated population (log10)" ,low = "#FFFFCC" , high = "#336600")
思路2:如果数据是普通经纬度数据(非sf)
如果还是想用geom_polygon(),那需要先计算每个州的中心点坐标,再用geom_text()来添加标签:
# 先计算每个州的中心点 state_centers <- pop_usa %>% group_by(state, group) %>% summarise(long = mean(long), lat = mean(lat), .groups = "drop") # 然后修改地图代码,用geom_text添加标签 scaling_map <- ggplot(pop_usa, aes(long, lat)) + geom_polygon(aes(group= group, fill = estimated_pop_2020) ,color="black") + geom_text(data = state_centers, aes(label = state), size = 3, color = "black") + # 使用计算好的中心点数据 theme(axis.title.x=element_blank(), axis.text.x=element_blank(), axis.ticks.x=element_blank(), axis.title.y=element_blank(), axis.text.y=element_blank(), axis.ticks.y=element_blank(), plot.title = element_text(face = "bold",hjust = 0.5)) + ggtitle("Estimated population by state") + scale_fill_gradient(name ="Estimated population (log10)" ,low = "#FFFFCC" , high = "#336600") + coord_map()
实现鼠标悬停交互效果
想要实现鼠标悬停显示州名(及其他信息),推荐用plotly包把你的ggplot对象转成交互式图表,步骤如下:
- 先确保安装了plotly:
install.packages("plotly")
- 修改你的地图代码(以sf版本为例),然后用
ggplotly()转换:
library(plotly) # 先构建基础ggplot(sf版本) scaling_map <- ggplot(pop_usa) + geom_sf(aes(fill = estimated_pop_2020, text = paste("州名:", state, "\n2020预估人口:", estimated_pop_2020))) + theme(axis.title.x=element_blank(), axis.text.x=element_blank(), axis.ticks.x=element_blank(), axis.title.y=element_blank(), axis.text.y=element_blank(), axis.ticks.y=element_blank(), plot.title = element_text(face = "bold",hjust = 0.5)) + ggtitle("Estimated population by state") + scale_fill_gradient(name ="Estimated population (log10)" ,low = "#FFFFCC" , high = "#336600") # 转换为交互式图表 ggplotly(scaling_map, tooltip = "text")
这样当你鼠标悬停在某个州上时,就会显示你定义的州名和人口信息啦。如果是用普通经纬度数据的版本,只需要在geom_polygon()的aes里加上text参数即可。
另外也可以用ggiraph包实现交互,不过plotly的上手难度更低,适合快速实现需求。
备注:内容来源于stack exchange,提问作者sikimimi
相关产品推荐
相关产品推荐

