Search code examples
rggplot2plotlegend

Overlapping legend of a line plot


I want to show each line as having a different color and shape, and that should be reflected on the legend. Basically, it should look something like this My Goal.

I could make the color and point style unique with the following code.

data <- data.frame("1" = c(1, 3, 6, 4), "2" = c(2, 9, 2, 8))
colnames(data) <- paste0("", c(1,2))

power_1 <- factor(c(0,0.25,0.33,"Period"))

density_vs_power <- ggplot(data = as.data.frame(data))


# Loop to add geom_line layers for each column
for (i in 1:2) {
  density_vs_power <- density_vs_power +
    geom_line(aes(x = power_1, y = !!sym(as.character(i)), group = 1, color = as.character(i))) +
    geom_point(shape = i, aes(x = power_1, y = !!sym(as.character(i)), color = as.character(i)))
}

density_vs_power <- density_vs_power +
  scale_y_continuous(trans = "log10") +
  theme_classic()


density_vs_power

However, this does not show a legend, as shown here different color but not legend. I knew that if I put the color attribute into aes(), a legend should appear. When I attempt this with the following code,


data <- data.frame("1" = c(1, 3, 6, 4), "2" = c(2, 9, 2, 8))
colnames(data) <- paste0("", c(1,2))

power_1 <- factor(c(0,0.25,0.33,"Period"))

density_vs_power <- ggplot(data = as.data.frame(data))


# Loop to add geom_line layers for each column
for (i in 1:2) {
  density_vs_power <- density_vs_power +
    geom_line(aes(x = power_1, y = !!sym(as.character(i)), group = 1, color = as.character(i))) +
    geom_point(shape = i, aes(x = power_1, y = !!sym(as.character(i)), color = as.character(i)))
}

density_vs_power <- density_vs_power +
  scale_y_continuous(trans = "log10") +
  theme_classic()


density_vs_power

the legend overlaps, as shown here legend but overlapping features. How can make the legend separate for each line and basically show the format "Object #"?

Any help is much appreciated!


Solution

  • The easiest way to achieve your desired result would be to reshape your data to long or tidy format which also allows to get rid of the for loop:

    library(ggplot2)
    
    data_long <- data |>
      dplyr::mutate(power1 = power_1) |>
      tidyr::pivot_longer(
        -power1,
        names_to = "group"
      )
    
    ggplot(
      data = data_long,
      aes(power1, value, color = factor(group), group = group)
    ) +
      geom_line() +
      geom_point(aes(shape = factor(group))) +
      scale_y_continuous(trans = "log10") +
      theme_classic()