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

Skip to content

Use matplotlib-inline instead of ipykernel.pylab #12817

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

Merged
merged 2 commits into from
Apr 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 38 additions & 16 deletions IPython/core/display.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ def reload(self):
with gzip.open(BytesIO(data), 'rt', encoding=encoding) as fp:
encoding = None
data = fp.read()

# decode data, if an encoding was specified
# We only touch self.data once since
# subclasses such as SVG have @data.setter methods
Expand Down Expand Up @@ -1155,7 +1155,12 @@ def reload(self):

@skip_doctest
def set_matplotlib_formats(*formats, **kwargs):
"""Select figure formats for the inline backend. Optionally pass quality for JPEG.
"""
.. deprecated:: 7.23

use `matplotlib_inline.backend_inline.set_matplotlib_formats()`

Select figure formats for the inline backend. Optionally pass quality for JPEG.

For example, this enables PNG and JPEG output with a JPEG quality of 90%::

Expand All @@ -1173,20 +1178,28 @@ def set_matplotlib_formats(*formats, **kwargs):
**kwargs
Keyword args will be relayed to ``figure.canvas.print_figure``.
"""
from IPython.core.interactiveshell import InteractiveShell
from IPython.core.pylabtools import select_figure_formats
# build kwargs, starting with InlineBackend config
kw = {}
from ipykernel.pylab.config import InlineBackend
cfg = InlineBackend.instance()
kw.update(cfg.print_figure_kwargs)
kw.update(**kwargs)
shell = InteractiveShell.instance()
select_figure_formats(shell, formats, **kw)
warnings.warn(
"`set_matplotlib_formats` is deprecated since IPython 7.23, directly "
"use `matplotlib_inline.backend_inline.set_matplotlib_formats()`",
DeprecationWarning,
stacklevel=2,
)

from matplotlib_inline.backend_inline import (
set_matplotlib_formats as set_matplotlib_formats_orig,
)

set_matplotlib_formats_orig(*formats, **kwargs)

@skip_doctest
def set_matplotlib_close(close=True):
"""Set whether the inline backend closes all figures automatically or not.
"""
.. deprecated:: 7.23

use `matplotlib_inline.backend_inline.set_matplotlib_close()`


Set whether the inline backend closes all figures automatically or not.

By default, the inline backend used in the IPython Notebook will close all
matplotlib figures automatically after each cell is run. This means that
Expand All @@ -1206,6 +1219,15 @@ def set_matplotlib_close(close=True):
Should all matplotlib figures be automatically closed after each cell is
run?
"""
from ipykernel.pylab.config import InlineBackend
cfg = InlineBackend.instance()
cfg.close_figures = close
warnings.warn(
"`set_matplotlib_close` is deprecated since IPython 7.23, directly "
"use `matplotlib_inline.backend_inline.set_matplotlib_close()`",
DeprecationWarning,
stacklevel=2,
)

from matplotlib_inline.backend_inline import (
set_matplotlib_close as set_matplotlib_close_orig,
)

