定义/修改draw_key的数据

Tje*_*ebo 5 r legend ggplot2 ggproto

这个问题是在回答How to show arrows in back andforward Directions in a ggplot2 legend? 时出现的。

我认为自动定义字形中箭头方向的一个好方法是传递这个值,这里是“方向”,作为一种美学,并相应地交换方向segmentsGrob。看起来draw_key_...像 Stat 和 Geom 一样使用“data”和“params”,但它只是一个单行的数据框,并且只包含四个变量。

## browser()
# Browse[1]> data
# colour size linetype alpha
# 1 #F8766D  0.5        1    NA
Run Code Online (Sandbox Code Playgroud)

我还尝试 - 但没有成功 - 通过以下方式添加方向作为美学:

GeomArrow <- ggproto(NULL, GeomSegment)
GeomArrow$required_aes <- c("x", "y", "xend", "yend", "direction")
Run Code Online (Sandbox Code Playgroud)

如何修改draw_key中使用的数据?

## browser()
# Browse[1]> data
# colour size linetype alpha
# 1 #F8766D  0.5        1    NA
Run Code Online (Sandbox Code Playgroud)

由reprex 包(v2.0.1)于 2022-06-28 创建

teu*_*and 9

我认为你首先想到的是正确的,这将是required_aesGeom 的一个。如果我们制作这样一个 Geom:

library(ggplot2)
library(rlang)

foo <- structure(list(direction = c("backward", "forward"), 
                      x = c(0, 0), xend = c(1, 1), y = c(1, 1.2), 
                      yend = c(1, 1.2)), row.names = 1:2, class = "data.frame")

GeomArrow <- ggproto(
  NULL, GeomSegment,
  required_aes = c("x", "y", "xend", "yend", "direction"),
  draw_layer = function (self, data, params, layout, coord) 
  {
    swap <- data$direction == "backward"
    v1 <- data$x
    v2 <- data$xend
    data$x[swap] <- v2[swap]
    data$xend[swap] <- v1[swap]
    GeomSegment$draw_layer(data, params, layout, coord)
  }
)
Run Code Online (Sandbox Code Playgroud)

并声明一个适当的关键绘图函数

draw_key_arrow = function(data, params, size) {
  grid::segmentsGrob(
    x0 = ifelse(data$direction == "forward", 0.1, 0.9),
    x1 = ifelse(data$direction == "forward", 0.9, 0.1),
    # Rest is just like vanilla
    y0 = 0.5, y1 = 0.5,
    gp = grid::gpar(
      col  = alpha(data$colour %||% data$fill %||% "black", data$alpha),
      fill = alpha(params$arrow.fill %||% data$colour %||% data$fill %||% 
                     "black", data$alpha),
      lwd = (data$size %||% 0.5) * .pt,
      lty = data$linetype %||% 1, lineend = "butt"
    ),
    arrow = params$arrow
  )
}
Run Code Online (Sandbox Code Playgroud)

然后,如果(!!!)我们还将direction美学映射到带有图例的比例,我们应该能够渲染绘图。

ggplot() +
  stat_identity(
    geom = GeomArrow,
    data = foo,
    aes(x, y, xend = xend, yend = yend, col = direction, direction = direction),
    arrow = arrow(length = unit(0.3, "cm"), type = "closed"),
    key_glyph = draw_key_arrow
  ) +
  # Hijacking a generic identity scale by specifying aesthetics
  scale_colour_identity(aesthetics = "direction", guide = "legend")
Run Code Online (Sandbox Code Playgroud)

由reprex 包于 2022 年 7 月 4 日创建(v2.0.1)


来自评论:相关源代码目前可以在ggplot2/R/guide-legend.r中找到

  • 相关源代码是[这里](https://github.com/tidyverse/ggplot2/blob/50e917a230d7347a30e2ebcca1e3baa9a4b82072/R/guide-legend.r#L260-L284),但看起来相当复杂。 (2认同)