I have some questions about maps/shapefiles. I'm not a expert in R, so, to make it easier do understand what I'm going for, I'll enumerate:
1- Identify each grid on the map, and maybe omit some of these grids.
2- Color each grid by values from a data frame
I just made what i'm trying to make using Photoshop to help to illustrate my goal here
I made this map using the 'intersect' function with a shapefile I got from internet and a grid i made using 'rastertoPolygons' function, but I'm not sure if using a .shp is the best way to get what I want, altough it has been the only way I found to do this, since I got lost trying with ggplot2 options (and I'm very familiar with the package)
Any help or suggestion will be awesome.
Sorry if I made a stupid question and sorry for my bad english.
If you are asking how you can do this in ggplot, you can pretty easily. If not, can you clarify what you are asking?
You can draw the map of Brazil easily, and use your shapefile either directly, or with some adjustments. Since I don't have your shapefile, I'll use one of my own and you can adjust for yourself. I just made two arbitrary boxes, and labelled them with a field called id. Your grouping name may be different.
library(ggplot2)
library(maps)
library(rgdal)
brasilia <- borders("world", regions = "Brazil")
brazil <- ggplot() + brasilia + theme_bw() + xlab("Longitude (decimals)") + ylab("Latitude (decimals)") +
theme(panel.border = element_blank(), panel.grid.major = element_line(colour = "grey80"), panel.grid.minor = element_blank()) +
coord_fixed(1.0)
brazil # You can see just the map of Brazil
Next, import your shapefile using rgdal, which should read all the metadata so you don't have to tell it what projection, etc. Just tell it where it is, and what the shape file name is. See ?readOGR for help.
shapes <- readOGR(dsn = "C:/foo/GIS/Brazil", layer = "brazil_grid")
brazil_shapes <- brazil + geom_path(data = shapes, aes(x = long, y = lat, group = id), color = "red")
brazil_shapes
Filling them with the colors you want may take the most work, creating a table to map your fill levels to the grids. It looks like this answer can point you in the right direction though. R ggplot2 merge with shapefile and csv data to fill polygons
Here's a good overview of mapping in R. http://eriqande.github.io/rep-res-web/lectures/making-maps-with-R.html
Related
I am facing the following problem:
when using the shape file of intercommunal limits in France (which you can download here: https://www.data.gouv.fr/fr/datasets/r/971027a8-3ceb-48c6-97e3-59deaf7e2704), plotting the map is really slow:
library(sf)
library(ggplot2)
epci_france <- read_sf("./epci_shape/EPCI_SHAPEFILE.shp")
ggplot()+
geom_sf(data = test,
aes(geometry = geometry),
color = "black")+
guides(fill = "none")+
theme_void()
I think this is due to the high number of points in the shapefile.
Following comments in here: https://github.com/tidyverse/ggplot2/issues/2655, I tried
sum(rapply(st_geometry(epci_france), nrow))
[1] 1913182
which looks like a lot of points. I am looking for a way to lower this number, i.e. lower the precision of the limits of the geometry. I tried smooth from library(smoothr), but it has the opposite effect: it increases the number of points. I tried to cast it to other formats with st_cast, but it did not work either.
How should I proceed? My objective is to have a simple delimitation of the intercommunal limits to make choropleth maps. Thanks!
I would like to make a map in R that colours in the FAO Fishing Areas according to a data set (in my case, length data of shark species).
I would prefer to do a choropleth map in ggplot but other types of maps are also fine. Worst case scenario a base map of FAO areas that I can add bubbles to. Even just an existing base map of FAO areas would be great. Any suggestions welcome!
I went to this page and clicked through to find this link to retrieve a GeoJSON file:
download.file("http://www.fao.org/fishery/geoserver/fifao/ows?service=WFS&request=GetFeature&version=1.0.0&typeName=fifao:FAO_AREAS_CWP&outputFormat=json", dest="FAO.json")
From here on, I was following this example from the R graph gallery, with a little help from this SO question and these notes:
library(geojsonio)
library(sp)
library(broom)
library(ggplot2)
library(dplyr) ## for joining values to map
spdf <- geojson_read("FAO.json", what = "sp")
At this point, plot(spdf) will bring up a plain (base-R) plot of the regions.
spdf_fortified <- tidy(spdf)
## make up some data to go with ...
fake_fish <- data.frame(id = as.character(1:324), value = rnorm(324))
spdf2 <- spdf_fortified %>% left_join(fake_fish, by = "id")
ggplot() +
geom_polygon(data = spdf2, aes( x = long, y = lat, group = group,
fill = value), color="grey") +
scale_fill_viridis_c() +
theme_void() +
theme(plot.background = element_rect(fill = 'lightgray', colour = NA)) +
coord_map() +
coord_sf(crs = "+proj=cea +lon_0=0 +lat_ts=45") ## Gall projection
ggsave("FAO.png")
notes
some of the steps are slow, it might be worth looking up how to coarsen/lower resolution of a spatial polygons object (if you just want to show the picture, the level of resolution might be overkill)
to be honest the default sequential colour scheme might be better but all the cool kids seem to like "viridis" these days so ...
There are probably better ways to do a lot of these pieces (e.g. set map projection, fill in background colour for land masses, ... ?)
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.
I have downloaded some NetCDF files of land use scenario results from http://luh.umd.edu/data.shtml. Each file at this location has values for 11 land use types with annual values from 2015 to 2100. I'd like to make an animated gif or movie that shows the changes over time. This seems like it should be straightforward but I've tried a variety of routes, none of which work, so I'm hoping for some that actually work.
1. One approach involves creating a raster stack or brick of one of the land use variables using the stack or brick functions from the raster package. then using the raster animate function. Unfortunately, I get the following error message "animation of RasterLayer [stack, brick] objects not supported".
Another option is to convert each year of the land use data into a SpatialPixelDataFrame and then into a data.frame, use ggplot to create a gif and then combine the gifs into an animated gif. But this process seems extremely convoluted.
An R script that contains my current efforts to do this is here.
Having a look through your code, I can make the code below work.
Basically, I'm making a big dataframe with data for all years.
mydf <- purrr::map_dfr(
as.list(ncin.brick),
~setNames(as.data.frame(as(., "SpatialPixelsDataFrame")), c('value', 'x', 'y')),
.id = 'year'
)
gg <- ggplot(
mydf,
aes(x = x, y = y, fill = value)
) +
geom_sf(data = borders, fill = "transparent", color = "black", inherit.aes = FALSE) +
geom_tile() +
scale_fill_viridis_c() +
ggthemes::theme_map()
gganim <- gg + transition_time(as.numeric(year)) #+ labs(title = "Year: {frame_time}")
gganim
The picture below is the result (animation is subtle).
Try raster::animate(), there are several incompatible animate functions across packages and this seems like a clash.
I usually animate using a loop to plot raster slices, and capture that using the animate package, e.g. with saveHTML().
For ggplot2 see the gganimate package, but it doesn't scale well given the need to expand the data out.
I am using R to try and produce a map animation that gradually adds points to the map as time changes, much like the map here. So far, I can only get the points to add with trails in between each one. That type of plotting would work if I wasn't plotting locations on a map that have no connection.
How can I plot my locations as points on the map that simply appear when it's their "year" (or other specified time)? For example, adding several points in 2004, then in 2005, etc, etc. I've tried all the transition_*() functions, and those don't seem to work, but maybe I've missed something.
The code I'm using to plot the points on the map is below:
Final_View <- Minneapolis + theme(legend.position = "none", axis.ticks.x = element_blank(), axis.ticks.y = element_blank(),
axis.text.x = element_blank(), axis.text.y = element_blank()) +
geom_point(aes(x = lon, y = lat, color = "darkred"), data = Properties, size = 1) +
transition_reveal(Year) +
shadow_mark(past = TRUE) +
labs(title = "CLCLT Properties Added")
I created the variable Final_View and added my map of Minneapolis (the city I'm mapping) along with all the parts of the map I wanted removed (like the legend and axis ticks). I then add all the points using geom_point with the data coming from a .csv that I read earlier on (that part of the code not shown).
Next is what I suspect is causing the issue, but I can't find a fix: I've been trying out the different transition_*() functions, but none of them add the points as groups by year and keep previous points added on the map.
Is there an alternative to transition_*() which will achieve what I'm looking for? Or is there a transition function which I probably didn't try yet or attempted incorrectly?
EDIT: Wanted to add that I've looked into the enter.*() functions as well, but those don't seem like they'd be what I'm looking for, since, if I'm reading it right, points plotted with those functions disappear as new points are plotted.