带有标签线的自定义轴
Posted
技术标签:
【中文标题】带有标签线的自定义轴【英文标题】:Custom axis with lines to labels 【发布时间】:2012-09-20 11:27:39 【问题描述】:我不知道如何表达这个问题,但我正在尝试将带有线条的标签添加到基本散点图上的对应点。到目前为止,我有以下内容:
example <- data.frame(name=paste("label_",1:200,sep=""),plot=rep(FALSE,200),rank=c(1:200),score=exp(seq(6,0,length.out=200)))
example$plot[c(1:3,7,8,35,37,150:155,183)] <- TRUE
plot(x=example$score,y=example$rank,ylim=rev(range(c(1:nrow(example)))),axes=FALSE,ylab="",xlab="Score",frame.plot=FALSE)
axis(side=1,labels=TRUE)
axis(side=2,labels=example$name[which(example$plot==TRUE)],at=example$rank[which(example$plot==TRUE)],las=1,tick=FALSE)
points(x=example$score[which(example$plot==TRUE)],y=example$rank[which(example$plot==TRUE)],col="Red",cex=1.5,pch=16)
代码给出了以下情节:
这对我的目的很有效,除了标签重叠非常严重。我正在寻找一种通用方法来制作如下图:
代码位于函数中,因此它需要适用于通用数据集的任何变化。我正在查看 safe
包中 safeplot
背后的代码,但到目前为止,我无法复制他们为解决类似问题所做的工作。
我现在也尝试使用 vegan
包中的 linestack()
函数。
par(mar=c(5,10,4,2))
plot(x=example$score,y=example$rank,ylim=rev(range(c(1:nrow(example)))),axes=FALSE,ylab="",xlab="Score",frame.plot=FALSE)
axis(side=1,labels=TRUE)
points(x=example$score[which(example$plot==TRUE)],y=example$rank[which(example$plot==TRUE)],col="Red",cex=1.5,pch=16)
linestack(x=example$rank[which(example$plot==TRUE)],labels=example$name[which(example$plot==TRUE)],add=TRUE,side="left",air=1.1,at=0,hoff=2)
但是,linestack()
只是给了我以下信息:
我尝试改变所有参数,但无法将标签分开。
【问题讨论】:
您可以使用lines()
和text()
函数绘制这些线条和标签。
lines()
和 text()
函数仅在绘图区域内绘制,而不在边缘绘制。
lines
和text
可以用par(xpd=TRUE)
画出边距。
我也试过了。我不清楚xpd=TRUE
时坐标系是如何工作的。
与绘图区域的坐标系相同。在内部区域之外绘制时我喜欢做的是首先在绘图区域中获取我需要的所有内容,然后调用par(new=TRUE, xpd=TRUE)
,然后调用plot(NA, NA, type='n', xlim=my.xlim, ylim=my.ylim)
,其中my.xlim
和my.ylim
是方便的xaxis 和yaxis 范围,用于在外部绘制边距,例如,my.xlim=c(0,1)
。
【参考方案1】:
这里有几个问题,特别是通常您不能在绘图区域之外绘制,因为剪裁会遮盖超出限制的任何内容(即在边距中)。您还需要在该边距中留出大量空间以容纳标签和线条。
虽然这比我现在可以在 SO 上从事的工作更重要,但我建议您查看 vegan 包中的 linestack()
函数以及它在 @ 中的使用方式987654322@方法。
我最近使用 `linestack() 函数做了一些与您描述的非常相似的事情,以改进 glmnet 包中的一些绘图。如果您需要更多帮助,请回复评论,我会一起编写一个示例。
【讨论】:
感谢您的回复。我会检查 linestack() 并让你知道我是否可以让它工作。在我的实际代码中,我确实增加了边距,我只是没有费心为示例添加代码行。再次感谢! 我尝试了linestack()
函数,但无法让它工作。我用我运行的代码更新了我的问题。
当你有时间时,我真的很感激一个例子。这似乎仍然是最有效的解决方案。提前致谢。
我发现了问题。 linestack()
函数在分隔标签时使用 strheight
函数作为乘数。当我在我的情节调用中将ylim
分配给反向时,它导致strheight
变为负数 - 因此标签不会分开。该函数的作用就像一个带有负 air
值的魅力。谢谢!
@PatrickT 我的编辑被拒绝了。我所做的只是重写 vegan
包中的 linestack
函数。您只需要通过在strheight
调用周围包裹abs
来修复ht <- air * strheight(names(x), cex = cex)
行。【参考方案2】:
查看 TeachingDemos 包中的 spread.labs
函数和 plotrix 包中的 spread.labels
函数,了解选择标签放置位置的方法。
设置par(xpd=NA)
可以让你使用text
,lines
,segments
等函数在绘图区域外绘制。
grconvertX
函数也可能有助于找到标签和线段的水平位置。
【讨论】:
以上是关于带有标签线的自定义轴的主要内容,如果未能解决你的问题,请参考以下文章
在 WooCommerce 产品页面中显示带有标签和值的自定义字段?