Plotting nb object in ggplot? - r

I would like to plot the outline of UK, along with an nb object that I generated from a spatial points dataframe.
The problem is that the outline of UK takes really, really long to plot --it keeps crashing my Rstudio. This for example, either take really long to load or my Rstudio just stops responding.
library(raster)
UK_gadm <- getData("GADM", country="GB", level=0)
plot(UK_gadm)
So I resorted to using ggplot2 from this solution where I can get the outline of UK like in a fraction of a second with the following commands:
library(ggplot2)
UK <- map_data(map = "world", region = "UK") # changed map to "world"
ggplot(data = UK, aes(x = long, y = lat, group = group)) +
geom_polygon() +
coord_map()
The issue now is that I would like the nb object to be plotting against the backdrop of the outline of UK -- however, this seems only achievable in base R like for example:
plot(orotl.shp, xlim=c(-125, -115), ylim=c(42,47))
plot(orstationc.neighbors.dist, orstationc.loc, add=T, lwd=2, col="blue")
Is there any way I could plot nb objects in ggplot or is there a way for R to plot the outline of UK without crashing my computer with the base R plot function?

Managed to find a fast, simple solution after a whole night of effort. Hope this helps someone else with a similar issue.
Just to elaborate on the goal: plot a neighbours object (nb) against a shapefile. This is to visualise the linkages among certain coordinates. After some googling, I think this can only be done with base R's plot function. The problem however, was loading a country's shapefile (downloaded from official sources/gadm)-- its too big.
To solve this issue, get a more generalised, simple map of the country via the maps package, turn it into a shapefile and then plot it alongside the neighbours object.
Here's the code:
library(spdep)
# get your neighbour object from your spatial points df
rest_neighbours <- dnearneigh(rest_spdf,0,1)
library(maps)
# get boundary of UK
UK_map <- sf::st_as_sf(maps::map(database='world',regions='UK', plot = FALSE, fill = TRUE))
# write to shapefile
st_write(UK_map, 'shapefiles/UK.shp')
# henceforth, we can just call the shapefile
UK <- readOGR('shapefiles/UK.shp')
# plot the boundary and the neighbours
plot(UK)
plot(rest_neighbours, rest_coords, add=T, lwd=2, col="blue")
I did not realise that official boundary files are often really detailed which also means that they are really huge and I'm glad that there's ready-made watered down versions of the maps available in the maps package of r. (Sorry if you already knew -- I'm still learning!)
Hope this helps anyone else!

Related

ggplot2 How to subsetting a value from a DataFrame which have a list of theses?

That's for covid data
I have seen a example code from internet to plot a world map which have a lot of variables. Like name (of the country), confirm (cases), suspect, dead, heal, showRate, and the deadRate
But I only know (by the example) how to plot the confirmed cases, and I want to plot dead toll and the deadRate, but I donĀ“t know how to do it
for work with this code you must install these package:
remotes::install_github("GuangchuangYu/nCov2019")
To get the latest data, you can load it in with get_nCov2019().
library(nCov2019)
x <- get_nCov2019(lang='en')
so... to Getting a plot of the world map is really simple. There are only three lines needed:
require(nCov2019)
x = get_nCov2019(lang='en')
plot(x)
but these code plot the cumulative cases.
If you want to see the all values for all the countries you can use these line:
View(x['global'])
But I want to plot the dead toll instead cumulative cases- How can to do it?
I have seen the code and the information here: link to the URL
For any reason inside that package (I can not see the settings for the map plot), it is always taking the confirmed serie and plotting it. You can do a trick by replacing the values in confirmed cases by those from death rate and then format the plot. Here the code to hack the plot scheme:
library(ggplot2)
library(maps)
library(nCov2019)
#Get data
x <- get_nCov2019(lang='en')
#Trick the variable
x$global$confirm <- as.numeric(trimws(x$global$deadRate))
#Plot
G1 <- plot(x)
#Modify
G1 <- G1+labs(subtitle = 'Death rate')+
theme(legend.title = element_blank())
Output:
You can further customize the plot with other elements present in ggplot2.

How to plot colored circles knowing X/Y coordinates, radius and a continuous 3rd parameter in R

In a telecommunication project I have a data basis of a list of antennas with their XY coordinates, emission radius and frequencies. I would like to represent with circles the covered area of each antennas, with a specific color depending on the frequency.
Ive been looking for libraries, but I'm very new to R and programmation in general, and I don't find any easy and simple ones. What would you recommend ?
Thank you for any help
You can do it with ggplot2 and ggforce package, like this:
# First generate a sample data
data <- data.frame(x=rnorm(50),y=rnorm(50),radius = rnorm(50,sd=0.1),freq = factor(1:5,levels=1:5))
# Load the package
library(ggplot2)
library(ggforce)
# Plot
ggplot(data=data,aes(x0=x,y0=y,col=freq,r=radius)) + geom_circle() +
coord_fixed()

Fortify and tidy (from broom) cause polygons to not be correct

I am attempting to use a map of Lesotho and plot various other data on it. The shapefile I pulled is the ESRI file from this link:
http://www.mapmaker.com/maplibrary/library/stacks/Africa/Lesotho/index.htm
When I import the shapefile via readOGR and then plot it with the base plot function, the polygons are in the appropriate orientation. As soon as I use fortify or tidy, they are no longer in the correct orientation. I have included the code below. Please note I only included the tidy code below, but have also tried with fortify with the same issue.
I have tried specifying the proj4string (which is fine in this shape file) and I tried spTransform, but neither one then has the correct orientation of the districts when I plot with ggplot. I'm not sure what other information to include that might be helpful... I'm in R 3.4.4. Any and all help appreciated!!
s1 <- readOGR(".","LSO_adm1")
summary(s1)
plot(s1) #This is actually what the districts in Lesotho look like
s2 <- tidy(s1)
ggplot()+
geom_polygon(data = s2, aes(x=lat, y=long, group=group), col="black")
#This is then some sort of weird alternative Lesotho

Clip the contour with polygon using ggplot and R

I want to create a contour and then clip the contour by the polygon and only show the contour within the polygon.
Shapefile data can be found here
Csv file can be found here
The code I used is as follows:
library("ggplot2")
library("rgdal")
library("gpclib")
library("maptools")
require(sp)
age2100 <- read.csv("temp.csv",header=TRUE, sep=",")
shape.dir <- "C:/Users/jdbaba/Documents/R working folder/shape" # use your directory name here
lon.shape <- readOGR(shape.dir, layer = "Export_Output_4")
str(lon.shape)
lon.df <- fortify(lon.shape, region = "Id")
p <- ggplot(lon.df, aes(x = long, y = lat, group = group)) +
geom_polygon(colour = "black", fill = "grey80", size = 1) +
theme()
p <- p + geom_point(data=age2100,aes(x=age2100$x,y=age2100$y,group="z"),size=0.1)
p <- p + geom_density2d(colour="red")
p
Here, I have created the map, points and the contour. I don't know whether the code I am using created the contour for variable z or not. If it is not correct can anyone suggest me ?
The sample output that I got is as follows:
Now, I want to clip the contour within the polygon and hide the part of contour that is outside the polygon.
I want to know how to add the labels to the contour and control the contour interval.
Please let me know if my question is not clear.
Thanks
Jdbaba
I can't reproduce your map exactly. The code you provided gives me a map with two sets of contours - one that looks like yours and one that overlaps it in the southern part of the region. I suspect this is an artefact of your group setting. Also, I can see there is an island in the southern part of what I assume is the lake.
I like to clean up and partition my ggplot stuff into bits, since I often find something in an early part of a ggplot call confuses something in a later part. Here's how I would map the region, draw points, and then add a density contour:
map <- function(){
geom_polygon(data=lon.df,aes(x=long,y=lat,group=piece),colour="black",fill="grey80",size=1)
}
points <- function(){
geom_point(data=age2100,aes(x=x,y=y),size=0.1)
}
density <- function(){
geom_density2d(data=age2100,aes(x=x,y=y),colour="red")
}
ggplot()+map() +points() +density()
Which gives this:
Now that's much different to what your contour looks like, and I don't know why. Maybe your group parameter is grouping all the points with the same z?
Anyway, it seems you don't want a density plot, you want a map of your Z values over your area. This is going to need kriging or some other interpolation technique. Forget about ggplot for a while, concentrate on the numbers.
For starters, plot the points coloured by the z value. You should see this:
which at least will give you a good idea of what the correct contour will look like.
Anyway, this is getting into a full-on tutorial..

R Plot Filled Longitude-Latitude Grid Cells on Map

I have a data frame containing a number of (x,y,z) data points, (x,y) is the lower-right coordinate of a longitude-latitude cell of size w (e.g. a 1-degree grid). The z value has been averaged over this cell.
I'd like to plot these points in R so that the entire grid cell is filled with some colour derived from z.
The result would look something like one of these images:
The projection itself (e.g. Lambert conformal conic, equirectangular) isn't important, just the grid cell plotting.
My data is sparse: not every longitude-latitude cell will have data associated with it.
My hope would be a solution similar to
library(maps)
map("state")
grid_points(my_data,c("x","y","z"),0.5)
where 0.5 is the grid resolution above, indicating a 0.5-degree cell.
Any thoughts?
Thanks!
An alternative to using either spplot or image is to use ggplot2. The relevant geometries are geom_raster and geom_tile. The first is supposed to perform better and yield smaller files, and the second is more standard. The following example call:
ggplot(aes(x = x, y = y, fill = value), data = dat_grid) + geom_tile() +
geom_path(data = ant_ggplot)
orginates from this blogpost of mine. In addition, ggplot2 supports a range of projections through the mapproj package, see coord_map for more details.
The following is a working example (provided you've defined YOUR_DATA to have x,y,z columns):
library(ggplot2)
library(maps)
us_states <- map_data("state")
(ggplot(aes(x=x,y=y,fill=z),data=YOUR_DATA) + geom_tile())+geom_polygon(data=us_states,aes(x=long, y=lat, group=group), colour="black", fill="white", alpha=0)
If your data.frame is "x", try this:
library(sp)
coordinates(x) <- c("x", "y", "z")
gridded(x) <- TRUE
image(x, col = terrain.colors(256), useRaster = TRUE)
To get a really exact answer you should provide a sample of your data, hopefully an entire data.frame or the source where you download and the code you used to read it into R.
If the code above fails at the gridded()<- step then it's likely your x and y values don't actually provide a regular grid, which is implied by your plots. If they really are gridded longitude/latitude values and you need to project them to the ones in your image then see the raster package, or more generally the rgdal package.
library(raster)
?projectRaster
library(rgdal)
?project
?spTransform
(The plots look to me like one of the "Albers Equal Area and Lambert Conformal Conic Projections of North America" as shown on this site: http://www.colorado.edu/geography/gcraft/notes/mapproj/mapproj_f.html).
See http://spatialreference.org to get the PROJ.4 string for your projection which you can use in sp or raster.
I tried to do that kind of map recently and ended up using function interp of library akima to intrapolate my z data into a regular grid before plotting (any kind of projections will have to be done prior to the use of interp):
library(akima)
interp(x,y,z,xo=seq(min(x),max(x),by=0.5),yo=seq(min(y),max(y),by=0.5),extrap=FALSE,linear=TRUE) -> xygrid
image(xygrid,breaks=seq(min(z),max(z),length=10), col=1:10)
You can do this:
library(raster)
r <- rasterFromXYZ(xyz)
plot(r)

Resources