如何在基本图形中复制 ggplot2::geom_raster?
How to replicate ggplot2::geom_raster in base graphics?
tl;博士
如果您运行下面的两个代码片段(注意:代码以前被破坏,但现在已修复并已在多台计算机上检查过),您将看到一些栅格数据的两个图。一个使用 ggplot2
并生成具有高分辨率海岸线的平滑图像,这些海岸线以某种方式继承自我用来屏蔽光栅的多边形。
不使用ggplot2,我们可以使用raster::plot(... , interpolate='bilinear')
或rasterImage(interpolate = TRUE)
得到平滑的图像。但是地图中的海岸线看起来不太好(根据栅格的分辨率,它们是jagged/pixellated)。您可能需要放大很多才能看到它。我有两个问题:
- 如何在基础图形中绘制栅格,但仅在它与多边形重叠的地方 其边缘的分辨率高于栅格(产生类似 ggplot 输出的内容)?我问这个问题in more detail here, with an example of the output I want.
- ggplot2 如何理解多边形边缘的位置以便正确绘图?我看不到 where/how 我告诉 ggplot 掩蔽多边形是什么!
血淋淋的细节
我正在 R 中绘制栅格。我最初使用 ggplot2
、geom_raster()
进行绘图,但现在我需要切换回基本 R,因为我最终需要显示多个栅格在单个地块上使用不同的色标(这是一张地图,色标最终会因大陆而异)。
下面的代码将重现情节(包括下载必要的文件)。在我的电脑上,完整的代码(下面的两个片段)需要大约 1.5 分钟才能 运行——其中大部分是 drawing/rendering 情节。
library("rgdal")
library("sp")
library("raster")
library("ggplot2")
# Downloading and loading raster
download.file("https://dl.dropboxusercontent.com/u/49481174/Stack.zip", destfile="Stack.zip")
unzip("Stack.zip")
msrP2 <- raster("Stack/msrP2.grd")
plot(msrP2, interpolate='bilinear')
注意沿海岸线的像素化(您可能需要放大才能看到)。这是基于光栅分辨率的预期结果。
但请注意 ggplot2
中会发生什么!
警告,渲染绘图需要我机器上的大量内存
# Convert to data.frame for ggplot2
msr.p <- rasterToPoints(msrP2)
mdf <- data.frame(msr.p)
colnames(mdf) <- c("Longitude", "Latitude", "RichnessProp")
# plot using geom_raster
b_map <- ggplot(data=mdf, aes_string(y="Latitude", x="Longitude")) +
geom_raster(aes(fill=RichnessProp)) +
theme_bw() +
coord_equal() +
scale_fill_gradientn("DD", colours=c("gold1", "coral", "navy"), na.value="black") +
theme(axis.title.x = element_blank(),
axis.title.y = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = "right",
legend.key = element_blank(),
axis.ticks=element_blank()) +
scale_y_continuous(limits=c(-5133051,6324167)) +
scale_x_continuous(limits=c(-20100000,20100000))
b_map
高保真再现海岸线!最终,造成这种情况的原因一定与以下事实有关:该栅格最初是通过使用大陆和湖泊的高分辨率 shapefile 屏蔽更大的栅格而生成的。所以重新陈述问题,按重要性排序:
Q1. 我如何在 base R 中创建这个高分辨率图?
Q2. ggplot 究竟如何根据我传递给它的 data.frame “知道”海岸线的位置?
既然你说 ggplot
占用大量内存而 plot
不占用内存,我认为像素化来自 raster::plot
默认情况下的事实仅接受一部分像素以减少内存占用,具体取决于参数 maxpixels
:
maxpixels
integer > 0. Maximum number of cells to use for the plot. If maxpixels < ncell(x), sampleRegular is used before plotting. If
gridded=TRUE maxpixels may be ignored to get a larger sample
我会尝试类似的方法:
plot(msrP2, interpolate='bilinear', maxpixels=50000000)
看看它是否能解决您的问题。
PS:关注Q2:ggplot2
对"coastline"一无所知。如果我是对的,那么您看到的问题仅与 raster::plot
自动 "reduces" 分辨率以节省您的内存这一事实有关。
tl;博士
如果您运行下面的两个代码片段(注意:代码以前被破坏,但现在已修复并已在多台计算机上检查过),您将看到一些栅格数据的两个图。一个使用 ggplot2
并生成具有高分辨率海岸线的平滑图像,这些海岸线以某种方式继承自我用来屏蔽光栅的多边形。
不使用ggplot2,我们可以使用raster::plot(... , interpolate='bilinear')
或rasterImage(interpolate = TRUE)
得到平滑的图像。但是地图中的海岸线看起来不太好(根据栅格的分辨率,它们是jagged/pixellated)。您可能需要放大很多才能看到它。我有两个问题:
- 如何在基础图形中绘制栅格,但仅在它与多边形重叠的地方 其边缘的分辨率高于栅格(产生类似 ggplot 输出的内容)?我问这个问题in more detail here, with an example of the output I want.
- ggplot2 如何理解多边形边缘的位置以便正确绘图?我看不到 where/how 我告诉 ggplot 掩蔽多边形是什么!
血淋淋的细节
我正在 R 中绘制栅格。我最初使用 ggplot2
、geom_raster()
进行绘图,但现在我需要切换回基本 R,因为我最终需要显示多个栅格在单个地块上使用不同的色标(这是一张地图,色标最终会因大陆而异)。
下面的代码将重现情节(包括下载必要的文件)。在我的电脑上,完整的代码(下面的两个片段)需要大约 1.5 分钟才能 运行——其中大部分是 drawing/rendering 情节。
library("rgdal")
library("sp")
library("raster")
library("ggplot2")
# Downloading and loading raster
download.file("https://dl.dropboxusercontent.com/u/49481174/Stack.zip", destfile="Stack.zip")
unzip("Stack.zip")
msrP2 <- raster("Stack/msrP2.grd")
plot(msrP2, interpolate='bilinear')
注意沿海岸线的像素化(您可能需要放大才能看到)。这是基于光栅分辨率的预期结果。
但请注意 ggplot2
中会发生什么!
警告,渲染绘图需要我机器上的大量内存
# Convert to data.frame for ggplot2
msr.p <- rasterToPoints(msrP2)
mdf <- data.frame(msr.p)
colnames(mdf) <- c("Longitude", "Latitude", "RichnessProp")
# plot using geom_raster
b_map <- ggplot(data=mdf, aes_string(y="Latitude", x="Longitude")) +
geom_raster(aes(fill=RichnessProp)) +
theme_bw() +
coord_equal() +
scale_fill_gradientn("DD", colours=c("gold1", "coral", "navy"), na.value="black") +
theme(axis.title.x = element_blank(),
axis.title.y = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = "right",
legend.key = element_blank(),
axis.ticks=element_blank()) +
scale_y_continuous(limits=c(-5133051,6324167)) +
scale_x_continuous(limits=c(-20100000,20100000))
b_map
高保真再现海岸线!最终,造成这种情况的原因一定与以下事实有关:该栅格最初是通过使用大陆和湖泊的高分辨率 shapefile 屏蔽更大的栅格而生成的。所以重新陈述问题,按重要性排序:
Q1. 我如何在 base R 中创建这个高分辨率图?
Q2. ggplot 究竟如何根据我传递给它的 data.frame “知道”海岸线的位置?
既然你说 ggplot
占用大量内存而 plot
不占用内存,我认为像素化来自 raster::plot
默认情况下的事实仅接受一部分像素以减少内存占用,具体取决于参数 maxpixels
:
maxpixels integer > 0. Maximum number of cells to use for the plot. If maxpixels < ncell(x), sampleRegular is used before plotting. If gridded=TRUE maxpixels may be ignored to get a larger sample
我会尝试类似的方法:
plot(msrP2, interpolate='bilinear', maxpixels=50000000)
看看它是否能解决您的问题。
PS:关注Q2:ggplot2
对"coastline"一无所知。如果我是对的,那么您看到的问题仅与 raster::plot
自动 "reduces" 分辨率以节省您的内存这一事实有关。