So I want to plot some ordination data. In this figure, points are informants with their distance from one another a measure of how similar or different their lists of homegarden plants are.

locations <- data.frame(SRplant.ord$points,SR.env)

ggplot(locations, aes(MDS1,MDS2))+
  geom_point()+
  theme_bw()

But when I add labels to the points I see that I have a big problem with overplotting - points from people who gave the exact same responses (and therefore have zero distance from one another) appear as a single point.

locations <- data.frame(SRplant.ord$points,SR.env)

ggplot(locations, aes(MDS1,MDS2))+
  geom_point()+
  geom_text(aes(label=1:length(Informant.name)))+
  theme_bw()

So after a lot of thinking, I came up with this:

require(circular)
#load a pacakge that gives me radians

  locations %>%
  mutate(roundx=(round(MDS1,1)),roundy=round(MDS2,1)) %>%
  #use rounding to make 'clusters' of points that are reasonably close
  group_by(roundx,roundy) %>%                                                           
  #group by those clusters
  
    mutate(n=n(),seq=1:length(n)) %>%
    #count the number of points in a cluster and asssign it to the individual records
    #also give them a sequential number within the cluster
  
  group_by(Informant.name) %>%
  #go back to doing things on each informant, rather than each cluster
         mutate(
         degrees=(360/n)*seq,              
         #divide up the angles in a circle by the number of points in a cluster
         yjitter=MDS2+round(sqrt(.007)*sin(rad(degrees/sin(rad(90)))),3),
         xjitter=MDS1+round(sqrt(.007)*sin(rad((180-degrees-90)/sin(rad(90)))),3)
         #and for each point, assign it one piece of the pi (heh)
         #figuring out how to convert angles to XY coordinates took me about 2 hours of refreshing my math skills
         ) -> locations

ggplot(locations, aes(MDS1,MDS2))+
  geom_point()+
  #plot points at original coordinates
  geom_segment(aes(x=xjitter,y=yjitter,xend=MDS1,yend=MDS2),alpha=I(0.4))+
  #plot 'leashes' which will connect points to labels
  geom_text(aes(x=xjitter,y=yjitter,label=1:length(Informant.name)))+
  #plot labels at the new exploded or 'jittered' coordinates
  theme_bw()

Or as it turns out I could have done a single google search instead and installed someone else’s package: 5 minutes of my time

require(ggrepel)
#install pre-made package

ggplot(locations, aes(MDS1,MDS2))+
  geom_point()+
  geom_text_repel(aes(label = 1:length(Informant.name))) +
  theme_bw()

#run it

Although! I think mine actually works a little better for this data. They’ve both got issues still.