I have created a ggplot worldmap that I want to save as svg. Both work fine. However, I want to change/specify the area of the plot that gets saved.
My code looks as follows:
raw_plot = ggplot(data = world_for_plot,
aes(x = long,
y = lat,
group = group,
fill = "black")) +
geom_polygon(aes(fill = results)) +
coord_equal(1.3, expand=F) +
scale_fill_continuous(na.value = '#F6F6F6', guide=F)
ggsave(file = "FOLDER\\LATAM.svg",
plot = raw_plot)
This gives me the following plot:

However, I want to have a file/plot that doesn't have all the unnecessary white space on top and bottom:

Any ideas? I already figured out that the coord_equal command creates some problems. Without it, the plot fills out the whole plot area. However, I need the coord_equal command, otherwise the world map would look stretched.
This might work if you adjust the lengths:
raw_plot + theme(plot.margin = margin(-2, 0, -2, 0, "cm"))
The order of the margins here is top, right, bottom, left.
I recently faced the same problem so here're my solutions for people with the same issue.
tmaptools has a function get_asp_ratio to compute the aspect ratio of spatial objects. We can use that ratio to remove the outer margin of any map.
library(ggplot2)
world <- rnaturalearth::ne_countries(returnclass = "sf") # to get the world map
ggplot() +
geom_sf(data = world) +
coord_sf(expand = FALSE) +
theme_void()
asp <- tmaptools::get_asp_ratio(world) # returns 2.070007
height <- 5
ggsave("world.svg", width = height * asp, height = height)
Alternatively, if we don't want to depend on tmaptools, we can make our own functions with a wrapper around ggsave. This is essentially based on the tmaptools::get_asp_ratio function.
deg_to_rad <- function(x) {
(mean(x) * pi) / 180
}
get_aspect_ratio <- function(geometry) {
if (!inherits(geometry, c("Spatial", "Raster", "sf", "sfc"))) {
stop('"geometry" must be of class "Spatial", "Raster", "sf" or "sfc".')
}
bbox <- sf::st_bbox(geometry)
xlim <- bbox[c(1, 3)]
ylim <- bbox[c(2, 4)]
xdeg <- diff(xlim)
ydeg <- diff(ylim)
if (xdeg == 0 || ydeg == 0) {
asp <- 1
} else {
is_lon_lat <- sf::st_is_longlat(geometry)
asp <- unname((xdeg / ydeg) * ifelse(is_lon_lat, cos(deg_to_rad(ylim)), 1))
}
asp
}
save_ggmap <- function(filename, plot = last_plot(), width = NA, height = NA, ...) {
geometry <- ggplot_build(plot)$data[[1]]$geometry
asp <- get_aspect_ratio(geometry)
if (is.na(width) && !is.na(height)) {
width <- height * asp
} else if (is.na(height) && !is.na(width)) {
height <- width / asp
}
ggsave(filename, plot, width = width, height = height, ...)
}
We can use the function the same way as ggsave. We only have to specify either the width or height and the function will save the map with the right aspect ratio automatically.
ggplot() +
geom_sf(data = world) +
coord_sf(expand = FALSE) +
theme_void()
save_ggmap("world.svg", width = 8)
To remove the inner margin, we can use theme(plot.margin = margin(0, 0, 0, 0)).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With