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

Skip to content

RF: always close old figure windows #3916

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
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
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ matrix:
env: BUILD_DOCS=true

install:
- pip install -q --use-mirrors nose python-dateutil $NUMPY pep8 pyparsing pillow
- pip install -q --use-mirrors nose python-dateutil $NUMPY pep8 pyparsing pillow sphinx
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you also remove the sphinx installation on line 30?

- sudo apt-get update && sudo apt-get -qq install inkscape libav-tools gdb
# We use --no-install-recommends to avoid pulling in additional large latex docs that we don't need

Expand All @@ -33,7 +33,7 @@ install:
- |
if [[ $BUILD_DOCS == true ]]; then
sudo apt-get install -qq --no-install-recommends dvipng texlive-latex-base texlive-latex-extra texlive-fonts-recommended graphviz
pip install sphinx numpydoc linkchecker
pip install numpydoc linkchecker
wget http://mirrors.kernel.org/ubuntu/pool/universe/f/fonts-humor-sans/fonts-humor-sans_1.0-1_all.deb
sudo dpkg -i fonts-humor-sans_1.0-1_all.deb
wget https://googlefontdirectory.googlecode.com/hg/ofl/felipa/Felipa-Regular.ttf
Expand Down
8 changes: 8 additions & 0 deletions doc/users/whats_new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ New backend selection
The environment variable :envvar:`MPLBACKEND` can now be used to set the
matplotlib backend.

New ``close-figs`` argument for plot directive
----------------------------------------------

Matplotlib has a sphinx extension ``plot_directive`` that creates plots for
inclusion in sphinx documents. Matplotlib 1.5 adds a new option to the plot
directive - ``close-figs`` - that closes any previous figure windows before
creating the plots. This can help avoid some surprising duplicates of plots
when using ``plot_directive``.

.. _whats-new-1-4:

Expand Down
1 change: 1 addition & 0 deletions lib/matplotlib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1440,6 +1440,7 @@ def tk_window_focus():
'matplotlib.tests.test_transforms',
'matplotlib.tests.test_triangulation',
'matplotlib.tests.test_widgets',
'matplotlib.sphinxext.tests.test_tinypages',
'mpl_toolkits.tests.test_mplot3d',
'mpl_toolkits.tests.test_axes_grid1',
]
Expand Down
43 changes: 28 additions & 15 deletions lib/matplotlib/sphinxext/plot_directive.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,11 @@
If provided, the code will be run in the context of all
previous plot directives for which the `:context:` option was
specified. This only applies to inline code plot directives,
not those run from files. If the ``:context: reset`` is specified,
the context is reset for this and future plots.
not those run from files. If the ``:context: reset`` option is
specified, the context is reset for this and future plots, and
previous figures are closed prior to running the code.
``:context:close-figs`` keeps the context but closes previous figures
before running the code.

nofigs : bool
If specified, the code block will be run, but no figures will
Expand Down Expand Up @@ -190,11 +193,9 @@ def _option_boolean(arg):


def _option_context(arg):
if arg in [None, 'reset']:
if arg in [None, 'reset', 'close-figs']:
return arg
else:
raise ValueError("argument should be None or 'reset'")
return directives.choice(arg, ('None', 'reset'))
raise ValueError("argument should be None or 'reset' or 'close-figs'")


def _option_format(arg):
Expand Down Expand Up @@ -333,8 +334,8 @@ def remove_coding(text):
"""
Remove the coding comment, which six.exec_ doesn't like.
"""
return re.sub(
"^#\s*-\*-\s*coding:\s*.*-\*-$", "", text, flags=re.MULTILINE)
sub_re = re.compile("^#\s*-\*-\s*coding:\s*.*-\*-$", flags=re.MULTILINE)
return sub_re.sub("", text)

#------------------------------------------------------------------------------
# Template
Expand Down Expand Up @@ -524,7 +525,8 @@ def clear_state(plot_rcparams, close=True):


