在geom_point中标记数据点

238

我正在处理的数据来自下面列出的互联网来源

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

我想要做的是创建一个二维点图,比较这个表中的两项指标,并且每个玩家在图上都代表一个点。我有以下代码:

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

这给了我以下图表:

NBA Plot

我想要的是选手姓名标签紧挨着每个点。我曾经认为ggplot美学中的标签函数可以帮我实现,但它没有。

我还尝试过使用text()函数和textxy()函数,来自library(calibrate),但似乎都无法与ggplot一起使用。

如何向这些点添加名称标签?

3个回答

361

使用geom_text,并使用aes标签。你可以通过调整hjust,vjust来调整文本位置。

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

enter image description here

编辑:仅对高于某个阈值的标签进行标记:

  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)

带有条件标签的图表


5
有没有办法稍微移动标签位置(轻微躲避它们),以避免它们重叠? - Thomas Browne
2
我认为 ggplot2 中不存在简单的解决方案。也许这里可以对您有所帮助。 - agstudy
1
有没有办法只对某些点进行标记,例如在上图中,只标记大于24的PTS? - ONeillMB1
如果不适当地“躲避”数据点,可以考虑将hjust = -0.1设置为稍微远离数据点的标签位置。 - PatrickT
3
考虑使用ggrepel来调整标签位置。 - Homer White
显示剩余2条评论

158

ggrepel 包可以很好地将重叠的文本标签分开,使它们不会互相遮盖。您可以使用 geom_label_repel()(在文本周围绘制矩形)或 geom_text_repel() 函数。

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

在此输入图片描述

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

编辑:如需将ggrepel与线条一起使用,请参见

此示例是使用reprex包(v0.2.0)在2019-05-01创建的。


1
不错!我真的很喜欢第一个图。我用我的数据尝试了一下,除了图例显示“a”而不是图中显示的形状之外,我对结果感到满意。(我使用美学形状来根据因子区分点) - bee guy
2
我现在通过以下两种方法解决了这个问题:(a) 在没有geom_label_repel的情况下提取绘图的图例 https://dev59.com/1Wct5IYBdhLWcg3wgNnR?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa,(b) 然后使用gridExtra::grid.arrange将其添加到带有标签的绘图中。如果您知道更简单的解决方案,我仍然会感激! - bee guy
1
@beeguy: 不确定我是否理解你的问题,但我最近在ggplot2开发中看到了一个提交,提到了类似的事情 https://github.com/tidyverse/ggplot2/commit/1d537ce78bd58772d64a554a9b105159470799c6。你可以尝试安装`ggplot2`和`ggrepel`的开发版本,看看你的问题是否得到解决。 - Tung
1
@beeguy:顺便说一下,还有lemon包非常擅长操作绘图图例。 - Tung
显示剩余3条评论

12

除了使用上面示例中的ifelse之外,还可以根据某些阈值先预过滤数据,然后再进行标记,这可以为绘图设备节省大量工作:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接