I've got a shapefile (SpatialLinesDataFrame) containing all streets in cologne, which can be downloaded from here. I merged this #data with data from an external source. How can i plot these streets (if possible on an google map using ggmaps), so that every street has a different colour (or thickness), depending on its individual value?
So far, i have done this:
shapefile <- readOGR(shapfile, "Strasse", stringsAsFactors=FALSE,
encoding="latin-9")
shp <- spTransform(shapefile, CRS("+proj=longlat +datum=WGS84"))
at this point i add another column to the shp#data data frame, which contains a certain value for each street. Then I fortifiy the the shapefile so it can be plotted using ggplot:
shp$id <- rownames(shp#data)
shp.df <- as.data.frame(shp)
data_fort <- fortify(shp, region = "id")
data_merged <- join(data_fort, shp.df, by="id")
When i use geom_lines, the lines do not look good and are not easy to identify:
ggplot(data_merged, aes(x=long, y=lat,
group=group,
colour=values)) +
geom_line()
Here i saw that one could transform the shapefile so that geom_segement (or in this case a modified function "geom_segment2") can be used, but then would loose my the street specific values.
So this code grabs the 100 longest roads from your shapefile, randomly assigns "values" on (1,10), and plots that with color based on value, on top of a google raster image of Cologne.
library(ggplot2)
library(ggmap) # for ggmap(...) and get_map(...)
library(rgdal) # for readOGR(...)
library(plyr) # for join(...)
set.seed(1) # for reproducible example
setwd(" <directory with your shapefiles> ")
spl <- readOGR(dsn=".", "Strasse", encoding="latin-9")
spl <- spl[spl$SHAPE_LEN %in% tail(sort(spl$SHAPE_LEN),100),]
shp <- spTransform(spl, CRS("+proj=longlat +datum=WGS84"))
shp.df <- data.frame(id=rownames(shp#data),
values=sample(1:10,length(shp),replace=T),
shp#data, stringsAsFactors=F)
data_fort <- fortify(shp)
data_merged <- join(data_fort, shp.df, by="id")
ggmap(get_map(unlist(geocode("Cologne")),zoom=11))+
geom_path(data=data_merged,size=1,
aes(x=long,y=lat,group=group,color=factor(values)))+
labs(x="",y="")+
theme(axis.text=element_blank(),axis.ticks=element_blank())
It is possible to make the ggmap(...) call simpler using, e.g.,
ggmap(get_map("Cologne"))
but there's a problem: the zoom=... argument is interpreted differently and I wasn't able to zoom the map sufficiently.
Related
I have a dataframe with three columns: city_name, longitude, latitude. Using ggplot I am attempting to visualize the data using longitude and latitude as coordinates, which represent the given city. I also want to label each point with the city name. Unfortunately the scale isn't quite right, so the points are mapped in the right location.
Example data for dataframe:
city_name <- c("Berlin", "Brussels", "Paris")
longitude <- c("13.405", "4.3517", "2.3522")
latitude <- c("52.52", "50.8503", "48.8566")
df <- data.frame(city_name, longitude, latitude)
I am using ggplot2.
mapWorld <- borders("world", colour="gray50", fill="gray50") # create a layer of borders
ggplot(df, aes(x= longitude, y= latitude, label=Name))+
geom_point() +geom_text(aes(label=city_name),hjust=0, vjust=0) + mapWorld
Current result:
https://imgur.com/K3RvqTm
Expected result would be mapping the coordinates to their correct location.
Thank you all in advance!
The issue seems to stem from the format of your latitude and longitude data. Instead of quoting each coordinate, just refer to them without quotes.
I also recommend leaflet for a wider array of mapping functionality. The code below worked for me:
longitude <- c(13.405, 4.3517, 2.3522)
latitude <- c(52.52, 50.8503, 48.8566)
df <- data.frame(city_name, longitude, latitude)
library(leaflet)
df$longitude<-as.numeric(df$longitude)
df$latitude<-as.numeric(df$latitude)
leaflet() %>%
addTiles()%>%
addMarkers(data=df,lng=~longitude,lat=~latitude) %>%
setView(10,50,zoom=4)
On top of the solution already provided, you might find it helpful to look into the sf package which, in my opinion, makes spatial data much more pleasant to work with. For example you can do:
library(ggrepel)
library(sf)
library(ggplot2)
mapWorld <- borders("world", colour="gray50", fill="gray50") # create a layer of borders
# define data frame ensuring lat and lon are numeric vectors
df <- data.frame(city_name = c("Berlin", "Brussels", "Paris"),
longitude = c(13.405, 4.3517, 2.3522),
latitude = c(52.52, 50.8503, 48.8566))
# convert into an sf object, letting it know the columns we want to use for X and Y
# setting crs = 4326 for lon/lat data and remove = F to stop those columns from being dropped
df_sf <- st_as_sf(df, coords=c('longitude', 'latitude'), crs = 4326, remove = F)
# it plays nicely with ggplot via the 'geom_sf' geom
ggplot(df_sf)+
mapWorld +
geom_sf() +
geom_text_repel(aes(x=longitude, y=latitude,label=city_name))
You'll notice sf objects come with their own 'geometry' column which is recognised and plays nicely with ggplot. One thing to note is be careful with your layer ordering - by adding mapWorld to your ggplot as the last layer, it will appear at the very top of the plot and may cover your points!
I have two netcdf files:
-air quality values (which is the z value or filled value) record for each grid (COL, ROW, LAY, TSTEP)
https://drive.google.com/open?id=1SHnmzV4L1Lqjj9XMdIFQ-nQHOGRpnPhB
-longitude and latitude for each grid
https://drive.google.com/open?id=1dvsh2Ct2--3Bvcux4EXoRm0ntzAVx9OW
I want to make tile plot on a map based on those information.
longitudes and latitudes are not in consist interval.
I have tried extracting part of the data and using ggplot + geom_raster
but the result is not what I expect to have
https://imgur.com/a/2fg33Sp
I also tried used the whole data with geom_tile and geom_polygon, but no tile was ploted
https://imgur.com/a/Zl1N2jV
library(ncdf4)
#path and file
path <- "C:/Users/jhuang/Documents"
file <- "emis_mole_all_20060801_12US1_cmaq_cb05_tx_C25_2006am.ncf"
GRID <- "GRIDCRO2D_Benchmark"
#pollutant interested
poll <- "SO2"
file1 <- sprintf("%s/%s",path, file)
file2 <- sprintf("%s/%s",path, GRID)
ncin <- nc_open(file1)
gridin <- nc_open(file2)
#extract LAT and LON and also SO2 concentrations for each grid
LAT <- ncvar_get(gridin,"LAT")
LON <- ncvar_get(gridin,"LON")
data <- ncvar_get(ncin,poll)
library(ggplot2)
library(maps)
library(ggmap)
#extract first time step
data_1 <- data[,,1]
#organize all data into one data frame
data_2 <- data.frame(cbind(as.vector(LON),as.vector(LAT),as.vector(data_1)))
colnames(data_2) <- c("LON","LAT","POLL")
us_states <- map_data("state")
ggplot(data = data_2, aes(x=LON,y=LAT,fill=POLL)) +
geom_tile()+
geom_polygon(data=us_states,aes(x=long, y=lat, group=group), colour="black", fill="red", alpha=0)
I expect to see https://imgur.com/a/q9uD0gh. I can use NCL to make this plot, just wonder is that possible to make similar plot in R.
I am currently plotting fisheries data and have managed to plot separately polygons shapefile of different provinces in the ocean over the coastal shapefile in ggplot. Also, I've made pie plots, where over a plot of the ocean I have added pies with add.pie (mapplots package).
I am looking for a way to combine them both, overlay them, so in the end I have a coastal shapefile, provinces shapefile and pies on top. How could I do this, does anyone have any ideas?
Thank you very much!
Update: I tried plotting the pies with plotGoogleMaps package in order to export t as a shapefile (which would be an ideal solution), but for some reason when I try to plot them in the end, there are no pies showing... I'm attaching the code, maybe the more experienced of you will know what I did wrong? Thanks again :)
library(sp)
library(plotGoogleMaps)
data<-read.csv("cdis5014_all9sp.csv")
# transform the data then change into large spdf
names(data)[1]<-c("Species")
TotalCatch15 <- aggregate(data$Catch_t, list(data$Species,data$YearC, data$xLon5ctoid, data$yLat5ctoid), sum) # per species, per gear, per year, per cell
names(TotalCatch15)<-c("Species", "Year", "Long", "Lat", "tCatch")
# now subset only years 2000-2014
?subset
last15yrs <- subset(TotalCatch15, Year %in% 2000:2014)
# now average it
AvgCatch15 <- aggregate(last15yrs$tCatch, list(last15yrs$Species, last15yrs$Long, last15yrs$Lat), mean) # per species, per cell!
names(AvgCatch15)<-c("Species", "Long", "Lat", "tCatch")
AvgCatch15$Species
# now try to transform it to make these pies?
# if needed AvgCatch15$Species <- as.character (AvgCatch15$Species)
?spread
pieready <- spread(AvgCatch15, Species, tCatch, fill=0)
summary(pieready)
coordinates(pieready)<-~Long+Lat
proj4string(pieready) <- CRS('+init=epsg:4326') #epsg can also be 32662?
piereadyshp <- spTransform(pieready, CRS("+proj=longlat +datum=WGS84"))
summary(piereadyshp)
?spTransform
#using plotGoogleMaps::pieSP to generate the spatial data.frame for pie-chart
?pieSP
pies1 <- pieSP(pieready, zcol= c("ALB", "BET", "BFT", "BUM", "SAI", "SKJ", "SWO", "WHM", "YFT"), max.radius=500)
pies1$pie=rep(c("ALB", "BET", "BFT", "BUM", "SAI", "SKJ", "SWO", "WHM", "YFT"),345)
# Extract spatial polygon data.frame
library(broom)
library(ggplot2)
names(pies1#polygons)<-pies1$pie
pi1<-tidy(pies1)
ggplot() +
geom_polygon(data=pi1, aes(x=long, y=lat, group=id, fill=.id))
This is where ggplot doesn't show anything. If you need more info about anything I can update it.
Here's a way to get pie chart as spatial polygons. Hopefully you could integrate this along with your shp files with ggmap:
library(sp)
library(plotGoogleMaps)
data(meuse)
coordinates(meuse)<-~x+y
proj4string(meuse) <- CRS('+init=epsg:28992')
df <- spTransform(meuse, CRS("+proj=longlat +datum=WGS84"))
#using plotGoogleMaps::pieSP to generate the spatial data.frame for pie-chart
pies <- pieSP(df,zcol=c('zinc','lead','copper'), max.radius=50)
pies$pie=rep(c('zinc','lead','copper'),155)
# m=plotGoogleMaps(pies, zcol='pie') #run this to show the java-based output of piechart on map
#Extract spatial polygon data.frame
library(broom)
library(ggplot2)
names(pies#polygons)<-pies$pie
pi<-tidy(pies)
ggplot() +
geom_polygon(data=pi, aes(x=long, y=lat, group=id, fill=.id))
I'm struggling with ggplot for days. I want to built a map with the different areas in different colors, and add the names of the cities on it. I manage to plot the map with the areas colored in a different fashion with the following code:
#require
library(plyr)
library(dplyr)
library(rgdal)
library(ggplot2)
library(ggmap)
#open data
data = read.table("region.txt", header=T, sep="\t", quote="", dec=".")
#open shapefile
mapa <- readOGR(dsn=".",layer="DEPARTEMENT")
#merge dataframe/shapefile
mapa#data$id <- rownames(mapa#data)
mapa#data <- join(mapa#data, data, by="ID_GEOFLA")
mapa.df <- fortify(mapa)
mapa.df <- join(mapa.df,mapa#data, by="id")
plotData <- join(mapa.df, data)
#plot
mapfr <- ggplot(plotData) +
aes(long,lat,group=group,fill=area) +
geom_polygon() +
geom_path(color="NA") +
coord_fixed() +
theme_nothing(legend = TRUE)
I then open the dataset containing the names and the long/lat of the cities I want to plot on the created map :
#opendata
points = read.table("cities.txt", header=T, sep="\t", quote="", dec=".")
#add points on the map
mapfr +
geom_point(data = points, aes(x = long, y = lat), color = "black", size = 1)
But my points are totally out of the map. Nevertheless, the coordinates are correct. Any idea what I should change to get my points correctly plotted? I know there is a way to do it with the "maps" package, but I'd like to use ggplot.
My datasets are available here
Just in case somebody struggles with the same issue. Instead of looking for another shapefile with the coordinates in another format, it is possible to convert the actual coordinates with the spTransformcommand from the rgdal package - add this line in the code right after importing the shapefile mapa <- spTransform(mapa, CRS("+proj=longlat +datum=WGS84")) and coordinates will be given in long/lat
I have been trying to draw the county based Choropleth map in R for visualizing my dataset for the State of Arizona.
For plotting the thematic map using the polygon bases data for the county from arizona.edu (Spatial Library) and data is from az.gov
It have the following for plotting the COUNTY polygon-
library(maptools)
library(rgdal)
library(ggplot2)
library(plyr)
county <- readShapePoly(file.choose())
county#data$id <- rownames(county#data)
county.points <- fortify(county, coords="id")
county.df <- join(county.points, county#data, by="id")
ggplot(county.df) + aes(long,lat,group=group, fill="id") +
geom_polygon() +
geom_path(color="white") +
coord_equal() +
scale_fill_brewer("County Arizona")
This code is not giving me any error and also no output.
My Source of Shape file here
Data Source here
I can't speak to why your code is not generating output - there are too many possible reasons - but is this what you are trying to achieve?
Code
library(rgdal)
library(ggplot2)
library(plyr)
library(RColorBrewer)
setwd("< directory with all your files >")
map <- readOGR(dsn=".",layer="ALRIS_tigcounty")
marriages <- read.csv("marriages.2012.csv",header=T,skip=3)
marriages <- marriages[2:16,]
marriages$County <- tolower(gsub(" ","",marriages$County))
marriages$Total <- as.numeric(as.character(marriages$Total))
data <- data.frame(id=rownames(map#data), NAME=map#data$NAME, stringsAsFactors=F)
data <- merge(data,marriages,by.x="NAME",by.y="County",all.x=T)
map.df <- fortify(map)
map.df <- join(map.df,data, by="id")
ggplot(map.df, aes(x=long, y=lat, group=group))+
geom_polygon(aes(fill=Total))+
geom_path(colour="grey50")+
scale_fill_gradientn("2012 Marriages",
colours=rev(brewer.pal(8,"Spectral")),
trans="log",
breaks=c(100,300,1000,3000,10000))+
theme(axis.text=element_blank(),
axis.ticks=element_blank(),
axis.title=element_blank())+
coord_fixed()
Explanation
To generate a choropleth map, ultimately we need to associate polygons with your datum of interest (total marriages by county). This is a three step process: first we associate polygon ID with county name:
data <- data.frame(id=rownames(map#data), NAME=map#data$NAME, stringsAsFactors=F)
Then we associate county name with total marriages:
data <- merge(data,marriages,by.x="NAME",by.y="County",all.x=T)
Then we associate the result with the polygon coordinate data:
map.df <- join(map.df,data, by="id")
Your specific case has a lot of potential traps:
The link you provided was to a pdf - utterly useless. But poking around a bit revealed an Excel file with the same data. Even this file needs cleaning: the data has "," separators, which need to be turned off, and some of the cells have footnotes, which have to be removed. Finally, we have to save as a csv file.
Since we are matching on county name, the names have to match! In the shapefile attributes table, the county names are all lower case, and spaces have been removed (e.g., "Santa Cruz" is "santacruz". So we need to lowercase the county names and remove spaces:
marriages$County <- tolower(gsub(" ","",marriages$County))
The totals column comes in as a factor, which has to be converted to numeric:
marriages$Total <- as.numeric(as.character(marriages$Total))
Your actual data is highly skewed: maricopa county had 23,600 marriages, greenlee had 50. So using a linear color scale is not very informative. Consequently, we use a logarithmic scale:
scale_fill_gradientn("2012 Marriages",
colours=rev(brewer.pal(8,"Spectral")),
trans="log",
breaks=c(100,300,1000,3000,10000))+