-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Warning: Graphics device changes when using ggplotGrob
inside future::future_lapply
with multisession plan
#6464
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I have fought with these types of issues a lot in my cowplot package. The brief answer is converting a plot into a grob should ideally only be done when actually rendering the plot into an opened graphics device. Otherwise you will run into all sorts of issues. However, you could try the Here is the relevant source code, which is quite cumbersome and lists some of the problems that can arise in different settings: The reason why a graphics device needs to be open is that we need font metrics to generate the grob and we don't have access to font metrics without having a graphics device open. An additional problem is that the font metrics will (subtly) change for different graphics devices and settings (for example, for raster devices, they can depend on the size of the output image), so we're almost guaranteed to have incorrect font metrics if we convert to a grob outside of final rendering. Again, this is where we go back to the point that ideally we wouldn't do this in the first place. |
Thanks @clauswilke. I tried a couple of examples using
As it is necessary to open a device to get font metrics, how device is opened in ggplot and is it explicitly closed afterwards? My understanding is that this opens device (which is probably fine) without closing it. |
AFAIK ggplot2 doesn't open graphics devices explicitly except in |
I think I found a temporary solution that disables the
|
@teunbrand Yes, this is exactly what happens. If you request font metrics and no graphics device is open then R just opens one. |
Right, but that isn't really behaviour ggplot2 has any sensible control over so there isn't much to adapt in ggplot2's code, I think. |
It is possible to avoid it in ggplot2 at the cost of performance. Text rendering is clearly moving towards an A and B tier device support, so it is likely that e.g. the string dimensions we get from one device cannot sensibly be used with another device. It might make sense to investigate wether the performance benefit that prompted the upfront-unit conversion still exist today |
Uh oh!
There was an error while loading. Please reload this page.
When using
ggplot2::ggplotGrob()
(and indirectlyggExtra::ggMarginal()
) inside afuture::future_lapply()
call withplan(multisession)
, warnings appear related to unexpected graphics device changes. This breaks the expected isolation of child processes: child workers should not open or close graphics devices that persist outside their scope or cause side effects detectable by the parent.Specifically, the warnings mention that a new device (usually pdf) is opened without being closed properly, or the device state changes unexpectedly during the future evaluation.
This happens even when
dev.list()
returnsNULL
before execution, and attempts to pre-open and explicitly close devices inside the future expression (e.g., usinggrDevices::pdf()
anddev.off()
) do not fully suppress these warnings.This makes it difficult to safely use ggplot2 in parallel workflows using multisession futures, where device state consistency is critical.
Reprex:
Opening a temporary pdf device explicitly before plotting and closing it afterwards did not fully solve the issue:
What internal calls in
ggplot2::ggplotGrob()
or related grid functions might open a graphics device implicitly, especially in headless or parallel contexts?Is there a recommended way to preemptively open and close devices, or to prevent implicit device openings, when using ggplot2 grobs in parallel processes?
See also: futureverse/future#788
The text was updated successfully, but these errors were encountered: