R语言:满足特定条件时如何隐藏geom_segment()绘制的箭头?
解决ggplot2中geom_segment仅在特定条件下绘制箭头的问题
问题描述
在R语言中使用ggplot2的geom_segment()绘制箭头时,希望当数据中的exposure_time为0时隐藏对应箭头。以下是简化的可运行示例场景:
原示例代码
# 加载必要包 library(ggplot2) library(sf) library(readr) # 读取数据并转为sf对象 photo_positions <- read_csv("photos_hamburg2.csv") |> sf::st_as_sf(coords=c('X', 'Y')) # 将角度转为弧度 photo_positions[['orientation_rad']] = photo_positions[['orientation']] * pi / 180 # 定义长度系数 length_factor <- .2 # 测试绘图 ggplot(data = photo_positions) + stat_sf_coordinates() + # 绘制箭头 geom_segment( stat = "sf_coordinates", mapping = aes( geometry = geometry, x = after_stat(x), y = after_stat(y), xend = after_stat(x) + photo_positions[['exposure_time']] * length_factor * sin(photo_positions[['orientation_rad']]), yend = after_stat(y) + photo_positions[['exposure_time']] * length_factor * cos(photo_positions[['orientation_rad']]) ), arrow = arrow(), size = 2, color = "turquoise" ) + # 绘制圆形标记 geom_sf(stat = "sf_coordinates", mapping = aes(geometry = geometry, x = after_stat(x), y = after_stat(y)), size = 4, shape = 21, fill = "white") + xlab("经度") + ylab("纬度") + ggtitle("汉堡拍摄点位")
示例CSV数据
X,Y,name,orientation,exposure_time 9.991293,53.55456,"Alster view 2",59,0.004 9.992967,53.550898,"Rathaus view 2",219,0.008 9.995563,53.556932,"Alster view 1",201,0 9.992591,53.551986,"Rathaus view 1",177,0 9.995724,53.552775,"Alster view 3",338,0.016
原绘图会显示exposure_time为0的箭头,需要隐藏这些无效箭头。
解决方案
方法1:提前过滤数据
在geom_segment()的data参数中仅传入exposure_time > 0的行,直接跳过不符合条件的箭头绘制:
ggplot(data = photo_positions) + stat_sf_coordinates() + # 仅使用exposure_time大于0的数据绘制箭头 geom_segment( data = subset(photo_positions, exposure_time > 0), stat = "sf_coordinates", mapping = aes( geometry = geometry, x = after_stat(x), y = after_stat(y), xend = after_stat(x) + exposure_time * length_factor * sin(orientation_rad), yend = after_stat(y) + exposure_time * length_factor * cos(orientation_rad) ), arrow = arrow(), size = 2, color = "turquoise" ) + geom_sf(stat = "sf_coordinates", mapping = aes(geometry = geometry, x = after_stat(x), y = after_stat(y)), size = 4, shape = 21, fill = "white") + xlab("经度") + ylab("纬度") + ggtitle("汉堡拍摄点位")
方法2:用ifelse控制端点坐标
在aes()中,当exposure_time为0时让xend = x、yend = y,使线段长度为0,视觉上完全隐藏:
ggplot(data = photo_positions) + stat_sf_coordinates() + geom_segment( stat = "sf_coordinates", mapping = aes( geometry = geometry, x = after_stat(x), y = after_stat(y), xend = after_stat(x) + ifelse(exposure_time > 0, exposure_time * length_factor * sin(orientation_rad), 0), yend = after_stat(y) + ifelse(exposure_time > 0, exposure_time * length_factor * cos(orientation_rad), 0) ), arrow = arrow(), size = 2, color = "turquoise" ) + geom_sf(stat = "sf_coordinates", mapping = aes(geometry = geometry, x = after_stat(x), y = after_stat(y)), size = 4, shape = 21, fill = "white") + xlab("经度") + ylab("纬度") + ggtitle("汉堡拍摄点位")
方法3:通过透明度控制
将alpha映射到exposure_time > 0的逻辑值,当exposure_time为0时设为完全透明:
ggplot(data = photo_positions) + stat_sf_coordinates() + geom_segment( stat = "sf_coordinates", mapping = aes( geometry = geometry, x = after_stat(x), y = after_stat(y), xend = after_stat(x) + exposure_time * length_factor * sin(orientation_rad), yend = after_stat(y) + exposure_time * length_factor * cos(orientation_rad), alpha = exposure_time > 0 ), arrow = arrow(), size = 2, color = "turquoise" ) + # 取消透明度图例,避免干扰 guides(alpha = "none") + geom_sf(stat = "sf_coordinates", mapping = aes(geometry = geometry, x = after_stat(x), y = after_stat(y)), size = 4, shape = 21, fill = "white") + xlab("经度") + ylab("纬度") + ggtitle("汉堡拍摄点位")
内容的提问来源于stack exchange,提问作者winnewoerp
相关产品推荐
相关产品推荐

