1
votes

I am creating a geographic map of data using ggplto2 and it's geom_sf capability. Ultimately, I'm will create an animation of data using gganimate. As such, I'm hoping to keep the placement of the logo within the functions of the ggplot2 library.

I'd like to place a logo in the lower-left corner of the map. When I use the annotation_raster function it's not obvious what the " location (in data coordinates) giving the horizontal location of raster" [see https://ggplot2.tidyverse.org/reference/annotation_raster.html] should be in this case. In the examples provided the coordinates are x & y on an xy plot.

using xmin=-Inf and ymin=-Inf anchors the image in the lower-left corner. What values of ymax and xmax should be used to place the image with a small size that does not impinge on the map?

The example code is below.

   library(urbnmapr)
   library(ggplot2)
   library(dplyr)
   library(magick)

   # Read the logo
   logo <- image_read(path='C:\\your\\local\\directory\\myawesomelogo.PNG')
   # Obtain the polygon data for states
   states_sf   <- get_urbn_map("states", sf = TRUE)

   # Remove AK and HI
   states_sf   <- states_sf[!(states_sf$state_abbv %in% c("HI","AK")),]

   # create random data
   dataplot <- tibble(xdata=runif(49,-1,1))

   # add FIPS data
   dataplot <- bind_cols(dataplot, tibble(state_fips = states_sf$state_fips))

   # Merge the polygon data into the data data
   dataplot <- left_join(states_sf, dataplot, by = "state_fips")

   # Plot the random data 
    dataplot  %>%  
    ggplot() +
    geom_sf(mapping = aes(fill = xdata), size=0.5, color=NA) +
    coord_sf(datum = NA) +   
    labs(fill  = "Random", 
         title = 'Map of Data with a Logo') + 
    scale_fill_gradient2(low='navyblue', high='red', limits=c(-1,1)) + # Add the logo
    annotation_raster(logo, ymin = -Inf, ymax = 1, xmin = -Inf, xmax = 1) + 
    theme_bw() + 
    theme(
      panel.border = element_blank(),
      plot.title   = element_text(hjust = 0.5))

This results in this map. enter image description here

I'd like the logo to be much smaller and tucked away in the lower-left corner of the image. Changing the size of the image seems to have no effect.

The "logo": enter image description here

Thank you for your suggestions!

1

1 Answers

1
votes

Getting the plot max/min from a geom_sf plot should help. Below I've just added a few lines to your code to make it easier to adjust the size and position on the final plot.

Multiplying the range by the percentage of plot you want covered in the x & y direction should make it easier to adjust the relative size of the logo. In the below example it's 10% of the height and 40% of the width.

library(urbnmapr)
library(ggplot2)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(magick)
#> Linking to ImageMagick 6.9.7.4
#> Enabled features: fontconfig, freetype, fftw, lcms, pango, x11
#> Disabled features: cairo, ghostscript, rsvg, webp
library(sf)
#> Linking to GEOS 3.6.2, GDAL 2.2.3, PROJ 4.9.3

# Read the logo
logo <- image_read(path='https://i.stack.imgur.com/o48f0.png')
# Obtain the polygon data for states
states_sf   <- get_urbn_map("states", sf = TRUE)

# Remove AK and HI
states_sf   <- states_sf[!(states_sf$state_abbv %in% c("HI","AK")),]

# create random data
dataplot <- tibble(xdata=runif(49,-1,1))

# add FIPS data
dataplot <- bind_cols(dataplot, tibble(state_fips = states_sf$state_fips))

# Merge the polygon data into the data data
dataplot <- left_join(states_sf, dataplot, by = "state_fips")

# Make a tibble with the max/min/range of plot coordinates
plot_box <- tibble(xmin = st_bbox(dataplot)[1],
                   xmax = st_bbox(dataplot)[3],
                   ymin = st_bbox(dataplot)[2],
                   ymax = st_bbox(dataplot)[4],
                   xrange = xmax - xmin,
                   yrange = ymax - ymin)

# Plot the random data,
#  Use plot_box to adjust max/min/range of annotation_raster position & size
dataplot  %>%  
  ggplot() +
  geom_sf(mapping = aes(fill = xdata), size=0.5, color=NA) +
  coord_sf(datum = NA) +   
  labs(fill  = "Random", 
       title = 'Map of Data with a Logo') + 
  scale_fill_gradient2(low='navyblue', high='red', limits=c(-1,1)) + # Add the logo
  annotation_raster(logo, 
                    # Position adjustments here using plot_box$max/min/range
                    ymin = -Inf, 
                    ymax = plot_box$ymin + plot_box$yrange*.1, 
                    xmin = -Inf, 
                    xmax = plot_box$xmin + plot_box$xrange * .4) + 
  theme_bw() + 
  theme(
    panel.border = element_blank(),
    plot.title   = element_text(hjust = 0.5))

Created on 2020-04-14 by the reprex package (v0.3.0)