Home > Net >  Separate legend by facet for geom_segment and geom_point
Separate legend by facet for geom_segment and geom_point

Time:12-07

I am interested in creating a figure akin to the below, which has a separate legend entry for each of four components: two geom_segment and two geom_point, which are grouped according to some facet (corresponding to the color).

figure

Here is a sample dataset, and some initial code.

x <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
y <- c(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
z <- c(3, 6, 9, 12, 15, 18, 21, 24, 27, 30)
s <- c(5, 5, 5, 5, 5, 5, 5, 5, 5, 5)
t <- c(10, 10, 10, 10, 10, 10, 10, 10, 10, 10)
n <- c("A", "A", "A", "A", "A", "A", "A", "A", "A", "A",
       "B", "B", "B", "B", "B", "B", "B", "B", "B", "B")
df <- cbind(rbind(data.frame(x = x, y = y, s = s), data.frame(x = x, y = z, s = t)), n)

ggplot(data = df, mapping = aes(x = x, y = y, color = n))  
  geom_point()  
  scale_color_manual(values = c("blue", "gray64"))  
  geom_segment(mapping = aes(x = 0, xend = 10, y = 10, yend = 10), color = "blue", inherit.aes = FALSE)  
  geom_segment(mapping = aes(x = 0, xend = 10, y = 20, yend = 20), color = "gray64", inherit.aes = FALSE)

CodePudding user response:

Give this a shot:

library(ggplot2)

ggplot()   
    geom_point(data = dplyr::filter(df, n == "A"), mapping = aes(x = x, y = y, shape = "Label A.1"), color = "gray")   
    geom_point(data = dplyr::filter(df, n == "B"), mapping = aes(x = x, y = y, shape = "Label B.1"), color = "blue")   
    geom_line(data = dplyr::filter(df, n == "A"), mapping = aes(x = x, y = s, color = "Label A.2"))   
    geom_line(data = dplyr::filter(df, n == "B"), mapping = aes(x = x, y = s, color = "Label B.2"))   
    scale_shape_manual(name = NULL, values = c(19, 19))   
    scale_color_manual(name = NULL, values = c("Label A.2" = "gray", "Label B.2" = "blue"))   
    guides(shape = guide_legend(override.aes = list(color = c("Label A.1" = "gray", "Label B.1" = "blue"))))

ggplot2 doesn't seem to like separating legends (I suppose it does make the plot more complicated). In this solution, we add each layer separately, controlling the legend using shape (which we later set to 19, the default filled-in circle) and color aesthetics. In the last line, we make sure the colors of the shape layer are correct (try the code without the last line to see what it does!).

I also don't think "facet" is used correctly in your question. Generally, facets are like subplots.

CodePudding user response:

Hey I think this might be able to help

# load the necessary libraries
library(ggplot2)
library(dplyr

# create the base plot
p <- ggplot(data, aes(x, y))  
     facet_wrap(~group, scales = "free")

# add the geoms with different legend entries
p <- p   geom_segment(aes(xend = x   1, yend = y   1),
                      color = "red", size = 1,
                      show.legend = TRUE,
                      inherit.aes = FALSE,
                      name = "Segment 1")
p <- p   geom_segment(aes(xend = x   2, yend = y   2),
                      color = "blue", size = 1,
                      show.legend = TRUE,
                      inherit.aes = FALSE,
                      name = "Segment 2")
p <- p   geom_point(aes(color = color), size = 3,
                    show.legend = TRUE,
                    shape = 21, fill = "white")

# specify the legend entries
p <- p   guides(color = guide_legend(override.aes = list(size = 3)))

# print the plot
print(p)
  • Related