R spplot diagrams on the map - r

Hallo everyone can anybody help me to upgrade my code with possibility of insering additional data into my map. This is the code that draw me a map with intensity of migration, and I am trying to add ehtnic information of every region (many small pie charts).
to draw a map
con <- url("http://biogeo.ucdavis.edu/data/gadm2/R/UKR_adm1.RData")
print(load(con))
close(con)
name<-gadm$VARNAME_1
value<-c(4,2,5,2,1,2,4,2,2,4,1,1,1,4,3,3,1,1,3,1,2,4,5,3,4,2,1)
gadm$VARNAME_1<-as.factor(value)
col<- colorRampPalette(c('cadetblue4','cadetblue1','mediumseagreen','tan2','tomato3'))(260)
spplot(gadm, "VARNAME_1", main="Ukraine", scales = list(draw = TRUE), col.regions=col)
sp.label <- function(x, label) {
list("sp.text", coordinates(x), label)
}
NAME.sp.label <- function(x) {
sp.label(x, x$NAME_1)
}
draw.sp.label <- function(x) {
do.call("list", NAME.sp.label(x))
}
spplot(gadm, 'VARNAME_1', sp.layout = draw.sp.label(gadm), col.regions=col,
colorkey = list(labels = list( labels = c("Very low","Low", "Average",
"High","Very high"),
width = 1, cex = 1)))
and this is a part of df, that I am trying to add to that map as pie charts or bar charts, with every latitude (lat) and longitude (long) to locate mu bar or pie charts.
df<-data.frame(region=c('Kiev oblast', 'Donezk oblast'),
rus=c(45,35), ukr=c(65,76), mold=c(11,44),long=c(50.43,48),
lat=c(30.52, 37.82))
i found one example and another but... can't figure out how to use it in ma case.
Hope for your help, thank you.
only that solution i have discovered by now, but it doesn't upgrade my code(((
mapPies( df,nameX="lat", nameY="long", nameZs=c('rus','ukr','mold'),
xlim=c(30,33), ylim=c(44,53), symbolSize = 2)

perhaps this will help:
pieSP The function provide SpatialPolygonsDataFrame depending on few attributes, ready to use for plotGoogleMaps or spplot.
library(plotGoogleMaps)
data(meuse)
coordinates(meuse)<-~x+y
proj4string(meuse) <- CRS('+init=epsg:28992')
pies <- pieSP(meuse,zcol=c('zinc','lead','copper'), max.radius=120)
pies$pie <- rep(c('zinc','lead','copper'),155)
pies$pie2 <- rep(1:3,155)
spplot(pies, 'pie2')

Related

Plotting a raster layer by setting a specific color to a non-central value

