如何按扇区与欧氏距离对散点图中的XY点进行分类?
散点图的原点距离标注与区域分类实现
一、区域分类规则定义
结合30°直线划分与环形距离,分类逻辑如下:
1. 角度分区(基于30°直线)
以第一象限为例(若数据包含正负坐标,可扩展象限判断逻辑):
- X轴附近:点满足
y ≤ tan(30°) × x(tan(30°)≈0.577),表示点更贴近X轴 - Y轴附近:点满足
x ≤ tan(30°) × y,表示点更贴近Y轴 - XY轴附近:点不满足上述两个条件,处于两条30°直线之间的区域
2. 距离分区(基于欧氏距离)
设定两个距离阈值(可根据数据范围灵活调整,示例用r_center=0.3和r_far=1.5):
- 中心区:到原点的欧氏距离 ≤
r_center - 近区:
r_center< 欧氏距离 ≤r_far,结合角度分区对应「X轴近区」「Y轴近区」「XY轴近区」 - 远区:欧氏距离 >
r_far,结合角度分区对应「X轴远区」「Y轴远区」「XY轴远区」
二、R语言完整实现代码
library(tidyverse) # 生成示例数据 dd <- data.frame(x = runif(10, min=0, max=2), y = runif(10, min=0, max=2)) # 计算每个点到原点的欧氏距离 dd <- dd %>% mutate(euclid_dist = sqrt(x^2 + y^2)) # 定义分类参数 tan30 <- tan(pi/6) # 30度角的正切值(≈0.577) r_center <- 0.3 # 中心区距离阈值 r_far <- 1.5 # 远区距离阈值 # 计算区域分类 dd <- dd %>% mutate( # 先判断角度所属区域 angle_zone = case_when( y <= tan30 * x ~ "X轴附近", x <= tan30 * y ~ "Y轴附近", TRUE ~ "XY轴附近" ), # 再判断距离所属区域 dist_zone = case_when( euclid_dist <= r_center ~ "中心", euclid_dist <= r_far ~ "近区", TRUE ~ "远区" ), # 合并为完整分类标签 full_zone = ifelse(dist_zone == "中心", "中心", paste(angle_zone, dist_zone)) ) # 绘制带分区标注的散点图 dd %>% ggplot(aes(x = x, y = y, color = full_zone)) + # 添加30°划分直线 geom_abline(slope = tan30, linetype = "dashed", color = "gray50") + geom_abline(slope = 1/tan30, linetype = "dashed", color = "gray50") + # 添加环形距离参考线(无需额外包) geom_path(data = data.frame(theta = seq(0, 2*pi, length.out=100)), aes(x = r_center*cos(theta), y = r_center*sin(theta), color = NULL), linetype = "dotted", color = "gray50") + geom_path(data = data.frame(theta = seq(0, 2*pi, length.out=100)), aes(x = r_far*cos(theta), y = r_far*sin(theta), color = NULL), linetype = "dotted", color = "gray50") + # 绘制散点并标注距离 geom_point(size = 3) + geom_text(aes(label = round(euclid_dist, 2)), hjust = -0.2, vjust = 0, size = 3) + # 图表样式设置 theme_bw() + theme(aspect.ratio = 1) + labs(title = "散点图:原点距离与区域分类", x = "X轴", y = "Y轴", color = "区域分类")
代码关键点说明
- 直接用
sqrt(x^2 + y^2)逐行计算欧氏距离,比自定义函数更简洁高效 - 用
case_when实现多条件分支判断,逻辑清晰易维护 - 添加参考线和环形线,让分区规则可视化
- 通过
geom_text直接在散点旁标注距离值,无需额外交互
内容的提问来源于stack exchange,提问作者maycca
相关产品推荐
相关产品推荐

