Rotular pontos em geom_point

178

Os dados com os quais estou jogando são da fonte da Internet listada abaixo

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

O que eu quero fazer é criar um gráfico de pontos 2D comparando duas métricas desta tabela, com cada jogador representando um ponto no gráfico. Eu tenho o seguinte código:

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

Isso me dá o seguinte:

NBA Plot

O que eu quero é um rótulo com o nome do jogador ao lado dos pontos. Eu pensei que a função de rótulo na estética do ggplot faria isso por mim, mas não o fez.

Eu também tentei a text()função e a textxy()função from library(calibrate), nenhuma das quais parece funcionar com o ggplot.

Como posso adicionar rótulos a esses pontos?

Demônio Verde
fonte

Respostas:

280

Use geom_text, com aesetiqueta. Você pode brincar com hjust, vjustpara ajustar a posição do texto.

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

insira a descrição da imagem aqui

EDIT: rotule apenas valores acima de um determinado limite:

  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)

gráfico com rótulos condicionais

estudo
fonte
4
Existe alguma maneira de mudar os rótulos (evite-os levemente), para que eles não se sobreponham?
Thomas Browne
2
Não acho que exista uma solução fácil ggplot2. Talvez isso possa ajudá-lo.
agstudy
1
Existe alguma maneira de rotular pontos acima de um determinado valor, por exemplo, PTS maior que 24 no gráfico acima?
ONeillMB1
A menos que se desvie adequadamente, considere isso hjust = -0.1para afastar um pouco as etiquetas impressas do ponto de dados.
precisa saber é o seguinte
Para mudar as etiquetas, considere ggrepel .
Homer White
92

O ggrepelpacote funciona muito bem para afastar os rótulos de texto sobrepostos. Você pode usar geom_label_repel()(desenha retângulos ao redor do texto) ou geom_text_repel()funções.

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

insira a descrição da imagem aqui

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

Editar: Para usar ggrepelcom linhas, veja isto e isto .

Criado em 2019-05-01 pelo pacote reprex (v0.2.0).

Tung
fonte
1
Arrumado! Eu realmente gosto do primeiro enredo. Eu tentei isso com meus dados e estou feliz com o resultado, exceto que a legenda mostra "a" s em vez das formas mostradas no gráfico. (Eu uso uma forma estética para distinguir pontos de acordo com um factor)
cara de abelha
2
Resolvi esse problema agora (a) extraindo a legenda de um plot sem o geom_label_repel stackoverflow.com/questions/12041042/… e (b) adicionando-o com gridExtra :: grid.arrange a um plot com os rótulos. Se você conhece uma solução mais simples, eu ainda aprecio isso!
bee guy
1
@beeguy: não sei se entendi o que você está perguntando, mas recentemente vi um commit no ggplot2dev que mencionava algo semelhante github.com/tidyverse/ggplot2/commit/… . Você pode tentar instalar a versão de desenvolvimento do ggplot2& ggrepelpara ver se o seu problema foi corrigido #
315 Tung
1
@beeguy: fyi também existe um lemonpacote que é muito bom em manipular a legenda da trama.
Tung
1
Obrigado pela dica
bee guy
10

Em vez de usar o ifelse como no exemplo acima, também é possível pré-filtrar os dados antes da rotulagem com base em alguns valores limite, economizando muito trabalho para o dispositivo de plotagem:

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
fonte