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

求助:使用R的ggplot2绘制指定角度与半轴的公差椭圆及轴

问题:ggplot2绘制指定参数的公差椭圆失败

我在用R和ggplot2复现一张包含50%、75%、95%三个公差等级椭圆的图表,目前已经完成坐标轴、背景及散点的绘制,但椭圆部分始终无法正确实现:

  • 用geom_ellipse绘制的绿色椭圆旋转后超出了图表范围
  • 尝试用rnorm生成模拟数据结合stat_ellipse实现,也没达到预期效果

已知参数(男性组)

  • 椭圆中心坐标:(298.6, 30.8)
  • 长短轴斜率:69.30° 和 -20.70°(对应椭圆旋转角度)
  • 各公差等级半轴长度:
    • 50%公差:89 Ω/m(长轴)、43 Ω/m(短轴)
    • 75%公差:127 Ω/m、61 Ω/m
    • 95%公差:187 Ω/m、89 Ω/m

当前使用代码

ggplot() +  
  annotation_custom(imgonchart, -Inf, Inf, -Inf, Inf) +
  geom_point(data=df, aes(rz,xc)) +
  geom_point(data=biadf, aes(mean(Rzm), mean(Xcm))) +
  geom_ellipse(aes(x0 = 298.6, y0 = 30.8, a = 43, b = 8.9, angle = pi / 39.30 ), color="green") +
  coord_fixed(ratio=10)+
  scale_x_continuous(expand = c(0, 0), limits = c(0,600), breaks = seq(0, 600, by= 50)) +  # set limit, steps, and how much can expand
  scale_y_continuous(expand = c(0, 0), limits = c(0,60), breaks = seq(0, 60, 5)) +
  labs(x = expression(paste("Rz/H (", Omega, "/m)")), 
       y = expression(paste("Xc/H (", Omega, "/m)"))
       ) + # LEGENDA
  theme(plot.title = element_text(hjust = 0.5),
        panel.grid.minor.y =  element_blank(),
        panel.grid.minor.x = element_blank()) # to adjust the title in the middle

解决方案

1. 修正geom_ellipse的核心参数错误

你的代码里有三个关键问题:

  • 角度转换错误:geom_ellipse的angle参数接受的是弧度值,且是从x轴正方向逆时针旋转的角度。69.30°转成弧度应该是69.30 * pi / 180,而非pi/39.30。
  • 半轴长度与坐标比例不匹配:你设置了coord_fixed(ratio=10),意味着x轴上1单位的长度等于y轴上10单位的长度。所以y方向的半轴长度需要除以10,才能在图表上显示正确的比例。
  • 半轴参数对应关系:a是旋转前x方向的半轴,b是旋转前y方向的半轴,要根据长短轴的实际长度对应设置。

2. 修正后的代码示例(包含三个公差等级椭圆)

# 先统一定义椭圆参数
ellipse_params <- list(
  center_x = 298.6,
  center_y = 30.8,
  angle_rad = 69.30 * pi / 180, # 转成弧度
  # 因coord_fixed(ratio=10),y轴半轴需除以10匹配比例
  a_50 = 89,   # x方向长半轴
  b_50 = 43 / 10, # y方向短半轴
  a_75 = 127,
  b_75 = 61 / 10,
  a_95 = 187,
  b_95 = 89 / 10
)

ggplot() +  
  annotation_custom(imgonchart, -Inf, Inf, -Inf, Inf) +
  geom_point(data=df, aes(rz,xc)) +
  geom_point(data=biadf, aes(mean(Rzm), mean(Xcm))) +
  # 50%公差椭圆
  geom_ellipse(aes(x0 = ellipse_params$center_x, 
                   y0 = ellipse_params$center_y, 
                   a = ellipse_params$a_50, 
                   b = ellipse_params$b_50, 
                   angle = ellipse_params$angle_rad), 
               color="green", linetype="solid") +
  # 75%公差椭圆
  geom_ellipse(aes(x0 = ellipse_params$center_x, 
                   y0 = ellipse_params$center_y, 
                   a = ellipse_params$a_75, 
                   b = ellipse_params$b_75, 
                   angle = ellipse_params$angle_rad), 
               color="blue", linetype="dashed") +
  # 95%公差椭圆
  geom_ellipse(aes(x0 = ellipse_params$center_x, 
                   y0 = ellipse_params$center_y, 
                   a = ellipse_params$a_95, 
                   b = ellipse_params$b_95, 
                   angle = ellipse_params$angle_rad), 
               color="red", linetype="dotted") +
  coord_fixed(ratio=10)+
  scale_x_continuous(expand = c(0, 0), limits = c(0,600), breaks = seq(0, 600, by= 50)) +
  scale_y_continuous(expand = c(0, 0), limits = c(0,60), breaks = seq(0, 60, 5)) +
  labs(x = expression(paste("Rz/H (", Omega, "/m)")), 
       y = expression(paste("Xc/H (", Omega, "/m)"))) +
  theme(plot.title = element_text(hjust = 0.5),
        panel.grid.minor.y = element_blank(),
        panel.grid.minor.x = element_blank())

3. 关于stat_ellipse的说明

stat_ellipse是基于输入数据计算的置信椭圆,它依赖数据的分布特征(均值、协方差),而你需要的是根据已知固定参数绘制的公差椭圆,所以直接用geom_ellipse指定参数才是正确的做法,不需要模拟数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 00:40:27