5

What I want to do

I currently have a custom theme for my plots, and I want to have on top of that some predefined parameters for all type of plots. My first focus is on bar charts, where I want to change the default width.

The default width of geom_bar in ggplot2 is "By default, set to 90% of the resolution of the data." (http://ggplot2.tidyverse.org/reference/geom_bar.html).

I'd like to change that default to 75%. To be clear, I am not interested in changing it like this:

geom_bar(stat='identity', width=0.75)

Because that would mean I have to specify it everytime I create a bar chart. I want it to be the new default.

What I tried so far

I tried to change the width default using this:

update_geom_defaults("bar", list(width=0.75))

But then I get an error message: Error: Aesthetics must be either length 1 or the same as the data (964): width. I'm thinking this might be due to the fact that the width is calculated based on the resolution of the data, which is not yet there at the moment I call update_geom_defaults

Plus, I also realised that width is not part of the default aes of the bars :

GeomBar$default_aes
* colour   -> NA
* fill     -> "grey35"
* size     -> 0.5
* linetype -> 1
* alpha    -> NA

My questions are:

  • Where is that 90% default set?
  • Can I change it in any way?
  • If not, is there another way to pass a predefined set of parameters to all the geom_* functions?

Thanks !

Mike Wise
  • 22,131
  • 8
  • 81
  • 104
agatheblues
  • 229
  • 1
  • 10

1 Answers1

6

The default is defined in GeomBar:

GeomBar <- ggproto("GeomBar", GeomRect,
  required_aes = c("x", "y"),

  setup_data = function(data, params) {
    data$width <- data$width %||%
      params$width %||% (resolution(data$x, FALSE) * 0.9)  ## <- right here
    transform(data,
      ymin = pmin(y, 0), ymax = pmax(y, 0),
      xmin = x - width / 2, xmax = x + width / 2, width = NULL
    )
  },

  draw_panel = function(self, data, panel_params, coord, width = NULL) {
    # Hack to ensure that width is detected as a parameter
    ggproto_parent(GeomRect, self)$draw_panel(data, panel_params, coord)
  }
)

The marked line uses %||%, which is used to set a default in the event params$width is NULL (which is the default in geom_bar, NULL means "set it to something reasonable for me").

There is no nice way like update_geom_defaults to change this. What you can do, is make your own geom_bar like this:

geom_bar75 <- function (..., width = 0.75) {
  geom_bar(..., width = width)
}

This will work just fine in most cases, i.e. with a discrete x-axis (because the resolution is then 1). For more complicated cases you may need to adjust, or redefine GeomBar itself.

ggplot(mpg, aes(class)) + geom_bar()
ggplot(mpg, aes(class)) + geom_bar75()

enter image description here

Axeman
  • 32,068
  • 8
  • 81
  • 94