##// END OF EJS Templates
Lots of work on the display system, focused on pylab stuff....
Brian Granger -
Show More
@@ -81,8 +81,6 b' c = get_config()'
81 81
82 82 # c.InteractiveShell.pdb = False
83 83
84 # c.InteractiveShell.pprint = True
85
86 84 # c.InteractiveShell.prompt_in1 = 'In [\#]: '
87 85 # c.InteractiveShell.prompt_in2 = ' .\D.: '
88 86 # c.InteractiveShell.prompt_out = 'Out[\#]: '
@@ -129,6 +127,12 b' c = get_config()'
129 127 # c.InteractiveShell.xmode = 'Context'
130 128
131 129 #-----------------------------------------------------------------------------
130 # Formatter and display options
131 #-----------------------------------------------------------------------------
132
133 # c.PlainTextFormatter.pprint = True
134
135 #-----------------------------------------------------------------------------
132 136 # PrefilterManager options
133 137 #-----------------------------------------------------------------------------
134 138
@@ -37,6 +37,9 b' from IPython.utils.traitlets import Bool, Dict, Int, Str'
37 37
38 38 class DisplayFormatter(Configurable):
39 39
40 # When set to true only the default plain text formatter will be used.
41 plain_text_only = Bool(False, config=True)
42
40 43 # A dict of formatter whose keys are format types (MIME types) and whose
41 44 # values are subclasses of BaseFormatter.
42 45 formatters = Dict(config=True)
@@ -93,6 +96,19 b' class DisplayFormatter(Configurable):'
93 96 except for those included in this argument.
94 97 """
95 98 format_dict = {}
99
100 # If plain text only is active
101 if self.plain_text_only:
102 formatter = self.formatters['text/plain']
103 try:
104 data = formatter(obj)
105 except:
106 # FIXME: log the exception
107 raise
108 if data is not None:
109 format_dict['text/plain'] = data
110 return format_dict
111
96 112 for format_type, formatter in self.formatters.items():
97 113 if include is not None:
98 114 if format_type not in include:
@@ -133,6 +149,9 b' class FormatterABC(object):'
133 149 # The format type of the data returned, usually a MIME type.
134 150 format_type = 'text/plain'
135 151
152 # Is the formatter enabled...
153 enabled = True
154
136 155 @abc.abstractmethod
137 156 def __call__(self, obj):
138 157 """Return a JSON'able representation of the object.
@@ -171,6 +190,8 b' class BaseFormatter(Configurable):'
171 190
172 191 format_type = Str('text/plain')
173 192
193 enabled = Bool(True, config=True)
194
174 195 print_method = Str('__repr__')
175 196
176 197 # The singleton printers.
@@ -193,28 +214,31 b' class BaseFormatter(Configurable):'
193 214
194 215 def __call__(self, obj):
195 216 """Compute the format for an object."""
196 obj_id = id(obj)
197 try:
198 obj_class = getattr(obj, '__class__', None) or type(obj)
199 if hasattr(obj_class, self.print_method):
200 printer = getattr(obj_class, self.print_method)
201 return printer(obj)
217 if self.enabled:
218 obj_id = id(obj)
202 219 try:
203 printer = self.singleton_printers[obj_id]
204 except (TypeError, KeyError):
205 pass
206 else:
207 return printer(obj)
208 for cls in pretty._get_mro(obj_class):
209 if cls in self.type_printers:
210 return self.type_printers[cls](obj)
220 obj_class = getattr(obj, '__class__', None) or type(obj)
221 if hasattr(obj_class, self.print_method):
222 printer = getattr(obj_class, self.print_method)
223 return printer(obj)
224 try:
225 printer = self.singleton_printers[obj_id]
226 except (TypeError, KeyError):
227 pass
211 228 else:
212 printer = self._in_deferred_types(cls)
213 if printer is not None:
214 return printer(obj)
229 return printer(obj)
230 for cls in pretty._get_mro(obj_class):
231 if cls in self.type_printers:
232 return self.type_printers[cls](obj)
233 else:
234 printer = self._in_deferred_types(cls)
235 if printer is not None:
236 return printer(obj)
237 return None
238 except Exception:
239 pass
240 else:
215 241 return None
216 except Exception:
217 pass
218 242
219 243 def for_type(self, typ, func):
220 244 """Add a format function for a given type.
@@ -281,6 +305,7 b' class BaseFormatter(Configurable):'
281 305 self.type_printers[cls] = printer
282 306 return printer
283 307
308
284 309 class PlainTextFormatter(BaseFormatter):
285 310 """The default pretty-printer.
286 311
@@ -308,6 +333,10 b' class PlainTextFormatter(BaseFormatter):'
308 333 # The format type of data returned.
309 334 format_type = Str('text/plain')
310 335
336 # This subclass ignores this attribute as it always need to return
337 # something.
338 enabled = Bool(True, config=False)
339
311 340 # Look for a __pretty__ methods to use for pretty printing.
312 341 print_method = Str('__pretty__')
313 342
@@ -156,33 +156,6 b' class CommandChainDispatcher:'
156 156 return iter(self.chain)
157 157
158 158
159 def result_display(self,arg):
160 """ Default display hook.
161
162 Called for displaying the result to the user.
163 """
164
165 if self.pprint:
166 try:
167 out = pformat(arg)
168 except:
169 # Work around possible bugs in pformat
170 out = repr(arg)
171 if '\n' in out:
172 # So that multi-line strings line up with the left column of
173 # the screen, instead of having the output prompt mess up
174 # their first line.
175 IPython.utils.io.Term.cout.write('\n')
176 print >>IPython.utils.io.Term.cout, out
177 else:
178 # By default, the interactive prompt uses repr() to display results,
179 # so we should honor this. Users who'd rather use a different
180 # mechanism can easily override this hook.
181 print >>IPython.utils.io.Term.cout, repr(arg)
182 # the default display hook doesn't manipulate the value to put in history
183 return None
184
185
186 159 def input_prefilter(self,line):
187 160 """ Default input prefilter
188 161
@@ -172,7 +172,6 b' class InteractiveShell(Configurable, Magic):'
172 172 config=True)
173 173 pdb = CBool(False, config=True)
174 174
175 pprint = CBool(True, config=True)
176 175 profile = Str('', config=True)
177 176 prompt_in1 = Str('In [\\#]: ', config=True)
178 177 prompt_in2 = Str(' .\\D.: ', config=True)
@@ -2424,12 +2424,12 b' Defaulting color scheme to \'NoColor\'"""'
2424 2424 else:
2425 2425 shell.inspector.set_active_scheme('NoColor')
2426 2426
2427 def magic_Pprint(self, parameter_s=''):
2427 def magic_pprint(self, parameter_s=''):
2428 2428 """Toggle pretty printing on/off."""
2429
2430 self.shell.pprint = 1 - self.shell.pprint
2429 ptformatter = self.shell.display_formatter.formatters['text/plain']
2430 ptformatter.pprint = bool(1 - ptformatter.pprint)
2431 2431 print 'Pretty printing has been turned', \
2432 ['OFF','ON'][self.shell.pprint]
2432 ['OFF','ON'][ptformatter.pprint]
2433 2433
2434 2434 def magic_Exit(self, parameter_s=''):
2435 2435 """Exit IPython."""
@@ -3163,6 +3163,8 b' Defaulting color scheme to \'NoColor\'"""'
3163 3163 shell = self.shell
3164 3164 oc = shell.displayhook
3165 3165 meta = shell.meta
3166 disp_formatter = self.shell.display_formatter
3167 ptformatter = disp_formatter.formatters['text/plain']
3166 3168 # dstore is a data store kept in the instance metadata bag to track any
3167 3169 # changes we make, so we can undo them later.
3168 3170 dstore = meta.setdefault('doctest_mode',Struct())
@@ -3170,12 +3172,13 b' Defaulting color scheme to \'NoColor\'"""'
3170 3172
3171 3173 # save a few values we'll need to recover later
3172 3174 mode = save_dstore('mode',False)
3173 save_dstore('rc_pprint',shell.pprint)
3175 save_dstore('rc_pprint',ptformatter.pprint)
3174 3176 save_dstore('xmode',shell.InteractiveTB.mode)
3175 3177 save_dstore('rc_separate_out',shell.separate_out)
3176 3178 save_dstore('rc_separate_out2',shell.separate_out2)
3177 3179 save_dstore('rc_prompts_pad_left',shell.prompts_pad_left)
3178 3180 save_dstore('rc_separate_in',shell.separate_in)
3181 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
3179 3182
3180 3183 if mode == False:
3181 3184 # turn on
@@ -3191,7 +3194,8 b' Defaulting color scheme to \'NoColor\'"""'
3191 3194 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3192 3195 oc.prompt_out.pad_left = False
3193 3196
3194 shell.pprint = False
3197 ptformatter.pprint = False
3198 disp_formatter.plain_text_only = True
3195 3199
3196 3200 shell.magic_xmode('Plain')
3197 3201 else:
@@ -3208,7 +3212,8 b' Defaulting color scheme to \'NoColor\'"""'
3208 3212 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3209 3213 oc.prompt_out.pad_left = dstore.rc_prompts_pad_left
3210 3214
3211 shell.pprint = dstore.rc_pprint
3215 ptformatter.pprint = dstore.rc_pprint
3216 disp_formatter.plain_text_only = dstore.rc_plain_text_only
3212 3217
3213 3218 shell.magic_xmode(dstore.xmode)
3214 3219
@@ -188,10 +188,10 b' class IPAppConfigLoader(BaseAppConfigLoader):'
188 188 action='store_false', dest='InteractiveShell.pdb',
189 189 help="Disable auto calling the pdb debugger after every exception.")
190 190 paa('--pprint',
191 action='store_true', dest='InteractiveShell.pprint',
191 action='store_true', dest='PlainTextFormatter.pprint',
192 192 help="Enable auto pretty printing of results.")
193 193 paa('--no-pprint',
194 action='store_false', dest='InteractiveShell.pprint',
194 action='store_false', dest='PlainTextFormatter.pprint',
195 195 help="Disable auto auto pretty printing of results.")
196 196 paa('--prompt-in1','-pi1',
197 197 type=str, dest='InteractiveShell.prompt_in1',
@@ -443,7 +443,7 b' class IPythonApp(Application):'
443 443 if hasattr(config.Global, 'classic'):
444 444 if config.Global.classic:
445 445 config.InteractiveShell.cache_size = 0
446 config.InteractiveShell.pprint = 0
446 config.PlainTextFormatter.pprint = 0
447 447 config.InteractiveShell.prompt_in1 = '>>> '
448 448 config.InteractiveShell.prompt_in2 = '... '
449 449 config.InteractiveShell.prompt_out = ''
@@ -19,6 +19,8 b' Authors'
19 19 # Imports
20 20 #-----------------------------------------------------------------------------
21 21
22 from cStringIO import StringIO
23
22 24 from IPython.utils.decorators import flag_calls
23 25
24 26 # If user specifies a GUI, that dictates the backend, otherwise we read the
@@ -31,7 +33,80 b" backends = {'tk': 'TkAgg',"
31 33 'inline' : 'module://IPython.zmq.pylab.backend_inline'}
32 34
33 35 #-----------------------------------------------------------------------------
34 # Main classes and functions
36 # Matplotlib utilities
37 #-----------------------------------------------------------------------------
38
39 def figsize(sizex, sizey):
40 """Set the default figure size to be [sizex, sizey].
41
42 This is just an easy to remember, convenience wrapper that sets::
43
44 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
45 """
46 import matplotlib
47 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
48
49
50 def figure_to_svg(fig):
51 """Convert a figure to svg for inline display."""
52 fc = fig.get_facecolor()
53 ec = fig.get_edgecolor()
54 fig.set_facecolor('white')
55 fig.set_edgecolor('white')
56 try:
57 string_io = StringIO()
58 fig.canvas.print_figure(string_io, format='svg')
59 svg = string_io.getvalue()
60 finally:
61 fig.set_facecolor(fc)
62 fig.set_edgecolor(ec)
63 return svg
64
65
66 # We need a little factory function here to create the closure where
67 # safe_execfile can live.
68 def mpl_runner(safe_execfile):
69 """Factory to return a matplotlib-enabled runner for %run.
70
71 Parameters
72 ----------
73 safe_execfile : function
74 This must be a function with the same interface as the
75 :meth:`safe_execfile` method of IPython.
76
77 Returns
78 -------
79 A function suitable for use as the ``runner`` argument of the %run magic
80 function.
81 """
82
83 def mpl_execfile(fname,*where,**kw):
84 """matplotlib-aware wrapper around safe_execfile.
85
86 Its interface is identical to that of the :func:`execfile` builtin.
87
88 This is ultimately a call to execfile(), but wrapped in safeties to
89 properly handle interactive rendering."""
90
91 import matplotlib
92 import matplotlib.pylab as pylab
93
94 #print '*** Matplotlib runner ***' # dbg
95 # turn off rendering until end of script
96 is_interactive = matplotlib.rcParams['interactive']
97 matplotlib.interactive(False)
98 safe_execfile(fname,*where,**kw)
99 matplotlib.interactive(is_interactive)
100 # make rendering call now, if the user tried to do it
101 if pylab.draw_if_interactive.called:
102 pylab.draw()
103 pylab.draw_if_interactive.called = False
104
105 return mpl_execfile
106
107
108 #-----------------------------------------------------------------------------
109 # Code for initializing matplotlib and importing pylab
35 110 #-----------------------------------------------------------------------------
36 111
37 112
@@ -111,7 +186,7 b' def import_pylab(user_ns, backend, import_all=True, shell=None):'
111 186 # function that will pick up the results for display. This can only be
112 187 # done with access to the real shell object.
113 188 if backend == backends['inline']:
114 from IPython.zmq.pylab.backend_inline import flush_svg, figsize
189 from IPython.zmq.pylab.backend_inline import flush_svg
115 190 from matplotlib import pyplot
116 191 shell.register_post_execute(flush_svg)
117 192 # The typical default figure size is too large for inline use. We
@@ -120,11 +195,20 b' def import_pylab(user_ns, backend, import_all=True, shell=None):'
120 195 # Add 'figsize' to pyplot and to the user's namespace
121 196 user_ns['figsize'] = pyplot.figsize = figsize
122 197 shell.user_ns_hidden['figsize'] = figsize
123 else:
124 from IPython.zmq.pylab.backend_inline import pastefig
125 from matplotlib import pyplot
126 # Add 'paste' to pyplot and to the user's namespace
127 user_ns['pastefig'] = pyplot.pastefig = pastefig
198
199 # The old pastefig function has been replaced by display
200 # Always add this svg formatter so display works.
201 from IPython.zmq.pylab.backend_inline import figure_to_svg
202 from IPython.core.display import display, display_svg
203 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
204 svg_formatter.for_type_by_name(
205 'matplotlib.figure','Figure',figure_to_svg
206 )
207 # Add display and display_png to the user's namespace
208 user_ns['display'] = display
209 shell.user_ns_hidden['display'] = display
210 user_ns['display_svg'] = display_svg
211 shell.user_ns_hidden['display_svg'] = display_svg
128 212
129 213 if import_all:
130 214 s = ("from matplotlib.pylab import *\n"
@@ -165,44 +249,3 b' For more information, type \'help(pylab)\'.""" % backend'
165 249
166 250 return gui
167 251
168 # We need a little factory function here to create the closure where
169 # safe_execfile can live.
170 def mpl_runner(safe_execfile):
171 """Factory to return a matplotlib-enabled runner for %run.
172
173 Parameters
174 ----------
175 safe_execfile : function
176 This must be a function with the same interface as the
177 :meth:`safe_execfile` method of IPython.
178
179 Returns
180 -------
181 A function suitable for use as the ``runner`` argument of the %run magic
182 function.
183 """
184
185 def mpl_execfile(fname,*where,**kw):
186 """matplotlib-aware wrapper around safe_execfile.
187
188 Its interface is identical to that of the :func:`execfile` builtin.
189
190 This is ultimately a call to execfile(), but wrapped in safeties to
191 properly handle interactive rendering."""
192
193 import matplotlib
194 import matplotlib.pylab as pylab
195
196 #print '*** Matplotlib runner ***' # dbg
197 # turn off rendering until end of script
198 is_interactive = matplotlib.rcParams['interactive']
199 matplotlib.interactive(False)
200 safe_execfile(fname,*where,**kw)
201 matplotlib.interactive(is_interactive)
202 # make rendering call now, if the user tried to do it
203 if pylab.draw_if_interactive.called:
204 pylab.draw()
205 pylab.draw_if_interactive.called = False
206
207 return mpl_execfile
208
@@ -2,15 +2,6 b''
2 2 """Generic functions for extending IPython.
3 3
4 4 See http://cheeseshop.python.org/pypi/simplegeneric.
5
6 Here is an example from IPython.utils.text::
7
8 def print_lsstring(arg):
9 "Prettier (non-repr-like) and more informative printer for LSString"
10 print "LSString (.p, .n, .l, .s available). Value:"
11 print arg
12
13 print_lsstring = result_display.when_type(LSString)(print_lsstring)
14 5 """
15 6
16 7 #-----------------------------------------------------------------------------
@@ -388,8 +388,6 b' class Struct(dict):'
388 388 inv_conflict_solve_user[func] = inv_conflict_solve_user[name]
389 389 del inv_conflict_solve_user[name]
390 390 conflict_solve.update(self.__dict_invert(inv_conflict_solve_user))
391 #print 'merge. conflict_solve: '; pprint(conflict_solve) # dbg
392 #print '*'*50,'in merger. conflict_solver:'; pprint(conflict_solve)
393 391 for key in data_dict:
394 392 if key not in self:
395 393 self[key] = data_dict[key]
@@ -6,103 +6,39 b''
6 6 from __future__ import print_function
7 7
8 8 # Standard library imports
9 from cStringIO import StringIO
10 9
11 # System library imports.
12 10 import matplotlib
13 11 from matplotlib.backends.backend_svg import new_figure_manager
14 12 from matplotlib._pylab_helpers import Gcf
15 13
16 14 # Local imports.
17 15 from IPython.core.displaypub import publish_display_data
16 from IPython.lib.pylabtools import figure_to_svg
18 17
19 18 #-----------------------------------------------------------------------------
20 19 # Functions
21 20 #-----------------------------------------------------------------------------
22 21
23 def show(close=True):
22 def show(close=False):
24 23 """Show all figures as SVG payloads sent to the IPython clients.
25 24
26 25 Parameters
27 26 ----------
28 27 close : bool, optional
29 28 If true, a ``plt.close('all')`` call is automatically issued after
30 sending all the SVG figures.
29 sending all the SVG figures. If this is set, the figures will entirely
30 removed from the internal list of figures.
31 31 """
32 32 for figure_manager in Gcf.get_all_fig_managers():
33 send_svg_canvas(figure_manager.canvas)
33 send_svg_figure(figure_manager.canvas.figure)
34 34 if close:
35 35 matplotlib.pyplot.close('all')
36 36
37
37 38 # This flag will be reset by draw_if_interactive when called
38 39 show._draw_called = False
39 40
40 41
41 def figsize(sizex, sizey):
42 """Set the default figure size to be [sizex, sizey].
43
44 This is just an easy to remember, convenience wrapper that sets::
45
46 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
47 """
48 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
49
50
51 def pastefig(*figs):
52 """Paste one or more figures into the console workspace.
53
54 If no arguments are given, all available figures are pasted. If the
55 argument list contains references to invalid figures, a warning is printed
56 but the function continues pasting further figures.
57
58 Parameters
59 ----------
60 figs : tuple
61 A tuple that can contain any mixture of integers and figure objects.
62 """
63 if not figs:
64 show(close=False)
65 else:
66 fig_managers = Gcf.get_all_fig_managers()
67 fig_index = dict( [(fm.canvas.figure, fm.canvas) for fm in fig_managers]
68 + [ (fm.canvas.figure.number, fm.canvas) for fm in fig_managers] )
69
70 for fig in figs:
71 canvas = fig_index.get(fig)
72 if canvas is None:
73 print('Warning: figure %s not available.' % fig)
74 else:
75 send_svg_canvas(canvas)
76
77
78 def send_svg_canvas(canvas):
79 """Draw the current canvas and send it as an SVG payload.
80 """
81 # Set the background to white instead so it looks good on black. We store
82 # the current values to restore them at the end.
83 fc = canvas.figure.get_facecolor()
84 ec = canvas.figure.get_edgecolor()
85 canvas.figure.set_facecolor('white')
86 canvas.figure.set_edgecolor('white')
87 try:
88 publish_display_data(
89 'IPython.zmq.pylab.backend_inline.send_svg_canvas',
90 'Matplotlib Plot',
91 {'image/svg+xml' : svg_from_canvas(canvas)}
92 )
93 finally:
94 canvas.figure.set_facecolor(fc)
95 canvas.figure.set_edgecolor(ec)
96
97
98 def svg_from_canvas(canvas):
99 """ Return a string containing the SVG representation of a FigureCanvasSvg.
100 """
101 string_io = StringIO()
102 canvas.print_figure(string_io, format='svg')
103 return string_io.getvalue()
104
105
106 42 def draw_if_interactive():
107 43 """
108 44 Is called after every pylab drawing command
@@ -119,5 +55,19 b' def flush_svg():'
119 55 prior code execution, there had been any calls to draw_if_interactive.
120 56 """
121 57 if show._draw_called:
122 show(close=True)
58 # Show is called with the default close=False here, otherwise, the
59 # Figure will be closed and not available for future plotting.
60 show()
123 61 show._draw_called = False
62
63
64 def send_svg_figure(fig):
65 """Draw the current figure and send it as an SVG payload.
66 """
67 svg = figure_to_svg(fig)
68 publish_display_data(
69 'IPython.zmq.pylab.backend_inline.send_svg_figure',
70 'Matplotlib Plot',
71 {'image/svg+xml' : svg}
72 )
73
@@ -203,6 +203,8 b' class ZMQInteractiveShell(InteractiveShell):'
203 203
204 204 # Shorthands
205 205 shell = self.shell
206 disp_formatter = self.shell.display_formatter
207 ptformatter = disp_formatter.formatters['text/plain']
206 208 # dstore is a data store kept in the instance metadata bag to track any
207 209 # changes we make, so we can undo them later.
208 210 dstore = shell.meta.setdefault('doctest_mode', Struct())
@@ -210,16 +212,19 b' class ZMQInteractiveShell(InteractiveShell):'
210 212
211 213 # save a few values we'll need to recover later
212 214 mode = save_dstore('mode', False)
213 save_dstore('rc_pprint', shell.pprint)
215 save_dstore('rc_pprint', ptformatter.pprint)
216 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
214 217 save_dstore('xmode', shell.InteractiveTB.mode)
215 218
216 219 if mode == False:
217 220 # turn on
218 shell.pprint = False
221 ptformatter.pprint = False
222 disp_formatter.plain_text_only = True
219 223 shell.magic_xmode('Plain')
220 224 else:
221 225 # turn off
222 shell.pprint = dstore.rc_pprint
226 ptformatter.pprint = dstore.rc_pprint
227 disp_formatter.plain_text_only = dstore.rc_plain_text_only
223 228 shell.magic_xmode(dstore.xmode)
224 229
225 230 # Store new mode and inform on console
@@ -213,13 +213,7 b' def find_data_files():'
213 213 data_files = [ (manpagebase, manpages),
214 214 (pjoin(docdirbase, 'extensions'), igridhelpfiles),
215 215 ] + manual_files + example_files
216
217 ## import pprint # dbg
218 ## print('*'*80)
219 ## print('data files')
220 ## pprint.pprint(data_files)
221 ## print('*'*80)
222
216
223 217 return data_files
224 218
225 219
General Comments 0
You need to be logged in to leave comments. Login now