Is it possible to overlay a scatterplot on map using ggplot? - r

I would like to draw a map of French departements (ie districts in France) and plot points on the map. I use ggplot2 to draw the map but when I want to add points on the map, R returns an error which says that it cannot find 'group'.
library("ggplot2")
library("ggmap")
# load the contour of French departements
wg <- read.csv("data/departements.csv")
metropoles <- c("Paris", "Rennes", "Rouen", "Lille", "Marseille")
geo <- geocode(metropoles)
met <- data.frame(ville = metropoles, geo)
map <- ggplot(data = wg, aes(x = long, y = lat, group = group)) +
geom_polygon() +
scale_x_continuous(limits = c(-7,10)) +
scale_y_continuous(limits = c(40,53)) +
coord_map() +
theme(axis.text = element_blank(), axis.title = element_blank())
map + geom_point(data = met, aes(x = lon, y = lat))
For replication, you can find the raw data here and the R program here

#Roland had the good answer. The problem is that I had defined group as a general argument.
ggplot() +
geom_polygon(data = wg, aes(x = long, y = lat, group = group)) +
scale_x_continuous(limits = c(-7,10)) +
scale_y_continuous(limits = c(40,53)) +
coord_map() +
theme(axis.text = element_blank(), axis.title = element_blank())
geom_point(data = met, aes(x = lon, y = lat))

Related

Ggplot map issue when adding fill

Does anyone have any ideas why this map glitches and how to fix it? I plotted it without my sample size variable and it worked fine. However, as soon as I added the fill all these lines appeared.
And
That's all the code I used:
map <- geojson_read("https://martinjc.github.io/UK-GeoJSON/json/sco/topo_lad.json", what = "sp")
map_fortified <- tidy(spdf, reigion="code")
ggplot() +
geom_polygon(data = map_fortified, aes( x = long, y = lat, group = group), fill="white", color="grey") +
theme_void() +
coord_map()
data2<-read.csv("location.csv", header = TRUE)
head(data2)
data2$id<-as.factor(data2$id)
map_fortified$id<-as.factor(map_fortified$id)
total <- merge(data2,spdf_fortified,by="id")
ggplot() +
geom_polygon(data = total, aes(fill = sample, x = long, y = lat, group = group)) +
theme_void() +
coord_map()

geom_polygon for map with scale_fill_manual is not maintaining order

