Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using ggplot to plot line segments and points together

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!

like image 753
ForceLeft415 Avatar asked Aug 29 '18 05:08

ForceLeft415


People also ask

How do I connect dots in ggplot2?

Connecting Paired Points with lines using geom_line() In ggplot2 we can add lines connecting two data points using geom_line() function and specifying which data points to connect inside aes() using group argument. Now we get a scatter plot connecting paired data with lines.

What does Geom_segment do in R?

geom_segment() draws a straight line between points (x, y) and (xend, yend). geom_curve() draws a curved line. See the underlying drawing function grid::curveGrob() for the parameters that control the curve.

What is Geom_line in Ggplot?

geom_line() connects them in order of the variable on the x axis. geom_step() creates a stairstep plot, highlighting exactly when changes occur. The group aesthetic determines which cases are connected together.

Which argument of Ggplot can be used to add customization to plots?

To customize the plot, the following arguments can be used: alpha, color, linetype, shape, size and fill. Learn more here: ggplot2 box plot.


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))
like image 111
drmariod Avatar answered Sep 21 '22 19:09

drmariod