Beschriften Sie Punkte in geom_point

178

Die Daten, mit denen ich spiele, stammen aus der unten aufgeführten Internetquelle

nba <- read.csv("http://datasets.flowingdata.com/ppg2008.csv", sep=",")

Ich möchte ein 2D-Punktediagramm erstellen, in dem zwei Metriken aus dieser Tabelle verglichen werden, wobei jeder Spieler einen Punkt im Diagramm darstellt. Ich habe folgenden Code:

nbaplot <- ggplot(nba, aes(x= MIN, y= PTS, colour="green", label=Name)) + 
                  geom_point() 

Dies gibt mir Folgendes:

NBA-Handlung

Was ich möchte, ist eine Bezeichnung des Spielernamens direkt neben den Punkten. Ich dachte, die Label-Funktion in der Ästhetik von ggplot würde dies für mich tun, aber das tat es nicht.

Ich habe auch die text()Funktion und die textxy()Funktion von ausprobiert library(calibrate), von denen keine mit ggplot zu funktionieren scheint.

Wie kann ich diesen Punkten Namensschilder hinzufügen?

Grüner Dämon
quelle

Antworten:

278

Verwenden Sie geom_textmit aesEtikett. Sie können damit spielen hjust, vjust, um die Textposition anzupassen.

ggplot(nba, aes(x= MIN, y= PTS, colour="green", label=Name))+
  geom_point() +geom_text(aes(label=Name),hjust=0, vjust=0)

Geben Sie hier die Bildbeschreibung ein

BEARBEITEN: Beschriften Sie nur Werte über einem bestimmten Schwellenwert:

  ggplot(nba, aes(x= MIN, y= PTS, colour="green", label=Name))+
  geom_point() +
  geom_text(aes(label=ifelse(PTS>24,as.character(Name),'')),hjust=0,vjust=0)

Diagramm mit bedingten Beschriftungen

Agstudy
quelle
4
Gibt es eine Möglichkeit, die Etiketten zu verschieben (ihnen etwas auszuweichen), damit sie sich nicht überlappen?
Thomas Browne
2
Ich glaube nicht, dass es eine einfache Lösung gibt ggplot2. Vielleicht dies kann Ihnen helfen.
Agstudy
1
Gibt es eine Möglichkeit, nur Punkte über einem bestimmten Wert zu kennzeichnen, z. B. PTS größer als 24 im obigen Diagramm?
ONeillMB1
Wenn Sie nicht richtig ausweichen, sollten Sie dies berücksichtigen hjust = -0.1, um die gedruckten Etiketten ein wenig vom Datenpunkt zu entfernen.
PatrickT
Berücksichtigen Sie ggrepel, um Beschriftungen zu verschieben .
Homer White
89

Das ggrepelPaket eignet sich hervorragend, um überlappende Textbeschriftungen voneinander abzuwehren. Sie können entweder geom_label_repel()(zeichnet Rechtecke um den Text) oder geom_text_repel()Funktionen verwenden.

library(ggplot2)
library(ggrepel)

nba <- read.csv("http://datasets.flowingdata.com/ppg2008.csv", sep = ",")

nbaplot <- ggplot(nba, aes(x= MIN, y = PTS)) + 
  geom_point(color = "blue", size = 3)

### geom_label_repel
nbaplot + 
  geom_label_repel(aes(label = Name),
                  box.padding   = 0.35, 
                  point.padding = 0.5,
                  segment.color = 'grey50') +
  theme_classic()

Geben Sie hier die Bildbeschreibung ein

### geom_text_repel
# only label players with PTS > 25 or < 18
# align text vertically with nudge_y and allow the labels to 
# move horizontally with direction = "x"
ggplot(nba, aes(x= MIN, y = PTS, label = Name)) + 
  geom_point(color = dplyr::case_when(nba$PTS > 25 ~ "#1b9e77", 
                                      nba$PTS < 18 ~ "#d95f02",
                                      TRUE ~ "#7570b3"), 
             size = 3, alpha = 0.8) +
  geom_text_repel(data          = subset(nba, PTS > 25),
                  nudge_y       = 32 - subset(nba, PTS > 25)$PTS,
                  size          = 4,
                  box.padding   = 1.5,
                  point.padding = 0.5,
                  force         = 100,
                  segment.size  = 0.2,
                  segment.color = "grey50",
                  direction     = "x") +
  geom_label_repel(data         = subset(nba, PTS < 18),
                  nudge_y       = 16 - subset(nba, PTS < 18)$PTS,
                  size          = 4,
                  box.padding   = 0.5,
                  point.padding = 0.5,
                  force         = 100,
                  segment.size  = 0.2,
                  segment.color = "grey50",
                  direction     = "x") +
  scale_x_continuous(expand = expand_scale(mult = c(0.2, .2))) +
  scale_y_continuous(expand = expand_scale(mult = c(0.1, .1))) +
  theme_classic(base_size = 16)

Erstellt am 01.05.2019 durch das reprex-Paket (v0.2.0).

Tung
quelle
1
Ordentlich! Ich mag die erste Handlung wirklich. Ich habe dies mit meinen Daten versucht und bin mit dem Ergebnis zufrieden, außer dass die Legende "a" anstelle der im Diagramm gezeigten Formen anzeigt. (Ich benutze eine ästhetische Form, um Punkte nach einem Faktor zu unterscheiden)
Bee Guy
2
Ich habe dieses Problem jetzt gelöst, indem ich (a) die Legende eines Plots ohne geom_label_repel stackoverflow.com/questions/12041042/… extrahiert und (b) sie dann mit gridExtra :: grid.arrange zu einem Plot mit den Beschriftungen hinzugefügt habe. Wenn Sie eine einfachere Lösung kennen, würde ich das trotzdem begrüßen!
Biene Kerl
1
@beeguy: Ich bin mir nicht sicher, ob ich verstehe, was Sie fragen, aber ich habe kürzlich ein Commit für ggplot2Entwickler gesehen, in dem ähnliche Dinge erwähnt wurden: github.com/tidyverse/ggplot2/commit/… . Sie können versuchen, beide Entwicklerversionen von ggplot2& zu installieren, um ggrepelzu sehen, ob Ihr Problem behoben ist
Tung
1
@beeguy: fyi es gibt auch ein lemonPaket, das sehr gut darin ist, die Handlungslegende zu manipulieren.
Tung
1
Vielen Dank für den Tipp
Bee Guy
10

Anstatt das ifelse wie im obigen Beispiel zu verwenden, können die Daten auch vor dem Etikettieren anhand einiger Schwellenwerte vorgefiltert werden. Dies spart dem Plotgerät viel Arbeit:

xlimit <- 36
ylimit <- 24
ggplot(myData)+geom_point(aes(myX,myY))+
    geom_label(data=myData[myData$myX > xlimit & myData$myY> ylimit,], aes(myX,myY,myLabel))
Patrick Dolan
quelle