MMM
MMM

Reputation: 435

how to add boundaries of specific(selected) US state map in r?

I have created US map using scale. I want to add boundaries of state to emphasize the figures(color) such as IL, NH, MI, NY, ND.

How I can draw the boundaries of states using my dataset?

My map_wc looks like below (it is shorted) and every state has figures in x.

> map_wc
                        id       long      lat order  hole piece                  group            x
1                  alabama  -85.05670 32.01738   142 FALSE     1              Alabama.1 0.0024057739
2                  alabama  -85.07007 31.98070   143 FALSE     1              Alabama.1 0.0024057739
3                  alabama  -85.04619 32.09090   139 FALSE     1              Alabama.1 0.0024057739
4                  alabama  -85.05666 32.06964   140 FALSE     1              Alabama.1 0.0024057739
5                  alabama  -86.18148 30.99523    28 FALSE     1              Alabama.1 0.0024057739


library(ggplot2)
library(fiftystater)
p <- ggplot(map_wc, aes(map_id =id)) + 
  # map points to the fifty_states shape data
  geom_map(aes(fill = x), map = fifty_states) + 
  expand_limits(x = fifty_states$long, y = fifty_states$lat) +
  coord_map() +
  scale_fill_gradient(low="white", high="red", name="Proportion")+
  scale_x_continuous(breaks = NULL) + 
  scale_y_continuous(breaks = NULL) +
  labs(x = "", y = "") +
  theme(legend.position = "bottom")+
    theme(panel.background = element_rect(fill = 'skyblue')) +    
    theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank()) +
    theme(axis.title.x=element_blank(),
          axis.text.x=element_blank(),
          axis.ticks.x=element_blank(),
          axis.title.y=element_blank(),
          axis.text.y=element_blank(),
          axis.ticks.y=element_blank())

enter image description here

Thank!

Upvotes: 0

Views: 1572

Answers (2)

sebdalgarno
sebdalgarno

Reputation: 3195

Although I don't have your map_wc dataset I can recreate what you want from the fifty_states dataset. Here is one approach:

First, you create a variable that passes a border color to the states you want outlined

library(ggplot2)
library(fiftystater)
fifty_states <- fiftystater::fifty_states

fifty_states$border <- ifelse(fifty_states$id %in% c('illinois', 'new york'), 'white', NA)

Now you plot the using aes(colour = border) (or whatever you name your new variable) and scale_color_identity(), which means that ggplot will assign the colour of the variable border (in this case, 'white')

p <- ggplot(fifty_states, aes(map_id = id)) + 
  # map points to the fifty_states shape data
  geom_map(map = fifty_states, aes(color = border)) +
  scale_color_identity() +
  expand_limits(x = fifty_states$long, y = fifty_states$lat) +
  coord_map() +
  scale_fill_gradient(low="white", high="red", name="Proportion")+
  scale_x_continuous(breaks = NULL) + 
  scale_y_continuous(breaks = NULL) +
  labs(x = "", y = "") +
  theme(legend.position = "bottom")+
  theme(panel.background = element_rect(fill = 'skyblue')) +    
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank()) +
  theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank(),
        axis.title.y=element_blank(),
        axis.text.y=element_blank(),
        axis.ticks.y=element_blank())

enter image description here

Note that Mikey Harper's approach is probably better for mapping a single colour. However, if there is a case for you to want different states to have more than one colour of border then you will have to have these as a variable, e.g.

fifty_states$border <- ifelse(fifty_states$id %in% c('illinois', 'new york'), 'white', 'orange')

Upvotes: 1

Mikey Harper
Mikey Harper

Reputation: 15419

Rather than adding a column as suggested by sebdalgamo, I prefer the approach of subsetting the main dataset and adding another layer to the plot, as follows:

ggplot(fifty_states, aes(map_id = id)) + 
  geom_map(map = fifty_states) +
  geom_map(map = subset(fifty_states, id %in% c('illinois', 'new york')),
           fill = NA, colour = "pink") +
  scale_color_identity() +
  expand_limits(x = fifty_states$long, y = fifty_states$lat) +
  coord_map() +
  scale_fill_gradient(low="white", high="red", name="Proportion")+
  scale_x_continuous(breaks = NULL) + 
  scale_y_continuous(breaks = NULL) +
  labs(x = "", y = "") +
  theme(legend.position = "bottom")+
  theme(panel.background = element_rect(fill = 'skyblue'))

enter image description here

This tends to be better practise, as rather than hard-coding the colour in, we can change as many attributes as we want without having to make a new column. For example, the following code changes the fill, size of the outline and transparency:

 geom_map(map = subset(fifty_states, id %in% c('illinois', 'new york')),
           fill = "yellow", colour = "pink", size = 2, alpha = 0.2) +

enter image description here

Upvotes: 2

Related Questions