4

I want to draw the outline of multiple US states in R using longitude and latitude points. Now I can only draw the outline of each states, so I want to know the way to draw the outline of multiple US states(only the outer line).

library(tidyverse)
library(knitr)    
library(broom)
library(stringr)
library(modelr)
library(forcats)
library(ggmap)


states <- map_data("state")# %>% as_tibble()
counties <- map_data("county")
il_df <- filter(fifty_states, id == "illinois")
midwest <- subset(fifty_states, id %in% c("illinois", "indiana", "iowa",
                                    "kansas", "michigan", "minnesota",
                                    "missouri", "nebraska", "north dakota",
                                    "ohio", "south dakota", "wisconsin"))


il_mid <- ggplot(data = midwest, mapping = aes(x = long, y = lat, group = group)) + 
  coord_fixed(1.3) + 
  geom_polygon(color = "black", fill = "gray")
il_mid

enter image description here

I want to know how to draw the pink line in below image.

enter image description here

Z.Lin
  • 28,055
  • 6
  • 54
  • 94
MMM
  • 425
  • 1
  • 7
  • 24

2 Answers2

5

Here's an approach using the sf package and the convenient geom_sf in the development version of ggplot2. I get the map data from the nice fiftystater package that provides Alaska and Hawaii as insets, but it requires conversion to sf format. I use an answer from here to do this.

Then the rest is simple, we just filter to the right states, union them together with summarise.sf, and then use geom_sf to plot the result.

library(tidyverse)
library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.2.3, proj.4 4.9.3
library(fiftystater)

sf_fifty <- sf::st_as_sf(fifty_states, coords = c("long", "lat")) %>% 
  group_by(id, piece) %>% 
  summarize(do_union = FALSE) %>%
  st_cast("POLYGON") %>% 
  ungroup()

midwest <- sf_fifty %>%
  filter(
    id %in% c(
      "illinois", "indiana", "iowa",
      "kansas", "michigan", "minnesota",
      "missouri", "nebraska", "north dakota",
      "ohio", "south dakota", "wisconsin"
    )
  ) %>%
  summarise(id = "midwest")

ggplot() +
  theme_minimal() +
  geom_sf(data = sf_fifty) +
  geom_sf(data = midwest, col = "hotpink", alpha = 0, size = 2)

Created on 2018-05-24 by the reprex package (v0.2.0).

Calum You
  • 14,687
  • 4
  • 23
  • 42
1

Here's a quick & dirty method that works for your example, assuming you want to outline all outer edges:

ggplot(data = midwest, mapping = aes(x = long, y = lat, group = group)) + 
  coord_fixed(1.3) + 
  geom_polygon(color = "hotpink", size = 5) + # or some other arbitrarily large number
  geom_polygon(color = "black", fill = "gray")

The additional geom_polygon layer has pink outline for every polygon, but only the edges not covered by the original layer are visible.

plot

Note that this won't work for more complicated cases (e.g. you wish to plot all US states, but show outline for Northeast / Midwest / South / West states). In that case, you'll probably need to merge the data frame to an appropriate spatial object and merge the underlying polygons, e.g. using rgeos::gUnion as per @r2evans' suggestion.

Z.Lin
  • 28,055
  • 6
  • 54
  • 94
  • Thank you! Actually I want to plot all US states but show outline for some multiple states with outlines, So I may need to use `rgeos::gUnion`. – MMM May 24 '18 at 16:21