16EAGLE / basemaps

A lightweight package for accessing basemaps from open sources in R 🗺️
https://jakob.schwalb-willmann.de/basemaps
GNU General Public License v3.0
57 stars 15 forks source link

cannot add layer to basemap_ggplot with fill aesthetic #17

Closed btosimongillings closed 6 months ago

btosimongillings commented 1 year ago

When using basemap_ggplot it does not appear to be possible to add additional layers with a fill aesthetic as these seem to interact with an existing (hidden?) fill aesthetic, returning the following error:

Scale for 'fill' is already present. Adding another scale for 'fill', which will replace the existing scale. Error in f(): ! Binned scales only support continuous data Run rlang::last_error() to see where the error occurred.

Minimum worked example below. Is there a way around this as adding filled polygons seems to be a common requirement:

` library(basemaps) library(ggplot2) library(sf)

set defaults for the basemap

set_defaults(map_service = "osm", map_type = "topographic")

make a bounding box on British National Grid

x1 <- 565000 y1 <- 341000 x2 <- 570000 y2 <- 346000 bb <- st_sfc(st_polygon(list(rbind(c(x1,y1), c(x1,y2), c(x2,y2), c(x2,y1), c(x1,y1))))) bb <- st_sf(bb, crs = 27700)

transform to Mercator for basemap extent

bb3857 <- st_transform(bb, 3857)

get basemap as GGPLOT

bm <- basemap_ggplot(bb3857)

create a grid to populate with dummy data

grid <- st_make_grid(x = bb, cellsize = 1000, #size of the grid offset = c(x1,y1), #ensures the grid starts on whole numbers what = 'polygons', square = TRUE)

convert to sf so can add data

grid <- st_as_sf(grid)

transform to Mercator

grid3857 <- st_transform(grid, 3857)

fix geometry name (still don't know why this sometimes gets renamed!)

names(grid3857)[names(grid3857)=='x'] = 'geometry' st_geometry(grid3857)='geometry'

make mapable data

grid3857$count <- runif(25)

make a plot without the basemap - WORKS, with colour-filled grid

ggplot() + geom_sf(data = bb3857) + geom_sf(data = grid3857, aes(fill = count)) + scale_fill_viridis_b()

now try plot with the basemap and just the bounding box = WORKS

bm + geom_sf(data = bb3857, fill = NA) + geom_sf(data = grid3857, aes(fill = count, col=count))

now basemap and grid with fill aesthetic = RUNS NO ERRORS BUT FAILS: no colour aesthetic and no fill

bm + geom_sf(data = grid3857, aes(fill = count))

finally with basemap and grid with fill aesthetic and scale = FAILS WITH ERROR

bm + geom_sf(data = grid3857, aes(fill = count)) + scale_fill_viridis_b() `

NB - I tried using basemap_gglayer() instead but that simply hangs mid execute.

Bevann commented 1 year ago

I have found that using a combination of the ggnewscale and inherit.aes=F does the trick. From your example try: library(ggnewscale) bm + new_scale_fill()+ geom_sf(data = grid3857, inherit.aes=F, aes(fill = count)) + scale_fill_viridis_b()

16EAGLE commented 6 months ago

Please reopen if needed. Thanks @Bevann for the ggnewscale example.