0

I am creating a choropleth map for CO2 emissions in Europe using ggplot2 and ggmap in R. The fill colour for each country corresponds to its CO2 emissions. The colours and continuous legend are implemented with scale_fill_gradient. However, I would also like for a single country to have a colour that is not from the continuous legend (for later use in a Shiny application). I have not worked out how to have scale_fill_gradient only apply to one of multiple geom_polygon layers.

Here is my initial map:

Initial map

To reproduce this map, download the map data from http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/50m/cultural/ne_50m_admin_0_countries.zip

Here is the code:

library(maptools)
library(ggplot2)
library(ggmap)

# read in a world map
WorldMap <- readShapePoly(fn="ne_50m_admin_0_countries/ne_50m_admin_0_countries")

# reduce shape file to a filtered data frame
WorldMapDf <- fortify(WorldMap,region='iso_a2')

# read in CO2 emissions
GEO <- c('FR','AT','BE','DE','DK','FI','GB','IE','NL','NO','SE')
CO2 <- c(59.5,86.9,137.4,425.8,303.9,353.2,380.3,427.0,476.4,1.8,47.6)
CO2_df <- data.frame(GEO,CO2)

# the range of values that the colour scale should cover
colorbar_range <- range(CO2_df$CO2)
mean_price <- mean(colorbar_range)

# merge map polygons with electricity CO2 emissions
CO2Map <- merge(WorldMapDf, CO2_df, by.x="id", by.y="GEO", all.x = T)
CO2Map <- CO2Map[order(CO2Map$order),]

#limit data to main Europe
europe.limits <- data.frame(matrix(c(35.50,-11.43,70,31.11),nrow=2,ncol=2,byrow = T))
names(europe.limits) <- c('lat','long')
CO2MapSubset <- subset(CO2Map, long > min(europe.limits$lon) & long < max(europe.limits$lon) & lat > min(europe.limits$lat) & lat < max(europe.limits$lat))

# create x and y limits
xrange <- c(min(CO2MapSubset$long),max(CO2MapSubset$long))
yrange <- c(min(CO2MapSubset$lat),max(CO2MapSubset$lat))

initial_map <- ggplot(data=CO2MapSubset) + # data layer
  geom_polygon(aes(x=long, y=lat, group=group, fill=CO2)) +
  coord_map(projection = "mercator",xlim=xrange,ylim=yrange) +
  scale_fill_gradient2(low='gold',mid = "white",high='firebrick2',na.value = "lightgrey",midpoint=mean_price,limits=colorbar_range, name='CO2 (g/kWh)') +
  geom_path(aes(x=long, y=lat, group=group), color='black',size=0.2)

# display map
initial_map

Now, I would like to make one country a different colour (for example, blue) that is not on the continuous colour scale as shown in the legend.

I thought I could do this by adding an additional geom_polygon layer to the initial map. To make Denmark blue, I tried this:

map_with_selected_country <- initial_map +
  geom_polygon(data = CO2MapSubset[CO2MapSubset$id == 'DK',], aes(x=long, y=lat, group=group, fill='blue'))

but I get the error message: 'Error: Discrete value supplied to continuous scale' because the fill 'blue' conflicts with scale_fill_gradient2. Is there a way to make scale_fill_gradient2 only point to one dataset? Or is there another way to tackle this problem?

fifthace
  • 506
  • 1
  • 10
  • 33
  • 1
    Usually, it's advisable to provide [*minimal* reproducible examples](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example#answer-5963610). I think there's some ballast here that could be dropped. You would of course have to abstract from your specific problem then... To your question: Have your tried putting ` fill='blue'` outside of the `aes` mapping? I.e. `geom_polygon(data = CO2MapSubset[CO2MapSubset$id == 'DK',], aes(x=long, y=lat, group=group), fill='blue')`? "blue" is a discrete value, a string, which is provided for a continous fill scale (1,2,3...) .. – lukeA Dec 07 '16 at 13:50
  • Thanks. This worked great. I guess I could have removed all of my comments, the libraries used and the map limits. I will next time. – fifthace Dec 07 '16 at 14:09

1 Answers1

3

Here's an example:

library(ggplot2)
map <- map_data("world")
map$value <- setNames(sample(1:50, 252, T), unique(map$region))[map$region]
p <- ggplot(map, aes(long, lat, group=group, fill=value)) + 
  geom_polygon() + 
  coord_quickmap(xlim = c(-50,50), ylim=c(25,75))
p + geom_polygon(data = subset(map, region=="Germany"), fill = "red")

Germany is overplotted using a red fill color:

enter image description here

You can adapt this example to fit your needs.

lukeA
  • 53,097
  • 5
  • 97
  • 100