classify raster stack with levelplot (RasterVis) - r

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)

Related

Combining rasters' legends in R language

Sorry for the evidently stupid question I haven't be able to solve, even after googleing for a while. Let's suppose the following situation, where I have two rasters with overlapping but different value ranks.
library(raster)
# A couple of rasters from scratch
r2 <- r1 <- raster(nrows=10, ncols=10)
r1[] <- sample(c(0:99), 100, replace = F)
r2[] <- sample(c(50:149), 100, replace = F)
par(mfrow = c(1,2))
plot(r1)
plot(r2)
How may I create the same plot but with only one legend ranging from 0 to 149, that is, the combined rank of both rasters?
Based on the answer I shared in the previous comment, you can manually set the breaks of the legend and the colors. Then you just need to apply that color ramp to both plots. Here's the code and the plot.
# Adjust plot margins
par(mar=c(2,2,2,5))
# Set manually the breaks
breaks = seq(0,150,25)
pal <- colorRampPalette(c("white","orange","yellow","green","forestgreen"))
plot(r1, breaks=breaks, col = pal(length(breaks)-1))
plot(r2, breaks=breaks, col = pal(length(breaks)-1))

Scaled plotting of multiple pairwise Venn diagrams in R

I want to plot >50 Venn/Euler diagrams of two sets each to scale.
It is necessary that not only the overlap of the two sets and the set size themselves should scale but also the size of the individual diagrams compared to each other.
Since I know of no R package that allows the plotting of >50 pairwise Venn diagrams at the same time, I was planning to plot them first individually (e.g., using eulerr) and then put all of them together using the gridExtra package or something similar.
However, in this way, the size of the individual pairwise diagrams is not comparable:
require(gridExtra)
require(eulerr)
fit1 <- euler(c(A=300, B=500, "A&B"=100))
fit2 <- euler(c(A=40, B=70, "A&B"=30))
grid.arrange(plot(fit1), plot(fit2), nrow=1)
Does anyone know of an R package or a combination of packages that would allow size-appropriate plotting of several pairwise Venn diagrams?
You could try using the widths argument of grid.arrange. You would have to determine the ratio of each of the venn diagrams' totals. In your example, the total size ratio is 800:110, which is 7.27, so if you do grid.arrange(plot(fit1), plot(fit2), ncol = 2, widths = c(7.27, 1)) then fit2 will be much smaller than fit1. The ggarrange() function from ggpubr should work also.
fit1 <- euler(c(A=300, B=500, "A&B"=100))
fit2 <- euler(c(A=40, B=70, "A&B"=30))
tot1 <- 800
tot2 <- 110
ratio_v <- tot1/tot2
grid.arrange(plot(fit1), plot(fit2), ncol = 2, widths = c(ratio_v, 1))
ggpubr:ggarrange(plotlist = list(plot(fit1), plot(fit2)), ncol = 2, widths = c(ratio_v, 1))
Edit: Want the individual pairwise sets to have their own size ratios, instead of everything relative to a global maximum. This is a simple example, but you can write a function to do this automatically for each one. Basically set the maximum number of columns (I just chose 100), and then convert each of your ratios to be out of 100. Make a row for each venn diagram set, then rbind them all into a matrix and use the layout_matrix argument.
### Make fits
fit1 <- euler(c(A=300, B=500, "A&B"=100))
fit2 <- euler(c(A=40, B=70, "A&B"=30))
fit3 <- euler(c(C=100, D=300, "C&D"=50))
fit4 <- euler(c(C=50, D=80, "C&D"=30))
### Assign totals
tot1 <- 800
tot2 <- 110
tot3 <- 400
tot4 <- 130
### Find ratios
ratioAB_v <- round(tot1/tot2)
ratioCD_v <- round(tot3/tot4)
### Convert ratios
smallAB_v <- round(1/ratioAB_v*100)
smallCD_v <- round(1/ratioCD_v*100)
### Make rows
row1_v <- c(rep(1, (100-smallAB_v)), rep(2, smallAB_v))
row2_v <- c(rep(3, (100-smallCD_v)), rep(4, smallCD_v))
### Make matrix
mat <- rbind(row1_v, row2_v)
### Plot
grid.arrange(plot(fit1), plot(fit2), plot(fit3), plot(fit4), layout_matrix = mat)

plotting 3d with akima: z scale is not in accordance with real data

I have a matrix with 3 columns. I want to make a 3d plot to see the relation between these 3 parameters.
I used akima package in R
library(fields)
library(akima)
library(lattice)
data <- read.table("data.txt", header=F)
colnames(data) <- c("A","B","C") ###A would be x, B:y and C:z
reggrid <- interp(data$A,data$B,data$C,linear=T,extrap=F,duplicate="mean")
par(family="arial", cex=1.2)
x.ticks <- round(reggrid$x[seq(1,length(reggrid$x),length=5)],5)
y.ticks <- round(reggrid$y[seq(1,length(reggrid$y),length=5)],5)
wireframe( reggrid$z,
xlab=list("A",rot=-30),
ylab=list("B",rot=35),
zlab=list("C",rot=0),zlim=c(0,1),
scales=list(x=list(labels=x.ticks),
y=list(labels=y.ticks),arrows=F),
col.regions=rainbow(1000),
drape=T,
#shade=T,
colorkey=T,
screen=list(z=-20, x=-60, y=0))
the problem is that, while the real range of C is between 0-1, in the figures it is between 0.5-0.6!
Would you please help me how to solve this issue?

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

ScatterPlot between two rasters, giving color from a third raster

I'm plotting two rasters data, producing the image below.
I'd like to color each point in the graph with a variable taken from a third raster data (with the same bbox, pixel size etc.).
Any ideas from R-Users? This operation is very easy in plotting data from a dataset, but I don’t know about raster…
Here I attach the code (simplified, I think you don't need all the plot parameters e.g. abline, xlab and so on) that produced the image:
plot(mask(raster1, my_mask,maskvalue=0), #first raster, masked by my_mask
mask(raster2, my_mask,maskvalue=0), #second raster, masked by my_mask
col = alpha('black', 0.1), #the current color scheme
)
raster3 #raster with categorical variable,
#that should give the colors to the points in the graph
Thanks a lot!
With the xyplot method defined in
rasterVis
you can use layers of a RasterStack as if they were columns of a
data.frame. Therefore, they can be the components of the formula or
the groups argument.
For example,
library(raster)
library(rasterVis)
f <- system.file("external/test.grd", package="raster")
r <- raster(f)
r2 <- r + 500 * init(r, rnorm)
## categorical variable
r3 <- cut(r, 3)
s <- stack(r, r2, r3)
names(s) <- c('r', 'r2', 'r3')
xyplot(r ~ r2, groups = r3, data = s,
auto.key = list(space = 'right'),
alpha = 1)

Resources