Skip to content
Snippets Groups Projects
Commit 78440c60 authored by Gordon Ball's avatar Gordon Ball
Browse files

New upstream version 0.1.6

parent a2bddc71
No related branches found
No related tags found
No related merge requests found
BSD 3-Clause License
Copyright (c) 2019,
Copyright (c) 2019-2022, IPython Development Team.
All rights reserved.
Redistribution and use in source and binary forms, with or without
......
# Matplotlib Inline Back-end for IPython and Jupyter
This package provides support for matplotlib to display figures directly inline in the Jupyter notebook and related clients, as shown below.
## Installation
With conda:
```bash
conda install -c conda-forge notebook matplotlib
conda install -c conda-forge matplotlib-inline
```
With pip:
```bash
pip install notebook matplotlib
pip install matplotlib-inline
```
## Usage
This package is included in IPython and can be used in a Jupyter Notebook:
Note that in current versions of JupyterLab and Jupyter Notebook, the explicit use of the `%matplotlib inline` directive is not needed anymore, though other third-party clients may still require it.
This will produce a figure immediately below:
```python
%matplotlib inline
......@@ -28,3 +32,7 @@ x = np.linspace(0, 3*np.pi, 500)
plt.plot(x, np.sin(x**2))
plt.title('A simple chirp');
```
## License
Licensed under the terms of the BSD 3-Clause License, by the IPython Development Team (see `LICENSE` file).
from . import backend_inline, config # noqa
__version__ = "0.1.6" # noqa
......@@ -4,13 +4,11 @@
# Distributed under the terms of the BSD 3-Clause License.
import matplotlib
from matplotlib.backends.backend_agg import ( # noqa
new_figure_manager,
FigureCanvasAgg,
new_figure_manager_given_figure,
)
from matplotlib import colors
from matplotlib.backends import backend_agg
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib._pylab_helpers import Gcf
from matplotlib.figure import Figure
from IPython.core.interactiveshell import InteractiveShell
from IPython.core.getipython import get_ipython
......@@ -20,6 +18,57 @@ from IPython.display import display
from .config import InlineBackend
def new_figure_manager(num, *args, FigureClass=Figure, **kwargs):
"""
Return a new figure manager for a new figure instance.
This function is part of the API expected by Matplotlib backends.
"""
return new_figure_manager_given_figure(num, FigureClass(*args, **kwargs))
def new_figure_manager_given_figure(num, figure):
"""
Return a new figure manager for a given figure instance.
This function is part of the API expected by Matplotlib backends.
"""
manager = backend_agg.new_figure_manager_given_figure(num, figure)
# Hack: matplotlib FigureManager objects in interacive backends (at least
# in some of them) monkeypatch the figure object and add a .show() method
# to it. This applies the same monkeypatch in order to support user code
# that might expect `.show()` to be part of the official API of figure
# objects. For further reference:
# https://github.com/ipython/ipython/issues/1612
# https://github.com/matplotlib/matplotlib/issues/835
if not hasattr(figure, 'show'):
# Queue up `figure` for display
figure.show = lambda *a: display(
figure, metadata=_fetch_figure_metadata(figure))
# If matplotlib was manually set to non-interactive mode, this function
# should be a no-op (otherwise we'll generate duplicate plots, since a user
# who set ioff() manually expects to make separate draw/show calls).
if not matplotlib.is_interactive():
return manager
# ensure current figure will be drawn, and each subsequent call
# of draw_if_interactive() moves the active figure to ensure it is
# drawn last
try:
show._to_draw.remove(figure)
except ValueError:
# ensure it only appears in the draw list once
pass
# Queue up the figure for drawing in next show() call
show._to_draw.append(figure)
show._draw_called = True
return manager
def show(close=None, block=None):
"""Show all figures as SVG/PNG payloads sent to the IPython clients.
......@@ -56,51 +105,6 @@ show._draw_called = False
show._to_draw = []
def draw_if_interactive():
"""
Is called after every pylab drawing command
"""
# signal that the current active figure should be sent at the end of
# execution. Also sets the _draw_called flag, signaling that there will be
# something to send. At the end of the code execution, a separate call to
# flush_figures() will act upon these values
manager = Gcf.get_active()
if manager is None:
return
fig = manager.canvas.figure
# Hack: matplotlib FigureManager objects in interacive backends (at least
# in some of them) monkeypatch the figure object and add a .show() method
# to it. This applies the same monkeypatch in order to support user code
# that might expect `.show()` to be part of the official API of figure
# objects.
# For further reference:
# https://github.com/ipython/ipython/issues/1612
# https://github.com/matplotlib/matplotlib/issues/835
if not hasattr(fig, 'show'):
# Queue up `fig` for display
fig.show = lambda *a: display(fig, metadata=_fetch_figure_metadata(fig))
# If matplotlib was manually set to non-interactive mode, this function
# should be a no-op (otherwise we'll generate duplicate plots, since a user
# who set ioff() manually expects to make separate draw/show calls).
if not matplotlib.is_interactive():
return
# ensure current figure will be drawn, and each subsequent call
# of draw_if_interactive() moves the active figure to ensure it is
# drawn last
try:
show._to_draw.remove(fig)
except ValueError:
# ensure it only appears in the draw list once
pass
# Queue up the figure for drawing in next show() call
show._to_draw.append(fig)
show._draw_called = True
def flush_figures():
"""Send all figures that changed
......@@ -115,19 +119,20 @@ def flush_figures():
if not show._draw_called:
return
if InlineBackend.instance().close_figures:
# ignore the tracking, just draw and close all figures
try:
return show(True)
except Exception as e:
# safely show traceback if in IPython, else raise
ip = get_ipython()
if ip is None:
raise e
else:
ip.showtraceback()
return
try:
if InlineBackend.instance().close_figures:
# ignore the tracking, just draw and close all figures
try:
return show(True)
except Exception as e:
# safely show traceback if in IPython, else raise
ip = get_ipython()
if ip is None:
raise e
else:
ip.showtraceback()
return
# exclude any figures that were closed:
active = set([fm.canvas.figure for fm in Gcf.get_all_fig_managers()])
for fig in [fig for fig in show._to_draw if fig in active]:
......
......@@ -32,26 +32,19 @@ class InlineBackendConfig(SingletonConfigurable):
class InlineBackend(InlineBackendConfig):
"""An object to store configuration of the inline backend."""
# The typical default figure size is too large for inline use,
# so we shrink the figure size to 6x4, and tweak fonts to
# make that fit.
# While we are deprecating overriding matplotlib defaults out of the
# box, this structure should remain here (empty) for API compatibility
# and the use of other tools that may need it. Specifically Spyder takes
# advantage of it.
# See https://github.com/ipython/ipython/issues/10383 for details.
rc = Dict(
{
'figure.figsize': (6.0, 4.0),
# play nicely with white background in the Qt and notebook frontend
'figure.facecolor': (1, 1, 1, 0),
'figure.edgecolor': (1, 1, 1, 0),
# 12pt labels get cutoff on 6x4 logplots, so use 10pt.
'font.size': 10,
# 72 dpi matches SVG/qtconsole
# this only affects PNG export, as SVG has no dpi setting
'figure.dpi': 72,
# 10pt still needs a little more room on the xlabel:
'figure.subplot.bottom': .125
},
help="""Subset of matplotlib rcParams that should be different for the
inline backend."""
).tag(config=True)
{},
help="""Dict to manage matplotlib configuration defaults in the inline
backend. As of v0.1.4 IPython/Jupyter do not override defaults out of
the box, but third-party tools may use it to manage rc data. To change
personal defaults for matplotlib, use matplotlib's configuration
tools, or customize this class in your `ipython_config.py` file for
IPython/Jupyter-specific usage.""").tag(config=True)
figure_formats = Set(
{'png'},
......
[metadata]
name = matplotlib-inline
version = 0.1.3
version = attr: matplotlib_inline.__version__
description = Inline Matplotlib backend for Jupyter
long_description = file: README.md, LICENSE
long_description_content_type = text/markdown
author = IPython Development Team
author_email = ipython-dev@scipy.org
url = https://github.com/ipython/matplotlib-inline
......@@ -27,3 +29,4 @@ classifiers =
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment