如何在R中制作亚马逊森林砍伐年度动态交互式地图?
问题描述
我正在使用R语言的brazilmaps包可视化亚马逊地区受森林砍伐影响的区域,已经完成了亚马逊流域附近受砍伐影响最严重的巴西各州的静态可视化,但想要追踪1988年至2021年这些区域的森林砍伐演变情况,不知道如何制作能以颜色突出森林砍伐影响的动态交互式地图。
已完成的代码:
library(sf) library(patchwork) library(animation) library(ggplot2) library(tidyverse) library(brazilmaps) AmazoniaStates <- AmazoniaDeforestation %>% dplyr::select(-"Total") States_Map <- get_brmap(geo = "State", geo.filter = list(State = c(12, 13, 16, 21, 51, 15, 11, 14, 17)), class = "sf") AmazoniaStateDeforestation <- plot_brmap(States_Map, data_to_join = AmazoniaStates, join_by = character(), theme = theme_map()) AmazoniaStates <- AmazoniaStates %>% pivot_longer(cols = !Year, names_to = "State", values_to = "Area")
数据dput输出:
dput(AmazoniaDeforestation) structure(list(Year = c(1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021), `Acre ` = c(620, 540, 550, 380, 400, 482, 482, 1208, 433, 358, 536, 441, 547, 419, 883, 1078, 728, 592, 398, 184, 254, 167, 259, 280, 305, 221, 309, 264, 372, 257, 444, 682, 706, 889), Amazonas = c(1510, 1180, 520, 980, 799, 370, 370, 2114, 1023, 589, 670, 720, 612, 634, 885, 1558, 1232, 775, 788, 610, 604, 405, 595, 502, 523, 583, 500, 712, 1129, 1001, 1045, 1434, 1512, 2306), Amapa = c(60, 130, 250, 410, 36, 0, 0, 9, 0, 18, 30, 0, 0, 7, 0, 25, 46, 33, 30, 39, 100, 70, 53, 66, 27, 23, 31, 25, 17, 24, 24, 32, 24, 17), `Maranhao ` = c(2450, 1420, 1100, 670, 1135, 372, 372, 1745, 1061, 409, 1012, 1230, 1065, 958, 1085, 993, 755, 922, 674, 631, 1271, 828, 712, 396, 269, 403, 257, 209, 258, 265, 253, 237, 336, 350), `Mato Grosso` = c(5140, 5960, 4020, 2840, 4674, 6220, 6220, 10391, 6543, 5271, 6466, 6963, 6369, 7703, 7892, 10405, 11814, 7145, 4333, 2678, 3258, 1049, 871, 1120, 757, 1139, 1075, 1601, 1489, 1561, 1490, 1702, 1779, 2213), Para = c(6990, 5750, 4890, 3780, 3787, 4284, 4284, 7845, 6135, 4139, 5829, 5111, 6671, 5237, 7510, 7145, 8870, 5899, 5659, 5526, 5607, 4281, 3770, 3008, 1741, 2346, 1887, 2153, 2992, 2433, 2744, 4172, 4899, 5238), `Rondonia ` = c(2340, 1430, 1670, 1110, 2265, 2595, 2595, 4730, 2432, 1986, 2041, 2358, 2465, 2673, 3099, 3597, 3858, 3244, 2049, 1611, 1136, 482, 435, 865, 773, 932, 684, 1030, 1376, 1243, 1316, 1257, 1273, 1673), `Roraima ` = c(290, 630, 150, 420, 281, 240, 240, 220, 214, 184, 223, 220, 253, 345, 84, 439, 311, 133, 231, 309, 574, 121, 256, 141, 124, 170, 219, 156, 202, 132, 195, 590, 297, 315), `Tocantins ` = c(1650, 730, 580, 440, 409, 333, 333, 797, 320, 273, 576, 216, 244, 189, 212, 156, 158, 271, 124, 63, 107, 61, 49, 40, 52, 74, 50, 57, 58, 31, 25, 23, 25, 37), Total = c(21050, 17770, 13730, 11030, 13786, 14896, 14896, 29059, 18161, 13227, 17383, 17259, 18226, 18165, 21651, 25396, 27772, 19014, 14286, 11651, 12911, 7464, 7000, 6418, 4571, 5891, 5012, 6207, 7893, 6947, 7536, 10129, 10851, 13038)), row.names = c(NA, -34L), class = "data.frame")
解决方案
首先要解决州名对齐问题:你的数据中部分州名带有末尾空格(比如Acre 、Maranhao ),而States_Map里的州名是标准格式,需要先统一:
# 清理数据中的州名空格 AmazoniaStates <- AmazoniaStates %>% mutate(State = str_trim(State)) # 给地图数据添加标准州名(匹配你的数据) States_Map <- States_Map %>% mutate(State = case_when( State == "12" ~ "Acre", State == "13" ~ "Amazonas", State == "16" ~ "Amapa", State == "21" ~ "Maranhao", State == "51" ~ "Mato Grosso", State == "15" ~ "Para", State == "11" ~ "Rondonia", State == "14" ~ "Roraima", State == "17" ~ "Tocantins" )) # 合并地图和数据 map_data <- left_join(States_Map, AmazoniaStates, by = "State")
方法1:用gganimate制作动态地图(本地播放/导出)
gganimate可以生成逐帧切换的动态地图,适合展示年度演变:
library(gganimate) # 绘制基础静态图 p <- ggplot() + geom_sf(data = map_data, aes(fill = Area), color = "white", size = 0.3) + scale_fill_viridis_c(name = "砍伐面积", option = "magma") + theme_minimal() + theme( axis.text = element_blank(), axis.title = element_blank(), panel.grid = element_blank(), plot.title = element_text(size = 16, hjust = 0.5) ) + # 添加年度标题 labs(title = "亚马逊各州森林砍伐面积: {frame_time}年") + # 设置动画参数:按Year切换,过渡平滑 transition_time(Year) + ease_aes("linear") # 播放动画 animate(p, fps = 3, duration = 15, width = 800, height = 600) # 导出为GIF anim_save("亚马逊森林砍伐动态图.gif", p, fps = 3, duration = 15, width = 800, height = 600)
方法2:用plotly制作交互式地图(可手动切换年份)
plotly生成的交互式地图支持点击、缩放,还能通过下拉菜单切换年份:
library(plotly) # 为每个年份创建单独的地图图层 plot_data <- map_data %>% group_split(Year) # 生成交互式地图 fig <- plot_ly() # 添加所有年份的图层 for (yr in unique(map_data$Year)) { fig <- fig %>% add_sf( data = filter(map_data, Year == yr), split = ~State, color = ~Area, colors = "magma", name = as.character(yr), visible = ifelse(yr == 1988, TRUE, FALSE) # 默认显示第一年 ) } # 添加下拉菜单控件 fig <- fig %>% layout( title = "亚马逊各州森林砍伐面积(1988-2021)", updatemenus = list( list( buttons = lapply(unique(map_data$Year), function(yr) { list( method = "restyle", args = list("visible", unique(map_data$Year) == yr), label = as.character(yr) ) }), direction = "down", showactive = TRUE, x = 0.1, y = 1.15 ) ), coloraxis = list(colorbar = list(title = "砍伐面积")) ) # 显示交互式地图 fig
关键说明
- 州名匹配是核心:必须确保地图数据和砍伐数据的州名完全一致,否则无法正确关联
- 颜色选择:用
viridis色系(scale_fill_viridis_c)能更清晰展示数值差异,避免视觉偏差 - 动画参数调整:
gganimate的fps和duration可以控制播放速度,plotly的下拉菜单支持自由切换年份
内容的提问来源于stack exchange,提问作者ArtUr693
相关产品推荐
相关产品推荐