I have been trying to plot a raster layer by setting the value 1 to the color white. I looked at many examples but still couldn't construct the colors as I wish. I want contrasting colors for the values below and above 1. I would like them start with a light tone and get darker as they go further from 1. I also posted the figure that I managed to create so far. It looks a bit weird since it is based on made up data. I can't share the real data unfortunately. The best would be to create this using viridis colors, but I don't know how doable it is.
I wonder if anyone has any suggestions?
I got the idea of breakpoints and colors from the following post :https://gis.stackexchange.com/questions/17339/raster-legend-in-r-how-to-colour-specific-values .
I got the shapefile from here : https://gadm.org/download_country.html .
Here is my example:
library(rgdal)
library(raster)
library(sp)
library(sf)
set.seed(123)
proj = "+units=km +proj=utm +zone=37 +ellps=clrk80 +towgs84=-160,-6,-302,0,0,0,0 +no_defs"
map0 = readOGR(dsn = "dataFiles/gadm40_NGA_shp", #https://gadm.org/download_country.html (Nigeria/shapefile)
layer = "gadm40_NGA_0")
map0_trnsfrmd = spTransform(map0,proj)
predRaster <- raster(ncol=400, nrow=400, xmn=-3805.7869, xmx=-2222.120, ymn=562.5405, ymx=1828.165)
res(predRaster) = 5
projection(predRaster) = "+units=km +proj=utm +zone=37 +ellps=clrk80 +towgs84=-160,-6,-302,0,0,0,0 +no_defs"
idx = 1:80201 # index for the cell numbers
val = c(rnorm(50000), rep(1,10201),runif(20000,min=0, max=3))
r = setValues(predRaster, values = val, index=idx) # assign values to the cells
r = raster::mask(crop(r, extent(map0_trnsfrmd)), map0_trnsfrmd, snap = 'out')
below=val[val<1]
above=val[val>1]
min(below)
[1] -4.289319
max(above)
[1] 4.438207
max(below)
[1] 0.9998253
min(above)
[1] 1.000105
breakpoints = c(-4.289319, 0.9998253, 1.000105, 4.438207)
colors = c("red","white","blue")
par(mgp=c(4,1,0), mar=c(5,7,3,1)+0.1)
plot(r,las=1, asp = 1, xlab="Easting", ylab="Northing", axis.args = list(cex.axis=1),
legend.shrink =1,legend.width=2, cex.lab=2, cex.axis=1.5, legend.args = list("title", cex =1),breaks=breakpoints,col=colors)
exampleplot
Please look below on the colors definition. I have removed the shape for clarity.
library(rgdal)
library(raster)
library(sp)
library(sf)
set.seed(123)
predRaster <- raster(ncol=400, nrow=400, xmn=-3805.7869, xmx=-2222.120, ymn=562.5405, ymx=1828.165)
res(predRaster) = 5
projection(predRaster) = "+units=km +proj=utm +zone=37 +ellps=clrk80 +towgs84=-160,-6,-302,0,0,0,0 +no_defs"
idx = 1:80201 # index for the cell numbers
val = c(rnorm(50000), rep(1,10201),runif(20000,min=0, max=3))
r = setValues(predRaster, values = val, index=idx) # assign values to the cells
below=val[val<1]
above=val[val>1]
colors = c(colorRampPalette(c(rgb(1,0,0,1), rgb(1,0,0,0.1)), alpha = TRUE)(19),"white", colorRampPalette(c(rgb(0,0,1,0.1), rgb(0,0,1,1)), alpha = TRUE)(19))
plot(r, col=colors, xlab="Easting", ylab="Northing", axis.args = list(cex.axis=1),
legend.shrink =1,legend.width=2, cex.axis=1.5, legend.args = list("title", cex =1))
You can increase the number of colors on both sides. Please check the help for colorRampPalette() function.
Created on 2022-08-31 by the reprex package (v2.0.1)

How can I make the map of Russia in R without splitting it? The split is happening because of the prime meridian

