Jelmer Jelmer - 1 month ago 10
R Question

Draw lines between all the coordinates in a plot

I have the following dataframe:

data <- data.frame(x = c(5,1,3,2,5,7,12), y = c(5,7,6,1,3,5,6))


I can plot these coordinates with the ggplot function and draw a line between these coordinates:

ggplot(data, aes(x, y)) + geom_point(size = 3) + geom_line()


So far, no problems. But instead of a single line though the coordinates, I want that a line is drawn between all the coordinates. Creating a sort of spider web between all the coordinates. Is this possible in the
ggplot2
package?

Answer

If you want to do this in ggplot2, then you could use geom_segment for this. But before you can make such a plot, you have to create a dataframe which connencts each observation to the other observations. You could approach it as follows:

library(ggplot2)
library(dplyr)
library(tidyr)
dat %>% 
  complete(nesting(x,y), id) %>%       # create the combinations
  select(id, xend=x, yend=y) %>%       # rename the new variables as end-points
  left_join(dat, ., by = 'id') %>%     # join with the original dataframe
  filter(!(x==xend & y==yend)) %>%     # remove the endpoints that are the same as the start points
  ggplot(., aes(x, y)) + 
  geom_segment(aes(x = x, y = y, xend = xend, yend = yend)) +
  geom_label(aes(x = x, y = y, label = id, color = factor(id)), show.legend = FALSE) +
  theme_minimal(base_size = 14) +
  theme(axis.title = element_blank())

which gives:

enter image description here


Used data:

dat <- data.frame(x = c(5,1,3,2,5,7,12), y = c(5,7,6,1,3,5,6))
dat$id <- 1:nrow(dat)

Alternatively, you can also add the row-id on the fly without doing it beforehand:

dat %>% 
  mutate(id = row_number()) %>%        # add a row id
  complete(nesting(x,y), id) %>%       # create the combinations
  select(id, xend=x, yend=y) %>%       # rename the new variables as end-points
  left_join(dat %>% mutate(id = row_number()), .,
            by = 'id') %>%             # join with the original dataframe (also with an added row id)
  filter(!(x==xend & y==yend)) %>%     # remove the endpoints that are the same as the start points
  ggplot(., aes(x, y)) + 
  geom_segment(aes(x = x, y = y, xend = xend, yend = yend)) +
  geom_label(aes(x = x, y = y, label = id, color = factor(id)), show.legend = FALSE) +
  theme_minimal(base_size = 14) +
  theme(axis.title = element_blank())