Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Small ggplot2 plots placed on coordinates on a ggmap

Tags:

r

ggplot2

ggmap

I would like to first use ggmap to plot a specific area with longitude and latitude as axes.

Then I would like to put small ggplot2 plots on the specific locations, given their longitude and latitude. These can be barplots with minimal theme.

My database may have the columns:

1. town
2. longitude
3. latitude
4. through 6. value A, B, C

I generate a plot (pseudocode)

p <- ggmap(coordinates) 

and I have my minimal ggplot2 design

q<-ggplot2()+geom_bar(....)+ ... x-axis null y axis null minimal template

How to combine the two designs to have a ggmap with small minimal ggplot plots imposed on specific coordinates of the map?

like image 553
Jacek Kotowski Avatar asked Jul 31 '17 08:07

Jacek Kotowski


1 Answers

Here's one I did using pie charts as points on a scatterplot. You can use the same concept to put barcharts on a map at specific lat/long coordinates.

R::ggplot2::geom_points: how to swap points with pie charts?

Needs further update. Some of the code used was abbreviated from another answer, which has since been deleted. If you find this answer via a search engine, drop a comment and I'll get around to fleshing it back out.


Updated:

enter image description here

Using mostly your adapted code from your answer, but I had to update a few lines.

p <- ggmap(Poland) + coord_quickmap(xlim = c(13, 25), ylim = c(48.8, 55.5), expand = F)

This change makes a better projection and eliminates the warnings about duplicated scales.

df.grobs <- df %>% 
  do(subplots = ggplot(., aes(1, value, fill = component)) + 
       geom_col(position = position_dodge(width = 1), 
                alpha = 0.75, colour = "white") +
       geom_text(aes(label = round(value, 1), group = component), 
                 position = position_dodge(width = 1),
                 size = 3) +
       theme_void()+ guides(fill = F)) %>% 
  mutate(subgrobs = list(annotation_custom(ggplotGrob(subplots), 
                                           x = lon-0.5, y = lat-0.5, 
                                           xmax = lon+0.5, ymax = lat+0.5))) 

Here I explicitly specified the dodge width for your geom_col so I could match it with geom_text. I used round(value, 1) for the label aesthetic, and it automatically inherits the x and y aesthetics from the subplots = ggplot(...) call. I also manually set the size to be quite small, so the labels would fit, but then I increased the overall bounding box for each subgrob, from 0.35 to 0.5 in each direction.

df.grobs %>%
  {p + 
    .$subgrobs + 
    geom_text(data=df, aes(label = name), vjust = 3.5, nudge_x = 0.065, size=2) + 
    geom_col(data = df,
             aes(Inf, Inf, fill = component), 
             colour = "white")}

The only change I made here was for the aesthetics of the "ghost" geom_col. When they were set to 0,0 they weren't plotted at all since that wasn't within the x and y limits. By using Inf,Inf they're plotted at the far upper right corner, which is enough to make them invisible, but still plotted for the legend.

like image 112
Brian Avatar answered Nov 15 '22 07:11

Brian