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?
segment() function in R Language is used to draw a line segment between to particular points.
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:
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())
Using base
plotting:
plot(data)
sapply(combn(nrow(data), 2L, simplify = FALSE),
function(x) do.call("segments", as.list(c(t(data[x, ])))))
Add bells and whistles to taste.
You may also use the FUN
argument in combn
:
plot(data)
combn(nrow(data), 2L, simplify = FALSE, FUN = function(cm){
segments(x0 = data[cm[1L], 1L],
y0 = data[cm[1L], 2L],
x1 = data[cm[2L], 1L],
y1 = data[cm[2L], 2L])
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With