JellisHeRo JellisHeRo - 1 month ago 7
R Question

R: Is there a way to add unused data levels in a ggplot legend?

I am trying to present a map using ggplot on a factor-type vector going from 0 to 4 that I color coded. The vector is in the dataframe I named

spat.dataframe
and the vector is
qt
.

enter image description here

# plot
ggplot(spat.dataframe, aes(long,lat,group=group)) + # the data
geom_polygon(aes(fill=as.factor(qt))) + # make polygons
scale_fill_manual(values = c("0"="#F0F0F0","1"="green","2"="red","3"="blue","4"="purple"),
labels = c(paste0("white (",length(spat.dataframe[spat.dataframe$qt==0,]),")"),
paste0("green (",length(spat.dataframe[spat.dataframe$qt==1,]),")"),
paste0("red (",length(spat.dataframe[spat.dataframe$qt==2,]),")"),
paste0("blue (",length(spat.dataframe[spat.dataframe$qt==3,]),")"),
paste0("pink (",length(spat.dataframe[spat.dataframe$qt==4,]),")")),
drop=F,
name=NULL) +
theme(line = element_blank(), # remove the background, tickmarks, etc
axis.text = element_blank(),
axis.title = element_blank(),
panel.background = element_blank()) +
ggtitle(title) +
geom_path( colour = "#6b6b6b", size = .5 ) +
coord_equal()


My problem lies with the legend portion, because what I want to do is display all of the legend options even if there arent any listed in the vector. So the values with colors blue and purple as well. It may seem like a bit of a stretch to try but I want it on my figure so that I can also display the number of values possible and the number of polygons associated with that value. So, for the values 3 and 4 in my vector
qt
, both are zero (i.e.,
blue (0)
and
purple (0)
).

Any suggestions would be greatly appreciated. Thanks.

Answer

Here's a working example with mtcars, taken from the ggplot2 documentation here. Namely, use scale_color_manual with the limits argument instead:

cols <- c("8" = "red","4" = "blue","6" = "darkgreen", "10" = "orange")
plot <- ggplot(mtcars, aes(x = mpg, y = wt, colour = factor(cyl))) + geom_point()
plot + scale_color_manual(values = cols,
                          limits = c("4", "6", "8", "10"),
                          labels = c("this", "is", "my", "test"))

enter image description here

That should be enough for you to adapt it to your problem. It's hard for me be sure this will work without having your actual data set, but here is a solution that should work:

cols= c("0"="#F0F0F0","1"="green","2"="red","3"="blue","4"="purple")

ggplot(spat.dataframe, aes(long,lat,group=group)) + # the data
  geom_polygon(aes(fill=as.factor(qt))) + # make polygons
  scale_color_manual(limits = c("0", "1", "2", "3", "4")
                     values = cols,
                     labels = c(paste0("white (",length(spat.dataframe[spat.dataframe$qt==0,]),")"),
                                paste0("green (",length(spat.dataframe[spat.dataframe$qt==1,]),")"),
                                paste0("red (",length(spat.dataframe[spat.dataframe$qt==2,]),")"),
                                paste0("blue (",length(spat.dataframe[spat.dataframe$qt==3,]),")"),
                                paste0("pink (",length(spat.dataframe[spat.dataframe$qt==4,]),")")),
                     drop=F,
                     name=NULL) +
  theme(line = element_blank(),  # remove the background, tickmarks, etc
    axis.text = element_blank(),
    axis.title = element_blank(),
    panel.background = element_blank()) +
  ggtitle(title) + 
  geom_path( colour = "#6b6b6b", size = .5 ) +
  coord_equal()