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

如何在ggplot2环形柱状图中添加均值角度与幅度箭头?

在ggplot2环形柱状图中添加均值角度与幅度箭头

我已经用circular包算出了均值角度(56.28°)和R值(0.6828),现在要在ggplot2绘制的环形柱状图里添加箭头来表示这两个值。以下是我的数据和绘图代码,求帮忙添加箭头。

数据

mes <- c("janeiro", "fevereiro", "marco", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro")
flor <- c(66.67, 93.33, 95.00, 93.33, 65.00, 20.00, NA, NA,  0.00, 0.00, 0.00, 40.00)
angulo <- c(0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330)
dados_canavalia <- data.frame (mes, angulo, flor)
dados_canavalia$mes<- factor(dados_canavalia$mes, ordered = TRUE, levels =c("janeiro","fevereiro", "marco", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro"))
str(dados_canavalia)  

原有绘图脚本

plt_canavalia <- ggplot(dados_canavalia) +  
  # 自定义面板网格线
  geom_hline(
    aes(yintercept = y), 
    data.frame(y = c(0,25,50,75,100)),
    color = "lightgrey"
  ) +
  geom_col(
    aes(
      x = mes, 
      y = flor, 
      fill = flor
    ),
    position = "dodge2",
    show.legend = FALSE,
    alpha = .9
  )+
  geom_segment(
    aes(
      x = mes,
      y = 0,
      xend = mes,
      yend = 100
    ),
    linetype = "dashed",
    color = "gray12"
  ) + 
  coord_polar()+  # 转换为环形图
  scale_y_continuous(
    limits = c(0, 100),
    expand = c(0,0),
    breaks = c(0,50,100)
  ) + 
  scale_fill_gradientn(              
    "Porcentagem de indivíduos (%)",
    colours = c( "#F8D8D8","#F8A8A8","#F07070","#E85830"),
    limits= c(0,100),
    breaks = seq(0, 100, by = 25)
  ) +
  # 自定义填充图例
  guides(
    fill = guide_colorsteps(
      barwidth = 35, barheight = 1, title.position = "top", title.hjust = .5
    )
  ) +
  theme(
    axis.title = element_blank(),
    axis.ticks = element_blank(),
    axis.text.y = element_blank(),
    axis.text.x = element_text(color = "gray12", size = 30),
    legend.position = "bottom"
  )+
  labs(
    title = "\nCanavalia rosea",
    sep = "\n") +
  theme(
    text = element_text(color = "gray12", family = "Arial"),
    plot.title = element_text(face = "italic", size = 35 , hjust = 0.04),
    legend.text = element_text(size = 27),
    legend.title = element_text(size = 24),
    panel.background = element_rect(fill = "white", color = "white"),
    panel.grid = element_blank(),
    panel.grid.major.x = element_blank())+
  scale_x_discrete(labels = c("Jan","Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"))

解决方案

要添加箭头,需要先把均值角度转换为ggplot离散x轴的对应位置,把R值转换为y轴的长度(y轴范围0-100,所以直接用R值×100),再用geom_segment绘制带箭头的线段。

1. 坐标转换逻辑

  • 每个月份对应30°,x轴离散值从1(1月,0°)到12(12月,330°),所以均值角度对应的x位置为:1 + (56.28 / 30) = 2.876
  • R值对应的y轴长度:0.6828 × 100 = 68.28

2. 添加箭头的代码片段

在原有绘图代码的末尾加入以下代码:

# 添加均值角度与幅度箭头
geom_segment(
  x = 0, y = 0,
  xend = 2.876, yend = 68.28,
  color = "black", size = 1.2,
  arrow = arrow(length = unit(0.5, "cm"), type = "closed")
)

3. 完整绘图代码

整合后的完整代码如下:

# 数据准备
mes <- c("janeiro", "fevereiro", "marco", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro")
flor <- c(66.67, 93.33, 95.00, 93.33, 65.00, 20.00, NA, NA,  0.00, 0.00, 0.00, 40.00)
angulo <- c(0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330)
dados_canavalia <- data.frame (mes, angulo, flor)
dados_canavalia$mes<- factor(dados_canavalia$mes, ordered = TRUE, levels =c("janeiro","fevereiro", "marco", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro"))

# 绘图代码
plt_canavalia <- ggplot(dados_canavalia) +  
  # 自定义面板网格线
  geom_hline(
    aes(yintercept = y), 
    data.frame(y = c(0,25,50,75,100)),
    color = "lightgrey"
  ) +
  geom_col(
    aes(
      x = mes, 
      y = flor, 
      fill = flor
    ),
    position = "dodge2",
    show.legend = FALSE,
    alpha = .9
  )+
  geom_segment(
    aes(
      x = mes,
      y = 0,
      xend = mes,
      yend = 100
    ),
    linetype = "dashed",
    color = "gray12"
  ) + 
  coord_polar()+  # 转换为环形图
  scale_y_continuous(
    limits = c(0, 100),
    expand = c(0,0),
    breaks = c(0,50,100)
  ) + 
  scale_fill_gradientn(              
    "Porcentagem de indivíduos (%)",
    colours = c( "#F8D8D8","#F8A8A8","#F07070","#E85830"),
    limits= c(0,100),
    breaks = seq(0, 100, by = 25)
  ) +
  # 自定义填充图例
  guides(
    fill = guide_colorsteps(
      barwidth = 35, barheight = 1, title.position = "top", title.hjust = .5
    )
  ) +
  theme(
    axis.title = element_blank(),
    axis.ticks = element_blank(),
    axis.text.y = element_blank(),
    axis.text.x = element_text(color = "gray12", size = 30),
    legend.position = "bottom"
  )+
  labs(
    title = "\nCanavalia rosea",
    sep = "\n") +
  theme(
    text = element_text(color = "gray12", family = "Arial"),
    plot.title = element_text(face = "italic", size = 35 , hjust = 0.04),
    legend.text = element_text(size = 27),
    legend.title = element_text(size = 24),
    panel.background = element_rect(fill = "white", color = "white"),
    panel.grid = element_blank(),
    panel.grid.major.x = element_blank())+
  scale_x_discrete(labels = c("Jan","Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez")) +
  # 添加均值角度与幅度箭头
  geom_segment(
    x = 0, y = 0,
    xend = 2.876, yend = 68.28,
    color = "black", size = 1.2,
    arrow = arrow(length = unit(0.5, "cm"), type = "closed")
  )

# 显示图形
print(plt_canavalia)

自定义说明

  • 可以通过调整size参数改变箭头粗细,length参数改变箭头头部大小
  • 修改color参数可以调整箭头颜色
  • 如果后续均值角度或R值变化,只需对应修改xend和yend的数值即可

内容的提问来源于stack exchange,提问作者Lais Stein

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 05:24:56