From: <md...@us...> - 2008-10-27 18:52:45
|
Revision: 6338 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6338&view=rev Author: mdboom Date: 2008-10-27 18:52:41 +0000 (Mon, 27 Oct 2008) Log Message: ----------- More docs. Modified Paths: -------------- trunk/matplotlib/doc/api/index.rst trunk/matplotlib/doc/devel/outline.rst trunk/matplotlib/lib/matplotlib/font_manager.py trunk/matplotlib/lib/matplotlib/fontconfig_pattern.py trunk/matplotlib/lib/matplotlib/lines.py trunk/matplotlib/lib/matplotlib/mlab.py Added Paths: ----------- trunk/matplotlib/doc/api/font_manager_api.rst Added: trunk/matplotlib/doc/api/font_manager_api.rst =================================================================== --- trunk/matplotlib/doc/api/font_manager_api.rst (rev 0) +++ trunk/matplotlib/doc/api/font_manager_api.rst 2008-10-27 18:52:41 UTC (rev 6338) @@ -0,0 +1,21 @@ +*********************** +matplotlib font_manager +*********************** + +:mod:`matplotlib.font_manager` +============================== + +.. automodule:: matplotlib.font_manager + :members: + :undoc-members: + :show-inheritance: + +:mod:`matplotlib.fontconfig_pattern` +============================== + +.. automodule:: matplotlib.fontconfig_pattern + :members: + :undoc-members: + :show-inheritance: + + Modified: trunk/matplotlib/doc/api/index.rst =================================================================== --- trunk/matplotlib/doc/api/index.rst 2008-10-27 18:04:58 UTC (rev 6337) +++ trunk/matplotlib/doc/api/index.rst 2008-10-27 18:52:41 UTC (rev 6338) @@ -14,7 +14,6 @@ matplotlib_configuration_api.rst afm_api.rst artist_api.rst - figure_api.rst axes_api.rst axis_api.rst cbook_api.rst @@ -22,6 +21,8 @@ collections_api.rst colorbar_api.rst colors_api.rst + figure_api.rst + font_manager_api.rst nxutils_api.rst mathtext_api.rst mlab_api.rst Modified: trunk/matplotlib/doc/devel/outline.rst =================================================================== --- trunk/matplotlib/doc/devel/outline.rst 2008-10-27 18:04:58 UTC (rev 6337) +++ trunk/matplotlib/doc/devel/outline.rst 2008-10-27 18:52:41 UTC (rev 6338) @@ -126,17 +126,17 @@ dviread Darren needs conversion figure Darren needs conversion finance Darren needs conversion -font_manager Mike needs conversion -fontconfig_pattern Mike needs conversion +font_manager Mike converted +fontconfig_pattern Mike converted image needs conversion legend needs conversion -lines needs conversion +lines Mike & ??? converted mathtext Mike converted -mlab needs conversion -mpl needs conversion +mlab John/Mike converted +mpl N/A patches Mike converted path Mike converted -pylab no docstrings +pylab N/A pyplot converted quiver needs conversion rcsetup needs conversion Modified: trunk/matplotlib/lib/matplotlib/font_manager.py =================================================================== --- trunk/matplotlib/lib/matplotlib/font_manager.py 2008-10-27 18:04:58 UTC (rev 6337) +++ trunk/matplotlib/lib/matplotlib/font_manager.py 2008-10-27 18:52:41 UTC (rev 6338) @@ -1,17 +1,26 @@ """ -A module for finding, managing, and using fonts across-platforms. +A module for finding, managing, and using fonts across platforms. -This module provides a single FontManager that can be shared across -backends and platforms. The findfont() function returns the best -TrueType (TTF) font file in the local or system font path that matches -the specified FontProperties. The FontManager also handles Adobe Font -Metrics (AFM) font files for use by the PostScript backend. +This module provides a single :class:`FontManager` instance that can +be shared across backends and platforms. The :func:`findfont` +function returns the best TrueType (TTF) font file in the local or +system font path that matches the specified FontProperties. The +FontManager also handles Adobe Font Metrics (AFM) font files for use +by the PostScript backend. -The design is based on the W3C Cascading Style Sheet, Level 1 (CSS1) -font specification (http://www.w3.org/TR/1998/REC-CSS2-19980512/ ). +The design is based on the `W3C Cascading Style Sheet, Level 1 (CSS1) +font specification <http://www.w3.org/TR/1998/REC-CSS2-19980512/>`_. Future versions may implement the Level 2 or 2.1 specifications. +Experimental support is included for using `fontconfig +<http://www.fontconfig.org>`_ on Unix variant plaforms (Linux, OS X, +Solaris). To enable it, set the constant ``USE_FONTCONFIG`` in this +file to ``True``. Fontconfig has the advantage that it is the +standard way to look up fonts on X11 platforms, so if a font is +installed, it is much more likely to be found. +""" +""" KNOWN ISSUES - documentation @@ -24,9 +33,9 @@ - 'light' is an invalid weight value, remove it. - update_fonts not implemented - Authors : John Hunter <jdh...@ac...> Paul Barrett <Ba...@ST...> + Michael Droettboom <md...@ST...> Copyright : John Hunter (2004,2005), Paul Barrett (2004,2005) License : matplotlib license (PSF compatible) The font directory code is from ttfquery, @@ -99,12 +108,21 @@ X11FontDirectories.append(path) def get_fontext_synonyms(fontext): + """ + Return a list of file extensions extensions that are synonyms for + the given file extension *fileext*. + """ return {'ttf': ('ttf', 'otf'), + 'otf': ('ttf', 'otf'), 'afm': ('afm',)}[fontext] def win32FontDirectory(): - """Return the user-specified font directory for Win32.""" + """Return the user-specified font directory for Win32. This is + looked up from the registry key:: + \\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Fonts + + If the key is not found, $WINDIR/Fonts will be returned.""" try: import _winreg except ImportError: @@ -126,8 +144,9 @@ def win32InstalledFonts(directory=None, fontext='ttf'): """ Search for fonts in the specified font directory, or use the - system directories if none given. A list of TrueType fonts are - returned by default with AFM fonts as an option. + system directories if none given. A list of TrueType font + filenames are returned by default, or AFM fonts if *fontext* == + 'afm'. """ import _winreg @@ -168,11 +187,16 @@ return None def OSXFontDirectory(): - """Return the system font directories for OS X.""" - + """ + Return the system font directories for OS X. This is done by + starting at the list of hardcoded paths in + :attr:`OSXFontDirectories` and returning all nested directories + within them. + """ fontpaths = [] def add(arg,directory,files): fontpaths.append(directory) + for fontdir in OSXFontDirectories: try: if os.path.isdir(fontdir): @@ -182,7 +206,9 @@ return fontpaths def OSXInstalledFonts(directory=None, fontext='ttf'): - """Get list of font files on OS X - ignores font suffix by default""" + """ + Get list of font files on OS X - ignores font suffix by default. + """ if directory is None: directory = OSXFontDirectory() @@ -200,7 +226,12 @@ def x11FontDirectory(): - """Return the system font directories for X11.""" + """ + Return the system font directories for X11. This is done by + starting at the list of hardcoded paths in + :attr:`X11FontDirectories` and returning all nested directories + within them. + """ fontpaths = [] def add(arg,directory,files): fontpaths.append(directory) @@ -213,10 +244,14 @@ pass return fontpaths + def get_fontconfig_fonts(fontext='ttf'): - """Grab a list of all the fonts that are being tracked by fontconfig. - This is an easy way to grab all of the fonts the user wants to be made - available to applications, without knowing where all of them reside.""" + """ + Grab a list of all the fonts that are being tracked by fontconfig + by making a system call to ``fc-list``. This is an easy way to + grab all of the fonts the user wants to be made available to + applications, without needing knowing where all of them reside. + """ try: import commands except ImportError: @@ -299,9 +334,8 @@ class FontKey(object): """ A class for storing Font properties. It is used when populating - the font dictionary. + the font lookup dictionary. """ - def __init__(self, name ='', style ='normal', @@ -323,8 +357,10 @@ def ttfFontProperty(font): """ - A function for populating the FontKey by extracting information - from the TrueType font file. + A function for populating the :class:`FontKey` by extracting + information from the TrueType font file. + + *font* is an :class:`FT2Font` instance. """ name = font.family_name @@ -416,8 +452,10 @@ def afmFontProperty(font): """ - A function for populating the FontKey by extracting information - from the AFM font file. + A function for populating a :class:`FontKey` instance by + extracting information from the AFM font file. + + *font* is a class:`AFM` instance. """ name = font.get_familyname() @@ -475,8 +513,8 @@ def add_filename(fontdict, prop, fname): """ A function to add a font file name to the font dictionary using - the FontKey properties. If a font property has no dictionary, then - create it. + the :class:`FontKey` properties. If a font property has no + dictionary, then create it. """ try: size = str(float(prop.size)) @@ -494,9 +532,9 @@ def createFontDict(fontfiles, fontext='ttf'): """ - A function to create a dictionary of font file paths. The - default is to create a dictionary for TrueType fonts. An AFM font - dictionary can optionally be created. + A function to create a font lookup dictionary. The default is to + create a dictionary for TrueType fonts. An AFM font dictionary + can optionally be created. """ fontdict = {} @@ -589,42 +627,55 @@ """ A class for storing and manipulating font properties. - The font properties are those described in the W3C Cascading Style - Sheet, Level 1 (CSS1; http://www.w3.org/TR/1998/REC-CSS2-19980512/) - font specification. The six properties are: + The font properties are those described in the `W3C Cascading + Style Sheet, Level 1 + <http://www.w3.org/TR/1998/REC-CSS2-19980512/>`_ font + specification. The six properties are: - family - A list of font names in decreasing order of priority. - The last item is the default font name and is given the - name of the font family, either serif, sans-serif, - cursive, fantasy, and monospace. - style - Either normal, italic or oblique. - variant - Either normal or small-caps. - stretch - Either an absolute value of ultra-condensed, extra- - condensed, condensed, semi-condensed, normal, semi- - expanded, expanded, extra-expanded or ultra-expanded; - or a relative value of narrower or wider. - This property is currently not implemented and is set to - normal. - weight - A numeric value in the range 100, 200, 300, ..., 900. - size - Either an absolute value of xx-small, x-small, small, - medium, large, x-large, xx-large; or a relative value - of smaller or larger; or an absolute font size, e.g. 12; - or scalable. + - family: A list of font names in decreasing order of priority. + The last item is the default font name and is given the name + of the font family, either 'serif', 'sans-serif', 'cursive', + 'fantasy', or 'monospace'. - The default font property for TrueType fonts is: sans-serif, normal, - normal, normal, 400, scalable. + - style: Either 'normal', 'italic' or 'oblique'. - The preferred usage of font sizes is to use the relative values, e.g. - large, instead of absolute font sizes, e.g. 12. This approach allows - all text sizes to be made larger or smaller based on the font manager's - default font size, i.e. by using the set_default_size() method of the - font manager. + - variant: Either 'normal' or 'small-caps'. - This class will also accept a fontconfig pattern, if it is the only - argument provided. fontconfig patterns are described here: + - stretch: Either an absolute value of 'ultra-condensed', + 'extra- condensed', 'condensed', 'semi-condensed', 'normal', + 'semi-expanded', 'expanded', 'extra-expanded' or + 'ultra-expanded'; or a relative value of narrower or wider. + This property is currently not implemented and is set to + normal. - http://www.fontconfig.org/fontconfig-user.html + - weight: A numeric value in the range 100, 200, 300, ..., 900. + - size: Either an absolute value of 'xx-small', 'x-small', 'small', + 'medium', 'large', 'x-large', 'xx-large'; or a relative value + of smaller or larger; or an absolute font size, e.g. 12; + or 'scalable'. + + The default font property for TrueType fonts is:: + + sans-serif, normal, normal, normal, 400, scalable. + + Alternatively, a font may be specified using an absolute path to a + .ttf file, by using the *fname* kwarg. + + The preferred usage of font sizes is to use the relative values, + e.g. 'large', instead of absolute font sizes, e.g. 12. This + approach allows all text sizes to be made larger or smaller based + on the font manager's default font size, i.e. by using the + :meth:`FontManager.set_default_size` method. + + This class will also accept a `fontconfig + <http://www.fontconfig.org/>`_ pattern, if it is the only argument + provided. See the documentation on `fontconfig patterns + <http://www.fontconfig.org/fontconfig-user.html>`_. This support + does not require fontconfig to be installed or support for it to + be enabled. We are merely borrowing its pattern syntax for use + here. + Note that matplotlib's internal font manager and fontconfig use a different algorithm to lookup fonts, so the results of the same pattern may be different in matplotlib than in other applications that use @@ -684,8 +735,9 @@ return self.get_fontconfig_pattern() def get_family(self): - """Return a list of font names that comprise the font family. """ + Return a list of font names that comprise the font family. + """ if self._family is None: family = rcParams['font.family'] if is_string_like(family): @@ -694,25 +746,33 @@ return self._family def get_name(self): - """Return the name of the font that best matches the font properties.""" + """ + Return the name of the font that best matches the font + properties. + """ return ft2font.FT2Font(str(findfont(self))).family_name def get_style(self): - """Return the font style. Values are: normal, italic or oblique.""" + """ + Return the font style. Values are: 'normal', 'italic' or + 'oblique'. + """ if self._slant is None: return rcParams['font.style'] return self._slant def get_variant(self): - """Return the font variant. Values are: normal or small-caps.""" + """ + Return the font variant. Values are: 'normal' or + 'small-caps'. + """ if self._variant is None: return rcParams['font.variant'] return self._variant def get_weight(self): """ - Return the font weight. See the FontProperties class for a - a list of possible values. + Return the font weight. """ if self._weight is None: return rcParams['font.weight'] @@ -720,30 +780,46 @@ def get_stretch(self): """ - Return the font stretch or width. Options are: normal, - narrow, condensed, or wide. + Return the font stretch or width. Options are: 'normal', + 'narrow', 'condensed', or 'wide'. """ if self._stretch is None: return rcParams['font.stretch'] return self._stretch def get_size(self): - """Return the font size.""" + """ + Return the font size. + """ if self._size is None: return rcParams['font.size'] return float(self._size) def get_file(self): + """ + Return the filename of the associated font. + """ return self._file def get_fontconfig_pattern(self): + """ + Get a fontconfig pattern suitable for looking up the font as + specified with fontconfig's ``fc-match`` utility. + + See the documentation on `fontconfig patterns + <http://www.fontconfig.org/fontconfig-user.html>`_. + + This support does not require fontconfig to be installed or + support for it to be enabled. We are merely borrowing its + pattern syntax for use here. + """ return generate_fontconfig_pattern(self) def set_family(self, family): """ Change the font family. May be either an alias (generic name - is CSS parlance), such as: serif, sans-serif, cursive, - fantasy, or monospace, or a real font name. + is CSS parlance), such as: 'serif', 'sans-serif', 'cursive', + 'fantasy', or 'monospace', or a real font name. """ if family is None: self._family = None @@ -754,22 +830,26 @@ set_name = set_family def set_style(self, style): - """Set the font style. Values are: normal, italic or oblique.""" + """ + Set the font style. Values are: 'normal', 'italic' or + 'oblique'. + """ if style not in ('normal', 'italic', 'oblique', None): raise ValueError("style must be normal, italic or oblique") self._slant = style set_slant = set_style def set_variant(self, variant): - """Set the font variant. Values are: normal or small-caps.""" + """ + Set the font variant. Values are: 'normal' or 'small-caps'. + """ if variant not in ('normal', 'small-caps', None): raise ValueError("variant must be normal or small-caps") self._variant = variant def set_weight(self, weight): """ - Set the font weight. See the FontProperties class for a - a list of possible values. + Set the font weight. """ if (weight is not None and weight not in weight_dict and @@ -779,15 +859,20 @@ def set_stretch(self, stretch): """ - Set the font stretch or width. Options are: normal, narrow, - condensed, or wide. + Set the font stretch or width. Options are: 'normal', 'narrow', + 'condensed', or 'wide'. """ if stretch not in ('normal', 'narrow', 'condensed', 'wide', None): raise ValueError("stretch is invalid") self._stretch = stretch def set_size(self, size): - """Set the font size.""" + """ + Set the font size. Either an absolute value of 'xx-small', + 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'; + or a relative value of smaller or larger; or an absolute font + size, e.g. 12; or 'scalable'. + """ if size is None: self._size = None else: @@ -803,13 +888,26 @@ size = parent_size assert(type(size) in (int, float)) self._size = size + get_size_in_points = get_size def set_file(self, file): + """ + Set the filename of the fontfile to use. In this case, all + other properties will be ignored. + """ self._file = file - get_size_in_points = get_size + def set_fontconfig_pattern(self, pattern): + """ + Set the properties by parsing a fontconfig *pattern*. - def set_fontconfig_pattern(self, pattern): + See the documentation on `fontconfig patterns + <http://www.fontconfig.org/fontconfig-user.html>`_. + + This support does not require fontconfig to be installed or + support for it to be enabled. We are merely borrowing its + pattern syntax for use here. + """ for key, val in self._parse_fontconfig_pattern(pattern).items(): if type(val) == list: getattr(self, "set_" + key)(val[0]) @@ -821,7 +919,9 @@ return FontProperties(_init = self) def ttfdict_to_fnames(d): - 'flatten a ttfdict to all the filenames it contains' + """ + flatten a ttfdict to all the filenames it contains + """ fnames = [] for named in d.values(): for styled in named.values(): @@ -833,8 +933,10 @@ return fnames def pickle_dump(data, filename): - """Equivalent to pickle.dump(data, open(filename, 'w')) - but closes the file to prevent filehandle leakage.""" + """ + Equivalent to pickle.dump(data, open(filename, 'w')) + but closes the file to prevent filehandle leakage. + """ fh = open(filename, 'w') try: pickle.dump(data, fh) @@ -842,8 +944,10 @@ fh.close() def pickle_load(filename): - """Equivalent to pickle.load(open(filename, 'r')) - but closes the file to prevent filehandle leakage.""" + """ + Equivalent to pickle.load(open(filename, 'r')) + but closes the file to prevent filehandle leakage. + """ fh = open(filename, 'r') try: data = pickle.load(fh) @@ -853,15 +957,19 @@ class FontManager: """ - On import, the FontManager creates a dictionary of TrueType - fonts based on the font properties: name, style, variant, weight, - stretch, and size. The findfont() method searches this dictionary - for a font file name that exactly matches the font properties of the - specified text. If none is found, a default font is returned. By - updating the dictionary with the properties of the found font, the - font dictionary can act like a font cache. + On import, the :class:`FontManager` singleton instance creates a + dictionary of TrueType fonts based on the font properties: name, + style, variant, weight, stretch, and size. The :meth:`findfont` + method searches this dictionary for a font file name that exactly + matches the font properties of the specified text. If none is + found, a default font is returned. By updating the dictionary + with the properties of the found font, the font dictionary can act + like a font cache. + + .. note:: The font lookup mechanism is very exact and brittle. If + the *exact* font specified is not found, a default font is + always returned. This should be improved in the future. """ - def __init__(self, size=None, weight='normal'): self.__default_weight = weight self.default_size = size @@ -870,7 +978,6 @@ os.path.join(rcParams['datapath'],'fonts','afm')] # Create list of font paths - for pathname in ['TTFPATH', 'AFMPATH']: if pathname in os.environ: ttfpath = os.environ[pathname] @@ -913,21 +1020,30 @@ self.afmdict = createFontDict(self.afmfiles, fontext='afm') def get_default_weight(self): - "Return the default font weight." + """ + Return the default font weight. + """ return self.__default_weight def get_default_size(self): - "Return the default font size." + """ + Return the default font size. + """ if self.default_size is None: return rcParams['font.size'] return self.default_size def set_default_weight(self, weight): - "Set the default font weight. The initial value is 'normal'." + """ + Set the default font weight. The initial value is 'normal'. + """ self.__default_weight = weight def set_default_size(self, size): - "Set the default font size in points. The initial value is set by font.size in rc." + """ + Set the default font size in points. The initial value is set + by ``font.size`` in rc. + """ self.default_size = size def update_fonts(self, filenames): @@ -941,16 +1057,17 @@ def findfont(self, prop, fontext='ttf'): """ Search the font dictionary for a font that exactly or closely - matches the specified font properties. See the FontProperties class - for a description. + matches the specified font properties. See the + :class:`FontProperties` class for a description. - The properties are searched in the following order: name, style, - variant, weight, stretch, and size. The font weight always matches - returning the closest weight, and the font size always matches for - scalable fonts. An oblique style font will be used inplace of a - missing italic style font if present. See the W3C Cascading Style - Sheet, Level 1 (CSS1; http://www.w3.org/TR/1998/REC-CSS2-19980512/) - documentation for a description of the font finding algorithm. + The properties are searched in the following order: name, + style, variant, weight, stretch, and size. The font weight + always matches returning the closest weight, and the font size + always matches for scalable fonts. An oblique style font will + be used inplace of a missing italic style font if present. + See the `W3C Cascading Style Sheet, Level 1 + <http://www.w3.org/TR/1998/REC-CSS2-19980512/>`_ documentation + for a description of the font finding algorithm. """ debug = False if is_string_like(prop): @@ -1067,7 +1184,8 @@ def is_opentype_cff_font(filename): """ Returns True if the given font is a Postscript Compact Font Format - Font embedded in an OpenType wrapper. + Font embedded in an OpenType wrapper. Used by the PostScript and + PDF backends that can not subset these fonts. """ if os.path.splitext(filename)[1].lower() == '.otf': result = _is_opentype_cff_font_cache.get(filename) @@ -1080,7 +1198,7 @@ return result return False - +# The experimental fontconfig-based backend. if USE_FONTCONFIG and sys.platform != 'win32': import re Modified: trunk/matplotlib/lib/matplotlib/fontconfig_pattern.py =================================================================== --- trunk/matplotlib/lib/matplotlib/fontconfig_pattern.py 2008-10-27 18:04:58 UTC (rev 6337) +++ trunk/matplotlib/lib/matplotlib/fontconfig_pattern.py 2008-10-27 18:52:41 UTC (rev 6338) @@ -1,22 +1,24 @@ """ -A module for parsing a fontconfig pattern. +A module for parsing and generating fontconfig patterns. -This class is defined here because it must be available in: - - The old-style config framework (rcsetup.py) - - The traits-based config framework (mpltraits.py) - - The font manager (font_manager.py) +See the `fontconfig pattern specification +<http://www.fontconfig.org/fontconfig-user.html>`_ for more +information. +""" -It probably logically belongs in font_manager.py, but -placing it in any of these places would have created cyclical -dependency problems, or an undesired dependency on traits even -when the traits-based config framework is not used. +# Author : Michael Droettboom <md...@st...> +# License : matplotlib license (PSF compatible) -See here for a rough specification of these patterns: -http://www.fontconfig.org/fontconfig-user.html +# This class is defined here because it must be available in: +# - The old-style config framework (:file:`rcsetup.py`) +# - The traits-based config framework (:file:`mpltraits.py`) +# - The font manager (:file:`font_manager.py`) -Author : Michael Droettboom <md...@st...> -License : matplotlib license (PSF compatible) -""" +# It probably logically belongs in :file:`font_manager.py`, but +# placing it in any of these places would have created cyclical +# dependency problems, or an undesired dependency on traits even +# when the traits-based config framework is not used. + import re from matplotlib.pyparsing import Literal, ZeroOrMore, \ Optional, Regex, StringEnd, ParseException, Suppress @@ -32,11 +34,11 @@ class FontconfigPatternParser: """A simple pyparsing-based parser for fontconfig-style patterns. - See here for a rough specification of these patterns: - http://www.fontconfig.org/fontconfig-user.html + See the `fontconfig pattern specification + <http://www.fontconfig.org/fontconfig-user.html>`_ for more + information. """ - _constants = { 'thin' : ('weight', 'light'), 'extralight' : ('weight', 'light'), @@ -113,6 +115,11 @@ self.ParseException = ParseException def parse(self, pattern): + """ + Parse the given fontconfig *pattern* and return a dictionary + of key/value pairs useful for initializing a + :class:`font_manager.FontProperties` object. + """ props = self._properties = {} try: self._parser.parseString(pattern) @@ -156,8 +163,10 @@ parse_fontconfig_pattern = FontconfigPatternParser().parse def generate_fontconfig_pattern(d): - """Given a dictionary of key/value pairs, generates a fontconfig pattern - string.""" + """ + Given a dictionary of key/value pairs, generates a fontconfig + pattern string. + """ props = [] families = '' size = '' Modified: trunk/matplotlib/lib/matplotlib/lines.py =================================================================== --- trunk/matplotlib/lib/matplotlib/lines.py 2008-10-27 18:04:58 UTC (rev 6337) +++ trunk/matplotlib/lib/matplotlib/lines.py 2008-10-27 18:52:41 UTC (rev 6338) @@ -1,6 +1,6 @@ """ This module contains all the 2D line class which can draw with a -variety of line styles, markers and colors +variety of line styles, markers and colors. """ # TODO: expose cap and join style attrs @@ -32,10 +32,12 @@ return _unmasked_index_ranges(mask, compressed=compressed) -def segment_hits(cx,cy,x,y,radius): - """Determine if any line segments are within radius of a point. Returns - the list of line segments that are within that radius. +def segment_hits(cx, cy, x, y, radius): """ + Determine if any line segments are within radius of a + point. Returns the list of line segments that are within that + radius. + """ # Process single points specially if len(x) < 2: res, = np.nonzero( (cx - x)**2 + (cy - y)**2 <= radius**2 ) @@ -173,7 +175,8 @@ Create a :class:`~matplotlib.lines.Line2D` instance with *x* and *y* data in sequences *xdata*, *ydata*. - The kwargs are Line2D properties: + The kwargs are :class:`~matplotlib.lines.Line2D` properties: + %(Line2D)s """ Artist.__init__(self) @@ -239,8 +242,9 @@ Test whether the mouse event occurred on the line. The pick radius determines the precision of the location test (usually within five points of the value). Use - :meth:`~matplotlib.lines.Line2D.get_pickradius`/:meth:`~matplotlib.lines.Line2D.set_pickradius` - to view or modify it. + :meth:`~matplotlib.lines.Line2D.get_pickradius` or + :meth:`~matplotlib.lines.Line2D.set_pickradius` to view or + modify it. Returns *True* if any values are within the radius along with ``{'ind': pointlist}``, where *pointlist* is the set of points Modified: trunk/matplotlib/lib/matplotlib/mlab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mlab.py 2008-10-27 18:04:58 UTC (rev 6337) +++ trunk/matplotlib/lib/matplotlib/mlab.py 2008-10-27 18:52:41 UTC (rev 6338) @@ -265,9 +265,9 @@ vectors see numpy.blackman, numpy.hamming, numpy.bartlett, scipy.signal, scipy.signal.get_window etc. - If length x < NFFT, it will be zero padded to NFFT + If len(*x*) < *NFFT*, it will be zero padded to *NFFT*. - Returns the tuple (*Pxx*, *freqs*) + Returns the tuple (*Pxx*, *freqs*). Refs: Bendat & Piersol -- Random Data: Analysis and Measurement Procedures, John Wiley & Sons (1986) @@ -318,26 +318,26 @@ window=window_hanning, noverlap=0): """ The cross spectral density Pxy by Welches average periodogram - method. The vectors x and y are divided into NFFT length - segments. Each segment is detrended by function detrend and - windowed by function window. noverlap gives the length of the - overlap between segments. The product of the direct FFTs of x and - y are averaged over each segment to compute Pxy, with a scaling to - correct for power loss due to windowing. Fs is the sampling - frequency. + method. The vectors *x* and *y* are divided into *NFFT* length + segments. Each segment is detrended by function *detrend* and + windowed by function *window*. *noverlap* gives the length of the + overlap between segments. The product of the direct FFTs of *x* + and *y* are averaged over each segment to compute *Pxy*, with a + scaling to correct for power loss due to windowing. *Fs* is the + sampling frequency. - NFFT must be even; a power of 2 is most efficient + *NFFT* must be even; a power of 2 is most efficient - window can be a function or a vector of length NFFT. To create - window vectors see numpy.blackman, numpy.hamming, numpy.bartlett, - scipy.signal, scipy.signal.get_window etc. + *window* can be a function or a vector of length *NFFT*. To create + window vectors see :func:`numpy.blackman`, :func:`numpy.hamming`, + :func:`numpy.bartlett`, :func:`scipy.signal`, + :func:`scipy.signal.get_window` etc. - Returns the tuple Pxy, freqs + Returns the tuple (*Pxy*, *freqs*) Refs: Bendat & Piersol -- Random Data: Analysis and Measurement Procedures, John Wiley & Sons (1986) - """ if NFFT % 2: @@ -393,14 +393,15 @@ def specgram(x, NFFT=256, Fs=2, detrend=detrend_none, window=window_hanning, noverlap=128): """ - Compute a spectrogram of data in x. Data are split into NFFT + Compute a spectrogram of data in *x*. Data are split into *NFFT* length segements and the PSD of each section is computed. The - windowing function window is applied to each segment, and the - amount of overlap of each segment is specified with noverlap. + windowing function *window* is applied to each segment, and the + amount of overlap of each segment is specified with *noverlap*. - window can be a function or a vector of length NFFT. To create - window vectors see numpy.blackman, numpy.hamming, numpy.bartlett, - scipy.signal, scipy.signal.get_window etc. + *window* can be a function or a vector of length *NFFT*. To create + window vectors see :func:`numpy.blackman`, :func:`numpy.hamming`, + :func:`numpy.bartlett`, :func:`scipy.signal`, + :func:`scipy.signal.get_window` etc. If *x* is real (i.e. non-complex) only the positive spectrum is given. If *x* is complex then the complete spectrum is given. @@ -474,13 +475,13 @@ -_coh_error = """Coherence is calculated by averaging over NFFT -length segments. Your signal is too short for your choice of NFFT. +_coh_error = """Coherence is calculated by averaging over *NFFT* +length segments. Your signal is too short for your choice of *NFFT*. """ def cohere(x, y, NFFT=256, Fs=2, detrend=detrend_none, window=window_hanning, noverlap=0): """ - The coherence between x and y. Coherence is the normalized + The coherence between *x* and *y*. Coherence is the normalized cross spectral density: .. math:: @@ -510,17 +511,20 @@ def corrcoef(*args): """ - corrcoef(X) where X is a matrix returns a matrix of correlation - coefficients for the columns of X. + corrcoef(*X*) where *X* is a matrix returns a matrix of correlation + coefficients for the columns of *X* - corrcoef(x,y) where x and y are vectors returns the matrix of - correlation coefficients for x and y. + corrcoef(*x*, *y*) where *x* and *y* are vectors returns the matrix of + correlation coefficients for *x* and *y*. - Numpy arrays can be real or complex + Numpy arrays can be real or complex. - The correlation matrix is defined from the covariance matrix C as + The correlation matrix is defined from the covariance matrix *C* + as - r(i,j) = C[i,j] / sqrt(C[i,i]*C[j,j]) + .. math:: + + r_{ij} = \\frac{C_{ij}}{\\sqrt{C_{ii}C_{jj}}} """ warnings.warn("Use numpy.corrcoef", DeprecationWarning) kw = dict(rowvar=False) @@ -528,11 +532,12 @@ def polyfit(*args, **kwargs): - """ - def polyfit(x,y,N) + u""" + polyfit(*x*, *y*, *N*) - Do a best fit polynomial of order N of y to x. Return value is a - vector of polynomial coefficients [pk ... p1 p0]. Eg, for N=2 + Do a best fit polynomial of order *N* of *y* to *x*. Return value + is a vector of polynomial coefficients [pk ... p1 p0]. Eg, for + *N*=2:: p2*x0^2 + p1*x0 + p0 = y1 p2*x1^2 + p1*x1 + p0 = y1 @@ -541,28 +546,32 @@ p2*xk^2 + p1*xk + p0 = yk - Method: if X is a the Vandermonde Matrix computed from x (see - `vandermonds <http://mathworld.wolfram.com/VandermondeMatrix.html>`_), then the - polynomial least squares solution is given by the 'p' in + Method: if *X* is a the Vandermonde Matrix computed from *x* (see + `vandermonds + <http://mathworld.wolfram.com/VandermondeMatrix.html>`_), then the + polynomial least squares solution is given by the '*p*' in X*p = y - where X is a len(x) x N+1 matrix, p is a N+1 length vector, and y - is a len(x) x 1 vector + where *X* is a (len(*x*) \N{MULTIPLICATION SIGN} *N* + 1) matrix, + *p* is a *N*+1 length vector, and *y* is a (len(*x*) + \N{MULTIPLICATION SIGN} 1) vector. This equation can be solved as - p = (XT*X)^-1 * XT * y + .. math:: - where XT is the transpose of X and -1 denotes the inverse. - Numerically, however, this is not a good method, so we use - numpy.linalg.lstsq. + p = (X_t X)^-1 X_t y - For more info, see - `least squares fitting <http://mathworld.wolfram.com/LeastSquaresFittingPolynomial.html>`_, - but note that the k's and n's in the superscripts and subscripts - on that page. The linear algebra is correct, however. + where :math:`X_t` is the transpose of *X* and -1 denotes the + inverse. Numerically, however, this is not a good method, so we + use :func:`numpy.linalg.lstsq`. + For more info, see `least squares fitting + <http://mathworld.wolfram.com/LeastSquaresFittingPolynomial.html>`_, + but note that the *k*'s and *n*'s in the superscripts and + subscripts on that page. The linear algebra is correct, however. + .. seealso:: :func:`polyval` """ @@ -574,12 +583,12 @@ def polyval(*args, **kwargs): """ - y = polyval(p,x) + *y* = polyval(*p*, *x*) - p is a vector of polynomial coeffients and y is the polynomial - evaluated at x. + *p* is a vector of polynomial coeffients and *y* is the polynomial + evaluated at *x*. - Example code to remove a polynomial (quadratic) trend from y: + Example code to remove a polynomial (quadratic) trend from y:: p = polyfit(x, y, 2) trend = polyval(p, x) @@ -593,12 +602,11 @@ def vander(*args, **kwargs): """ - X = vander(x,N=None) + *X* = vander(*x*, *N* = *None*) - The Vandermonde matrix of vector x. The i-th column of X is the - the i-th power of x. N is the maximum power to compute; if N is - None it defaults to len(x). - + The Vandermonde matrix of vector *x*. The *i*-th column of *X* is the + the *i*-th power of *x*. *N* is the maximum power to compute; if *N* is + *None* it defaults to len(*x*). """ warnings.warn("Use numpy.vander()", DeprecationWarning) return np.vander(*args, **kwargs) @@ -613,61 +621,63 @@ progressCallback=donothing_callback, returnPxx=False): - """ - Cxy, Phase, freqs = cohere_pairs( X, ij, ...) + u""" + Cxy, Phase, freqs = cohere_pairs(X, ij, ...) - Compute the coherence for all pairs in ij. X is a - numSamples,numCols numpy array. ij is a list of tuples (i,j). - Each tuple is a pair of indexes into the columns of X for which - you want to compute coherence. For example, if X has 64 columns, - and you want to compute all nonredundant pairs, define ij as + Compute the coherence for all pairs in *ij*. *X* is a + (*numSamples*, *numCols*) numpy array. *ij* is a list of tuples + (*i*, *j*). Each tuple is a pair of indexes into the columns of *X* + for which you want to compute coherence. For example, if *X* has 64 + columns, and you want to compute all nonredundant pairs, define *ij* + as:: ij = [] for i in range(64): for j in range(i+1,64): - ij.append( (i,j) ) + ij.append( (i, j) ) - The other function arguments, except for 'preferSpeedOverMemory' - (see below), are explained in the help string of 'psd'. + The other function arguments, except for *preferSpeedOverMemory* + (see below), are explained in the help string of :func:`psd`. - Return value is a tuple (Cxy, Phase, freqs). + Return value is a tuple (*Cxy*, *Phase*, *freqs*). - Cxy -- a dictionary of (i,j) tuples -> coherence vector for that - pair. Ie, Cxy[(i,j) = cohere(X[:,i], X[:,j]). Number of - dictionary keys is len(ij) + - *Cxy*: a dictionary of (*i*, *j*) tuples -> coherence vector for that + pair. I.e., ``Cxy[(i,j)] = cohere(X[:,i], X[:,j])``. Number of + dictionary keys is ``len(ij)``. - Phase -- a dictionary of phases of the cross spectral density at - each frequency for each pair. keys are (i,j). + - *Phase*: a dictionary of phases of the cross spectral density at + each frequency for each pair. The keys are ``(i,j)``. - freqs -- a vector of frequencies, equal in length to either the - coherence or phase vectors for any i,j key. Eg, to make a coherence - Bode plot: + - *freqs*: a vector of frequencies, equal in length to either + the coherence or phase vectors for any (*i*, *j*) key.. Eg, + to make a coherence Bode plot:: subplot(211) plot( freqs, Cxy[(12,19)]) subplot(212) plot( freqs, Phase[(12,19)]) - For a large number of pairs, cohere_pairs can be much more - efficient than just calling cohere for each pair, because it - caches most of the intensive computations. If N is the number of - pairs, this function is O(N) for most of the heavy lifting, - whereas calling cohere for each pair is O(N^2). However, because - of the caching, it is also more memory intensive, making 2 - additional complex arrays with approximately the same number of - elements as X. + For a large number of pairs, :func:`cohere_pairs` can be much more + efficient than just calling :func:`cohere` for each pair, because + it caches most of the intensive computations. If *N* is the + number of pairs, this function is O(N) for most of the heavy + lifting, whereas calling cohere for each pair is + O(N\N{SUPERSCRIPT TWO}). However, because of the caching, it is + also more memory intensive, making 2 additional complex arrays + with approximately the same number of elements as *X*. - The parameter 'preferSpeedOverMemory', if false, limits the + The parameter *preferSpeedOverMemory*, if *False*, limits the caching by only making one, rather than two, complex cache arrays. This is useful if memory becomes critical. Even when - preferSpeedOverMemory is false, cohere_pairs will still give - significant performace gains over calling cohere for each pair, - and will use subtantially less memory than if - preferSpeedOverMemory is true. In my tests with a 43000,64 array - over all nonredundant pairs, preferSpeedOverMemory=1 delivered a - 33% performace boost on a 1.7GHZ Athlon with 512MB RAM compared - with preferSpeedOverMemory=0. But both solutions were more than - 10x faster than naievly crunching all possible pairs through + *preferSpeedOverMemory* is *False*, :func:`cohere_pairs` will + still give significant performace gains over calling + :func:`cohere` for each pair, and will use subtantially less + memory than if *preferSpeedOverMemory* is *True*. In my tests + with a (43000, 64) array over all non-redundant pairs, + *preferSpeedOverMemory* = *True* delivered a 33% performace boost + on a 1.7GHZ Athlon with 512MB RAM compared with + *preferSpeedOverMemory* = *False*. But both solutions were more + than 10x faster than naievly crunching all possible pairs through cohere. .. seealso:: @@ -757,17 +767,21 @@ def entropy(y, bins): - """ - Return the entropy of the data in y + r""" + Return the entropy of the data in *y*. - \sum p_i log2(p_i) where p_i is the probability of observing y in - the ith bin of bins. bins can be a number of bins or a range of - bins; see numpy.histogram + .. math:: - Compare S with analytic calculation for a Gaussian - x = mu + sigma*randn(200000) - Sanalytic = 0.5 * ( 1.0 + log(2*pi*sigma**2.0) ) + \sum p_i \log_2(p_i) + where :math:`p_i` is the probability of observing *y* in the + :math:`i^{th}` bin of *bins*. *bins* can be a number of bins or a + range of bins; see :func:`numpy.histogram`. + + Compare *S* with analytic calculation for a Gaussian:: + + x = mu + sigma * randn(200000) + Sanalytic = 0.5 * ( 1.0 + log(2*pi*sigma**2.0) ) """ n,bins = np.histogram(y, bins) n = n.astype(np.float_) @@ -783,29 +797,30 @@ def hist(y, bins=10, normed=0): """ - Return the histogram of y with bins equally sized bins. If bins - is an array, use the bins. Return value is - (n,x) where n is the count for each bin in x + Return the histogram of *y* with *bins* equally sized bins. If + bins is an array, use those bins. Return value is (*n*, *x*) + where *n* is the count for each bin in *x*. - If normed is False, return the counts in the first element of the - return tuple. If normed is True, return the probability density - n/(len(y)*dbin) + If *normed* is *False*, return the counts in the first element of + the returned tuple. If *normed* is *True*, return the probability + density :math:`\\frac{n}{(len(y)\mathrm{dbin}}`. - If y has rank>1, it will be raveled. If y is masked, only - the unmasked values will be used. + If *y* has rank > 1, it will be raveled. If *y* is masked, only the + unmasked values will be used. + Credits: the Numeric 22 documentation """ warnings.warn("Use numpy.histogram()", DeprecationWarning) return np.histogram(y, bins=bins, range=None, normed=normed) def normpdf(x, *args): - "Return the normal pdf evaluated at x; args provides mu, sigma" + "Return the normal pdf evaluated at *x*; args provides *mu*, *sigma*" mu, sigma = args return 1./(np.sqrt(2*np.pi)*sigma)*np.exp(-0.5 * (1./sigma*(x - mu))**2) def levypdf(x, gamma, alpha): - "Returm the levy pdf evaluated at x for params gamma, alpha" + "Returm the levy pdf evaluated at *x* for params *gamma*, *alpha*" N = len(x) @@ -835,7 +850,7 @@ def trapz(x, y): """ - Trapezoidal integral of y(x). + Trapezoidal integral of *y*(*x*). """ warnings.warn("Use numpy.trapz(y,x) instead of trapz(x,y)", DeprecationWarning) return np.trapz(y, x) @@ -849,10 +864,9 @@ def longest_contiguous_ones(x): """ - return the indices of the longest stretch of contiguous ones in x, - assuming x is a vector of zeros and ones. - If there are two equally long stretches, pick the first - + Return the indices of the longest stretch of contiguous ones in *x*, + assuming *x* is a vector of zeros and ones. If there are two + equally long stretches, pick the first. """ x = np.ravel(x) if len(x)==0: @@ -880,16 +894,21 @@ def prepca(P, frac=0): """ - Compute the principal components of P. P is a numVars x - numObs array. frac is the minimum fraction of - variance that a component must contain to be included. + Compute the principal components of *P*. *P* is a (*numVars*, + *numObs*) array. *frac* is the minimum fraction of variance that a + component must contain to be included. - Return value are - Pcomponents : a numVars x numObs array - Trans : the weights matrix, ie, Pcomponents = Trans*P - fracVar : the fraction of the variance accounted for by each - component returned + Return value is a tuple of the form (*Pcomponents*, *Trans*, + *fracVar*) where: + - *Pcomponents* : a (numVars, numObs) array + + - *Trans* : the weights matrix, ie, *Pcomponents* = *Trans* * + *P* + + - *fracVar* : the fraction of the variance accounted for by each + component returned + A similar function of the same name was in the Matlab (TM) R13 Neural Network Toolbox but is not found in later versions; its successor seems to be called "processpcs". @@ -907,11 +926,11 @@ def prctile(x, p = (0.0, 25.0, 50.0, 75.0, 100.0)): """ - Return the percentiles of x. p can either be a sequence of - percentile values or a scalar. If p is a sequence the i-th element - of the return sequence is the p(i)-th percentile of x. - If p is a scalar, the largest value of x less than or equal - to the p percentage point in the sequence is returned. + Return the percentiles of *x*. *p* can either be a sequence of + percentile values or a scalar. If *p* is a sequence, the ith + element of the return sequence is the *p*(i)-th percentile of *x*. + If *p* is a scalar, the largest value of *x* less than or equal to + the *p* percentage point in the sequence is returned. """ @@ -929,15 +948,15 @@ def prctile_rank(x, p): """ - return the for each element in x, return the rank 0..len(p) . Eg - if p=(25, 50, 75), the return value will be a len(x) array with - values in [0,1,2,3] where 0 indicates the value is less than the - 25th percentile, 1 indicates the value is >= the 25th and < 50th - percentile, ... and 3 indicates the value is above the 75th - percentile cutoff + Return the rank for each element in *x*, return the rank + 0..len(*p*). Eg if *p* = (25, 50, 75), the return value will be a + len(*x*) array with values in [0,1,2,3] where 0 indicates the + value is less than the 25th percentile, 1 indicates the value is + >= the 25th and < 50th percentile, ... and 3 indicates the value + is above the 75th percentile cutoff. - p is either an array of percentiles in [0..100] or a scalar which - indicates how many quantiles of data you want ranked + *p* is either an array of percentiles in [0..100] or a scalar which + indicates how many quantiles of data you want ranked. """ if not cbook.iterable(p): @@ -953,10 +972,10 @@ def center_matrix(M, dim=0): """ - Return the matrix M with each row having zero mean and unit std + Return the matrix *M* with each row having zero mean and unit std. - if dim=1 operate on columns instead of rows. (dim is opposite - to the numpy axis kwarg.) + If *dim* = 1 operate on columns instead of rows. (*dim* is + opposite to the numpy axis kwarg.) """ M = np.asarray(M, np.float_) if dim: @@ -970,7 +989,10 @@ def rk4(derivs, y0, t): """ - Integrate 1D or ND system of ODEs using 4-th order Runge-Kutta. This is a toy implementation which may be useful if you find yourself stranded on a system w/o scipy. Otherwise use ``scipy.integrate`` + Integrate 1D or ND system of ODEs using 4-th order Runge-Kutta. + This is a toy implementation which may be useful if you find + yourself stranded on a system w/o scipy. Otherwise use + :func:`scipy.integrate`. *y0* initial state vector @@ -1009,7 +1031,6 @@ If you have access to scipy, you should probably be using the scipy.integrate tools rather than this function. - """ try: Ny = len(y0) @@ -1040,9 +1061,11 @@ def bivariate_normal(X, Y, sigmax=1.0, sigmay=1.0, mux=0.0, muy=0.0, sigmaxy=0.0): """ - Bivariate gaussan distribution for equal shape X, Y + Bivariate Gaussian distribution for equal shape *X*, *Y*. - See `bivariate normal <http://mathworld.wolfram.com/BivariateNormalDistribution.html>`_ at mathworld. + See `bivariate normal + <http://mathworld.wolfram.com/BivariateNormalDistribution.html>`_ + at mathworld. """ Xmu = X-mux Ymu = Y-muy @@ -1052,21 +1075,22 @@ denom = 2*np.pi*sigmax*sigmay*np.sqrt(1-rho**2) return np.exp( -z/(2*(1-rho**2))) / denom - - - def get_xyz_where(Z, Cond): """ - Z and Cond are MxN matrices. Z are data and Cond is a boolean - matrix where some condition is satisfied. Return value is x,y,z - where x and y are the indices into Z and z are the values of Z at - those indices. x,y,z are 1D arrays + *Z* and *Cond* are *M* x *N* matrices. *Z* are data and *Cond* is + a boolean matrix where some condition is satisfied. Return value + is (*x*, *y*, *z*) where *x* and *y* are the indices into *Z* and + *z* are the values of *Z* at those indices. *x*, *y*, and *z* are + 1D arrays. """ X,Y = np.indices(Z.shape) return X[Cond], Y[Cond], Z[Cond] def get_sparse_matrix(M,N,frac=0.1): - 'return a MxN sparse matrix with frac elements randomly filled' + """ + Return a *M* x *N* sparse matrix with *frac* elements randomly + filled. + """ data = np.zeros((M,N))*0. for i in range(int(M*N*frac)): x = np.random.randint(0,M-1) @@ -1075,15 +1099,17 @@ return data def dist(x,y): - 'return the distance between two points' + """ + Return the distance between two points. + """ d = x-y return np.sqrt(np.dot(d,d)) def dist_point_to_segment(p, s0, s1): """ - get the distance of a point to a segment. + Get the distance of a point to a segment. - p, s0, s1 are xy sequences + *p*, *s0*, *s1* are *xy* sequences This algorithm from http://softsurfer.com/Archive/algorithm_0102/algorithm_0102.htm#Distance%20to%20Ray%20or%20Segment @@ -1108,12 +1134,11 @@ def segments_intersect(s1, s2): """ - Return True if s1 and s2 intersect. - s1 and s2 are defined as + Return *True* if *s1* and *s2* intersect. + *s1* and *s2* are defined as:: - s1: (x1, y1), (x2, y2) - s2: (x3, y3), (x4, y4) - + s1: (x1, y1), (x2, y2) + s2: (x3, y3), (x4, y4) """ (x1, y1), (x2, y2) = s1 (x3, y3), (x4, y4) = s2 @@ -1135,7 +1160,7 @@ def fftsurr(x, detrend=detrend_none, window=window_none): """ - Compute an FFT phase randomized surrogate of x + Compute an FFT phase randomized surrogate of *x*. """ if cbook.iterable(window): x=window*detrend(x) @@ -1168,30 +1193,36 @@ What the function here calculates may not be what you really want; *caveat emptor*. - It also seems that this function's name is badly misspelled. + It also seems that this function's name is badly misspelled. """ return np.mean(np.log(np.absolute(fprime(x)))) class FIFOBuffer: """ - A FIFO queue to hold incoming x, y data in a rotating buffer using - numpy arrays under the hood. It is assumed that you will call - asarrays much less frequently than you add data to the queue -- - otherwise another data structure will be faster + A FIFO queue to hold incoming *x*, *y* data in a rotating buffer + using numpy arrays under the hood. It is assumed that you will + call asarrays much less frequently than you add data to the queue + -- otherwise another data structure will be faster. This can be used to support plots where data is added from a real - time feed and the plot object wants grab data from the buffer and - plot it to screen less freqeuently than the incoming + time feed and the plot object wants to grab data from the buffer + and plot it to screen less freqeuently than the incoming. - If you set the dataLim attr to a matplotlib BBox (eg ax.dataLim), - the dataLim will be updated as new data come in + If you set the *dataLim* attr to + :class:`~matplotlib.transforms.BBox` (eg + :attr:`matplotlib.Axes.dataLim`), the *dataLim* will be updated as + new data come in. - TODI: add a grow method that will extend nmax + TODO: add a grow method that will extend nmax - mlab seems like the wrong place for this class. + .. note:: + + mlab seems like the wrong place for this class. """ def __init__(self, nmax): - 'buffer up to nmax points' + """ + Buffer up to *nmax* points. + """ self._xa = np.zeros((nmax,), np.float_) self._ya = np.zeros((nmax,), np.float_) self._xs = np.zeros((nmax,), np.float_) @@ -1202,11 +1233,16 @@ self.callbackd = {} def register(self, func, N): - 'call func everytime N events are passed; func signature is func(fifo)' + """ + Call *func* every time *N* events are passed; *func* signature + is ``func(fifo)``. + """ self.callbackd.setdefault(N, []).append(func) def add(self, x, y): - 'add scalar x and y to the queue' + """ + Add scalar *x* and *y* to the queue. + """ if self.dataLim is not None: xys = ((x,y),) self.dataLim.update(xys, -1) #-1 means use the default ignore setting @@ -1223,15 +1259,17 @@ self._ind += 1 def last(self): - 'get the last x, y or None, None if no data set' + """ + Get the last *x*, *y* or *None*. *None* if no data set. + """ if self._ind==0: return None, None ind = (self._ind-1) % self._nmax return self._xs[ind], self._ys[ind] def asarrays(self): """ - return x and y as arrays; their length will be the len of data - added or nmax + Return *x* and *y* as arrays; their length will be the len of + data added or *nmax*. """ if self._ind<self._nmax: return self._xs[:self._ind], self._ys[:self._ind] @@ -1245,36 +1283,41 @@ return self._xa, self._ya def update_datalim_to_current(self): - 'update the datalim in the current data in the fifo' + """ + Update the *datalim* in the current data in the fifo. + """ if self.dataLim is None: raise ValueError('You must first set the dataLim attr') x, y = self.asarrays() self.dataLim.update_numerix(x, y, True) def movavg(x,n): - 'compute the... [truncated message content] |