
În această postare pe blog, vom folosi date din pachetul {GapMinder} R, împreună cu limitele spațiale globale de la „OpendataSoft”. Vom complota speranța de viață a fiecărei țări din America și o vom anima pentru a vedea schimbările din 1957 până în 2007.
Pachetul {GapMinder} pe care îl folosim este de la Fundația GapMinder, o educație independentă non-profit de concepții greșite globale. Probleme de acoperire precum încălzirea globală, plasticul în oceane și satisfacția vieții.
Mai întâi vom încărca setul de date complet din pachetul GapMinder și vom vedea ce este conținut în acesta.
data("gapminder_unfiltered", package = "gapminder")
names(gapminder_unfiltered)
## (1) "country" "continent" "year" "lifeExp" "pop" "gdpPercap"
Apoi vom filtra setul de date pentru a menține datele speranței de viață pentru anii 1952 până în 2007 (în pași de 5 ani).
O formă de formă (*.shp) conținând limitele geografice ale fiecărei țări poate fi importat folosind {sf} Pachet R.
library(sf)
library(dplyr)
if (getwd() == "/home/osheen/corporate-website"){
world = st_read("content/blog/2025-animated-map/data/world-administrative-boundaries.shp") |>
select(-"continent")
} else {
world = st_read("data/world-administrative-boundaries.shp") |>
select(-"continent")
}
## Reading layer `world-administrative-boundaries' from data source
## `/home/osheen/corporate-website/content/blog/2025-animated-map/data/world-administrative-boundaries.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 256 features and 8 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -180 ymin: -58.49861 xmax: 180 ymax: 83.6236
## Geodetic CRS: WGS 84
head(world)
## Simple feature collection with 6 features and 7 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -58.43861 ymin: -34.94382 xmax: 148.8519 ymax: 51.09111
## Geodetic CRS: WGS 84
## iso3 status color_code name
## 1 MNP US Territory USA Northern Mariana Islands
## 2 Sovereignty unsettled RUS Kuril Islands
## 3 FRA Member State FRA France
## 4 SRB Member State SRB Serbia
## 5 URY Member State URY Uruguay
## 6 GUM US Non-Self-Governing Territory GUM Guam
## region iso_3166_1_ french_shor
## 1 Micronesia MP Northern Mariana Islands
## 2 Eastern Asia Kuril Islands
## 3 Western Europe FR France
## 4 Southern Europe RS Serbie
## 5 South America UY Uruguay
## 6 Micronesia GU Guam
## geometry
## 1 MULTIPOLYGON (((145.6333 14...
## 2 MULTIPOLYGON (((146.6827 43...
## 3 MULTIPOLYGON (((9.4475 42.6...
## 4 MULTIPOLYGON (((20.26102 46...
## 5 MULTIPOLYGON (((-53.3743 -3...
## 6 MULTIPOLYGON (((144.7094 13...
Unul dintre lucrurile frumoase despre {sf} Pachetul este că stochează date geografice într-o structură specializată de cadru de date care ne permite să îmbinăm datele noastre de graniță cu statisticile GapMinder folosind aceleași funcții pe care le-am folosi pentru a combina cadre de date mai tipice. Aici ne alăturăm celor două seturi de date, potrivind intrările după numele țării, folosind dPlyr left_join funcţie.
joined = left_join(gapminder_unfiltered,
world,
by = c("country" = "name")) |>
st_as_sf()
head(joined)
## Simple feature collection with 6 features and 12 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 60.50417 ymin: 29.40611 xmax: 74.91574 ymax: 38.47198
## Geodetic CRS: WGS 84
## # A tibble: 6 × 13
## country continent year lifeExp pop gdpPercap iso3 status color_code
##
## 1 Afghanistan Asia 1952 28.8 8425333 779. AFG Membe… AFG
## 2 Afghanistan Asia 1957 30.3 9240934 821. AFG Membe… AFG
## 3 Afghanistan Asia 1962 32.0 10267083 853. AFG Membe… AFG
## 4 Afghanistan Asia 1967 34.0 11537966 836. AFG Membe… AFG
## 5 Afghanistan Asia 1972 36.1 13079460 740. AFG Membe… AFG
## 6 Afghanistan Asia 1977 38.4 14880372 786. AFG Membe… AFG
## # ℹ 4 more variables: region , iso_3166_1_ , french_shor ,
## # geometry
Voi selecta coloana țării și o voi complota care utilizează baza r
plot Funcție pentru o vizualizare rapidă.
joined |>
select("country") |>
plot()


Hmmmmmmm care nu arată destul de corect?
Problema de aici este una obișnuită atunci când apucați un fișier de granițe spațiale de pe Internet. Seturile de date care sunt alăturate au nume diferite pentru unele dintre țări. De exemplu, în world date pe care le avem SUA ca „Statele Unite”, unde ca în gapminder Este „Statele Unite ale Americii”. dplyr::anti_join Funcția poate fi utilă pentru a găsi țări care nu se potrivesc. Voi folosi fct_recode de la {forcats} pentru a alinia world
nume de țară cu gapminder. În exemplul de mai jos, doar remediez SUA, dar puteți vedea din complotul de mai sus că alte câteva țări trebuie să fie recodificate (19 în total), fac acest lucru în spatele scenei pentru a evita blocarea paginii.
library(forcats) world = world |> mutate(name = fct_recode(.data$name, "United States" = "United States of America"))
Bine, să vedem cum arată acest lucru acum.
joined |>
select("country") |>
plot()


