Helen K.
Helen K.

Reputation: 69

ggplot2 legend: combine discrete colors and continuous point size

There are similar posts to this, namely here and here, but they address instances where both point color and size are continuous. Is it possible to:

  1. Combine discrete colors and continuous point size within a single legend?
  2. Within that same legend, add a description to each point in place of the numerical break label?

Toy data

xval = as.numeric(c("2.2", "3.7","1.3"))
yval = as.numeric(c("0.3", "0.3", "0.2"))
color.group = c("blue", "red", "blue")
point.size = as.numeric(c("200", "11", "100"))
description = c("descript1", "descript2", "descript3")

df = data.frame(xval, yval, color.group, point.size, description)

ggplot(df, aes(x=xval, y=yval, size=point.size)) + 
  geom_point(color = df$color.group) +
  scale_size_continuous(limits=c(0, 200), breaks=seq(0, 200, by=50))

Upvotes: 1

Views: 1762

Answers (1)

Julius Vainora
Julius Vainora

Reputation: 48211

Doing what you originally asked - continuous + discrete in a single legend - in general doesn't seem to be possible even conceptually. The only sensible thing would be to have two legends for size, with a different color for each legend.


Now let's consider having a single legend. Given your "In my case, each unique combination of point size + color is associated with a description.", it sounds like there are very few possible point sizes. In that case, you could use both scales as discrete. But I believe even that is not enough as you use different variables for size and color scales. A solution then would be to create a single factor variable with all possible combinations of color.group and point.size. In particular,

df <- data.frame(xval, yval, f = interaction(color.group, point.size), description)
ggplot(df, aes(x = xval, y = yval, size = f, color = f)) + 
  geom_point() + scale_color_discrete(labels = 1:3) +
  scale_size_discrete(labels = 1:3)

enter image description here

Here 1:3 are those descriptions that you want, and you may also set the colors the way you like. For instance,

ggplot(df, aes(x = xval, y = yval, size = f, color = f)) + 
  geom_point() + scale_size_discrete(labels = 1:3) +
  scale_color_manual(labels = 1:3, values = c("red", "blue", "green"))

enter image description here

However, we may also exploit color.group by using

ggplot(df, aes(x = xval, y = yval, size = f, color = f)) + 
  geom_point() + scale_size_discrete(labels = 1:3) +
  scale_color_manual(labels = 1:3, values = gsub("(.*)\\..*", "\\1", sort(df$f)))

enter image description here

Upvotes: 1

Related Questions