简体   繁体   中英

Adding polar bar plot as separate object into ggplot/ggmap?

I have a code below for generating a simple polar bar plot in ggplot for quadrant-based values (wind radii from a central point of latitude & longitude), which looks like this:

极地情节

I want to extract these polar plots to a SpatialPolygons object, so I can plot them as polygons on a map similar to this:

地图

Is there any method to extract ggplot objects like this to a SpatialPolygons, shapefile, or some kind of dataframe for plotting on a map with ggplot/ggmap? Even a suggestion to explore further would be useful. Thanks in advance.

My dataframe:

winds <- data.frame(WindField = c(34, 50, 64, 34, 50, 64, 34, 50, 64, 34, 50, 64), 
                    Quadrant = c("NE", "NE", "NE", "SE", "SE", "SE", 
                                 "SW", "SW", "SW", "NW", "NW", "NW"), 
                    Radius = c(222, 93, 37, 139, 46, 37, 74, 19, 9, 222, 93, 37)) 

quads <- c("NE", "SE", "SW", "NW")

My ggplot code:

ggplot() + 
    geom_col(data = winds,
             aes(x = factor(Quadrant, levels = quads),
                 y = Radius,
                 fill = factor(WindField),
                 group = factor(Quadrant, levels = quads)),
             stat = "identity", position = "identity", width = 1, color = 'black') +
    scale_fill_manual(values = c("yellow", "orange", "red")) +
    guides(fill = guide_legend(title = "Wind [kt]")) +
    coord_polar() +
    theme_bw() +
    theme(plot.title = element_text(size = 16), 
          plot.subtitle = element_text(size = 12),
          axis.title = element_text(size = 14),
          axis.text.y = element_text(size = 12, face = 'bold'),
          axis.text.x = element_text(size = 14, face = 'bold'),
          legend.text = element_text(size = 13), 
          legend.title = element_text(size = 13),
          panel.border = element_blank(), 
          legend.position = "bottom") +
    labs(y = "Radius [km]", x='Quadrant') 

I don't think shapefiles play very well with ggplot, but you can convert the plots (which are ggplot objects) into grob objects & add them to the map using annotation_custom() .

Here's an example, assuming you wish to plot multiple bar plots using a single data frame source file that contains all the necessary information.

Step 0 : Generate data

set.seed(123)
df <- data.frame(
  plot.ID = rep(1:2, each = 12),
  WindField = rep(c(34, 50, 64), times = 8),
  Quadrant = rep(rep(c("NE", "SE", "SW", "NW"), each = 3), times = 2),
  Radius = rpois(24, lambda = 50) * 
    rep(c(5, 2, 1), times = 8) * # ensure radii decreases as WindField increases
    c(rep(sample(1:4), each = 3), # ensure each quadrant looks visually distinct
      rep(sample(5:8), each = 3)) # & looks different between plots
)

# convert Quadrant / WindField to factors
df$Quadrant = factor(df$Quadrant, levels = c("NE", "SE", "SW", "NW"))
df$WindField = factor(df$WindField)

# add position for each plot (using Florida for illustration)
# note maximum radius of the largest plot
df <- left_join(df,
                 data.frame(plot.ID = 1:2,
                            lon = c(-82, -80),
                            lat = c(29, 26)),
                 by = "plot.ID") %>%
  mutate(max.Radius = max(Radius))

> head(df)
  plot.ID WindField Quadrant Radius lon lat max.Radius
1       1        34       NE    460 -82  29       1920
2       1        50       NE    232 -82  29       1920
3       1        64       NE     76 -82  29       1920
4       1        34       SE   1000 -82  29       1920
5       1        50       SE    496 -82  29       1920
6       1        64       SE    212 -82  29       1920

Verify what the plots would look like, on a normal plot:

ggplot(df,
       aes(x = Quadrant, y = Radius, fill = WindField)) +
  geom_col(position = "identity", width = 1, color = "black") +
  scale_fill_manual(values = c("yellow", "orange", "red")) +
  coord_polar() +
  facet_grid(~plot.ID) +
  theme_void()

情节

Step 1 : Create separate polar bar plot for each location, convert to grob object, & specify their positions

df.grobs <- df %>%
  group_by(plot.ID, lon, lat, max.Radius) %>%
  do(subplots = ggplot(.,
                       aes(x = Quadrant, y = Radius, fill = WindField)) +
       geom_col(position = "identity", width = 1, color = "black",
                alpha = 0.5,            # increase transparency to see map underneath
                show.legend = FALSE) +  # don't show legend for individual grobs
       scale_y_continuous(limits = c(0, unique(.$max.Radius))) + 
       scale_fill_manual(values = c("yellow", "orange", "red")) +
       coord_polar() +
       theme_void()) %>%
  mutate(subgrobs = list(annotation_custom(ggplotGrob(subplots),
                                           x = lon - 1,      # change from 1 to other 
                                           y = lat - 1,      # values if necessary,
                                           xmax = lon + 1,   # depending on the map's
                                           ymax = lat + 1))) # resolution.

Step 2 : Create map

library(ggmap)

p <- get_map("Florida", zoom = 7) %>% 
  ggmap() + 
  coord_fixed()

Step 3 : Combine map with the list of bar plot grobs

p + df.grobs$subgrobs

组合地图

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM