Display aerial photographs interactively in R - r

I have taken aerial photographs with a drone and stitched those together into a .geotiff file, using third party software. I would like to add this file as a layer to an interactive leaflet map, e.g. as produced by mapview. I can produce an interactive map, but this only shows data, e.g. digital elevation not the actual photograph.
.geotiff files aren't very freely available, so see this link for an example file from naturalearth: https://www.naturalearthdata.com/downloads/50m-raster-data/50m-cross-blend-hypso/
library(magrittr)
exmpl <- terra::rast(".\\HYP_50M_SR.tif") %>%
raster::brick()
mapview::mapview(exmpl)
I am only interested in showing change over time as documented by repeated aerial photography and not interested in extracting data from the raster image. I have previously only worked with vector data, so please go easy on me if this is not a smart question. I like using mapview for it's simplicity, but base leaflet, tmap or any other interactive, R based solution would be fine by me. Thanks a lot!

I guess you ar looking for the mapview::viewRGB() function.
Please find below a little reprex.
Reprex
library(mapview)
library(magrittr)
exmpl <- terra::rast(".\\HYP_50M_SR.tif") %>%
raster::brick()
plotRGB(exmpl)
mapview::viewRGB(exmpl, r = 1, g = 2, b = 3, quantiles = NULL)
Created on 2022-02-10 by the reprex package (v2.0.1)

Related

Global cartogram in R

I am trying to create a global cartogram using the cartogram package in R. I am trying to use the data from wrld_simpl. What I expect is a cartogram in which the Population ("Pop2005" variable) is plotted. The code I have developed is this:
data(wrld_simpl)
world<-wrld_simpl
world_sf = st_as_sf(world)
world_sf_proj = st_transform(world_sf, crs = 3785)
world_cartogram <- cartogram_cont(world_sf_proj, "POP2005")
plot(world_cartogram)
Nonetheless, this has resulted in the following figure:
Do you know what is wrong with the code? Maybe the CRS? I have tried to use others CRS but I got the following error:
"Error: Using an unprojected map. This function does not give correct centroids and distances for longitude/latitude data:
Use "st_transform()" to transform coordinates to another projection."
Taken from this documentation, it is stated that
The default plot of an sf object is a multi-plot of all attributes, up
to a reasonable maximum
If you want to use the base R plot function, then use st_geometry(your_map) to plot (the geometry) an sf object.
Another possibility (which I don't recommend) is to set plot options to 1 plot maximum (options(sf_max.plot=1)), but this plots the first variable, and it might not be the best idea.
library(sf)
library(spData)
library(cartogram)
library(tidyverse)
world_sf = st_as_sf(world)
world_sf_proj = st_transform(world_sf, crs = 3785)
world_cartogram <- cartogram_cont(world_sf_proj, "pop")
plot(st_geometry(world_cartogram))
Now, sf is particularly well suited with ggplot2 and the tidyverse. In that setting, just use ggplot in combination with geom_sf.
ggplot(world_cartogram) +
geom_sf()

Represent a colored polygon in ggplot2

I am using the statspat package because I am working on spatial patterns.
I would like to do in ggplot and with colors instead of numbers (because it is not too readable),
the following graph, produced with the plot.quadratest function: Polygone
The numbers that interest me for the intensity of the colors are those at the bottom of each box.
The test object contains the following data:
Test object
I have looked at the help of the function, as well as the code of the function but I still cannot manage it.
Ideally I would like my final figure to look like this (maybe not with the same colors haha):
Final object
Thanks in advance for your help.
Please provide a reproducible example in the future.
The package reprex may be very helpful.
To use ggplot2 for this my best bet would be to convert
spatstat objects to sf and do the plotting that way,
but it may take some time. If you are willing to use base
graphics and spatstat you could do something like:
library(spatstat)
# Data (using a built-in dataset):
X <- unmark(chorley)
plot(X, main = "")
# Test:
test <- quadrat.test(X, nx = 4)
# Default plot:
plot(test, main = "")
# Extract the the `quadratcount` object (regions with observed counts):
counts <- attr(test, "quadratcount")
# Convert to `tess` (raw regions with no numbers)
regions <- as.tess(counts)
# Add residuals as marks to the tessellation:
marks(regions) <- test$residuals
# Plot regions with marks as colors:
plot(regions, do.col = TRUE, main = "")

integer(0) when plotting a shapefile and points

I am plotting points over a shapefile and R keeps printing "integer(0)" after it completes the command. It plots fine, which can be seen in this reproducible example (with jarring colors because FUN=had ;-) )
### get Germany as shp
Germany.shp<-getData("GADM", country="DEU",level=1,download=T,path=getwd())
par(mfrow=c(1,2))
plot(Germany.shp, col="magenta", main="plots normally")
### make up some spatial points (yes, the proper cities in Germany)
points.df<-data.frame(name=c("Berlin","Frankfurt","Rostock"),
lat=c(52.5243700,50.1155200,54.0887000), long=c(13.4105300,8.6841700,12.1404900))
coordinates(points.df)=~long+lat ### converts df to spatial df
crs(points.df)<-CRS("+init=epsg:4326") ### defines CRS
points.df<-spTransform(points.df,crs(Germany.shp)) ### project to same CRS as Germany.shp
### plot
plot(Germany.shp, col="magenta", sub="is 0 actually in integer? just asking",main="integer 0",)+
points(points.df,col="blue", pch=16,cex=2.2)
### !!! ### CONSOLE shows integer(0), plots perfectly well though ### !!! ###
I was really worried initially, since I am plotting 35000 points in my actual dataset. So I made up this example to cross-check and the cities are in the right place. However I am using a markdown and have 10-15 plots like this and thus have to manually delete the "integer(0)" console output manually. annoying ;)
There seem to be several solutions.
easiest is to add your plot() to an object:
x<-plot()
Others have suggested wrapping it in invisible() or adjusting markdown settings to results="hide"
But making your plots into objects (imo) allows most flexibility and the opportunity to arrange the objects later so that you can plot them agian!

