From ade496c7fdee54a46edf1c8a1b9e58a0edfb6e41 Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Wed, 6 Jun 2012 19:20:54 +0100 Subject: [PATCH 1/7] Auto build pyplot from setup. --- lib/matplotlib/pyplot.py | 9 ++++++++- setup.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index f6b814ba88fd..a4bb6d98290a 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -1,3 +1,6 @@ +# This file is entirely autogenerated by setup.py, and any changes to it will be lost. +# The leading part of this file can be modified in src/pyplot_header.py +# whilst the latter part is generated by boilerplate.py """ Provides a MATLAB-like plotting framework. @@ -2220,6 +2223,10 @@ def spy(Z, precision=0, marker=None, markersize=None, aspect='equal', hold=None, sci(ret) return ret + +################# REMAINING CONTENT GENERATED BY boilerplate.py ############## + + # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost @autogen_docstring(Axes.acorr) @@ -2925,7 +2932,7 @@ def step(x, y, *args, **kwargs): # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost @autogen_docstring(Axes.streamplot) -def streamplot(x, y, u, v, density=1, linewidth=None, color=None, cmap=None, norm=None, arrowsize=1, arrowstyle='-|>', minlength=0.10000000000000001, hold=None): +def streamplot(x, y, u, v, density=1, linewidth=None, color=None, cmap=None, norm=None, arrowsize=1, arrowstyle='-|>', minlength=0.1, hold=None): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() diff --git a/setup.py b/setup.py index f53f46ce5318..ed0ba427d654 100644 --- a/setup.py +++ b/setup.py @@ -248,6 +248,37 @@ def add_dateutil(): template = template.replace(" use = 'Agg'", " use = '%s'"%rc['backend']) open('lib/matplotlib/mpl-data/matplotlib.conf', 'w').write(template) +def build_pyplot(): + import StringIO + import os + import sys + + pyplot_path = os.path.join('lib', 'matplotlib', 'pyplot.py') + + pyplot_orig = file(pyplot_path, 'r').readlines() + + # this is the magic line that must exist in pyplot, after which the boilerplate content will be + # appended + bp_marker = '################# REMAINING CONTENT GENERATED BY boilerplate.py ##############\n' + + try: + pyplot_orig = pyplot_orig[:pyplot_orig.index(bp_marker)+1] + except IndexError: + raise ValueError('The pyplot.py file *must* have the exact line: %s' % bp_marker) + + pyplot = file(pyplot_path, 'w') + pyplot.writelines(pyplot_orig) + pyplot.write('\n\n') + + # importing boilerplate prints code. So capture the stdout and put it into the pyplot file. + old_stdout = sys.stdout + sys.stdout = pyplot + import boilerplate + sys.stdout = old_stdout + +# Write the matplotlib.pyplot file +build_pyplot() + try: additional_params # has setupegg.py provided except NameError: additional_params = {} From 87025b044517264465f503f27d816248f3e95dbe Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Wed, 6 Jun 2012 19:34:44 +0100 Subject: [PATCH 2/7] Tidied message in pyplot --- lib/matplotlib/pyplot.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index a4bb6d98290a..b111ac1ab277 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -1,6 +1,4 @@ -# This file is entirely autogenerated by setup.py, and any changes to it will be lost. -# The leading part of this file can be modified in src/pyplot_header.py -# whilst the latter part is generated by boilerplate.py +# Note: the latter part of this file is generated by boilerplate.py in setup.py """ Provides a MATLAB-like plotting framework. From 79170fa568dec660668760656cc5c0fb6b06086a Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Thu, 7 Jun 2012 09:20:48 +0100 Subject: [PATCH 3/7] boilerplate is now the script to run to generate pyplot.py --- boilerplate.py | 433 ++++++++++++++++++++++----------------- lib/matplotlib/pyplot.py | 4 +- setup.py | 32 +-- 3 files changed, 243 insertions(+), 226 deletions(-) diff --git a/boilerplate.py b/boilerplate.py index 8bf63b24528c..36f0181adf3d 100644 --- a/boilerplate.py +++ b/boilerplate.py @@ -1,11 +1,22 @@ -# Wrap the plot commands defined in axes. The code generated by this -# file is pasted into pyplot.py. We did try to do this the smart way, +""" +Script to autogenerate pyplot wrappers. + +When this script is run, the current contents of pyplot are +split into generatable and non-generatable content (via the magic header +:attr:`PYPLOT_MAGIC_HEADER`) and the generatable content is overwritten. +Hence, the non-generatable content should be edited in the pyplot.py file +itself, whereas the generatable content must be edited via templates in +this file. + +""" +# We did try to do the wrapping the smart way, # with callable functions and new.function, but could never get the # docstrings right for python2.2. See # http://groups.google.com/group/comp.lang.python/browse_frm/thread/dcd63ec13096a0f6/1b14640f3a4ad3dc?#1b14640f3a4ad3dc # For some later history, see # http://thread.gmane.org/gmane.comp.python.matplotlib.devel/7068 +import os import inspect import random import re @@ -17,7 +28,20 @@ from matplotlib.axes import Axes from matplotlib.cbook import dedent -_fmtplot = """\ + +# this is the magic line that must exist in pyplot, after which the boilerplate content will be +# appended +PYPLOT_MAGIC_HEADER = '################# REMAINING CONTENT GENERATED BY boilerplate.py ##############\n' + +PYPLOT_PATH = os.path.join(os.path.dirname(__file__), 'lib', + 'matplotlib', 'pyplot.py') + + + +def boilerplate_gen(): + """Generator of lines for the automated part of pyplot.""" + + _fmtplot = """ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost @autogen_docstring(Axes.%(func)s) @@ -35,9 +59,9 @@ def %(func)s(%(argspec)s): %(ax)s.hold(%(washold)s) %(mappable)s return %(ret)s -""" - -_fmtmisc = """\ + """ + + _fmtmisc = """ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost @docstring.copy_dedent(Axes.%(func)s) @@ -45,174 +69,174 @@ def %(func)s(%(argspec)s): %(ret)s = gca().%(func)s(%(call)s) draw_if_interactive() return %(ret)s -""" - -# these methods are all simple wrappers of Axes methods by the same -# name. -_plotcommands = ( - 'acorr', - 'arrow', - 'axhline', - 'axhspan', - 'axvline', - 'axvspan', - 'bar', - 'barh', - 'broken_barh', - 'boxplot', - 'cohere', - 'clabel', - 'contour', - 'contourf', - 'csd', - 'errorbar', - 'fill', - 'fill_between', - 'fill_betweenx', - 'hexbin', - 'hist', - 'hist2d', - 'hlines', - 'imshow', - 'loglog', - 'pcolor', - 'pcolormesh', - 'pie', - 'plot', - 'plot_date', - 'psd', - 'quiver', - 'quiverkey', - 'scatter', - 'semilogx', - 'semilogy', - 'specgram', - #'spy', - 'stem', - 'step', - 'streamplot', - 'tricontour', - 'tricontourf', - 'tripcolor', - 'triplot', - 'vlines', - 'xcorr', - 'barbs', - ) - -_misccommands = ( - 'cla', - 'grid', - 'legend', - 'table', - 'text', - 'annotate', - 'ticklabel_format', - 'locator_params', - 'tick_params', - 'margins', - 'autoscale', - ) - -cmappable = { - 'contour' : 'if %(ret)s._A is not None: sci(%(ret)s)', - 'contourf': 'if %(ret)s._A is not None: sci(%(ret)s)', - 'hexbin' : 'sci(%(ret)s)', - 'scatter' : 'sci(%(ret)s)', - 'pcolor' : 'sci(%(ret)s)', - 'pcolormesh': 'sci(%(ret)s)', - 'hist2d' : 'sci(%(ret)s[-1])', - 'imshow' : 'sci(%(ret)s)', - #'spy' : 'sci(%(ret)s)', ### may return image or Line2D - 'quiver' : 'sci(%(ret)s)', - 'specgram' : 'sci(%(ret)s[-1])', - 'streamplot' : 'sci(%(ret)s)', - 'tricontour' : 'if %(ret)s._A is not None: sci(%(ret)s)', - 'tricontourf': 'if %(ret)s._A is not None: sci(%(ret)s)', - 'tripcolor' : 'sci(%(ret)s)', - -} - -def format_value(value): - """ - Format function default values as needed for inspect.formatargspec. - The interesting part is a hard-coded list of functions used - as defaults in pyplot methods. """ - if isinstance(value, types.FunctionType): - if value.func_name in ('detrend_none', 'window_hanning'): - return '=mlab.' + value.func_name - if value.func_name == 'mean': - return '=np.' + value.func_name - raise ValueError, ('default value %s unknown to boilerplate.formatvalue' - % value) - return '='+repr(value) - -def remove_final_whitespace(string): - """ - Return a copy of *string* with final whitespace removed from each line. - """ - return '\n'.join(x.rstrip() for x in string.split('\n')) - -for fmt,cmdlist in (_fmtplot,_plotcommands),(_fmtmisc,_misccommands): - for func in cmdlist: - # For some commands, an additional line is needed to set the - # color map - if func in cmappable: - mappable = cmappable[func] % locals() - else: - mappable = '' - - # Get argspec of wrapped function - args, varargs, varkw, defaults = inspect.getargspec(getattr(Axes, func)) - args.pop(0) # remove 'self' argument - if defaults is None: - defaults = () - - # How to call the wrapped function - call = map(str, args) - if varargs is not None: - call.append('*'+varargs) - if varkw is not None: - call.append('**'+varkw) - call = ', '.join(call) - - # Add a hold keyword argument if needed (fmt is _fmtplot) and - # possible (if *args is used, we can't just add a hold - # argument in front of it since it would gobble one of the - # arguments the user means to pass via *args) - if varargs: - sethold = "hold = %(varkw)s.pop('hold', None)" % locals() - elif fmt is _fmtplot: - args.append('hold') - defaults = defaults + (None,) - sethold = '' - - # Now we can build the argspec for defining the wrapper - argspec = inspect.formatargspec(args, varargs, varkw, defaults, - formatvalue=format_value) - argspec = argspec[1:-1] # remove parens - - # A gensym-like facility in case some function takes an - # argument named washold, ax, or ret - washold,ret,ax = 'washold', 'ret', 'ax' - bad = set(args) | set((varargs, varkw)) - while washold in bad or ret in bad or ax in bad: - washold = 'washold' + str(random.randrange(10**12)) - ret = 'ret' + str(random.randrange(10**12)) - ax = 'ax' + str(random.randrange(10**12)) - - # Since we can't avoid using some function names, - # bail out if they are used as argument names - for reserved in ('gca', 'gci', 'draw_if_interactive'): - if reserved in bad: - raise ValueError, \ - 'Axes method %s has kwarg named %s' % (func, reserved) - - print remove_final_whitespace(fmt%locals()) - -# define the colormap functions -_fmtcmap = """\ + + # these methods are all simple wrappers of Axes methods by the same + # name. + _plotcommands = ( + 'acorr', + 'arrow', + 'axhline', + 'axhspan', + 'axvline', + 'axvspan', + 'bar', + 'barh', + 'broken_barh', + 'boxplot', + 'cohere', + 'clabel', + 'contour', + 'contourf', + 'csd', + 'errorbar', + 'fill', + 'fill_between', + 'fill_betweenx', + 'hexbin', + 'hist', + 'hist2d', + 'hlines', + 'imshow', + 'loglog', + 'pcolor', + 'pcolormesh', + 'pie', + 'plot', + 'plot_date', + 'psd', + 'quiver', + 'quiverkey', + 'scatter', + 'semilogx', + 'semilogy', + 'specgram', + #'spy', + 'stem', + 'step', + 'streamplot', + 'tricontour', + 'tricontourf', + 'tripcolor', + 'triplot', + 'vlines', + 'xcorr', + 'barbs', + ) + + _misccommands = ( + 'cla', + 'grid', + 'legend', + 'table', + 'text', + 'annotate', + 'ticklabel_format', + 'locator_params', + 'tick_params', + 'margins', + 'autoscale', + ) + + cmappable = { + 'contour' : 'if %(ret)s._A is not None: sci(%(ret)s)', + 'contourf': 'if %(ret)s._A is not None: sci(%(ret)s)', + 'hexbin' : 'sci(%(ret)s)', + 'scatter' : 'sci(%(ret)s)', + 'pcolor' : 'sci(%(ret)s)', + 'pcolormesh': 'sci(%(ret)s)', + 'hist2d' : 'sci(%(ret)s[-1])', + 'imshow' : 'sci(%(ret)s)', + #'spy' : 'sci(%(ret)s)', ### may return image or Line2D + 'quiver' : 'sci(%(ret)s)', + 'specgram' : 'sci(%(ret)s[-1])', + 'streamplot' : 'sci(%(ret)s)', + 'tricontour' : 'if %(ret)s._A is not None: sci(%(ret)s)', + 'tricontourf': 'if %(ret)s._A is not None: sci(%(ret)s)', + 'tripcolor' : 'sci(%(ret)s)', + + } + + def format_value(value): + """ + Format function default values as needed for inspect.formatargspec. + The interesting part is a hard-coded list of functions used + as defaults in pyplot methods. + """ + if isinstance(value, types.FunctionType): + if value.func_name in ('detrend_none', 'window_hanning'): + return '=mlab.' + value.func_name + if value.func_name == 'mean': + return '=np.' + value.func_name + raise ValueError, ('default value %s unknown to boilerplate.formatvalue' + % value) + return '='+repr(value) + + def remove_final_whitespace(string): + """ + Return a copy of *string* with final whitespace removed from each line. + """ + return '\n'.join(x.rstrip() for x in string.split('\n')) + + for fmt,cmdlist in (_fmtplot,_plotcommands),(_fmtmisc,_misccommands): + for func in cmdlist: + # For some commands, an additional line is needed to set the + # color map + if func in cmappable: + mappable = cmappable[func] % locals() + else: + mappable = '' + + # Get argspec of wrapped function + args, varargs, varkw, defaults = inspect.getargspec(getattr(Axes, func)) + args.pop(0) # remove 'self' argument + if defaults is None: + defaults = () + + # How to call the wrapped function + call = map(str, args) + if varargs is not None: + call.append('*'+varargs) + if varkw is not None: + call.append('**'+varkw) + call = ', '.join(call) + + # Add a hold keyword argument if needed (fmt is _fmtplot) and + # possible (if *args is used, we can't just add a hold + # argument in front of it since it would gobble one of the + # arguments the user means to pass via *args) + if varargs: + sethold = "hold = %(varkw)s.pop('hold', None)" % locals() + elif fmt is _fmtplot: + args.append('hold') + defaults = defaults + (None,) + sethold = '' + + # Now we can build the argspec for defining the wrapper + argspec = inspect.formatargspec(args, varargs, varkw, defaults, + formatvalue=format_value) + argspec = argspec[1:-1] # remove parens + + # A gensym-like facility in case some function takes an + # argument named washold, ax, or ret + washold,ret,ax = 'washold', 'ret', 'ax' + bad = set(args) | set((varargs, varkw)) + while washold in bad or ret in bad or ax in bad: + washold = 'washold' + str(random.randrange(10**12)) + ret = 'ret' + str(random.randrange(10**12)) + ax = 'ax' + str(random.randrange(10**12)) + + # Since we can't avoid using some function names, + # bail out if they are used as argument names + for reserved in ('gca', 'gci', 'draw_if_interactive'): + if reserved in bad: + raise ValueError, \ + 'Axes method %s has kwarg named %s' % (func, reserved) + + yield remove_final_whitespace(fmt%locals()) + + # define the colormap functions + _fmtcmap = """ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost def %(name)s(): @@ -228,25 +252,48 @@ def %(name)s(): draw_if_interactive() """ + + cmaps = ( + 'autumn', + 'bone', + 'cool', + 'copper', + 'flag', + 'gray' , + 'hot', + 'hsv', + 'jet' , + 'pink', + 'prism', + 'spring', + 'summer', + 'winter', + 'spectral' + ) + # add all the colormaps (autumn, hsv, ....) + for name in cmaps: + yield _fmtcmap%locals() + + +def build_pyplot(): + pyplot_path = os.path.join(os.path.dirname(__file__), 'lib', + 'matplotlib', 'pyplot.py') + + pyplot_orig = file(pyplot_path, 'r').readlines() + + + try: + pyplot_orig = pyplot_orig[:pyplot_orig.index(PYPLOT_MAGIC_HEADER)+1] + except IndexError: + raise ValueError('The pyplot.py file *must* have the exact line: %s' % PYPLOT_MAGIC_HEADER) + + pyplot = file(pyplot_path, 'w') + pyplot.writelines(pyplot_orig) + pyplot.write('\n') + + pyplot.writelines(boilerplate_gen()) -cmaps = ( - 'autumn', - 'bone', - 'cool', - 'copper', - 'flag', - 'gray' , - 'hot', - 'hsv', - 'jet' , - 'pink', - 'prism', - 'spring', - 'summer', - 'winter', - 'spectral' -) -# add all the colormaps (autumn, hsv, ....) -for name in cmaps: - print _fmtcmap%locals() +if __name__ == '__main__': + # Write the matplotlib.pyplot file + build_pyplot() \ No newline at end of file diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index b111ac1ab277..5daf924833d9 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -1,4 +1,5 @@ -# Note: the latter part of this file is generated by boilerplate.py in setup.py +# Note: The first part of this file can be modified in place, but the latter part +# is autogenerated by the boilerplate.py script. """ Provides a MATLAB-like plotting framework. @@ -3383,4 +3384,3 @@ def spectral(): im.set_cmap(cm.spectral) draw_if_interactive() - diff --git a/setup.py b/setup.py index ed0ba427d654..cfc27b9d9b36 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,5 @@ """ -You will need to have freetype, libpng and zlib installed to comile +You will need to have freetype, libpng and zlib installed to compile matplotlib, inlcuding the *-devel versions of these libraries if you are using a package manager like RPM or debian. @@ -248,36 +248,6 @@ def add_dateutil(): template = template.replace(" use = 'Agg'", " use = '%s'"%rc['backend']) open('lib/matplotlib/mpl-data/matplotlib.conf', 'w').write(template) -def build_pyplot(): - import StringIO - import os - import sys - - pyplot_path = os.path.join('lib', 'matplotlib', 'pyplot.py') - - pyplot_orig = file(pyplot_path, 'r').readlines() - - # this is the magic line that must exist in pyplot, after which the boilerplate content will be - # appended - bp_marker = '################# REMAINING CONTENT GENERATED BY boilerplate.py ##############\n' - - try: - pyplot_orig = pyplot_orig[:pyplot_orig.index(bp_marker)+1] - except IndexError: - raise ValueError('The pyplot.py file *must* have the exact line: %s' % bp_marker) - - pyplot = file(pyplot_path, 'w') - pyplot.writelines(pyplot_orig) - pyplot.write('\n\n') - - # importing boilerplate prints code. So capture the stdout and put it into the pyplot file. - old_stdout = sys.stdout - sys.stdout = pyplot - import boilerplate - sys.stdout = old_stdout - -# Write the matplotlib.pyplot file -build_pyplot() try: additional_params # has setupegg.py provided except NameError: additional_params = {} From d7b2999353c654fcd863e9793c9b917e84b099a0 Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Fri, 8 Jun 2012 10:29:36 +0100 Subject: [PATCH 4/7] Tidied boilerplate a little. Seems more python3 compatible (although untested). --- boilerplate.py | 96 ++++++++++++++---------------- lib/matplotlib/pyplot.py | 124 +++++++++++++++++++-------------------- 2 files changed, 107 insertions(+), 113 deletions(-) diff --git a/boilerplate.py b/boilerplate.py index 36f0181adf3d..b559a7cd4d81 100644 --- a/boilerplate.py +++ b/boilerplate.py @@ -19,14 +19,11 @@ import os import inspect import random -import re -import sys import types # import the local copy of matplotlib, not the installed one #sys.path.insert(0, './lib') from matplotlib.axes import Axes -from matplotlib.cbook import dedent # this is the magic line that must exist in pyplot, after which the boilerplate content will be @@ -37,13 +34,12 @@ 'matplotlib', 'pyplot.py') +AUTOGEN_MSG = """ +# This function was autogenerated by boilerplate.py. Do not edit as +# changes will be lost""" -def boilerplate_gen(): - """Generator of lines for the automated part of pyplot.""" - _fmtplot = """ -# This function was autogenerated by boilerplate.py. Do not edit as -# changes will be lost +PLOT_TEMPLATE = AUTOGEN_MSG + """ @autogen_docstring(Axes.%(func)s) def %(func)s(%(argspec)s): %(ax)s = gca() @@ -59,17 +55,38 @@ def %(func)s(%(argspec)s): %(ax)s.hold(%(washold)s) %(mappable)s return %(ret)s - """ - - _fmtmisc = """ -# This function was autogenerated by boilerplate.py. Do not edit as -# changes will be lost +""" + + +# Used for misc functions such as cla/legend etc. +MISC_FN_TEMPLATE = AUTOGEN_MSG + """ @docstring.copy_dedent(Axes.%(func)s) def %(func)s(%(argspec)s): %(ret)s = gca().%(func)s(%(call)s) draw_if_interactive() return %(ret)s - """ +""" + + +# Used for colormap functions +CMAP_TEMPLATE = AUTOGEN_MSG + """ +def {name}(): + ''' + set the default colormap to {name} and apply to current image if any. + See help(colormaps) for more information + ''' + rc('image', cmap='{name}') + im = gci() + + if im is not None: + im.set_cmap(cm.{name}) + draw_if_interactive() + +""" + + +def boilerplate_gen(): + """Generator of lines for the automated part of pyplot.""" # these methods are all simple wrappers of Axes methods by the same # name. @@ -168,17 +185,12 @@ def format_value(value): return '=mlab.' + value.func_name if value.func_name == 'mean': return '=np.' + value.func_name - raise ValueError, ('default value %s unknown to boilerplate.formatvalue' - % value) + raise ValueError(('default value %s unknown to boilerplate.' + \ + 'formatvalue') % value) return '='+repr(value) - def remove_final_whitespace(string): - """ - Return a copy of *string* with final whitespace removed from each line. - """ - return '\n'.join(x.rstrip() for x in string.split('\n')) - - for fmt,cmdlist in (_fmtplot,_plotcommands),(_fmtmisc,_misccommands): + for fmt, cmdlist in [(PLOT_TEMPLATE, _plotcommands), + (MISC_FN_TEMPLATE, _misccommands)]: for func in cmdlist: # For some commands, an additional line is needed to set the # color map @@ -201,13 +213,13 @@ def remove_final_whitespace(string): call.append('**'+varkw) call = ', '.join(call) - # Add a hold keyword argument if needed (fmt is _fmtplot) and + # Add a hold keyword argument if needed (fmt is PLOT_TEMPLATE) and # possible (if *args is used, we can't just add a hold # argument in front of it since it would gobble one of the # arguments the user means to pass via *args) if varargs: sethold = "hold = %(varkw)s.pop('hold', None)" % locals() - elif fmt is _fmtplot: + elif fmt is PLOT_TEMPLATE: args.append('hold') defaults = defaults + (None,) sethold = '' @@ -219,7 +231,7 @@ def remove_final_whitespace(string): # A gensym-like facility in case some function takes an # argument named washold, ax, or ret - washold,ret,ax = 'washold', 'ret', 'ax' + washold, ret, ax = 'washold', 'ret', 'ax' bad = set(args) | set((varargs, varkw)) while washold in bad or ret in bad or ax in bad: washold = 'washold' + str(random.randrange(10**12)) @@ -230,29 +242,11 @@ def remove_final_whitespace(string): # bail out if they are used as argument names for reserved in ('gca', 'gci', 'draw_if_interactive'): if reserved in bad: - raise ValueError, \ - 'Axes method %s has kwarg named %s' % (func, reserved) - - yield remove_final_whitespace(fmt%locals()) - - # define the colormap functions - _fmtcmap = """ -# This function was autogenerated by boilerplate.py. Do not edit as -# changes will be lost -def %(name)s(): - ''' - set the default colormap to %(name)s and apply to current image if any. - See help(colormaps) for more information - ''' - rc('image', cmap='%(name)s') - im = gci() - - if im is not None: - im.set_cmap(cm.%(name)s) - draw_if_interactive() - -""" + msg = 'Axes method %s has kwarg named %s' % (func, reserved) + raise ValueError(msg) + yield fmt % locals() + cmaps = ( 'autumn', 'bone', @@ -272,14 +266,14 @@ def %(name)s(): ) # add all the colormaps (autumn, hsv, ....) for name in cmaps: - yield _fmtcmap%locals() + yield CMAP_TEMPLATE.format(name=name) def build_pyplot(): pyplot_path = os.path.join(os.path.dirname(__file__), 'lib', 'matplotlib', 'pyplot.py') - pyplot_orig = file(pyplot_path, 'r').readlines() + pyplot_orig = open(pyplot_path, 'r').readlines() try: @@ -287,7 +281,7 @@ def build_pyplot(): except IndexError: raise ValueError('The pyplot.py file *must* have the exact line: %s' % PYPLOT_MAGIC_HEADER) - pyplot = file(pyplot_path, 'w') + pyplot = open(pyplot_path, 'w') pyplot.writelines(pyplot_orig) pyplot.write('\n') diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 5daf924833d9..8b9a205c3886 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -2233,7 +2233,7 @@ def acorr(x, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2241,7 +2241,7 @@ def acorr(x, hold=None, **kwargs): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2251,7 +2251,7 @@ def arrow(x, y, dx, dy, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2259,7 +2259,7 @@ def arrow(x, y, dx, dy, hold=None, **kwargs): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2269,7 +2269,7 @@ def axhline(y=0, xmin=0, xmax=1, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2277,7 +2277,7 @@ def axhline(y=0, xmin=0, xmax=1, hold=None, **kwargs): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2287,7 +2287,7 @@ def axhspan(ymin, ymax, xmin=0, xmax=1, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2295,7 +2295,7 @@ def axhspan(ymin, ymax, xmin=0, xmax=1, hold=None, **kwargs): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2305,7 +2305,7 @@ def axvline(x=0, ymin=0, ymax=1, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2313,7 +2313,7 @@ def axvline(x=0, ymin=0, ymax=1, hold=None, **kwargs): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2323,7 +2323,7 @@ def axvspan(xmin, xmax, ymin=0, ymax=1, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2331,7 +2331,7 @@ def axvspan(xmin, xmax, ymin=0, ymax=1, hold=None, **kwargs): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2341,7 +2341,7 @@ def bar(left, height, width=0.8, bottom=None, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2349,7 +2349,7 @@ def bar(left, height, width=0.8, bottom=None, hold=None, **kwargs): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2359,7 +2359,7 @@ def barh(bottom, width, height=0.8, left=None, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2367,7 +2367,7 @@ def barh(bottom, width, height=0.8, left=None, hold=None, **kwargs): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2377,7 +2377,7 @@ def broken_barh(xranges, yrange, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2385,7 +2385,7 @@ def broken_barh(xranges, yrange, hold=None, **kwargs): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2395,7 +2395,7 @@ def boxplot(x, notch=0, sym='b+', vert=1, whis=1.5, positions=None, widths=None, ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2403,7 +2403,7 @@ def boxplot(x, notch=0, sym='b+', vert=1, whis=1.5, positions=None, widths=None, draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2413,7 +2413,7 @@ def cohere(x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, window=mlab.wi ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2421,7 +2421,7 @@ def cohere(x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, window=mlab.wi draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2439,7 +2439,7 @@ def clabel(CS, *args, **kwargs): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2485,7 +2485,7 @@ def csd(x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, window=mlab.windo ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2493,7 +2493,7 @@ def csd(x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, window=mlab.windo draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2503,7 +2503,7 @@ def errorbar(x, y, yerr=None, xerr=None, fmt='-', ecolor=None, elinewidth=None, ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2511,7 +2511,7 @@ def errorbar(x, y, yerr=None, xerr=None, fmt='-', ecolor=None, elinewidth=None, draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2529,7 +2529,7 @@ def fill(*args, **kwargs): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2539,7 +2539,7 @@ def fill_between(x, y1, y2=0, where=None, interpolate=False, hold=None, **kwargs ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2547,7 +2547,7 @@ def fill_between(x, y1, y2=0, where=None, interpolate=False, hold=None, **kwargs draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2557,7 +2557,7 @@ def fill_betweenx(y, x1, x2=0, where=None, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2565,7 +2565,7 @@ def fill_betweenx(y, x1, x2=0, where=None, hold=None, **kwargs): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2575,7 +2575,7 @@ def hexbin(x, y, C=None, gridsize=100, bins=None, xscale='linear', yscale='linea ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2593,7 +2593,7 @@ def hist(x, bins=10, range=None, normed=False, weights=None, cumulative=False, b ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2601,7 +2601,7 @@ def hist(x, bins=10, range=None, normed=False, weights=None, cumulative=False, b draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2611,7 +2611,7 @@ def hist2d(x, y, bins=10, range=None, normed=False, weights=None, cmin=None, cma ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2629,7 +2629,7 @@ def hlines(y, xmin, xmax, colors='k', linestyles='solid', label='', hold=None, * ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2637,7 +2637,7 @@ def hlines(y, xmin, xmax, colors='k', linestyles='solid', label='', hold=None, * draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2647,7 +2647,7 @@ def imshow(X, cmap=None, norm=None, aspect=None, interpolation=None, alpha=None, ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2673,7 +2673,7 @@ def loglog(*args, **kwargs): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2719,7 +2719,7 @@ def pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6 ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2727,7 +2727,7 @@ def pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6 draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2745,7 +2745,7 @@ def plot(*args, **kwargs): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2755,7 +2755,7 @@ def plot_date(x, y, fmt='bo', tz=None, xdate=True, ydate=False, hold=None, **kwa ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2763,7 +2763,7 @@ def plot_date(x, y, fmt='bo', tz=None, xdate=True, ydate=False, hold=None, **kwa draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2773,7 +2773,7 @@ def psd(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, window=mlab.window_h ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2781,7 +2781,7 @@ def psd(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, window=mlab.window_h draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2817,7 +2817,7 @@ def quiverkey(*args, **kw): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2827,7 +2827,7 @@ def scatter(x, y, s=20, c='b', marker='o', cmap=None, norm=None, vmin=None, vmax ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2853,7 +2853,7 @@ def semilogx(*args, **kwargs): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2871,7 +2871,7 @@ def semilogy(*args, **kwargs): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2881,7 +2881,7 @@ def specgram(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, window=mlab.win ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2899,7 +2899,7 @@ def stem(x, y, linefmt='b-', markerfmt='bo', basefmt='r-', bottom=None, label=No ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -2907,7 +2907,7 @@ def stem(x, y, linefmt='b-', markerfmt='bo', basefmt='r-', bottom=None, label=No draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2925,7 +2925,7 @@ def step(x, y, *args, **kwargs): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -2935,7 +2935,7 @@ def streamplot(x, y, u, v, density=1, linewidth=None, color=None, cmap=None, nor ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -3015,7 +3015,7 @@ def triplot(*args, **kwargs): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -3025,7 +3025,7 @@ def vlines(x, ymin, ymax, colors='k', linestyles='solid', label='', hold=None, * ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -3033,7 +3033,7 @@ def vlines(x, ymin, ymax, colors='k', linestyles='solid', label='', hold=None, * draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -3043,7 +3043,7 @@ def xcorr(x, y, normed=True, detrend=mlab.detrend_none, usevlines=True, maxlags= ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() - + if hold is not None: ax.hold(hold) try: @@ -3051,7 +3051,7 @@ def xcorr(x, y, normed=True, detrend=mlab.detrend_none, usevlines=True, maxlags= draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as @@ -3069,7 +3069,7 @@ def barbs(*args, **kw): draw_if_interactive() finally: ax.hold(washold) - + return ret # This function was autogenerated by boilerplate.py. Do not edit as From 12f407bbbb83301109d35bbad28f0d8270d9d5c6 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Fri, 8 Jun 2012 10:29:21 -0400 Subject: [PATCH 5/7] Make boilerplate.py Python 3 compatible --- boilerplate.py | 60 +++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/boilerplate.py b/boilerplate.py index b559a7cd4d81..ecbf01607281 100644 --- a/boilerplate.py +++ b/boilerplate.py @@ -3,9 +3,9 @@ When this script is run, the current contents of pyplot are split into generatable and non-generatable content (via the magic header -:attr:`PYPLOT_MAGIC_HEADER`) and the generatable content is overwritten. +:attr:`PYPLOT_MAGIC_HEADER`) and the generatable content is overwritten. Hence, the non-generatable content should be edited in the pyplot.py file -itself, whereas the generatable content must be edited via templates in +itself, whereas the generatable content must be edited via templates in this file. """ @@ -30,7 +30,7 @@ # appended PYPLOT_MAGIC_HEADER = '################# REMAINING CONTENT GENERATED BY boilerplate.py ##############\n' -PYPLOT_PATH = os.path.join(os.path.dirname(__file__), 'lib', +PYPLOT_PATH = os.path.join(os.path.dirname(__file__), 'lib', 'matplotlib', 'pyplot.py') @@ -87,7 +87,7 @@ def {name}(): def boilerplate_gen(): """Generator of lines for the automated part of pyplot.""" - + # these methods are all simple wrappers of Axes methods by the same # name. _plotcommands = ( @@ -140,7 +140,7 @@ def boilerplate_gen(): 'xcorr', 'barbs', ) - + _misccommands = ( 'cla', 'grid', @@ -154,7 +154,7 @@ def boilerplate_gen(): 'margins', 'autoscale', ) - + cmappable = { 'contour' : 'if %(ret)s._A is not None: sci(%(ret)s)', 'contourf': 'if %(ret)s._A is not None: sci(%(ret)s)', @@ -171,9 +171,9 @@ def boilerplate_gen(): 'tricontour' : 'if %(ret)s._A is not None: sci(%(ret)s)', 'tricontourf': 'if %(ret)s._A is not None: sci(%(ret)s)', 'tripcolor' : 'sci(%(ret)s)', - + } - + def format_value(value): """ Format function default values as needed for inspect.formatargspec. @@ -181,14 +181,14 @@ def format_value(value): as defaults in pyplot methods. """ if isinstance(value, types.FunctionType): - if value.func_name in ('detrend_none', 'window_hanning'): - return '=mlab.' + value.func_name - if value.func_name == 'mean': - return '=np.' + value.func_name + if value.__name__ in ('detrend_none', 'window_hanning'): + return '=mlab.' + value.__name__ + if value.__name__ == 'mean': + return '=np.' + value.__name__ raise ValueError(('default value %s unknown to boilerplate.' + \ 'formatvalue') % value) return '='+repr(value) - + for fmt, cmdlist in [(PLOT_TEMPLATE, _plotcommands), (MISC_FN_TEMPLATE, _misccommands)]: for func in cmdlist: @@ -198,21 +198,21 @@ def format_value(value): mappable = cmappable[func] % locals() else: mappable = '' - + # Get argspec of wrapped function args, varargs, varkw, defaults = inspect.getargspec(getattr(Axes, func)) args.pop(0) # remove 'self' argument if defaults is None: defaults = () - + # How to call the wrapped function - call = map(str, args) + call = list(map(str, args)) if varargs is not None: call.append('*'+varargs) if varkw is not None: call.append('**'+varkw) call = ', '.join(call) - + # Add a hold keyword argument if needed (fmt is PLOT_TEMPLATE) and # possible (if *args is used, we can't just add a hold # argument in front of it since it would gobble one of the @@ -223,12 +223,12 @@ def format_value(value): args.append('hold') defaults = defaults + (None,) sethold = '' - + # Now we can build the argspec for defining the wrapper argspec = inspect.formatargspec(args, varargs, varkw, defaults, formatvalue=format_value) argspec = argspec[1:-1] # remove parens - + # A gensym-like facility in case some function takes an # argument named washold, ax, or ret washold, ret, ax = 'washold', 'ret', 'ax' @@ -237,16 +237,16 @@ def format_value(value): washold = 'washold' + str(random.randrange(10**12)) ret = 'ret' + str(random.randrange(10**12)) ax = 'ax' + str(random.randrange(10**12)) - + # Since we can't avoid using some function names, # bail out if they are used as argument names for reserved in ('gca', 'gci', 'draw_if_interactive'): if reserved in bad: msg = 'Axes method %s has kwarg named %s' % (func, reserved) raise ValueError(msg) - + yield fmt % locals() - + cmaps = ( 'autumn', 'bone', @@ -270,24 +270,24 @@ def format_value(value): def build_pyplot(): - pyplot_path = os.path.join(os.path.dirname(__file__), 'lib', + pyplot_path = os.path.join(os.path.dirname(__file__), 'lib', 'matplotlib', 'pyplot.py') - + pyplot_orig = open(pyplot_path, 'r').readlines() - - + + try: pyplot_orig = pyplot_orig[:pyplot_orig.index(PYPLOT_MAGIC_HEADER)+1] except IndexError: raise ValueError('The pyplot.py file *must* have the exact line: %s' % PYPLOT_MAGIC_HEADER) - + pyplot = open(pyplot_path, 'w') pyplot.writelines(pyplot_orig) pyplot.write('\n') - + pyplot.writelines(boilerplate_gen()) -if __name__ == '__main__': +if __name__ == '__main__': # Write the matplotlib.pyplot file - build_pyplot() \ No newline at end of file + build_pyplot() From 7b1e8872b18ff2ccf3dc1989de42388cad09868f Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Fri, 8 Jun 2012 16:01:19 +0100 Subject: [PATCH 6/7] Coding guide pyplot update. --- doc/devel/coding_guide.rst | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/devel/coding_guide.rst b/doc/devel/coding_guide.rst index 1d338e4d71e8..eb07ba335cbe 100644 --- a/doc/devel/coding_guide.rst +++ b/doc/devel/coding_guide.rst @@ -323,7 +323,7 @@ Writing examples ================ We have hundreds of examples in subdirectories of -file:`matplotlib/examples`, and these are automatically +:file:`matplotlib/examples`, and these are automatically generated when the website is built to show up both in the `examples `_ and `gallery `_ sections of the @@ -349,6 +349,17 @@ object:: print 'datafile', datafile +Writing a new pyplot function +============================= + +The :mod:`matplotlib.pyplot` module can be thought of as combination of some +manually written and some autogenerated functions. Modifications can be made +to pyplot where the function definition does not explicitly state otherwise +and autogenerated functions can be modified by changing, and subsequently +runnning, the :file:`boilerplate.py` script which will re-generate the complete +pyplot module inplace, keeping all of the manual content. + + Testing ======= From 46e1761e92e880ffb18737d49666b96406aae926 Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Mon, 11 Jun 2012 13:52:52 +0100 Subject: [PATCH 7/7] @mdboom's suggested devel documentation for boilerplate. --- doc/devel/coding_guide.rst | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/doc/devel/coding_guide.rst b/doc/devel/coding_guide.rst index eb07ba335cbe..87c15a68f492 100644 --- a/doc/devel/coding_guide.rst +++ b/doc/devel/coding_guide.rst @@ -351,14 +351,12 @@ object:: Writing a new pyplot function ============================= - -The :mod:`matplotlib.pyplot` module can be thought of as combination of some -manually written and some autogenerated functions. Modifications can be made -to pyplot where the function definition does not explicitly state otherwise -and autogenerated functions can be modified by changing, and subsequently -runnning, the :file:`boilerplate.py` script which will re-generate the complete -pyplot module inplace, keeping all of the manual content. - +A large portion of the pyplot interface is automatically generated by the +`boilerplate.py` script (in the root of the source tree). To add or remove +a plotting method from pyplot, edit the appropriate list in `boilerplate.py` +and then run the script which will update the content in +`lib/matplotlib/pyplot.py`. Both the changes in `boilerplate.py` and +`lib/matplotlib/pyplot.py` should be checked into the repository. Testing =======