简体   繁体   English

在 base R、ggplot2 或 levelplot 中绘制带有栅格的多边形

[英]Plotting polygons with rasters in base R, ggplot2 or levelplot

I am trying to plot in R a raster layer with lines/polygon objects in R and each time I fail miserably with errors.我正在尝试 plot 中的 R 中带有线/多边形对象的栅格图层 R 中,每次我都因错误而惨败。 I tried to do this in base R , ggplot2 and using levelplot but can't get the right result.我尝试在base Rggplot2和使用levelplot中执行此操作,但无法获得正确的结果。

Source data can be found here .可以在此处找到源数据。

What I need to do in the plot (all in one plot) is to: 1) zoom in a certain area defined as NIG .我需要在 plot(全部在一个图中)中做的是:1)放大定义为NIG的特定区域。 T 2) Display raster r values on a scale with cuts intervals. T 2) 在具有cuts间隔的刻度上显示栅格r值。 3) Plot the country boundaries( shpAfr in base R and ggplot2 or world.outlines.sp in levelplot ). 3) Plot 国家边界( shpAfrbase Rggplot2world.outlines.splevelplot )。 4) Finally, include shpWater polygon layer (with col="blue" fill and contours). 4) 最后,包括shpWater多边形图层(使用col="blue"填充和轮廓)。

library(raster)
library(maptools)
library(rasterVis)
library(viridis)
library(sf)
library(rgdal)
library(ggplot2)

r <- raster("raster_example.tif")
crs(r) <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +to wgs84=0,0,0"
NIG <- c(2,14.5,4,14)
Reg_name <- "Nigeria"

shpAfr <- readOGR(dsn="Africa.shp")
proj4string(shpAfr) # describes data’s current coordinate reference system
#st_read(system.file("shape/nc.shp", package="sf"))

# Import water polygon
shpWater <- readOGR(dsn="waterbodies_africa.shp")
shpWater.count <- nrow(shpWater@data)
shpWater$id <- 1:shpWater.count
shpWater.fort <- fortify(shpWater, region='id')

# Import Africa admin map
shpAfr <- readOGR(dsn="Africa.shp")
shpAfr.count <- nrow(shpAfr@data)
shpAfr$id <- 1:shpAfr.count
shpAfr.fort <- fortify(shpAfr, region='id')

# Set colour intervals for plotting:
cuts=seq(0,1,0.1) #set breaks

Trying in base R, my problem is I can get the water shape fill in the right colour (fill and contour should be blue).在 base R 中尝试,我的问题是我可以用正确的颜色填充水的形状(填充和轮廓应该是蓝色)。 If I try to plot both wrld_simpl and shpWater as polygon() I get into even bigger troubles.如果我尝试 plot wrld_simpl 和 shpWater 作为 polygon() 我会遇到更大的麻烦。

plot(r, xlim = NIG[1:2], ylim = NIG[3:4],
     breaks=cuts, col = rev(plasma(11)))
lines(wrld_simpl,lwd = 1.5)
lines(shpWater, col="blue") # works but cannot fill the polygon
polygon(shpWater, col = "blue", border = "blue") # getting error here
Error in as.double(y) : 
  cannot coerce type 'S4' to vector of type 'double'

Ok, so now I try ggplot2, but I can't find a way to include a raster here without getting an error.好的,现在我尝试 ggplot2,但我找不到一种方法来在此处包含栅格而不出现错误。

lon <- seq(r@extent@xmin,r@extent@xmax,
           (r@extent@xmax-r@extent@xmin)/r@ncols)
lat <- seq(r@extent@ymin,r@extent@ymax,
           (r@extent@ymax-r@extent@ymin)/r@nrows)

Plot1 <- ggplot()+
  geom_polygon(aes(x = long, y = lat, group=id),
               data = shpAfr.fort, color ="grey27", fill ="grey",
               alpha = .4, size = .2)+
  geom_raster(data = test, aes(fill=values))+ ## here it goes bad
  #geom_tile(data=test_df, aes(x=x, y=y, fill=value), alpha=0.8) + 
  #scale_fill_viridis() +
  geom_polygon(aes(x = long, y = lat, group=id),
               data = shpWater.fort, color ="lightskyblue2", fill ="lightskyblue2",
               size = .2)+coord_equal()+
  theme_minimal()+
  coord_map(xlim = Region[[3]][1:2],ylim = Region[[3]][3:4])

