wilkelab / cowplot

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

Cowplot breaks ggtern #88

Open Fitzgabbro opened 6 years ago

Fitzgabbro commented 6 years ago

When cowplot is loaded, ggtern (for plotting ternary diagrams using ggplot2) fails to plot anything and returns the error:

Warning in if (x) { : argument is of length zero Error in if (zero_range(as.numeric(limits))) { : missing value where TRUE/FALSE needed

clauswilke commented 6 years ago

Please provide a minimal reproducible example.

Fitzgabbro commented 6 years ago

Sorry, here's a minimal working example:

require(ggplot2)
require(ggtern)

df <- data.frame(
  x = c(1,7,5),
  y = c(7,2,6),
  z = c(1,1,7)
)

ggtern(data = df, aes(x=x, y=y, z=z)) +
  geom_point()

produces: delwedd

As soon as I add cowplot, I get an error. This code:

require(ggplot2)
require(ggtern)
require(cowplot)

df <- data.frame(
  x = c(1,7,5),
  y = c(7,2,6),
  z = c(1,1,7)
)

ggtern(data = df, aes(x=x, y=y, z=z)) +
  geom_point()

Produces the error:

Error in if (zero_range(as.numeric(limits))) { : missing value where TRUE/FALSE needed In addition: Warning message: In if (x) { : argument is of length zero

clauswilke commented 6 years ago

I can't properly debug this at this time because ggtern does not seem to work with the current development version of ggplot2. In either case, it looks like the cowplot theme is at fault. ggtern adds a lot of elements to the theme and cowplot doesn't know that. There should be two workarounds:

  1. Try theme_set(theme_gray()) after loading cowplot and see if that fixes things.

  2. Don't load cowplot at all, just call its functions via cowplot::..., e.g. cowplot::plot_grid().

Fitzgabbro commented 6 years ago

Using theme_set(theme_gray()) works perfectly with one ternary plot.

Using plot_grid() sort of works, but the axes go a bit funny (both if I call it using cowplot::, or if I use theme_set(theme_gray()). For example

require(ggplot2)
require(ggtern)

df <- data.frame(
  x = c(1,7,5),
  y = c(7,2,6),
  z = c(1,1,7)
)

Plot1 <- ggtern(data = df, aes(x=x, y=y, z=z)) +
  geom_point()

Plot2 <- ggplot(data = df, aes (x=x, y=y)) +
  geom_point()

cowplot::plot_grid(Plot1, Plot2)

produces this figure: delwedd

Anyway, thanks for taking the time to help. The first workaround will do what I want for the moment. It would be nice to be able to use plot_grid() with ternary plots in the future, but I understand that maybe it wouldn't be such a widely used feature...

clauswilke commented 6 years ago

Try the following:

gg <- ggplotGrob(Plot1)
cowplot::plot_grid(gg, Plot2)

The problem is that ggtern replaces all the default ggplot2 functions and cowplot doesn't know that and continues to call the functions from the ggplot2 namespace, not the ggtern one. There isn't a good way to fix this, because ggplot2 was not written for what ggtern does to it.