Mapping my data to a Zip Code area map in R

My data is like this:
ZIPcode Cases longi lati
43613 1 -83.604452 41.704307
44140 1 -81.92148 41.48982
46052 1 -86.470531 40.051603
48009 22 -83.213883 42.544619
48017 6 -83.151815 42.535396
48021 7 -82.946167 42.463894
48025 19 -83.265758 42.523195
I want to get a map similar to this (if you can see it) in R. The outline should be zipcodes and the shading should be according to number of cases, darker as cases increase.
I'm very new to R. Tried a lot of code I found online but can't get what I want. Any help is appreciated. Can this be done in base SAS ?
Thank you!
enter image description here
Definetly you can do it in R, I put together a reprex (reproducible example) for you. Key points:
You need to load into R a .shp file (or .geojson, .gpkg, etc.). That is an actual file with the outline of your map. For ZIPCODES I found a R package, tigris, that does that for you, if not you'll need to load it by yourself.
For handling mapping objects (load, transform, .etc), sf package is your best friend.
For plotting, in this example I used cartography, but you can use several different package, as ggplot2 or tmap.
Last line is that, given your data (and if I didn't get the ZIPCODEs wrong), a map as the one you shown (choropleth map) maybe is not the best options. Have a look here to see other alternatives.
library(sf) #Overall handling of sf objects
library(cartography) #Plotting maps package
#1. Create your data
yourdata <- data.frame(ZCTA5CE10=c("43613", "44140", "46052",
"48009","48017", "48021","48025"),
Cases=c(1,1,1,22,6,7,19)
)
#2. Download a shapefile (shp,gpkg,geojson...)
library(tigris) #For downloading the zipcode map
options(tigris_use_cache = TRUE)
geo <- st_as_sf(zctas(cb = TRUE, starts_with = yourdata$ZCTA5CE10))
#Overall shape of USA states
states <- st_as_sf(states(cb=TRUE))
#For plotting, all the maps should have the same crs
states=st_transform(states,st_crs(geo))
#3. Now Merge your data
yourdata.sf=merge(geo,yourdata)
#4. Plotting
par(mar=c(1,1,1,1))
ghostLayer(yourdata.sf)
plot(st_geometry(states), add=TRUE)
choroLayer(yourdata.sf,
var="Cases",
add=TRUE,
border = NA,
legend.pos = "right",
legend.frame = TRUE)
layoutLayer(title = "Cases by ZIPCODE",
theme = "blue.pal",
scale = FALSE,
sources = "Source; your question on SO",
author = "by dieghernan, 2020"
)
Created on 2020-02-27 by the reprex package (v0.3.0)

Plotting country borders with maptools - R

Following the excelent post from Joe Wheatley (http://joewheatley.net/ncep-global-forecast-system/) I managed to produce a
temperature global map. But, instead of only plotting coastline I've tried to use maptools package to plot country borders.
The problem comes when only eastern hemisphere country borders are plotted. I should be missing something I can't figure out,
still looking for on stackoverflow and google. Hope you can help.
Here is the code I'm using (most coming from Joe's post)
loc=file.path("ftp://ftp.ncep.noaa.gov/pub/data/nccf/com/gfs/prod/gfs.2013052100/gfs.t00z.sfluxgrbf03.grib2")
download.file(loc,"temp.grb",mode="wb")
system("wgrib2 -s temp.grb | grep :TMP: | wgrib2 -i temp.grb -netcdf TMP.nc",intern=T)
system("wgrib2 -s temp.grb | grep :LAND: | wgrib2 -i temp.grb -netcdf temp.nc",intern=T)
library(ncdf)
landFrac <-open.ncdf("LAND.nc")
lon <- get.var.ncdf(landFrac,"longitude")
lat <- get.var.ncdf(landFrac,"latitude")
temp=open.ncdf("TMP.nc")
t2m.mean <- get.var.ncdf(temp,"TMP_2maboveground")
library("fields")
library("sp", lib.loc="/usr/lib/R/site-library")
library("maptools", lib.loc="/usr/lib/R/site-library")
day="DIA"
png(filename="gfs.png",width=1215,height=607,bg="white")
rgb.palette <- colorRampPalette(c("snow1","snow2","snow3","seagreen","orange","firebrick"), space = "rgb")#colors
image.plot(lon,lat,t2m.mean,col=rgb.palette(200),main=as.expression(paste("GFS 24hr Average 2M Temperature",day,"00 UTC",sep="")),axes=T,legend.lab="o C")
data(wrld_simpl)
plot(wrld_simpl, add = TRUE)
dev.off()
and this is the image produced
This is a global map, should I use xlim and ylim in image.plot to extract a region (i.e. Europe)
EDIT: Added url for temp.nc file
http://ubuntuone.com/29DKAeRjUCiCzLblgfSLc9
Any help would be appreciated, thanks
The data set wrld_simpl is aligned on longitudes [-180, 180] but your grid data is clearly [0,360]. Since you have maptools loaded try this to add a modified copy to your plot:
plot(elide(wrld_simpl, shift = c(360, 0)), add = TRUE)
There are other tools to crop and move/combine and recentre data like this, including ?rotate in the package raster. It really depends on what you need.
Another graphics-alternative is to just use "world2" in the maps package
library(maps)
map("world2", add = TRUE)
Either of those will work to finish your plot started above.
Here's another discussion related to this: Fixing maps library data for Pacific centred (0°-360° longitude) display
You can do this:
library(raster)
r <- raster("temp.nc")
r <- rotate(r)
plot(r)

Resources