Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add _repr_png_ for figures with no configured IPython backend #17891

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

Closed
wants to merge 16 commits into from

Conversation

bdice
Copy link
Contributor

@bdice bdice commented Jul 11, 2020

PR Summary

This PR continues work started by @tdpetrou in #16788. I applied some suggested changes from the previous PR review and changed from _repr_html_ to _repr_png_ after conversation with @tacaswell and @Carreau.

Resolves #16782.

PR Checklist

  • Has Pytest style unit tests
  • Code is Flake 8 compliant
  • New features are documented, with examples if plot related
  • Documentation is sphinx and numpydoc compliant
  • Added an entry to doc/users/next_whats_new/ if major new feature (follow instructions in README.rst there)
  • Documented in doc/api/next_api_changes/* if API changed in a backward-incompatible way

@bdice bdice force-pushed the _repr_png_-inline-figures branch from 46e810e to 1f94c51 Compare July 11, 2020 21:29
@bdice bdice marked this pull request as ready for review July 11, 2020 22:30
@tacaswell
Copy link
Member

We talked about this on the phone at the end of day 1 scipy sprints when my brain was turning to mush.

The quandary (quagmire?) we are trying to get our selves out of is that

a) we want to use the standard IPython/jupyter protocols as much as possible
b) there is a long history of special casing things (on all sides) to "make it work"
c) attempts to do a) tend to run afoul of b)

The things we want to work in notebooks / jlab

fig = plt.figure()
fig, ax = plt.subplots()

should show the figure even though the Figure is not the last thing in the cell (so not a candidate for the automatic display) and the user has not explicitly displayed it. You could argue that this is counter to a) above, but there is a decade of user expectation on this. If we find a process to achieve this within the constraints of a) that lets us drop all of b) that can presumable this could be extend to other libraries that want to fabricate complicated widgets and have them implicitly shown.

fig = plt.figure()
fig

This should show exactly once so that the implicit display from the first case and the automatic display from the second case do not conflict with each other.

fig # assuming this is defined in another cell

should also show the "correct" version of the Figure in the notebook.

Tangentially, we probably also want a clean way for ipympl / notebook to throw a snapshot of the current figure into the notebook. This can be very useful if you have a notebook that is progressively building a complex figure to get "snapshots" of the intermediate state. We are also using this to work around the issue with ipympl rendering a an empty figure when exported.

We also want to make sure that we do not render the figure N times (for example always including both a html and a png version which both have the png embedded) both for run time and payload size reasons (or find a way to manage the caching / data sharing).


Tools we have at our disposal

  • the _repr_*_ methods on the Figure and canvas objects
  • post-execute hooks (well, pre-execute too, but that seems not useful for us)
  • the ability to register higher-priority single-dispatch display logic with IPython / jupyter
  • explicit calls to display

I think the question with this PR is not if it solves all of the problems, but if it moves us forward along any direction (which I think it does in the case of a no-pyplot workflow) and if it paints us into an API corner that we will not be able to get out of (which I don't think it does because this is the lowest priority code path and all of the current special-casing will still win).

@tacaswell tacaswell added this to the v3.4.0 milestone Jul 12, 2020
@bdice
Copy link
Contributor Author

bdice commented Jul 12, 2020

@tacaswell I have confirmed that the following code cell renders a figure twice in Jupyter Lab, but the new code for _repr_png_ in this PR is not called. It must be something else in IPython / matplotlib causing that, which is best left for another issue / PR.

import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot()
fig

To the best of my knowledge / testing, this PR meets @tacaswell's stated goal:

I think the question with this PR is not if it solves all of the problems, but if it moves us forward along any direction (which I think it does in the case of a no-pyplot workflow) and if it paints us into an API corner that we will not be able to get out of (which I don't think it does because this is the lowest priority code path and all of the current special-casing will still win).

@tacaswell
Copy link
Member

@Carreau
Copy link
Contributor

Carreau commented Jul 12, 2020

It looks like there is some figure-level registration at ipython/ipython@8ad12b0/IPython/core/pylabtools.py#L209-L257

I'm happy to have a matplotlib version check there and do nothing if matplotlib.version >= whatever. I can even backport such a change to 7.x which is released monthly.

@tacaswell
Copy link
Member

For further details, ipympl works because ipywidgets implements _ipython_display_ (in widgets < 8 and _repr_mimbundle_ in 8+) on the canvas class.

_repr_mimebundle_ / _ipython_display_, but I am having trouble sorting out how to force it to down-grade to a png (maybe because it does not know about it yet?)

@tdpetrou
Copy link
Contributor

Great job @bdice for picking this up!

This is probably an unpopular opinion, but I think there should be a clean split between ipython and matplotlib. As far as I know, matplotlib is the only library that gets special cased.

Seems it would be much simpler if users just had to place fig as the last line of a notebook cell.

@jklymak
Copy link
Member

jklymak commented Jul 13, 2020

Seems it would be much simpler if users just had to place fig as the last line of a notebook cell.

Do you mean always, or only if the %matplotlib magic has not been called?

@QuLogic QuLogic added this to the v3.5.0 milestone Jan 22, 2021
@jklymak
Copy link
Member

jklymak commented May 10, 2021

This needs a rebase. It probably also needs a project manager... @tacaswell you are probably the best person to lead the charge on this?

@jklymak jklymak marked this pull request as draft May 10, 2021 19:45
@QuLogic QuLogic modified the milestones: v3.5.0, v3.6.0 Aug 23, 2021
@timhoffm timhoffm modified the milestones: v3.6.0, unassigned Apr 30, 2022
@story645 story645 modified the milestones: unassigned, needs sorting Oct 6, 2022
@bdice
Copy link
Contributor Author

bdice commented Jun 28, 2023

I'm not sure how to help this move forward. I am going to close this as a stale PR, but feel free to upstream/rebase anything you want from here!

@bdice bdice closed this Jun 28, 2023
@tacaswell tacaswell removed this from the future releases milestone Jun 29, 2023
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.

Add _repr_html_ for inline backend to eliminate need for %matplotlib inline
8 participants