避免r图中的标签过度拥挤

时间:2013-02-20 02:15:23

标签: r plot ggplot2

我正在努力避免在以下情节中过度拥挤标签:

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 

我只想显示第一个&#34; MR1&#34;。

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

enter image description here

2 个答案:

答案 0 :(得分: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])

给出:

marking lines with callouts

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

我没有太多想过在一个情节中做多行,但我认为我的代码和添加参数有点混乱应该是可能的。您还可以使用颜色来显示群集。我很确定这些技术存在于R ...的一些集群包中。

显然,即使有很多标记,这也会变得很轻松,但是对于很多集群来说,同样的事情也会发生。也许你最终用这种技术标记集群?

答案 1 :(得分: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)

Labelled Clusters

(我只在下面的线上标记了簇 - 相同的原理也可以应用于上面的线)。 h的{​​{1}}参数可能需要逐个调整,以便为您提供所需标签的分辨率,但这种方法至少比手工标记每个群集更容易。

相关问题