tidyverse / ggplot2

An implementation of the Grammar of Graphics in R
https://ggplot2.tidyverse.org
Other
6.5k stars 2.02k forks source link

default `width` aesthetic of geom_errorbar does not impact plot #2800

Open dpseidel opened 6 years ago

dpseidel commented 6 years ago

width is an aesthetic and a parameter of geom_errorbar (also worth nothing that it is not documented as either except in examples). Because of this dual classification, although you can set the default globally in update_geom_defaults, it actually has no effect. In fact, although the default is 0.5 what plots by default in the case below is a width of 0.9. The aesthetic or parameter must be set by the user explicitly for it to take effect given the way width is calculated in GeomErrorbar$setup_data(). This is also a problem with the height aesthetic of geom_errorbarh.

library(dplyr)
library(ggplot2)

iris %>%
  group_by(Species) %>%
  summarise(y=mean(Sepal.Length),
            ymin=min(Sepal.Length),
            ymax=max(Sepal.Length)) %>%
  rename(x=Species) ->
  summary_df

GeomErrorbar$default_aes
#> Aesthetic mapping: 
#> * `colour`   -> "black"
#> * `size`     -> 0.5
#> * `linetype` -> 1
#> * `width`    -> 0.5
#> * `alpha`    -> NA
ggplot(summary_df, aes(y=y, x=x, ymin=ymin, ymax=ymax)) + geom_errorbar()

# update_geom_defaults does work... it just doesn't impact the plot....
update_geom_defaults("errorbar", list(width = 0))
GeomErrorbar$default_aes
#> $width
#> [1] 0
#> 
#> $colour
#> [1] "black"
#> 
#> $size
#> [1] 0.5
#> 
#> $linetype
#> [1] 1
#> 
#> $alpha
#> [1] NA
ggplot(summary_df, aes(y=y, x=x, ymin=ymin, ymax=ymax)) + geom_errorbar()

# setting the parameter (or aesthetic mapping) explicitly does work
ggplot(summary_df, aes(y=y, x=x, ymin=ymin, ymax=ymax)) + geom_errorbar(width = 0)

Created on 2018-08-03 by the reprex package (v0.2.0).

The simplest way (and perhaps the most consistent with other geoms) is to actually remove the width and height aesthetics from errorbar and errorbarh - leaving them only as parameters and removing the ability to set global defaults altogether, as width is in geom_boxplot (noted in #2245) or fatten is in geom_pointrange (discussed in #2798), but this will break any existing users' plots that map the width/height to some data value. As @clauswilke notes, there is no real technical reason to limit the aesthetics available to users; we just also need to make sure that they are globally updatable with existing functions which will require either making them simply aesthetics (not also calculated parameters) or, if it is desirable to have dual parameter/aesthetics, we will likely need to adjust the order in which default aesthetics are applied and setup_data is called - or some similar solution.

paleolimbot commented 5 years ago

It's worth noting that the handling of the width aesthetic/parameter occasionally causes problems in other places as well (#3142).