2013-02-20 19 views
5

Ich arbeite an avoid über Crowding der Etiketten in der folgenden Handlung:Vermeidung von Überbelegung von Etiketten in r Graphen

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) 

können Sie einige Bereiche zu sehen sind, mit den Etiketten krähte - wenn x-Wert gleich ist o.ä. Ich möchte nur ein Label anzeigen (wenn mehrere Labels am selben Punkt sind). Zum Beispiel

mydf $ Position [1: 5] sind alle 0,

aber entsprechende Etikett mydf MyLab $ [1: 5] -

MR1 MR2 MR3 MR4 MR5 

Ich möchte nur die ersten anzuzeigen "MR1".

Ähnlich sind die folgenden Punkte zu nahe (sagen wir die Differenz von 0,35), sie sollten als ein einziger Cluster betrachtet werden und die erste Beschriftung wird angezeigt. Auf diese Weise würde ich die Überfüllung der Etiketten beseitigen können. Wie kann ich es erreichen?

enter image description here

+2

Es gibt keine automatische Lösung für diese Art von Problemen.Auf die eine oder andere Weise müssen Sie dies "von Hand" beheben: Entweder indem Sie die Beschriftungen für Gruppen enger Zeilen hart codieren oder indem Sie alle Beschriftungen weglassen und sie anschließend mit einem Bildeditor hinzufügen. – joran

+0

Sie können die i-Position von i-1-Positionsdaten subtrahieren und dann einen Schwellenwert erstellen, um einen Cluster zu erstellen. Dann wahrscheinlich ein Label pro Cluster anzeigen – jon

Antwort

10

Wenn Sie die Etiketten ausschneiden und einige zusätzliche Zeilen hinzufügen, können Sie jeden Marker beschriften.

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) 
} 

mit dann Ihre Daten:

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

gibt:

marking lines with callouts

Sie dann über die Kennzeichnung Cluster unterhalb der Hauptlinie denken konnte.

Ich habe nicht viel darüber nachgedacht, mehrere Zeilen in einem Plot zu machen, aber ich denke mit ein bisschen Muck mit meinem Code und dem Add-Parameter sollte es möglich sein. Sie können auch Farben zum Anzeigen von Clustern verwenden. Ich bin ziemlich sicher, dass diese Techniken in einigen der Clustering-Pakete für R vorhanden sind ...

Offensichtlich mit einer Menge von Markern wird auch dies zu werden, aber mit vielen Clustern das gleiche wird zu gehen geschehen. Vielleicht beschreibst du Cluster mit dieser Technik?

+0

+1: Sehr elegante Option! – Simon

+0

+1 für nette Option – SHRram

2

Im Allgemeinen bin ich mit @Joran dass Cluster Markierung kann nicht automatisiert werden, aber Sie haben gesagt, dass in dem Cluster mit dem ersten Etikett eine Gruppe von Linien Kennzeichnung wäre in Ordnung, es ist also möglich, einen Teil des Prozesses zu automatisieren.

den folgenden Code nach der Linie Putting lg2 = lng*2 gibt das Ergebnis im Bild unten dargestellt:

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

(Ich habe nur die Cluster in der unteren Zeile markiert - das gleiche Prinzip könnte auch auf die obere Linie angewendet werden). Der Parameter h von cutree() muss möglicherweise von Fall zu Fall angepasst werden, um die Auflösung der gewünschten Beschriftungen zu erhalten, aber dieser Ansatz ist zumindest einfacher als die Beschriftung jedes Clusters per Hand.