2016-02-03 10 views
13

Ich habe ein Dataset, in dem jeder Datenpunkt einen x-Wert hat, der beschränkt ist (repräsentiert eine tatsächliche Instanz einer quantitativen Variablen), y-Wert ist beliebig (existiert einfach, um eine Dimension zu verteilen Text) und eine Bezeichnung. Meine Datensätze können sehr groß sein, und es gibt häufig Textüberschneidungen, selbst wenn ich versuche, die Daten so weit wie möglich über die y-Achse zu verteilen.ggrepel: Text in nur einer Richtung abstoßen und Werte von abgestoßenem Text zurückgeben

Daher versuche ich das neue ggrepel zu verwenden. Ich versuche jedoch, die Textbeschriftungen an ihrer x-Wert-Position eingeschränkt zu halten, während sie sich nur gegenseitig in y-Richtung abstoßen können.

Als Beispiel erzeugt der folgende Code ein Diagramm für 32 Datenpunkte, wobei die x-Werte die Anzahl der Zylinder in einem Auto zeigen, und die y-Werte sind zufällig bestimmt (haben keine Bedeutung, aber eine Sekunde zu liefern) Dimension für Textplottzwecke). Ohne ggrepel zu verwenden, gibt es erhebliche Überschneidungen im Text:

library(ggrepel) 
library(ggplot2) 
set.seed(1) 
data = data.frame(x=runif(100, 1, 10),y=runif(100, 1, 10),label=paste0("label",seq(1:100))) 
origPlot <- ggplot(data) + 
    geom_point(aes(x, y), color = 'red') + 
    geom_text(aes(x, y, label = label)) + 
    theme_classic(base_size = 16) 

Original plot

ich den Text überlappt mit ggrepel beheben kann, wie unten gezeigt. Dies ändert jedoch nicht nur die y-Werte, sondern auch die x-Werte. Ich versuche, die x-Werte nicht zu verändern, da sie eine tatsächliche physikalische Bedeutung (die Anzahl der Zylinder) darstellen:

repelPlot <- ggplot(data) + 
    geom_point(aes(x, y), color = 'red') + 
    geom_text_repel(aes(x, y, label = label)) + 
    theme_classic(base_size = 16) 

enter image description here

Als Hinweis, der Grund, warum ich nicht dem x-Wert zulassen Der Text zu ändern ist, weil ich nur den Text (nicht die Punkte) plotten. Hingegen scheint es, dass die meisten Beispiele in grepel die Position der Punkte behalten (so dass ihre Werte wahr bleiben) und nur die x- und y-Werte der Labels abstoßen. Dann die Punkte und verbunden mit den Beschriftungen mit Segmenten (das sieht man in meinem zweiten Plotbeispiel).

Ich habe die Punkte in den beiden obigen Beispielen zu Demonstrationszwecken behalten. Allerdings bin ich behielt nur den Text (und damit die Punkte und die Segmente werden zu entfernen), so dass ich mit so etwas wie folgt aus:

repelPlot2 <- ggplot(data) + geom_text_repel(aes(x, y, label = label), segment.size = 0) + theme_classic(base_size = 16) 

enter image description here

Meine Frage ist zweifach:

1) Kann ich die Textbeschriftungen nur in y-Richtung abstoßen?

2) Ist es mir möglich, eine Struktur zu erhalten, die die neuen (abgestoßenen) y-Werte des Textes enthält?

Vielen Dank für jeden Hinweis!

+0

Ich verstehe nicht, wie das das Problem lösen würde? Vielen Dank. – luckButtered

Antwort

4

ggrepel Version 0.6.8 (Installieren von GitHub devtools Verwendung :: github_install) unterstützt jetzt eine "Richtung" -Argument, die nur in "x" Abstoßen von Etiketten ermöglicht, oder "y" -Richtung .

repelPlot2 <- ggplot(data) + geom_text_repel(aes(x, y, label = label), segment.size = 0, direction = "y") + theme_classic(base_size = 16)

die y-Werte zu erhalten ist schwieriger - ein Ansatz sein, um die „repel_boxes“ -Funktion von ggrepel zu verwenden, zuerst abgestoßen Werte zu erhalten und geben Sie dann diejenigen in ggplot mit geom_text. Zur Diskussion und zum Beispielcode dieses Ansatzes siehe https://github.com/slowkow/ggrepel/issues/24. Beachten Sie, dass die Funktion repel_boxes jetzt auch ein "Direction" -Argument enthält, das "both", "x" oder "y" verwendet, wenn Sie die neueste Version verwenden.

5

Ich glaube nicht, dass es möglich ist, Text-Etiketten nur in einer Richtung mit ggrepel abzustoßen.

Ich würde dieses Problem anders angehen, indem ich die willkürlichen Y-Achsen-Positionen manuell erzeuge. Für den Datensatz in Ihrem Beispiel können Sie beispielsweise den folgenden Code verwenden.

Ich habe das Paket dplyr verwendet, um den Datensatz mit den Werten x zu gruppieren, und dann eine neue Spalte mit den Daten y mit den Zeilennummern innerhalb jeder Gruppe erstellt. Die Zeilennummern werden dann als Werte für die Y-Achse verwendet.

library(ggplot2) 
library(dplyr) 

data <- data.frame(x = mtcars$cyl, label = paste0("label", seq(1:32))) 

data <- data %>% 
    group_by(x) %>% 
    mutate(y = row_number()) 

ggplot(data, aes(x = x, y = y, label = label)) + 
    geom_text(size = 2) + 
    xlim(3.5, 8.5) + 
    theme_classic(base_size = 8) 

ggsave("filename.png", width = 4, height = 2) 

enter image description here

+0

Ich weiß, meine Frage ist unbeabsichtigt irreführend. In meinem realen Datensatz sind die x-Werte kontinuierlich (nicht diskret, wie ich meinen MWE gemacht habe). Wenn ich also Ihre Lösung anwende, löst sie das Problem nicht. Ich bearbeite meinen Fehler, und wenn ich keine Lösung für meine (klarere) Frage höre, werde ich auch Ihre aktuelle Antwort auswählen. Vielen Dank. – luckButtered

+0

Ich habe ursprünglich eine ähnliche Lösung angewendet, ursprünglich, was Sie getan haben. Außer ich habe Labels in Bins mit ähnlichen X-Werten gruppiert. Es gibt jedoch immer noch erhebliche Überschneidungen in einem Datensatz mit vielen Labels, und das war der Zeitpunkt, als ich mich an grepel wandte. – luckButtered

Verwandte Themen