I have been trying to draw a map for Ethiopia and here is my code in R script. I am using ggplot and for color filling using scale_fill_manual.
ggplot(eth_map_data, aes(x=long, y=lat, group=group))+
geom_polygon(aes(fill=basepovband), size=.2)+
coord_equal()+
scale_fill_manual("Poverty rate", values = brewer.pal(5, "YlOrRd"))+
geom_path(color='black')+
theme(axis.text=element_blank(),axis.ticks=element_blank(),
legend.position = "bottom",
panel.spacing = unit(0,"null"),
plot.margin = rep(unit(0,"null"),4),
axis.ticks.length = unit(0,"null"),
axis.text.margin = unit(0,"null")
)+
with(centroids_1, annotate(geom='text', x=long, y=lat, label=ADM1, size=3, color='black'))+
theme_map()
What I am struggling is that color of the regions for poverty rate should be in order. The map if you look closely you will see that poverty rate at 4-10 interval received deep red color instead of light yellow.
How to resolve this unordered color mapping? Your kind help is appreciated.
You have to set basepovband as a factor and order its levels:
eth_map_data$basepovband <-
factor(eth_map_data$basepovband, levels = c("4-10", "10-15", "15-20", "20-25", "25-30"))
Here is an example:
library(dplyr)
library(ggplot2)
library(RColorBrewer)
# we'll use this dataset
mi_counties <- map_data("county", "michigan") %>%
select(lon = long, lat, group, id = subregion)
mi_counties$basepovband <-
sample(c("4-10", "10-15", "15-20"), size = nrow(mi_counties), replace = TRUE)
mi_counties$basepovband <-
factor(mi_counties$basepovband, levels = c("4-10", "10-15", "15-20"))
# ggplot
ggplot(mi_counties, aes(x = lon, y = lat, group = group)) +
geom_polygon(aes(fill = basepovband), size =.2) +
coord_equal() +
scale_fill_manual("Poverty rate", values = brewer.pal(3, "YlOrRd")) +
geom_path(color = 'black')
Let me put my revised codes that work reasonably well. d1, d2, d3 and d4 are subset of original data (eth_map_data)
geom_polygon(data = d1, aes(x = long, y = lat, group = group, fill = basepovband)) +
geom_polygon(data = d2, aes(x = long, y = lat, group = group, fill = basepovband)) +
geom_polygon(data = d3, aes(x = long, y = lat, group = group, fill = basepovband))+
geom_polygon(data = d4, aes(x = long, y = lat, group = group, fill = basepovband))+
scale_fill_manual('Poverty rate', values=cols.bef)+
geom_path(color='black')+
theme(axis.text=element_blank(),axis.ticks=element_blank(),
legend.position = "bottom",
panel.margin = unit(0,"null"),
plot.margin = rep(unit(0,"null"),4),
axis.ticks.length = unit(0,"null"),
axis.ticks.margin = unit(0,"null")
)+
with(centroids_1, annotate(geom='text', x=long, y=lat, label=ADM1_base, size=3, color='black'))+
theme_map()```
[1]: https://i.stack.imgur.com/fYcAZ.png
Two problems/issues still exist:
- geom_path is not working, so no boundary of regions is showing
- intervals are not in order. If you look at the map, you will see 5-10 is showing last in the legend, even though I have converted the variable into factor with proper levels and labels. I had to hard code with colors.
Any comments are welcome.

Change fill colour of polygon with ggplot2

I have a simple question which I've asked myself many times already. When I am plotting one or more polygons in R using ggplot2, how can I actually change the filling colour? I do not only want to change the outline of the polygon, but the whole thing.
In my first simple plots (ea_map and hb_map) it works fine to assign the colours "yellow" and "purple", however in my final plot "ea_hb_map" (which I've pictured below), the colours are set back to default.
ea <- readOGR("C:/Users/BASELINE/Eastern Arctic/Summer/2010_EA_S/cis_SGRDREA_20100628_pl_a.shp")
hb <- readOGR("C:/Users/BASELINE/Hudson Bay/Summer/2010_HB_S/cis_SGRDRHB_20100628_pl_a.shp")
ea_map <- ggplot() +
geom_polygon(data=ea, aes(x = long, y = lat, group = group), fill = "red")
plot(ea_map)
hb_map <- ggplot() +
geom_polygon(data=hb, aes(x = long, y = lat, group = group), fill = "purple")
plot(hb_map)
ea_df <- tidy(ea)
hb_df <- tidy(hb)
eastern_arctic_map <- ea_map +
geom_sf(data=world, fill = "antiquewhite1") +
coord_sf(xlim = c(-115, -50), ylim = c(50,83), expand = FALSE)+
scale_y_continuous(breaks = c(50, 60, 70, 80)) +
scale_x_continuous(breaks = c(-50, -70, -90, -110)) +
geom_polygon(data = ea_df, aes(x=long, y=lat, group=group, fill="Eastern Arctic"), alpha=0.4) +
labs(fill = "",
x = "lon",
y = "lat") +
theme_grey(base_size = 9) +
theme(legend.key.size = unit(0.8,"line"))
print(eastern_arctic_map)
ea_hb_map <- eastern_arctic_map +
geom_polygon(data=hb_df, aes(x = long, y = lat, group = group, fill = "Hudson Bay"), alpha=0.4)
print(ea_hb_map)

How do I combine a raster dataframe with a shapefile to create a map of species richness?

I want to plot the raster plot/dataframe on top of the shapefile but I keep getting various errors depending on how I write the code.
I've tried using a + with the finished objects, landmap+critmapped, I've tried adding the codes together and plotting both as data but that didn't work:
I've tried the following, as well as other things...
Thank you for any help/direction.
critmapped<-ggplot(df, aes(x, y, fill = layer)) +
geom_raster() +
scale_fill_viridis_c(na.value = "white") +
labs(fill = "Count") +
theme_minimal() + ggplot() + geom_path(data = land_df, aes(x = long, y = lat, group = group), color = 'black', fill = 'green')
#Error: Don't know how to add ggplot() to a plot
critmapped+landmap2
#Error: Don't know how to add landmap2 to a plot
#The shapefile code
require(rgdal)
land <- readOGR(dsn = "C:/Users/tjef631/Desktop/R Stats/Data/NE_10m_full",
layer = "ne_10m_land")
land_df<-fortify(land)
names(land_df)
landmap<-ggplot() + geom_path(data = land_df, aes(x = long, y = lat, group
= group),
color = 'black', fill = 'green')
landmap
#the raster/dataframe code
critmapped<-ggplot(df, aes(x, y, fill = layer)) +
geom_raster() +
scale_fill_viridis_c(na.value = "white") +
labs(fill = "Count") +
theme_minimal()
critmapped

how to plot rivers efficiently?

I came up with a way to plot rivers using geom_path. I do not know if there is a better way. I had to split the dataframe into hundreds of "rivers". So it is very slow. Any ideas?
world_map <- map_data('world')
system("wget https://sites.google.com/site/joabelb/Home/PrincRiosBrazil.zip")
system("unzip -o PrincRiosBrazil.zip")
library(rgdal)
shapeHid <- readOGR(dsn = ".", layer = "PrincipaisRiosDoBrasil")
shapeHid#data$id = rownames(shapeHid#data)
library(ggplot2)
shapeHid.points = fortify(shapeHid, region="id")#
shapeHid.df = merge(shapeHid.points, shapeHid#data, by="id", all=F)
listofrivers<-split(shapeHid.df, shapeHid.df$id)
myMap3 <- ggplot() +
lapply(listofrivers, function(x) geom_path(data=x, aes(x=long, y=lat), color="gray70", linetype=1)) +
geom_map(data = world_map, map = world_map, aes(map_id = region),
color = 'black', fill = NA, linetype=2) +
theme(panel.border = element_rect(fill = NA, colour = "black"))+
theme(axis.title=element_blank())+
scale_y_continuous(limits=c(-15,6),expand=c(0,0))+
scale_x_continuous(limits=c(-76,-55),expand=c(0,0))
myMap3
If you routinely work with shapefiles, geom_path and geom_polygon gives everything you need. In recent versions, ggplot deals directly with spatial objects, so there's no need to use fortify and merge (probably the step taking more time in your code). Here's an example using the shapefile of federative units of Brazil from IBGE as base map:
shapeUFs <- readOGR('.', 'BRUFE250GC_SIR')
shapeHid <- readOGR('.', 'PrincipaisRiosDoBrasil')
ggplot(shapeUFs, aes(long, lat, group = group)) +
geom_polygon(fill = 'gray90', color = 'black') +
geom_path(data = shapeHid, color = 'steelblue2') +
coord_map() + theme_void()
Performance will be affected by the size of your shapes (determined by number of features and level of details) more than the geometry you're using in ggplot. You can use rgeos::gSimplify to reduce the number of vertices in a spatial polygon/lines object. You can also plot points directly over the map:
# Simplifying the geometry of the federative units
shapeUFs.s <- rgeos::gSimplify(shapeUFs, .05, TRUE)
# Storing map in an object
riversMap <- ggplot(shapeUFs.s, aes(long, lat)) +
geom_polygon(aes(group = group), fill = 'gray90', color = 'black') +
geom_path(data = shapeHid, aes(group = group), color = 'steelblue2') +
coord_map() + theme_void()
# Sampling 20 cities in Brazil
brMunics <- read.csv('https://raw.githubusercontent.com/kelvins/Municipios-Brasileiros/master/Municipios_Brasileiros.csv')
Munics <- brMunics[sample(nrow(brMunics), 20), ]
# Plotting points over the map
riversMap + geom_point(data = Munics, aes(Longitude, Latitude), color = 'red')
# If your data already have the coordinates named 'lat' and 'long',
# you can skip aes(Longitude, Latitude):
names(Munics)[6:7] <- c('lat','long')
riversMap + geom_point(data = Munics, color = 'red')
I would do the following:
library(sf)
library(ggplot2)
world_map <- map_data('world')
sdf <- read_sf("PrincipaisRiosDoBrasil.shp")
myMap3 <- ggplot() +
geom_map(data = world_map, map = world_map, aes(map_id = region), color = 'black', fill = NA, linetype=2) +
geom_sf(data = sdf)+
theme(panel.border = element_rect(fill = NA, colour = "black"))+
theme(axis.title=element_blank())+
scale_y_continuous(limits=c(-15,6),expand=c(0,0))+
scale_x_continuous(limits=c(-76,-55),expand=c(0,0))
myMap3
You'll need to update ggplot2 to 3.0.0 for geom_sf.

Resources