[英]Defining / modifying data for draw_key
This question came up on answering How to show arrows in backward and forward directions in a ggplot2 legend?这个问题出现在回答如何在ggplot2图例中显示向后和向前方向的箭头?
I thought that a good way to automatically define the direction of the arrow in the glyph would be to pass this value, here "direction", as an aesthetic and to swap the direction of the segmentsGrob
accordingly.我认为在字形中自动定义箭头方向的一种好方法是将这个值(这里是“方向”)作为美学传递,并相应地交换
segmentsGrob
的方向。 It seems that draw_key_...
uses "data" and "params" like Stat and Geom do, but it is only a data frame with a single row and it only contains four variables.似乎
draw_key_...
像 Stat 和 Geom 一样使用“数据”和“参数”,但它只是一个单行数据框,它只包含四个变量。
## browser()
# Browse[1]> data
# colour size linetype alpha
# 1 #F8766D 0.5 1 NA
I also tried - without success - to add direction as an aesthetic with:我也尝试过——但没有成功——将方向作为一种美学添加:
GeomArrow <- ggproto(NULL, GeomSegment)
GeomArrow$required_aes <- c("x", "y", "xend", "yend", "direction")
How can I modify this data that is used in draw_key?如何修改 draw_key 中使用的数据?
library(ggplot2)
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")
StatArrow <- ggproto(NULL, StatIdentity)
StatArrow$compute_layer <- function (self, data, params, layout)
{
swap <- data$direction == "backward"
v1 <- data$x
v2 <- data$xend
data$x[swap] <- v2[swap]
data$xend[swap] <- v1[swap]
data
}
# draw_key_segment_custom <- function(data, params = list(direction), size) {
## ...
## the idea was to simply switch x0 and x1 in the segmentsGrob depending on the new aesthetic
## This does not work because "data$direction" does not exist
## something like
# if(data$direction == "backward") {
# x0 = 0.9
# x1 = 0.1
# } else {
# x0 = 0.1
# x1 = 0.9
# }
## then
# grid::segmentsGrob(x0, 0.5, x1, 0.5,
##...)
## but
## browser()
# Browse[1]> data
# colour size linetype alpha
# 1 #F8766D 0.5 1 NA
# }
## direction as an aesthetic works despite this warning
ggplot() +
geom_segment(data = foo,
stat = "arrow",
aes(x, y, xend = xend, yend = yend, col = direction,
direction = direction),
arrow = arrow(length = unit(0.3, "cm"), type = "closed")
## does not work, as per above
# key_glyph = "segment_custom"
)
#> Warning: Ignoring unknown aesthetics: direction
Created on 2022-06-28 by the reprex package (v2.0.1)由reprex 包创建于 2022-06-28 (v2.0.1)
I think you first thought was correct, that it would be a required_aes
of the Geom.我认为您首先认为是正确的,这将是 Geom 的
required_aes
。 If we make such a Geom:如果我们制作这样一个 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)
}
)
And declare an appropriate key drawing function并声明一个合适的按键绘制函数
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
)
}
Then we should be able to render the plot if (!!!) we also map the direction
aesthetic to a scale with a legend.然后,如果(!!!)我们还将
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")
Created on 2022-07-04 by the reprex package (v2.0.1)由reprex 包创建于 2022-07-04 (v2.0.1)
From comments: The relevant source code can be currently found in ggplot2/R/guide-legend.r来自评论:目前可以在ggplot2/R/guide-legend.r中找到相关源代码
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.