求助:使用pdf()导出R绘图时图外图例无法显示的问题
问题:R批量导出PDF时图例外无法显示,手动导出正常
我遇到的问题与多年前的一个Stack提问一致,但当时的所有解答都未能解决我的问题,因此重新发起提问。
需求是批量生成20张带外部图例的PDF图,代码如下:
for(i in 1:20){ pdf(paste0("Plot_BOTH_cM-Mb_CHR", i, ".pdf"), width = 10, height = 8) par(mar = c(5,5,5,10), xpd = T) plot(cm_r10 ~ mb, data = subset(recomb_match[[i]], recomb_match[[i]][,"snp_both"]=="1_1"), las = 1, main = paste("chromosome",i, sep = " "), xlab = "Mb", ylab = "cM", ylim = c(0,120)) points(cm_m10 ~ mb, data = subset(recomb_match[[i]], recomb_match[[i]][,"snp_both"]=="1_1"), col = "red") legend("topright", inset=c(-0.81,-0.08), col = c("black","red"), legend = c("RheMac10 (old)","Mmul_10 (new)"), bty="n", pch = 19, y.intersp=0.2, x.intersp = 0.2, xpd = T) dev.off() }
当前现象:在RStudio中手动导出PDF时,图例可以正常显示;但使用pdf()函数批量导出时,图外的图例无法显示。
解决方法尝试
1. 调整边距与inset的匹配
当前右边距设置为10,但图例的x方向偏移量过大(inset=c(-0.81,-0.08)),可能超出PDF画布范围。尝试增大右边距并减小偏移量:
for(i in 1:20){ pdf(paste0("Plot_BOTH_cM-Mb_CHR", i, ".pdf"), width = 10, height = 8) par(mar = c(5,5,5,15), xpd = TRUE) # 右边距从10调整为15 plot(cm_r10 ~ mb, data = subset(recomb_match[[i]], recomb_match[[i]][,"snp_both"]=="1_1"), las = 1, main = paste("chromosome",i, sep = " "), xlab = "Mb", ylab = "cM", ylim = c(0,120)) points(cm_m10 ~ mb, data = subset(recomb_match[[i]], recomb_match[[i]][,"snp_both"]=="1_1"), col = "red") legend("topright", inset=c(-0.3, 0), # 减小x方向负偏移 col = c("black","red"), legend = c("RheMac10 (old)","Mmul_10 (new)"), bty="n", pch = 19, y.intersp=0.2, x.intersp = 0.2, xpd = TRUE) dev.off() }
2. 使用xpd=NA替代xpd=T
xpd=T仅允许内容在绘图区和边距内显示,xpd=NA则允许内容超出整个设备区域,可避免画布裁剪:
for(i in 1:20){ pdf(paste0("Plot_BOTH_cM-Mb_CHR", i, ".pdf"), width = 10, height = 8) par(mar = c(5,5,5,10), xpd = NA) # 改为xpd=NA plot(cm_r10 ~ mb, data = subset(recomb_match[[i]], recomb_match[[i]][,"snp_both"]=="1_1"), las = 1, main = paste("chromosome",i, sep = " "), xlab = "Mb", ylab = "cM", ylim = c(0,120)) points(cm_m10 ~ mb, data = subset(recomb_match[[i]], recomb_match[[i]][,"snp_both"]=="1_1"), col = "red") legend("topright", inset=c(-0.81,-0.08), col = c("black","red"), legend = c("RheMac10 (old)","Mmul_10 (new)"), bty="n", pch = 19, y.intersp=0.2, x.intersp = 0.2, xpd = NA) dev.off() }
3. 用layout()分割画布,单独预留图例区域
这种方法更稳定,直接将画布分为绘图区和图例区,彻底避免偏移量问题:
for(i in 1:20){ pdf(paste0("Plot_BOTH_cM-Mb_CHR", i, ".pdf"), width = 12, height = 8) # 适当加宽画布 # 布局:左侧80%为绘图区,右侧20%为图例区 layout(matrix(c(1,2), ncol=2), widths=c(4,1)) # 绘图区设置 par(mar = c(5,5,5,2)) # 减小右边距 plot(cm_r10 ~ mb, data = subset(recomb_match[[i]], recomb_match[[i]][,"snp_both"]=="1_1"), las = 1, main = paste("chromosome",i, sep = " "), xlab = "Mb", ylab = "cM", ylim = c(0,120)) points(cm_m10 ~ mb, data = subset(recomb_match[[i]], recomb_match[[i]][,"snp_both"]=="1_1"), col = "red") # 图例区设置 par(mar = c(5,0,5,5)) # 左侧边距设为0,消除空隙 plot.new() # 创建空绘图区 legend("left", col = c("black","red"), legend = c("RheMac10 (old)","Mmul_10 (new)"), bty="n", pch = 19, y.intersp=0.2, x.intersp = 0.2) dev.off() }
4. 调整PDF设备参数
部分PDF阅读器对符号渲染支持不佳,可尝试关闭useDingbats:
pdf(paste0("Plot_BOTH_cM-Mb_CHR", i, ".pdf"), width = 10, height = 8, useDingbats = FALSE)
内容的提问来源于stack exchange,提问作者Cephalanthera
相关产品推荐
相关产品推荐