E mai bine! Acum am datele pe care vreau să le complotez, pot folosi GGPLOT2 pentru a începe să creez vizualizarea pe care o voi anima. Înainte de asta, voi filtra datele pentru a păstra doar America, apoi voi folosi
geom_sf pentru a complota datele de geometrie.
library(ggplot2) americas = joined |> filter(continent == "Americas") americas_plot = ggplot(americas) + geom_sf()


Acest complot arată bine, dar voi schimba sistemul de referință de coordonate (CRS) la unul („EPSG: 8858”) care este conceput pentru America. Am găsit acest CRS pe epsg.io, un site web pe care l -aș recomanda dacă sunteți în căutarea unor CRS diferite. st_transform
Poate fi utilizat pentru a schimba CRS în EPSG: 8858. Așa arată acum:
americas = st_transform(americas, "EPSG:8858") new_crs_plot = ggplot(americas) + geom_sf()


Bine, așa că acum complotul arată corect, vom începe să -l pregătim pentru a fi animat.
library(ggplot2)
plot = americas %>%
filter(year == 2007) %>%
ggplot() +
geom_sf(aes(fill = lifeExp)) +
labs(title = "Year: 2007",
fill = "Life Expectancy") +
theme_void() +
ggplot2::scale_fill_viridis_b() +
theme(legend.position = c("inside"),
legend.position.inside = c(0.23, 0.23),
plot.title = element_text(size = 15,
hjust = 0.5),
panel.border = element_rect(color = "black",
fill = NA))


Acesta este complotul pe care îl vom anima acum, așa că vom folosi {gganimate}. transition_states Funcția partifică datele folosind un states
Coloana (aici coloana noastră „Anul”), creând iterativ un cadru al animației pentru fiecare an în datele de intrare. Următoarea funcție este
animate care va converti aceste cadre într -un GIF. Rețineți, asigurați -vă că aveți dependențele instalate sau puteți ajunge la 100 de fișiere PNG în directorul dvs. de lucru, mai degrabă decât cu un GIF!
library(gganimate)
animation = plot +
ggtitle("Year: {closest_state}") +
transition_states(states = year)
animate(animation,
renderer = gifski_renderer("img/map.gif"),
alt = "Animation with missing values.")


Ochiul cu atenție al dvs. va observa că unele țări nu au o valoare pentru fiecare an.
americas |> st_drop_geometry() |> count(country) |> arrange(n) ## # A tibble: 36 × 2 ## country n #### 1 French Guiana 1 ## 2 Guadeloupe 1 ## 3 Martinique 1 ## 4 Aruba 8 ## 5 Grenada 8 ## 6 Netherlands Antilles 8 ## 7 Suriname 8 ## 8 Bahamas 10 ## 9 Barbados 10 ## 10 Belize 10 ## # ℹ 26 more rows
Deci, 25 de țări au 12 observații (max), patru au 10 și 8, respectiv, iar trei au 1. Pentru a completa aceste semifabricate, voi folosi {Tidyr} pentru a calcula unele valori batjocoritoare folosind media setului de date pentru fiecare an. Țările cu una vor continua cu o valoare din 2002.
library(tidyr)
completed = americas |>
mutate(country = forcats::fct_drop(country)) |>
complete(year, country) |>
select(country, lifeExp, year) |>
group_by(year) |>
mutate(lifeExp =
replace_na(lifeExp,
replace = mean(lifeExp,
na.rm = TRUE)))
geoms = americas |>
select(country) |>
distinct()
plot = left_join(completed,
geoms,
by = "country") |>
st_as_sf() |>
st_transform("EPSG:8858") |>
ggplot() +
geom_sf(aes(fill = lifeExp)) +
labs(title = "Year: {closest_state}",
fill = "Life Expectancy") +
theme_void() +
ggplot2::scale_fill_viridis_b() +
theme(legend.position = c("inside"),
legend.position.inside = c(0.23, 0.23),
plot.title = element_text(size = 15,
hjust = 0.5),
panel.border = element_rect(color = "black",
fill = NA))
animation = plot +
transition_states(states = year)
animate(animation,
renderer = gifski_renderer("img/map2.gif"))


Așadar, aceasta este harta noastră animată finală, desigur am putea adăuga mai mult stil sau complexitate – poate într -un viitor blog. Dacă doriți să aflați mai multe despre lucrul subiectului, consultați analiza noastră de date spațiale cu curs R sau un alt blog Jumping Rivers, Gândindu -mă la hărți și înghețată
de Nicola Rennie.
Pentru actualizări și revizii la acest articol, consultați postarea originală
