简体   繁体   中英

Plot a small region of a map with ocean in ggplot2

I am trying to plot some parts of Canada using the ggplot2 package. I know that it could be tricky to keep the entire polygons because ggplot is getting rid of the points outside the limits (if you use limits in scale_x/y_continuous() ). To overcome this, it is useful to plot the entire map and then to apply a zoom (coord_map). My polygons are all okay except that ocean is in the same color than Canada/Alaska. However, if I look at the entire map it is white.

A working example :

require(rgdal)
require(ggplot2)
YK <- map_data("world")  ##World

## Regions Canada
library(autoimage)
data(canada)
library(broom)
canada_df <- tidy(canada)


p <- (ggplot() 
      + theme_bw()
      + geom_polygon(data = YK, aes(x=long, y = lat, group = group), fill="gray70")
      + geom_path(data = canada_df, aes(x=long, y=lat, group=group), colour="black"))
p

This gives a correct world map : 世界

Then if I want to zoom at the west part of Canada :

p <- (ggplot() 
      + theme_bw()
      + geom_polygon(data = YK, aes(x=long, y = lat, group = group), fill="gray70")
      + geom_path(data = canada_df, aes(x=long, y=lat, group=group), colour="black")
      + coord_map("mercator", xlim=c(-150, -120), ylim=c(50, 70)))
p

This gives :

1

Regions are correct but the Pacific ocean should be in white in the left side... So I tried with the other way :

p <- (ggplot() 
      + theme_bw()
      + geom_polygon(data = YK, aes(x=long, y = lat, group = group), fill="gray70")
      + geom_path(data = canada_df, aes(x=long, y=lat, group=group), colour="black")
      + scale_x_continuous(limits = c(-150, -120))
      + scale_y_continuous(limits = c(50, 70)))
p

Which gives :

2

The ocean is in white but as excepted, the polygons are cropped...

Is there a way to have this zoom with the entire polygons and the ocean in white ? Because like this, it is as if everything was the continent...

Thank you !

There is a new package, which makes plotting oceans in ggplot easier . The package should be available on CRAN soon. At the moment of writing, you need to install the package from GitHub:

devtools::install_github("MikkoVihtakari/ggOceanMapsData") # required by ggOceanMaps
devtools::install_github("MikkoVihtakari/ggOceanMaps")

At the moment of writing, the installation might require updating R because one of the dependencies requires sf >= 0.9 . Once the package is installed, making maps is simple as:

library(ggOceanMaps)
#> Loading required package: ggplot2
#> Loading required package: ggspatial
#> Loading required package: ggOceanMapsData
basemap(limits = c(-150, -120, 50, 70), rotate = TRUE)

You might want to play around with the limits, but this gives an idea. If you want the state borders, just plot them using the original sp shapefiles and + layer_spatial(data = YK, fill = NA, color = "black")

Created on 2020-04-27 by the reprex package (v0.3.0)

EDIT 2021-02-22: The package is now available on CRAN.

As @Phil mentioned, something is not going right with the YK layer when you ask ggplot to plot the subregion in Canada. I do not have time to dissect this issue. But, I am guessing that, when you ask ggplot to subset the YK data, the order of data points for polygons are probably changing. Unless you have reasons to subset polygon data from world map, I would do the following. I downloaded a polygon data from GAMD with the raster package and converted it to data frame. When I drew the map, I used geom_cartogram() , which is similar to geom_map() . As you specified long/lat, I used scale_x/y_continuous() to draw a subregion on Canada. Sorry for not being able to dissect the cause behind your problem. But, I hope this map will let you get going.

EDIT

I investigated what is going on with your second case. I accessed to the data frame behind your graphic and my graphic using ggplot_build() . The first block is showing the data frame behind your graphic with scale_x/y_continuous() . I am showing a part of the data. As you see, y values are not in order. You can see that there are NA in the middle of Y values.

             x         y map_id PANEL group colour fill size linetype alpha
