ggplot绘制envfit结果时箭头与样点比例失调问题求助
解决ggplot绘制NMDS+envfit时箭头过长的问题
我参考了很多用ggplot绘制metaMDS和envfit结果的教程及已解决案例,但按步骤操作后,仍出现变量箭头异常过长、完全掩盖样点图的问题。多次尝试用ordiArrowMul()缩放箭头,结果依旧无效。原生plot()函数绘图结果正常,仅ggplot版本出问题。
问题原因
ordiArrowMul(ef)返回的缩放系数是为原生plot()设计的,ggplot的坐标系统与原生plot存在差异,直接相乘会导致箭头过度放大。同时,部分环境变量的数值范围差异较大,也会加剧箭头长度失衡的问题。
修改后的代码
1. 数据读取与基础分析(保留原逻辑)
# 读取数据 data <- read.csv('~/data.csv', row.names = 1) envi <- read.csv('~/env.csv', row.names = 1) meta <- structure(list(SAMPLE_ID = c("MOLA_1-1_A", "MOLA_1-1_A", "MOLA_1-1_A", "MOLA_10-1_A", "MOLA_10-1_A", "MOLA_10-1_A", "MOLA_12-1_A", "MOLA_12-1_A", "MOLA_12-1_A", "MOLA_13-1_A", "MOLA_13-1_A", "MOLA_15-1_A", "MOLA_15-1_A", "MOLA_15-1_A", "MOLA_18-1_A", "MOLA_18-1_A", "MOLA_18-1_A", "MOLA_19-1_A", "MOLA_19-1_A", "MOLA_19-1_A", "MOLA_21-1_B", "MOLA_21-1_B", "MOLA_22-1_A", "MOLA_22-1_A", "MOLA_22-1_A", "MOLA_23-1_B", "MOLA_23-1_B", "MOLA_23-1_B", "MOLA_25-1_A", "MOLA_25-1_A", "MOLA_25-1_A", "MOLA_4-1_A", "MOLA_4-1_A", "MOLA_4-1_A", "MOLA_7-1_A", "MOLA_7-1_A", "MOLA_7-1_A", "MOLA_9-1_A", "MOLA_9-1_A", "MOLA_9-1_A"), `Month-Year` = structure(c(1556668800, 1556668800, 1556668800, 1590969600, 1590969600, 1590969600, 1593561600, 1593561600, 1593561600, 1596240000, 1596240000, 1604188800, 1604188800, 1604188800, 1612137600, 1612137600, 1612137600, 1614556800, 1614556800, 1614556800, 1617235200, 1617235200, 1619827200, 1619827200, 1619827200, 1625097600, 1625097600, 1625097600, 1564617600, 1564617600, 1564617600, 1559347200, 1559347200, 1559347200, 1569888000, 1569888000, 1569888000, 1577836800, 1577836800, 1577836800), tzone = "UTC", class = c("POSIXct", "POSIXt")), season = c("Spring", "Spring", "Spring", "Summer", "Summer", "Summer", "Summer", "Summer", "Summer", "Summer", "Summer", "Autumn", "Autumn", "Autumn", "Winter", "Winter", "Winter", "Spring", "Spring", "Spring", "Spring", "Spring", "Spring", "Spring", "Spring", "Summer", "Summer", "Summer", "Summer", "Summer", "Summer", "Summer", "Summer", "Summer", "Autumn", "Autumn", "Autumn", "Winter", "Winter", "Winter"), Depth = c("5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m", "5 m"), month = c("May", "May", "May", "Jun", "Jun", "Jun", "Jul", "Jul", "Jul", "Aug", "Aug", "Nov", "Nov", "Nov", "Feb", "Feb", "Feb", "Mar", "Mar", "Mar", "Apr", "Apr", "May", "May", "May", "Jul", "Jul", "Jul", "Aug", "Aug", "Aug", "Jun", "Jun", "Jun", "Oct", "Oct", "Oct", "Jan", "Jan", "Jan")), class = "data.frame", row.names = c(NA, -40L)) # NMDS分析 set.seed(123) nmds <- metaMDS(as.matrix(data), distance = "bray") # envfit环境因子拟合 set.seed(123) ef <- envfit(nmds, envi, permu = 999)
2. 优化后的ggplot绘图代码
# 提取显著环境因子箭头数据(弃用ordiArrowMul,改用自定义缩放) en_coord_cont <- as.data.frame(scores(ef, "vectors")) en_coord_cont$pval <- ef[["vectors"]][["pvals"]] en_coord_cont <- dplyr::filter(en_coord_cont, pval <= 0.05) # 自定义缩放系数:基于NMDS样点坐标范围调整箭头长度 max_nmds1 <- max(abs(scores(nmds)$NMDS1)) max_nmds2 <- max(abs(scores(nmds)$NMDS2)) scale_factor <- min(max_nmds1, max_nmds2) / 4 # 分母可按需调整(3-5之间) # 对箭头坐标进行缩放 en_coord_cont <- en_coord_cont * scale_factor # 提取样点NMDS得分并关联元数据 data.scores <- as.data.frame(scores(nmds)) temp <- cbind(data.scores, meta) temp$month <- factor(temp$month, levels = month.abb) # ggplot绘图 xx <- ggplot(temp, aes(x = NMDS1, y = NMDS2)) + geom_point(size = 4, aes(shape = Depth, colour = month)) + coord_fixed() + theme( axis.text.y = element_text(colour = "black", size = 12, face = "bold"), axis.text.x = element_text(colour = "black", face = "bold", size = 12), legend.text = element_text(size = 12, face = "bold", colour = "black"), legend.position = "right", axis.title.y = element_text(face = "bold", size = 14), axis.title.x = element_text(face = "bold", size = 14, colour = "black"), legend.title = element_text(size = 14, colour = "black", face = "bold"), panel.background = element_blank(), panel.border = element_rect(colour = "black", fill = NA, size = 1.2), legend.key = element_blank() ) + scale_colour_manual(values = c('blue4','blue','green4','green3','green','red4','orangered','orange','yellow3','yellow')) + geom_vline(xintercept = 0, linetype = "dashed") + geom_hline(yintercept = 0, linetype = "dashed") + # 绘制缩放后的箭头 geom_segment( aes(x = 0, y = 0, xend = NMDS1, yend = NMDS2), data = en_coord_cont, size = 1, alpha = 0.5, colour = "grey30" ) + # 文本标签偏移到箭头外侧,避免重叠 geom_text( data = en_coord_cont, aes(x = NMDS1 * 1.1, y = NMDS2 * 1.1), colour = "grey30", fontface = "bold", label = row.names(en_coord_cont) ) print(xx)
关键调整说明
- 核心修改:放弃
ordiArrowMul(ef),改用基于NMDS样点坐标范围的自定义缩放系数,确保箭头长度与样点图比例匹配。 - 微调方式:若箭头长度仍不符合预期,可调整
scale_factor的分母(比如改成3或5),按需适配。 - 细节优化:将环境变量标签偏移到箭头外侧,避免与箭头或样点重叠。
内容的提问来源于stack exchange,提问作者user18309655
相关产品推荐
相关产品推荐

