nateroe
nateroe

Reputation: 547

ggplot2 legend with outline on every other grouping

I am making a scatterplot using . I have 17 groups that need to be displayed though, and I am trying to find ways of making that many colors distinguishable from each other. How could I put a black outline on every other grouping so that the black outline shows both in the scatterplot and in the legend.

Here is a reproducible example of having too many colors to visualize. I would like 'Group 1', 'Group 11', 'Group 13', etc. to have a black outline around them so that they are distinguishable from their neighbors.

groupings <- paste0("Group", 1:15)
iris$group <- rep(groupings, 10)

iris_plot <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + geom_point(aes(Sepal.Length, Sepal.Width, colour = factor(iris$group)))

shrink_legend <- function(NMDS, pointSize, textSize, spaceLegend){
  NMDS +
        guides(shape = guide_legend(override.aes = list(size = pointSize)),
               color = guide_legend(override.aes = list(size = pointSize))) +
        theme(legend.title = element_text(size = textSize), 
              legend.text  = element_text(size = textSize),
              legend.key.size = unit(spaceLegend, "lines"))
}

shrink_legend(iris_plot, pointSize = 1.2, textSize = 10, spaceLegend = 0.5)

Thank you for your help!

Upvotes: 2

Views: 721

Answers (2)

stefan
stefan

Reputation: 125832

Try this. First I change the shape of the points to points with borders. Second. To achieve the wanted plot I set the border colors for uneven groups to black, while using default ggplot2 colors for even ones. Colors are set using scale_color_manual. As a result the outline shows up in the plot as well as in the legend.

library(ggplot2)
library(forcats)
library(scales)

# Helper to make it easy to set colors
iris$group1 <- rep(1:15, 10)
iris$group <- paste0("Group", iris$group1)
# Order Groups
iris$group <- forcats::fct_reorder(iris$group, iris$group1)
# Default ggplot2 colors
colors <- scales::hue_pal()(15)
# Set color to "black" for uneven groups
colors[seq(1, 15, by = 2)] <- "black"

iris_plot <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + 
  # Change shape to 21 = point with outline
  geom_point(aes(Sepal.Length, Sepal.Width, fill = group, color = group), shape = 21) +
  # Set colors
  scale_color_manual(values = colors)

shrink_legend <- function(NMDS, pointSize, textSize, spaceLegend){
  NMDS +
    guides(shape = guide_legend(override.aes = list(size = pointSize)),
            color = guide_legend(override.aes = list(size = pointSize))) +
    theme(legend.title = element_text(size = textSize), 
          legend.text  = element_text(size = textSize),
          legend.key.size = unit(spaceLegend, "lines"))
}

shrink_legend(iris_plot, pointSize = 1.2, textSize = 10, spaceLegend = 0.5)

Created on 2020-04-12 by the reprex package (v0.3.0)

Upvotes: 2

salexir
salexir

Reputation: 46

I think the default shape for geom_point does not support a fill and a outline/border (colour). If you use shapes 21-24, you would be able to add in two values to fill and colour. I've used shape 21 in this e.g.

I've added a border column to identify which one would be given a border. Of course, that would mean you would have two legend entries (see pic.)

groupings <- paste0("Group", 1:15)
iris$group <- rep(groupings, 10)
iris$border <- c(T,F)


iris_plot <-  ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, fill = factor(iris$group))) + 
    geom_point(aes(Sepal.Length, Sepal.Width, fill = group, colour = border), shape = 21, size = 3)+ scale_colour_manual(values=c("grey", "black"))

shrink_legend <- function(NMDS, pointSize, textSize, spaceLegend){
  NMDS +
    guides(shape = guide_legend(override.aes = list(size = pointSize)),
           color = guide_legend(override.aes = list(size = pointSize))) +
    theme(legend.title = element_text(size = textSize), 
          legend.text  = element_text(size = textSize),
          legend.key.size = unit(spaceLegend, "lines"))
}

shrink_legend(iris_plot, pointSize = 1.2, textSize = 10, spaceLegend = 0.5)

Plot output

Upvotes: 2

Related Questions