5

我正在努力避免下图中的标签过于拥挤:

set.seed(123)
position <- c(rep (0,5), rnorm (5,1,0.1), rnorm (10, 3,0.1), rnorm (3, 4, 0.2), 5, rep(7,5), rnorm (3, 8,2),  rnorm (10,9,0.5),
               rep (0,5), rnorm (5,1,0.1), rnorm (10, 3,0.1), rnorm (3, 4, 0.2), 5, rep(7,5), rnorm (3, 8,2),  rnorm (10,9,0.5))
group <- c(rep (1, length (position)/2),rep (2, length (position)/2)  )
mylab <- paste ("MR", 1:length (group), sep = "")
barheight <- 0.5

y.start <- c(group-barheight/2)
y.end <- c(group+barheight/2)
mydf <- data.frame (position, group, barheight, y.start, y.end, mylab)


plot(0,type="n",ylim=c(0,3),xlim=c(0,10),axes=F,ylab="",xlab="")
#Create two horizontal lines
require(fields)
yline(1,lwd=4)
yline(2,lwd=4)
#Create text for the lines
text(10,1.1,"Group 1",cex=0.7)
text(10,2.1,"Group 2",cex=0.7)
#Draw vertical bars
lng = length(position)/2
lg1 = lng+1
lg2 = lng*2
segments(mydf$position[1:lng],mydf$y.start[1:lng],y1=mydf$y.end[1:lng])
segments(mydf$position[lg1:lg2],mydf$y.start[lg1:lg2],y1=mydf$y.end[lg1:lg2])
text(mydf$position[1:lng],mydf$y.start[1:lng]+0.65, mydf$mylab[1:lng], srt = 90)
text(mydf$position[lg1:lg2],mydf$y.start[lg1:lg2]+0.65, mydf$mylab[lg1:lg2], srt = 90)

您可以看到一些区域被标签挤满 - 当 x 值相同或相似时。我只想显示一个标签(当同一点有多个标签时)。例如,

mydf$position[1:5] 都是 0,

但相应的标签 mydf$mylab[1:5] -

 MR1  MR2  MR3  MR4  MR5 

我只想显示第一个“MR1”。

类似地,以下点太接近了(比如 0.35 的差异),它们应该被认为是一个单独的集群,并且将显示第一个标签。通过这种方式,我将能够摆脱过度拥挤的标签。我怎样才能实现它?

在此处输入图像描述

4

2 回答 2

10

如果您将标签隔开并添加一些额外的行,您可以标记每个标记。

clpl <- function(xdata, names, y=1, dy=0.25, add=FALSE){
  o = order(xdata)
  xdata=xdata[o]
  names=names[o]
  if(!add)plot(0,type="n",ylim=c(y-1,y+2),xlim=range(xdata),axes=F,ylab="",xlab="")
  abline(h=1,lwd=4)
  dy=0.25
  segments(xdata,y-dy,xdata,y+dy)
  tpos = seq(min(xdata),max(xdata),len=length(xdata))
  text(tpos,y+2*dy,names,srt=90,adj=0)
  segments(xdata,y+dy,tpos,y+2*dy)
}

然后使用您的数据:

clpl(mydf$position[lg1:lg2],mydf$mylab[lg1:lg2])

给出:

带有标注的标记线

然后,您可以考虑在主线下方标记集群。

我没有太多考虑在一个情节中做多行,但我认为对我的代码和 add 参数进行一些处理应该是可能的。您还可以使用颜色来显示集群。我相当确定这些技术存在于 R 的一些集群包中......

显然,如果有很多标记,即使这也会被弄脏,但是如果有很多集群,同样的事情也会发生。也许您最终会使用这种技术标记集群?

于 2013-02-20T08:44:21.830 回答
2

一般来说,我同意@Joran 的观点,集群标签不能自动化,但你说过用集群中的第一个标签来标记一组行是可以的,因此可以自动化一些过程。

将以下代码放在该行之后lg2 = lng*2会产生下图所示的结果:

clust <- cutree(hclust(dist(mydf$position[1:lng])),h=0.75)
u <- rep(T,length(unique(clust)))
clust.labels <- sapply(c(1:lng),function (i)
    {
    if (u[clust[i]])
        {
        u[clust[i]] <<- F
        as.character(mydf$mylab)[i]
        }
    else
        {
        ""
        }
    })

segments(mydf$position[1:lng],mydf$y.start[1:lng],y1=mydf$y.end[1:lng])
segments(mydf$position[lg1:lg2],mydf$y.start[lg1:lg2],y1=mydf$y.end[lg1:lg2])
text(mydf$position[1:lng],mydf$y.start[1:lng]+0.65, clust.labels, srt = 90)
text(mydf$position[lg1:lg2],mydf$y.start[lg1:lg2]+0.65, mydf$mylab[lg1:lg2], srt = 90)

标记的集群

(我只在下一行标记了集群——同样的原则也可以应用于上一行)。可能必须根据具体情况调整参数hcutree()提供您想要的标签分辨率,但这种方法至少比手动标记每个集群更容易。

于 2013-02-20T04:17:35.630 回答