1

I have been working on plotting several lines according to different probability levels and am stuck adding labels to each line to represent the probability level.

Since each curve plotted has varying x and y coordinates, I cannot simply have a large data-frame on which to perform usual ggplot2 functions.

The end goal is to have each line with a label next to it according to the p-level.

What I have tried:

To access the data comfortably, I have created a list df with for example 5 elements, each element containing a nx2 data frame with column 1 the x-coordinates and column 2 the y-coordinates. To plot each curve, I create a for loop where at each iteration (i in 1:5) I extract the x and y coordinates from the list and add the p-level line to the plot by:

plot = plot + 
    geom_line(data=df[[i]],aes(x=x.coor, y=y.coor),color = vector_of_colors[i])

where vector_of_colors contains varying colors.

I have looked at using ggrepel and its geom_label_repel() or geom_text_repel() functions, but being unfamiliar with ggplot2 I could not get it to work. Below is a simplification of my code so that it may be reproducible. I could not include an image of the actual curves I am trying to add labels to since I do not have 10 reputation.


# CREATION OF DATA
plevel0.5 = cbind(c(0,1),c(0,1))
colnames(plevel0.5) = c("x","y")

plevel0.8 = cbind(c(0.5,3),c(0.5,1.5))
colnames(plevel0.8) = c("x","y")

data = list(data1 = line1,data2 = line2)

# CREATION OF PLOT
plot = ggplot() 

for (i in 1:2) {
  plot = plot + geom_line(data=data[[i]],mapping=aes(x=x,y=y))
}

Thank you in advance and let me know what needs to be clarified.


EDIT :

I have now attempted the following :

Using bind_rows(), I have created a single dataframe with columns x.coor and y.coor as well as a column called "groups" detailing the p-level of each coordinate.

This is what I have tried:

plot = ggplot(data) +
      geom_line(aes(coors.x,coors.y,group=groups,color=groups)) + 
      geom_text_repel(aes(label=groups))

But it gives me the following error:

geom_text_repel requires the following missing aesthetics: x and y

I do not know how to specify x and y in the correct way since I thought it did this automatically. Any tips?

1 Answers1

0

You approach is probably a bit to complicated. As far as I get it you could of course go on with one dataset and use the group aesthetic to get the same result you are trying to achieve with your for loop and multiple geom_line. To this end I use dplyr:.bind_rows to bind your datasets together. Whether ggrepel is needed depends on your real dataset. In my code below I simply use geom_text to add an label at the rightmost point of each line:

plevel0.5 <- data.frame(x = c(0, 1), y = c(0, 1))
plevel0.8 <- data.frame(x = c(0.5, 3), y = c(0.5, 1.5))

library(dplyr)
library(ggplot2)

data <- list(data1 = plevel0.5, data2 = plevel0.8) |>
  bind_rows(.id = "id")

ggplot(data, aes(x = x, y = y, group = id)) +
  geom_line(aes(color = id)) +
  geom_text(data = ~ group_by(.x, id) |> filter(x %in% max(x)), aes(label = id), vjust = -.5, hjust = .5)

stefan
  • 90,330
  • 6
  • 25
  • 51
  • Thanks for your answer! Perhaps I am indeed better off just creating a dataframe for the whole data. – Marco Froelich Apr 05 '22 at 22:13
  • I posted an edit: I have encountered further troubles. Could you help me out? – Marco Froelich Apr 05 '22 at 23:08
  • Hi Marco. The issue is that you set the x and y coords as local aesthetics only in geom_line. Simply move them to ggplot() to make them global as I did in my example code. – stefan Apr 06 '22 at 05:57
  • This is a short notation for writing functions. You will find that all over the tidyverse. `~ group_by(.x, id) |> filter(x %in% max(x))` is the same as `function(x) group_by(x, id) |> filter(x %in% max(x))`. But when using the `~` we have to use the special `.x` (or just a `.`). – stefan Apr 06 '22 at 18:32