Skip to content

Adding new theme elements to ggplot2 #5521

Closed
@eliocamp

Description

@eliocamp

I'm wondering what's the best way of adding new theme elements to ggplot2 plots.
As motivation, I wanted to make this plot, which includes a yellow line at the top of the plot:

image

I think this is not possible with vainilla ggplot2 as there is no element in the plot layout for a line in that place. My solution was to subclass the plot and create a new ggplot_gtable method that adds the line to the regular gtable.

Reprex here:

library(ggplot2)

theme_ba <- function() {
  list(
    # Normal theme stuff
    theme_minimal(base_size = 14),
    # Placeholder structure with special class "ba"
    structure(.Data = list(), class = "ba")  
  )
}

# The "ba" object adds a new class to the plot when added to it
ggplot_add.ba <- function(object, plot, object_name) {
  class(plot) <- c("ba_plot", class(plot))
  return(plot)
}


# The "ba_plot" object has special ggplot_build and ggplot_gtable methods. 

# The first method does nothing except to add a new class 
# to the built plot. This then uses the custom ggplot_gtable method
ggplot_build.ba_plot <- function(plot) {
  gb <- NextMethod("ggplot_build")
  class(gb) <- c("ba_plot", class(gb))
  return(gb)
}

# The ggplot_gtable method adds a line above the title panel. 
ggplot_gtable.ba_plot <- function(data) {
  # First, do all the normal ggplot_gtable stuff
  gt <- NextMethod("ggplot_gtable")  
  
  # Now, add the line
  line <- grid::linesGrob(x = c(0, 1), 
                          y = c(1, 1), 
                          gp = grid::gpar(col = "#fdd306",
                                          lwd = 10))
  
  panels <- gt$layout$name == "title"
  this_panel <- gt$layout[panels, ]
  
  gt <- gtable::gtable_add_grob(gt, line, t = this_panel$t, l = this_panel$l) 
    
  return(gt)
}


ggplot(mtcars, aes(cyl, disp)) +
  geom_point() +
  labs(title = "Title") +
  theme_ba()

This is a similar to what I did with in my tagger package, which adds a new panel tag element.

Now I'm wondering if this can be generalised. Create plots that have custom theme elements similar to title, subtitle, strip, etc. This would be useful, for example, for adding a "logo" element.

So a few questions. Is this the best way to do this? Could it be possible to extend ggplot2 extendability to also include adding custom elements like this natively?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions