library("tidyverse")
library("maps")
library("sf")
library("giscoR")
library("countrycode")
<- gisco_get_countries() %>%
countries_sf as_tibble() %>%
st_as_sf()
# Manually remove duplicate San Jose and Nicosia
<- world.cities %>%
cities_clean as_tibble() %>%
# filter(capital == 1) %>%
filter(!(name == "San Jose" & lat == 10.97),
!(name == "Nicosia" & long == 33.37)) %>%
mutate(iso_3c = countrycode(country.etc, "country.name", "iso3c")) %>%
drop_na() %>%
st_as_sf(coords = c("long", "lat"), crs = 4326)
I really enjoyed seeing other’s #30DayMapChallenge posts, and particularly those of Ansgar Wolsing. I spent a while thinking about this glorious post
And had the idea of creating a map of circles centered around cities with the radius being the shortest distance to another city above a certain population threshold. So let’s throw something together.
First I’ll load my packages, and Ansgar introduced me to {giscoR}
for obtaining shapefiles. Previously, I’ve used {rnaturalearthdata}
but think I might change the default going forwards.
Let’s only look at cities with a population of at least 1 million
<- cities_clean %>%
cities_of_interest filter(pop >= 1000000)
Here’s a neat little function that finds the max and min distance to each row in the data
<- function(data, row_n){
add_max_min_point_to_row <- slice(data, row_n)
target_row
<- slice(data, setdiff(1:nrow(data), row_n))
all_others
<- st_distance(st_as_sfc(target_row), st_as_sfc(all_others))
all_distances
<- slice(all_others, which.min(as.numeric(all_distances))) %>%
min_iso_3c pull(iso_3c)
<- slice(all_others, which.max(as.numeric(all_distances))) %>%
max_iso_3c pull(iso_3c)
%>%
target_row mutate(min_iso_3c = min_iso_3c,
min_distance = min(all_distances),
max_iso_3c = max_iso_3c,
max_distance = max(all_distances))
}
<- 1:nrow(cities_of_interest) %>%
cities_of_interest_distances map_dfr(~add_max_min_point_to_row(cities_of_interest, .x))
And map!
<- ggplot() +
gg_city_circles geom_sf(data = cities_of_interest_distances %>%
mutate(geometry = st_buffer(geometry, dist = min_distance, nQuadSegs = 100)) %>%
st_wrap_dateline() ,
fill = "#663399",
linewidth = 0) +
geom_sf(data = countries_sf %>%
filter(!NAME_ENGL %in% c("Antarctica")) %>%
mutate(area = as.numeric(st_area(geometry))) %>%
filter(area >= 1E11),
fill = "transparent",
colour = colorspace::lighten("lightblue", amount = 0.2)) +
labs(title = "Closest cities with populations of least 1 million") +
coord_sf(crs = "+proj=robin") +
theme_void() +
theme(panel.background = element_rect(fill = "lightblue")) +
NULL
ggsave(quarto_here("gg_city_circles.png"),
gg_city_circles,width = 2 * 4,
height = 2 * 2.37)
Reuse
Citation
BibTeX citation:
@online{hadley2024,
author = {Hadley, Charlie},
title = {Capital {Circles}},
date = {2024-11-30},
url = {https://visibledata.co.uk/posts/2024-11-29_capital-circles/},
langid = {en}
}
For attribution, please cite this work as:
Hadley, Charlie. 2024. “Capital Circles.” November 30,
2024. https://visibledata.co.uk/posts/2024-11-29_capital-circles/.