Show More
@@ -55,7 +55,6 b' from IPython.core.macro import Macro' | |||||
55 | from IPython.core.payload import PayloadManager |
|
55 | from IPython.core.payload import PayloadManager | |
56 | from IPython.core.prefilter import PrefilterManager |
|
56 | from IPython.core.prefilter import PrefilterManager | |
57 | from IPython.core.profiledir import ProfileDir |
|
57 | from IPython.core.profiledir import ProfileDir | |
58 | from IPython.core.pylabtools import pylab_activate |
|
|||
59 | from IPython.core.prompts import PromptManager |
|
58 | from IPython.core.prompts import PromptManager | |
60 | from IPython.lib.latextools import LaTeXTool |
|
59 | from IPython.lib.latextools import LaTeXTool | |
61 | from IPython.testing.skipdoctest import skip_doctest |
|
60 | from IPython.testing.skipdoctest import skip_doctest | |
@@ -2839,6 +2838,51 b' class InteractiveShell(SingletonConfigurable):' | |||||
2839 | def enable_gui(self, gui=None): |
|
2838 | def enable_gui(self, gui=None): | |
2840 | raise NotImplementedError('Implement enable_gui in a subclass') |
|
2839 | raise NotImplementedError('Implement enable_gui in a subclass') | |
2841 |
|
2840 | |||
|
2841 | def enable_matplotlib(self, gui=None): | |||
|
2842 | """Enable interactive matplotlib and inline figure support. | |||
|
2843 | ||||
|
2844 | This takes the following steps: | |||
|
2845 | ||||
|
2846 | 1. select the appropriate eventloop and matplotlib backend | |||
|
2847 | 2. set up matplotlib for interactive use with that backend | |||
|
2848 | 3. configure formatters for inline figure display | |||
|
2849 | 4. enable the selected gui eventloop | |||
|
2850 | ||||
|
2851 | Parameters | |||
|
2852 | ---------- | |||
|
2853 | gui : optional, string | |||
|
2854 | If given, dictates the choice of matplotlib GUI backend to use | |||
|
2855 | (should be one of IPython's supported backends, 'qt', 'osx', 'tk', | |||
|
2856 | 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by | |||
|
2857 | matplotlib (as dictated by the matplotlib build-time options plus the | |||
|
2858 | user's matplotlibrc configuration file). Note that not all backends | |||
|
2859 | make sense in all contexts, for example a terminal ipython can't | |||
|
2860 | display figures inline. | |||
|
2861 | """ | |||
|
2862 | from IPython.core import pylabtools as pt | |||
|
2863 | gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select) | |||
|
2864 | ||||
|
2865 | if gui != 'inline': | |||
|
2866 | # If we have our first gui selection, store it | |||
|
2867 | if self.pylab_gui_select is None: | |||
|
2868 | self.pylab_gui_select = gui | |||
|
2869 | # Otherwise if they are different | |||
|
2870 | elif gui != self.pylab_gui_select: | |||
|
2871 | print ('Warning: Cannot change to a different GUI toolkit: %s.' | |||
|
2872 | ' Using %s instead.' % (gui, self.pylab_gui_select)) | |||
|
2873 | gui, backend = pt.find_gui_and_backend(self.pylab_gui_select) | |||
|
2874 | ||||
|
2875 | pt.activate_matplotlib(backend) | |||
|
2876 | pt.configure_inline_support(self, backend) | |||
|
2877 | ||||
|
2878 | # Now we must activate the gui pylab wants to use, and fix %run to take | |||
|
2879 | # plot updates into account | |||
|
2880 | self.enable_gui(gui) | |||
|
2881 | self.magics_manager.registry['ExecutionMagics'].default_runner = \ | |||
|
2882 | pt.mpl_runner(self.safe_execfile) | |||
|
2883 | ||||
|
2884 | return gui, backend | |||
|
2885 | ||||
2842 | def enable_pylab(self, gui=None, import_all=True, welcome_message=False): |
|
2886 | def enable_pylab(self, gui=None, import_all=True, welcome_message=False): | |
2843 | """Activate pylab support at runtime. |
|
2887 | """Activate pylab support at runtime. | |
2844 |
|
2888 | |||
@@ -2847,6 +2891,8 b' class InteractiveShell(SingletonConfigurable):' | |||||
2847 | interact with the GUI event loop. The GUI backend to be used can be |
|
2891 | interact with the GUI event loop. The GUI backend to be used can be | |
2848 | optionally selected with the optional ``gui`` argument. |
|
2892 | optionally selected with the optional ``gui`` argument. | |
2849 |
|
2893 | |||
|
2894 | This method only adds preloading the namespace to InteractiveShell.enable_matplotlib. | |||
|
2895 | ||||
2850 | Parameters |
|
2896 | Parameters | |
2851 | ---------- |
|
2897 | ---------- | |
2852 | gui : optional, string |
|
2898 | gui : optional, string | |
@@ -2857,30 +2903,29 b' class InteractiveShell(SingletonConfigurable):' | |||||
2857 | user's matplotlibrc configuration file). Note that not all backends |
|
2903 | user's matplotlibrc configuration file). Note that not all backends | |
2858 | make sense in all contexts, for example a terminal ipython can't |
|
2904 | make sense in all contexts, for example a terminal ipython can't | |
2859 | display figures inline. |
|
2905 | display figures inline. | |
|
2906 | import_all : optional, bool, default: True | |||
|
2907 | Whether to do `from numpy import *` and `from pylab import *` | |||
|
2908 | in addition to module imports. | |||
|
2909 | welcome_message : deprecated | |||
|
2910 | This argument is ignored, no welcome message will be displayed. | |||
2860 | """ |
|
2911 | """ | |
2861 |
from IPython.core.pylabtools import |
|
2912 | from IPython.core.pylabtools import import_pylab | |
|
2913 | ||||
|
2914 | gui, backend = self.enable_matplotlib(gui) | |||
|
2915 | ||||
2862 | # We want to prevent the loading of pylab to pollute the user's |
|
2916 | # We want to prevent the loading of pylab to pollute the user's | |
2863 | # namespace as shown by the %who* magics, so we execute the activation |
|
2917 | # namespace as shown by the %who* magics, so we execute the activation | |
2864 | # code in an empty namespace, and we update *both* user_ns and |
|
2918 | # code in an empty namespace, and we update *both* user_ns and | |
2865 | # user_ns_hidden with this information. |
|
2919 | # user_ns_hidden with this information. | |
2866 | ns = {} |
|
2920 | ns = {} | |
2867 | try: |
|
2921 | import_pylab(ns, import_all) | |
2868 | gui = pylab_activate(ns, gui, import_all, self, welcome_message=welcome_message) |
|
2922 | # warn about clobbered names | |
2869 | except KeyError: |
|
2923 | ignored = set(["__builtins__"]) | |
2870 | error("Backend '%s' not supported. Supported backends are: %s" |
|
2924 | both = set(ns).intersection(self.user_ns).difference(ignored) | |
2871 | % (gui, " ".join(sorted(backends.keys())))) |
|
2925 | clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ] | |
2872 | return |
|
|||
2873 | except ImportError: |
|
|||
2874 | error("pylab mode doesn't work as matplotlib could not be found." + \ |
|
|||
2875 | "\nIs it installed on the system?") |
|
|||
2876 | return |
|
|||
2877 | self.user_ns.update(ns) |
|
2926 | self.user_ns.update(ns) | |
2878 | self.user_ns_hidden.update(ns) |
|
2927 | self.user_ns_hidden.update(ns) | |
2879 | # Now we must activate the gui pylab wants to use, and fix %run to take |
|
2928 | return gui, backend, clobbered | |
2880 | # plot updates into account |
|
|||
2881 | self.enable_gui(gui) |
|
|||
2882 | self.magics_manager.registry['ExecutionMagics'].default_runner = \ |
|
|||
2883 | mpl_runner(self.safe_execfile) |
|
|||
2884 |
|
2929 | |||
2885 | #------------------------------------------------------------------------- |
|
2930 | #------------------------------------------------------------------------- | |
2886 | # Utilities |
|
2931 | # Utilities |
@@ -14,29 +14,40 b'' | |||||
14 |
|
14 | |||
15 | # Our own packages |
|
15 | # Our own packages | |
16 | from IPython.config.application import Application |
|
16 | from IPython.config.application import Application | |
|
17 | from IPython.core import magic_arguments | |||
17 | from IPython.core.magic import Magics, magics_class, line_magic |
|
18 | from IPython.core.magic import Magics, magics_class, line_magic | |
18 | from IPython.testing.skipdoctest import skip_doctest |
|
19 | from IPython.testing.skipdoctest import skip_doctest | |
|
20 | from IPython.utils.warn import warn | |||
|
21 | from IPython.core.pylabtools import backends | |||
19 |
|
22 | |||
20 | #----------------------------------------------------------------------------- |
|
23 | #----------------------------------------------------------------------------- | |
21 | # Magic implementation classes |
|
24 | # Magic implementation classes | |
22 | #----------------------------------------------------------------------------- |
|
25 | #----------------------------------------------------------------------------- | |
23 |
|
26 | |||
|
27 | magic_gui_arg = magic_arguments.argument( | |||
|
28 | 'gui', nargs='?', | |||
|
29 | help="""Name of the matplotlib backend to use %s. | |||
|
30 | If given, the corresponding matplotlib backend is used, | |||
|
31 | otherwise it will be matplotlib's default | |||
|
32 | (which you can set in your matplotlib config file). | |||
|
33 | """ % str(tuple(sorted(backends.keys()))) | |||
|
34 | ) | |||
|
35 | ||||
|
36 | ||||
24 | @magics_class |
|
37 | @magics_class | |
25 | class PylabMagics(Magics): |
|
38 | class PylabMagics(Magics): | |
26 | """Magics related to matplotlib's pylab support""" |
|
39 | """Magics related to matplotlib's pylab support""" | |
27 |
|
40 | |||
28 | @skip_doctest |
|
41 | @skip_doctest | |
29 | @line_magic |
|
42 | @line_magic | |
30 | def pylab(self, parameter_s=''): |
|
43 | @magic_arguments.magic_arguments() | |
31 | """Load numpy and matplotlib to work interactively. |
|
44 | @magic_gui_arg | |
|
45 | def matplotlib(self, line=''): | |||
|
46 | """Set up matplotlib to work interactively. | |||
32 |
|
47 | |||
33 | %pylab [GUINAME] |
|
48 | This function lets you activate matplotlib interactive support | |
34 |
|
49 | at any point during an IPython session. | ||
35 | This function lets you activate pylab (matplotlib, numpy and |
|
50 | It does not import anything into the interactive namespace. | |
36 | interactive support) at any point during an IPython session. |
|
|||
37 |
|
||||
38 | It will import at the top level numpy as np, pyplot as plt, matplotlib, |
|
|||
39 | pylab and mlab, as well as all names from numpy and pylab. |
|
|||
40 |
|
51 | |||
41 | If you are using the inline matplotlib backend for embedded figures, |
|
52 | If you are using the inline matplotlib backend for embedded figures, | |
42 | you can adjust its behavior via the %config magic:: |
|
53 | you can adjust its behavior via the %config magic:: | |
@@ -49,40 +60,82 b' class PylabMagics(Magics):' | |||||
49 | # cells: |
|
60 | # cells: | |
50 | In [2]: %config InlineBackend.close_figures = False |
|
61 | In [2]: %config InlineBackend.close_figures = False | |
51 |
|
62 | |||
52 | Parameters |
|
|||
53 | ---------- |
|
|||
54 | guiname : optional |
|
|||
55 | One of the valid arguments to the %gui magic ('qt', 'wx', 'gtk', |
|
|||
56 | 'osx' or 'tk'). If given, the corresponding Matplotlib backend is |
|
|||
57 | used, otherwise matplotlib's default (which you can override in your |
|
|||
58 | matplotlib config file) is used. |
|
|||
59 |
|
||||
60 | Examples |
|
63 | Examples | |
61 | -------- |
|
64 | -------- | |
62 | In this case, where the MPL default is TkAgg:: |
|
65 | In this case, where the MPL default is TkAgg:: | |
63 |
|
66 | |||
64 |
In [2]: % |
|
67 | In [2]: %matplotlib | |
65 |
|
68 | Using matplotlib backend: TkAgg | ||
66 | Welcome to pylab, a matplotlib-based Python environment. |
|
|||
67 | Backend in use: TkAgg |
|
|||
68 | For more information, type 'help(pylab)'. |
|
|||
69 |
|
69 | |||
70 | But you can explicitly request a different backend:: |
|
70 | But you can explicitly request a different backend:: | |
71 |
|
71 | |||
72 |
In [3]: % |
|
72 | In [3]: %matplotlib qt | |
|
73 | """ | |||
|
74 | args = magic_arguments.parse_argstring(self.matplotlib, line) | |||
|
75 | gui, backend = self.shell.enable_matplotlib(args.gui) | |||
|
76 | self._show_matplotlib_backend(args.gui, backend) | |||
73 |
|
77 | |||
74 | Welcome to pylab, a matplotlib-based Python environment. |
|
78 | @skip_doctest | |
75 | Backend in use: Qt4Agg |
|
79 | @line_magic | |
76 | For more information, type 'help(pylab)'. |
|
80 | @magic_arguments.magic_arguments() | |
|
81 | @magic_arguments.argument( | |||
|
82 | '--no-import-all', action='store_true', default=None, | |||
|
83 | help="""Prevent IPython from performing ``import *`` into the interactive namespace. | |||
|
84 | ||||
|
85 | The names that will still be added to the namespace if this flag is given:: | |||
|
86 | ||||
|
87 | numpy | |||
|
88 | matplotlib | |||
|
89 | np (numpy alias) | |||
|
90 | plt (matplotlib.pyplot alias) | |||
|
91 | pylab (from matplotlib) | |||
|
92 | pyplot (from matplotlib) | |||
|
93 | mlab (from matplotlib) | |||
|
94 | display (from IPython) | |||
|
95 | figsize (from IPython) | |||
|
96 | getfigs (from IPython) | |||
|
97 | ||||
|
98 | You can govern the default behavior with the | |||
|
99 | InteractiveShellApp.pylab_import_all configurable. | |||
77 |
|
|
100 | """ | |
|
101 | ) | |||
|
102 | @magic_gui_arg | |||
|
103 | def pylab(self, line=''): | |||
|
104 | """Load numpy and matplotlib to work interactively. | |||
|
105 | ||||
|
106 | This function lets you activate pylab (matplotlib, numpy and | |||
|
107 | interactive support) at any point during an IPython session. | |||
|
108 | ||||
|
109 | It will import at the top level numpy as np, pyplot as plt, matplotlib, | |||
|
110 | pylab and mlab, as well as all names from numpy and pylab. | |||
78 |
|
111 | |||
|
112 | See the %matplotlib magic for more details. | |||
|
113 | """ | |||
|
114 | args = magic_arguments.parse_argstring(self.pylab, line) | |||
|
115 | if args.no_import_all is None: | |||
|
116 | # get default from Application | |||
79 | if Application.initialized(): |
|
117 | if Application.initialized(): | |
80 | app = Application.instance() |
|
118 | app = Application.instance() | |
81 | try: |
|
119 | try: | |
82 |
import_all |
|
120 | import_all = app.pylab_import_all | |
83 | except AttributeError: |
|
121 | except AttributeError: | |
84 |
import_all |
|
122 | import_all = True | |
85 | else: |
|
123 | else: | |
86 | import_all_status = True |
|
124 | # nothing specified, no app - default True | |
|
125 | import_all = True | |||
|
126 | else: | |||
|
127 | # invert no-import flag | |||
|
128 | import_all = not args.no_import_all | |||
|
129 | ||||
|
130 | gui, backend, clobbered = self.shell.enable_pylab(args.gui, import_all=import_all) | |||
|
131 | self._show_matplotlib_backend(args.gui, backend) | |||
|
132 | if clobbered: | |||
|
133 | warn("pylab import has clobbered these variables: %s" % clobbered + | |||
|
134 | "\n`%pylab --no-import-all` prevents importing * from pylab and numpy" | |||
|
135 | ) | |||
|
136 | ||||
|
137 | def _show_matplotlib_backend(self, gui, backend): | |||
|
138 | """show matplotlib message backend message""" | |||
|
139 | if not gui or gui == 'auto': | |||
|
140 | print ("using matplotlib backend: %s" % backend) | |||
87 |
|
141 | |||
88 | self.shell.enable_pylab(parameter_s, import_all=import_all_status, welcome_message=True) |
|
@@ -251,7 +251,13 b' def activate_matplotlib(backend):' | |||||
251 |
|
251 | |||
252 |
|
252 | |||
253 | def import_pylab(user_ns, import_all=True): |
|
253 | def import_pylab(user_ns, import_all=True): | |
254 | """Import the standard pylab symbols into user_ns.""" |
|
254 | """Populate the namespace with pylab-related values. | |
|
255 | ||||
|
256 | Imports matplotlib, pylab, numpy, and everything from pylab and numpy. | |||
|
257 | ||||
|
258 | Also imports a few names from IPython (figsize, display, getfigs) | |||
|
259 | ||||
|
260 | """ | |||
255 |
|
261 | |||
256 | # Import numpy as np/pyplot as plt are conventions we're trying to |
|
262 | # Import numpy as np/pyplot as plt are conventions we're trying to | |
257 | # somewhat standardize on. Making them available to users by default |
|
263 | # somewhat standardize on. Making them available to users by default | |
@@ -269,8 +275,15 b' def import_pylab(user_ns, import_all=True):' | |||||
269 | "from numpy import *\n") |
|
275 | "from numpy import *\n") | |
270 | exec s in user_ns |
|
276 | exec s in user_ns | |
271 |
|
277 | |||
|
278 | # IPython symbols to add | |||
|
279 | user_ns['figsize'] = figsize | |||
|
280 | from IPython.core.display import display | |||
|
281 | # Add display and getfigs to the user's namespace | |||
|
282 | user_ns['display'] = display | |||
|
283 | user_ns['getfigs'] = getfigs | |||
|
284 | ||||
272 |
|
285 | |||
273 |
def configure_inline_support(shell, backend |
|
286 | def configure_inline_support(shell, backend): | |
274 | """Configure an IPython shell object for matplotlib use. |
|
287 | """Configure an IPython shell object for matplotlib use. | |
275 |
|
288 | |||
276 | Parameters |
|
289 | Parameters | |
@@ -278,10 +291,6 b' def configure_inline_support(shell, backend, user_ns=None):' | |||||
278 | shell : InteractiveShell instance |
|
291 | shell : InteractiveShell instance | |
279 |
|
292 | |||
280 | backend : matplotlib backend |
|
293 | backend : matplotlib backend | |
281 |
|
||||
282 | user_ns : dict |
|
|||
283 | A namespace where all configured variables will be placed. If not given, |
|
|||
284 | the `user_ns` attribute of the shell object is used. |
|
|||
285 | """ |
|
294 | """ | |
286 | # If using our svg payload backend, register the post-execution |
|
295 | # If using our svg payload backend, register the post-execution | |
287 | # function that will pick up the results for display. This can only be |
|
296 | # function that will pick up the results for display. This can only be | |
@@ -296,8 +305,6 b' def configure_inline_support(shell, backend, user_ns=None):' | |||||
296 | return |
|
305 | return | |
297 | from matplotlib import pyplot |
|
306 | from matplotlib import pyplot | |
298 |
|
307 | |||
299 | user_ns = shell.user_ns if user_ns is None else user_ns |
|
|||
300 |
|
||||
301 | cfg = InlineBackend.instance(parent=shell) |
|
308 | cfg = InlineBackend.instance(parent=shell) | |
302 | cfg.shell = shell |
|
309 | cfg.shell = shell | |
303 | if cfg not in shell.configurables: |
|
310 | if cfg not in shell.configurables: | |
@@ -313,8 +320,6 b' def configure_inline_support(shell, backend, user_ns=None):' | |||||
313 | shell._saved_rcParams[k] = pyplot.rcParams[k] |
|
320 | shell._saved_rcParams[k] = pyplot.rcParams[k] | |
314 | # load inline_rc |
|
321 | # load inline_rc | |
315 | pyplot.rcParams.update(cfg.rc) |
|
322 | pyplot.rcParams.update(cfg.rc) | |
316 | # Add 'figsize' to pyplot and to the user's namespace |
|
|||
317 | user_ns['figsize'] = pyplot.figsize = figsize |
|
|||
318 | else: |
|
323 | else: | |
319 | from IPython.kernel.zmq.pylab.backend_inline import flush_figures |
|
324 | from IPython.kernel.zmq.pylab.backend_inline import flush_figures | |
320 | if flush_figures in shell._post_execute: |
|
325 | if flush_figures in shell._post_execute: | |
@@ -324,62 +329,5 b' def configure_inline_support(shell, backend, user_ns=None):' | |||||
324 | del shell._saved_rcParams |
|
329 | del shell._saved_rcParams | |
325 |
|
330 | |||
326 | # Setup the default figure format |
|
331 | # Setup the default figure format | |
327 |
|
|
332 | select_figure_format(shell, cfg.figure_format) | |
328 | select_figure_format(shell, fmt) |
|
|||
329 |
|
||||
330 | # The old pastefig function has been replaced by display |
|
|||
331 | from IPython.core.display import display |
|
|||
332 | # Add display and getfigs to the user's namespace |
|
|||
333 | user_ns['display'] = display |
|
|||
334 | user_ns['getfigs'] = getfigs |
|
|||
335 |
|
||||
336 |
|
||||
337 | def pylab_activate(user_ns, gui=None, import_all=True, shell=None, welcome_message=False): |
|
|||
338 | """Activate pylab mode in the user's namespace. |
|
|||
339 |
|
||||
340 | Loads and initializes numpy, matplotlib and friends for interactive use. |
|
|||
341 |
|
||||
342 | Parameters |
|
|||
343 | ---------- |
|
|||
344 | user_ns : dict |
|
|||
345 | Namespace where the imports will occur. |
|
|||
346 |
|
||||
347 | gui : optional, string |
|
|||
348 | A valid gui name following the conventions of the %gui magic. |
|
|||
349 |
|
||||
350 | import_all : optional, boolean |
|
|||
351 | If true, an 'import *' is done from numpy and pylab. |
|
|||
352 |
|
||||
353 | welcome_message : optional, boolean |
|
|||
354 | If true, print a welcome message about pylab, which includes the backend |
|
|||
355 | being used. |
|
|||
356 |
|
333 | |||
357 | Returns |
|
|||
358 | ------- |
|
|||
359 | The actual gui used (if not given as input, it was obtained from matplotlib |
|
|||
360 | itself, and will be needed next to configure IPython's gui integration. |
|
|||
361 | """ |
|
|||
362 | pylab_gui_select = shell.pylab_gui_select if shell is not None else None |
|
|||
363 | # Try to find the appropriate gui and backend for the settings |
|
|||
364 | gui, backend = find_gui_and_backend(gui, pylab_gui_select) |
|
|||
365 | if shell is not None and gui != 'inline': |
|
|||
366 | # If we have our first gui selection, store it |
|
|||
367 | if pylab_gui_select is None: |
|
|||
368 | shell.pylab_gui_select = gui |
|
|||
369 | # Otherwise if they are different |
|
|||
370 | elif gui != pylab_gui_select: |
|
|||
371 | print ('Warning: Cannot change to a different GUI toolkit: %s.' |
|
|||
372 | ' Using %s instead.' % (gui, pylab_gui_select)) |
|
|||
373 | gui, backend = find_gui_and_backend(pylab_gui_select) |
|
|||
374 | activate_matplotlib(backend) |
|
|||
375 | import_pylab(user_ns, import_all) |
|
|||
376 | if shell is not None: |
|
|||
377 | configure_inline_support(shell, backend, user_ns) |
|
|||
378 | if welcome_message: |
|
|||
379 | print """ |
|
|||
380 | Welcome to pylab, a matplotlib-based Python environment [backend: %s]. |
|
|||
381 | For more information, type 'help(pylab)'.""" % backend |
|
|||
382 | # flush stdout, just to be safe |
|
|||
383 | sys.stdout.flush() |
|
|||
384 |
|
||||
385 | return gui |
|
@@ -176,8 +176,11 b' class InteractiveShellApp(Configurable):' | |||||
176 | """ |
|
176 | """ | |
177 | ) |
|
177 | ) | |
178 | pylab_import_all = Bool(True, config=True, |
|
178 | pylab_import_all = Bool(True, config=True, | |
179 |
help="""If true, |
|
179 | help="""If true, IPython will populate the user namespace with numpy, pylab, etc. | |
180 | when using pylab""" |
|
180 | and an 'import *' is done from numpy and pylab, when using pylab mode. | |
|
181 | ||||
|
182 | When False, pylab mode should not import any names into the user namespace. | |||
|
183 | """ | |||
181 | ) |
|
184 | ) | |
182 | shell = Instance('IPython.core.interactiveshell.InteractiveShellABC') |
|
185 | shell = Instance('IPython.core.interactiveshell.InteractiveShellABC') | |
183 |
|
186 | |||
@@ -198,7 +201,9 b' class InteractiveShellApp(Configurable):' | |||||
198 | gui, backend = pylabtools.find_gui_and_backend(self.pylab) |
|
201 | gui, backend = pylabtools.find_gui_and_backend(self.pylab) | |
199 | self.log.info("Enabling GUI event loop integration, " |
|
202 | self.log.info("Enabling GUI event loop integration, " | |
200 | "toolkit=%s, pylab=%s" % (gui, self.pylab)) |
|
203 | "toolkit=%s, pylab=%s" % (gui, self.pylab)) | |
201 | shell.enable_pylab(gui, import_all=self.pylab_import_all, welcome_message=True) |
|
204 | if self.pylab == "auto": | |
|
205 | print ("using matplotlib backend: %s" % backend) | |||
|
206 | shell.enable_pylab(self.pylab, import_all=self.pylab_import_all) | |||
202 | else: |
|
207 | else: | |
203 | self.log.info("Enabling GUI event loop integration, " |
|
208 | self.log.info("Enabling GUI event loop integration, " | |
204 | "toolkit=%s" % self.gui) |
|
209 | "toolkit=%s" % self.gui) |
@@ -23,6 +23,7 b' from matplotlib import pyplot as plt' | |||||
23 | import numpy as np |
|
23 | import numpy as np | |
24 |
|
24 | |||
25 | # Our own imports |
|
25 | # Our own imports | |
|
26 | from IPython.core.interactiveshell import InteractiveShell | |||
26 | from IPython.testing import decorators as dec |
|
27 | from IPython.testing import decorators as dec | |
27 | from .. import pylabtools as pt |
|
28 | from .. import pylabtools as pt | |
28 |
|
29 | |||
@@ -62,10 +63,10 b' def test_import_pylab():' | |||||
62 | nt.assert_true('plt' in ns) |
|
63 | nt.assert_true('plt' in ns) | |
63 | nt.assert_equal(ns['np'], np) |
|
64 | nt.assert_equal(ns['np'], np) | |
64 |
|
65 | |||
65 |
|
||||
66 | class TestPylabSwitch(object): |
|
66 | class TestPylabSwitch(object): | |
67 |
class Shell( |
|
67 | class Shell(InteractiveShell): | |
68 | pylab_gui_select = None |
|
68 | def enable_gui(self, gui): | |
|
69 | pass | |||
69 |
|
70 | |||
70 | def setup(self): |
|
71 | def setup(self): | |
71 | import matplotlib |
|
72 | import matplotlib | |
@@ -93,47 +94,47 b' class TestPylabSwitch(object):' | |||||
93 |
|
94 | |||
94 | def test_qt(self): |
|
95 | def test_qt(self): | |
95 | s = self.Shell() |
|
96 | s = self.Shell() | |
96 | gui = pt.pylab_activate(dict(), None, False, s) |
|
97 | gui, backend = s.enable_matplotlib(None) | |
97 | nt.assert_equal(gui, 'qt') |
|
98 | nt.assert_equal(gui, 'qt') | |
98 | nt.assert_equal(s.pylab_gui_select, 'qt') |
|
99 | nt.assert_equal(s.pylab_gui_select, 'qt') | |
99 |
|
100 | |||
100 | gui = pt.pylab_activate(dict(), 'inline', False, s) |
|
101 | gui, backend = s.enable_matplotlib('inline') | |
101 | nt.assert_equal(gui, 'inline') |
|
102 | nt.assert_equal(gui, 'inline') | |
102 | nt.assert_equal(s.pylab_gui_select, 'qt') |
|
103 | nt.assert_equal(s.pylab_gui_select, 'qt') | |
103 |
|
104 | |||
104 | gui = pt.pylab_activate(dict(), 'qt', False, s) |
|
105 | gui, backend = s.enable_matplotlib('qt') | |
105 | nt.assert_equal(gui, 'qt') |
|
106 | nt.assert_equal(gui, 'qt') | |
106 | nt.assert_equal(s.pylab_gui_select, 'qt') |
|
107 | nt.assert_equal(s.pylab_gui_select, 'qt') | |
107 |
|
108 | |||
108 | gui = pt.pylab_activate(dict(), 'inline', False, s) |
|
109 | gui, backend = s.enable_matplotlib('inline') | |
109 | nt.assert_equal(gui, 'inline') |
|
110 | nt.assert_equal(gui, 'inline') | |
110 | nt.assert_equal(s.pylab_gui_select, 'qt') |
|
111 | nt.assert_equal(s.pylab_gui_select, 'qt') | |
111 |
|
112 | |||
112 | gui = pt.pylab_activate(dict(), None, False, s) |
|
113 | gui, backend = s.enable_matplotlib() | |
113 | nt.assert_equal(gui, 'qt') |
|
114 | nt.assert_equal(gui, 'qt') | |
114 | nt.assert_equal(s.pylab_gui_select, 'qt') |
|
115 | nt.assert_equal(s.pylab_gui_select, 'qt') | |
115 |
|
116 | |||
116 | def test_inline(self): |
|
117 | def test_inline(self): | |
117 | s = self.Shell() |
|
118 | s = self.Shell() | |
118 | gui = pt.pylab_activate(dict(), 'inline', False, s) |
|
119 | gui, backend = s.enable_matplotlib('inline') | |
119 | nt.assert_equal(gui, 'inline') |
|
120 | nt.assert_equal(gui, 'inline') | |
120 | nt.assert_equal(s.pylab_gui_select, None) |
|
121 | nt.assert_equal(s.pylab_gui_select, None) | |
121 |
|
122 | |||
122 | gui = pt.pylab_activate(dict(), 'inline', False, s) |
|
123 | gui, backend = s.enable_matplotlib('inline') | |
123 | nt.assert_equal(gui, 'inline') |
|
124 | nt.assert_equal(gui, 'inline') | |
124 | nt.assert_equal(s.pylab_gui_select, None) |
|
125 | nt.assert_equal(s.pylab_gui_select, None) | |
125 |
|
126 | |||
126 | gui = pt.pylab_activate(dict(), 'qt', False, s) |
|
127 | gui, backend = s.enable_matplotlib('qt') | |
127 | nt.assert_equal(gui, 'qt') |
|
128 | nt.assert_equal(gui, 'qt') | |
128 | nt.assert_equal(s.pylab_gui_select, 'qt') |
|
129 | nt.assert_equal(s.pylab_gui_select, 'qt') | |
129 |
|
130 | |||
130 | def test_qt_gtk(self): |
|
131 | def test_qt_gtk(self): | |
131 | s = self.Shell() |
|
132 | s = self.Shell() | |
132 | gui = pt.pylab_activate(dict(), 'qt', False, s) |
|
133 | gui, backend = s.enable_matplotlib('qt') | |
133 | nt.assert_equal(gui, 'qt') |
|
134 | nt.assert_equal(gui, 'qt') | |
134 | nt.assert_equal(s.pylab_gui_select, 'qt') |
|
135 | nt.assert_equal(s.pylab_gui_select, 'qt') | |
135 |
|
136 | |||
136 | gui = pt.pylab_activate(dict(), 'gtk', False, s) |
|
137 | gui, backend = s.enable_matplotlib('gtk') | |
137 | nt.assert_equal(gui, 'qt') |
|
138 | nt.assert_equal(gui, 'qt') | |
138 | nt.assert_equal(s.pylab_gui_select, 'qt') |
|
139 | nt.assert_equal(s.pylab_gui_select, 'qt') | |
139 |
|
140 |
@@ -160,19 +160,23 b' class InProcessInteractiveShell(ZMQInteractiveShell):' | |||||
160 | #------------------------------------------------------------------------- |
|
160 | #------------------------------------------------------------------------- | |
161 |
|
161 | |||
162 | def enable_gui(self, gui=None): |
|
162 | def enable_gui(self, gui=None): | |
163 |
""" |
|
163 | """Enable GUI integration for the kernel.""" | |
164 | """ |
|
|||
165 | from IPython.kernel.zmq.eventloops import enable_gui |
|
164 | from IPython.kernel.zmq.eventloops import enable_gui | |
166 | if not gui: |
|
165 | if not gui: | |
167 | gui = self.kernel.gui |
|
166 | gui = self.kernel.gui | |
168 | enable_gui(gui, kernel=self.kernel) |
|
167 | return enable_gui(gui, kernel=self.kernel) | |
|
168 | ||||
|
169 | def enable_matplotlib(self, gui=None): | |||
|
170 | """Enable matplotlib integration for the kernel.""" | |||
|
171 | if not gui: | |||
|
172 | gui = self.kernel.gui | |||
|
173 | return super(InProcessInteractiveShell, self).enable_matplotlib(gui) | |||
169 |
|
174 | |||
170 | def enable_pylab(self, gui=None, import_all=True, welcome_message=False): |
|
175 | def enable_pylab(self, gui=None, import_all=True, welcome_message=False): | |
171 |
""" |
|
176 | """Activate pylab support at runtime.""" | |
172 | """ |
|
|||
173 | if not gui: |
|
177 | if not gui: | |
174 | gui = self.kernel.gui |
|
178 | gui = self.kernel.gui | |
175 | super(InProcessInteractiveShell, self).enable_pylab(gui, import_all, |
|
179 | return super(InProcessInteractiveShell, self).enable_pylab(gui, import_all, | |
176 | welcome_message) |
|
180 | welcome_message) | |
177 |
|
181 | |||
178 | InteractiveShellABC.register(InProcessInteractiveShell) |
|
182 | InteractiveShellABC.register(InProcessInteractiveShell) |
@@ -42,7 +42,7 b' class InProcessKernelTestCase(unittest.TestCase):' | |||||
42 | kc = self.kc |
|
42 | kc = self.kc | |
43 | kc.execute('%pylab') |
|
43 | kc.execute('%pylab') | |
44 | msg = get_stream_message(kc) |
|
44 | msg = get_stream_message(kc) | |
45 |
self.assert_(' |
|
45 | self.assert_('matplotlib' in msg['content']['data']) | |
46 |
|
46 | |||
47 | def test_raw_input(self): |
|
47 | def test_raw_input(self): | |
48 | """ Does the in-process kernel handle raw_input correctly? |
|
48 | """ Does the in-process kernel handle raw_input correctly? |
@@ -83,8 +83,7 b' In \\[1\\]: from IPython\\.config\\.application import Application' | |||||
83 | In \[2\]: app = Application\.instance\(\) |
|
83 | In \[2\]: app = Application\.instance\(\) | |
84 | In \[3\]: app\.pylab_import_all = True |
|
84 | In \[3\]: app\.pylab_import_all = True | |
85 | In \[4\]: pylab |
|
85 | In \[4\]: pylab | |
86 | ^Welcome to pylab, a matplotlib-based Python environment |
|
86 | ^using matplotlib backend: | |
87 | For more information, type 'help\(pylab\)'\. |
|
|||
88 | In \[5\]: ip=get_ipython\(\) |
|
87 | In \[5\]: ip=get_ipython\(\) | |
89 | In \[6\]: \'plot\' in ip\.user_ns |
|
88 | In \[6\]: \'plot\' in ip\.user_ns | |
90 | Out\[6\]: True |
|
89 | Out\[6\]: True | |
@@ -109,8 +108,7 b' In \\[1\\]: from IPython\\.config\\.application import Application' | |||||
109 | In \[2\]: app = Application\.instance\(\) |
|
108 | In \[2\]: app = Application\.instance\(\) | |
110 | In \[3\]: app\.pylab_import_all = False |
|
109 | In \[3\]: app\.pylab_import_all = False | |
111 | In \[4\]: pylab |
|
110 | In \[4\]: pylab | |
112 | ^Welcome to pylab, a matplotlib-based Python environment |
|
111 | ^using matplotlib backend: | |
113 | For more information, type 'help\(pylab\)'\. |
|
|||
114 | In \[5\]: ip=get_ipython\(\) |
|
112 | In \[5\]: ip=get_ipython\(\) | |
115 | In \[6\]: \'plot\' in ip\.user_ns |
|
113 | In \[6\]: \'plot\' in ip\.user_ns | |
116 | Out\[6\]: False |
|
114 | Out\[6\]: False |
@@ -34,6 +34,10 b' def flag_calls(func):' | |||||
34 | Testing for truth in wrapper.called allows you to determine if a call to |
|
34 | Testing for truth in wrapper.called allows you to determine if a call to | |
35 | func() was attempted and succeeded.""" |
|
35 | func() was attempted and succeeded.""" | |
36 |
|
36 | |||
|
37 | # don't wrap twice | |||
|
38 | if hasattr(func, 'called'): | |||
|
39 | return func | |||
|
40 | ||||
37 | def wrapper(*args,**kw): |
|
41 | def wrapper(*args,**kw): | |
38 | wrapper.called = False |
|
42 | wrapper.called = False | |
39 | out = func(*args,**kw) |
|
43 | out = func(*args,**kw) |
General Comments 0
You need to be logged in to leave comments.
Login now