Creating static maps in RStudio

Below is part of a code I am working on, I am trying to map the city_names onto the map but I keep coming across an error about requesting colour from hue palette. I did some research to look for a soultion and one of them being to utilizing as.character for city_names but it still doesn't work.

city_data <- data.frame(island_name=c("Poor Knights", "Stephen", "North Brother", "Hen", "Cuvier", "Mercury", "Plate"))
city_data$lat <- c(-35.450, -40.667, -41.114, -35.965, -36.435, -37, -37.662)
city_data$lon <- c(174.750, 174.0, 174.433, 174.719, 175.770, 175.917, 176.560)

city_data_sf <- st_as_sf(city_data, crs = 4326, coords = c("lon", "lat"))
zealand <- rnaturalearth::ne_states(iso_a2 = 'NZ', returnclass = 'sf')

zealand_joined <- st_join(zealand, city_data_sf)

ggplot() +
geom_sf(data = zealand_joined, aes(fill = as.character (island_name))) +
xlab("Longitude") + ylab("Latitude") +
ggtitle("Islands of New Zeland")

Error in palette():
! Must request at least one colour from a hue palette.

First of all, the polygons aren't that detailed, so the points are outside of them. Maybe get the official polygons from LINZ.

mapview::mapview(list(zealand, city_data_sf))

image

Also note this issue with NZ. ggplot2 - Issue with R script to create a static map of New Zealand - Stack Overflow

**I am trying to re-create a map that was created in the solution of this post How can I color code a region in static map? - #2 by jlacko

You can do that, but with better data. That Natural Earth polygon for NZ isn't very detailed. You want something like NZ Coastlines and Islands Polygons (Topo 1:50k) | LINZ Data Service

The immediate cause of the error in palette

Error in `palette()` :
! Must request at least one colour from a hue palette.

is that the data frame zealand_joined contains no value of column island_name, so that no color gets assigned.

The reason for this is that none of your "cities" - I put that in quotation marks, since they don't really remind me of any NZ city that I know, but than again NZ is about as far from where I live as can be (while staying on the surface of the Earth) - lies on NZ mainland as defined by Natural Earth.

Thus the default spatial join function, which is sf::st_intersects() will return no values, and the column city_name is not present in the zealand_joined object at all.

This can be verified by actually running the st_intersects separately; it will return an empty set.

Two things can be done to remedy this:

  • using a more detailed spatial data, both for your polygons and point coordinates
  • using a different spatial predicate function, one that does not rely on intersection

For the sake of argument I present you with sf::st_nearest_feature() which will color code NZ regions based on the nearest "city" from your list. I don't really think that this is what you had in mind, but it serves nicely to illustrate the broader point.

library(sf) #'simple features' package
library(ggplot2) # general purpose plotting
library(rnaturalearth) # map data


city_data <- data.frame(island_name=c("Poor Knights", "Stephen", "North Brother", "Hen", "Cuvier", "Mercury", "Plate"))
city_data$lat <- c(-35.450, -40.667, -41.114, -35.965, -36.435, -37, -37.662)
city_data$lon <- c(174.750, 174.0, 174.433, 174.719, 175.770, 175.917, 176.560)

city_data_sf <- st_as_sf(city_data, crs = 4326, coords = c("lon", "lat"))
zealand <- rnaturalearth::ne_states(iso_a2 = 'NZ', returnclass = 'sf')

st_intersects(st_union(zealand), city_data_sf)
# Sparse geometry binary predicate list of length 1, where the predicate was `intersects'
#  1: (empty)

zealand_joined <- st_join(zealand, city_data_sf, join = st_nearest_feature)

ggplot() +
  geom_sf(data = zealand_joined, 
          aes(fill = island_name)) +
  xlab("Longitude") + ylab("Latitude") +
  ggtitle("Islands of New Zeland") +
  xlim(166, 179) +
  ylim(-48, -34)

2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.