# How do I avoid overlapping labels in an R plot? [closed]

I'm trying to label a pretty simple scatterplot in R. This is what I use:

plot(SI, TI)
text(SI, TI, Name, pos=4, cex=0.7)


The result is mediocre, as you can see (click to enlarge):

I tried to compensate for this using the textxy function, but it's not better. Making the image itself larger doesn't work for the dense clusters.

Is there any function or easy way to compensate for this and let R plot labels that don't overlap?

Here is a small subset of the data I have:

Name;SI;TI
01_BAD_talking_head;6.944714;4.421208
01_GOOD_talking_head;5.680141;4.864035
01_GOOD_talking_head_subtitles;7.170114;4.664205

• I posted similar question here, have a look on the answers there.. Sep 30, 2011 at 20:22
• I found a solution! The identify() let's you manually decide where to place the label! It's not ideal, but from the proposed solutions this works best for me. Oct 28, 2011 at 15:35
• blog.revolutionanalytics.com/2016/01/… Jan 18, 2016 at 13:47

## 6 Answers

Check out the new package ggrepel. ggrepel provides geoms for ggplot2 to repel overlapping text labels. It works both for geom_text and geom_label.

Figure is taken from this blog post.

The directlabels package does that. From its web page:

This package is an attempt to make direct labeling a reality in everyday statistical practice by making available a body of useful functions that make direct labeling of common plots easy to do with high-level plotting systems such as lattice and ggplot2.

It might not always be possible for dense plots, though.

Here is a short example:

set.seed(123)
a <- c(rnorm(10,-3,2),rnorm(10,3,2))
b <- c(rnorm(10,-3,2),rnorm(10,3,2))
dfr <- data.frame(a,b)
dfr\$t <- c(paste("A",1:10,sep=""),paste("B",1:10,sep=""))
direct.label(xyplot(b~a,dfr,groups=t, col="black"))


I did manage get rid of the point colouring with col="black", but the not labels.

• I'm having trouble getting it to work. Could you maybe provide a simple working example? Sep 26, 2011 at 16:31
• In your case, something like direct.label(xyplot(SI~TI,data=yourDataFrame,group=Name)) should get a similar result. Sep 26, 2011 at 17:13
• Perfect. Here's what I ended up with using your last simple example. The color labels and points are actually very nice, since you know where the labels belong. Sep 26, 2011 at 17:22
• I had to use library(lattice) to get xyplot to work. Sep 4, 2013 at 22:26

I'd suggest you take a look at the wordcloud package. I know this package focuses not exactly on the points but on the labels themselves, and also the style seems to be rather fixed. But still, the results I got from using it were pretty stunning. Also note that the package version in question was released about the time you asked the question, so it's still very new.

http://blog.fellstat.com/?cat=11

In the event that you simply cannot get the labels to work correctly as produced by R, keep in mind you can always save the graphs in a vector format (like .pdf) and pull them into an editing program like InkScape or Adobe Illustrator.

I ran into a similar problem with several of the plots I have been working with and wrote a basic package that uses force field simulation to adjust object locations. The advantage over some of the above-cited solutions is the dynamic adjustment for relative object proximity in 2D. While much improvement is possible, including heuristics and integration with ggplot, etc. it seems to get the task accomplished. The following illustrates the functionality:

install.packages("FField", type = "source")
install.packages("ggplot2")
install.packages("gridExtra")
library(FField)
FFieldPtRepDemo()


For now there is no heuristics for a variety of areas and point distributions as the solution met my needs and I wanted to get something helpful to folks out quickly but I'll add these in the medium term. At this time I recommend scaling charts to 100x100 and back and slightly tweaking the default attraction and repulsion parameters as warranted.

A couple of additional tools to look at in R:

These won't do everything for you, but one of them may be part of a solution.