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

如何在ggplot中绘制角度数据并实现多圆形叠加对比?

问题描述

我有一组角度数据,想要用圆形刻度绘制、对比并可视化,之后整合到对比图面板中。已知基础绘图(base plot)的plot函数能处理单个数据集,但因为有多组数据,想借助ggplot的美观效果实现对比可视化,核心需求是将两个圆形图叠加对比。

我使用的示例代码如下:

a<-c(289.25, 279.61, 288.09, 208.22, 295.74, 214.48, 192.51, 269.93, 225.89, 215.65)
ap<-circular(a, template = "geographics", modulo = "2pi")
plot(ap)
arrows.circular(ap, col = "blue", length = 0.25, angle = 30)

我尝试用ggplotify包的as.ggplot函数将base plot转为ggplot对象,但只能转换plot(ap)部分,无法添加arrows.circular的箭头图层。想请教两个问题:

  1. 是否可以直接用ggplot绘制这类圆形角度图?
  2. 有没有办法通过as.ggplot将base plot的所有图层都转为ggplot对象?

解决方案

一、直接用ggplot绘制圆形角度图

完全可以用ggplot2配合circular包的数据处理实现这类图形,而且更便于后续叠加多组数据和调整样式,具体步骤如下:

1. 加载依赖包并处理数据

library(ggplot2)
library(circular)

# 原始角度数据
a <- c(289.25, 279.61, 288.09, 208.22, 295.74, 214.48, 192.51, 269.93, 225.89, 215.65)
# 转换为circular对象(地理模板,0度为正北)
ap <- circular(a, template = "geographics", modulo = "2pi")

# 转换为ggplot可用的数据框,注意调整角度适配ggplot极坐标
# ggplot极坐标默认0度为正东,地理模板0度为正北,需减去pi/2转换
df <- data.frame(
  angle_rad = as.numeric(ap),
  angle_adj = (pi/2) - as.numeric(ap)
)

2. 绘制单组数据的圆形箭头图

ggplot(df, aes(x = 0, y = 0, angle = angle_adj)) +
  # 绘制角度对应的点(模拟base plot的刻度点)
  geom_point(aes(x = cos(angle_adj), y = sin(angle_adj)), size = 2) +
  # 添加指向角度的箭头
  geom_spoke(
    radius = 0.8, 
    arrow = arrow(length = unit(0.25, "cm"), angle = 30), 
    color = "blue"
  ) +
  # 设置极坐标,匹配地理模板(正北向上,顺时针旋转)
  coord_polar(start = pi/2, direction = -1) +
  # 隐藏坐标轴刻度,调整画布范围
  scale_x_continuous(limits = c(-1.2, 1.2), breaks = NULL) +
  scale_y_continuous(limits = c(-1.2, 1.2), breaks = NULL) +
  # 清空不必要的主题元素,模拟circular包的简洁风格
  theme_void() +
  theme(panel.background = element_rect(fill = "white"))

3. 叠加两组数据对比

如果要实现多组数据的叠加对比,只需合并数据并添加分组变量,通过颜色或样式区分即可:

# 模拟第二组角度数据
b <- c(250.1, 260.3, 270.5, 220.7, 280.9, 230.2, 200.4, 240.6, 250.8, 210.1)
bp <- circular(b, template = "geographics", modulo = "2pi")

# 转换第二组数据并添加分组标识
df_b <- data.frame(
  angle_rad = as.numeric(bp),
  angle_adj = (pi/2) - as.numeric(bp),
  group = "组B"
)
df_a <- df %>% mutate(group = "组A")

# 合并两组数据
df_combined <- rbind(df_a, df_b)

# 绘制叠加对比图
ggplot(df_combined, aes(x = 0, y = 0, angle = angle_adj, color = group)) +
  geom_point(aes(x = cos(angle_adj), y = sin(angle_adj)), size = 2) +
  geom_spoke(
    radius = 0.8, 
    arrow = arrow(length = unit(0.25, "cm"), angle = 30)
  ) +
  coord_polar(start = pi/2, direction = -1) +
  scale_x_continuous(limits = c(-1.2, 1.2), breaks = NULL) +
  scale_y_continuous(limits = c(-1.2, 1.2), breaks = NULL) +
  # 自定义分组颜色
  scale_color_manual(values = c("组A" = "blue", "组B" = "red")) +
  theme_void() +
  theme(
    panel.background = element_rect(fill = "white"),
    legend.position = "bottom"
  )

二、关于as.ggplot转换完整base plot的方法

ggplotify::as.ggplot默认只能转换plot()函数返回的绘图对象,但arrows.circular是在base绘图设备上追加绘制的元素,不属于plot(ap)的返回对象,因此无法直接一次性转换。

如果一定要将完整的base plot(包括箭头)转为ggplot对象,可以通过捕获整个绘图设备的内容实现:

library(ggplotify)
library(grid)

# 创建临时空绘图设备
pdf(NULL)
# 绘制base plot的所有元素
plot(ap)
arrows.circular(ap, col = "blue", length = 0.25, angle = 30)
# 捕获当前绘图的grid对象
g <- grid.grab()
dev.off()

# 转换为ggplot对象
p <- as.ggplot(g)
print(p)

不过这种方式得到的ggplot对象是一张静态图片,无法再单独修改箭头、点等元素的样式,灵活性远不如直接用ggplot绘制。


内容的提问来源于stack exchange,提问作者Baheerathan M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 13:41:13