How to plot a extracted raster in proper xy coordinates? - r

I have a ndvi raster. I had to extract the values using a threshold conditon.When I plot the graph of the extracted raster, the x y coordinated are not lat long.
I have tried the ggplot() , also the used rastertopoints and rasterfromXYZ to plot the raster but in vain.
The code is below.
Unable to plot s. xy coordiantes are not lat long.
library(raster)
library(rgdal)
raster <- ("D:/Project/ndvisoybean.tif")
plot(ndvi)
ndvi[is.na(ndvi)] <-0
s <- ndvi[ndvi#data#values<maxValue(ndvi) & ndvi#data#values>0.3*maxValue(ndvi)]
I want a graph of the extracted raster s with proper lat long coordinates in x y.

As fa as I know there is no appropriate case to plot lon/lat xy coordinate map if the raster is not WGS84 projection.
One way is that converting raster layer to WGS84 projection.So that the plot coordiante is lon/lat. It is only appreciate for small map or world map.
The other way is using coord_map function in ggplot.But the import data must be lon/lat dataframe rather than ohter projection coordinate. So it is low efficiency to plot map. More serous it is very slow when converting data.frame point coordinate to another. this way is only suitable for small width/height raster. Code example:
Primaly you should convert your raster to WGS84 coordiante.
df=rasterToPoint(raster_WGS84)
ggplot(df, aes(y=lon, x=lat, color=values)) +
geom_point(size=2, shape=15) +
theme() +
scale_color_distiller(palette='Spectral') +
coord_map('lambert', lat0=30, lat1=65, xlim=c(-20, 39), ylim=c(19, 75))
Summary: If your raster is projected coordinate,such as Albers,lambert rather than lon/lat WGS84 coordiate, it is inconvenient to plot a map with lon/lat xy coodiate.

Related

geom_sf does not use geometry coordinates in axes but plots correct shape of polygon?

My overall aim is to combine multiple shape files (polygons of river sub-basins from within a large river basin) into one file and plot as a map. This new combined file will later combine with variable data e.g.(rainfall) and plot by aes().
My problem is:
ggplot()+geom_sf() plots the correct shapes of the polygons but doesn't have the correct co-ordinates on the axes - it doesn't use the values given in the geometry column on the axes.
My thoughts on what is wrong, but I'm not sure how to correct:
The shape file read in has geometry in 'long' 'lat' (crs= 4326) but the crs is saying the coordinates are in UTM Zone 48N WGS84 (crs=32648). If I try and force the crs to 4326 the coordinate values change as if the conversion formula is trying to correct them.
geom_sf and coord_sf are doing something that I don't understand!
.
library(sp)
library(raster)
library(ggplot2)
library(sf)
library(ggsf)
library(rgdal)
library(plyr)
library(dplyr)
library(purrr)
setwd("/Users/.../Sub_Basin_Outlines_withSdata/")
list.files('/Users/.../Sub_Basin_Outlines_withSdata/', pattern='\\.shp$')
Read in individual polygon shape files from folder. Combine with ID.
bangsai <- st_read("./without_S_data/", "Nam Bang Sai")
BasinID <- "BGS"
bangsai <- cbind(bangsai,BasinID)
ing <- st_read("./without_S_data/", "Nam Ing Outline")
BasinID <- "ING"
The two individual shape files import as simple features, see image of R code
Combine the individual sub-basin polygon shape files into one shapefile with multiple features.
all_sub_basins <- rbind(bangsai,ing)
The image shows the values of the coordinates of the polygons/features in all_sub_basins$geometry. They are long lat format yet the proj4sting suggests UTM?
Plot the all_sub_basins simple feature shapefile in ggplot
subbasins <- ggplot()+
geom_sf(data=all_sub_basins, colour="red", fill=NA)
subbasins
The result is a correctly plotted shape file with multiple features (there are more polygons in this image than read in above). However the axes are incorrect (nonsense values) and are not plotting the same values as in the geometry field.
If I add in coord_sf and confirm the crs:
subbasins <- ggplot() +
geom_sf(data=all_sub_basins, colour="red", fill=NA)
coord_sf(datum=st_crs(32648), xlim = c(94,110), ylim = c(9,34))
subbasins
Then I get the Correct axes values but not as coordinates with N and E. It seems as if the geometry isn't recognised as coordinates, just as forced numbers?
I don't mind if the coordinates are UTM Zone 48N or lat long. Could I fix it in any of these ways? If so, how do I achieve that?
Change the shape file crs without changing the values in the geometry column so geom_sf would know to plot the correct axes text.
Extract the geometry from the shape file into a two column .csv file with long and lat columns. Convert csv into a sf and create my own shape file with correct crs.
Last resort, leave the plot as it is and replace new axes text manually.
Any help is much appreciated!

Is ggplot map spatial raster/grid so slow while using coord_map to convert projection?

The raster data contianing projection wgs84 whose coordinates is lon/lat degree. If I want to map local area meeting suitable projection such as albers. main code as follows:
ras <- raster('r2008-03.tif')
ras_mtx <- rasterToPoints(ras_aea)
ras_df <- as.data.frame(ras_mtx)
colnames(ras_df) <- c('lon','lat','val')
basemap <- ggplot(data=ras_df,aes(x=lon,y=lat,fill=val))+
geom_tile()+
borders('world',xlim=range(ras_df$lon),ylim=range(ras_df$lat),
colour='black')+
coord_map(projection='albers',lat0=25,lat1=47)
It takes a long time (>10min) on mapping a small raster (260*400 resolution). The step coord_map for tranforming each grid point is slow. I think the input data.frame of ggplot reduce the efficiency of projection transform.
Why not use matrix to mapping grid like python basemap?
So I convert raster projection firstly ,then map it. Now the xy coordinate unit is meter. How to convert the xy to lon/lat degree is another problem?
ras_aea <- projectRaster(ras,crs='+proj=aea +lat_1=25 +lat_2=47 +datum=WGS84')
ras_mtx <- rasterToPoints(ras_aea)
ras_df <- as.data.frame(ras_mtx)
colnames(ras_df) <- c('lon','lat','val')
bm <- ggplot(data=ras_df,aes(x=lon,y=lat,fill=val))+
geom_raster()
First comment #Z.Lin has illuminated that the coord_map is actully slow rather than code error. Therefore I should tranform raster projection before mapping. So my purpose is that change the geographic xy coordinate label(unit meter) to lon/lat (as upper fig).

Can I clip an area around a shapefile in R by specifying the coordinates?

I have a map of landcover data in R and want to clip a circle of specific area, say 20km, and extract the resultant circular shapefile.
# read in the shape file, assign the CRS and plot it
area <- readShapePoly("Corrine Land Use ITM Projection - Copy.shp", proj4string = CRS("+init=epsg:2157"))
plot(area, xlim = c(560000,600000), ylim = c(530000,580000), axes=TRUE)
# create a dataframe of the location where the buffer should be made and plot it
locations<-data.frame(latitude=584503.3,longitude = 560164.5)
points(locations, bg='tomato2', pch=21, cex=3)
Do I need to change my points into a coordinate system first before I do this?
The shape file is the Corine Landcover 2012 - National http://gis.epa.ie/GetData/Download
Thanks
Your polygons
area <- shapefile("Corrine Land Use ITM Projection - Copy.shp")
You can create a circle (or multiple circles) like this:
library(dismo)
p <- polygons(circles(cbind(0,0), sqrt(20000 / pi), lonlat=FALSE, dissolve=FALSE))
crs(p) <- crs(area)
Intersect
int <- crop(area, p)
Write
shapefile(int, 'landcover_circle.shp')
#Manassa: I believe you will need to ensure the shapefile and raster are in the same projection before you clip, then you can use the crop function in the raster library. Please note, the output will be a clipped raster, not a shapefile as stated in your original question.
# Reproject shapefile to same projection as the raster
#shp = shapefile
#r = raster
library(rdgal)
shp.reproject <- spTransform(shp, crs(r))
#crop raster with polygon
library(raster)
r.crop <- crop(r, shp.reproject)

How can I add a lat-long grid to a projected map?

EDIT: question really pertains to how one can add lat/long gridlines to a projected map. I changed title to match.
I have some layers in geographic coords. I want to plot them in LCC projection, but have a geographic (lat/long) grid. From mapproj I can use map.grid() to add a grid, with the limits set by the lim argument. It takes a vector or a range object:
a vector of 4 numbers specifying limits: c(lon.low, lon.high, lat.low,
lat.high). lim can also be a list with a component named range, such
as the result of map, from which limits are taken.
I construct my map by clipping a large vector layer with a clipping polygon:
myPoly <- readOGR(dsn=".", layer="myPolygon") # just a shapefile in geographic coords
library(raster) # To convert an 'extent' object to a SpatialPolygons object
cp <- as(extent(146, 149, -39, -37.5), "SpatialPolygons")
proj4string(cp) <- CRS(proj4string(myPoly)) # copy from shapefile
# Transform and plot:
lcc <- CRS("+init=epsg:3111")
myPoly.proj <- spTransform(myPoly, lcc)
cp.proj <- spTransform(cp, lcc) # transform the clip box
myPoly.proj.clip <- gIntersection(myPoly.proj, cp.proj, byid=TRUE)
plot(myPoly.proj.clip)
# Then finally, add a lat/long grid:
map.grid(lim=as.vector(cp.proj#bbox), labels=TRUE)
That last line is not correct, as the #bbox returned is xmin, ymin, xmax, ymax, but needs to be in xmin, xmax, ymin, ymax. There must be a simple solution to all this, but as usual I am lost in the vortex. I could manually create a limits vector, but really?
EDIT: the OP points out rgdal::llgridlines which is a better solution.
You are using context from sp/rgdal which uses a different system to that of mapproj/maps.
Try this (untested):
library(rgdal)
gl <- gridlines(myPoly)
cp.gl <- spTransform(gl, lcc)
plot(cp.gl, add = TRUE)
See ?gridlines for more on using this with labels. I find it works well as long as you stay away from circumpolar maps.

Overlay decimal coordinates (New Jersey) on NAD83 Stateplane polygon in R

I am trying to make a plot with points (decimal coordinates in New Jersey) on polyline shapefile with projection NAD 83 Stateplane (feet) (New Jersey). How can I do it? So far, I could plot the points and the shapefile separately but cannot overlay.
Plotted the shapefile using the following code:
orgListLayers("Counties.shp") # Shows the available layers for the shpaefile "Counties:
shape=readOGR("Counties.shp", layer="Counties") # Load the layer of the shapefile
plot(shape) # Plots the shapefile
Plotted points (vectors are lat1,long1) using the following code after transforming the points into Stateplane in ArcGIS:
dpts <- as.data.frame(cbind(long1,lat1))
plot(dpts2)
How can I overlay these points on the polyline shapefile?
Ultimately, I will have multiple sets of points which I want to plot on the shapefile as circles whose size would be dependent on values associated with the points. e.g. if each point represents a town, I want a bigger circle for a town having higher population.
You didn't provide any data, so this may be a partial answer.
Using the ggplot package it is easy to create layered maps. This map, of universities in NJ, was created with the code snippet that follows. It demonstrates plotting points and boundaries on the same map, and sizing the points based on a datum of the university (here, enrollment).
library(ggplot2)
library(rgdal)
setwd("<directory containing your data and maps")
states <- readOGR(dsn=".",layer="tl_2013_us_state")
nj.map <- states[states$NAME=="New Jersey",]
univ.map <- readOGR(dsn=".",layer="NJ_College_Univ_NAD83njsp")
nj.df <- fortify(nj.map)
univ.df <- univ.map#data
univ.df$ENROLL <- as.numeric(as.character(univ.df$ENROLL))
# create the layers
ggMap <- ggplot(nj.df)
ggMap <- ggMap + geom_path(aes(x=long,y=lat, group=group)) # NJ boundary
ggMap <- ggMap + geom_point(data=univ.df, aes(x=X, y=Y, size=ENROLL),color="red", alpha=0.7)
ggMap <- ggMap + coord_fixed()
ggMap <- ggMap + scale_size_continuous(breaks=c(5000,10000,15000,20000,25000,30000), range=c(0,10))
# render the map
ggMap
The TIGER/Line shapefile of US States was obtained here. The NJ Universities were obtained here.
Explanation:
The call to ggplot(...) defines the NJ map as the default dataset.
The call to geom_path(...) adds a layer to draw the NJ boundary.
The call to geom_point(...) adds a point layer locating the universities, with point size proportional to enrollment.
The call to coord_fixed(...) ensures that the map will not be distorted.
The call to scale_size_continuous(...) establishes breaks for the legend labels.

Resources