TheWangLab / algatr

A Landscape Genomic Analysis Toolkit in R
https://thewanglab.github.io/algatr/
MIT License
12 stars 1 forks source link

Help Plotting Polygons onto tess_ggplot() #40

Closed alexkrohn closed 11 months ago

alexkrohn commented 11 months ago

Hi there! I really appreciate the package you've put out. Thanks so much for compiling all these great packages together into this easy to use framework.

I was wondering if you might explain how to plot polygons (ideally sf objects) onto your tess_ggplot() objects. Basically, I'd like to plot polygons for reference on top of the raster layer generated by tess_krig.

Here's a reproducible example:

library(algatr)
library(wingen)
library(tidyverse)

# Create lat long data
lat.longs <- data.frame(x = seq(from= -82, to = -83, by = -0.05), y = seq(from= 31, to = 32, by = 0.05))

# Create a background raster from that data
blank.raster <- coords_to_raster(lat.longs, buffer = 5, disagg = 2, plot = TRUE)

# Generate a fake qvalue matrix for K = 2
set.seed(420)

k1 <- runif(21, 0, 1)
k2 <- 1- k1

qvals <- matrix(c(k1,k2), nrow = 21, ncol = 2)

# Krig the q values over the blank.raster
krig_raster <- tess_krig(qvals, lat.longs, blank.raster)

# Plotting works by itself
tess_ggplot(krig_raster, plot_axes =  TRUE)

# But adding polygons that fit within the extent does not
library(maps)

state.boundaries <- map_data("state") %>%
  filter(region %in% c( "georgia"))

tess_ggplot(krig_raster, plot_axes =  TRUE)+
  geom_polygon(data = state.boundaries, aes(x = long, y = lat), color = "black")

# sf polygons do not work either
fake.polygon <- data.frame(x = c(-84,-80), y = c(30,35)) %>%
  st_as_sf(coords = c("x", "y")) %>%
  st_bbox() %>%
  st_as_sfc() %>%
  st_as_sf(var = 1)

tess_ggplot(krig_raster, plot_axes = TRUE)+
  geom_sf(data = fake.polygon, fill = NA)

Is there an easy way to get sf (ideally) or other polygons to print on top of the raster from tess_ggplot? This functionality seems to work well with ggplot_gd from wingen.

(edited to add sf polygon example too)

eachambers commented 11 months ago

Hi Alex,

Thanks for bringing this to our attention and for the reprex. The issue here is that the finalized plot produced by tess_ggplot() is actually two gridded plots which are combined using cowplot::plot_grid(), one for the base plot and one for the custom legend. This is why no additional ggplot functions can be added.

I’ve added a new argument to the tess_ggplot() function, list, which will return a list of two elements. Each element in the list is a ggplot object: one for the base plot and one for the legend.

Using your reprex objects as an example, you can now add your additional ggplot functions on to the base plot like so:

plot <- 
  tess_ggplot(krig_raster, plot_axes = TRUE, list = TRUE)

# Add in your polygon:
modplot <-
  plot$plot + 
  geom_polygon(data = state.boundaries, aes(x = long, y = lat), color = "black")

# And add in the legend:
library(cowplot)
cowplot::plot_grid(modplot, 
                   plot$legend, 
                   rel_widths = c(3, 1))

Note that the custom legend is only created if plot_method is set to "allQ" or "maxQ"; for "maxQ_poly" and "allQ_poly" a ggplot object is already produced by the function, so you can do:

tess_ggplot(krig_raster, plot_axes = TRUE, plot_method = “maxQ”) + 
  geom_polygon(data = state.boundaries, aes(x = long, y = lat), color = "black")

Thanks again for submitting this as an issue and let us know if you run into any additional problems.

alexkrohn commented 11 months ago

That resolved the issue. Thank you!

(And go bears!)