How to overlay a heat map onto spatial map in R? - r

I am looking for help in creating a heat map of sorts that can overlay a spatial map. I have multiple data points, such as temperature, along coordinates in a river and would like to be able to visualize the change in temperature along the river (for example: higher temperature would be shown as red and lower temperature blue). Is this possible? I've gone through the different heat map questions and can't seem to piece it together.
This code gives the closest representation I think, but I don't know how to adapt it to what I need:
sample <- data.frame(Longitude=c(-1+rnorm(50,0,.5),-2+rnorm(50,0,0.5),-4.5+rnorm(50,0,.5)),
Latitude =c(52+rnorm(50,0,.5),54+rnorm(50,0,0.5),56+rnorm(50,0,.5)))
CanMap <- readOGR(dsn="gadm-CAN-shapefile",layer="gadm36_CAN_2")
map.df <- fortify(CanMap)
ggplot(sample, aes(x=Longitude, y=Latitude)) +
stat_density2d(aes(fill = ..level..), alpha=0.5, geom="polygon")+
geom_point(colour="red")+
geom_path(data=map.df,aes(x=long, y=lat,group=group), colour="grey50")+
scale_fill_gradientn(colours=rev(brewer.pal(7,"Spectral")))+
xlim(-10,+2.5) +
coord_fixed()

Related

Heat Map in ggplot(), getting all the layers plotted

I am making a heat map of flooding incidents in the UK. I am following the example listed here. However, I am using a different base map from the example and it won't show up on the map. For my base map I use shapefiles provided by the UK gov, found here, and named it uk.shp, an sf object. Flooding data is proprietary and I cannot share but the original format is polygon shapefile. I then turn those shapefiles into gridded points so I can plot a continuous heat map, this sf object is named pt.shp.
Here is the the base map, original shapefile, and gridded points overlaid for context. You can see there are many floods here, often laying under the same point. I constructed a grid sf object that repeats a given point and uses flood ID as the unique identifier. Below is an example of the data with proprietary information removed. One possible issue I can think of is st_intersection returned the lat and long of the flooding shapefile (which I set as the mapping aes()) but the point's mapping coords are listed in the geometry column of the data.
However, when I use stat_density2d() with my base map, the continuous plot disappears. Below is my plotting code w/ each mapping iteration.
# base map plots
base <- ggplot()+
geom_sf(data=uk.shp)
# Plot density of the points
ggplot()+
stat_density2d(data=pt.shp, aes(x=long, y=lat, fill = ..density..), geom='tile', contour = F)
# base map shows up w/o density map? But legend exists so it is being mapped...
base +
stat_density2d(data=pt.shp, aes(x=long, y=lat, fill = ..density..), geom='tile', contour = F, alpha = .5) +
viridis::scale_fill_viridis(option='inferno')
Some issues are clear, like the plotting window of the heatmap has different dimensions than the base map. However, my main issues is I can't overlay the two plots and I don't know why.

How to generate a map with density based on value, not amount of points in R?

I am using following data set:
head(trip_3)
TIP LON LAT
1 0 -73.866 40.741
2 10.0 -73.906 40.707
3 1.2 -73.706 40.738
4 2.0 -73.946 40.640
5 0 -73.946 40.625
6 1.5 -73.986 40.602
I was able to generate following map to present points with high and low average tip values:
I have achieved it with following code:
nyc_map + geom_point(data=as.data.frame(trip_3), aes(x=LON, y=LAT, fill=TIP), size=3,
shape=21, alpha=0.6, position="jitter") + scale_fill_continuous(low="white", high="#FF0033")
Now I want to get a map presenting areas (density) with high and low tips but not using points - I want to get something like this:
But it counts amount of points, not bases on TIP value. It would be great to achieve what I have described earlier. It is the code I used:
nyc_map + stat_density2d(aes(x=LON, y=LAT, fill = ..level..), size=3,
bins=10, data=as.data.frame(trip_3), geom="polygon")
How to make stat_density2d rely on TIP, not amount of points?
Try geom_contour. It allows you to specify a third variable as z. geom_contour will draw lines at equal TIP areas like a topographic map.
nyc_map + geom_contour(aes(x=LON, y=LAT, z=TIP, fill=TIP), color="white")
You can also use stat_contour if you want it to shade between the lines.
nyc_map + stat_contour(aes(fill=..level..), geom="polygon", binwidth=250, alpha=.5)
Here's an example. The white lines are drawn by geom_contour. The shading is done by stat_contour.

maps r plot distances with color on these