set_matplotlib_close_orig(close)
3 changes: 2 additions & 1 deletion IPython/core/interactiveshell.py
Original file line number Diff line number Diff line change
Expand Up @@ -3514,6 +3514,7 @@ def enable_matplotlib(self, gui=None):
display figures inline.
"""
from IPython.core import pylabtools as pt
from matplotlib_inline.backend_inline import configure_inline_support
gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)

if gui != 'inline':
Expand All @@ -3527,7 +3528,7 @@ def enable_matplotlib(self, gui=None):
gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)

pt.activate_matplotlib(backend)
pt.configure_inline_support(self, backend)
configure_inline_support(self, backend)

# Now we must activate the gui pylab wants to use, and fix %run to take
# plot updates into account
Expand Down
135 changes: 52 additions & 83 deletions IPython/core/pylabtools.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,32 @@
# Distributed under the terms of the Modified BSD License.

from io import BytesIO
import warnings

from IPython.core.display import _pngxy
from IPython.utils.decorators import flag_calls

# If user specifies a GUI, that dictates the backend, otherwise we read the
# user's mpl default from the mpl rc structure
backends = {'tk': 'TkAgg',
'gtk': 'GTKAgg',
'gtk3': 'GTK3Agg',
'wx': 'WXAgg',
'qt4': 'Qt4Agg',
'qt5': 'Qt5Agg',
'qt': 'Qt5Agg',
'osx': 'MacOSX',
'nbagg': 'nbAgg',
'notebook': 'nbAgg',
'agg': 'agg',
'svg': 'svg',
'pdf': 'pdf',
'ps': 'ps',
'inline': 'module://ipykernel.pylab.backend_inline',
'ipympl': 'module://ipympl.backend_nbagg',
'widget': 'module://ipympl.backend_nbagg',
}
backends = {
"tk": "TkAgg",
"gtk": "GTKAgg",
"gtk3": "GTK3Agg",
"wx": "WXAgg",
"qt4": "Qt4Agg",
"qt5": "Qt5Agg",
"qt": "Qt5Agg",
"osx": "MacOSX",
"nbagg": "nbAgg",
"notebook": "nbAgg",
"agg": "agg",
"svg": "svg",
"pdf": "pdf",
"ps": "ps",
"inline": "module://matplotlib_inline.backend_inline",
"ipympl": "module://ipympl.backend_nbagg",
"widget": "module://ipympl.backend_nbagg",
}

# We also need a reverse backends2guis mapping that will properly choose which
# GUI support to activate based on the desired matplotlib backend. For the
Expand All @@ -44,12 +46,12 @@
backend2gui['WX'] = 'wx'
backend2gui['CocoaAgg'] = 'osx'
# And some backends that don't need GUI integration
del backend2gui['nbAgg']
del backend2gui['agg']
del backend2gui['svg']
del backend2gui['pdf']
del backend2gui['ps']
del backend2gui['module://ipykernel.pylab.backend_inline']
del backend2gui["nbAgg"]
del backend2gui["agg"]
del backend2gui["svg"]
del backend2gui["pdf"]
del backend2gui["ps"]
del backend2gui["module://matplotlib_inline.backend_inline"]

#-----------------------------------------------------------------------------
# Matplotlib utilities
Expand Down Expand Up @@ -96,10 +98,10 @@ def figsize(sizex, sizey):

def print_figure(fig, fmt='png', bbox_inches='tight', **kwargs):
"""Print a figure to an image, and return the resulting file data

Returned data will be bytes unless ``fmt='svg'``,
in which case it will be unicode.

Any keyword args are passed to fig.canvas.print_figure,
such as ``quality`` or ``bbox_inches``.
"""
Expand All @@ -112,7 +114,7 @@ def print_figure(fig, fmt='png', bbox_inches='tight', **kwargs):
if fmt == 'retina':
dpi = dpi * 2
fmt = 'png'

# build keyword args
kw = {
"format":fmt,
Expand Down Expand Up @@ -162,7 +164,7 @@ def mpl_runner(safe_execfile):
A function suitable for use as the ``runner`` argument of the %run magic
function.
"""

def mpl_execfile(fname,*where,**kw):
"""matplotlib-aware wrapper around safe_execfile.

Expand Down Expand Up @@ -243,7 +245,7 @@ def select_figure_formats(shell, formats, **kwargs):
bs = "%s" % ','.join([repr(f) for f in bad])
gs = "%s" % ','.join([repr(f) for f in supported])
raise ValueError("supported formats are: %s not %s" % (gs, bs))

if 'png' in formats:
png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))
if 'retina' in formats or 'png2x' in formats:
Expand Down Expand Up @@ -274,7 +276,7 @@ def find_gui_and_backend(gui=None, gui_select=None):
Returns
-------
A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
'WXAgg','Qt4Agg','module://ipykernel.pylab.backend_inline','agg').
'WXAgg','Qt4Agg','module://matplotlib_inline.backend_inline','agg').
"""

import matplotlib
Expand Down Expand Up @@ -308,7 +310,7 @@ def activate_matplotlib(backend):

import matplotlib
matplotlib.interactive(True)

# Matplotlib had a bug where even switch_backend could not force
# the rcParam to update. This needs to be set *before* the module
# magic of switch_backend().
Expand All @@ -329,11 +331,11 @@ def activate_matplotlib(backend):

def import_pylab(user_ns, import_all=True):
"""Populate the namespace with pylab-related values.

Imports matplotlib, pylab, numpy, and everything from pylab and numpy.

Also imports a few names from IPython (figsize, display, getfigs)

"""

# Import numpy as np/pyplot as plt are conventions we're trying to
Expand All @@ -346,12 +348,12 @@ def import_pylab(user_ns, import_all=True):
"plt = pyplot\n"
)
exec(s, user_ns)

if import_all:
s = ("from matplotlib.pylab import *\n"
"from numpy import *\n")
exec(s, user_ns)

# IPython symbols to add
user_ns['figsize'] = figsize
from IPython.display import display
Expand All @@ -361,59 +363,26 @@ def import_pylab(user_ns, import_all=True):


