gbradburd / conStruct

method for modeling continuous and discrete population genetic structure
35 stars 14 forks source link

Piemap plotting query #41

Closed kdm9 closed 2 years ago

kdm9 commented 3 years ago

Hi Gideon,

Thanks again for a fantastic method. This is a question rather than a bug report, in the vain hope that you either have or are aware of someone else having solving this issue.

We're doing up some final figures on an upcoming paper that uses construct, and I'm having issues getting a publication quality piemap-like plot. Specifically, we'd like to plot pie charts of the admixture proportions on a country border-style map of Europe. I'm only really conversant in the extended ggplot universe flavour of graphics, so I'm using ggmap for the base layer and ggforce to generate a "piemap".

The issue is that these two plot components have fundamentally different coordinate spaces: a pie chart should be circular, but the "circle" of radius 1° around a point has a range of sizes, shapes and circularities across any geodetic coordinate system. And conversely, plotting a map on the Cartesian plane leads to weird artefacts, e.g. a very fat northern Europe. We've also tried plotting them separately and combining in Illustrator or inkscape, but with no better results.

Do you have any thoughts, tips, or other gems of wisdom you can share?

Best, Kevin

Examples:

1) WGS84 coordinate space for the map, but with squished pie charts in the correct locations

k3-piemap

2) The pie charts themselves with Cartesian coordinates, which are now circular, but in the wrong locations. If the map were plotted underneath this it would be stretched very wide.

02_Hpa_cs_k3-justpies

petrelharp commented 3 years ago

Hi, @kdm9 - glad it's being helpful! And gee - it looks to me like the distortion in the first map is coming from being squished horizontally, not from the map projection - here's a zoom in on a northern and a southern pie plot in exactly the same rectangle: Screenshot from 2021-08-31 07-37-48 Screenshot from 2021-08-31 07-37-42

This can happen if you plot to a window in R and then save it out as a pdf to a different aspect ratio image - how are you saving it to a file?

kdm9 commented 3 years ago

Hi Peter,

Thanks for your help! Yes, it's odd isn't it.

I'm using ggsave, with an a4-compatible width and height (6" by 7"). It is a bit suspicious, but I don't think the save aspect ratio is the direct cause. See for example below, which is what happens when you use an export size of 6" by 20" wide. The plot isn't stretched, it seems to keep its own native aspect ratio (nb the large white margins on each side). Additionally, if one scales points to the equator to the poles and then plot, one can see a trend of squishedness from the equator to the poles.

k2-piemap-big

petrelharp commented 3 years ago

Ah, ok, you're right. How about this? https://stackoverflow.com/questions/51398344/r-pie-charts-distorted-when-adding-to-projected-map-using-ggplot

kdm9 commented 3 years ago

Ah, fantastic! Many thanks. I googled extensively, but looks like I missed that SO question/answer. I'd be happy to write a small section for the construct vignette with example code once it's working if that's of interest, since this is something others probably could use too.

gbradburd commented 3 years ago

That'd be great Kevin - thanks!

gbradburd commented 2 years ago

Hey Kevin - I'm going to close this issue, but feel free to reopen if you have further thoughts/problems with this!

kdm9 commented 2 years ago

The only further thought I have is "oops, I forgot to upload this" :)

I don't have time right now to make this a nice function, but for those who are searching, here's my plotting code. Hopefully, I'll soon have time and remember to turn this into a function within the conStruct package, but in the mean time, here goes:

#' # Construct-related plots for the paper

library(tidyverse)
library(ggspatial)
library(ggplot2)
library(sf)
library(rnaturalearth)
library(rnaturalearthdata)
library(ggforce)
library(foreach)
theme_set(theme_bw())

#' # Fancy piemaps
#'
#' This looted from https://stackoverflow.com/questions/51398344/r-pie-charts-distorted-when-adding-to-projected-map-using-ggplot

world = map_data("world", resolution=0)
basem = ggplot(data=world, aes(x=long, y=lat, group=group)) + 
  geom_polygon(color = "grey", fill="white") + 
  coord_quickmap(xlim = c(-12, 55), ylim = c(34, 60)) +
  ylab("Latitude") + 
  xlab("Longitude") + 
  theme(
    panel.background = element_rect(fill = "lightsteelblue2"),
    panel.grid = element_blank(), 
    legend.position = "top")

basem

pie.list = csvmap_data %>% 
  tidyr::nest(c(pop, proportion)) %>%
  # make a pie chart from each row, & convert to grob
  mutate(pie.grob = purrr::map(data,
                               function(d) ggplotGrob(ggplot(d, aes(x = 1, y = proportion, fill = pop)) +
                                                      geom_col(show.legend = FALSE) +
                                                      scale_fill_manual(values=gautam.pal.k3) +
                                                      coord_polar(theta = "y") +
                                                      theme_void()))) %>%
  # convert each grob to an annotation_custom layer.
  rowwise() %>%
  mutate(radius = 0.9) %>%
  mutate(subgrob = list(annotation_custom(grob = pie.grob,
                                          xmin = longitude - radius, xmax = longitude + radius,
                                          ymin = latitude  - radius, ymax = latitude + radius)))

basem + 
    pie.list %>%
    filter(mdl=="sp", K==3) %>%
    pull(subgrob)

basem + 
    pie.list %>%
    filter(mdl=="sp", K==2) %>%
    pull(subgrob)