9593         NA 50.13589   187     1     NA gray70  0.5        1    NA
9594         NA 50.15318   187     1     NA gray70  0.5        1    NA
9595         NA 50.13906   187     1     NA gray70  0.5        1    NA
9596         NA 50.09707   187     1     NA gray70  0.5        1    NA
9597         NA 50.04688   187     1     NA gray70  0.5        1    NA
9598         NA 50.00244   187     1     NA gray70  0.5        1    NA
9599         NA       NA   187     1     NA gray70  0.5        1    NA
9600         NA       NA   187     1     NA gray70  0.5        1    NA
9601         NA       NA   187     1     NA gray70  0.5        1    NA
9602         NA       NA   187     1     NA gray70  0.5        1    NA
9603         NA       NA   187     1     NA gray70  0.5        1    NA
9604         NA 50.00000   187     1     NA gray70  0.5        1    NA
9605         NA 50.02388   187     1     NA gray70  0.5        1    NA
9606         NA 50.05283   187     1     NA gray70  0.5        1    NA
9607         NA 50.09414   187     1     NA gray70  0.5        1    NA
9608         NA 50.12988   187     1     NA gray70  0.5        1    NA
9609         NA 50.14380   187     1     NA gray70  0.5        1    NA

This block is showing a part of the data behind my plot. As you can see y values are in order. As far as I checked the data, I did not see NAs staying in the middle of y values.

I am still not sure what is causing this difference. Yet, it is clear that something went wrong with your YK data when you drew the second Canadian map.

                x        y map_id PANEL group colour   fill size linetype alpha

770            NA 53.62133      1     1     1  black gray70  0.3        1    NA
771            NA 53.62124      1     1     1  black gray70  0.3        1    NA
772            NA 53.62115      1     1     1  black gray70  0.3        1    NA
773            NA 53.62107      1     1     1  black gray70  0.3        1    NA
774            NA 53.62097      1     1     1  black gray70  0.3        1    NA
775            NA 53.62088      1     1     1  black gray70  0.3        1    NA
776            NA 53.62083      1     1     1  black gray70  0.3        1    NA
777            NA 53.62079      1     1     1  black gray70  0.3        1    NA
778            NA 53.62070      1     1     1  black gray70  0.3        1    NA
779            NA 53.62061      1     1     1  black gray70  0.3        1    NA

CODE

library(raster)
library(tidyverse)
library(ggalt)
library(ggthemes)

canada <- getData("GADM", country = "canada", level = 1)
foo <- fortify(canada)

g <- ggplot() +
     geom_cartogram(data = foo, aes(x = long, y = lat, map_id = id), map = foo,
                    fill = "gray70", color = "black", size = 0.3) + 
     scale_x_continuous(limits = c(-150, -120)) +
     scale_y_continuous(limits = c(50, 70)) +
     theme_map()

在此处输入图片说明

As stated in the comment, Chika wanted to have Alaska in a map. So here it is.

canada <- getData("GADM", country = "canada", level = 1)
usa <- getData("GADM", country = "usa", level = 1)
alaska <- subset(usa, NAME_1 == "Alaska")

ca <- fortify(canada)
al <- fortify(alaska)

g <- ggplot() +
     geom_cartogram(data = al, aes(x = long, y = lat, map_id = id), map = al) +
     geom_cartogram(data = ca, aes(x = long, y = lat, map_id = id), map = ca) +
     scale_x_continuous(limits = c(-170, -120)) +
     scale_y_continuous(limits = c(50, 70))

在此处输入图片说明

Seems the problem is with coord_map . If using coord_cartesian or coord_fixed the zoom in is ok. And coord_quickmap works too.

p <- ggplot() +
      theme_bw() +
      geom_polygon(data = YK, aes(x=long, y = lat, group = group), fill="gray70") +
      geom_path(data = canada_df, aes(x=long, y=lat, group=group), colour="black")
p

p + coord_cartesian(xlim=c(-150, -120), ylim=c(50, 70))

p + coord_fixed(ratio = 2, xlim=c(-150, -120), ylim=c(50, 70))


p + coord_quickmap(xlim=c(-150, -120), ylim=c(50, 70))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM