Skip to content
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

Unless captureGraphics is turned off, plot output to devices other than the canvas gets swallowed #482

Open
christianp opened this issue Sep 13, 2024 · 3 comments
Labels
feature New feature or request

Comments

@christianp
Copy link
Contributor

christianp commented Sep 13, 2024

I've made an example at https://webr-issue-482-capturegraphics.think.somethingorotherwhatever.com/.

With the automatic canvas graphics capturing left turned on, graphics plotted to other devices such as SVG are lost if the initialisation of the device, the plot call, and dev.off() are in separate calls. The SVG file is created, but never filled.

Is it the case that with captureGraphics: true, a new canvas device is created for each call to Shelter.captureR?

@georgestagg
Copy link
Member

Is it the case that with captureGraphics: true, a new canvas device is created for each call to Shelter.captureR?

Yes, currently the following scheme is performed for each call to captureR(), when captureGraphics: true:

  • Note the currently active graphics device, as there may be multiple on the device stack.
  • Starts a new canvas() device, adding it to the device stack and making it the active device.
  • Runs the user code, then grabs any captured canvas device images.
  • Turns the canvas() device off, removing it from the stack.
  • Restores whatever device was active at the start.

So, setting captureGraphics: false means that your svg() device is made the active device in one call and then remains the active device over all the other calls until dev.off().

Do you think this behaviour should be different? I guess it could be made so that a canvas() device is only spun up if there are no other graphics device already on the stack. Is that the behaviour you were expecting?

@christianp
Copy link
Contributor Author

Yeah, I think that if there's already an active graphics device then the auto-capturing shouldn't interfere with it.

I don't know much about R though, so if people have reasons to have a long stack of graphics devices and would benefit from the current behaviour, I suppose I could do the check myself and set captureGraphics appropriately.

@georgestagg
Copy link
Member

georgestagg commented Sep 13, 2024

It's worth noting that the current behaviour matches that of the {evaluate} package. It has a similar setup when new_device = TRUE (the default) where a new capturing graphics device is started at the beginning of evaluation.

Non-wasm example:

$ R
[...]
> svglite::svglite()
> capture <- evaluate::evaluate("plot(123)")
> dev.off()
null device 
          1 
> q()
Save workspace image? [y/n/c]: n

$ cat Rplot001.svg 
$ wc -c Rplot001.svg 
       0 Rplot001.svg

So for consistency I think I'd like to match that behaviour by default.

Though I think we could maybe add an option to switch to the suggested alternative behaviour for Shelter.captureR().

@georgestagg georgestagg added the feature New feature or request label Oct 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants