geom_sf 使用 coord_sf 指定 xlim、ylim 时填充失败。尝试使用 av 包创建动画时寻找解决方法
geom_sf fill fails when xlim, ylim are specified using coord_sf. Looking for a workaround when trying to create an animation using the av package
ggplot2
存在一个已知问题,在使用 coord_sf
指定 xlim
和 ylim
时,geom_sf
函数并不总是正常工作。这个问题似乎是 Windows 特有的,当前的解决方法是将绘图保存为 .png。 See GitHub link: geom_sf fill missing when xlim,ylim set in coord_sf
我遇到的问题是我不是要制作静态图,而是要使用 av
包将数百个图拼接在一起的动画。
基本上,我正在寻求帮助来实施合适的解决方法,并且不需要保存或调用单个 .png 文件。
如有任何想法或建议,我们将不胜感激。
下图显示了我解决这个问题的动机,绘制了飓风随时间变化的轨迹。
Whosebug 不允许对视频进行 post 编辑,因此如果您想查看我的可重现代码的输出,您可以在此处查看我的原始 GitHub post可以在这里找到... geom_sf, fill missing when xlim, ylim set in coord_sf in windows (follow-up to #3283) #4306
library(tidyverse)
library(sf)
library(av)
tracts <- read_sf("https://opendata.arcgis.com/datasets/230f9d23f6874be983901876cd600c4e_0.geojson") %>%
select(
geometry,
ALAND10,
GEOID10
)
st_crs(tracts)
set.seed(264)
v1 <- runif(1:dim(tracts)[1], .7, 1.25)
tracts2 <- cbind(tracts, v1)
tracts_2017 <- tracts2 %>%
mutate(season=2017)
tracts_2018 <- tracts2 %>%
mutate(
season=2018,
ALAND10 = ALAND10*v1
)
tracts3 <- rbind(tracts_2017, tracts_2018)
st_crs(tracts3)
makeplot1 <- function(){
datalist1 <- split(
tracts3,
tracts3$season
)
datalist2 <- split(
tracts3,
tracts3$season
)
mapply(function(data1, data2){
p1 <- ggplot() +
geom_sf(
data = data1,
aes(fill = ALAND10)
) +
geom_sf(
data = data2 %>% st_union(),
fill = alpha("red", 0.4),
color = alpha("red", 0.4)
) +
coord_sf(
ylim = c( 43.04, 43.07),
xlim = c(-76.14,-76.10),
clip = "on",
expand = F
)
print(p1)
},
datalist1, datalist2
)
}
makeplot2 <- function(){
datalist1 <- split(
tracts3,
tracts3$season
)
datalist2 <- split(
tracts3,
tracts3$season
)
mapply(function(data1, data2){
p2 <- ggplot() +
geom_sf(
data = data1,
aes(fill = ALAND10)
) +
geom_sf(
data = data2 %>% st_union(),
fill = alpha("red", 0.4),
color = alpha("red", 0.4)
)
print(p2)
},
datalist1, datalist2
)
}
video_file1 <- file.path(tempdir(), 'Tracts1.mp4')
av::av_capture_graphics(makeplot1(), video_file1, vfilter='framerate=fps=10')
av::av_media_info(video_file1)
utils::browseURL(video_file1)
video_file2 <- file.path(tempdir(), 'Tracts2.mp4')
av::av_capture_graphics(makeplot2(), video_file2, vfilter='framerate=fps=10')
av::av_media_info(video_file2)
utils::browseURL(video_file2)
正如 Thomas Lin Pedersen 在您链接的 github 问题中所建议的那样,解决方案是在 Windows 机器上使用 png(..., type = 'cairo')
设备。如果您阅读 ?av::av_capture_graphics()
上的文档,您会发现 ...
参数可用于将参数传递给 png()
函数。因此,我建议完全这样做:
library(tidyverse)
library(sf)
library(av)
tracts <- read_sf("https://opendata.arcgis.com/datasets/230f9d23f6874be983901876cd600c4e_0.geojson") %>%
select(
geometry,
ALAND10,
GEOID10
)
st_crs(tracts)
set.seed(264)
v1 <- runif(1:dim(tracts)[1], .7, 1.25)
tracts2 <- cbind(tracts, v1)
tracts_2017 <- tracts2 %>%
mutate(season=2017)
tracts_2018 <- tracts2 %>%
mutate(
season=2018,
ALAND10 = ALAND10*v1
)
tracts3 <- rbind(tracts_2017, tracts_2018)
st_crs(tracts3)
makeplot1 <- function(){
datalist1 <- split(
tracts3,
tracts3$season
)
datalist2 <- split(
tracts3,
tracts3$season
)
mapply(function(data1, data2){
p1 <- ggplot() +
geom_sf(
data = data1,
aes(fill = ALAND10)
) +
geom_sf(
data = data2 %>% st_union(),
fill = alpha("red", 0.4),
color = alpha("red", 0.4)
) +
coord_sf(
ylim = c( 43.04, 43.07),
xlim = c(-76.14,-76.10),
clip = "on",
expand = F
)
print(p1)
},
datalist1, datalist2
)
}
video_file1 <- file.path(tempdir(), 'Tracts1.mp4')
av::av_capture_graphics(makeplot1(), video_file1,
vfilter='framerate=fps=10',
type = "cairo")
av::av_media_info(video_file1)
utils::browseURL(video_file1)
此外,
the current work around involves saving the plot as a .png.
正是av::av_capture_graphics()
在幕后所做的,也是gganimate
包所做的。
最后,我建议您对色标设置固定限制,因为这似乎在帧之间发生变化,使任何解释都变得复杂。 gganimate
包优雅地说明了这些细节。
ggplot2
存在一个已知问题,在使用 coord_sf
指定 xlim
和 ylim
时,geom_sf
函数并不总是正常工作。这个问题似乎是 Windows 特有的,当前的解决方法是将绘图保存为 .png。 See GitHub link: geom_sf fill missing when xlim,ylim set in coord_sf
我遇到的问题是我不是要制作静态图,而是要使用 av
包将数百个图拼接在一起的动画。
基本上,我正在寻求帮助来实施合适的解决方法,并且不需要保存或调用单个 .png 文件。
如有任何想法或建议,我们将不胜感激。
下图显示了我解决这个问题的动机,绘制了飓风随时间变化的轨迹。
Whosebug 不允许对视频进行 post 编辑,因此如果您想查看我的可重现代码的输出,您可以在此处查看我的原始 GitHub post可以在这里找到... geom_sf, fill missing when xlim, ylim set in coord_sf in windows (follow-up to #3283) #4306
library(tidyverse)
library(sf)
library(av)
tracts <- read_sf("https://opendata.arcgis.com/datasets/230f9d23f6874be983901876cd600c4e_0.geojson") %>%
select(
geometry,
ALAND10,
GEOID10
)
st_crs(tracts)
set.seed(264)
v1 <- runif(1:dim(tracts)[1], .7, 1.25)
tracts2 <- cbind(tracts, v1)
tracts_2017 <- tracts2 %>%
mutate(season=2017)
tracts_2018 <- tracts2 %>%
mutate(
season=2018,
ALAND10 = ALAND10*v1
)
tracts3 <- rbind(tracts_2017, tracts_2018)
st_crs(tracts3)
makeplot1 <- function(){
datalist1 <- split(
tracts3,
tracts3$season
)
datalist2 <- split(
tracts3,
tracts3$season
)
mapply(function(data1, data2){
p1 <- ggplot() +
geom_sf(
data = data1,
aes(fill = ALAND10)
) +
geom_sf(
data = data2 %>% st_union(),
fill = alpha("red", 0.4),
color = alpha("red", 0.4)
) +
coord_sf(
ylim = c( 43.04, 43.07),
xlim = c(-76.14,-76.10),
clip = "on",
expand = F
)
print(p1)
},
datalist1, datalist2
)
}
makeplot2 <- function(){
datalist1 <- split(
tracts3,
tracts3$season
)
datalist2 <- split(
tracts3,
tracts3$season
)
mapply(function(data1, data2){
p2 <- ggplot() +
geom_sf(
data = data1,
aes(fill = ALAND10)
) +
geom_sf(
data = data2 %>% st_union(),
fill = alpha("red", 0.4),
color = alpha("red", 0.4)
)
print(p2)
},
datalist1, datalist2
)
}
video_file1 <- file.path(tempdir(), 'Tracts1.mp4')
av::av_capture_graphics(makeplot1(), video_file1, vfilter='framerate=fps=10')
av::av_media_info(video_file1)
utils::browseURL(video_file1)
video_file2 <- file.path(tempdir(), 'Tracts2.mp4')
av::av_capture_graphics(makeplot2(), video_file2, vfilter='framerate=fps=10')
av::av_media_info(video_file2)
utils::browseURL(video_file2)
正如 Thomas Lin Pedersen 在您链接的 github 问题中所建议的那样,解决方案是在 Windows 机器上使用 png(..., type = 'cairo')
设备。如果您阅读 ?av::av_capture_graphics()
上的文档,您会发现 ...
参数可用于将参数传递给 png()
函数。因此,我建议完全这样做:
library(tidyverse)
library(sf)
library(av)
tracts <- read_sf("https://opendata.arcgis.com/datasets/230f9d23f6874be983901876cd600c4e_0.geojson") %>%
select(
geometry,
ALAND10,
GEOID10
)
st_crs(tracts)
set.seed(264)
v1 <- runif(1:dim(tracts)[1], .7, 1.25)
tracts2 <- cbind(tracts, v1)
tracts_2017 <- tracts2 %>%
mutate(season=2017)
tracts_2018 <- tracts2 %>%
mutate(
season=2018,
ALAND10 = ALAND10*v1
)
tracts3 <- rbind(tracts_2017, tracts_2018)
st_crs(tracts3)
makeplot1 <- function(){
datalist1 <- split(
tracts3,
tracts3$season
)
datalist2 <- split(
tracts3,
tracts3$season
)
mapply(function(data1, data2){
p1 <- ggplot() +
geom_sf(
data = data1,
aes(fill = ALAND10)
) +
geom_sf(
data = data2 %>% st_union(),
fill = alpha("red", 0.4),
color = alpha("red", 0.4)
) +
coord_sf(
ylim = c( 43.04, 43.07),
xlim = c(-76.14,-76.10),
clip = "on",
expand = F
)
print(p1)
},
datalist1, datalist2
)
}
video_file1 <- file.path(tempdir(), 'Tracts1.mp4')
av::av_capture_graphics(makeplot1(), video_file1,
vfilter='framerate=fps=10',
type = "cairo")
av::av_media_info(video_file1)
utils::browseURL(video_file1)
此外,
the current work around involves saving the plot as a .png.
正是av::av_capture_graphics()
在幕后所做的,也是gganimate
包所做的。
最后,我建议您对色标设置固定限制,因为这似乎在帧之间发生变化,使任何解释都变得复杂。 gganimate
包优雅地说明了这些细节。