Trouble overlaying plots in R - r

I've produced a raster using idw to make predictions across California, and now I'm trying to overlay the raster image with the border/shp file of california.
I've ensured the crs projections are the same for both plots, however I still can't get both to show up.
The following is the code for how I produced the raster:
plot(zip_table)
x.range <- as.double(range(zip_table#coords[,1]))
y.range <- as.double(range(zip_table#coords[,2]))
grd <- expand.grid(x=seq(from=x.range[1], to=x.range[2], by=0.01),
y=seq(from=y.range[1], to=y.range[2], by=0.01))
## convert grid to SpatialPixel class
coordinates(grd) <- ~ x + y
gridded(grd) <- TRUE
idw1 <- gstat::idw(TELERATIO ~ 1, zip_table, grd, idp = 2)
idw.output <- as.data.frame(idw1)
names(idw.output)[1:3] <- c("lng","lat","var1.pred")
r <- raster(idw1)```
And the CA state file I downloaded using a work around of the raster::getData function:
``` CA <- gadm36_USA_1_sp[gadm36_USA_1_sp$NAME_1 =='California',]
When I produce my plots, only the raster shows up. Any help is appreciated:
plot(r)
plot(CA, add = TRUE)

Related

Rasterize lines in R: How to assign max value to a cell?

Problem
I want to rasterize spatial lines and assign the maximum value of all lines that touch/intersect a raster cell to that cell.
I work in terra with lines as a SpatVect object, I would hence prefer a terra::rasterize solution. I would also be happy with a solution using stars::st_rasterize (see also this question).
The documentation of terra::rasterize seems to suggest it does not support lines properly so far - using the fun argument seems to be limited to points vector data only. I tried with terra::rasterize nevertheless, see the example below.
I'm aware of raster::rasterize, but it seems a bit outdated since it's still sp object based. Or is it the only way to do it atm?
Example
Here you can see that neither the max nor the mean function seems to work properly when rasterizing via terra::rasterize(... fun = "max"/"mean"):
library("terra")
### Example data ###
f <- system.file("ex/lux.shp", package="terra")
v <- vect(f)
lns <- as.lines(v)
r <- rast(v, res=.2)
### Rasterize via terra::rasterize ###
x_max <- rasterize(lns, r, fun="max", field = "POP")
x_mean <- rasterize(lns, r, fun="mean", field = "POP")
### Plot results ###
fontsize <- 0.7
par(mfrow=c(1,3))
plot(lns, y = "POP", main = "Lines with original values")
text(lns, "POP", cex = fontsize)
plot(x_max, main = "Rasterized via fun 'max'")
text(x_max, cex = fontsize)
plot(lns, add = T)
plot(x_mean, main = "Rasterized via fun 'mean'")
text(x_mean, cex = fontsize)
plot(lns, add = T)
I have found a somewhat hacky solution.
As proposed in the comments, I turned the lines into points by sampling along them.
I used sf::st_line_sample() for this instead of rgeos::gInterpolate() - it was cleaner and easier. Then terra::rasterize() can handle the points correctly and applies the max fun as expected.
Confirmed by the plot below.
Example solution
library("terra")
library("dplyr")
library("sf")
library("units")
### Example data ###
f <- system.file("ex/lux.shp", package="terra")
v <- vect(f)
lns <- as.lines(v)
r <- rast(v, res=.2)
### Turn SpatVector lines into sf object
lns_sf <- lns %>%
st_as_sf() %>%
st_transform(2169) # reprojection needed for st_line_sample
### Sample points along all lines every kilometer
pts_geometries <- lns_sf %>%
st_line_sample(density = units::set_units(1, 1/km))
### Add attributes and make MULTIPOINTs simple POINTS
pts_sf <- st_sf(lns_sf,
geometry = pts_geometries) %>%
st_cast("POINT") %>%
st_transform(crs(lns))
### Go back to terra: Turn sf into SpatVector object
pts <- pts_sf %>%
vect()
### Now rasterization works and "max" function is applied corretly
x_max <- rasterize(pts, r, fun="max", field = "POP")
fontsize <- 0.7
par(mfrow=c(1,3))
plot(lns, y = "POP", main = "Lines with original values")
text(lns, "POP", cex = fontsize)
plot(x_max, main = "Rasterized with fun 'max' using points generated from lines")
text(x_max, cex = fontsize)
plot(lns, add = T)
plot(pts, main = "Points used for rasterization")

r raster statistics per grid cell zone

I would like to calculate grid cell statistics in zones that are within graticules (see plot).
Getting the cellstats for the shown grid cell is not difficult, but how could this be done for all grid cells?
library(raster)
filename <- system.file("external/test.grd", package="raster")
r=raster(filename)
plot(r)
e=extent(180000,181000,330000,331000)
plot(e,add=T)
grid()
x=crop(r,e)
cellStats(x,mean)
Your reproducible example did not work for me as I am not sure why r[r>500]=1 and r[r<=500]=NA are used while your original plot is different?! Plus, I was not sure what rx is?! One way to do this as below:
library(raster)
filename <- system.file("external/test.grd", package="raster")
r=raster(filename)
# r[r>500]=1
# r[r<=500]=NA
plot(r)
xmin <- seq(178000, 181000, 1000)
xmax <- seq(179000, 182000, 1000)
ymin <- seq(329000, 333000, 1000)
ymax <- seq(330000, 334000, 1000)
zonal.mtx <- matrix(nrow=length(xmin), ncol=length(ymin))
library(spatialEco)
for (i in 1:length(xmin)){
for (j in 1:length(ymin)){
e=extent(xmin[i],xmax[i],ymin[j],ymax[j])
plot(e,add=T)
grid()
p <- as(e, 'SpatialPolygons')
crs(p) <- crs(r)
p$ID=j
p <- SpatialPolygonsDataFrame(p,p#data)
zonal.mtx[i,j] <- zonal.stats(x=p, y=r, stat=sum, trace=TRUE, plot=TRUE)
#print(zonal.mtx[i,j])
}
}
Note: this plots each portion of the data while calculating zonal stats. I am sure you already know that you can also define your own function for using in zonal.stats rather than sum, mean etc.

Spatial data overlay selection in R

I'm trying to overlay some spatial data from a bigger SpatialPolygonsDataFrame (world size) to a smaller (country size), by doing these:
x <- c("rgdal", "dplyr",'ggplot2')
apply(x, library, character.only = TRUE)
est<-readOGR(dsn='/estados_2010',layer='estados_2010')
est_f<-fortify(est)
est$id<-row.names(est)
est_f<-left_join(est_f,est#data)
zon<-readOGR(dsn='/Zonas Homogeneas/gyga_ed_poly.shp',layer='gyga_ed_poly')
zon_f<-fortify(zon)
zon$id<-row.names(zon)
zon_f<-left_join(zon_f,zon#data)
t<-ggplot()+geom_polygon(data=zon_f,aes(x=long,y=lat,group=group,fill=GRID_CODE))
t+geom_polygon(data=est_f,aes(x=long,y=lat,group=group),fill=NA,color='red')+coord_fixed(xlim=est_f$long,ylim=est_f$lat,1)
Which is resulting in this:
I'm want to select only what is being plotted inside the polygon with the red lines.
If someone could help me with this issue, I'll appreciate
PS.: For those who want to reproduce the example completely by yourselves, the files are available in the links above to my google drive:
https://drive.google.com/open?id=0B6XKeXRlyyTDakx2cmJORlZqNUE
Thanks in advance.
Since you are using polygons to display the raster values, you can use a spatial selection via [ like in this reproducible example:
library(raster)
library(rgdal)
bra <- getData("GADM", country = "BRA", level = 1)
r <- getData("worldclim", res = 10, var = "bio")
r <- r[[1]]
r <- crop(r, bra)
r <- rasterToPolygons(r)
# bra and raster (now as polygons) have to have the same projection, thusly reproject!
bra <- spTransform(bra, CRSobj = proj4string(r))
here comes the magic!!
r <- r[bra, ]
let's look at the results:
library(ggplot2)
t <- ggplot()+
geom_polygon(data=r,aes(x=long,y=lat,group=group, fill = rep(r$bio1, each = 5)))
t +
geom_polygon(data=bra,aes(x=long,y=lat,group=group),fill=NA,color='red') + coord_map()

classify raster stack with levelplot (RasterVis)

i have a raster stack of 7 rasters with quite varying data ranges and not all of the rasters adhere to quite the same range. (some are low value ranges, some much higher). Using the levelplot function with the stack, it plots nicely enough, eg:
r <- raster(ncol=10,nrow=10)
r[] <- sample(c(1:3),size=100,replace=T)
r1 <- raster(ncol=10,nrow=10)
r1[] <- sample(c(1:9),size=100,replace=T)
r2 <- raster(ncol=10,nrow=10)
r2[] <- sample(c(5:15),size=100,replace=T)
r3 <- raster(ncol=10,nrow=10)
r3[] <- sample(c(3:35),size=100,replace=T)
s <- stack(r,r1,r2,r3)
breaks <- 7
my.at <- round(seq(min(minValue(s)), max(maxValue(s)), length.out = breaks),digits=2)
myColorkey <- list(at=my.at,height=0.95, width=1, labels=list(at=my.at,cex=1.1))
cols <- (brewer.pal(length(my.at)-1, "YlGnBu"))
levelplot(s,at=my.at,col.regions=cols,colorkey = myColorkey)
As you can see, the images with the lower value data are one colour (Actually in my real data most of the plots are one colour as the data range is dominated by two latter rasters). Using the levelplot function, i would like to reclassify the entire raster stack, teasing out some patterns in the lower value rasters with some classes that i define and simply assign anything over value x (perhaps 10 in the sample data above) to be one colour.
the usual method of ratifying and setting levels will not work for a stack and any workaround i have tried (using a matrix and reclassify) will not force more levels than there are classes for a raster
this is my workaround, using the standard legend, but i'd like to use ratify etc if possible;
# using s from above
m <- c(0,1,1, 1,3,2, 3,6,3, 6,10,4, 10,35,5)
mat <- matrix(m, ncol=3, byrow=TRUE)
src <- reclassify(s, mat)
breaks <- nrow(mat)
my.at <- (0:breaks)
myColorkey <- list(at=my.at,height=0.95, width=1, labels=list(at=my.at+0.5,labels=c("0-1","1-3","3-6","6-10","10-35"),cex=1.1))
cols <- (brewer.pal(length(my.at)-1, "YlGnBu"))
levelplot(src,at=my.at,col.regions=cols,colorkey = myColorkey)

overlap points(or symbols) in a raster with levelplot

I would like to ask some help for plotting a matrix(converted to raster) and overlay with symbols another one. For that, I was trying to use layer (and sp.points), as in several examples that I have read...but I am not very familiar with that and I am missing something. This would be the main idea. I will put a reproducible example (since the real data are more complex).
#Create 1 matrix
m1 <- matrix(runif(100),nrow=10,ncol=20)
#create 2 matrix
m2 <- matrix(1:4,nrow=10,ncol=20)
#Convert to raster
M1<- stack(raster(m1))
#plot
p<-levelplot(M1, margin=FALSE)
#For the second matrix
xy<-melt(m2)
#Add the layer
p +layer(sp.points(xy, pch=1:4)
I am aware that this is wrong..but I don't know how to plot it...
Any suggestion will be appreciated.
Thanks in advance!
Here is a couple of ideas/alternatives that might be of use:
m1 <- matrix(runif(100),nrow=10,ncol=20)
m2 <- matrix(1:4,nrow=10,ncol=20)
library(raster)
M1 <- raster(m1)
M2 <- raster(m2)
plot(M1)
text(M2)
pts <- cbind(xyFromCell(M1, 1:ncell(M1)), value=as.vector(t(m2)))
plot(M1)
cols=rainbow(4)[pts[,3]]
points(pts)
points(pts, col=cols, pch=20)
xy <- SpatialPoints(pts[,1:2])
library(rasterVis)
p <-levelplot(M1, margin=FALSE)
p + layer(sp.points(xy, pch=1:4))
spplot(M1, sp.layout = list("sp.points", xy, pch=1:4))

Resources