wilkelab / cowplot

cowplot: Streamlined Plot Theme and Plot Annotations for ggplot2
https://wilkelab.org/cowplot/
704 stars 84 forks source link

plots with additional layer with `draw_label` can't be modified with `ggplot2` functions #107

Closed IndrajeetPatil closed 6 years ago

IndrajeetPatil commented 6 years ago

I am wondering if there is any possibility that the plot containing a layer drawn using draw_label can still be modified further with ggplot2 functions. I am a bit confused because the class of object from cowplot is still ggplot and so not sure why the layers can no longer be modified.

# loading needed libraries
library(ggplot2)
library(cowplot)

# basic plot
p1 <- ggplot(mpg, aes(displ, cty)) + geom_point()

# further modification with ggplot2 functions
p1 + labs(title = "Dataset: mpg")


# adding a label to the plot
p2 <- ggdraw(p1) +
  draw_label("Draft",
             colour = "grey",
             size = 120,
             angle = 45)

# further modification with ggplot2 functions
p2 + labs(title = "Dataset: mpg")

Created on 2018-08-25 by the reprex package (v0.2.0.9000).

clauswilke commented 6 years ago

You can further modify the enclosing ggplot object that ggdraw() generates, but you need to use a theme that draws the elements you want to see.

# loading needed libraries
library(ggplot2)
library(cowplot)
#> 
#> 
#> *******************************************************
#> Note: cowplot does not change the default ggplot2 theme
#> anymore. To recover the previous behavior, execute:
#>   theme_set(theme_cowplot())
#> *******************************************************

# basic plot
p1 <- ggplot(mpg, aes(displ, cty)) + geom_point()

p2 <- ggdraw(p1) +
  draw_label("Draft",
             colour = "grey",
             size = 120,
             angle = 45)

# further modification with ggplot2 functions
p2 + labs(title = "Dataset: mpg") + theme_void()

p2 + labs(title = "Dataset: mpg") + theme_bw() + xlim(0, 1) + ylim(0, 1)
#> Scale for 'x' is already present. Adding another scale for 'x', which
#> will replace the existing scale.
#> Scale for 'y' is already present. Adding another scale for 'y', which
#> will replace the existing scale.

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

IndrajeetPatil commented 6 years ago

Thanks. This solves the issue of modifying elements that are absent from the original plot, but what if I want to modify the existing element? For example, changing the title from "Hello" to "Dataset: mpg" rather than adding it on top?

(I'm curious about this because my function outputs plots with certain defaults and I want users to still have the ability to modify the plot anyway they like. For example, changing the x-axis labels. But I am guessing ggdraw() outputs a fixed plot and all further modifications are done on top of this fixed plot but nothing within the plot itself?)

library(ggplot2)
library(cowplot)
#> 
#> 
#> *******************************************************
#> Note: cowplot does not change the default ggplot2 theme
#> anymore. To recover the previous behavior, execute:
#>   theme_set(theme_cowplot())
#> *******************************************************

# basic plot
p1 <- ggplot(mpg, aes(displ, cty)) + geom_point() + labs(title = "Hello")

p2 <- ggdraw(p1) +
  draw_label("Draft",
             colour = "grey",
             size = 120,
             angle = 45)

# further modification with ggplot2 functions
p2 + labs(title = "Dataset: mpg") + theme_void()

Created on 2018-08-26 by the reprex package (v0.2.0.9000).

clauswilke commented 6 years ago

That’s correct. ggdraw() takes a snapshot of the plot and then enables you to draw on top of it. If you want to return a fully modifyable ggplot object then you can’t stick it into ggdraw() inside your function. I would say though that almost anything except combining multiple plots can be done directly from ggplot. There’s probably no need for ggdraw() for whatever it is you want to do.