I'm interested in changing how the ggplot2
handles shapefiles when plotted with use of the facet_wrap
. I'm using the code below to generate a fairly simple maps for groups of various shapes:
# Data sourcing -----------------------------------------------------------
# Download an read US state shapefiles
tmp_shps <- tempfile(); tmp_dir <- tempdir()
download.file("http://www2.census.gov/geo/tiger/GENZ2014/shp/cb_2014_us_state_20m.zip",
tmp_shps)
unzip(tmp_shps, exdir = tmp_dir)
# Libs
require(rgdal); require(ggplot2)
# Read
us_shps <- readOGR(dsn = tmp_dir, layer = "cb_2014_us_state_20m")
# Prepare data set for ggplot2
us_shps_frt <- fortify(us_shps, region = "NAME")
# Drop some to make smaller graphs for the example
us_shps_frt <- us_shps_frt[us_shps_frt$id == unique(us_shps_frt$id)[10:20],]
# Graph -------------------------------------------------------------------
ggplot(us_shps_frt, aes(long, lat, group = group, fill = id)) +
geom_polygon(colour = 'black', size = 0.5) +
coord_equal() +
guides(fill = FALSE) +
theme_bw() +
facet_wrap(~id, ncol = 2) +
ggtitle("Some Title") +
theme(axis.text = element_blank(),
axis.title = element_blank(),
axis.ticks = element_blank(),
panel.grid.minor = element_blank(),
panel.grid.major = element_blank(),
panel.border = element_blank())
As illustrated in the figure below the use of space within each facet is not ideal which makes the shapes difficult to read:
I'm interested in achieving the following:
I have tried the combination of coord_equal()
and free scales, as illustrated in the snippet below:
# Desperate attempt
ggplot(us_shps_frt, aes(long, lat, group = group, fill = id)) +
geom_polygon(colour = 'black', size = 0.5) +
coord_equal() +
guides(fill = FALSE) +
theme_bw() +
facet_wrap(~id, ncol = 2, scales = 'free') +
coord_equal() +
ggtitle("Some Title") +
theme(axis.text = element_blank(),
axis.title = element_blank(),
axis.ticks = element_blank(),
panel.grid.minor = element_blank(),
panel.grid.major = element_blank(),
panel.border = element_blank())
But the results are pointless:
The solution using the multiplot function and plotting single graphs in the loop would be accepted only if proposed in a manner ensuring a convenient usability of the final graph in a R Markdown document.
First: serious kudos for a perfectly reproducible example for a semi-complex problem.
This isn't much more work:
# need this to ensure ggplot treats it as factor and so we can tell it
# not to drop the factor levels for the fill aesthetic
us_shps_frt$id <- factor(us_shps_frt$id)
# now we build a plot list
lapply(unique(us_shps_frt$id), function(x) {
ggplot(dplyr::filter(us_shps_frt, id==x),
aes(long, lat, group = group, fill = id)) +
geom_polygon(colour = 'black', size = 0.5) +
coord_quickmap() + # better than the other coords_ for this
guides(fill = FALSE) +
theme_bw() +
ggtitle(x) + # faux facet labels
scale_fill_discrete(drop=FALSE) +
theme(axis.text = element_blank(),
axis.title = element_blank(),
axis.ticks = element_blank(),
panel.grid.minor = element_blank(),
panel.grid.major = element_blank(),
panel.border = element_blank())
}) -> states_list
# now mimic facet_wrap layout with grid.arrange
do.call(gridExtra::grid.arrange, c(states_list, ncol=2))