使用gganimate和ggplot2时出现意外错误

问题描述 投票:0回答:1

我希望对多年来绘制在世界地图(来自 rnaturalearth)上的价值观地图进行动画处理。我已经下载了 rnaturalearth 数据并将其与我的数据集连接起来(三个变量:将其与 rnaturalearth 数据连接的国家/地区代码之一、每个国家/地区的值之一以及年份的值)。我可以正常连接这两个数据集:

baseBorderMap <- 
  ne_countries(returnclass = 'sf') # Returns world country polygons as sf class
baseBorderMap["51", "iso_a2_eh"] <- "NM" # Renames Namibia country code
baseBorderMap["175", "iso_a2_eh"] <- "XK" # Renames Kosovo country code
aniData <- baseBorderMap %>% right_join(countryYearMam, by = "iso_a2_eh") # Adds counts to map data (maybe something to do with fill needing data with borders?)
aniData <- filter(aniData, !is.na(specimens)) # Remove records with no specimens

我可以使用普通的 ggplot2 函数绘制地图,忽略年份数据:

mammalYear <- ggplot(data = aniData) + # Plots map
  geom_sf(data = aniData, lwd = 0) +
  geom_sf(data = aniData, aes(fill = log(specimens)), lwd = 0.3) + # Sets fill colour based on specimens from mydata2
  #ggtitle("(b)") +
  scale_fill_viridis_c() +
  theme_bw() +
  theme(legend.title = element_blank())

将 gganimate 函数添加到图中并尝试将其可视化或使用

animate()
函数后,我收到错误。

timelapse_mammalYear <- mammalYear +
  transition_states(year,
                    transition_length = 2,
                    state_length = 1) +
  enter_fade() +
  exit_fade()

> timelapse_mammalYear
Error in vapply(from, nrow, integer(1)) : values must be length 1,
 but FUN(X[[8]]) result is length 0
In addition: Warning message:
In max(area_diff) : no non-missing arguments to max; returning -Inf

此错误是什么意思,如何修改我的数据以正确使用这些函数,以便为我的地图制作动画?

第二次编辑:任何列中都没有 NA。

>dput(head(countryYearMam, 5))
structure(list(iso_a2_eh = c("AD", "AD", "AD", "AD", "AD"), year = c(1930L, 
1950L, 1962L, 1965L, 1968L), specimens = c(1L, 12L, 24L, 14L, 
3L)), row.names = c(NA, 5L), class = "data.frame")

年份:最小值 = 1793,最大值 = 2020 样本:最小值 = 1,最大值 = 2601

r gganimate
1个回答
0
投票

我无法重现您的问题,但潜在原因包括:

  • 您的 countryYearMam 数据存在问题
  • 您的软件包版本/R 环境
  • gganimate
  • 的错误

如果没有您的完整数据集,我无法保证这会解决您的具体问题。但是,这里有一个对您的方法进行了一些改进的代表,“应该”适用于您的实际数据。它使用包含 29,259 行的示例 countryYearMam 数据集。需要考虑的一些要点:

您创建的
    ne_countries()
  1. 对象不包含数据中存在的所有管理区域,例如安道尔,所以使用更详细的版本
    在您的 
  2. ggplot()
  3. 中,您调用 aniData 两次,但只有其中一次应用了
    aes()
    。这是不必要的开销,因此使用
    baseBorderMap
    来代替。
  4. gganimate
  5. 存在
    已知错误。我不能确定您是否遇到了错误,但是 
    ne_countries()
    过去曾引发过问题
    
    
加载包并生成数据:

library(rnaturalearth) # 1.0.1 library(dplyr) # 1.1.4 library(sf) # 1.0.15 library(gganimate) # 1.0.8 with ggplot2 3.5.0 # Create world map sf: note addition of scale argument baseBorderMap <- ne_countries(scale = 50, returnclass = 'sf') %>% st_set_crs(NA) # Correct ISO2 country codes: note substitution of iso_a2_eh column baseBorderMap[which(baseBorderMap$sovereignt == "Namibia"), "iso_a2"] <- "NM" baseBorderMap[which(baseBorderMap$sovereignt == "Kosovo"), "iso_a2"] <- "XK" # Simplify geometries for faster plotting baseBorderMap <- baseBorderMap %>% st_simplify(preserveTopology = FALSE, dTolerance = .001) # Create example countryYearMam df countryYearMam <- data.frame(matrix(NA, nrow = 0, ncol = 3)) colnames(countryYearMam) <- c("iso_a2", "year", "specimens") set.seed(1) for(i in sort(baseBorderMap$iso_a2)) { j <- sample(30:227, 1) k <- rep(i, j) m <- sort(sample(1793:2020, j)) n <- sample(1:2601, j) tmp <- data.frame(iso_a2 = k, year = m, specimens = n) countryYearMam <- rbind(countryYearMam, tmp) }

将 sf 数据加入到 

countryYearMam: # Join countryYearMam to map sf and filter NAs aniData <- baseBorderMap %>% right_join(countryYearMam, by = "iso_a2") %>% filter(!is.na(specimens)) %>% # included for completeness, no NAs were generated in sample df above select(continent, iso_a2, year, specimens)

生成情节:

mammalYear <- ggplot() + geom_sf(data = baseBorderMap, colour = "grey75") + geom_sf(data = aniData, aes(fill = log(specimens)), lwd = 0.3) + scale_fill_viridis_c() + theme_bw() + theme(legend.title = element_blank()) timelapse_mammalYear <- mammalYear + transition_states(year, transition_length = 2, state_length = 1) + labs(title = "Year: {closest_state}") + # For illustrative purposes enter_fade() + exit_fade()

生成 .gif:

注意此 animate() 脚本在相对低规格的 PC 上运行大约需要 53 分钟

anim <- animate(timelapse_mammalYear, 
        renderer = gifski_renderer(), 
        height = 5,
        width = 8, 
        units = "cm",
        fps = 1, 
        duration = 228, 
        end_pause = 2, 
        res = 100)

anim

© www.soinside.com 2019 - 2024. All rights reserved.