Using ggplot to plot line segments and points together

Viewed 3003

What I am trying to accomplish: manually add shapes (lines and circles for a soccer pitch, in my actual project) to a scatterplot. This is a scaled-down example of my actual project, but illustrates the issue I need help with.

Here is the data I am using for this example:

data <- data.frame("name" = c("A", "A", "B", "B", "C", "C"),
                     "x" = c(.13, .64, .82, .39, .51, .03),
                     "y" = c(.62, .94, .10, .24, .20, .84))

I will provide example code, first one way that works (tedious, too long), and then one way that I can't figure out (which seems more efficient/concise, and possilbly... faster?).

library(ggplot2)

ggplot(data, aes(x, y)) +
  geom_point() +
  geom_segment(aes(x = 0,xend = 1,y = 1,yend = 1)) +
  geom_segment(aes(x = 0, xend = 1, y=0,yend=0)) +
  geom_segment(aes(x=1, xend=1, y=0, yend=1)) +
  geom_segment(aes(x=0, xend=0, y=0, yend=1))

Example plot of player position on 1x1 soccer pitch

This gets me a nice 1x1 pitch with 6 data points (don't think I can embed the plot, since I don't have enough reputation). Since my actual project has many more data points, and also many more "shapes" (line segments, circles, and circle arcs) that make up the pitch, I thought it would be better to use vectors to define the geom_segment aesthetics - since the full data set plots very slowly. This is what I have:

ggplot(data, aes(x, y)) +
  geom_point() +
  geom_segment(aes(x = c(0,0,1,0),
               xend = c(1,1,1,0),
               y = c(1,0,0,0),
               yend = c(1,0,1,1)))

I get the following error:

Error: Aesthetics must be either length 1 or the same as the data (16): x, y, xend, yend

I have tried changing the layer where I call aes(), using the inherit.aes = FALSE in geom_segment, but it still gives that error. I'm relatively new to R, and very new to SO, so my apologies if I'm using any incorrect terminology or protocol when posting this question.

The issue is that when listing out each of the shapes that make up the pitch individually (an extra layer for every single line segment or circle), and then adding the x, y data as points, it takes forever for the plot to render.

Any help avoiding that error when using vectors to plot the shape layers, or any other creative solutions would be great. My main goal is to make this plot of many shapes and many data points render more quickly (having more elegant code would be a nice bonus as well).

Thank you!

1 Answers

What Axeman is trying to say is, write and extra data frame with your segments and load this into the geom_segment function via the data parameter. If you do so, it doesn't use the standard data provided to the ggplot function but it will use it's own data.

Something like

data <- data.frame("name" = c("A", "A", "B", "B", "C", "C"),
                   "x" = c(.13, .64, .82, .39, .51, .03),
                   "y" = c(.62, .94, .10, .24, .20, .84))

seg_df <- data.frame(x=c(0,0,1,0),
                     y=c(1,0,0,0),
                     xend=c(1,1,1,0),
                     yend=c(1,0,1,1))

ggplot(data, aes(x, y)) +
  geom_point() +
  geom_segment(data=seg_df, aes(x, y, xend=xend, yend=yend))
Related