You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 20:21:42