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

MRG: use Matplotlib to detect new Matplotlib figures #1401

Merged
merged 15 commits into from Jun 27, 2023

Conversation

matthew-brett
Copy link
Contributor

This uses what appears to be the standard
idiom

to detect pending Matplotlib plots.

With this PR, we do detect plots generated by code such as:

res = plt.plot(range(10))

whereas previously we would have missed this as a plot generator, because
it was not a standalone expression.

Check Matplotlib fignums to look for new figures created during chunk.
@matthew-brett
Copy link
Contributor Author

I see that tests are failing, and detecting output differences, but I'm having some trouble replicating locally. Can I ask for hints as where to look to debug the test failures?

@t-kalinowski
Copy link
Member

Nice, this looks like a much better approach!

Do you know if we have to cache the result of get_fignums() between chunks? It might be good to add a test for this edge case, to make sure we don't call plt.show() too many times.

The relevant test file is: https://github.com/rstudio/reticulate/blob/main/tests/testthat/test-python-knitr-engine.R

To run locally and interactively, from the package directory you can evaluate the R expressions:

devtools::load_all()
testthat::test_file("tests/testthat/test-python-knitr-engine.R")

The test snapshots and resources are available under the parent folder, named "testthat/resources" and "testthat/_snaps", respectively.

Thank you!

@matthew-brett
Copy link
Contributor Author

OK - thanks - with those hints, I tracked down the failures. It turns out that, at least from document to document, there can be stray empty Matplotlib figures, resulting in multiple empty figures being generated, and then inserted into the output documents.

For now, I've just checked if pending figures are empty, and closed those found to be empty.

I did think about what to do if there were figures pending from before the chunk starts - but it seemed to me that a) I wasn't sure how those would come about, given the current mode, of always displaying figures if they arose in a chunk, and b) if they did come about - it seemed to me that the Jupyter way would be to display them - but I don't think there is a way to have panding figures from a Jupyter chunk.

@matthew-brett
Copy link
Contributor Author

Am I right in thinking that the current test failures are unrelated?

@matthew-brett
Copy link
Contributor Author

While I was looking at it - is this line safe?

https://github.com/rstudio/reticulate/blob/main/R/knitr-engine.R#L431

? Won't it error if Matplotib is not installed, and the user is using RStudio desktop, for example?

- reset matplot fig size each chunk
closes rstudio#1398

- call plt.close() instead of plt.clf() to ensure that plt.get_fignums() is cleared and so we can easily avoid calling plt.show() too many times.
@t-kalinowski
Copy link
Member

t-kalinowski commented Jun 26, 2023

I made some commits to the branch, but they diverged with the most recent force-push.
For now I pushed them to a separate branch here: https://github.com/rstudio/reticulate/tree/mpl-figure-check. Can you please merge/rebase/cherry-pick them into this branch, incorporating your most recent force push?

Re the import("matplotlib") question, that call should always succeed, since it's only called from a hook that is registered to run only after the first time the matplotlib module is imported successfully.

@t-kalinowski
Copy link
Member

t-kalinowski commented Jun 26, 2023

Pushed another commit to https://github.com/rstudio/reticulate/tree/mpl-figure-check tweaking NEWS

matthew-brett and others added 6 commits June 26, 2023 16:59
- reset matplot fig size each chunk
closes rstudio#1398

- call plt.close() instead of plt.clf() to ensure that plt.get_fignums() is cleared and so we can easily avoid calling plt.show() too many times.
@t-kalinowski
Copy link
Member

The failing tests are unrelated, they're due to a new scipy release. I'll fix on a different branch.

@t-kalinowski t-kalinowski merged commit 0902de4 into rstudio:main Jun 27, 2023
12 of 13 checks passed
@t-kalinowski
Copy link
Member

Many thanks @matthew-brett!

@matthew-brett
Copy link
Contributor Author

matthew-brett commented Jun 27, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants