hughjonesd/ggmagnify

background of inset

simonheb opened this issue · 11 comments

I have a graph with transparent background. I'd like to have the zoomed area use a plain color background (e.g. white) so that the original plot does not show through. is it possible to do that?

The problem emerges because the plot I want to magnify is extracted like this:

  gpanel <- ggpubr::as_ggplot(cowplot::get_legend(ggplot_object))
  gzoom <- ggmagnify(gpanel ,xlim = c(0.8, 1), ylim = c(0.8, 1),
                     inset_xlim = c(0, 0.5), inset_ylim = c(0, 0.5), zoom=2,
                     shadow = TRUE)

Try gzoom$inset <- gzoom$inset + theme(plot.background = "white")

You may need to readd inset_theme() afterwards

theme(plot.background = "white")

This gives me that:

gpanelzoom$inset + theme(plot.background="white")
Error in mapply(validate_element, theme, names(theme), MoreArgs = list(element_tree = get_element_tree())) : 
  The `plot.background` theme element must be a <element_rect> object.

This worked:
gpanelzoom$inset + theme(plot.background = element_rect(fill = 'white'))

What seems odd though, is that this also sets the background of the main plot to white, not only the inset. is there a way to do this only to the inset?

You added the theme to gzoom$inset, not just to gzoom?

If so please file a reproducible example.

The following works for me:

ggp <- ggplot(iris, aes(Sepal.Width, Sepal.Length, color = Species)) + geom_point() + theme(plot.background = element_rect(fill = NA))
ggp
ggm <- ggmagnify(ggp, xlim = 3:4, ylim = 5:6, inset_xlim = 2:3, inset_ylim = 7:8, shadow = TRUE, axes=TRUE)
ggm # plot background shows, shadow is only of panel
ggm$inset <- ggm$inset + theme(plot.background = element_rect(fill = "orange"))
ggm # inset background is orange, plot is unchanged

Ok, yes. As always, when I worked out the reproducible example I noticed that the problem came from elsewhere. The plot I was feeding to ggmagnify exports (via ggsave) to a png with transparent background. one I use ggmagnify (irrespecitve of what I do to the background of the inset) it does so only with ggsave( ... , bg='transparent'). So, I'll just use that now.

In case this is unintended behavior, here's the code to reproduce it:

library(ggraph)
library(igraph)
library(ggmagnify)
set.seed(1)

# some random network
g <- erdos.renyi.game(100,p=0.01,directed = TRUE)
E(g)$weight <- runif(gsize(g))

# some funny plot
ggobj <- ggraph(g) + 
  geom_edge_arc(aes(edge_width=weight), strength = 0.1) + 
  scale_edge_width(range=c(0.1,1)) + 
  theme_graph(base_family="sans")

# only using the panel here
gpanel  <- ggpubr::as_ggplot(cowplot::get_panel(ggobj))

# now magnify 
gpanelzoom <- ggmagnify(gpanel,xlim=c(0.4,0.5), ylim=c(0.4,0.5),
                        inset_xlim = c(0.6, 0.95), inset_ylim = c(0.6, 0.95), 
                        target_linewidth = 2)


ggsave(paste0("transparent.png"),gpanel,width=5,height=5)
ggsave(paste0("nottransparent.png"),gpanelzoom,width=5,height=5)
ggsave(paste0("transparentagain.png"),gpanelzoom,width=5,height=5,bg='transparent')

That's a legit bug. I guess it is because of what grid.draw.GgMagnify does. Hmm. Thanks.

Yeah, this is because of the following line in ggsave:

 bg <- calc_element("plot.background", plot_theme(plot))$fill %||% 
      "transparent"

There's nothing to be done about that. plot_theme is a private function, and within it it calls x$theme on the plot object. I suppose I could fake up a theme element but it just all feels too hacky.

The real solution is:

ggsave("filename", compose(ggm))

which will create a proper ggplot object from the ggm object, and save it correctly. Getting ggsave to work directly on ggm was always a bit of a hack...