##// END OF EJS Templates
use Popen instead of getstatusoutput to check for libedit....
use Popen instead of getstatusoutput to check for libedit. getstatusoutput uses os.popen, and is vulnerable to EINTR weirdness in environments such as gdb or PyQt. Exponential falloff is also used, to prevent waiting forever or firing requests too fast, though I haven't had it fire more than once after moving to Popen. closes gh-473

File last commit:

r3902:29735619
r3906:cf26ce8a
Show More
pylabtools.py
309 lines | 10.6 KiB | text/x-python | PythonLexer
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363 # -*- coding: utf-8 -*-
"""Pylab (matplotlib) support utilities.
Authors
-------
Brian Granger
Updating terminal GUI support to use guisupport.py for qt4/wx.
r2918
* Fernando Perez.
* Brian Granger
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363 """
#-----------------------------------------------------------------------------
# Copyright (C) 2009 The IPython Development Team
#
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------
Brian Granger
Work to address the review comments on Fernando's branch....
r2498
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363 #-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
Brian Granger
Work to address the review comments on Fernando's branch....
r2498
Brian Granger
Lots of work on the display system, focused on pylab stuff....
r3280 from cStringIO import StringIO
Brian Granger
Work to address the review comments on Fernando's branch....
r2498 from IPython.utils.decorators import flag_calls
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363
Fernando Perez
Add support for simultaneous interactive and inline matplotlib plots....
r2987 # 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',
'wx': 'WXAgg',
'qt': 'Qt4Agg', # qt3 not supported
'qt4': 'Qt4Agg',
MinRK
add 'osx' to known pylab backends, fix pylab mode with MacOSX backend...
r3462 'osx': 'MacOSX',
Fernando Perez
Renamed 'payload-svg' matplotlib backend to 'inline'.
r2991 'inline' : 'module://IPython.zmq.pylab.backend_inline'}
Fernando Perez
Add support for simultaneous interactive and inline matplotlib plots....
r2987
Fernando Perez
Fix support for raw GTK and WX matplotlib backends....
r3902 # We also need a reverse backends2guis mapping that will properly choose which
# GUI support to activate based on the desired matplotlib backend. For the
# most part it's just a reverse of the above dict, but we also need to add a
# few others that map to the same GUI manually:
backend2gui = dict(zip(backends.values(), backends.keys()))
# In the reverse mapping, there are a few extra valid matplotlib backends that
# map to the same GUI support
backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk'
backend2gui['WX'] = 'wx'
backend2gui['CocoaAgg'] = 'osx'
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363 #-----------------------------------------------------------------------------
Brian Granger
Lots of work on the display system, focused on pylab stuff....
r3280 # Matplotlib utilities
#-----------------------------------------------------------------------------
Brian Granger
Final work on display system....
r3288
def getfigs(*fig_nums):
"""Get a list of matplotlib figures by figure numbers.
If no arguments are given, all available figures are returned. If the
argument list contains references to invalid figures, a warning is printed
but the function continues pasting further figures.
Parameters
----------
figs : tuple
A tuple of ints giving the figure numbers of the figures to return.
"""
from matplotlib._pylab_helpers import Gcf
if not fig_nums:
fig_managers = Gcf.get_all_fig_managers()
return [fm.canvas.figure for fm in fig_managers]
else:
figs = []
for num in fig_nums:
f = Gcf.figs.get(num)
if f is None:
print('Warning: figure %s not available.' % num)
Brian Granger
Renaming the special methods of the formatters....
r3878 else:
figs.append(f.canvas.figure)
Brian Granger
Final work on display system....
r3288 return figs
Brian Granger
Lots of work on the display system, focused on pylab stuff....
r3280 def figsize(sizex, sizey):
"""Set the default figure size to be [sizex, sizey].
This is just an easy to remember, convenience wrapper that sets::
matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
"""
import matplotlib
matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
def figure_to_svg(fig):
"""Convert a figure to svg for inline display."""
Fernando Perez
Do not generate output for empty figures in Qt console....
r3731 # When there's an empty figure, we shouldn't return anything, otherwise we
# get big blank areas in the qt console.
if not fig.axes:
return
Brian Granger
Lots of work on the display system, focused on pylab stuff....
r3280 fc = fig.get_facecolor()
ec = fig.get_edgecolor()
fig.set_facecolor('white')
fig.set_edgecolor('white')
try:
string_io = StringIO()
fig.canvas.print_figure(string_io, format='svg')
svg = string_io.getvalue()
finally:
fig.set_facecolor(fc)
fig.set_edgecolor(ec)
return svg
# We need a little factory function here to create the closure where
# safe_execfile can live.
def mpl_runner(safe_execfile):
"""Factory to return a matplotlib-enabled runner for %run.
Parameters
----------
safe_execfile : function
This must be a function with the same interface as the
:meth:`safe_execfile` method of IPython.
Returns
-------
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.
Its interface is identical to that of the :func:`execfile` builtin.
This is ultimately a call to execfile(), but wrapped in safeties to
properly handle interactive rendering."""
import matplotlib
import matplotlib.pylab as pylab
#print '*** Matplotlib runner ***' # dbg
# turn off rendering until end of script
is_interactive = matplotlib.rcParams['interactive']
matplotlib.interactive(False)
safe_execfile(fname,*where,**kw)
matplotlib.interactive(is_interactive)
# make rendering call now, if the user tried to do it
if pylab.draw_if_interactive.called:
pylab.draw()
pylab.draw_if_interactive.called = False
return mpl_execfile
#-----------------------------------------------------------------------------
# Code for initializing matplotlib and importing pylab
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363 #-----------------------------------------------------------------------------
Brian Granger
Initial GUI support in kernel.
r2868 def find_gui_and_backend(gui=None):
"""Given a gui string return the gui and mpl backend.
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363
Parameters
----------
Brian Granger
Initial GUI support in kernel.
r2868 gui : str
Fernando Perez
Renamed 'payload-svg' matplotlib backend to 'inline'.
r2991 Can be one of ('tk','gtk','wx','qt','qt4','inline').
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363
Returns
-------
Brian Granger
Initial GUI support in kernel.
r2868 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
Fernando Perez
Renamed 'payload-svg' matplotlib backend to 'inline'.
r2991 'WXAgg','Qt4Agg','module://IPython.zmq.pylab.backend_inline').
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363 """
import matplotlib
if gui:
# select backend based on requested gui
Fernando Perez
Add support for simultaneous interactive and inline matplotlib plots....
r2987 backend = backends[gui]
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363 else:
backend = matplotlib.rcParams['backend']
# In this case, we need to find what the appropriate gui selection call
# should be for IPython, so we can activate inputhook accordingly
Fernando Perez
Fix support for raw GTK and WX matplotlib backends....
r3902 gui = backend2gui.get(backend, None)
Brian Granger
Initial GUI support in kernel.
r2868 return gui, backend
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363
Brian Granger
Initial GUI support in kernel.
r2868
def activate_matplotlib(backend):
"""Activate the given backend and set interactive to True."""
import matplotlib
if backend.startswith('module://'):
# Work around bug in matplotlib: matplotlib.use converts the
# backend_id to lowercase even if a module name is specified!
matplotlib.rcParams['backend'] = backend
else:
matplotlib.use(backend)
matplotlib.interactive(True)
Brian Granger
GUI support for wx, qt and tk.
r2872
# This must be imported last in the matplotlib series, after
# backend/interactivity choices have been made
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363 import matplotlib.pylab as pylab
Brian Granger
GUI support for wx, qt and tk.
r2872 # XXX For now leave this commented out, but depending on discussions with
# mpl-dev, we may be able to allow interactive switching...
#import matplotlib.pyplot
#matplotlib.pyplot.switch_backend(backend)
pylab.show._needmain = False
# We need to detect at runtime whether show() is called by the user.
# For this, we wrap it into a decorator which adds a 'called' flag.
pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363
Fernando Perez
Add support for simultaneous interactive and inline matplotlib plots....
r2987
def import_pylab(user_ns, backend, import_all=True, shell=None):
Brian Granger
Initial GUI support in kernel.
r2868 """Import the standard pylab symbols into user_ns."""
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363
# Import numpy as np/pyplot as plt are conventions we're trying to
# somewhat standardize on. Making them available to users by default
Fernando Perez
Fix name pollution of interactive namespace in pylab mode....
r3195 # will greatly help this.
s = ("import numpy\n"
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363 "import matplotlib\n"
"from matplotlib import pylab, mlab, pyplot\n"
"np = numpy\n"
"plt = pyplot\n"
Fernando Perez
Fix name pollution of interactive namespace in pylab mode....
r3195 )
exec s in user_ns
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363
Fernando Perez
Add support for simultaneous interactive and inline matplotlib plots....
r2987 if shell is not None:
Fernando Perez
Fix name pollution of interactive namespace in pylab mode....
r3195 exec s in shell.user_ns_hidden
Fernando Perez
Add support for simultaneous interactive and inline matplotlib plots....
r2987 # 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.
Fernando Perez
Renamed 'payload-svg' matplotlib backend to 'inline'.
r2991 if backend == backends['inline']:
Brian Granger
Lots of work on the display system, focused on pylab stuff....
r3280 from IPython.zmq.pylab.backend_inline import flush_svg
Fernando Perez
Set default figure size in inline mode to (6,4)....
r3045 from matplotlib import pyplot
Fernando Perez
Add support for simultaneous interactive and inline matplotlib plots....
r2987 shell.register_post_execute(flush_svg)
MinRK
use config.Global.inline_rc to initialize matplotlib with the inline backend....
r3353 # The typical default figure size is too large for inline use,
# so we shrink the figure size to 6x4, and tweak fonts to
MinRK
rename inline_rc to pylab_inline_rc
r3354 # make that fit. This is configurable via Global.pylab_inline_rc,
MinRK
use config.Global.inline_rc to initialize matplotlib with the inline backend....
r3353 # or rather it will be once the zmq kernel is hooked up to
# the config system.
default_rc = {
'figure.figsize': (6.0,4.0),
# 12pt labels get cutoff on 6x4 logplots, so use 10pt.
'font.size': 10,
# 10pt still needs a little more room on the xlabel:
'figure.subplot.bottom' : .125
}
MinRK
rename inline_rc to pylab_inline_rc
r3354 rc = getattr(shell.config.Global, 'pylab_inline_rc', default_rc)
MinRK
use config.Global.inline_rc to initialize matplotlib with the inline backend....
r3353 pyplot.rcParams.update(rc)
MinRK
rename inline_rc to pylab_inline_rc
r3354 shell.config.Global.pylab_inline_rc = rc
MinRK
use config.Global.inline_rc to initialize matplotlib with the inline backend....
r3353
Fernando Perez
Set default figure size in inline mode to (6,4)....
r3045 # Add 'figsize' to pyplot and to the user's namespace
user_ns['figsize'] = pyplot.figsize = figsize
Fernando Perez
Fix name pollution of interactive namespace in pylab mode....
r3195 shell.user_ns_hidden['figsize'] = figsize
Brian Granger
Lots of work on the display system, focused on pylab stuff....
r3280
# The old pastefig function has been replaced by display
# Always add this svg formatter so display works.
from IPython.core.display import display, display_svg
svg_formatter = shell.display_formatter.formatters['image/svg+xml']
svg_formatter.for_type_by_name(
'matplotlib.figure','Figure',figure_to_svg
)
# Add display and display_png to the user's namespace
user_ns['display'] = display
shell.user_ns_hidden['display'] = display
user_ns['display_svg'] = display_svg
shell.user_ns_hidden['display_svg'] = display_svg
Brian Granger
Final work on display system....
r3288 user_ns['getfigs'] = getfigs
shell.user_ns_hidden['getfigs'] = getfigs
Fernando Perez
Add support for simultaneous interactive and inline matplotlib plots....
r2987
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363 if import_all:
Fernando Perez
Fix name pollution of interactive namespace in pylab mode....
r3195 s = ("from matplotlib.pylab import *\n"
"from numpy import *\n")
exec s in user_ns
if shell is not None:
exec s in shell.user_ns_hidden
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363
Brian Granger
Initial GUI support in kernel.
r2868
def pylab_activate(user_ns, gui=None, import_all=True):
"""Activate pylab mode in the user's namespace.
Loads and initializes numpy, matplotlib and friends for interactive use.
Parameters
----------
user_ns : dict
Namespace where the imports will occur.
gui : optional, string
A valid gui name following the conventions of the %gui magic.
import_all : optional, boolean
If true, an 'import *' is done from numpy and pylab.
Returns
-------
The actual gui used (if not given as input, it was obtained from matplotlib
itself, and will be needed next to configure IPython's gui integration.
"""
gui, backend = find_gui_and_backend(gui)
activate_matplotlib(backend)
Fernando Perez
Add support for simultaneous interactive and inline matplotlib plots....
r2987 import_pylab(user_ns, backend)
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363
print """
Fernando Perez
Small fix to info message when pylab starts.
r2364 Welcome to pylab, a matplotlib-based Python environment [backend: %s].
Fernando Perez
First semi-complete support for -pylab and %pylab....
r2363 For more information, type 'help(pylab)'.""" % backend
return gui