如何在基础图形中复制ggplot2 :: geom_raster? [英] How to replicate ggplot2::geom_raster in base graphics?

查看:201
本文介绍了如何在基础图形中复制ggplot2 :: geom_raster?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

tl; dr



如果您在下面运行了两个代码片段(注意:代码先前已损坏,但现在已修复且已在多台计算机上进行检查),您会看到一些栅格数据的两幅图。一个使用 ggplot2 并产生高分辨率海岸线的平滑图像,这些海岸线从我用来屏蔽栅格的多边形以某种方式继承。



不使用ggplot2,我们可以使用 raster :: plot(...,interpolate ='bilinear') rasterImage(interpolate = TRUE)。但地图中的海岸线看起来不太好(根据栅格的分辨率,它们锯齿状/像素化)。你可能需要放大一下才能看到这个。我有两个问题:


  1. 如何在基本图形中绘制栅格,但只能与其边缘重叠的多边形比栅格更高的分辨率<产生类似ggplot输出的东西?>?我在这里更详细地提出这个问题:,举个例子输出我想。

  2. ggplot2如何理解多边形边界的正确绘图位置?我看不到我在哪里/如何告诉ggplot屏蔽多边形是什么!



宝石细节



我在R中绘制栅格。我最初使用 ggplot2 进行绘图,使用 geom_raster(),但现在我需要切换回基本R,因为我最终需要在一个绘图上显示具有不同颜色标度的多个栅格(这是一张地图,而颜色标尺最终会因大陆而异)。

下面的代码将重现这些情节(包括下载必要的文件)。在我的计算机上,完整的代码(下面两个代码片段)大约需要1.5分钟的时间来运行 - 大部分代码都是绘制/渲染绘图。

  
#下载和加载栅格
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')
pre>

请注意海岸线上的像素化​​(您可能需要放大才能看到此图像)。这是根据栅格的分辨率预计的。

但请注意 ggplot2 中发生了什么!



警告,呈现剧情需要我的机器上有相当一部分内存

 #转换为数据。 (gdf)2 
msr.p< - rasterToPoints(msrP2)
mdf< - data.frame(msr.p)
colnames(mdf)< - c(Longitude, Latitude,RichnessProp)

#使用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,colors = 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

现在海岸线以高保真再现!最终,其原因必定与这样一个事实有关,即该栅格最初是通过使用高分辨率的大陆和湖泊形状文件掩盖更大的栅格而产生的。因此,要按照重要性重新陈述问题:



Q1。如何在基本R中创建此高分辨率图?



Q2。 ggplot如何知道海岸线基于我传递给它的data.frame的位置? ?

解决方案

既然你说 ggplot 需要大量内存而 plot 不会,我认为像素化默认来自 raster :: plot 默认情况实际上只需要一部分像素来减少内存占用量,具体取决于参数 maxpixels


maxpixels
整数> 0.用于绘图的最大单元格数。如果maxpixels< ncell(x),sampleRegular在绘图之前使用。如果
gridded = TRUE maxpixels可能会被忽略以获得更大的样本


我会尝试如下所示:

  plot(msrP2,interpolate ='bilinear',maxpixels = 50000000)

查看是否可以解决您的问题。

PS:关注点Q2: ggplot2 无法知道任何有关海岸线的信息。如果我是对的,你所看到的问题只是与 raster :: plot 自动减少分辨率以节省内存有关。

tl;dr

If you run both code snippets below (note: code was previously broken, but now is fixed and has been checked on multiple computers), you will see two plots of some raster data. One uses ggplot2 and produces a smoothed image with high-resolution coastlines that are somehow inherited from the polygons that I used to mask the raster.

Without using ggplot2, we can get the smoothed image using raster::plot(... , interpolate='bilinear') or rasterImage(interpolate = TRUE). But the coastlines in the map don't look good (they are jagged/pixellated, according to the resolution of the raster). You may have to zoom in quite a bit to see this. I have two questions:

  1. How can I plot the raster in base graphics, but only where it overlaps a polygon whose edge has higher resolution than the raster (yielding something like the ggplot output)? I ask this question in more detail here, with an example of the output I want.
  2. How does ggplot2 understand where the polygon edges are for correct plotting? I cannot see where/how I tell ggplot what the masking polygon is!

Gory details

I am plotting a raster in R. I initially did the plotting with ggplot2, using geom_raster(), but now I need to switch back to base R because I ultimately need to display multiple rasters with different color-scales on a single plot (this is a map, and color-scales will eventually differ by continent).

The code below will reproduce the plots (including downloading the necessary files). On my computer, the full code (both snippets below) takes about 1.5 minutes to run--most of this is drawing/rendering the plots.

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')

Note the pixellation along coastlines (you may need to zoom in to see this). This is expected based on the resolution of the raster.

But watch what happens in ggplot2!

warning, rendering the plot requires a decent chunk of memory on my machine

# 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

Now the coastlines are reproduced in high fidelity! Ultimately, the reason for this must have something to do with the fact that this raster was originally produced by masking a larger raster using high-resolution shapefiles of continents and lakes. So to re-state the questions, in order of importance:

Q1. How can I create this high-resolution plot in base R?

Q2. How in the heck does ggplot "know" where the coastline is based on the data.frame that I am passing to it??

解决方案

Since you say that ggplot takes a huge amount of memory while plot doesn't, I'd think that the pixellation comes from the fact that raster::plot by default actually takes in only a subset of pixels to reduce memory footprint, depending on argument 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

I'd try something like:

plot(msrP2, interpolate='bilinear', maxpixels=50000000)

to see if it solves your issue.

PS: Concernign Q2: ggplot2 can not know anything about the "coastline". If I'm right, the problem you are seeing is just related to the fact that raster::plot automatically "reduces" resolution to save you memory.

这篇关于如何在基础图形中复制ggplot2 :: geom_raster?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