我试图了解如何ggproto
编写自己的 geoms。
我写了geom_myerrorbarh(类似于geom_errorbarh,但只有x
, y
,xwidth
参数)。下图显示一切都在线性比例下正常工作。但是,如果您使用 log10 比例,它与geom_errorbarh不同。
我注意到在使用scale_x_log10()时,x=log10(x)
首先转换,然后xmin=x-xwidth; xmax=x+xwidth
(参见 setup_data 参数)。但它应该是xmin=log10(x-width); xmax=log10(x+xwidth)
。
如何解决这个问题呢?
library(grid)
library(ggplot2)
library(patchwork)
theme_set(theme_minimal())
GeomMyerrorbarh <- ggproto("GeomMyerrorbarh", Geom,
required_aes = c("x", "y", "xwidth"),
draw_key = draw_key_path,
setup_data = function(data, params){
transform(data, xmin = x - xwidth, xmax = x + xwidth)
},
draw_group = function(data, panel_scales, coord) {
## Transform the data first
coords <- coord$transform(data, panel_scales)
## Construct a grid grob
grid::segmentsGrob(
x0 = coords$xmin,
x1 = coords$xmax,
y0 = coords$y,
y1 = coords$y,
gp = gpar(lwd = coords$size,
col = coords$colour,
alpha = coords$alpha))
})
geom_myerrorbarh <- function(mapping = NULL, data = NULL, stat = "identity",
position = "identity", na.rm = FALSE,
show.legend = NA, inherit.aes = TRUE, ...) {
ggplot2::layer(
geom = GeomMyerrorbarh, mapping = mapping,
data = data, stat = stat, position = position,
show.legend = show.legend, inherit.aes = inherit.aes,
params = list(na.rm = na.rm, ...)
)
}
df <- data.frame(x = c(1, 2),
y = c(1, 2),
xerr = c(0.1, 0.2))
p1 <- ggplot(df, aes(x, y)) +
geom_point() +
geom_errorbarh(aes(xmin = x - xerr, xmax = x + xerr),
height=0, size=4, alpha=0.2, color='red') +
geom_myerrorbarh(aes(xwidth = xerr)) +
labs(subtitle = 'Linear scale x')
p2 <- p1 +
scale_x_log10() +
labs(subtitle = 'Log10 scale x')
# Plot:
# Red transparent region - geom_errorbarh
# Black line - geom_myerrorbarh
p1 | p2