KopfLab / ggstackplot

R package for stacked ggplots
https://ggstackplot.kopflab.org
Other
0 stars 0 forks source link

decide what to do with legends for additional aesthetics #10

Closed sebkopf closed 1 year ago

sebkopf commented 1 year ago

Adding additional aesthetics to the plot can be very desirable for differentiating data in each panel. But what should happen to the legends? please chime in @KopfLab/ggstackplot-team

library(ggstackplot)
#> Loading required package: ggplot2
ggstackplot(
  mtcars,
  x = mpg,
  y = c(wt, qsec, drat),
  color = c("#E41A1C", "#377EB8", "#4DAF4A"),
  template = ggplot() +
    aes(linetype = factor(cyl), shape = factor(cyl)) +
    geom_line() +
    geom_point(size = 3) +
    theme_bw() +
    theme(panel.grid = element_blank())
)

test

rabergj commented 1 year ago

@sebkopf seems like adding the linetype aesthetic could be useful for distinguishing between two data series with the same y axis, for example from different sites or different calibrations (see issue I just started: #11 ). Color would be one of the first aesthetics I'd go for to make those distinctions, but it's tied up in ggstackplot() already before we get to aes(). Thoughts?

rabergj commented 1 year ago

This legend question seems quite tricky. I've seen people put legends inside the stacked plot where appropriate, and leave legends out where they're not needed, like this:

Screenshot 2023-06-09 at 10 12 58 AM

But that's super case dependent, so any options would have to be very flexible.

Another possibility would be to have the legends appear on the opposite side of the y axis. I think that would allow them to line up on each side? And it would save a little space. But it might look weird.

A third possibility would just be to have one legend on top that captures everything in the stacked plot, but that might get unwieldy pretty quick.

Personally, I would prefer the first option, where you can turn on legends for just the subplots that you want and control their position manually. Is that possible to do? Or should we be focusing on an automated layout that looks best.

sebkopf commented 1 year ago

thanks for the input! the placement of individual panel legends is already possible but it's very roundabout, reprex below. Question is - should these kind of by-plot theme modifications be more straightforward to do as part of a ggstackplot argument, maybe something like features = list(p1 = theme(....), p2 = geom_point() + theme(....), p3 = NULL) - what do you all think @KopfLab/ggstackplot-team ?

Second question is: the combined title in one location or another, we could definitely pull that out but I'm not sure what the best approach is, maybe something akin to the simplify_shared_axis argument but simplify_shared_legend and shared_legend_size (how much space to reserve, wherever it is placed which can be taken from the template them)? Alternatively shared_legend_source = <panel number> (or NULL) and shared_legend_size since it might not always be obvious which plot the shared legend should be taken from. Alternatively to that both a simplify_shared_axis argument (TRUE/FALSE) with the shared_legend_source = 1 as default (but can be set by user to pick from a different panel)?

library(ggplot2)
library(ggstackplot)

# prep plot
stackplot <- 
  mtcars |>
  prepare_stackplot(
    x = mpg,  y = c(wt, qsec, drat),
    template = 
      ggplot() +
      aes(color = factor(cyl), linetype = factor(cyl), shape = factor(cyl)) +
      geom_line() +
      geom_point(size = 3) +
      theme_bw() +
      theme_stackplot() 
  )

# modify themes (or plots) manually
stackplot$theme[[1]] <- stackplot$theme[[1]] + theme(legend.position = c(0.8, 0.7))
stackplot$theme[[2]] <- stackplot$theme[[2]] + theme(legend.position = "left")

# assemble
stackplot |>
  assemble_stackplot()

Created on 2023-06-09 with reprex v2.0.2

sebkopf commented 1 year ago

alright, add argument is implemented and i think is a very flexible way to achieve lots of different customizations on the stackplots. See example on how to use this for legends below. I'd say for now maybe we call the features done and see if this is sufficient for the kind of legends placement and specification users might need since it doesn't come with any assumptions on our end and just gives the user full control. See all new examples in the features vignette section on the add argument: https://ggstackplot.kopflab.org/articles/features.html#the-add-argument - let me know what you think @KopfLab/ggstackplot-team

library(ggstackplot)
library(ggplot2)
mtcars |>
  ggstackplot(
    x = mpg,  y = c(wt, qsec, drat),
    color = c("#E41A1C", "#377EB8", "#4DAF4A"),
    template = 
      ggplot() + aes(linetype = factor(vs)) +
      geom_line() + theme_stackplot() +
      theme(legend.position = "none"),
    # re-include the middle panel legend on the plot
    # with some additional styling
    add = list(
      qsec = 
        theme(
          legend.position = c(0.2, 0.9),
          legend.title = element_text(size = 20),
          legend.text = element_text(size = 16),
          legend.background = element_rect(
            color = "black", fill = "gray90", linewidth = 0.5),
          legend.key = element_blank(),
          legend.direction = "horizontal"
        ) +
        labs(linetype = "VS")
    )
  )

Created on 2023-06-11 with reprex v2.0.2