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)