geom_vline 和 geom_hline 在 ggplot2 上对空间地图进行分面时均失败
Both geom_vline and geom_hline fails when faceting spatial map on ggplot2
在发布这个问题之前我非常小心,以避免重复。所以我打算创建一个基于四分之一的分面图,同时配备主要和次要网格,而纬度和经度标签只在主要网格上。这是 MWE:
library(sf)
library(rnaturalearth)
sf::sf_use_s2(FALSE)
dummy <- data.frame(
Lat1 = seq(-14.5, 4.5, by = 1),
Lon1 = seq(105.5, 124.5, by = 1),
quarter = rep(1:4, 10)
)
worldmap <- ne_countries(scale = 'medium', type = 'map_units', returnclass = 'sf')
wpp <- st_crop(worldmap, ymin = -15, ymax = -5, xmin = 105, xmax = 125)
minor.x <- seq(105, 125, by = 1)
minor.y <- seq(-15, -5, by = 1)
ggplot() +
geom_sf(data = wpp, color = "gray", fill = "gray") +
coord_sf(xlim=c(min(data.pie$Lon1-0.5),max(data.pie$Lon1)+0.5),
ylim=c(min(data.pie$Lat1)-0.5,max(data.pie$Lat1)+0.5),
expand = FALSE) +
geom_hline(aes(yintercept = minor.y), color = "gray", linetype = "solid", size = 0.1) +
geom_vline(aes(xintercept = minor.x), color = "gray", linetype = "solid", size = 0.1) +
geom_point(data = dummy, aes(x = Lon1, y = Lat1), color= "black") +
xlab("Longitude") + ylab("Latitude") +
scale_x_continuous(breaks = seq(105,125,2), minor_breaks = seq(106, 124, 2)) +
scale_y_continuous(breaks = seq(-15,-5,2), minor_breaks = seq(-14, -4, 2)) +
facet_wrap(~quarter) +
theme_minimal() +
theme(
# panel.grid.minor = element_line(color = "blue", size = 0.1),
panel.grid.major = element_blank(),
panel.background = element_rect(colour = "black", size=0.5),
legend.position = "right",
legend.title.align = 0.5,
legend.text.align = 1)
没有分面我可以产生所需的输出
但是,当我使用facet_wrap(~quarter)
时出现错误:Error in FUN(X[[i]], ...) : subscript out of bounds
如果我关闭 geom_vline
和 geom_hline
我设法生成了一个分面图,但与此同时,我将失去对次网格的控制(只显示主要网格。是否有有什么解决方法吗?PS。我使用的是最新的 R 和 ggplot()
版本。
问题是您将 x/yintercept
包裹在 aes()
中。不能 100% 确定原因,但我的猜测是,当 quarter
分面时,ggplot2 也在传递给 geom_hline/vline
的数据中寻找名为 quarter
的列。但是,由于既没有全局也没有本地 data
你会得到一个错误。
作为这个问题的更简单的代表:
library(ggplot2)
ggplot() +
geom_point(data = mtcars, aes(hp, mpg)) +
geom_point(aes(x = 1, y = 1), color = "red") +
facet_wrap(~cyl)
#> Error in FUN(X[[i]], ...): subscript out of bounds
要解决您的问题,请将 x/yintercept
设置为参数而不是美学。
library(sf)
library(rnaturalearth)
library(ggplot2)
ggplot() +
geom_sf(data = wpp, color = "gray", fill = "gray") +
coord_sf(
xlim = range(dummy$Lon1) + c(-0.5, 0.5),
ylim = range(dummy$Lat1) + c(-0.5, 0.5),
expand = FALSE
) +
geom_hline(yintercept = minor.y, color = "gray", linetype = "solid", size = 0.1) +
geom_vline(xintercept = minor.x, color = "gray", linetype = "solid", size = 0.1) +
geom_point(data = dummy, aes(x = Lon1, y = Lat1), color = "black") +
xlab("Longitude") +
ylab("Latitude") +
scale_x_continuous(breaks = seq(105, 125, 2), minor_breaks = seq(106, 124, 2)) +
scale_y_continuous(breaks = seq(-15, -5, 2), minor_breaks = seq(-14, -4, 2)) +
facet_wrap(~quarter) +
theme_minimal() +
theme(
# panel.grid.minor = element_line(color = "blue", size = 0.1),
panel.grid.major = element_blank(),
panel.background = element_rect(colour = "black", size = 0.5),
legend.position = "right",
legend.title.align = 0.5,
legend.text.align = 1
)
在发布这个问题之前我非常小心,以避免重复。所以我打算创建一个基于四分之一的分面图,同时配备主要和次要网格,而纬度和经度标签只在主要网格上。这是 MWE:
library(sf)
library(rnaturalearth)
sf::sf_use_s2(FALSE)
dummy <- data.frame(
Lat1 = seq(-14.5, 4.5, by = 1),
Lon1 = seq(105.5, 124.5, by = 1),
quarter = rep(1:4, 10)
)
worldmap <- ne_countries(scale = 'medium', type = 'map_units', returnclass = 'sf')
wpp <- st_crop(worldmap, ymin = -15, ymax = -5, xmin = 105, xmax = 125)
minor.x <- seq(105, 125, by = 1)
minor.y <- seq(-15, -5, by = 1)
ggplot() +
geom_sf(data = wpp, color = "gray", fill = "gray") +
coord_sf(xlim=c(min(data.pie$Lon1-0.5),max(data.pie$Lon1)+0.5),
ylim=c(min(data.pie$Lat1)-0.5,max(data.pie$Lat1)+0.5),
expand = FALSE) +
geom_hline(aes(yintercept = minor.y), color = "gray", linetype = "solid", size = 0.1) +
geom_vline(aes(xintercept = minor.x), color = "gray", linetype = "solid", size = 0.1) +
geom_point(data = dummy, aes(x = Lon1, y = Lat1), color= "black") +
xlab("Longitude") + ylab("Latitude") +
scale_x_continuous(breaks = seq(105,125,2), minor_breaks = seq(106, 124, 2)) +
scale_y_continuous(breaks = seq(-15,-5,2), minor_breaks = seq(-14, -4, 2)) +
facet_wrap(~quarter) +
theme_minimal() +
theme(
# panel.grid.minor = element_line(color = "blue", size = 0.1),
panel.grid.major = element_blank(),
panel.background = element_rect(colour = "black", size=0.5),
legend.position = "right",
legend.title.align = 0.5,
legend.text.align = 1)
没有分面我可以产生所需的输出
但是,当我使用facet_wrap(~quarter)
时出现错误:Error in FUN(X[[i]], ...) : subscript out of bounds
如果我关闭 geom_vline
和 geom_hline
我设法生成了一个分面图,但与此同时,我将失去对次网格的控制(只显示主要网格。是否有有什么解决方法吗?PS。我使用的是最新的 R 和 ggplot()
版本。
问题是您将 x/yintercept
包裹在 aes()
中。不能 100% 确定原因,但我的猜测是,当 quarter
分面时,ggplot2 也在传递给 geom_hline/vline
的数据中寻找名为 quarter
的列。但是,由于既没有全局也没有本地 data
你会得到一个错误。
作为这个问题的更简单的代表:
library(ggplot2)
ggplot() +
geom_point(data = mtcars, aes(hp, mpg)) +
geom_point(aes(x = 1, y = 1), color = "red") +
facet_wrap(~cyl)
#> Error in FUN(X[[i]], ...): subscript out of bounds
要解决您的问题,请将 x/yintercept
设置为参数而不是美学。
library(sf)
library(rnaturalearth)
library(ggplot2)
ggplot() +
geom_sf(data = wpp, color = "gray", fill = "gray") +
coord_sf(
xlim = range(dummy$Lon1) + c(-0.5, 0.5),
ylim = range(dummy$Lat1) + c(-0.5, 0.5),
expand = FALSE
) +
geom_hline(yintercept = minor.y, color = "gray", linetype = "solid", size = 0.1) +
geom_vline(xintercept = minor.x, color = "gray", linetype = "solid", size = 0.1) +
geom_point(data = dummy, aes(x = Lon1, y = Lat1), color = "black") +
xlab("Longitude") +
ylab("Latitude") +
scale_x_continuous(breaks = seq(105, 125, 2), minor_breaks = seq(106, 124, 2)) +
scale_y_continuous(breaks = seq(-15, -5, 2), minor_breaks = seq(-14, -4, 2)) +
facet_wrap(~quarter) +
theme_minimal() +
theme(
# panel.grid.minor = element_line(color = "blue", size = 0.1),
panel.grid.major = element_blank(),
panel.background = element_rect(colour = "black", size = 0.5),
legend.position = "right",
legend.title.align = 0.5,
legend.text.align = 1
)