plot(Plot1)

Finally, I tried the levelplot and AGAIN failed.最后,我尝试了 levelplot,但又失败了。

mapTheme <- rasterTheme(region = rev(brewer.pal(10, "RdBu")))

# Get world outlines:
world.outlines <- map("world", plot=FALSE)
world.outlines.sp <- map2SpatialLines(world.outlines, proj4string = CRS("+proj=longlat"))

# Plot raster and polygon:
Plot2 <- levelplot(r,par.settings = mapTheme,pretty=TRUE,margin = F,
          xlim = NIG[1:2],ylim = NIG[3:4],
          col.regions=colorRampPalette(c("light blue","blue", "red")),
          main=paste0("test")) + layer(sp.lines(world.outlines.sp, col = "black", lwd = 0.5))
plot(Plot2 + layer(sp.lines(world.outlines.sp, col = "black", lwd = 0.5))
#Error: Attempted to create layer with no stat.

My results so far: 1) first image does not have the polygons filled with blue 2) second image has clearly world outlines not in the right location:到目前为止我的结果:1)第一张图片没有填充蓝色的多边形2)第二张图片有明显的世界轮廓不在正确的位置: 在此处输入图像描述 在此处输入图像描述

You would have probably have had answers a lot earlier if you had made a simple reprex, eg like this如果你做了一个简单的代表,你可能会更早得到答案,例如像这样

library(raster)
r <- raster(res=1/12)
values(r) <- sample(100, ncell(r), replace=TRUE)
filename <- system.file("external/lux.shp", package="raster")
v <- shapefile(filename)
  1. zoom in a certain area放大某个区域

One way to zoom is to use crop (alternatively use the ext argument in plot)缩放的一种方法是使用裁剪(或者在绘图中使用ext参数)

x <- crop(r, v)
  1. Display raster r values on a scale with cuts intervals在具有切割间隔的刻度上显示栅格 r 值
cuts <- c(0,20,60,100)
plot(x, breaks=cuts, col=rainbow(3))

or要么

 y <- cut(x, cuts) 
  1. Plot the country boundaries Plot国界
lines(v)
  1. Finally, include polygon layer (with col="blue" fill and contours).最后,包括多边形图层(使用 col="blue" 填充和轮廓)。
plot(v[c(1,3),], col="blue", border="red", lwd=2, add=TRUE)
  • 6 months later but I feel this question. 6个月后,但我觉得这个问题。 My two thoughts are (1) I have had luck with plotting geom_sf and geom_stars together.我的两个想法是 (1) 我很幸运将 geom_sf 和 geom_stars 一起绘制。 You have to change your raster to a df before changing to a geom_stars.在更改为 geom_stars 之前,您必须将光栅更改为 df。 and (2) regardless of method, you need all datasets in the same projection - check with crs() and set all to the same with st_transform()和 (2) 无论采用何种方法,您都需要同一投影中的所有数据集 - 使用 crs() 检查并使用 st_transform() 将所有数据集设置为相同

I didn't actually test this with your data but something like:我实际上并没有用您的数据对此进行测试,而是类似:

make raster into a df将光栅化为 df

test.df = as.data.frame (test, xy=TRUE) # Convert to data.frame, keeping the 
coordinates
class(test.df)

convert to geom_stars转换为 geom_stars

test.stars = st_as_stars(test.df)

try your plot试试你的 plot

    Plot1 <- ggplot()+

  geom_stars(data = test, aes(fill=values))+ #need to plot raster first I think?
scale_fill_identity( name = "", breaks = cuts,labels = "")+      

  geom_sf(data = shpAfr.fort, color ="grey27", size = .2)+
geom_sf(data = shpWater.fort, color ="lightskyblue2", fill 
  ="lightskyblue2", size = .2)+

  theme_minimal()+
  coord_sf( xlim = NIG[1:2], ylim = NIG[3:4]),expand = FALSE)

Plot1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM