geom_scatterpie映射半径为总鱼数时饼图重叠问题求解
ggplot2 散点饼图半径映射总个体数后重叠问题解决
问题描述
需要绘制散点饼图同时展示两类信息:
- 每个采样点的鱼类物种组成占比
- 每个采样点的鱼类总个体数(通过饼图半径大小体现)
使用ggplot2 + scatterpie扩展包的geom_scatterpie函数绘图时出现两类异常:
- 不指定半径参数时,所有饼图尺寸完全一致,无法体现点位总鱼数差异,运行代码如下:
ggplot()+ geom_scatterpie( data=Data_longlat, aes(x=Longitude, y=Latitude), alpha=0.5, cols = c("Abbor", "Laue", "Harr","Mort","Sik", "Stingsild", "Vederbuk", "Steinsmett", "Orekyt","Orret", "Hork", "Lagesild", "Gjedde", "Brasme", "Karpefisk", "Karuss","Krokle","Karpefisk 0+"), color=NA ) + coord_equal()
- 直接在
aes中映射r=Totalt(Totalt为点位总鱼数列)时,饼图尺寸过大,所有饼图完全重叠无法识别点位分布,运行代码如下:
ggplot()+ geom_scatterpie( data=Data_longlat, aes(x=Longitude, y=Latitude, r=Totalt), alpha=0.5, cols = c("Abbor", "Laue", "Harr","Mort","Sik", "Stingsild", "Vederbuk", "Steinsmett", "Orekyt","Orret", "Hork", "Lagesild", "Gjedde", "Brasme","Karpefisk", "Karuss","Krokle","Karpefisk 0+"), color=NA ) + coord_equal()
问题原因
geom_scatterpie的半径单位和x/y坐标轴的单位完全一致。当前绘图使用的x/y是经纬度坐标,点位间的经纬度差通常在零点几到几度的范围,但总鱼数Totalt的数值范围远大于这个区间,直接映射会导致饼图半径远大于点位间距,必然出现重叠。
解决步骤
- 先对总鱼数做缩放,把半径值限制在和坐标间距匹配的范围:
library(dplyr) # 计算所有采样点之间的最小平面距离 min_point_dist <- min(dist(Data_longlat[, c("Longitude", "Latitude")])) # 设定最大饼图半径为最小点距的40%,预留足够间隙避免相邻饼图接触 max_allowed_r <- min_point_dist * 0.4 # 按总鱼数等比例换算每个点位的缩放后半径 Data_longlat <- Data_longlat %>% mutate(r_scaled = Totalt / max(Totalt, na.rm = TRUE) * max_allowed_r) - 绘图时用缩放后的半径列做映射,同时添加
scale_radius强制半径从0开始计量,避免默认的尺度扩张导致尺寸溢出:ggplot() + geom_scatterpie( data = Data_longlat, aes(x = Longitude, y = Latitude, r = r_scaled), alpha = 0.5, cols = c("Abbor", "Laue", "Harr","Mort","Sik", "Stingsild", "Vederbuk", "Steinsmett", "Orekyt","Orret", "Hork", "Lagesild", "Gjedde", "Brasme","Karpefisk", "Karuss","Krokle","Karpefisk 0+"), color = NA ) + # 关键设置:锁定半径范围,关闭默认尺度偏移 scale_radius(limits = c(0, max(Data_longlat$r_scaled)), guide = "none") + coord_equal()
补充优化提示:如果研究区纬度跨度较大,建议先将经纬度转换为等距投影坐标(如UTM投影)后再绘图,可避免高纬度地区经纬度平面距离变形导致的饼图视觉大小偏差。
内容的提问来源于stack exchange,提问作者Thor Bjørn Rudi Thorkildsen
相关产品推荐
相关产品推荐

