Overlapping legend of a line plot

38 Views Asked by At

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!

2

There are 2 best solutions below

0
stefan On BEST ANSWER

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()

0
we need a Mat. Stat. On

Is this what you mean?

library(tidyverse)
my_data <- data.frame("One" = c(1, 3, 6, 4), "Two" = c(2, 9, 2, 8), power_1=factor(c(0,0.25,0.33,"Period")))
# avoid using numerical numbers in column names.
# and a data.frame can hold all kinds of data together

# make the data long
my_data <- my_data %>% pivot_longer(cols=c("One", "Two"), names_to = "level", values_to = "value")

#plot it!
ggplot(data = my_data, aes(x=power_1, y=value, group = level, col=level)) + 
  geom_line() +
  geom_point(aes(pch=level)) +
  theme_bw()  # I like the bw theme..