11

I'm using ggplot to map data values to a (fortified) SpatialPolygonsDataFrame, but many of the polygons have NA values because there is no data available.

I used na.value = "white" to display the missing data correctly, but I'd like to add a box with a white fill in the legend (or a separate legend) with the label "no data".

library(ggplot2)

india.df <- read.csv('india.df.csv') 
# (I don't know how to provide this file to make the code reproducible)

ggplot() +
geom_polygon(data=india.df, aes(x = long, y = lat, group = group, fill=Area_pct)) +
scale_fill_gradient(low="orange2", high="darkblue", na.value = "white") +
geom_path(data=india.df, aes_string(x = x, y = y, group = group), color = "gray", size = 0.25) +
theme_bw() +
coord_map() +
labs(title = "Rice Under Irrigation in Gujarat - 2001", 
     fill = "Area (%)")

(I have a great image to illustrate this but don't have enough reputation points to post it)

I've read this, but my data is continuous (not discrete), and this, but I can't figure out how to adapt the 'line' change to 'fill'.

Thanks for the help!!

Community
  • 1
  • 1
Hilary
  • 151
  • 2
  • 6
  • 2
    Found https://github.com/hadley/ggplot2/issues/410 seems like we are stuck with workarounds... – animalito Apr 28 '15 at 01:03
  • 1
    It's more likely that we will be able to help you if you make a minimal reproducible example to go along with your question. Something we can work from and use to show you how it might be possible to solve your problem. You can have a look at [this SO post](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) on how to make a great reproducible example in R. – Eric Fail Nov 22 '15 at 16:45

3 Answers3

3

You could make use of the behavior of ggplot which creates a legend when specifying certain aesthetics within aes()
I am creating some dummy data and am using geom_map instead of geom_polygon, which I find easier. You can then use override.aes to specify the fill of the legend key with the NA value. You can then easily rename the legend etc.

library(tidyverse)

worldData <- map_data('world') %>% fortify()
india.df <- data.frame(region = 'India', Area_pct = 2, stringsAsFactors = FALSE) %>% right_join(worldData, by = 'region')

na.value.forplot <- 'white'

ggplot() +
  geom_map(data = india.df, map = india.df, aes(x = long, y = lat, fill = Area_pct, map_id = region, color = 'NA')) +
  scale_fill_gradient(low="orange2", high="darkblue", na.value = na.value.forplot) +
  scale_color_manual(values = 'black', labels = 'Missing value') +
  guides(color = guide_legend(override.aes = list(fill = na.value.forplot)))
#> Warning: Ignoring unknown aesthetics: x, y

Created on 2019-07-18 by the reprex package (v0.3.0)

tjebo
  • 21,977
  • 7
  • 58
  • 94
  • I like your reply, but failed reproducing it when changing the countries' outline colors, by adding ```colour="darkgrey"``` to ```geom_map()```. Your example ```geom_map(data = india.df, map = india.df, aes(x = long, y = lat, fill = Area_pct, map_id = region, color = 'NA'))``` work, but ```geom_map(data = india.df, map = india.df, colour="darkgrey", aes(x = long, y = lat, fill = Area_pct, map_id = region, color = 'NA'))``` does not. How to combine both options? – MsGISRocker Jul 30 '20 at 15:49
  • @MrGISRocker possibly worth a follow up question. Please also don't forget to link to this question. Cheers. – tjebo Jul 30 '20 at 17:30
0

you can replace your NAs with 0 using

data[is.na(data)] <- 0

that way your nas will be replaced by zero and yout legend will show "0s"

And to show us the image you can have a blog and can paste the link here

R Vij
  • 80
  • 1
  • 11
  • 2
    This doesn't deal with the situation that the OP describes, in which "no data" is not the same as "data was collected for this area on the map but there were 0 cases" - should it not be a feature request for ggplot2 to have an option to show NAs, choose how to label them, colour them and include them in the legend? – Amy M Jan 06 '17 at 19:50
-3

Try this:

ggplot(all your info) + geom_point(na.rm = TRUE) + geom_line(na.rm = TRUE)
dbc
  • 104,963
  • 20
  • 228
  • 340
Cass
  • 1