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.
Related
I am using an excel sheet for data. One column has FIPS numbers for GA counties and the other is labeled Count with numbers 1 - 5. I have made a map with these values using the following code:
library(usmap)
library(ggplot2)
library(rio)
carrierdata <- import("GA Info.xlsx")
plot_usmap( data = carrierdata, values = "Count", "counties", include = c("GA"), color="black") +
labs(title="Georgia")+
scale_fill_continuous(low = "#56B1F7", high = "#132B43", name="Count", label=scales::comma)+
theme(plot.background=element_rect(), legend.position="right")
I've included the picture of the map I get and a sample of the data I am using. Can anyone help me put the actual Count numbers on each county?
Thanks!
Data
The usmap package is a good source for county maps, but the data it contains is in the format of data frames of x, y co-ordinates of county outlines, whereas you need the numbers plotted in the center of the counties. The package doesn't seem to contain the center co-ordinates for each county.
Although it's a bit of a pain, it is worth converting the map into a formal sf data frame format to give better plotting options, including the calculation of the centroid for each county. First, we'll load the necessary packages, get the Georgia data and convert it to sf format:
library(usmap)
library(sf)
library(ggplot2)
d <- us_map("counties")
d <- d[d$abbr == "GA",]
GAc <- lapply(split(d, d$county), function(x) st_polygon(list(cbind(x$x, x$y))))
GA <- st_sfc(GAc, crs = usmap_crs()#projargs)
GA <- st_sf(data.frame(fips = unique(d$fips), county = names(GAc), geometry = GA))
Now, obviously I don't have your numeric data, so I'll have to make some up, equivalent to the data you are importing from Excel. I'll assume your own carrierdata has a column named "fips" and another called "values":
set.seed(69)
carrierdata <- data.frame(fips = GA$fips, values = sample(5, nrow(GA), TRUE))
So now we left_join our imported data to the GA county data:
GA <- dplyr::left_join(GA, carrierdata, by = "fips")
And we can calculate the center point for each county:
GA$centroids <- st_centroid(GA$geometry)
All that's left now is to plot the result:
ggplot(GA) +
geom_sf(aes(fill = values)) +
geom_sf_text(aes(label = values, geometry = centroids), colour = "white")
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'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'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.
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))+