I am trying to make a Russian map. I have already tried several tips, but nothing is working for me.
Initially, I was trying just to use spplot:
library(rgdal)
gadm= getData('GADM', country = 'RUS', level = 1)
gadm$regions = as.factor(1:83)
spplot(gadm, "regions")
Then I have realised that there is a problem beacause of the prime meridian, so i've tried this:
gadm_new <- spTransform(gadm, CRS("+proj=longlat +lon_wrap=105"))
spplot(gadm_new, "regions")
Result was the same
My last attempt failed as well
proj4.str <- CRS("+init=epsg:3413 +lon_0=105")
gadm.prj <- spTransform(gadm, proj4.str)
spplot(gadm.prj, "regions")
I've turned it upside down somehow
I am desperate for help!
I have figured that out:
library(rgdal)
library(RColorBrewer)
library(raster)
gadm=getData('GADM', country = 'RUS', level = 1)
chukotka=gadm#polygons[[12]]
for (i in 1:length(chukotka#Polygons)) {
polygon_long <- chukotka#Polygons[[i]]#coords[, 1]
if (mean(polygon_long) < 0) {
polygon_long <- 360 + polygon_long
}
chukotka#Polygons[[i]]#coords[, 1] <- polygon_long
}
gadm#polygons[[12]]=chukotka
gadm$regions = as.factor(1:83)
my.palette=brewer.pal(n = 9, name = "OrRd")
spplot(gadm, "regions", xlim=c(15,190), ylim=c(40,83), col.regions = my.palette, cuts = 4, col = "transparent")

Legend in multiple plot in R

According to the comments from others, this post has been separated into several
smaller questions from the previous version of this OP.
In the graph below, will you help me to (Newbie to R)
Custom legends according to the data they represent like filled for variable 1, circle points for variable 2 and line for variable 3 and their colors.
same letter size for the legend and axis-names.
The graph below is produced with the data in pdf device with following layout.
m <- matrix(c(1,2,3,3,4,5),nrow = 3,ncol = 2,byrow = TRUE)
layout(mat = m,heights = c(0.47,0.06,0.47))
par(mar=c(4,4.2,3,4.2))
#Codes for Fig A and B
...
#Margin for legend
par(mar = c(0.2,0.2,0.1,0.1))
# Code for legend
...
#Codes for Fig C and D
...
Using doubleYScale from latticeExtra and the data in the long format (see my previous answer), you can simplify the work:
No need to create a custom layout to superpose many plots
No need to create the legend manually
The idea is to create 2 separates objects and then merge them using doubleYScale. The latter will create the second axes. I hope I get your ploygon idea since it is not very clear why do you invert it in your OP.
library(latticeExtra)
obj1 <- xyplot(Variable~TimeVariable|Type,type='l',
groups=time, scales=list(x=list(relation='free'),
y=list(relation='free')),
auto.key=list(columns = 3,lines = TRUE,points=FALSE) ,
data = subset(dat.l,time !=1))
obj2 <- xyplot(Variable~TimeVariable|Type,
data = subset(dat.l,time ==1),type='l',
scales=list(x=list(alternating=2),
auto.key=list(columns = 3,lines = TRUE,points=FALSE),
y=list(relation='free')),
panel=function(x,y,...){
panel.xyplot(x,y,...)
panel.polygon(x,y,col='violetred4',border=NA,alpha=0.3)
})
doubleYScale(obj1, obj2, add.axis = TRUE,style1 = 0, style2 = 1)
Try the following:
1) For the legend part
The data can be found on https://www.dropbox.com/s/4kgq8tyvuvq22ym/stackfig1_2.csv
The code I used is as follows:
data <- read.csv("stackfig1_2.csv")
library(Hmisc)
label1=c(0,100,200,300)
plot(data$TimeVariable2C,data$Variable2C,axes=FALSE,ylab="",xlab="",xlim=c(0,24),
ylim=c(0,2.4),xaxs="i",yaxs="i",pch=19)
lines(data$TimeVariable3C,data$Variable3C)
axis(2,tick=T,at=seq(0.0,2.4,by=0.6),label= seq(0.0,2.4,by=0.6))
axis(1,tick=T,at=seq(0,24,by=6),label=seq(0,24,by=6))
mtext("(C)",side=1,outer=F,line=-10,adj=0.8)
minor.tick(nx=5,ny=5)
par(new=TRUE)
plot(data$TimeVariable1C,data$Variable1C,axes=FALSE,xlab="",ylab="",type="l",
ylim=c(800,0),xaxs="i",yaxs="i")
axis(3,xlim=c(0,24),tick=TRUE,at= seq(0,24,by=6),label=seq(0,24,by=6),col.axis="violetred4",col="violetred4")
axis(4,tick=TRUE,at= label1,label=label1,col.axis="violetred4",col="violetred4")
polygon(data$TimeVariable1C,data$Variable1C,col='violetred4',border=NA)
legend("top", legend = c("Variable A","Variable B","Variable C"), col = c("black","violetred4","black"),
ncol = 2, lwd =c("","",2),pch=c(19,15,NA),cex=1)
The output is as follows:
2) To make the font size same use the parameter cex and make it same everywhere.

ggplot2 and maps: geom_point and annotation_raster position mismatch

Good day everyone,
Using the code below I can successfully retrieve a raster from Google using ggmap, plot an annotation_raster using ggplot2, and plot site localities as red dots on top of the raster layer. On the plot the positions don't quite match (they should follow the coastline). I know my sites' positions are correct because they plot where they should be when I upload the data onto Google Earth as a KML file.
Suggestions will be appreciated.
This code will run as is... Note that you need a development version of ggplot2, which is available on github. To install:
# install.packages("devtools")
library(devtools)
install_github("ggplot2")
and for the code:
library(ggplot2)
library(ggmap)
library(grDevices)
theme_set(theme_bw())
# Some coordinates of points to plot:
siteLat = c(-22.94414, -22.67119, -29.25241, -30.31181, -32.80670, -33.01054, -32.75833, - 33.36068, -31.81708, -32.09185, -32.31667, -34.13667, -34.05016, -33.91847, -34.13525, -34.12811, -34.10399, -34.16342, -34.41459, -34.58786, -34.83353, -34.37150, -34.40278, -34.17091, -34.08565, -34.04896, -33.98066, -34.02448, -34.20667, -34.05889, -33.97362, -33.99125, -33.28611, -33.02407, -33.01798, -32.99316, -31.09704, -31.05000, -30.91622, -30.70735, -30.28722, -30.27389, -29.86476, -29.54501, -29.49660, -29.28056, -28.80467, -27.42472)
siteLon = c(14.50175, 14.52134, 16.86710, 17.26951, 17.88522, 17.95063, 18.02778, 18.15731, 18.23065, 18.30262, 18.32222, 18.32674, 18.34971, 18.38217, 18.43592, 18.45077, 18.48364, 18.85908, 19.25493, 19.33971, 20.00439, 21.43518, 21.73972, 22.12749, 23.05532, 23.37925, 23.64567, 23.89933, 24.77944, 25.58889, 25.64724, 25.67788, 27.48889, 27.91626, 27.92182, 27.95036, 30.18395, 30.21666, 30.32982, 30.48474, 30.76026, 30.83556, 31.04479, 31.21662, 31.24665, 31.44403, 32.07567, 32.73333)
siteName = c(seq(1:length(siteLon)))
sites <- as.data.frame(cbind(siteLat, siteLon, siteName))
# specify raster's approximate coordinates:
lats = c(-35, -20)
lons = c(10, 35)
SAMap <- GetMap.bbox(lons, lats, maptype = "satellite")
# extract "real" coords of raster:
lonr <- c(SAMap$BBOX$ll[2], SAMap$BBOX$ur[2])
latr <- c(SAMap$BBOX$ll[1], SAMap$BBOX$ur[1])
# extract raster fill data:
h_raster <- as.raster(SAMap$myTile)
# plot using annotation_raster:
g <- ggplot(sites, aes(siteLon, siteLat))
g + annotation_raster(h_raster, lonr[1], lonr[2], latr[1], latr[2]) +
geom_point(aes(x = siteLon, y = siteLat), colour = "red", data = sites) +
scale_x_continuous(limits = lonr) +
scale_y_continuous(limits = latr)
(Sorry, I cannot post an image as I am new here).
Okay, the problem has been resolved thanks to David Kahle. See this post:
https://groups.google.com/forum/?hl=en&fromgroups#!topic/ggplot2/ABffHL3WTpY
AJ

