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
Closed
6 changes: 6 additions & 0 deletions doc/api/next_api_changes/deprecations/17891-BDD.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Removing ``ipython_inline_display`` from Webagg backend
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The function ``matplotlib.backends.backend_webagg.ipython_inline_display`` is
deprecated. It relies on outdated functionality of the tornado server and
asyncio event loop and appears to be broken.
7 changes: 7 additions & 0 deletions doc/users/next_whats_new/figure_repr_png.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Add ``_repr_png_`` for figures with no configured IPython backend
-----------------------------------------------------------------

Previously, IPython would not show figures as images unless using the
``matplotlib.pyplot`` interface or with an IPython magic statement like
``%matplotlib backend``. Now, no magic is required to view PNG figure
representations.
20 changes: 20 additions & 0 deletions lib/matplotlib/backend_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -1701,6 +1701,26 @@ def __init__(self, figure):
self.toolbar = None # NavigationToolbar2 will set me
self._is_idle_drawing = False

def _repr_png_(self):
"""Generate a PNG representation of the FigureCanvasBase."""
# Defer to IPython to handle output if possible.
if 'IPython' in sys.modules:
from IPython.core.pylabtools import configure_inline_support
# Check whether %matplotlib was run.
if hasattr(configure_inline_support, 'current_backend'):
return

png_bytes = io.BytesIO()
self.print_figure(
png_bytes,
format='png',
facecolor=self.figure.get_facecolor(),
edgecolor=self.figure.get_edgecolor(),
dpi=self.figure.dpi,
bbox_inches=self.figure.bbox_inches
)
return png_bytes.getvalue()

@classmethod
@functools.lru_cache()
def _fix_ipython_backend2gui(cls):
Expand Down
2 changes: 2 additions & 0 deletions lib/matplotlib/backends/backend_webagg.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import tornado.websocket

import matplotlib as mpl
from matplotlib import cbook
from matplotlib.backend_bases import _Backend
from matplotlib._pylab_helpers import Gcf
from . import backend_webagg_core as core
Expand Down Expand Up @@ -282,6 +283,7 @@ def catch_sigint():
ioloop.start()


@cbook.deprecated("3.4")
def ipython_inline_display(figure):
import tornado.template

Expand Down
14 changes: 4 additions & 10 deletions lib/matplotlib/figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,16 +365,10 @@ def __init__(self,
# list of child gridspecs for this figure
self._gridspecs = []

# TODO: I'd like to dynamically add the _repr_html_ method
# to the figure in the right context, but then IPython doesn't
# use it, for some reason.

def _repr_html_(self):
# We can't use "isinstance" here, because then we'd end up importing
# webagg unconditionally.
if 'WebAgg' in type(self.canvas).__name__:
from matplotlib.backends import backend_webagg
return backend_webagg.ipython_inline_display(self)
def _repr_png_(self):
"""Generate a PNG representation of the Figure."""
if hasattr(self.canvas, '_repr_png_'):
return self.canvas._repr_png_()

def show(self, warn=True):
"""
Expand Down
8 changes: 8 additions & 0 deletions lib/matplotlib/tests/test_figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,14 @@ def test_hashable_keys(self, fig_test, fig_ref):
fig_ref.subplot_mosaic([["A", "B"]])


def test_figure_repr_png():
from matplotlib.figure import Figure
fig = Figure(figsize=(4, 2))
ax = fig.add_subplot()
png_bytes = fig._repr_png_()
assert len(png_bytes) > 0


def test_reused_gridspec():
"""Test that these all use the same gridspec"""
fig = plt.figure()
Expand Down