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.
Related
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
I am trying to plot out a base map of Illinois by counties.
Libraries I had loaded:
library(ggplot2)
library(maps)
library(ggmap)
library(mapdata)
This is my code:
states <- map_data("state")
IL <- subset(states, region %in% c("illinois"))
counties <- map_data("county")
IL_county <- subset(counties, region == "illinois")
il_base <- ggplot(data = IL, mapping = aes(x = long, y = lat)) +
coord_fixed(1.3) +
geom_polygon(color = "black", fill = NA) +
theme_nothing()
il_base
il_base +
geom_polygon(data = IL_county, fill = NA, color = "black") +
geom_polygon(color = "black", fill = NA)
The il_base plot is fine, it shows a basic outline of the state. However, as soon as I add geom_polygon to this it maps the counties out like this:
And this is NOT what the counties of IL look like. What did I do wrong here?
I solved the problem by modifying the base plot to:
# Add group
il_base <- ggplot(data = IL, mapping = aes(x = long, y = lat, group = group)) +
coord_fixed(1.3) +
geom_polygon(color = "black", fill = NA) +
theme_nothing()
I'm trying to plot the different ways to name a pencil in France on a map with ggplot2. For each of the 96 departments of France, I have one item and a score associated to this item. I have no problem plotting the items according to their departments on a map, but I can't figure out a way to make the colors of each polygons vary according to their associated score. My data is here. The code to produce the map is below:
library(ggplot2)
library(scales)
library(Cairo)
#open data
plotDatafr = read.table("plotDatafr.txt", header=T, sep="\t", quote="", dec=".")
g <- ggplot() +
geom_polygon(data = plotDatafr, aes(x=long, y = lat, group = group, fill=item), alpha=0.8, colour = "black") +
scale_fill_manual(values = c("#009E73", "#F0E442", "#0072B2", "#D55E00"), na.value=NA) +
theme_nothing(legend = TRUE) +
coord_map() #avoid distorsion
ggsave(g, filename = "crayon_euro.png", scale=1) #save for futher use
I tried to use the "scale_fill_distiller" command, but with such command I can only plot the properties of a single item, and I loose their given colors, for example:
g <- ggplot() +
geom_polygon(data = plotDatafr, aes(x = long, y = lat, group = group, fill = score), colour = "black", alpha = 0.8) +
scale_fill_distiller(palette = "Purples", breaks = pretty_breaks(n = 9), labels = percent, direction = 1, "", guide=FALSE) +
guides(fill = guide_legend(reverse = TRUE, override.aes = list(alpha = 1))) +
theme_nothing(legend = TRUE) +
coord_map() #avoid distorsion
ggsave(g, filename = "crayon_euro.png", scale=1) #save for futher use
Does anyone have any idea how I can make the different my polygons shades varying according to their numerical value? I can't figure a way to combine scale_fill_distiller and scale_fill_manual in the same time.
you could use scale_fill_gradient instead to adjust aes(fill) by plotDatafr$score:
#open plotting data
plotDatafr = read.table("plotDatafr.txt", header=T, sep="\t", quote="", dec=".")
# make mapping data object
fr <- map_data("france")
# plot
ggplot(fr, aes(x=long, y = lat, group = group)) +
geom_polygon(data = plotDatafr, aes(fill=score), alpha=0.8, colour = "black") +
scale_fill_gradient(low = "yellow", high = "blue", na.value=NA) +
coord_map()
scale_fill_distiller is designed for discrete data, so you would have to bin plotDatafr$score in some way, before using it.
The answer given by #Haboryme above works perfectly! The trick is to set the alpha with "score" directly in the aes() of geom_polygon, that is to say:
ggplot() + geom_polygon(data = plotDatafr, aes(x = long, y = lat, group = group, fill = item, alpha = score), colour = NA) + scale_fill_manual(values = c("#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7"), name = "", na.value=NA) + coord_map()
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))
I am wondering how to draw a map using get_map and ggmap of any federal country (i.e. a country with provinces and counties). Any country, other than the US would be great. To make it look nice, fill the geom_polygon of counties (any fill), and provinces are empty polygons, only with its contours. So, basically, it is two overlapping ggmaps.
You can get the shapefiles here:
https://www.dropbox.com/s/4nl685t860x1e8r/municipios_br.zip
rm(list = ls())
library(ggplot2)
library(rgdal)
library(ggmap)
# READ SHAPEFILE OF BOUNDARIES
Map <- readShapePoly("municipios_br.shp")
head(as.data.frame(Map))
Map = gBuffer(Map, width=0, byid=TRUE)
MapC <- fortify(Map, region="CODIGO_MUN") # municipalities
MapP <- fortify(Map, region="CODIGO_UF") # state boundaries
MapC$test <- 1
MapP$test <- 1
MapC <- Map[order(MapC$order),]
MapP <- MapP[order(MapP$order),]
The following code produces counties boundaries:
google.map <- get_map(location = 'Brazil', zoom=4,maptype="terrain")
m0 <- ggmap(google.map)
m1 <- m0 + geom_polygon(color = 'grey90', size = .01, aes(x=long, y=lat, group=group, fill=as.factor(test)), data=MapC, alpha=.6)
m1 + guides(fill=FALSE) + scale_fill_manual(values=c("red"))
Now, provinces:
m2 <- m0 + geom_polygon(color = 'grey50', size = .1, aes(x=long, y=lat, group=group, fill=as.factor(test)), data=MapP, alpha=.9)
m2 + guides(fill=FALSE) + scale_fill_manual(values=c(NA))
How to make the two work together?
You could also get your maps from e.g. GADM:
library(raster)
adm1 <- getData('GADM', country='HUN', level=0)
adm2 <- getData('GADM', country='HUN', level=1)
And let us fortify those for ggplot usage:
library(ggplot2)
fadm1 = fortify(adm1)
fadm2 = fortify(adm2)
And add as many layers and geoms as you wish:
ggplot(fadm1, aes(x = long, y = lat, group = group)) + geom_path() +
geom_polygon(data = fadm2, aes(x = long, y = lat),
fill = "green", alpha = 0.5) +
geom_path(data = fadm2, aes(x = long, y = lat), color = "blue") +
theme_bw()
Resulting in:
Update: combining your two layers mentioned in the updated questions
m0 + geom_polygon(size = .01,
aes(x = long, y = lat, group = group, fill = as.factor('red')),
data = MapC,
alpha = .6) +
geom_path(color = 'grey50', size = .1, aes(x = long, y = lat, group = group),
data=MapP, alpha=.9) +
guides(fill=FALSE)