country-labels on spplot()

I'd like to add name-labels for regions on an spplot().
Example:
load(url('http://gadm.org/data/rda/FRA_adm0.RData'))
FR <- gadm
FR <- spChFIDs(FR, paste("FR", rownames(FR), sep = "_"))
load(url('http://gadm.org/data/rda/CHE_adm0.RData'))
SW <- gadm
SW <- spChFIDs(SW, paste("SW", rownames(SW), sep = "_"))
load(url('http://gadm.org/data/rda/DEU_adm0.RData'))
GE <- gadm
GE <- spChFIDs(GE, paste("GE", rownames(GE), sep = "_"))
df <- rbind(FR, SW, GE)
## working
plot(df)
text(getSpPPolygonsLabptSlots(df), labels = c("FR", "SW", "GE"))
## not working
spplot(df[1-2,])
text((getSpPPolygonsLabptSlots(df), labels = c("FR", "SW"))
The second one probably doesn't work because of lattice!?
However, I need the spplot-functionality.
How would I get the labels on the plot?
Standard way of adding some text is using the function ltext of lattice, but the coordinates given there are always absolute. In essence, you can't really rescale the figure after adding the text. Eg :
data(meuse.grid)
gridded(meuse.grid)=~x+y
meuse.grid$g = factor(sample(letters[1:5], 3103, replace=TRUE),levels=letters[1:10])
meuse.grid$f = factor(sample(letters[6:10], 3103, replace=TRUE),levels=letters[1:10])
spplot(meuse.grid, c("f","g"))
ltext(100,200,"Horror")
Produces these figures (before and after scaling)
You can use a custom panel function, using the coordinates within each panel :
myPanel <- function(x,y,xx,yy,labels,...){
panel.xyplot(x,y,...)
ltext(xx,yy,labels)
}
xyplot(1:10 ~ 1:10,data=quakes,panel=myPanel,
xx=(1:5),yy=(1:5)+0.5,labels=letters[1:5])
(run it for yourself to see how it looks)
This trick you can use within the spplot function as well, although you really have to check whatever plotting function you use. In the help files on spplot you find the possible options (polygonsplot, gridplot and pointsplot), so you have to check whether any of them is doing what you want. Continuing with the gridplot above, this becomes :
myPanel <- function(x,y,z,subscripts,xx,yy,labels,...){
panel.gridplot(x,y,z,subscripts,...)
ltext(xx,yy,labels)
}
# I just chose some coordinates
spplot(meuse.grid, c("f","g"),panel=myPanel,xx=180000,yy=331000,label="Hooray")
which gives a rescalable result, where the text is added in each panel :
Thank you, Gavin Simpson!
I finally found a way.
In the hope it helps others in the future, I post my solution:
sp.label <- function(x, label) {
list("sp.text", coordinates(x), label)
}
ISO.sp.label <- function(x) {
sp.label(x, row.names(x["ISO"]))
}
make.ISO.sp.label <- function(x) {
do.call("list", ISO.sp.label(x))
}
spplot(df['ISO'], sp.layout = make.ISO.sp.label(df))

Resources