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

避免r图中标签的过度拥挤,r,plot,ggplot2,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, r

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

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)
我只想显示第一个“MR1”

类似地,以下点太接近(比如差0.35),应将其视为单个簇,并显示第一个标签。这样,我就可以摆脱过度拥挤的标签。我怎样才能做到呢


一般来说,我同意@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)

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

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)
}
给出:

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

我没有太多考虑在一个绘图中绘制多行,但我认为稍微修改一下我的代码和add参数应该是可能的。您还可以使用颜色来显示簇。我相当肯定这些技术在一些集群软件包中都有,用于R


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

对于这类问题没有自动的解决方案。不管怎样,你都必须“手工”解决这个问题:要么对闭合线组的标签进行硬编码,要么省略所有标签,然后用图像编辑器添加。你可以从i-1位置数据中减去i位置,然后设置一个阈值来创建一个簇。然后可能会为每个集群显示一个标签
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])