I have a shapefile from this site that I am working with. I'd like to only plot the a) 30 fathom layer, and b) this layer on latitudes above 34.4. I've been able to subset only the 30 fathom layer, but cannot subset within each region to only include certain latitudes. Below is my current code:
packages <- c('rnaturalearth', 'sf', 'tidyverse', 'ggsignif',
'data.table', 'patchwork', 'ggOceanMaps',
"tools", "dplyr", 'sp', 'readr','mapproj',
'cowplot', 'raster')
installed_packages <- packages %in% rownames(installed.packages())
if (any(installed_packages == FALSE)) {
install.packages(packages[!installed_packages])
}
invisible(lapply(packages, library, character.only = TRUE))
path.RCA <- ("~/Downloads/Rockfish_Conservation_Area_-_R7_-_CDFW_[ds3144]/")
fnam.RCA <- "Rockfish_Conservation_Area_-_R7_-_CDFW_[ds3144].shp"
RCA <- st_read(dsn = path.RCA, layer = file_path_sans_ext(fnam.RCA))
dat.RCA <- fortify(RCA)
fathom_30 <- dat.RCA[dat.RCA$area_name %like% "30-fm", ]
fathom_30 <- fathom_30[fathom_30$area_name %like% "Coastwide", ]
world <- ne_countries(scale = "medium", returnclass = "SF")
socal_map <- ggplot() +
geom_sf(data = world) +
geom_sf(data = fathom_30, size = 1, color = 'lightgreen')+
coord_sf(xlim = c(-117, -121.5), ylim = c(31.75, 36), expand = FALSE)+
scale_x_continuous(breaks = c(seq(from = -121, to = -117, by = 2))) +
scale_y_continuous(breaks = c(seq(from = 32, to = 36, by = 2)))+
theme(legend.position = 'bottom',
strip.background = element_blank(),
legend.title = element_blank(),
strip.text.x = element_text(
size = 12, hjust = 0, face = "bold"),
panel.border = element_rect(color = "red",
fill = NA,
linewidth = 1),
axis.line.y = element_blank(), axis.line.x = element_blank(),
axis.title.x=element_blank(),
axis.title.y=element_blank())
socal_map
Thank you in advance!
As Chris noted in comments, you need to take care of coordinate reference system (CRS). So if you need to crop sf
object by a bounding box or some other sf
object, both must share the same CRS. And to transform from one to another, we use st_transform()
. So you either need to transform your cropping boundaries to EPSG:3857 ((-124.679 34.4)
translates to (-13879203 4082640)
) or transform sf
object to geographic coordinates, WGS84. We'll go with the latter.
Cropping with geographic coordinates can be bit tricky in sf
when s2
is enabled (geometries on a sphere, on by default), so we'll turn it off while manipulating with geometries. One of recent answers that attempts to explain & illustrate this - https://stackoverflow.com/a/78725088/646761
library(sf)
#> Linking to GEOS 3.12.1, GDAL 3.8.4, PROJ 9.3.1; sf_use_s2() is TRUE
library(dplyr)
library(stringr)
library(ggplot2)
world <- rnaturalearth::ne_countries(scale = "medium")
# underlying GDAL library supports virtual file systems and can read
# zipped shapefiles by prefixing file name with `/vsizip/`
rca_shp <- "/vsizip/Rockfish_Conservation_Area_-_R7_-_CDFW_[ds3144].zip"
# check layers and projection / CRS
st_layers(rca_shp)
#> Driver: ESRI Shapefile
#> Available layers:
#> layer_name geometry_type features fields
#> 1 Rockfish_Conservation_Area_-_R7_-_CDFW_[ds3144] Line String 71 5
#> crs_name
#> 1 WGS 84 / Pseudo-Mercator
# load shapefile, transform from pseudo-mercator (EPSG:3857) to
# geographic coordinates (WGS84)
rca_wgs84 <-
read_sf(rca_shp) |>
st_transform("wgs84")
# use bounding box of sf object for a crop area template, update latitude limits
(bbox <- st_bbox(rca_wgs84))
#> xmin ymin xmax ymax
#> -124.67900 32.35717 -117.25733 42.00000
bbox[["ymin"]] <- 34.4
bbox[["ymax"]] <- 36
# to crop with a bounding box and handle geographic coordinates as
# planar coordinates, we'll crop with s2 (geometries on a sphere) disabled;
# filter by area_name, crop by updated bbox
sf_use_s2(use_s2 = FALSE)
#> Spherical geometry (s2) switched off
fathom_30 <-
rca_wgs84 |>
filter(str_detect(area_name, "30-fm.*Coastwide")) |>
st_crop(bbox)
#> although coordinates are longitude/latitude, st_intersection assumes that they
#> are planar
#> Warning: attribute variables are assumed to be spatially constant throughout
#> all geometries
sf_use_s2(use_s2 = TRUE)
#> Spherical geometry (s2) switched on
# after filtering by area_name and cropping into bbox we are left with
# 2 features:
fathom_30
#> Simple feature collection with 2 features and 5 fields
#> Geometry type: LINESTRING
#> Dimension: XY
#> Bounding box: xmin: -121.5683 ymin: 34.4 xmax: -119.9203 ymax: 36
#> Geodetic CRS: WGS 84
#> # A tibble: 2 × 6
#> OBJECTID area_name START_Fath Region Shape__Len geometry
#> * <int> <chr> <int> <chr> <dbl> <LINESTRING [°]>
#> 1 52 30-fm (55-m) … 30 South… 548019. (-120.5052 34.45, -120.4…
#> 2 53 30-fm (55-m) … 30 Centr… 266038. (-121.5683 36, -121.5635…
# to visualize
# mapview::mapview(fathom_30, zcol = "Region")
# plot
ggplot() +
geom_sf(data = world) +
geom_sf(data = fathom_30, linewidth = 1, aes(color = "fathom_30")) +
scale_color_manual(name = "Legend title", values = c(fathom_30 = "lightgreen")) +
coord_sf(xlim = c(-117, -121.5), ylim = c(31.75, 36), expand = FALSE) +
theme_minimal()
Created on 2024-07-23 with reprex v2.1.0