perhaps you have an idea and could help me. I have following data:
lon.x <- c(11.581981, 13.404954, 9.993682, 7.842104 , 11.741185)
lat.x <- c(48.135125, 52.520007, 53.551085, 47.999008, 48.402880)
lon.y <- c(8.801694, 7.842104 , 11.581981, 13.404954, 7.842104 )
lat.y <- c(53.079296,47.999008, 48.135125, 52.520007, 47.999008)
pred <- c(1,2,3,4,5)
data <- data.frame(cbind(lon.x, lat.x, lon.y, lat.y, pred))
where "lon.x" and "lat.x" are longitude-latitude points of a city and "lon.y" and "lat.y" of another city. So there are pairs of cities.
Now, I would like to make a map in R, with
(1) the direct distances between the x and y coordinates as a line
(2) which will receive a different color based on the variable "pred", this could be red for higher values and blue for lower, or thicker lines with higher values of "pred".
The result should be a simple map, with lines between the cities, that are shaped based on the variable "pred". For instance, the line between the first pair of cities would be thinner, while the last one would be thicker. Is that possible?
I have currently only made to receive a (very complicated) google map of Germany:
library(mapproj)
map <- get_map(location = 'Germany', zoom = 6.2)
ggmap(map)
But I am not sure how to plot points and especially relations between the points that differ based on "pred". Also a very simple map (not so detailed google map) would be best! Any idea? THANKS!
You can use ggplot2 to add lines onto the plot.
library(ggplot2)
library(ggmap)
map <- get_map(location = 'Germany', zoom = 6)
ggmap(map) +
geom_segment(data=data, aes(x=lon.x, xend=lon.y, y=lat.x, yend=lat.y, color=pred), size=2) +
scale_color_continuous(high="red", low="blue")
As for the simpler map, you can download shape files (just the outlines of countries) from www.gadm.org. Level 0 maps are just the country, level 1 have state boundaries, etc. To use one of these, download the file from the website and use this code:
load("DEU_adm0.RData")
gadm <- fortify(gadm)
ggplot(gadm) +
geom_path(aes(x=long, y=lat, group=group)) +
geom_segment(data=data, aes(x=lon.x, xend=lon.y, y=lat.x, yend=lat.y, color=pred), size=2) +
scale_color_continuous(high="red", low="blue")

How to plot a heat map on a spatial map

I am new to spatial data analysis in R and would like to do something easy, I am still having difficulties...
I have a big table with latitudes and longitudes
sample = structure(list(Longitude = c(-0.19117, -0.211708, -0.206458,
-0.173862, -0.156618), Latitude = c(51.489096, 51.520075, 51.525301,
51.482442, 51.495752), Location_Easting_OSGR = c(525680L, 524170L,
524520L, 526900L, 528060L), Location_Northing_OSGR = c(178240L,
181650L, 182240L, 177530L, 179040L)), .Names = c("Longitude",
"Latitude", "Location_Easting_OSGR", "Location_Northing_OSGR"
), row.names = c(NA, -5L), class = c("data.table", "data.frame"
))
I got a map of the UK from GADM (level 2 of UK map).
I would like to be able to
plot points defined by longitude/latitude on the map
build a heat map that shows where the points are more concentrated...
Is it easy ? If not do you have some pointers (only UK please)
Cheers
Is this what you had in mind?
Your sample was too small to demonstrate a heat map, so I created a bigger sample with artificial clusters at (long,lat) = (-1,52), (-2,54) and (-4.5,56). IMO the map would be more informative without the points.
Also, I downloaded the shapefile, not the .Rdata, and imported that. The reason is that you are much more likely to find shapefiles in other projects, and it is easy to import them into R.
setwd("< directory with all your files>")
library(rgdal) # for readOGR(...)
library(ggplot2)
library(RColorBrewer) # for brewer.pal(...)
sample <- data.frame(Longitude=c(-1+rnorm(50,0,.5),-2+rnorm(50,0,0.5),-4.5+rnorm(50,0,.5)),
Latitude =c(52+rnorm(50,0,.5),54+rnorm(50,0,0.5),56+rnorm(50,0,.5)))
UKmap <- readOGR(dsn=".",layer="GBR_adm2")
map.df <- fortify(UKmap)
ggplot(sample, aes(x=Longitude, y=Latitude)) +
stat_density2d(aes(fill = ..level..), alpha=0.5, geom="polygon")+
geom_point(colour="red")+
geom_path(data=map.df,aes(x=long, y=lat,group=group), colour="grey50")+
scale_fill_gradientn(colours=rev(brewer.pal(7,"Spectral")))+
xlim(-10,+2.5) +
coord_fixed()
Explanation:
This approach uses the ggplot package, which allows you to create layers and then render the map. The calls do the following:
ggplot - establish `sample` as the default dataset and define (Longitude,Latitude) as (x,y)
stat_density2d - heat map layer; polygons with fill color based on relative frequency of points
geom_point - the points
geom_path - the map (boundaries of the admin regions)
scale_fill_gradientn - defines which colors to use for the fill
xlim - x-axis limits
coord_fixed - force aspect ratio = 1, so map is not distorted

How to change ggplot legend labels and names with two layers?

I am plotting the longitude and latitude coordinates of two different data frames in São Paulo map using ggmap and ggplot packages and want to label manually each legend layer:
update: I edited my code below to become fully reproducible (I was using the geocode function instead of get_map).
update: I would like to do this without combining the data frames.
require(ggmap)
sp <- get_map('sao paulo', zoom=11, color='bw')
restaurants <- data.frame(lon=c(-46.73147, -46.65389, -46.67610),
lat=c(-23.57462, -23.56360, -23.53748))
suppliers <- data.frame(lon=c(-46.70819,-46.68155, -46.74376),
lat=c(-23.53382, -23.53942, -23.56630))
ggmap(sp)+geom_point(data=restaurants, aes(x=lon, y=lat),color='blue',size=4)+geom_point(data=suppliers, aes(x=lon, y=lat), color='red', size=4)
I have looked to several questions and tried different ways without success. Does anyone know how can I insert legend and label the blue points as restaurants and the red points as suppliers?
Now that your code is reproducible (thanks!):
dat <- rbind(restaurants,suppliers)
dat$grp <- rep(c('Restaurants','Suppliers'),each = 3)
ggmap(sp) +
geom_point(data=dat, aes(x=lon, y=lat,colour = grp),size = 4) +
scale_colour_manual(values = c('red','blue'))

Resources