3

我试图了解如何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

阴谋

4

0 回答 0