def configure_inline_support(shell, backend):
"""Configure an IPython shell object for matplotlib use.
"""
.. deprecated: 7.23

use `matplotlib_inline.backend_inline.configure_inline_support()`

Configure an IPython shell object for matplotlib use.

Parameters
----------
shell : InteractiveShell instance

backend : matplotlib backend
"""
# If using our svg payload backend, register the post-execution
# function that will pick up the results for display. This can only be
# done with access to the real shell object.
warnings.warn(
"`configure_inline_support` is deprecated since IPython 7.23, directly "
"use `matplotlib_inline.backend_inline.configure_inline_support()`",
DeprecationWarning,
stacklevel=2,
)

# Note: if we can't load the inline backend, then there's no point
# continuing (such as in terminal-only shells in environments without
# zeromq available).
try:
from ipykernel.pylab.backend_inline import InlineBackend
except ImportError:
return
import matplotlib
from matplotlib_inline.backend_inline import configure_inline_support_orig

cfg = InlineBackend.instance(parent=shell)
cfg.shell = shell
if cfg not in shell.configurables:
shell.configurables.append(cfg)

if backend == backends['inline']:
from ipykernel.pylab.backend_inline import flush_figures
shell.events.register('post_execute', flush_figures)

# Save rcParams that will be overwrittern
shell._saved_rcParams = {}
for k in cfg.rc:
shell._saved_rcParams[k] = matplotlib.rcParams[k]
# load inline_rc
matplotlib.rcParams.update(cfg.rc)
new_backend_name = "inline"
else:
from ipykernel.pylab.backend_inline import flush_figures
try:
shell.events.unregister('post_execute', flush_figures)
except ValueError:
pass
if hasattr(shell, '_saved_rcParams'):
matplotlib.rcParams.update(shell._saved_rcParams)
del shell._saved_rcParams
new_backend_name = "other"

# only enable the formats once -> don't change the enabled formats (which the user may
# has changed) when getting another "%matplotlib inline" call.
# See https://github.com/ipython/ipykernel/issues/29
cur_backend = getattr(configure_inline_support, "current_backend", "unset")
if new_backend_name != cur_backend:
# Setup the default figure format
select_figure_formats(shell, cfg.figure_formats, **cfg.print_figure_kwargs)
configure_inline_support.current_backend = new_backend_name
configure_inline_support_orig(shell, backend)
2 changes: 1 addition & 1 deletion IPython/core/tests/test_display.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def test_image_filename_defaults():
nt.assert_is_none(img._repr_jpeg_())

def _get_inline_config():
from ipykernel.pylab.config import InlineBackend
from matplotlib_inline.config import InlineBackend
return InlineBackend.instance()


Expand Down
9 changes: 6 additions & 3 deletions IPython/core/tests/test_pylabtools.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import nose.tools as nt

from matplotlib import pyplot as plt
import matplotlib_inline
import numpy as np

from IPython.core.getipython import get_ipython
Expand Down Expand Up @@ -167,13 +168,15 @@ def act_mpl(backend):
pt.activate_matplotlib = act_mpl
self._save_ip = pt.import_pylab
pt.import_pylab = lambda *a,**kw:None
self._save_cis = pt.configure_inline_support
pt.configure_inline_support = lambda *a,**kw:None
self._save_cis = matplotlib_inline.backend_inline.configure_inline_support
matplotlib_inline.backend_inline.configure_inline_support = (
lambda *a, **kw: None
)

def teardown(self):
pt.activate_matplotlib = self._save_am
pt.import_pylab = self._save_ip
pt.configure_inline_support = self._save_cis
matplotlib_inline.backend_inline.configure_inline_support = self._save_cis
import matplotlib
matplotlib.rcParams = self._saved_rcParams
matplotlib.rcParamsOrig = self._saved_rcParamsOrig
Expand Down
19 changes: 10 additions & 9 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,15 +191,16 @@
)

install_requires = [
'setuptools>=18.5',
'jedi>=0.16',
'decorator',
'pickleshare',
'traitlets>=4.2',
'prompt_toolkit>=2.0.0,<3.1.0,!=3.0.0,!=3.0.1',
'pygments',
'backcall',
'stack_data',
"setuptools>=18.5",
"jedi>=0.16",
"decorator",
"pickleshare",
"traitlets>=4.2",
"prompt_toolkit>=2.0.0,<3.1.0,!=3.0.0,!=3.0.1",
"pygments",
"backcall",
"stack_data",
"matplotlib-inline",
]

# Platform-specific dependencies:
Expand Down