Reputation: 547
I am making a scatterplot using ggplot2. 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
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
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)
Upvotes: 2