rggplot2geom-segment

ggplot2 Custom Geom Line Glyphs Incorrect


Background

I am developing a custom geom for ggplot2 in R that starts by building on geom_segment():

geom_custom <- function(mapping = NULL, data = NULL,
                     stat = "identity", position = "identity",
                     ..., na.rm = FALSE, show.legend = NA,
                     inherit.aes = TRUE) {
  
  out <- layer(
    data = data,
    mapping = mapping,
    stat = stat,
    geom = CustomGeom,
    position = position,
    show.legend = show.legend,
    inherit.aes = inherit.aes,
    params = list(na.rm = na.rm, ...)
  )
  
  out
}

CustomGeom <- ggproto("CustomGeom", Geom,
                    required_aes = c("x", "y", "xend"),
                    non_missing_aes = c("linetype", "linewidth"),
                    default_aes = aes(
                      colour = "black",
                      linewidth = 2,
                      size = 2,
                      linetype = 1,
                      alpha = NA
                    ),
                    draw_panel = function(data, panel_params, coord, ...) {
                      
                      # Return all components
                      grid::gList(
                        GeomSegment$draw_panel(data, panel_params, coord, ...)
                      )
                    }
)

Problem

The issue is the legend glyphs are incorrectly showing shape values instead of lines that geom_segment() normally gives. Here is a sample reprex and the output:

df <- tibble::tribble(
  ~"record", ~"status", ~"start_time", ~"end_time",
  1, "status1", 0, 5,
  2, "status1", -2, 7,
  3, "status2", 2, 15
)

ggplot() +
  geom_custom(data = df,
              mapping = aes(x = start_time, xend = end_time, y = record, colour = status))

enter image description here

And the expected output using geom_segment():

enter image description here

Any advice on how to correct the legend glyphs here?

Thank you!


Solution

  • I believe I've found a solution by setting key_glyph = "path" in the layer definition:

    geom_custom <- function(mapping = NULL, data = NULL,
                         stat = "identity", position = "identity",
                         ..., na.rm = FALSE, show.legend = NA,
                         inherit.aes = TRUE) {
      
      out <- layer(
        data = data,
        mapping = mapping,
        stat = stat,
        geom = CustomGeom,
        position = position,
        show.legend = show.legend,
        inherit.aes = inherit.aes,
        key_glyph = "path",
        params = list(na.rm = na.rm, ...)
      )
      
      out
    }
    

    I'm still confused as to why the legend glyph was changed in the first place based on the original code, and happy to accept a new answer if someone has more insight. But for now this seems to fit my use case.