如何在geom_spoke上获得一个传奇

时间:2018-04-03 22:12:44

标签: r ggplot2

我有风速和风向。我希望根据箭头和线的长度(在下面的代码中用半径定义)来获取图例中的风速。基于this问题,如何使用箭头在图例中添加速度。

   library(ggplot2)
        wind.dt<-structure(list(Lon = c(170.25, 171, 171.75, 172.5, 173.25, 174, 
174.75, 175.5, 176.25, 177, 177.75, 178.5, 179.25, 180, 180.75, 
181.5, 182.25, 183, 183.75, 184.5, 185.25, 186, 186.75, 187.5, 
188.25, 189, 189.75, 190.5, 191.25, 192), Lat = c(14.25, 14.25, 
14.25, 14.25, 14.25, 14.25, 14.25, 14.25, 14.25, 14.25, 14.25, 
14.25, 14.25, 14.25, 14.25, 14.25, 14.25, 14.25, 14.25, 14.25, 
14.25, 14.25, 14.25, 14.25, 14.25, 14.25, 14.25, 14.25, 14.25, 
14.25), mean_wind = c(8.34, 8.33, 8.31, 8.29, 8.27, 8.24, 8.22, 
8.2, 8.19, 8.16, 8.14, 8.13, 8.1, 8.08, 8.06, 8.02, 7.99, 7.96, 
7.93, 7.89, 7.85, 7.81, 7.78, 7.73, 7.7, 7.67, 7.63, 7.62, 7.6, 
7.58), wind_dir = c(81.27, 81.34, 81.38, 81.44, 81.47, 81.34, 
81.31, 81.51, 81.56, 81.46, 81.54, 81.53, 81.42, 81.53, 81.66, 
81.76, 81.86, 81.96, 82.02, 82.28, 82.65, 82.77, 83.07, 83.46, 
83.78, 84.15, 84.52, 84.92, 85.39, 85.87)), .Names = c("Lon", 
"Lat", "mean_wind", "wind_dir"), row.names = c(NA, -30L), class = c("tbl_df", 
"tbl", "data.frame"))
ggplot(wind.dt, 
       aes(x = Lon , 
           y = Lat, 
           fill = mean_wind, 
           angle = wind_dir, 
           radius = scales::rescale(mean_wind, c(.2, .8)))) +
    geom_raster() +
    geom_spoke(arrow = arrow(length = unit(.05, 'inches'))) + 
    scale_fill_distiller(palette = "RdYlGn") + 
    coord_equal(expand = 0) + 
    theme(legend.position = 'bottom', 
          legend.direction = 'horizontal')

1 个答案:

答案 0 :(得分:2)

这是一种有点粗略的做法,模仿the scatterpie package中使用的机制。它是一个生成geoms列表以添加到绘图中的函数。最大的警告是你只能将图例放在情节面板中。

library(scales)

geom_spoke_legend <- function(r, x, y, n = 5, scaled = c(0.2,0.8), 
                              arrow = NULL, label = NULL) {

  dd <- data.frame(breaks = pretty_breaks(n)(r))
  dd$radius <- rescale(dd$breaks, to = scaled, from = range(r, na.rm = T, finite = T))
  dd$xpos <- seq(0, by = round(max(scaled)), length.out = length(dd$breaks))
  dd$xpos <- dd$xpos + x
  dd$ypos <- rep(y, length(dd$breaks))



  g <- list(
    geom_spoke(data = dd,
               aes(x = xpos, y = ypos + 0.5, radius = radius),
               angle = pi/4, arrow = arrow,
               inherit.aes = F),
    geom_text(data = dd,
              aes(x = xpos, y = ypos, label = format(breaks)),
              hjust = 0, vjust = 0, size = 3,
              inherit.aes = F)
  )

  if (!is.null(label)) {
      dd1 <- dd[1,]
      dd1$label <- label

      g <- c(g,
             geom_text(data = dd1,
                       aes(x = xpos, y = ypos-0.5, label = label),
                       hjust = 0, vjust = 0, size = 3,
                       inherit.aes = F))
  }

  g
}

要使用此功能,您必须明确提供几个参数:

  1. 来自原始数据帧的半径向量
  2. 面板中图例左下角的所需x位置
  3. 与#2相同,但对于y
  4. 还可以选择其他一些参数:

    1. 图例中所需的休息数
    2. 向量的重新调整长度,在您调用rescale
    3. 时在原始图中使用
    4. 来自原始arrow()
    5. geom_spoke来电
    6. 标题
    7. 要使用它,你可以这样做:

      ggplot(wind.dt, 
             aes(x = Lon, 
                 y = Lat, 
                 fill = mean_wind)) +
        geom_raster() +
        geom_spoke(aes(angle = wind_dir, 
                       radius = scales::rescale(mean_wind, c(.2, .8))),
                   arrow = arrow(length = unit(.05, 'inches'))) + 
        scale_fill_distiller(palette = "RdYlGn") + 
        coord_equal(expand = 0) + 
        theme_classic() +                       # added for legibility
        theme(legend.position = 'bottom', 
              legend.direction = 'horizontal') +
        # use the function like any other geom*
        geom_spoke_legend(wind.dt$mean_wind, x = 186, y = 15.5, 
                          arrow = arrow(length = unit(.05, 'inches')),
                          label = "Mean windspeed")
      

      enter image description here

      此解决方案未针对分面图进行优化,如果您想自定义它们,现在需要对某些细节进行硬编码。

      作为旁注,&#34;对&#34;这样做的方法是绘制任意的grobs,这是内部ggplot::draw_key*函数的工作方式。但是,没有办法保持x和y坐标的长度与绘图面板中的相同,这就是我使用scatterpie包中的解决方案的原因。