Shading a map with underlying data in Julia - julia

I want to create a map of Germany where each state is shaded according to its gross domestic product. I know how to do this in R (and put the code below). Is there a possibility to do this in Julia in an equally simple way?
library(tidyverse)
library(ggplot2)
library(sf)
shpData = st_read("./geofile.shp")
GDPData <- read.delim("./stateGDP.csv", header=FALSE)
GDPData <- rename(GDPData,StateName=V1,GDP=V2)
GDPData %>%
left_join(shpData) ->mergedData
ggplot(mergedData) + geom_sf(data = mergedData, aes(fill = BIP,geometry=geometry)) + coord_sf(crs = st_crs(mergedData))-> pBIP1

You'd load the Shapefile and use Plots to plot it.
The ideomatic code is something like
using Plots, Shapefile, CSV
shp = Shapefile.shapes(Shapefile.Table("geofile.shp"))
GDPData = CSV.read("stateGDP.csv")
plot(shp, fill_z = GDPData.V2')
Note the ' which transposes the values to a column vector - this will tell Plots to apply the colors to individual polygons.

Related

Crop netcdf files in R

I'm trying to crop a netcdf file with a polygon with stars package from daily netcdf data. I think I have managed to do it and could get this plot
with this script
library(tidyverse)
library(sf)
library(stars)
# Input nc file
nc.file <- "20220301120000-NCEI-L4_GHRSST-SSTblend-AVHRR_OI-GLOB-v02.0-fv02.1.nc"
# read nc data
nc.data <- read_ncdf(nc.file, var="analysed_sst")
# Read mask coordinates
coordenades.poligon <- read_csv("coordenades_poligon.csv")
colnames(coordenades.poligon) <- c("lon","lat")
# Build sf polygon to crop data
polygon <- coordenades.poligon %>%
st_as_sf(coords = c("lon", "lat"), crs = 4326) %>%
summarise(geometry = st_combine(geometry)) %>%
st_cast("POLYGON")
# Crop data
nc.stars.crop <- st_crop(nc.data,polygon)
# plot
ggplot() + geom_stars(data=nc.stars.crop) +
coord_equal() + theme_void() +
scale_x_discrete(expand=c(0,0))+
scale_y_discrete(expand=c(0,0))
Now I would like to combine lon, lat and analysed_sst in a data frame. I managed to extract coordinates with
nc.stars.coords <- as.data.frame(st_coordinates(nc.stars.crop))
But can't find how to get the corresponding sst values to cbind with longitude and latitude. Maybe there are other solutions with ncdf4 package.
Thank you very much for your help
EDIT 1
Link to SST original data (nc file): SST data
EDIT 2
Added head of coordenades_poligons.csv. First columns are longitude and latitude points, third column is the area ID and fourth one denotes the season. These are just the coordinates of a single area filtered by ID and season.
12.5,44.5,Z1,S
2,44.5,Z1,S
0,41.5,Z1,S
4,40,Z1,S
9,40,Z1,S
9,42,Z1,S
0,41.5,Z2,S
I am making assumptions here, because this is not my area of expertise, but you are able to simply transform this into a dataset using the raster-package. This seems to be the way to go, also according to this author.
raster::as.data.frame(nc.stars.crop, xy = TRUE)
At least for me this worked. And then you could transform it back into a simple features object, if you are so inclined with
raster::as.data.frame(nc.stars.crop, xy = TRUE) %>%
sf::st_as_sf(coords = c('lon','lat'))
However, the transformation to lon/lat is not really exact, because it produces point data, whereas the original information is raster data. So there is clearly information that gets lost.
sf::st_as_sf() seems to work out of the box for this, but I am not sure, because I have no way to validate the transformation of the original data. For me the following worked:
read_ncdf('20220301120000-NCEI-L4_GHRSST-SSTblend-AVHRR_OI-GLOB-v02.0-fv02.1.nc', var="analysed_sst") %>%
sf::st_as_sf()
This creates polygons, the size of your initial raster tiles and seems to conserve all necessary information.
Finally, here is a work-around to extracting exactly the data you were plotting. You can access the data that ggplot used, by assigning the ggplot to a variable and then accessing the data layer.
p <- ggplot() + geom_stars(data=nc.stars.crop) +
coord_equal() + theme_void() +
scale_x_discrete(expand=c(0,0))+
scale_y_discrete(expand=c(0,0))
p$layers[[1]]$data

How to combine sf elements (layers) in R

despite having some experience with R, I am much less experienced using R for GIS-like tasks.
I have a shapefile of all communities within Germany and created a new object that only shows the borders of the 16 states of Germany.
gem <- readOGR(path/to/shapefile.shp) # reading shapefile
gemsf <- st_read(path/to/shapefile.shp) # reading shapefile as sf object
f00 <- gUnaryUnion(gem, id = gem#data$SN_L) # SN_L is the column of the various states - this line creates a new sp object with only the states instead of all communities
f002 <- sf::st_as_sf(f00, coords = c("x","y")) # turning the object into an sf object, so graphing with ggplot is easier
To check my work so far I plotted the base data (communities) using
gemsf %>%
ggplot(data = .,) + geom_sf( aes(fill = SN_L)) # fill by state
as well as plot(f002) which creates a plot of the 16 states, while the ggplot-code provides a nice map of Germany by community, with each state filled in a different color.
Now I'd like to overlay this with a second layer that indicates the borders of the states (so if you e.g. plot population density you can still distinguish states easily).
My attempt to do so, I used "standard procedure" and added another layer
ggplot() +
geom_sf(data = gemsf, aes(fill = SN_L)) + # fill by state
geom_sf(data = f002) # since the f002 data frame/sf object ONLY has a geometry column, there is no aes()
results in the following output: https://i.ibb.co/qk9zWRY/ggplot-map-layer.png
So how do I get to add a second layer that only provides the borders and does not cover the actual layer of interest below? In QGIS or ArcGIS, this is common procedure and not a problem, and I'd like to be able to recreate this in R, too.
Thank you very much for your help!
I found a solution which I want to share with everyone.
ggplot() +
geom_sf(data = gemsf_data, aes(fill = log(je_km2))) + # fill by state
geom_sf(data = f002, alpha = 0, color = "black") + # since the f002 data frame/sf object ONLY has a geometry column, there is no aes()
theme_minimal()
The trick was adding "alpha" not in the aes() part, but rather just as shown above.

Putting Values on a County Map in R

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")

R:How to display city level data on map and how to ZOOM it on one specific region of the map

I am using usmap and ggplot to plot population on a map. My data has two columns - population and zipcodes.
Question: How can I display data on city level using the same libraries or if you know of other libraries that can do the job.
Question: I am plotting California map and I want to zoom on LA county and nearby counties.
Below code gives me a nice California map and population as a color.
library(usmap)
library(ggplot2)
usmap::plot_usmap("counties",
include = ("CA") )
plot_usmap(data = data, values = "pop_2015", include = c("CA"), color = "grey") +
theme(legend.position = "right")+scale_fill_gradient(trans = "log10")
The tigris package makes downloading zip code tabulation areas fairly simple. You can download as a simple features dataframe so joining your data by zip code using dplyr functions is fairly easy. Here is a quick example:
library(tigris)
library(dplyr)
library(ggplot2)
df <- zctas(cb = TRUE,
starts_with = c("778"),
class = "sf")
## generate some sample data that
## can be joined to the downloaded data
sample_data <- tibble(zips = df$ZCTA5CE10,
values = rnorm(n = df$ZCTA5CE10))
## left join the sample data to the downloaded data
df <- df %>%
left_join(sample_data,
by = c("ZCTA5CE10" = "zips"))
## plot something
ggplot(df) +
geom_sf(aes(fill = values))

Add cities to a map (ggplot2)

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

Resources