def render_figures(code, code_path, output_dir, output_base, context,
function_name, config, context_reset=False):
function_name, config, context_reset=False,
close_figs=False):
"""
Run a pyplot script and save the low and high res PNGs and a PDF
in *output_dir*.
Expand Down Expand Up @@ -600,11 +602,16 @@ def render_figures(code, code_path, output_dir, output_base, context,

if context_reset:
clear_state(config.plot_rcparams)
plot_context.clear()

close_figs = not context or close_figs

for i, code_piece in enumerate(code_pieces):

if not context or config.plot_apply_rcparams:
clear_state(config.plot_rcparams, close=not context)
clear_state(config.plot_rcparams, close_figs)
elif close_figs:
plt.close('all')

run_code(code_piece, code_path, ns, function_name)

Expand Down Expand Up @@ -644,8 +651,8 @@ def run(arguments, content, options, state_machine, state, lineno):
nofigs = 'nofigs' in options

options.setdefault('include-source', config.plot_include_source)
context = 'context' in options
context_reset = True if (context and options['context'] == 'reset') else False
keep_context = 'context' in options
context_opt = None if not keep_context else options['context']

rst_file = document.attributes['source']
rst_dir = os.path.dirname(rst_file)
Expand Down Expand Up @@ -729,9 +736,15 @@ def run(arguments, content, options, state_machine, state, lineno):

# make figures
try:
results = render_figures(code, source_file_name, build_dir, output_base,
context, function_name, config,
context_reset=context_reset)
results = render_figures(code,
source_file_name,
build_dir,
output_base,
keep_context,
function_name,
config,
context_reset=context_opt == 'reset',
close_figs=context_opt == 'close-figs')
errors = []
except PlotError as err:
reporter = state.memo.reporter
Expand Down
1 change: 1 addition & 0 deletions lib/matplotlib/sphinxext/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Make tests a package
85 changes: 85 additions & 0 deletions lib/matplotlib/sphinxext/tests/test_tinypages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
""" Tests for tinypages build using sphinx extensions """

import shutil
import tempfile

from os.path import (join as pjoin, dirname, isdir)

from subprocess import call, Popen, PIPE

from nose import SkipTest
from nose.tools import assert_true

HERE = dirname(__file__)
TINY_PAGES = pjoin(HERE, 'tinypages')


def setup():
# Check we have the sphinx-build command
try:
ret = call(['sphinx-build', '--help'], stdout=PIPE, stderr=PIPE)
except OSError:
raise SkipTest('Need sphinx-build on path for these tests')
if ret != 0:
raise RuntimeError('sphinx-build does not return 0')


def file_same(file1, file2):
with open(file1, 'rb') as fobj:
contents1 = fobj.read()
with open(file2, 'rb') as fobj:
contents2 = fobj.read()
return contents1 == contents2


class TestTinyPages(object):
# Test build and output of tinypages project

@classmethod
def setup_class(cls):
cls.page_build = tempfile.mkdtemp()
try:
cls.html_dir = pjoin(cls.page_build, 'html')
cls.doctree_dir = pjoin(cls.page_build, 'doctrees')
# Build the pages with warnings turned into errors
cmd = ['sphinx-build', '-W', '-b', 'html',
'-d', cls.doctree_dir,
TINY_PAGES,
cls.html_dir]
proc = Popen(cmd, stdout=PIPE, stderr=PIPE)
out, err = proc.communicate()
except Exception as e:
shutil.rmtree(cls.page_build)
raise e
if proc.returncode != 0:
shutil.rmtree(cls.page_build)
raise RuntimeError('sphinx-build failed with stdout:\n'
'{0}\nstderr:\n{1}\n'.format(
out, err))

@classmethod
def teardown_class(cls):
shutil.rmtree(cls.page_build)

def test_some_plots(self):
assert_true(isdir(self.html_dir))

def plot_file(num):
return pjoin(self.html_dir, 'some_plots-{0}.png'.format(num))

range_10, range_6, range_4 = [plot_file(i) for i in range(1, 4)]
# Plot 5 is range(6) plot
assert_true(file_same(range_6, plot_file(5)))
# Plot 7 is range(4) plot
assert_true(file_same(range_4, plot_file(7)))
# Plot 11 is range(10) plot
assert_true(file_same(range_10, plot_file(11)))
# Plot 12 uses the old range(10) figure and the new range(6) figure
assert_true(file_same(range_10, plot_file('12_00')))
assert_true(file_same(range_6, plot_file('12_01')))
# Plot 13 shows close-figs in action
assert_true(file_same(range_4, plot_file(13)))
# Plot 14 has included source
with open(pjoin(self.html_dir, 'some_plots.html'), 'rt') as fobj:
html_contents = fobj.read()
assert_true('# Only a comment' in html_contents)
1 change: 1 addition & 0 deletions lib/matplotlib/sphinxext/tests/tinypages/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
_build/
3 changes: 3 additions & 0 deletions lib/matplotlib/sphinxext/tests/tinypages/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Test project for matplotlib sphinx extensions

A tiny sphinx project from ``sphinx-quickstart`` with all default answers.
Empty file.
7 changes: 7 additions & 0 deletions lib/matplotlib/sphinxext/tests/tinypages/_static/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
##############################
Static directory for tinypages
##############################

We need this README file to make sure the ``_static`` directory gets created
in the installation. The tests check for warnings in builds, and, when the
``_static`` directory is absent, this raises a warning.
Loading