diff -Nru matplotlib-1.1.1/CHANGELOG matplotlib-1.2.0/CHANGELOG --- matplotlib-1.1.1/CHANGELOG 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/CHANGELOG 2012-11-08 13:38:03.000000000 +0000 @@ -1,16 +1,99 @@ +2012-08-11 Fix path-closing bug in patches.Polygon, so that regardless + of whether the path is the initial one or was subsequently + set by set_xy(), get_xy() will return a closed path if and + only if get_closed() is True. Thanks to Jacob Vanderplas. - EF + +2012-08-05 When a norm is passed to contourf, either or both of the + vmin, vmax attributes of that norm are now respected. + Formerly they were respected only if both were + specified. In addition, vmin and/or vmax can now + be passed to contourf directly as kwargs. - EF + +2012-07-24 Contourf handles the extend kwarg by mapping the extended + ranges outside the normed 0-1 range so that they are + handled by colormap colors determined by the set_under + and set_over methods. Previously the extended ranges + were mapped to 0 or 1 so that the "under" and "over" + colormap colors were ignored. This change also increases + slightly the color contrast for a given set of contour + levels. - EF + +2012-06-24 Make use of mathtext in tick labels configurable - DSD + +2012-06-05 Images loaded through PIL are now ordered correctly - CG + +2012-06-02 Add new Axes method and pyplot function, hist2d. - PO + +2012-05-31 Remove support for 'cairo.' style of backend specification. + Deprecate 'cairo.format' and 'savefig.extension' rcParams and + replace with 'savefig.format'. - Martin Spacek + +2012-05-29 pcolormesh now obeys the passed in "edgecolor" kwarg. + To support this, the "shading" argument to pcolormesh now only + takes "flat" or "gouraud". To achieve the old "faceted" behavior, + pass "edgecolors='k'". - MGD + +2012-05-22 Added radius kwarg to pie charts. - HH + +2012-05-22 Collections now have a setting "offset_position" to select whether + the offsets are given in "screen" coordinates (default, + following the old behavior) or "data" coordinates. This is currently + used internally to improve the performance of hexbin. + + As a result, the "draw_path_collection" backend methods have grown + a new argument "offset_position". - MGD + +2012-05-04 Add a new argument to pie charts - startingangle - that + allows one to specify the angle offset for the first wedge + of the chart. - EP + +2012-05-03 symlog scale now obeys the logarithmic base. Previously, it was + completely ignored and always treated as base e. - MGD + +2012-05-03 Allow linscalex/y keyword to symlog scale that allows the size of + the linear portion relative to the logarithmic portion to be + adjusted. - MGD + +2012-04-14 Added new plot style: stackplot. This new feature supports stacked + area plots. - Damon McDougall + 2012-04-06 When path clipping changes a LINETO to a MOVETO, it also changes any CLOSEPOLY command to a LINETO to the initial point. This fixes a problem with pdf and svg where the CLOSEPOLY would then draw a line to the latest MOVETO position instead of the intended initial position. - JKS +2012-03-27 Add support to ImageGrid for placing colorbars only at + one edge of each column/row. - RMM + +2012-03-07 Refactor movie writing into useful classes that make use + of pipes to write image data to ffmpeg or mencoder. Also + improve settings for these and the ability to pass custom + options. - RMM + +2012-02-29 errorevery keyword added to errorbar to enable errorbar + subsampling. fixes issue #600. + +2012-02-28 Added plot_trisurf to the mplot3d toolkit. This supports plotting + three dimensional surfaces on an irregular grid. - Damon McDougall + 2012-01-23 The radius labels in polar plots no longer use a fixed padding, but use a different alignment depending on the quadrant they are in. This fixes numerical problems when (rmax - rmin) gets too small. - MGD +2012-01-08 Add axes.streamplot to plot streamlines of a velocity field. + Adapted from Tom Flannaghan streamplot implementation. -TSY + +2011-12-29 ps and pdf markers are now stroked only if the line width + is nonzero for consistency with agg, fixes issue #621. - JKS + 2011-12-27 Work around an EINTR bug in some versions of subprocess. - JKS +2011-10-25 added support for \operatorname to mathtext, + including the ability to insert spaces, such as + $\operatorname{arg\,max}$ - PI + 2011-08-18 Change api of Axes.get_tightbbox and add an optional keyword parameter *call_axes_locator*. - JJL diff -Nru matplotlib-1.1.1/CXX/Python3/Objects.hxx matplotlib-1.2.0/CXX/Python3/Objects.hxx --- matplotlib-1.1.1/CXX/Python3/Objects.hxx 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/CXX/Python3/Objects.hxx 2012-10-31 00:11:13.000000000 +0000 @@ -413,7 +413,7 @@ { } - bool accepts( PyObject *pyob ) + virtual bool accepts( PyObject *pyob ) const { return pyob == NULL; } @@ -1520,7 +1520,7 @@ int operator-( const iterator &other ) const { - if( seq.ptr() != other.seq.ptr() ) + if( seq->ptr() != other.seq->ptr() ) throw RuntimeError( "SeqBase::iterator comparison error" ); return count - other.count; diff -Nru matplotlib-1.1.1/CXX/Python3/cxx_extensions.cxx matplotlib-1.2.0/CXX/Python3/cxx_extensions.cxx --- matplotlib-1.1.1/CXX/Python3/cxx_extensions.cxx 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/CXX/Python3/cxx_extensions.cxx 2012-10-31 00:11:13.000000000 +0000 @@ -440,10 +440,10 @@ table->tp_version_tag = 0; #ifdef COUNT_ALLOCS - table->tp_alloc = 0; - table->tp_free = 0; + table->tp_allocs = 0; + table->tp_frees = 0; table->tp_maxalloc = 0; - table->tp_orev = 0; + table->tp_prev = 0; table->tp_next = 0; #endif } diff -Nru matplotlib-1.1.1/INSTALL matplotlib-1.2.0/INSTALL --- matplotlib-1.1.1/INSTALL 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/INSTALL 2012-11-06 22:31:09.000000000 +0000 @@ -6,21 +6,21 @@ Installing ********** -There are many different ways to install matplotlib, and the best -way depends on what operating system you are using, what you already -have installed, and how you want to use it. To avoid wading through -all the details (and potential complications) on this page, the -easiest thing for you to do is use one of the pre-packaged python +There are many different ways to install matplotlib, and the best way +depends on what operating system you are using, what you already have +installed, and how you want to use it. To avoid wading through all +the details (and potential complications) on this page, the easiest +thing for you to do is use one of the pre-packaged python distributions that already provide matplotlib built-in. The Enthought Python Distribution `(EPD) `_ for Windows, OS X or Redhat is an excellent choice that "just works" out of the box. Another excellent alternative for Windows users is `Python (x, y) -`_ which tends to be updated a -bit more frequently. Both of these packages include matplotlib and -pylab, and *lots* of other useful tools. matplotlib is also packaged -for almost every major Linux distribution. So if you are on Linux, -your package manager will probably provide matplotlib prebuilt. +`_ which tends to be updated a bit more +frequently. Both of these packages include matplotlib and pylab, and +*lots* of other useful tools. matplotlib is also packaged for almost +every major Linux distribution. So if you are on Linux, your package +manager will probably provide matplotlib prebuilt. Manually installing pre-built packages @@ -37,10 +37,9 @@ but OS X users please read :ref:`which-python-for-osx`. Once you have python up and running, you will need to install `numpy -`_. -numpy provides high-performance array data structures and mathematical -functions, and is a requirement for matplotlib. You can test your -progress:: +`_. numpy provides high-performance array data +structures and mathematical functions, and is a requirement for +matplotlib. You can test your progress:: >>> import numpy >>> print numpy.__version__ @@ -52,14 +51,14 @@ Next, we need to get matplotlib installed. We provide prebuilt binaries for OS X and Windows on the matplotlib `download -`_ page. Click on +`_ page. Click on the latest release of the "matplotlib" package, choose your python -version (e.g., 2.5, 2.6 or 2.7) and your platform (macosx or win32). -If you have any problems, please check the :ref:`installing-faq`, -search using Google, and/or post a question to the `mailing list +version (2.6, 2.7 or 3.2) and your platform (macosx or win32). If you +have any problems, please check the :ref:`installing-faq`, search +using Google, and/or post a question the `mailing list `_. -If you are on Debian/Ubuntu Linux, it suffices to do:: +If you are on Debian/Ubuntu linux, it suffices to do:: > sudo apt-get install python-matplotlib @@ -119,13 +118,13 @@ Installing from source ====================== -If you are interested in contributing to matplotlib -development, running the latest source code, or just like to -build everything yourself, it is not difficult to build matplotlib -from source. Grab the latest *tar.gz* release file from `sourceforge -`_, or if -you want to develop matplotlib or just need the latest bugfixed -version, grab the latest git version :ref:`install-from-git`. +If you are interested in contributing to matplotlib development, +running the latest source code, or just like to build everything +yourself, it is not difficult to build matplotlib from source. Grab +the latest *tar.gz* release file from `the download page +`_, or if you want +to develop matplotlib or just need the latest bugfixed version, grab +the latest git version :ref:`install-from-git`. Once you have satisfied the requirements detailed below (mainly python, numpy, libpng and freetype), you can build matplotlib:: @@ -157,11 +156,12 @@ These are external packages which you will need to install before installing matplotlib. Windows users only need the first two (python and numpy) since the others are built into the matplotlib Windows -installers available for download at the sourceforge site. If you are +installers available for download at `the download page +_`. If you are building on OSX, see :ref:`build_osx`. If you are installing -dependencies with a package manager on Linux, you may need to install the -development packages (look for a "-dev" postfix) in addition to the -libraries themselves. +dependencies with a package manager on Linux, you may need to install +the development packages (look for a "-dev" postfix) in addition to +the libraries themselves. .. note:: @@ -179,12 +179,11 @@ This does not build matplotlib, but it does get the install the build dependencies, which will make building from source easier. -:term:`python` 2.4 (or later but not python3) - matplotlib requires python 2.4 or later (`download `__) +:term:`python` 2.6, 2.7, 3.1 or 3.2 + `Download python `_. :term:`numpy` |minimum_numpy_version| (or later) - array support for python (`download - `__) + array support for python (`download `_) libpng 1.2 (or later) library for loading and saving :term:`PNG` files (`download @@ -254,4 +253,3 @@ the different OSX version (e.g., 10.4 and 10.5). We recommend that you build the way we do for the OSX release: get the source from the tarball or the git repository and follow the instruction in :file:`README.osx`. - diff -Nru matplotlib-1.1.1/MANIFEST.in matplotlib-1.2.0/MANIFEST.in --- matplotlib-1.1.1/MANIFEST.in 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/MANIFEST.in 2012-11-06 22:31:09.000000000 +0000 @@ -13,6 +13,7 @@ include lib/matplotlib/mpl-data/fonts/ttf/* include lib/matplotlib/mpl-data/fonts/pdfcorefonts/* include lib/matplotlib/mpl-data/fonts/afm/* +recursive-include lib/matplotlib/mpl-data/sample_data/* recursive-include license LICENSE* recursive-include examples * recursive-include doc * diff -Nru matplotlib-1.1.1/PKG-INFO matplotlib-1.2.0/PKG-INFO --- matplotlib-1.1.1/PKG-INFO 2012-06-30 19:37:14.000000000 +0000 +++ matplotlib-1.2.0/PKG-INFO 2012-11-08 16:39:22.000000000 +0000 @@ -1,10 +1,10 @@ -Metadata-Version: 1.0 +Metadata-Version: 1.1 Name: matplotlib -Version: 1.1.1 +Version: 1.2.0 Summary: Python plotting package -Home-page: http://matplotlib.sourceforge.net -Author: John D. Hunter -Author-email: jdh2358@gmail.com +Home-page: http://matplotlib.org +Author: John D. Hunter, Michael Droettboom +Author-email: mdroe@stsci.edu License: UNKNOWN Description: matplotlib strives to produce publication quality 2D graphics @@ -14,3 +14,10 @@ which emulates matlab graphics Platform: any +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Science/Research +Classifier: License :: OSI Approved :: Python Software Foundation License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 3 +Classifier: Topic :: Scientific/Engineering :: Visualization diff -Nru matplotlib-1.1.1/README.txt matplotlib-1.2.0/README.txt --- matplotlib-1.1.1/README.txt 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/README.txt 2012-10-31 00:11:13.000000000 +0000 @@ -1,51 +1,9 @@ -matplotlib for MacOS X 10.3.9 or later and Python 2.5 and Python 2.6 - matplotlib is a python 2D plotting library which produces publication quality figures in a variety of hardcopy formats and interactive environments across platforms. matplotlib can be used in python scripts, the python and ipython shell (ala matlab or mathematica), web application servers, and various graphical user interface toolkits. -Home page: - -Before running matplotlib, you must install numpy. Binary installers -for all these packages are available here: - - . - -*** Setup from source using Pip *** - -:: - - pip install -e https://github.com/matplotlib/matplotlib.git#egg=Package - -*** Back Ends *** - -You may use TkAgg or WXAgg back ends; Qt and GTK support is not -provided in this package. By default this matplotlib uses TkAgg -because Tcl/Tk is included with MacOS X. - -If you wish to use WXAgg then: -* Install wxPython from: - . -* Configure a matplotlibrc file, as described below. - -For TkAgg you may use Apple's built-in Tcl/Tk or install your own 8.4.x - -*** Configuring a matplotlibrc file *** - -If you wish to change any matplotlib settings, create a file: - ~/.matplotlib/matplotlibrc - - -that contains at least the following information. The values shown are -the defaults in the internal matplotlibrc file; change them as you see -fit: - -# the default backend; one of GTK GTKAgg GTKCairo FltkAgg QtAgg TkAgg WXAgg -# Agg Cairo GD GDK Paint PS PDF SVG Template -backend : TkAgg -interactive : False # see http://matplotlib.sourceforge.net/interactive.html +Home page: -See also - +For installation instructions and requirements, see the INSTALL file. diff -Nru matplotlib-1.1.1/debian/README.debian matplotlib-1.2.0/debian/README.debian --- matplotlib-1.1.1/debian/README.debian 2008-11-09 00:29:51.000000000 +0000 +++ matplotlib-1.2.0/debian/README.debian 2012-11-09 18:48:38.000000000 +0000 @@ -28,10 +28,8 @@ backend : -where can be chosen from this list: - - # Default backend, one of: Agg, Cairo, CocoaAgg, GTK, GTKAgg, - # GTKCairo, FltkAgg, Pdf, Ps, QtAgg, Qt4Agg, SVG, TkAgg, WX, WXAgg. + # Default backend, one of: GTK GTKAgg GTKCairo GTK3Agg GTK3Cairo CocoaAgg + # FltkAgg MacOSX QtAgg Qt4Agg TkAgg WX WXAgg Agg Cairo GDK PS PDF SVG Template # # The Agg, Ps, Pdf and SVG backends do not require external # dependencies. Do not choose GTK, GTKAgg, GTKCairo, TkAgg or WXAgg if @@ -41,5 +39,7 @@ GTK+ -> python-gtk2 Tk -> python-tk - QT -> python-qt3 or python-qt4 + QT -> python-qt4, python-sip WX -> python-wxgtk2.6 or python-wxgtk2.8 + GTK3 -> gir1.2-gtk-3.0, python-gi, python-gobject + FLTK -> python-fltk diff -Nru matplotlib-1.1.1/debian/changelog matplotlib-1.2.0/debian/changelog --- matplotlib-1.1.1/debian/changelog 2012-08-11 18:16:07.000000000 +0000 +++ matplotlib-1.2.0/debian/changelog 2013-01-25 10:59:07.000000000 +0000 @@ -1,3 +1,64 @@ +matplotlib (1.2.0-1~ubuntu12.10.1~ppa1) quantal; urgency=low + + * No-change backport to quantal + + -- Thomas Kluyver Fri, 25 Jan 2013 10:59:07 +0000 + +matplotlib (1.2.0-1) experimental; urgency=low + + * New upstream release + * debian/{control, rules} + - run tests for python3 module + * debian/{control, README.debian} + - add several missing dependencies (and b-d) for Matplotlib backends + * debian/rules + - no longer set examples.* options in matplotlibrc when building doc (they + are not needed with 1.2.0) + * debian/patches/60_bts691960_reintroduce_examples.directory_rcparam.patch + - reintroduce (removed in 1.2.x series) 'examples.directory' rc parameter, + in order to specify the Debian custom sample_data path; thanks to Julian + Taylor for the report; Closes: #691960 + + -- Sandro Tosi Sun, 11 Nov 2012 12:17:37 +0100 + +matplotlib (1.2.0~rc2-2) experimental; urgency=low + + * debian/{control, rules} + - provide Python 3 packages, based on the work of Thomas Kluyver (thanks!); + thanks to Yaroslav Halchenko for the report; Closes: #669272 + + -- Sandro Tosi Tue, 23 Oct 2012 22:55:15 +0200 + +matplotlib (1.2.0~rc2-1) experimental; urgency=low + + * New upstream release candidate + * debian/control + - updated Homepage field to new upstream website location + * debian/copyright + - converted to DEP-5 format + - updated to new upstream code + - extended packaging copyright years + * debian/patches/60_new_syntax_to_load_searchindex.patch + - removed, merged upstream + * debian/watch + - updated to point to github + * debian/patches/30_disable_sample_downloads.patch + - removed, no longer needed + * debian/patches/10_build_fix.patch + - disabled, but not removed in case we'll have to restore it + * debian/python-matplotlib-data.install + - install sampledata from new location (now it's in upstream tarball) + - use matplotlibrc.template to install base matplotlib.conf file + * debian/rules + - set backend and not datapath in matplotlibrc when running tests + - fix broken symlinks to TrueType fonts; thanks to Ian Zimmerman for the + report; Closes: #687674 + * debian/{control, rules} + - run tests under 'xvfb-run', needed to run inkscape (which is required to + compare SVG images); adding relevant b-d (xvfb and xauth) + + -- Sandro Tosi Tue, 25 Sep 2012 19:44:06 +0200 + matplotlib (1.1.1-1) experimental; urgency=low * New upstream release diff -Nru matplotlib-1.1.1/debian/control matplotlib-1.2.0/debian/control --- matplotlib-1.1.1/debian/control 2012-08-11 14:19:31.000000000 +0000 +++ matplotlib-1.2.0/debian/control 2012-11-09 18:48:38.000000000 +0000 @@ -13,19 +13,35 @@ libpng-dev, python-all-dbg (>= 2.4.4-6), python-all-dev (>= 2.3.5-7), + python3-all-dbg, + python3-all-dev, python-dateutil, + python-cairo, + python3-cairo, + python3-dateutil, + python-gi, + python3-gi, python-gtk2-dev, python-imaging, python-nose, + python3-nose, python-numpy (>= 1:1.5.1-4), python-numpy-dbg (>= 1:1.5.1-4), + python3-numpy, + python3-numpy-dbg, python-pkg-resources, + python3-pkg-resources, python-qt4, + python3-pyqt4, python-setuptools, + python3-setuptools, + python3-six, python-sphinx (>= 1.0.7+dfsg), python-support (>= 1.0.0), python-tk (>= 2.5.2-1.1), + python3-tk, python-tz, + python3-tz, python-wxgtk2.8, python-xlwt, tcl8.5-dev, @@ -33,18 +49,19 @@ texlive-latex-extra, texlive-latex-recommended, tk8.5-dev, + xauth, + xvfb, zlib1g-dev XS-Python-Version: all +X-Python3-Version: >= 3.2 Standards-Version: 3.9.3 -Homepage: http://matplotlib.sf.net/ +Homepage: http://matplotlib.org/ Vcs-Svn: svn://svn.debian.org/svn/python-modules/packages/matplotlib/trunk/ Vcs-Browser: http://svn.debian.org/viewsvn/python-modules/packages/matplotlib/trunk/ Package: python-matplotlib Architecture: any -Depends: python-cairo, - python-dateutil, - python-gobject, +Depends: python-dateutil, python-matplotlib-data (>= ${source:Version}), python-pyparsing, python-tz, @@ -54,14 +71,19 @@ Recommends: python-glade2, python-tk (>= 2.5.2-1.1) Enhances: ipython Suggests: dvipng, + gir1.2-gtk-3.0, ipython (>= 0.6.3), librsvg2-common, + python-cairo, python-configobj, python-excelerator, + python-fltk, + python-gobject, python-gtk2, python-matplotlib-doc, python-qt4, python-scipy, + python-sip, python-traits (>= 2.0), python-wxgtk2.8, texlive-extra-utils, @@ -73,6 +95,40 @@ be accessed either via a functional interface familiar to Matlab users or an object oriented interface familiar to Python users. +Package: python3-matplotlib +Architecture: any +Depends: python3-dateutil, + python-matplotlib-data (>= ${source:Version}), + python3-pyparsing, + python3-six, + python3-tz, + ${misc:Depends}, + ${python3:Depends}, + ${shlibs:Depends} +Recommends: python3-tk +Enhances: ipython3 +Suggests: dvipng, + gir1.2-gtk-3.0, + ipython3, + librsvg2-common, + python-matplotlib-doc, + python3-cairo, + python3-gi, + python3-gobject, + python3-pyqt4, + python3-scipy, + python3-sip, + texlive-extra-utils, + texlive-latex-extra +Description: Python based plotting system in a style similar to Matlab (Python 3) + Matplotlib is a pure Python plotting library designed to bring + publication quality plotting to Python with a syntax familiar to + Matlab users. All of the plotting commands in the pylab interface can + be accessed either via a functional interface familiar to Matlab + users or an object oriented interface familiar to Python users. + . + This package contains the Python 3 version of matplotlib. + Package: python-matplotlib-data Architecture: all Depends: fonts-lyx, ${misc:Depends} @@ -114,3 +170,20 @@ users or an object oriented interface familiar to Python users. . This package contains the debug extension for python-matplotlib. + +Package: python3-matplotlib-dbg +Architecture: any +Section: debug +Priority: extra +Depends: python3-all-dbg, + python3-matplotlib (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Description: Python based plotting system (debug extension, Python 3) + Matplotlib is a pure Python plotting library designed to bring + publication quality plotting to Python with a syntax familiar to + Matlab users. All of the plotting commands in the pylab interface can + be accessed either via a functional interface familiar to Matlab + users or an object oriented interface familiar to Python users. + . + This package contains the debug extension for python3-matplotlib. diff -Nru matplotlib-1.1.1/debian/copyright matplotlib-1.2.0/debian/copyright --- matplotlib-1.1.1/debian/copyright 2011-09-26 21:04:37.000000000 +0000 +++ matplotlib-1.2.0/debian/copyright 2012-09-23 20:27:39.000000000 +0000 @@ -1,458 +1,460 @@ -This package was debianized by Vittorio Palmisano on -Sun, 24 Sep 2006 12:12:29 +0200 +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: matplotlib +Upstream-Contact: John D. Hunter, Michael Droettboom +Source: http://matplotlib.org -It is now maintainer under the Debian Python Modules Team. -It was downloaded from http://matplotlib.sourceforge.net/ +Files: * +Copyright: Copyright (c) 2002-2008 John D. Hunter +License: + Matplotlib only uses BSD compatible code, and its license is based + on the PSF license. See the Open Source Initiative licenses page + for details on individual licenses. Non-BSD compatible licenses + (eg LGPL) are acceptable in matplotlib Toolkits. For a discussion + of the motivations behind the licencing choice, see Licenses. + License agreement for matplotlib. + . + 1. This LICENSE AGREEMENT is between John D. Hunter ("JDH"), and + the Individual or Organization ("Licensee") accessing and + otherwise using matplotlib software in source or binary form and + its associated documentation. + . + 2. Subject to the terms and conditions of this License Agreement, + JDH hereby grants Licensee a nonexclusive, royalty-free, + world-wide license to reproduce, analyze, test, perform and/or + display publicly, prepare derivative works, distribute, and + otherwise use matplotlib alone or in any derivative version, + provided, however, that JDH’s License Agreement and JDH’s notice + of copyright, i.e., "Copyright (c) 2002-2008 John D. Hunter; All + Rights Reserved" are retained in matplotlib alone or in any + derivative version prepared by Licensee. + . + 3. In the event Licensee prepares a derivative work that is based + on or incorporates matplotlib or any part thereof, and wants to + make the derivative work available to others as provided herein, + then Licensee hereby agrees to include in any such work a brief + summary of the changes made to matplotlib. + . + 4. JDH is making matplotlib available to Licensee on an ΄AS IS‘ + basis. JDH MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR + IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, JDH MAKES NO AND + DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR + FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF MATPLOTLIB + WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. + . + 5. JDH SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF + MATPLOTLIB FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES + OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING + MATPLOTLIB, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE + POSSIBILITY THEREOF. + . + 6. This License Agreement will automatically terminate upon a + material breach of its terms and conditions. + . + 7. Nothing in this License Agreement shall be deemed to create any + relationship of agency, partnership, or joint venture between JDH + and Licensee. This License Agreement does not grant permission to + use JDH trademarks or trade name in a trademark sense to endorse + or promote products or services of Licensee, or any third party. + . + 8. By copying, installing or otherwise using matplotlib, Licensee + agrees to be bound by the terms and conditions of this License + Agreement. + +Files: debian/* +Copyright: Copyright (C) 2008-2012 Sandro Tosi +License: same as upstream + +Files: lib/matplotlib/fontconfig_pattern.py +Author: Michael Droettboom + +Files: lib/matplotlib/backends/backend_fltkagg.py +Copyright: Gregory Lielens, Free Field Technologies SA and + John D. Hunter 2004 + +Files: lib/matplotlib/backends/backend_wxagg.py +Copyright: Copyright (C) 2003-5 Jeremy O'Donoghue, John Hunter, Illinois Institute of Technology + +Files: lib/matplotlib/backends/backend_wx.py +Copyright: Copyright (C) Jeremy O'Donoghue & John Hunter, 2003-4 +License: This work is licensed under a PSF compatible license. + +Files: lib/matplotlib/pyparsing_py2.py +Copyright: Copyright (c) 2003-2010 Paul T. McGuire +License: + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + . + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Files: lib/matplotlib/pyparsing_py3.py +Copyright: Copyright (c) 2003-2010 Paul T. McGuire +License: + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + . + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Files: lib/matplotlib/sankey.py +Author: Kevin L. Davies +License: BSD + +Files: lib/matplotlib/table.py +Author: John Gill +Copyright: 2004 John Gill and John Hunter + +Files: lib/matplotlib/delaunay/VoronoiDiagramGenerator.{cpp, h} +Author: The author of this software is Steven Fortune. +Copyright: Copyright (c) 1994 by AT&T Bell Laboratories. +License: + Permission to use, copy, modify, and distribute this software for any + purpose without fee is hereby granted, provided that this entire notice + is included in all copies of any software which is or includes a copy + or modification of this software and in all copies of the supporting + documentation for such software. + THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY + REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. +Comment: + This code was originally written by Stephan Fortune in C code. I, Shane O'Sullivan, + have since modified it, encapsulating it in a C++ class and, fixing memory leaks and + adding accessors to the Voronoi Edges. + Permission to use, copy, modify, and distribute this software for any + purpose without fee is hereby granted, provided that this entire notice + is included in all copies of any software which is or includes a copy + or modification of this software and in all copies of the supporting + documentation for such software. + THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY + REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + +Files: lib/matplotlib/delaunay/./__init__.py +Author: Robert Kern +Copyright: Copyright 2005 Robert Kern. +License: BSD-style license. See LICENSE.txt in the scipy source directory. + +Files: lib/matplotlib/testing/image_util.py +Copyright: Copyright (c) 1997-2009 by Secret Labs AB + Copyright (c) 1995-2009 by Fredrik Lundh +License: + Permission to use, copy, modify, and distribute this software and its + associated documentation for any purpose and without fee is hereby + granted, provided that the above copyright notice appears in all + copies, and that both that copyright notice and this permission notice + appear in supporting documentation, and that the name of Secret Labs + AB or the author not be used in advertising or publicity pertaining to + distribution of the software without specific, written prior + permission. + . + SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO + THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR + ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +Files: lib/matplotlib/mpl-data/fonts/ttf/(non STIX)*.ttf +Copyright: Copyright (c) 2003 by Bitstream, Inc. All Rights + Reserved. Bitstream Vera is a trademark of Bitstream, Inc. +License: + Permission is hereby granted, free of charge, to any person + obtaining a copy of the fonts accompanying this license ("Fonts") + and associated documentation files (the "Font Software"), to + reproduce and distribute the Font Software, including without + limitation the rights to use, copy, merge, publish, distribute, + and/or sell copies of the Font Software, and to permit persons to + whom the Font Software is furnished to do so, subject to the + following conditions: + . + The above copyright and trademark notices and this permission + notice shall be included in all copies of one or more of the Font + Software typefaces. + . + The Font Software may be modified, altered, or added to, and in + particular the designs of glyphs or characters in the Fonts may be + modified and additional glyphs or characters may be added to the + Fonts, only if the fonts are renamed to names not containing + either the words "Bitstream" or the word "Vera". + . + This License becomes null and void to the extent applicable to + Fonts or Font Software that has been modified and is distributed + under the "Bitstream Vera" names. + . + The Font Software may be sold as part of a larger software package + but no copy of one or more of the Font Software typefaces may be + sold by itself. + . + THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY + KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER + RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY + GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER + DEALINGS IN THE FONT SOFTWARE. + . + Except as contained in this notice, the names of Gnome, the Gnome + Foundation, and Bitstream Inc., shall not be used in advertising + or otherwise to promote the sale, use or other dealings in this + Font Software without prior written authorization from the Gnome + Foundation or Bitstream Inc., respectively. For further + information, contact: fonts at gnome dot org. -Upstream Author: +Files: lib/matplotlib/mpl-data/fonts/ttf/STIX*.ttf +License: + 1. Permission is hereby granted, free of charge, to any person + obtaining a copy of the STIX Fonts-TM set accompanying this + license (collectively, the "Fonts") and the associated + documentation files (collectively with the Fonts, the "Font + Software"), to reproduce and distribute the Font Software, + including the rights to use, copy, merge and publish copies of the + Font Software, and to permit persons to whom the Font Software is + furnished to do so same, subject to the following terms and + conditions (the "License"). + . + 2. The following copyright and trademark notice and these Terms + and Conditions shall be included in all copies of one or more of + the Font typefaces and any derivative work created as permitted + under this License: + . + Copyright (c) 2001-2005 by the STI Pub Companies, consisting + of the American Institute of Physics, the American Chemical + Society, the American Mathematical Society, the American Physical + Society, Elsevier, Inc., and The Institute of Electrical and + Electronic Engineers, Inc. Portions copyright (c) 1998-2003 by + MicroPress, Inc. Portions copyright (c) 1990 by Elsevier, Inc. All + rights reserved. STIX Fonts-TM is a trademark of The Institute of + Electrical and Electronics Engineers, Inc. + . + 3. You may (a) convert the Fonts from one format to another + (e.g., from TrueType to PostScript), in which case the normal and + reasonable distortion that occurs during such conversion shall be + permitted and (b) embed or include a subset of the Fonts in a + document for the purposes of allowing users to read text in the + document that utilizes the Fonts. In each case, you may use the + STIX Fonts-TM mark to designate the resulting Fonts or subset of + the Fonts. + . + 4. You may also (a) add glyphs or characters to the Fonts, or + modify the shape of existing glyphs, so long as the base set of + glyphs is not removed and (b) delete glyphs or characters from the + Fonts, provided that the resulting font set is distributed with + the following disclaimer: "This [name] font does not include all + the Unicode points covered in the STIX Fonts-TM set but may + include others." In each case, the name used to denote the + resulting font set shall not include the term "STIX" or any + similar term. + . + 5. You may charge a fee in connection with the distribution of + the Font Software, provided that no copy of one or more of the + individual Font typefaces that form the STIX Fonts-TM set may be + sold by itself. + . + 6. THE FONT SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF + ANY KIND, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, ANY + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK OR OTHER + RIGHT. IN NO EVENT SHALL MICROPRESS OR ANY OF THE STI PUB + COMPANIES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + INCLUDING, BUT NOT LIMITED TO, ANY GENERAL, SPECIAL, INDIRECT, + INCIDENTAL OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM OR OUT OF THE USE OR + INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE + FONT SOFTWARE. + . + 7. Except as contained in the notice set forth in Section 2, + the names MicroPress Inc. and STI Pub Companies, as well as the + names of the companies/organizations that compose the STI Pub + Companies, shall not be used in advertising or otherwise to + promote the sale, use or other dealings in the Font Software + without the prior written consent of the respective company or + organization. + . + 8. This License shall become null and void in the event of any + material breach of the Terms and Conditions herein by licensee. + . + 9. A substantial portion of the STIX Fonts set was developed by + MicroPress Inc. for the STI Pub Companies. To obtain additional + mathematical fonts, please contact MicroPress, Inc., 68-30 Harrow + Street, Forest Hills, NY 11375, USA - Phone: (718) 575-1816. + +Files: lib/matplotlib/mpl-data/fonts/pdfcorefonts/* +Copyright: Copyright (c) 1985, 1987, 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. + +Files: lib/matplotlib/mpl-data/fonts/afm/pcrro8a.afm +Copyright: Copyright (c) 1985, 1987, 1989, 1990, 1991, 1992 Adobe Systems Incorporated. All Rights Reserved. + +Files: lib/six.py +Author: Benjamin Peterson + +Files: src/nxutils.c +Copyright: Copyright (c) 1970-2003, Wm. Randolph Franklin +License: pnpoly license + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + . + 1. Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimers. 2. Redistributions in binary form must + reproduce the above copyright notice in the documentation + and/or other materials provided with the distribution. + 3. The name of W. Randolph Franklin may not be used to + endorse or promote products derived from this Software + without specific prior written permission. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + +FileS: src/_subprocess.c +Copyright: Copyright (c) 2004 by Fredrik Lundh + Copyright (c) 2004 by Secret Labs AB, http://www.pythonware.com + Copyright (c) 2004 by Peter Astrand +License: + Permission to use, copy, modify, and distribute this software and + its associated documentation for any purpose and without fee is + hereby granted, provided that the above copyright notice appears in + all copies, and that both that copyright notice and this permission + notice appear in supporting documentation, and that the name of the + authors not be used in advertising or publicity pertaining to + distribution of the software without specific, written prior + permission. + . + THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + . + Licensed to PSF under a Contributor Agreement. + See http://www.python.org/2.4/license for licensing details. + +Files: src/_wxagg.cpp +Author: Ken McIvor +Copyright: Copyright 2005 Illinois Institute of Technology +Comment: Derived from `_gtkagg.cpp', Copyright 2004-2005 John Hunter + +Files: lib/dateutil_py2/* +Copyright: Copyright (c) 2003-2010 Gustavo Niemeyer +License: PSF License + +Files: lib/dateutil_py3/* +Copyright: Copyright (c) 2003-2011 Gustavo Niemeyer + Copyright (c) 2012 - Tomi Pieviläinen +License: Simplified BSD + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + . + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - John D. Hunter - -Copyright Holder: - - Copyright (c) 2002-2008 John D. Hunter - -License: - - Matplotlib only uses BSD compatible code, and its license is based - on the PSF license. See the Open Source Initiative licenses page - for details on individual licenses. Non-BSD compatible licenses - (eg LGPL) are acceptable in matplotlib Toolkits. For a discussion - of the motivations behind the licencing choice, see Licenses. - License agreement for matplotlib. - - 1. This LICENSE AGREEMENT is between John D. Hunter ("JDH"), and - the Individual or Organization ("Licensee") accessing and - otherwise using matplotlib software in source or binary form and - its associated documentation. - - 2. Subject to the terms and conditions of this License Agreement, - JDH hereby grants Licensee a nonexclusive, royalty-free, - world-wide license to reproduce, analyze, test, perform and/or - display publicly, prepare derivative works, distribute, and - otherwise use matplotlib alone or in any derivative version, - provided, however, that JDH’s License Agreement and JDH’s notice - of copyright, i.e., "Copyright (c) 2002-2008 John D. Hunter; All - Rights Reserved" are retained in matplotlib alone or in any - derivative version prepared by Licensee. - - 3. In the event Licensee prepares a derivative work that is based - on or incorporates matplotlib or any part thereof, and wants to - make the derivative work available to others as provided herein, - then Licensee hereby agrees to include in any such work a brief - summary of the changes made to matplotlib. - - 4. JDH is making matplotlib available to Licensee on an ΄AS IS‘ - basis. JDH MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR - IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, JDH MAKES NO AND - DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR - FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF MATPLOTLIB - WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. - - 5. JDH SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF - MATPLOTLIB FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES - OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING - MATPLOTLIB, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE - POSSIBILITY THEREOF. - - 6. This License Agreement will automatically terminate upon a - material breach of its terms and conditions. - - 7. Nothing in this License Agreement shall be deemed to create any - relationship of agency, partnership, or joint venture between JDH - and Licensee. This License Agreement does not grant permission to - use JDH trademarks or trade name in a trademark sense to endorse - or promote products or services of Licensee, or any third party. - - 8. By copying, installing or otherwise using matplotlib, Licensee - agrees to be bound by the terms and conditions of this License - Agreement. - -The Debian packaging is: - - Copyright (C) 2008-2011 Sandro Tosi - -and is licensed under the same terms as upstream code. - - -These files have different copyright/license notices: - -lib/matplotlib/fontconfig_pattern.py - Author : Michael Droettboom - -lib/matplotlib/backends/backend_fltkagg.py - Copyright: Gregory Lielens, Free Field Technologies SA and - John D. Hunter 2004 - -lib/matplotlib/backends/backend_wxagg.py - Copyright (C) 2003-5 Jeremy O'Donoghue, John Hunter, Illinois Institute of - Technology - -lib/matplotlib/backends/backend_wx.py - Copyright (C) Jeremy O'Donoghue & John Hunter, 2003-4 - License: This work is licensed under a PSF compatible license. - -lib/matplotlib/pyparsing.py - # Copyright (c) 2003-2008 Paul T. McGuire - # - # Permission is hereby granted, free of charge, to any person obtaining - # a copy of this software and associated documentation files (the - # "Software"), to deal in the Software without restriction, including - # without limitation the rights to use, copy, modify, merge, publish, - # distribute, sublicense, and/or sell copies of the Software, and to - # permit persons to whom the Software is furnished to do so, subject to - # the following conditions: - # - # The above copyright notice and this permission notice shall be - # included in all copies or substantial portions of the Software. - # - # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -lib/matplotlib/sankey.py - Author: Kevin L. Davies - License: BSD - -lib/matplotlib/table.py - Author : John Gill - Copyright : 2004 John Gill and John Hunter - -lib/matplotlib/delaunay/VoronoiDiagramGenerator.{cpp, h} - /* - * The author of this software is Steven Fortune. Copyright (c) 1994 by AT&T - * Bell Laboratories. - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software and in all copies of the supporting - * documentation for such software. - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - */ - - /* - * This code was originally written by Stephan Fortune in C code. I, Shane O'Sullivan, - * have since modified it, encapsulating it in a C++ class and, fixing memory leaks and - * adding accessors to the Voronoi Edges. - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software and in all copies of the supporting - * documentation for such software. - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - */ - -lib/matplotlib/delaunay/./__init__.py - Author: Robert Kern - - Copyright: Copyright 2005 Robert Kern. - License: BSD-style license. See LICENSE.txt in the scipy source directory. - -lib/matplotlib/mpl-data/fonts/ttf/(non STIX)*.ttf - Copyright - ========= - - Copyright (c) 2003 by Bitstream, Inc. All Rights - Reserved. Bitstream Vera is a trademark of Bitstream, Inc. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of the fonts accompanying this license ("Fonts") - and associated documentation files (the "Font Software"), to - reproduce and distribute the Font Software, including without - limitation the rights to use, copy, merge, publish, distribute, - and/or sell copies of the Font Software, and to permit persons to - whom the Font Software is furnished to do so, subject to the - following conditions: - - The above copyright and trademark notices and this permission - notice shall be included in all copies of one or more of the Font - Software typefaces. - - The Font Software may be modified, altered, or added to, and in - particular the designs of glyphs or characters in the Fonts may be - modified and additional glyphs or characters may be added to the - Fonts, only if the fonts are renamed to names not containing - either the words "Bitstream" or the word "Vera". - - This License becomes null and void to the extent applicable to - Fonts or Font Software that has been modified and is distributed - under the "Bitstream Vera" names. - - The Font Software may be sold as part of a larger software package - but no copy of one or more of the Font Software typefaces may be - sold by itself. - - THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY - KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY - WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER - RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY - GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER - DEALINGS IN THE FONT SOFTWARE. - - Except as contained in this notice, the names of Gnome, the Gnome - Foundation, and Bitstream Inc., shall not be used in advertising - or otherwise to promote the sale, use or other dealings in this - Font Software without prior written authorization from the Gnome - Foundation or Bitstream Inc., respectively. For further - information, contact: fonts at gnome dot org. - -lib/matplotlib/mpl-data/fonts/ttf/STIX*.ttf - License: - - 1. Permission is hereby granted, free of charge, to any person - obtaining a copy of the STIX Fonts-TM set accompanying this - license (collectively, the "Fonts") and the associated - documentation files (collectively with the Fonts, the "Font - Software"), to reproduce and distribute the Font Software, - including the rights to use, copy, merge and publish copies of the - Font Software, and to permit persons to whom the Font Software is - furnished to do so same, subject to the following terms and - conditions (the "License"). - - 2. The following copyright and trademark notice and these Terms - and Conditions shall be included in all copies of one or more of - the Font typefaces and any derivative work created as permitted - under this License: - - Copyright (c) 2001-2005 by the STI Pub Companies, consisting - of the American Institute of Physics, the American Chemical - Society, the American Mathematical Society, the American Physical - Society, Elsevier, Inc., and The Institute of Electrical and - Electronic Engineers, Inc. Portions copyright (c) 1998-2003 by - MicroPress, Inc. Portions copyright (c) 1990 by Elsevier, Inc. All - rights reserved. STIX Fonts-TM is a trademark of The Institute of - Electrical and Electronics Engineers, Inc. - - 3. You may (a) convert the Fonts from one format to another - (e.g., from TrueType to PostScript), in which case the normal and - reasonable distortion that occurs during such conversion shall be - permitted and (b) embed or include a subset of the Fonts in a - document for the purposes of allowing users to read text in the - document that utilizes the Fonts. In each case, you may use the - STIX Fonts-TM mark to designate the resulting Fonts or subset of - the Fonts. - - 4. You may also (a) add glyphs or characters to the Fonts, or - modify the shape of existing glyphs, so long as the base set of - glyphs is not removed and (b) delete glyphs or characters from the - Fonts, provided that the resulting font set is distributed with - the following disclaimer: "This [name] font does not include all - the Unicode points covered in the STIX Fonts-TM set but may - include others." In each case, the name used to denote the - resulting font set shall not include the term "STIX" or any - similar term. - - 5. You may charge a fee in connection with the distribution of - the Font Software, provided that no copy of one or more of the - individual Font typefaces that form the STIX Fonts-TM set may be - sold by itself. - - 6. THE FONT SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF - ANY KIND, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, ANY - WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK OR OTHER - RIGHT. IN NO EVENT SHALL MICROPRESS OR ANY OF THE STI PUB - COMPANIES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - INCLUDING, BUT NOT LIMITED TO, ANY GENERAL, SPECIAL, INDIRECT, - INCIDENTAL OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM OR OUT OF THE USE OR - INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE - FONT SOFTWARE. - - 7. Except as contained in the notice set forth in Section 2, - the names MicroPress Inc. and STI Pub Companies, as well as the - names of the companies/organizations that compose the STI Pub - Companies, shall not be used in advertising or otherwise to - promote the sale, use or other dealings in the Font Software - without the prior written consent of the respective company or - organization. - - 8. This License shall become null and void in the event of any - material breach of the Terms and Conditions herein by licensee. - - 9. A substantial portion of the STIX Fonts set was developed by - MicroPress Inc. for the STI Pub Companies. To obtain additional - mathematical fonts, please contact MicroPress, Inc., 68-30 Harrow - Street, Forest Hills, NY 11375, USA - Phone: (718) 575-1816. - -lib/matplotlib/mpl-data/fonts/pdfcorefonts/* - Copyright (c) 1985, 1987, 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. - -lib/matplotlib/mpl-data/fonts/afm/pcrro8a.afm - Copyright (c) 1985, 1987, 1989, 1990, 1991, 1992 Adobe Systems Incorporated. All Rights Reserved. - -src/nxutils.c - pnpoly license - Copyright (c) 1970-2003, Wm. Randolph Franklin - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - 1. Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimers. 2. Redistributions in binary form must - reproduce the above copyright notice in the documentation - and/or other materials provided with the distribution. - 3. The name of W. Randolph Franklin may not be used to - endorse or promote products derived from this Software - without specific prior written permission. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. */ - -src/_subprocess.c - /* - * support routines for subprocess module - * - * Currently, this extension module is only required when using the - * subprocess module on Windows, but in the future, stubs for other - * platforms might be added here as well. - * - * Copyright (c) 2004 by Fredrik Lundh - * Copyright (c) 2004 by Secret Labs AB, http://www.pythonware.com - * Copyright (c) 2004 by Peter Astrand - * - * By obtaining, using, and/or copying this software and/or its - * associated documentation, you agree that you have read, understood, - * and will comply with the following terms and conditions: - * - * Permission to use, copy, modify, and distribute this software and - * its associated documentation for any purpose and without fee is - * hereby granted, provided that the above copyright notice appears in - * all copies, and that both that copyright notice and this permission - * notice appear in supporting documentation, and that the name of the - * authors not be used in advertising or publicity pertaining to - * distribution of the software without specific, written prior - * permission. - * - * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. - * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - - /* Licensed to PSF under a Contributor Agreement. */ - /* See http://www.python.org/2.4/license for licensing details. */ - -src/_wxagg.cpp - // Purpose: Accelerate WXAgg by doing the agg->wxWidgets conversions in C++. - // Author: Ken McIvor - // - // Copyright 2005 Illinois Institute of Technology - // Derived from `_gtkagg.cpp', Copyright 2004-2005 John Hunter - // - // See the file "LICENSE" for information on usage and redistribution - // of this file, and for a DISCLAIMER OF ALL WARRANTIES. - -lib/dateutil/* - Copyright (c) 2003-2005 Gustavo Niemeyer - __author__ = "Gustavo Niemeyer " - __license__ = "PSF License" - -ttconv/* - /* - * Modified for use within matplotlib - * 5 July 2007 - * Michael Droettboom - */ - - /* - ** ~ppr/src/include/global_defines.h - ** Copyright 1995, Trinity College Computing Center. - ** Written by David Chappell. - ** - ** Permission to use, copy, modify, and distribute this software and its - ** documentation for any purpose and without fee is hereby granted, provided - ** that the above copyright notice appear in all copies and that both that - ** copyright notice and this permission notice appear in supporting - ** documentation. This software and documentation are provided "as is" without - ** express or implied warranty. - ** - ** The PPR project was begun 28 December 1992. - ** - ** There are many things in this file you may want to change. This file - ** should be the first include file. It is the header file for the whole - ** project. - ** - ** This file was last modified 22 December 1995. - */ - -CXX/* - // Copyright (c) 1998 - 2007, The Regents of the University of California - // Produced at the Lawrence Livermore National Laboratory - // All rights reserved. - // - // This file is part of PyCXX. For details,see http://cxx.sourceforge.net/. The - // full copyright notice is contained in the file COPYRIGHT located at the root - // of the PyCXX distribution. - // - // Redistribution and use in source and binary forms, with or without - // modification, are permitted provided that the following conditions are met: - // - // - Redistributions of source code must retain the above copyright notice, - // this list of conditions and the disclaimer below. - // - Redistributions in binary form must reproduce the above copyright notice, - // this list of conditions and the disclaimer (as noted below) in the - // documentation and/or materials provided with the distribution. - // - Neither the name of the UC/LLNL nor the names of its contributors may be - // used to endorse or promote products derived from this software without - // specific prior written permission. - // - // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - // ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF - // CALIFORNIA, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR - // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - // DAMAGE. - -agg24/* - //---------------------------------------------------------------------------- - // Anti-Grain Geometry - Version 2.4 - // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) - // - // Permission to copy, use, modify, sell and distribute this software - // is granted provided this copyright notice appears in all copies. - // This software is provided "as is" without express or implied - // warranty, and with no claim as to its suitability for any purpose. - // - //---------------------------------------------------------------------------- - // Contact: mcseem@antigrain.com - // mcseemagg@yahoo.com - // http://www.antigrain.com - //---------------------------------------------------------------------------- +Files: ttconv/* +Copyright: Copyright 1995, Trinity College Computing Center. Written by David Chappell. +License: + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation. This software and documentation are provided "as is" without + express or implied warranty. + +Files: CXX/* +Copyright: Copyright (c) 1998 - 2007, The Regents of the University of California + Produced at the Lawrence Livermore National Laboratory + All rights reserved. +License: + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + . + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the disclaimer below. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the disclaimer (as noted below) in the + documentation and/or materials provided with the distribution. + - Neither the name of the UC/LLNL nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF + CALIFORNIA, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. + +Files: agg24/* +Copyright: Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +License: + Permission to copy, use, modify, sell and distribute this software + is granted provided this copyright notice appears in all copies. + This software is provided "as is" without express or implied + warranty, and with no claim as to its suitability for any purpose. diff -Nru matplotlib-1.1.1/debian/patches/30_disable_sample_downloads.patch matplotlib-1.2.0/debian/patches/30_disable_sample_downloads.patch --- matplotlib-1.1.1/debian/patches/30_disable_sample_downloads.patch 2011-09-26 21:50:33.000000000 +0000 +++ matplotlib-1.2.0/debian/patches/30_disable_sample_downloads.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -Description: disable download of sample data (used to run examples) -Author: Benjamin Gamari - -Index: matplotlib-1.1.0~rc1/matplotlibrc.template -=================================================================== ---- matplotlib-1.1.0~rc1.orig/matplotlibrc.template 2011-09-24 17:08:27.000000000 +0200 -+++ matplotlib-1.1.0~rc1/matplotlibrc.template 2011-09-26 23:46:09.712993921 +0200 -@@ -404,5 +404,5 @@ - # examples.download to False and examples.directory to the directory - # where you have a checkout of https://github.com/matplotlib/sample_data - --#examples.download : True # False to bypass downloading mechanism --#examples.directory : '' # directory to look in if download is false -+examples.download : False # False to bypass downloading mechanism -+examples.directory : '/usr/share/matplotlib/sampledata' # absolute directory to look in if download is false diff -Nru matplotlib-1.1.1/debian/patches/60_bts691960_reintroduce_examples.directory_rcparam.patch matplotlib-1.2.0/debian/patches/60_bts691960_reintroduce_examples.directory_rcparam.patch --- matplotlib-1.1.1/debian/patches/60_bts691960_reintroduce_examples.directory_rcparam.patch 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/debian/patches/60_bts691960_reintroduce_examples.directory_rcparam.patch 2012-11-10 22:01:43.000000000 +0000 @@ -0,0 +1,81 @@ +Description: Reintroduce examples.directory rc parameter +Forwarded: https://github.com/matplotlib/matplotlib/pull/1479 +Bug-Debian: http://bugs.debian.org/691960 +Author: Sandro Tosi + +--- a/lib/matplotlib/__init__.py ++++ b/lib/matplotlib/__init__.py +@@ -825,6 +825,20 @@ Please do not ask for support with these + # this is the instance used by the matplotlib classes + rcParams = rc_params() + ++if rcParams['examples.directory']: ++ # paths that are intended to be relative to matplotlib_fname() ++ # are allowed for the examples.directory parameter. ++ # However, we will need to fully qualify the path because ++ # Sphinx requires absolute paths. ++ if not os.path.isabs(rcParams['examples.directory']): ++ _basedir, _fname = os.path.split(matplotlib_fname()) ++ # Sometimes matplotlib_fname() can return relative paths, ++ # Also, using realpath() guarentees that Sphinx will use ++ # the same path that matplotlib sees (in case of weird symlinks). ++ _basedir = os.path.realpath(_basedir) ++ _fullpath = os.path.join(_basedir, rcParams['examples.directory']) ++ rcParams['examples.directory'] = _fullpath ++ + rcParamsOrig = rcParams.copy() + + rcParamsDefault = RcParams([ (key, default) for key, (default, converter) in \ +--- a/lib/matplotlib/cbook.py ++++ b/lib/matplotlib/cbook.py +@@ -21,6 +21,7 @@ import traceback + import warnings + from weakref import ref, WeakKeyDictionary + ++import matplotlib + + import numpy as np + import numpy.ma as ma +@@ -570,9 +571,17 @@ def get_sample_data(fname, asfileobj=Tru + `mpl-data/sample_data` directory. If *asfileobj* is `True` + return a file object, otherwise just a file path. + ++ Set the rc parameter examples.directory to the directory where we should ++ look, if sample_data files are stored in a location different than ++ default (which is 'mpl-data/sample_data` at the same level of 'matplotlib` ++ Python module files). ++ + If the filename ends in .gz, the file is implicitly ungzipped. + """ +- root = os.path.join(os.path.dirname(__file__), "mpl-data", "sample_data") ++ if matplotlib.rcParams['examples.directory']: ++ root = matplotlib.rcParams['examples.directory'] ++ else: ++ root = os.path.join(os.path.dirname(__file__), "mpl-data", "sample_data") + path = os.path.join(root, fname) + + if asfileobj: +--- a/lib/matplotlib/rcsetup.py ++++ b/lib/matplotlib/rcsetup.py +@@ -616,6 +616,9 @@ defaultParams = { + 'keymap.xscale' : [['k', 'L'], validate_stringlist], + 'keymap.all_axes' : ['a', validate_stringlist], + ++ # sample data ++ 'examples.directory' : ['', str], ++ + # Animation settings + 'animation.writer' : ['ffmpeg', validate_movie_writer], + 'animation.codec' : ['mpeg4', str], +--- a/matplotlibrc.template ++++ b/matplotlibrc.template +@@ -423,6 +423,9 @@ text.hinting_factor : 8 # Specifies the + #keymap.xscale : L, k # toggle scaling of x-axes ('log'/'linear') + #keymap.all_axes : a # enable all axes + ++# Control location of examples data files ++examples.directory : /usr/share/matplotlib/sample_data ++ + ###ANIMATION settings + #animation.writer : ffmpeg # MovieWriter 'backend' to use + #animation.codec : mp4 # Codec to use for writing movie diff -Nru matplotlib-1.1.1/debian/patches/60_new_syntax_to_load_searchindex.patch matplotlib-1.2.0/debian/patches/60_new_syntax_to_load_searchindex.patch --- matplotlib-1.1.1/debian/patches/60_new_syntax_to_load_searchindex.patch 2012-04-08 14:47:55.000000000 +0000 +++ matplotlib-1.2.0/debian/patches/60_new_syntax_to_load_searchindex.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -Description: use recent sphinx syntax to load searchindex.js, so dh_sphinxdoc can recognize it -Author: Sandro Tosi -Forwarded: yes -Bug: https://github.com/matplotlib/matplotlib/issues/820 -Index: matplotlib-1.1.1~rc1/doc/_templates/search.html -=================================================================== ---- matplotlib-1.1.1~rc1.orig/doc/_templates/search.html 2012-03-23 02:58:28.000000000 +0100 -+++ matplotlib-1.1.1~rc1/doc/_templates/search.html 2012-04-08 16:03:22.404159237 +0200 -@@ -38,5 +38,7 @@ - {% endblock %} - {% block footer %} - {{ super() }} -- -+ - {% endblock %} diff -Nru matplotlib-1.1.1/debian/patches/series matplotlib-1.2.0/debian/patches/series --- matplotlib-1.1.1/debian/patches/series 2012-04-08 14:47:55.000000000 +0000 +++ matplotlib-1.2.0/debian/patches/series 2012-11-10 22:01:43.000000000 +0000 @@ -1,6 +1,5 @@ -10_build_fix.patch +#10_build_fix.patch 20_matplotlibrc_path_search_fix.patch -30_disable_sample_downloads.patch 40_bts608939_draw_markers_description.patch 50_bts608942_spaces_in_param_args.patch -60_new_syntax_to_load_searchindex.patch +60_bts691960_reintroduce_examples.directory_rcparam.patch diff -Nru matplotlib-1.1.1/debian/python-matplotlib-data.install matplotlib-1.2.0/debian/python-matplotlib-data.install --- matplotlib-1.1.1/debian/python-matplotlib-data.install 2011-01-11 00:28:14.000000000 +0000 +++ matplotlib-1.2.0/debian/python-matplotlib-data.install 2012-09-22 19:50:14.000000000 +0000 @@ -2,6 +2,6 @@ lib/matplotlib/mpl-data/fonts/ /usr/share/matplotlib/mpl-data/ lib/matplotlib/mpl-data/images/ /usr/share/matplotlib/mpl-data/ lib/matplotlib/mpl-data/lineprops.glade /usr/share/matplotlib/mpl-data/ -lib/matplotlib/mpl-data/matplotlib.conf /usr/share/matplotlib +matplotlibrc.template /usr/share/matplotlib/matplotlib.conf lib/matplotlib/mpl-data/matplotlibrc /etc/ -sampledata/ /usr/share/matplotlib/ +lib/matplotlib/mpl-data/sample_data/ /usr/share/matplotlib/ diff -Nru matplotlib-1.1.1/debian/rules matplotlib-1.2.0/debian/rules --- matplotlib-1.1.1/debian/rules 2012-05-20 17:42:43.000000000 +0000 +++ matplotlib-1.2.0/debian/rules 2012-11-09 19:21:50.000000000 +0000 @@ -1,12 +1,15 @@ #!/usr/bin/make -f -PYVERS := $(shell pyversions -v -r debian/control) +PY2VERS := $(shell pyversions -v -r debian/control) +PY3VERS := $(shell py3versions -v -r debian/control) DEFPY := $(shell pyversions -v -d) PY_PLATFORM := $(shell python -c 'from distutils.util import get_platform; print get_platform()') pd := python-matplotlib-doc p := python-matplotlib +p3 := python3-matplotlib pdata := python-matplotlib-data pdbg := python-matplotlib-dbg +p3dbg := python3-matplotlib-dbg # build build: build-arch build-indep @@ -15,17 +18,13 @@ build-indep-stamp: $(DEFPY:%=build-%-stamp) dh_testdir - # add information to use local copy of 'sampledata' and bypass downloading - echo "examples.download : False" >> $(CURDIR)/doc/matplotlibrc - echo "examples.directory : $(CURDIR)/sampledata" >> $(CURDIR)/doc/matplotlibrc - # build the doc -( cd doc ; MPLCONFIGDIR=. MATPLOTLIBDATA=../lib/matplotlib/mpl-data/ \ PYTHONPATH=../build/lib.$(PY_PLATFORM)-$(DEFPY) ./make.py --small all ) touch $@ -build-arch: $(PYVERS:%=build-%-stamp) +build-arch: $(PY2VERS:%=build-%-stamp) $(PY3VERS:%=build-%-stamp) build-%-stamp: dh_testdir @@ -35,24 +34,24 @@ python$*-dbg ./setup.py build $(PY_BUILD_FLAGS) ifeq (,$(findstring nocheck,$(DEB_BUILD_OPTIONS))) - echo "datapath : $(CURDIR)/lib/matplotlib/mpl-data/" > matplotlibrc + echo "backend : TkAgg" > matplotlibrc -PYTHONPATH=$(shell python$* -c "from distutils.command.build import build ; \ from distutils.core import Distribution ; \ b = build(Distribution()) ; \ b.finalize_options() ; \ - print b.build_platlib") \ + print(b.build_platlib)") \ MATPLOTLIBDATA=$(CURDIR)/lib/matplotlib/mpl-data/ \ MPLCONFIGDIR=. \ - python$* -c "import matplotlib as m ; m.test(verbosity=1)" + xvfb-run python$* -c "import matplotlib as m ; m.test(verbosity=1)" -PYTHONPATH=$(shell python$*-dbg -c "from distutils.command.build import build ; \ from distutils.core import Distribution ; \ b = build(Distribution()) ; \ b.finalize_options() ; \ - print b.build_platlib") \ + print(b.build_platlib)") \ MATPLOTLIBDATA=$(CURDIR)/lib/matplotlib/mpl-data/ \ MPLCONFIGDIR=. \ - python$*-dbg -c "import matplotlib as m ; m.test(verbosity=1)" + xvfb-run python$*-dbg -c "import matplotlib as m ; m.test(verbosity=1)" rm -f matplotlibrc endif @@ -64,7 +63,7 @@ dh_testdir dh_testroot - for i in $(PYVERS); do \ + for i in $(PY2VERS) $(PY3VERS); do \ python$(i) ./setup.py clean --all; \ python$(i)-dbg ./setup.py clean --all; \ done @@ -93,10 +92,11 @@ sed -i '/^examples\./d' $(CURDIR)/doc/matplotlibrc # install -install-arch: build-arch $(PYVERS:%=install-%-stamp) +install-arch: build-arch $(PY2VERS:%=install-%-stamp) $(PY3VERS:%=install-py3-%-stamp) dh_testdir dh_testroot dh_numpy + dh_numpy3 install-%-stamp: build-%-stamp dh_testdir @@ -123,6 +123,31 @@ touch $@ +install-py3-%-stamp: build-%-stamp + dh_testdir + dh_testroot + + python$* ./setup.py install_lib \ + -d $(CURDIR)/debian/$(p3)/usr/lib/python3/dist-packages/ --no-compile + python$* ./setup.py install_egg_info \ + -d $(CURDIR)/debian/$(p3)/usr/lib/python3/dist-packages/ + python$*-dbg ./setup.py install_lib \ + -d $(CURDIR)/debian/$(p3dbg)/usr/lib/python3/dist-packages/ --no-compile + + find debian/$(p3dbg) ! -type d ! -name '*.so' | xargs rm -f + find debian/$(p3dbg) -depth -empty -exec rmdir {} \; + + # don't install baseline_images, needed for tests only, but huge + rm -rf $(CURDIR)/debian/$(p3)/usr/lib/python3/*-packages/matplotlib/tests/baseline_images/ + + rm -rf $(CURDIR)/debian/$(p3)/usr/lib/python3/dist-packages/matplotlib/mpl-data/ + rm -rf $(CURDIR)/debian/$(p3)/usr/lib/python3/dist-packages/matplotlib/backends/Matplotlib.nib/ + + rm -rf $(CURDIR)/debian/$(p3dbg)/usr/lib/python3/dist-packages/matplotlib/mpl-data/ + rm -rf $(CURDIR)/debian/$(p3dbg)/usr/lib/python3/dist-packages/matplotlib/backends/Matplotlib.nib/ + + touch $@ + install-indep: build-indep dh_testdir -i dh_testroot -i @@ -134,10 +159,10 @@ rm -fr $(CURDIR)/debian/$(pdata)/usr/share/matplotlib/mpl-data/fonts/pdfcorefonts/readme.txt chmod 644 $(CURDIR)/debian/$(pdata)/usr/share/matplotlib/mpl-data/images/*.svg # link to fonts in ttf-lyx - ln -sf /usr/share/fonts/truetype/ttf-lyx/cmex10.ttf $(CURDIR)/debian/$(pdata)/usr/share/matplotlib/mpl-data/fonts/ttf/cmex10.ttf - ln -sf /usr/share/fonts/truetype/ttf-lyx/cmmi10.ttf $(CURDIR)/debian/$(pdata)/usr/share/matplotlib/mpl-data/fonts/ttf/cmmi10.ttf - ln -sf /usr/share/fonts/truetype/ttf-lyx/cmr10.ttf $(CURDIR)/debian/$(pdata)/usr/share/matplotlib/mpl-data/fonts/ttf/cmr10.ttf - ln -sf /usr/share/fonts/truetype/ttf-lyx/cmsy10.ttf $(CURDIR)/debian/$(pdata)/usr/share/matplotlib/mpl-data/fonts/ttf/cmsy10.ttf + for font in cmex10.ttf cmmi10.ttf cmr10.ttf cmsy10.ttf ; \ + do \ + ln -sf /usr/share/fonts/truetype/lyx/$$font $(CURDIR)/debian/$(pdata)/usr/share/matplotlib/mpl-data/fonts/ttf/$$font; \ + done # binary binary-indep: build-indep install-indep @@ -171,9 +196,11 @@ fi; \ done dh_pysupport -a + dh_python3 -a dh_link -a dh_lintian -a - dh_strip -a --dbg-package=$(pdbg) + dh_strip -a -p$(p) --dbg-package=$(pdbg) + dh_strip -a -p$(p3) --dbg-package=$(p3dbg) # fix python-debug-in-wrong-location lintian warning cd debian/*-dbg/usr/lib/debug/usr/lib && mv pyshared pymodules dh_compress -a diff -Nru matplotlib-1.1.1/debian/watch matplotlib-1.2.0/debian/watch --- matplotlib-1.1.1/debian/watch 2008-07-01 21:33:53.000000000 +0000 +++ matplotlib-1.2.0/debian/watch 2012-09-17 22:00:54.000000000 +0000 @@ -1,2 +1,3 @@ version=3 -http://sf.net/matplotlib/matplotlib-([0-9]+(?:\.[0-9]+)*)\.tar\.gz +opts="uversionmangle=s/rc/~rc/" \ +https://github.com/matplotlib/matplotlib/downloads .*/matplotlib-(.*).tar.gz Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/doc/_static/John-hunter-crop-2.jpg and /tmp/dj4q_yDaTz/matplotlib-1.2.0/doc/_static/John-hunter-crop-2.jpg differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/doc/_static/pgf_fonts.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/doc/_static/pgf_fonts.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/doc/_static/pgf_fonts.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/doc/_static/pgf_fonts.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/doc/_static/pgf_preamble.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/doc/_static/pgf_preamble.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/doc/_static/pgf_preamble.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/doc/_static/pgf_preamble.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/doc/_static/pgf_texsystem.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/doc/_static/pgf_texsystem.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/doc/_static/pgf_texsystem.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/doc/_static/pgf_texsystem.png differ diff -Nru matplotlib-1.1.1/doc/_templates/index.html matplotlib-1.2.0/doc/_templates/index.html --- matplotlib-1.1.1/doc/_templates/index.html 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/_templates/index.html 2012-11-08 02:24:13.000000000 +0000 @@ -3,7 +3,67 @@ {% block body %} -

intro

+ + + + Fork me on GitHub + +

John Hunter (1968-2012)

+ + + + + + +
+ + +

+ On August 28 2012, John D. Hunter, the creator of matplotlib, died + from complications arising from cancer treatment, after a brief but + intense battle with this terrible illness. John is survived by his + wife Miriam, his three daughters Rahel, Ava and Clara, his sisters + Layne and Mary, and his mother Sarah.

+ +

+ If you have benefited from John's many contributions, please say + thanks in the way that would matter most to him. Please consider + making a donation to + the John Hunter Memorial + Fund.

+
+ +

Introduction

matplotlib is a python 2D plotting library which produces publication quality figures in a variety of hardcopy formats and @@ -17,23 +77,17 @@ web application servers, and six graphical user interface toolkits.

- - - - +

screenshots

matplotlib tries to make easy things easy and hard things possible. You can generate plots, histograms, power spectra, bar charts, errorcharts, scatterplots, etc, with just a few lines of code. For a sampling, see the screenshots, thumbnail gallery, and -examples directory

+ examples directory

-

screenshots

- - -

For example, using "ipython -pylab" to provide an interactive +

For example, using "ipython --pylab" to provide an interactive environment, to generate 10,000 gaussian random numbers and plot a histogram with 100 bins, you simply need to type

@@ -44,1266 +98,97 @@

For the power user, you have full control of line styles, font properties, axes properties, etc, via an object oriented interface - or via a set of functions familiar to MATLAB users. - The pylab mode provides all of the pyplot plotting - functions listed below, as well as non-plotting functions from - numpy and - matplotlib.mlab.

- -

plotting commands


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + or via a set of functions familiar to MATLAB users.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +

Download

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +

Documentation

- + This is the documentation for matplotlib version {{ version }}. + +

+ + +

Trying to learn how to do a particular kind of plot? Check out + the gallery, examples, + or the list of plotting + commands.

+ +

Other learning resources

+ + + +

Need help?

+ +

Check the faq, +the api docs, +mailing +list archives, and join the matplotlib +mailing lists. +Check out the matplotlib questions +on stackoverflow. +The search tool searches all of +the documentation, including full text search of over 350 complete +examples which exercise almost every corner of matplotlib.

+ +

You can file bugs, patches and feature requests on the +github +tracker, +but it is a good idea to ping us on the mailing list too.

+ +

To keep up to date with what's going on in matplotlib, see +the what's new +page, the more detailed changelog or browse +the source +code. Anything that could require changes to your existing code +is logged in the api +changes file.

+ +

Toolkits

+ +

There are several matplotlib add-on toolkits, including the projection +and mapping toolkit +basemap, 3d plotting with mplot3d, axes and axis helpers in axes_grid and more. +

+ +

Open source

+ +

Please +consider donating +to support matplotlib development or to +the John Hunter Memorial +Fund.

+ +

The matplotlib license +is based on the Python Software Foundation +(PSF) license.

+ +

There is an active developer community and a long list of people +who have made significant contributions.

- -
FunctionDescription
- acorr - - - plot the autocorrelation function -
- annotate - - - annotate something in the figure -
- arrow - - - add an arrow to the axes -
- axes - - - create a new axes -
- axhline - - - draw a horizontal line across axes -
- axvline - - - draw a vertical line across axes -
- axhspan - - - draw a horizontal bar across axes -
- axvspan - - - draw a vertical bar across axes -
- axis - - - set or return the current axis limits -
- barbs - - - a (wind) barb plot -
- bar - - - make a bar chart -
- barh - - - a horizontal bar chart -
- broken_barh - - - a set of horizontal bars with gaps -
- box - - - set the axes frame on/off state -
- boxplot - - - make a box and whisker plot -
- cla - - - clear current axes -
- clabel - - - label a contour plot -
- clf - - - clear a figure window -
- clim - - - adjust the color limits of the current image -
- close - - - close a figure window -
- colorbar - - - add a colorbar to the current figure -
- cohere - - - make a plot of coherence -
- contour - - - make a contour plot -
- contourf - - - make a filled contour plot -
- csd - - - make a plot of cross spectral density -
- delaxes - - - delete an axes from the current figure -
- draw - - - Force a redraw of the current figure -
- errorbar - - - make an errorbar graph -
- figlegend - - - make legend on the figure rather than the axes -
- figimage - - - make a figure image -
- figtext - - - add text in figure coords -
- figure - - - create or change active figure -
- fill - - - make filled polygons -
- fill_between - - - make filled polygons between two curves -
- findobj - - - recursively find all objects matching some criteria -
- gca - - - return the current axes -
- gcf - - - return the current figure -
- gci - - - get the current image, or None -
- getp - - - get a graphics property -
- grid - - - set whether gridding is on -
- hexbin - - - make a 2D hexagonal binning plot -
- hist - - - make a histogram -
- hold - - - set the axes hold state -
- ioff - - - turn interaction mode off -
- ion - - - turn interaction mode on -
- isinteractive - - - return True if interaction mode is on -
- imread - - - load image file into array -
- imsave - - - save array as an image file -
- imshow - - - plot image data -
- ishold - - - return the hold state of the current axes -
- legend - - - make an axes legend -
- locator_params - - - adjust parameters used in locating axis ticks -
- loglog - - - a log log plot -
- matshow - - - display a matrix in a new figure preserving aspect -
- margins - - - set margins used in autoscaling -
- pcolor - - - make a pseudocolor plot -
- pcolormesh - - - make a pseudocolor plot using a quadrilateral mesh -
- pie - - - make a pie chart -
- plot - - - make a line plot -
- plot_date - - - plot dates -
- plotfile - - - plot column data from an ASCII tab/space/comma delimited file -
- pie - - - pie charts -
- polar - - - make a polar plot on a PolarAxes -
- psd - - - make a plot of power spectral density -
- quiver - - - make a direction field (arrows) plot -
- rc - - - control the default params -
- rgrids - - - customize the radial grids and labels for polar -
- savefig - - - save the current figure -
- scatter - - - make a scatter plot -
- setp - - - set a graphics property -
- semilogx - - - log x axis -
- semilogy - - - log y axis -
- show - - - show the figures -
- specgram - - - a spectrogram plot -
- spy - - - plot sparsity pattern using markers or image -
- stem - - - make a stem plot -
- subplot - - - make a subplot (numrows, numcols, axesnum) -
- subplots - - - Create a figure with subplots -
- subplots_adjust - - - change the params controlling the subplot positions of current figure -
- subplot_tool - - - launch the subplot configuration tool -
- suptitle - - - add a figure title -
- table - - - add a table to the plot -
- text - - - add some text at location x,y to the current axes -
- thetagrids - - - customize the radial theta grids and labels for polar -
- tick_params - - - control the appearance of ticks and tick labels -
- ticklabel_format - - - control the format of tick labels -
- title - - - add a title to the current axes -
- tricontour - - - make a contour plot on a triangular grid -
- tricontourf - - - make a filled contour plot on a triangular grid -
- tripcolor - - - make a pseudocolor plot on a triangular grid -
- triplot - - - plot a triangular grid -
- xcorr - - - plot the autocorrelation function of x and y -
- xlim - - - set/get the xlimits -
- ylim - - - set/get the ylimits -
- xticks - - - set/get the xticks -
- yticks - - - set/get the yticks -
- xlabel - - - add an xlabel to the current axes -
- ylabel - - - add a ylabel to the current axes -
- autumn - - - set the default colormap to autumn -
- bone - - - set the default colormap to bone -
- cool - - - set the default colormap to cool -
- copper - - - set the default colormap to copper -
- flag - - - set the default colormap to flag -
- gray - - - set the default colormap to gray -
- hot - - - set the default colormap to hot -
- hsv - - - set the default colormap to hsv -
- jet - - - set the default colormap to jet -
- pink - - - set the default colormap to pink -
- prism - - - set the default colormap to prism -
- spring - - - set the default colormap to spring -
- summer - - - set the default colormap to summer -
- winter - - - set the default colormap to winter -
- spectral + Matplotlib is available for +download. - - set the default colormap to spectral -

* diff -Nru matplotlib-1.1.1/doc/_templates/indexsidebar.html matplotlib-1.2.0/doc/_templates/indexsidebar.html --- matplotlib-1.1.1/doc/_templates/indexsidebar.html 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/_templates/indexsidebar.html 2012-10-31 00:11:13.000000000 +0000 @@ -1,82 +0,0 @@ -

News

- - -

Please donate -to support matplotlib development.

- - -

Matplotlib 1.1.1 is available for -download. -See what's new -and tips on installing. -

- -

Sandro Tosi has a new book - Matplotlib for python - developers - also - at amazon.

- -

Build websites like matplotlib's, -with Sphinx and extensions for -mpl plots, math, inheritance diagrams -- try -the sampledoc -tutorial. -

- -

Videos

- -

Watch the SciPy 2009 intro and advanced matplotlib tutorials -

- -

Watch -a talk about -matplotlib presented -at NIPS 08 -Workshop MLOSS and one presented -at ChiPy. -

- - -

Toolkits

- -

There are several matplotlib add-on toolkits, including the projection -and mapping toolkit -basemap, 3d plotting with mplot3d, axes and axis helpers in axes_grid and more. -

- -

Need help?

- -

Check the user guide, -the faq, the api docs, -archives, -and join the matplotlib -mailing lists. -The search tool searches all of -the documentation, including full text search of over 350 complete -examples which exercise almost every corner of matplotlib.

- -

You can file bugs, patches and feature requests on the -github -tracker, -but it is a good idea to ping us on the mailing list too.

- -

For details on what's new, see the detailed changelog or browse the source code. Anything that could -require changes to your existing codes is logged in the api changes file.

- -

Other stuff

- -

The matplotlib license -is based on the Python Software Foundation -(PSF) license.

- -

There is an active developer community and a long list of people -who have made significant contributions.

- diff -Nru matplotlib-1.1.1/doc/_templates/search.html matplotlib-1.2.0/doc/_templates/search.html --- matplotlib-1.1.1/doc/_templates/search.html 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/_templates/search.html 2012-10-31 00:11:13.000000000 +0000 @@ -10,7 +10,7 @@ words. Pages containing less words won't appear in the result list.{% endtrans %} If you want to limit your search to working code examples, include the keyword "codex" (mnemonic for code example) in your - search, eg "codex ellipse"; + search, eg "codex ellipse"; see search examples.

@@ -38,5 +38,7 @@ {% endblock %} {% block footer %} {{ super() }} - + {% endblock %} diff -Nru matplotlib-1.1.1/doc/api/api_changes.rst matplotlib-1.2.0/doc/api/api_changes.rst --- matplotlib-1.1.1/doc/api/api_changes.rst 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/api/api_changes.rst 2012-11-08 13:38:03.000000000 +0000 @@ -11,6 +11,152 @@ For new features that were added to matplotlib, please see :ref:`whats-new`. +Changes in 1.2.x +================ + +* The ``classic`` option of the rc parameter ``toolbar`` is deprecated + and will be removed in the next release. + +* The :meth:`~matplotlib.cbook.isvector` method has been removed since it + is no longer functional. + +* The `rasterization_zorder` property on `~matplotlib.axes.Axes` a + zorder below which artists are rasterized. This has defaulted to + -30000.0, but it now defaults to `None`, meaning no artists will be + rasterized. In order to rasterize artists below a given zorder + value, `set_rasterization_zorder` must be explicitly called. + +* In :meth:`~matplotlib.axes.Axes.scatter`, and `~pyplot.scatter`, + when specifying a marker using a tuple, the angle is now specified + in degrees, not radians. + +* Using :meth:`~matplotlib.axes.Axes.twinx` or + :meth:`~matplotlib.axes.Axes.twiny` no longer overrides the current locaters + and formatters on the axes. + +* In :meth:`~matplotlib.axes.Axes.contourf`, the handling of the *extend* + kwarg has changed. Formerly, the extended ranges were mapped + after to 0, 1 after being normed, so that they always corresponded + to the extreme values of the colormap. Now they are mapped + outside this range so that they correspond to the special + colormap values determined by the + :meth:`~matplotlib.colors.Colormap.set_under` and + :meth:`~matplotlib.colors.Colormap.set_over` methods, which + default to the colormap end points. + +* The new rc parameter ``savefig.format`` replaces ``cairo.format`` and + ``savefig.extension``, and sets the default file format used by + :meth:`matplotlib.figure.Figure.savefig`. + +* In :meth:`~matplotlib.pyplot.pie` and :meth:`~matplotlib.Axes.pie`, one can + now set the radius of the pie; setting the *radius* to 'None' (the default + value), will result in a pie with a radius of 1 as before. + +* Use of :func:`~matplotlib.projections.projection_factory` is now deprecated + in favour of axes class identification using + :func:`~matplotlib.projections.process_projection_requirements` followed by + direct axes class invocation (at the time of writing, functions which do this + are: :meth:`~matplotlib.figure.Figure.add_axes`, + :meth:`~matplotlib.figure.Figure.add_subplot` and + :meth:`~matplotlib.figure.Figure.gca`). Therefore:: + + + key = figure._make_key(*args, **kwargs) + ispolar = kwargs.pop('polar', False) + projection = kwargs.pop('projection', None) + if ispolar: + if projection is not None and projection != 'polar': + raise ValuError('polar and projection args are inconsistent') + projection = 'polar' + ax = projection_factory(projection, self, rect, **kwargs) + key = self._make_key(*args, **kwargs) + + # is now + + projection_class, kwargs, key = \ + process_projection_requirements(self, *args, **kwargs) + ax = projection_class(self, rect, **kwargs) + + This change means that third party objects can expose themselves as + matplotlib axes by providing a ``_as_mpl_axes`` method. See + :ref:`adding-new-scales` for more detail. + +* A new keyword *extendfrac* in :meth:`~matplotlib.pyplot.colorbar` and + :class:`~matplotlib.colorbar.ColorbarBase` allows one to control the size of + the triangular minimum and maximum extensions on colorbars. + +* A new keyword *capthick* in :meth:`~matplotlib.pyplot.errorbar` has been + added as an intuitive alias to the *markeredgewidth* and *mew* keyword + arguments, which indirectly controlled the thickness of the caps on + the errorbars. For backwards compatibility, specifying either of the + original keyword arguments will override any value provided by + *capthick*. + +* Transform subclassing behaviour is now subtly changed. If your transform + implements a non-affine transformation, then it should override the + ``transform_non_affine`` method, rather than the generic ``transform`` method. + Previously transforms would define ``transform`` and then copy the + method into ``transform_non_affine``:: + + class MyTransform(mtrans.Transform): + def transform(self, xy): + ... + transform_non_affine = transform + + + This approach will no longer function correctly and should be changed to:: + + class MyTransform(mtrans.Transform): + def transform_non_affine(self, xy): + ... + + +* Artists no longer have ``x_isdata`` or ``y_isdata`` attributes; instead + any artist's transform can be interrogated with + ``artist_instance.get_transform().contains_branch(ax.transData)`` + +* Lines added to an axes now take into account their transform when updating the + data and view limits. This means transforms can now be used as a pre-transform. + For instance:: + + >>> import matplotlib.pyplot as plt + >>> import matplotlib.transforms as mtrans + >>> ax = plt.axes() + >>> ax.plot(range(10), transform=mtrans.Affine2D().scale(10) + ax.transData) + >>> print(ax.viewLim) + Bbox('array([[ 0., 0.],\n [ 90., 90.]])') + +* One can now easily get a transform which goes from one transform's coordinate + system to another, in an optimized way, using the new subtract method on a + transform. For instance, to go from data coordinates to axes coordinates:: + + >>> import matplotlib.pyplot as plt + >>> ax = plt.axes() + >>> data2ax = ax.transData - ax.transAxes + >>> print(ax.transData.depth, ax.transAxes.depth) + 3, 1 + >>> print(data2ax.depth) + 2 + + for versions before 1.2 this could only be achieved in a sub-optimal way, + using ``ax.transData + ax.transAxes.inverted()`` (depth is a new concept, + but had it existed it would return 4 for this example). + +* ``twinx`` and ``twiny`` now returns an instance of SubplotBase if + parent axes is an instance of SubplotBase. + +* All Qt3-based backends are now deprecated due to the lack of py3k bindings. + Qt and QtAgg backends will continue to work in v1.2.x for py2.6 + and py2.7. It is anticipated that the Qt3 support will be completely + removed for the next release. + +* :class:`~matplotlib.colors.ColorConverter`, + :class:`~matplotlib.colors.Colormap` and + :class:`~matplotlib.colors.Normalize` now subclasses ``object`` + +* ContourSet instances no longer have a ``transform`` attribute. Instead, + access the transform with the ``get_transform`` method. + Changes in 1.1.x ================ @@ -230,7 +376,7 @@ labelsep labelspacing handlelen handlelength handlestextsep handletextpad - axespad borderaxespad + axespad borderaxespad ================ ================ @@ -398,51 +544,51 @@ ------------------------------------------------------------ ------------------------------------------------------------ :meth:`Bbox.height` :attr:`transforms.Bbox.height` ------------------------------------------------------------ ------------------------------------------------------------ -`Bbox.intervalx().get_bounds()` :attr:`transforms.Bbox.intervalx` +`Bbox.intervalx().get_bounds()` :attr:`transforms.Bbox.intervalx` `Bbox.intervalx().set_bounds()` [:attr:`Bbox.intervalx` is now a property.] ------------------------------------------------------------ ------------------------------------------------------------ -`Bbox.intervaly().get_bounds()` :attr:`transforms.Bbox.intervaly` +`Bbox.intervaly().get_bounds()` :attr:`transforms.Bbox.intervaly` `Bbox.intervaly().set_bounds()` [:attr:`Bbox.intervaly` is now a property.] ------------------------------------------------------------ ------------------------------------------------------------ -:meth:`Bbox.xmin` :attr:`transforms.Bbox.x0` or +:meth:`Bbox.xmin` :attr:`transforms.Bbox.x0` or :attr:`transforms.Bbox.xmin` [1]_ ------------------------------------------------------------ ------------------------------------------------------------ -:meth:`Bbox.ymin` :attr:`transforms.Bbox.y0` or +:meth:`Bbox.ymin` :attr:`transforms.Bbox.y0` or :attr:`transforms.Bbox.ymin` [1]_ ------------------------------------------------------------ ------------------------------------------------------------ -:meth:`Bbox.xmax` :attr:`transforms.Bbox.x1` or +:meth:`Bbox.xmax` :attr:`transforms.Bbox.x1` or :attr:`transforms.Bbox.xmax` [1]_ ------------------------------------------------------------ ------------------------------------------------------------ -:meth:`Bbox.ymax` :attr:`transforms.Bbox.y1` or +:meth:`Bbox.ymax` :attr:`transforms.Bbox.y1` or :attr:`transforms.Bbox.ymax` [1]_ ------------------------------------------------------------ ------------------------------------------------------------ -`Bbox.overlaps(bboxes)` `Bbox.count_overlaps(bboxes)` +`Bbox.overlaps(bboxes)` `Bbox.count_overlaps(bboxes)` ------------------------------------------------------------ ------------------------------------------------------------ -`bbox_all(bboxes)` `Bbox.union(bboxes)` +`bbox_all(bboxes)` `Bbox.union(bboxes)` [:meth:`transforms.Bbox.union` is a staticmethod.] ------------------------------------------------------------ ------------------------------------------------------------ -`lbwh_to_bbox(l, b, w, h)` `Bbox.from_bounds(x0, y0, w, h)` +`lbwh_to_bbox(l, b, w, h)` `Bbox.from_bounds(x0, y0, w, h)` [:meth:`transforms.Bbox.from_bounds` is a staticmethod.] ------------------------------------------------------------ ------------------------------------------------------------ `inverse_transform_bbox(trans, bbox)` `Bbox.inverse_transformed(trans)` ------------------------------------------------------------ ------------------------------------------------------------ -`Interval.contains_open(v)` `interval_contains_open(tuple, v)` +`Interval.contains_open(v)` `interval_contains_open(tuple, v)` ------------------------------------------------------------ ------------------------------------------------------------ -`Interval.contains(v)` `interval_contains(tuple, v)` +`Interval.contains(v)` `interval_contains(tuple, v)` ------------------------------------------------------------ ------------------------------------------------------------ -`identity_transform()` :class:`matplotlib.transforms.IdentityTransform` +`identity_transform()` :class:`matplotlib.transforms.IdentityTransform` ------------------------------------------------------------ ------------------------------------------------------------ `blend_xy_sep_transform(xtrans, ytrans)` `blended_transform_factory(xtrans, ytrans)` ------------------------------------------------------------ ------------------------------------------------------------ -`scale_transform(xs, ys)` `Affine2D().scale(xs[, ys])` +`scale_transform(xs, ys)` `Affine2D().scale(xs[, ys])` ------------------------------------------------------------ ------------------------------------------------------------ -`get_bbox_transform(boxin, boxout)` `BboxTransform(boxin, boxout)` or - `BboxTransformFrom(boxin)` or - `BboxTransformTo(boxout)` +`get_bbox_transform(boxin, boxout)` `BboxTransform(boxin, boxout)` or + `BboxTransformFrom(boxin)` or + `BboxTransformTo(boxout)` ------------------------------------------------------------ ------------------------------------------------------------ -`Transform.seq_xy_tup(points)` `Transform.transform(points)` +`Transform.seq_xy_tup(points)` `Transform.transform(points)` ------------------------------------------------------------ ------------------------------------------------------------ -`Transform.inverse_xy_tup(points)` `Transform.inverted().transform(points)` +`Transform.inverse_xy_tup(points)` `Transform.inverted().transform(points)` ============================================================ ============================================================ .. [1] The :class:`~matplotlib.transforms.Bbox` is bound by the points @@ -485,7 +631,7 @@ ============================================================ ============================================================ Old method New method ============================================================ ============================================================ -`Artist.set_clip_path(path)` `Artist.set_clip_path(path, transform)` [5]_ +`Artist.set_clip_path(path)` `Artist.set_clip_path(path, transform)` [5]_ ============================================================ ============================================================ .. [5] :meth:`matplotlib.artist.Artist.set_clip_path` now accepts a @@ -512,7 +658,7 @@ ============================================================ ============================================================ Old method New method ============================================================ ============================================================ -`ColorConvertor.to_rgba_list(c)` `ColorConvertor.to_rgba_array(c)` +`ColorConvertor.to_rgba_list(c)` `ColorConvertor.to_rgba_array(c)` [:meth:`matplotlib.colors.ColorConvertor.to_rgba_array` returns an Nx4 Numpy array of RGBA color quadruples.] ============================================================ ============================================================ @@ -523,7 +669,7 @@ ============================================================ ============================================================ Old method New method ============================================================ ============================================================ -`Contour._segments` :meth:`matplotlib.contour.Contour.get_paths`` [Returns a +`Contour._segments` :meth:`matplotlib.contour.Contour.get_paths`` [Returns a list of :class:`matplotlib.path.Path` instances.] ============================================================ ============================================================ @@ -533,7 +679,7 @@ ============================================================ ============================================================ Old method New method ============================================================ ============================================================ -`Figure.dpi.get()` / `Figure.dpi.set()` :attr:`matplotlib.figure.Figure.dpi` *(a property)* +`Figure.dpi.get()` / `Figure.dpi.set()` :attr:`matplotlib.figure.Figure.dpi` *(a property)* ============================================================ ============================================================ :mod:`matplotlib.patches` diff -Nru matplotlib-1.1.1/doc/api/index.rst matplotlib-1.2.0/doc/api/index.rst --- matplotlib-1.1.1/doc/api/index.rst 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/api/index.rst 2012-10-31 00:11:13.000000000 +0000 @@ -12,6 +12,7 @@ .. toctree:: :maxdepth: 1 + pyplot_summary.rst api_changes.rst matplotlib_configuration_api.rst afm_api.rst diff -Nru matplotlib-1.1.1/doc/api/pyplot_api.rst matplotlib-1.2.0/doc/api/pyplot_api.rst --- matplotlib-1.1.1/doc/api/pyplot_api.rst 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/api/pyplot_api.rst 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,7 @@ ****** pyplot ****** - + :mod:`matplotlib.pyplot` ======================== @@ -10,3 +10,4 @@ :members: :undoc-members: :show-inheritance: + :exclude-members: plotting, colormaps diff -Nru matplotlib-1.1.1/doc/api/pyplot_summary.rst matplotlib-1.2.0/doc/api/pyplot_summary.rst --- matplotlib-1.1.1/doc/api/pyplot_summary.rst 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/api/pyplot_summary.rst 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,8 @@ +Plotting commands summary +========================= + +.. currentmodule:: matplotlib.pyplot + +.. autofunction:: plotting + +.. autofunction:: colormaps diff -Nru matplotlib-1.1.1/doc/conf.py matplotlib-1.2.0/doc/conf.py --- matplotlib-1.1.1/doc/conf.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/conf.py 2012-10-31 00:11:13.000000000 +0000 @@ -25,9 +25,10 @@ # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['matplotlib.sphinxext.mathmpl', 'math_symbol_table', 'sphinx.ext.autodoc', 'matplotlib.sphinxext.only_directives', + 'sphinx.ext.doctest', 'matplotlib.sphinxext.plot_directive', 'sphinx.ext.inheritance_diagram', 'gen_gallery', 'gen_rst', - 'matplotlib.sphinxext.ipython_console_highlighting'] + 'matplotlib.sphinxext.ipython_console_highlighting', 'github'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -40,7 +41,7 @@ # General substitutions. project = 'Matplotlib' -copyright = '2008, John Hunter, Darren Dale, Michael Droettboom' +copyright = '2012 John Hunter, Darren Dale, Eric Firing, Michael Droettboom and the matplotlib development team' # The default replacements for |version| and |release|, also used in various # other places throughout the built documents. @@ -74,11 +75,17 @@ # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' +default_role = 'obj' + # Plot directive configuration # ---------------------------- plot_formats = [('png', 80), ('hires.png', 200), ('pdf', 50)] +# Github extension + +github_project_url = "http://github.com/matplotlib/matplotlib/" + # Options for HTML output # ----------------------- @@ -155,7 +162,9 @@ # (source start file, target name, title, author, document class [howto/manual]). latex_documents = [ - ('contents', 'Matplotlib.tex', 'Matplotlib', 'Darren Dale, Michael Droettboom, Eric Firing, John Hunter', 'manual'), + ('contents', 'Matplotlib.tex', 'Matplotlib', + 'John Hunter, Darren Dale, Eric Firing, Michael Droettboom and the ' + 'matplotlib development team', 'manual'), ] @@ -186,3 +195,11 @@ rst_epilog = """ .. |minimum_numpy_version| replace:: %s """ % matplotlib.__version__numpy__ + +texinfo_documents = [ + ("contents", 'matplotlib', 'Matplotlib Documentation', + 'John Hunter@*Darren Dale@*Eric Firing@*Michael Droettboom@*' + 'The matplotlib development team', + 'Matplotlib', "Python plotting package", 'Programming', + 1), +] diff -Nru matplotlib-1.1.1/doc/contents.rst matplotlib-1.2.0/doc/contents.rst --- matplotlib-1.1.1/doc/contents.rst 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/contents.rst 2012-10-31 00:11:13.000000000 +0000 @@ -8,7 +8,7 @@ :Release: |version| :Date: |today| - Download `PDF `_ + Download `PDF `_ .. toctree:: diff -Nru matplotlib-1.1.1/doc/devel/add_new_projection.rst matplotlib-1.2.0/doc/devel/add_new_projection.rst --- matplotlib-1.1.1/doc/devel/add_new_projection.rst 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/devel/add_new_projection.rst 2012-10-31 00:11:13.000000000 +0000 @@ -71,8 +71,9 @@ Creating a new projection ========================= -Adding a new projection consists of defining a subclass of -:class:`matplotlib.axes.Axes`, that includes the following elements: +Adding a new projection consists of defining a projection axes which +subclasses :class:`matplotlib.axes.Axes` and includes the following +elements: - A transformation from data coordinates into display coordinates. @@ -101,8 +102,25 @@ - Any additional methods for additional convenience or features. -Once the class is defined, it must be registered with matplotlib -so that the user can select it. +Once the projection axes is defined, it can be used in one of two ways: + + - By defining the class attribute ``name``, the projection axes can be + registered with :func:`matplotlib.projections.register_projection` + and subsequently simply invoked by name:: + + plt.axes(projection='my_proj_name') + + - For more complex, parameterisable projections, a generic "projection" + object may be defined which includes the method ``_as_mpl_axes``. + ``_as_mpl_axes`` should take no arguments and return the projection's + axes subclass and a dictionary of additional arguments to pass to the + subclass' ``__init__`` method. Subsequently a parameterised projection + can be initialised with:: + + plt.axes(projection=MyProjection(param1=param1_value)) + + where MyProjection is an object which implements a ``_as_mpl_axes`` method. + A full-fledged and heavily annotated example is in :file:`examples/api/custom_projection_example.py`. The polar plot diff -Nru matplotlib-1.1.1/doc/devel/coding_guide.rst matplotlib-1.2.0/doc/devel/coding_guide.rst --- matplotlib-1.1.1/doc/devel/coding_guide.rst 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/devel/coding_guide.rst 2012-10-31 00:11:13.000000000 +0000 @@ -17,8 +17,7 @@ and consider posting to `matplotlib-devel `_ -* Are your changes python2.4 compatible? We still support 2.4, so - avoid features new to 2.5 +* Are your changes python2.6 compatible? We support python2.6 and later * Can you pass :file:`examples/tests/backend_driver.py`? This is our poor man's unit test. @@ -324,16 +323,16 @@ ================ We have hundreds of examples in subdirectories of -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 -website. Many people find these examples from the website, and do not -have ready access to the file:`examples` directory in which they -reside. Thus any example data that is required for the example should -be added to the `sample_data -`_ git repository. -Then in your example code you can load it into a file handle with:: +: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 website. Many +people find these examples from the website, and do not have ready +access to the file:`examples` directory in which they reside. Thus +any example data that is required for the example should be added to +the `sample_data `_ git +repository. Then in your example code you can load it into a file +handle with:: import matplotlib.cbook as cbook fh = cbook.get_sample_data('mydata.dat') @@ -350,6 +349,15 @@ print 'datafile', datafile +Writing a new pyplot function +============================= +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 ======= @@ -366,11 +374,7 @@ The following software is required to run the tests: - - nose_, version 0.11.1 or later - - - `Python Imaging Library - `_ (to compare image - results) + - nose_, version 1.0 or later - `Ghostscript `_ (to render PDF files) @@ -406,6 +410,9 @@ .. _`nosetest arguments`: http://somethingaboutorange.com/mrl/projects/nose/1.0.0/usage.html +Running tests by any means other than `matplotlib.test()` +does not load the nose "knownfailureif" (Known failing tests) plugin, +causing known-failing tests to fail for real. Writing a simple test --------------------- @@ -502,6 +509,72 @@ the list of default tests, append its name to ``default_test_modules`` in :file:`lib/matplotlib/__init__.py`. +Using tox +--------- + +`Tox `_ is a tool for running tests against multiple +Python environments, including multiple versions of Python (e.g.: 2.6, 2.7, +3.2, etc.) and even different Python implementations altogether (e.g.: CPython, +PyPy, Jython, etc.) + +Testing all 4 versions of Python (2.6, 2.7, 3.1, and 3.2) requires having four +versions of Python installed on your system and on the PATH. Depending on your +operating system, you may want to use your package manager (such as apt-get, +yum or MacPorts) to do this, or use `pythonbrew +`_. + +tox makes it easy to determine if your working copy introduced any regressions +before submitting a pull request. Here's how to use it: + +.. code-block:: bash + + $ pip install tox + $ tox + +You can also run tox on a subset of environments: + +.. code-block:: bash + + $ tox -e py26,py27 + +Tox processes everything serially so it can take a long time to test several +environments. To speed it up, you might try using a new, parallelized version +of tox called ``detox``. Give this a try: + +.. code-block:: bash + + $ pip install -U -i http://pypi.testrun.org detox + $ detox + +Tox is configured using a file called ``tox.ini``. You may need to edit this +file if you want to add new environments to test (e.g.: ``py33``) or if you +want to tweak the dependencies or the way the tests are run. For more info on +the ``tox.ini`` file, see the `Tox Configuration Specification +`_. + +Using Travis CI +--------------- + +`Travis CI `_ is a hosted CI system "in the cloud". + +Travis is configured to receive notifications of new commits to GitHub repos +(via GitHub "service hooks") and to run builds or tests when it sees these new +commits. It looks for a YAML file called ``.travis.yml`` in the root of the +repository to see how to test the project. + +Travis CI is already enabled for the `main matplotlib GitHub repository +`_ -- for example, see `its Travis +page `_. + +If you want to enable Travis CI for your personal matplotlib GitHub repo, +simply enable the repo to use Travis CI in either the Travis CI UI or the +GitHub UI (Admin | Service Hooks). For details, see `the Travis CI Getting +Started page `_. + +Once this is configured, you can see the Travis CI results at +http://travis-ci.org/#!/your_GitHub_user_name/matplotlib -- here's `an example +`_. + .. _license-discussion: Licenses diff -Nru matplotlib-1.1.1/doc/devel/gitwash/this_project.inc matplotlib-1.2.0/doc/devel/gitwash/this_project.inc --- matplotlib-1.1.1/doc/devel/gitwash/this_project.inc 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/devel/gitwash/this_project.inc 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,5 @@ .. matplotlib -.. _matplotlib: http://matplotlib.sourceforge.net +.. _matplotlib: http://matplotlib.org .. _`matplotlib github`: http://github.com/matplotlib/matplotlib .. _`matplotlib mailing list`: https://lists.sourceforge.net/lists/listinfo/matplotlib-devel diff -Nru matplotlib-1.1.1/doc/devel/release_guide.rst matplotlib-1.2.0/doc/devel/release_guide.rst --- matplotlib-1.1.1/doc/devel/release_guide.rst 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/devel/release_guide.rst 2012-10-31 00:11:13.000000000 +0000 @@ -46,6 +46,20 @@ On the branch, do any additional testing you want to do, and then build binaries and source distributions for testing as release candidates. +For each release candidate as well as for the final release version, +please `git tag` the commit you will use for packaging like so:: + + git tag -a v1.1.0rc1 + +The `-a` flag will allow you to write a message about the tag, and +affiliate your name with it. A reasonable tag message would be something +like ``v1.1.0 Release Candidate 1 (September 24, 2011)``. To tag a +release after the fact, just track down the commit hash, and:: + + git tag -a v1.0.1 a9f3f3a50745 + +Tags allow developers to quickly checkout different releases by name, +and also provides source download via zip and tarball on github. .. _release-packaging: @@ -64,7 +78,7 @@ OSX, the default backend should be TkAgg. You should also turn on or off any platform specific build options you need. Importantly, you also need to make sure that you delete the :file:`build` dir - after any changes to file:`setup.cfg` before rebuilding since cruft + after any changes to :file:`setup.cfg` before rebuilding since cruft in the :file:`build` dir can get carried along. * on windows, unix2dos the rc file @@ -74,66 +88,17 @@ * We have a Makefile for the win32 mingw builds in the mpl source dir :file:`release/win32` which you can use this to prepare the windows - releases, but this is currently broken for python2.6 as described at - http://www.nabble.com/binary-installers-for-python2.6--libpng-segfault%2C-MSVCR90.DLL-and-%09mingw-td23971661.html + releases. .. _release-candidate-testing: -Release candidate testing: -============================ - -Post the release candidates to -http://matplotlib.sf.net/release-candidates and post a message to -matplotlib-users and devel requesting testing. To post to the server, -you can do:: - - > scp somefile.tgz jdh2358,matplotlib@shell.sf.net:/home/groups/m/ma/matplotlib/htdocs/release-candidates/ - -replacing 'jdh2358' with your sourceforge login. - - -Any changes to fix bugs in the release candidate should be fixed in -the release branch and merged into the trunk. - - -.. _release-uploading: - -Uploading -========= - -* Post the win32 and OS-X binaries for testing and make a request on - matplotlib-devel for testing. Pester us if we don't respond - - -* ftp the source and binaries to the anonymous FTP site:: - - mpl> git clean - mpl> python setup.py sdist - mpl> cd dist/ - dist> sftp jdh2358@frs.sourceforge.net - Connecting to frs.sourceforge.net... - sftp> cd uploads - sftp> ls - sftp> lls - matplotlib-0.98.2.tar.gz - sftp> put matplotlib-0.98.2.tar.gz - Uploading matplotlib-0.98.2.tar.gz to /incoming/j/jd/jdh2358/uploads/matplotlib-0.98.2.tar.gz - -* go https://sourceforge.net/project/admin/explorer.php?group_id=80706 and do a - file release. Click on the "Admin" tab to log in as an admin, and - then the "File Releases" tab. Go to the bottom and click "add - release" and enter the package name but not the version number in - the "Package Name" box. You will then be prompted for the "New - release name" at which point you can add the version number, eg - somepackage-0.1 and click "Create this release". - - You will then be taken to a fairly self explanatory page where you - can enter the Change notes, the release notes, and select which - packages from the incoming ftp archive you want to include in this - release. For each binary, you will need to select the platform and - file type, and when you are done you click on the "notify users who - are monitoring this package link" +Release candidate testing +========================= +Post the release candidates tarballs to the `matplotlib download page +`_. If you have +developer rights, you should see an "Upload a new file" section +there. .. _release-announcing: diff -Nru matplotlib-1.1.1/doc/faq/environment_variables_faq.rst matplotlib-1.2.0/doc/faq/environment_variables_faq.rst --- matplotlib-1.1.1/doc/faq/environment_variables_faq.rst 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/faq/environment_variables_faq.rst 2012-10-31 00:11:13.000000000 +0000 @@ -25,7 +25,10 @@ This is the directory used to store user customizations to matplotlib, as well as some caches to improve performance. If :envvar:`MPLCONFIGDIR` is not - defined, :file:`{HOME}/.matplotlib` is used by default. + defined, :file:`{HOME}/.matplotlib` is used if it is writable. + Otherwise, the python standard library :func:`tempfile.gettmpdir` is + used to find a base directory in which the :file:`matplotlib` + subdirectory is created. .. _setting-linux-osx-environment-variables: diff -Nru matplotlib-1.1.1/doc/faq/howto_faq.rst matplotlib-1.2.0/doc/faq/howto_faq.rst --- matplotlib-1.1.1/doc/faq/howto_faq.rst 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/faq/howto_faq.rst 2012-10-31 00:11:13.000000000 +0000 @@ -756,8 +756,9 @@ =============== If you want to refer to matplotlib in a publication, you can use -"Matplotlib: A 2D Graphics Environment" by J. D. Hunter In Computing in Science & -Engineering, Vol. 9, No. 3. (2007), pp. 90-95 (see `citeulike `_):: +"Matplotlib: A 2D Graphics Environment" by J. D. Hunter In Computing +in Science & Engineering, Vol. 9, No. 3. (2007), pp. 90-95 (see `here +`_):: @article{Hunter:2007, Address = {10662 LOS VAQUEROS CIRCLE, PO BOX 3014, LOS ALAMITOS, CA 90720-1314 USA}, diff -Nru matplotlib-1.1.1/doc/faq/installing_faq.rst matplotlib-1.2.0/doc/faq/installing_faq.rst --- matplotlib-1.1.1/doc/faq/installing_faq.rst 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/faq/installing_faq.rst 2012-11-06 22:31:09.000000000 +0000 @@ -209,15 +209,15 @@ setuptools' easy_install. The mkpg installer will have a "zip" extension, and will have a name -like :file:`matplotlib-0.99.0.rc1-py2.5-macosx10.5_mpkg.zip`. +like :file:`matplotlib-1.2.0-py2.7-macosx10.5_mpkg.zip`. The name of the installer depends on which versions of python, matplotlib, and OSX it was built for. You need to unzip this file using either the "unzip" command, or simply double clicking on the it. Then when you double-click on the resulting mpkd, which will have a name like -:file:`matplotlib-0.99.0.rc1-py2.5-macosx10.5.mpkg`, it will run the +:file:`matplotlib-1.2.0-py2.7-macosx10.5.mpkg`, it will run the Installer.app, prompt you for a password if you need system-wide installation privileges, and install to a directory like -:file:`/Library/Python/2.5/site-packages/` (exact path depends on your +:file:`/Library/Python/2.7/site-packages/` (exact path depends on your python version). This directory may not be in your python 'path' variable, so you should test your installation with:: @@ -231,7 +231,7 @@ then you will need to set your PYTHONPATH, eg:: - export PYTHONPATH=/Library/Python/2.5/site-packages:$PYTHONPATH + export PYTHONPATH=/Library/Python/2.7/site-packages:$PYTHONPATH See also ref:`environment-variables`. @@ -248,40 +248,14 @@ > easy_install matplotlib -which should grab the latest egg from the sourceforge site, but sometimes -the naming conventions for OSX eggs can be broken (see below). -Therefore, there is no guarantee the right egg will be found. We recommend -you download the latest egg from our `download site -`_ directly to your +which should grab the latest egg from github, but sometimes the naming +conventions for OSX eggs can be broken (see below). Therefore, there +is no guarantee the right egg will be found. We recommend you download +the latest egg from our `download site +`_ directly to your harddrive, and manually install it, eg:: - > easy_install --install-dir=~/dev/lib/python2.5/site-packages/ matplotlib-0.99.0.rc1-py2.5-macosx-10.5-i386.egg - -Naming convention issues -^^^^^^^^^^^^^^^^^^^^^^^^ -.. note:: - This should no longer be an issue. If it is, please - report it to the mailing list. - -Some users have reported problems with the egg for 0.98 from the -matplotlib download site, with ``easy_install``, getting an error:: - - > easy_install ./matplotlib-0.98.0-py2.5-macosx-10.3-fat.egg - Processing matplotlib-0.98.0-py2.5-macosx-10.3-fat.egg - removing '/Library/Python/2.5/site-packages/matplotlib-0.98.0-py2.5- - ...snip... - Reading http://matplotlib.sourceforge.net - Reading http://cheeseshop.python.org/pypi/matplotlib/0.91.3 - No local packages or download links found for matplotlib==0.98.0 - error: Could not find suitable distribution for - Requirement.parse('matplotlib==0.98.0') - -If you rename ``matplotlib-0.98.0-py2.5-macosx-10.3-fat.egg`` to -``matplotlib-0.98.0-py2.5.egg``, ``easy_install`` will install it from -the disk. Many Mac OS X eggs have cruft at the end of the filename, -which prevents their installation through easy_install. Renaming is -all it takes to install them; still, it's annoying. - + > easy_install --install-dir=~/path/to/site-packages/ matplotlib-1.2.0-py2.7-macosx-10.5-i386.egg .. _install_from_source_on_osx_epd: @@ -349,13 +323,11 @@ If you have already installed python, you can use one of the matplotlib binary installers for windows -- you can get these from the -`sourceforge download -`_ -site. Choose the files that match your version of python (eg -``py2.5`` if you installed Python 2.5) which have the ``exe`` -extension. If you haven't already installed python, you can get the -official version from the `python web site -`_. +`download `_ site. +Choose the files that match your version of python (eg ``py2.7`` if +you installed Python 2.7) which have the ``exe`` extension. If you +haven't already installed python, you can get the official version +from the `python web site `_. There are also two packaged distributions of python that come preloaded with matplotlib and many other tools like ipython, numpy, diff -Nru matplotlib-1.1.1/doc/faq/troubleshooting_faq.rst matplotlib-1.2.0/doc/faq/troubleshooting_faq.rst --- matplotlib-1.1.1/doc/faq/troubleshooting_faq.rst 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/faq/troubleshooting_faq.rst 2012-11-06 15:42:20.000000000 +0000 @@ -62,14 +62,22 @@ .. _reporting-problems: -Report a problem -================ +Getting help +============ -If you are having a problem with matplotlib, search the mailing -lists first: there's a good chance someone else has already run into -your problem. +There are a number of good resources for getting help with matplotlib. +There is a good chance your question has already been asked: -If not, please provide the following information in your e-mail to the + - The `mailing list + `_. + + - `Github issues `_. + + - Stackoverflow questions tagged `matplotlib +`_. + +If you are unable to find an answer to your question through search, +please provide the following information in your e-mail to the `mailing list `_: diff -Nru matplotlib-1.1.1/doc/faq/usage_faq.rst matplotlib-1.2.0/doc/faq/usage_faq.rst --- matplotlib-1.1.1/doc/faq/usage_faq.rst 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/faq/usage_faq.rst 2012-11-08 16:38:03.000000000 +0000 @@ -253,17 +253,21 @@ ============ ================================================================ Backend Description ============ ================================================================ -GTKAgg Agg rendering to a :term:`GTK` canvas (requires PyGTK_) -GTK GDK rendering to a :term:`GTK` canvas (not recommended) +GTKAgg Agg rendering to a :term:`GTK` 2.x canvas (requires PyGTK_) +GTK3Agg Agg rendering to a :term:`GTK` 3.x canvas (requires PyGObject_) +GTK GDK rendering to a :term:`GTK` 2.x canvas (not recommended) (requires PyGTK_) -GTKCairo Cairo rendering to a :term:`GTK` Canvas (requires PyGTK_) +GTKCairo Cairo rendering to a :term:`GTK` 2.x canvas (requires PyGTK_ + and pycairo_) +GTK3Cairo Cairo rendering to a :term:`GTK` 3.x canvas (requires PyGObject_ + and pycairo_) WXAgg Agg rendering to to a :term:`wxWidgets` canvas (requires wxPython_) WX Native :term:`wxWidgets` drawing to a :term:`wxWidgets` Canvas (not recommended) (requires wxPython_) TkAgg Agg rendering to a :term:`Tk` canvas (requires TkInter_) QtAgg Agg rendering to a :term:`Qt` canvas (requires PyQt_) - (not recommended; use Qt4Agg) + (deprecated; use Qt4Agg) Qt4Agg Agg rendering to a :term:`Qt4` canvas (requires PyQt4_) FLTKAgg Agg rendering to a :term:`FLTK` canvas (requires pyFLTK_) (not widely used; consider TKAgg, GTKAgg, WXAgg, or @@ -280,6 +284,8 @@ .. _`Cairo graphics`: http://en.wikipedia.org/wiki/Cairo_(graphics) .. _`Gimp Drawing Kit`: http://en.wikipedia.org/wiki/GDK .. _PyGTK: http://www.pygtk.org +.. _PyGObject: https://live.gnome.org/PyGObject +.. _pycairo: http://www.cairographics.org/pycairo/ .. _wxPython: http://www.wxpython.org/ .. _TkInter: http://wiki.python.org/moin/TkInter .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/intro @@ -320,6 +326,11 @@ Interactive mode may also be turned on via :func:`matplotlib.pyplot.ion`, and turned off via :func:`matplotlib.pyplot.ioff`. +.. note:: + Interactive mode works with suitable backends in ipython and in + the ordinary python shell, but it does *not* work in the IDLE IDE. + + Interactive example -------------------- @@ -420,6 +431,3 @@ or generating a new set of figures. In that case, use :func:`~matplotlib.pyplot.show` to display the figure(s) and to block execution until you have manually destroyed them. - - - diff -Nru matplotlib-1.1.1/doc/make.py matplotlib-1.2.0/doc/make.py --- matplotlib-1.1.1/doc/make.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/make.py 2012-11-08 02:24:13.000000000 +0000 @@ -1,4 +1,6 @@ #!/usr/bin/env python + +from __future__ import print_function import fileinput import glob import os @@ -112,24 +114,18 @@ def check_build(): build_dirs = ['build', 'build/doctrees', 'build/html', 'build/latex', - '_static', '_templates'] + 'build/texinfo', '_static', '_templates'] for d in build_dirs: try: os.mkdir(d) except OSError: pass -def sf(): - 'push a copy to the sf site' - shutil.copy('../CHANGELOG', 'build/html/_static/CHANGELOG') - os.system('cd build/html; rsync -avz . jdh2358,matplotlib@web.sf.net:/home/groups/m/ma/matplotlib/htdocs/ -essh --cvs-exclude') - -def sfpdf(): - 'push a copy to the sf site' - os.system('cd build/latex; scp Matplotlib.pdf jdh2358,matplotlib@web.sf.net:/home/groups/m/ma/matplotlib/htdocs/') +def doctest(): + os.system('sphinx-build -b doctest -d build/doctrees . build/doctest') -def figs(): - os.system('cd users/figures/ && python make.py') +def linkcheck(): + os.system('sphinx-build -b linkcheck -d build/doctrees . build/linkcheck') def html(): check_build() @@ -152,6 +148,8 @@ for filename in glob.glob('build/html/_images/*.pdf'): os.remove(filename) + shutil.copy('../CHANGELOG', 'build/html/_static/CHANGELOG') + def latex(): check_build() #figs() @@ -169,7 +167,27 @@ os.chdir('../..') else: - print 'latex build has not been tested on windows' + print('latex build has not been tested on windows') + +def texinfo(): + check_build() + #figs() + if sys.platform != 'win32': + # Texinfo format. + if os.system( + 'sphinx-build -b texinfo -d build/doctrees . build/texinfo'): + raise SystemExit("Building Texinfo failed.") + + # Produce info file. + os.chdir('build/texinfo') + + # Call the makefile produced by sphinx... + if os.system('make'): + raise SystemExit("Rendering Texinfo failed.") + + os.chdir('../..') + else: + print('texinfo build has not been tested on windows') def clean(): shutil.rmtree("build", ignore_errors=True) @@ -193,13 +211,13 @@ funcd = { - 'figs' : figs, 'html' : html, 'latex' : latex, + 'texinfo' : texinfo, 'clean' : clean, - 'sf' : sf, - 'sfpdf' : sfpdf, 'all' : all, + 'doctest' : doctest, + 'linkcheck': linkcheck, } diff -Nru matplotlib-1.1.1/doc/mpl_examples/animation/basic_example.py matplotlib-1.2.0/doc/mpl_examples/animation/basic_example.py --- matplotlib-1.1.1/doc/mpl_examples/animation/basic_example.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/animation/basic_example.py 2012-10-31 00:11:13.000000000 +0000 @@ -29,6 +29,6 @@ im_ani = animation.ArtistAnimation(fig2, ims, interval=50, repeat_delay=3000, blit=True) -#im_ani.save('im.mp4') +#im_ani.save('im.mp4', metadata={'artist':'Guido'}) plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/animation/basic_example_writer.py matplotlib-1.2.0/doc/mpl_examples/animation/basic_example_writer.py --- matplotlib-1.1.1/doc/mpl_examples/animation/basic_example_writer.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/animation/basic_example_writer.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,42 @@ +# Same as basic_example, but writes files using a single MovieWriter instance +# without putting on screen +# -*- noplot -*- +import numpy as np +import matplotlib +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import matplotlib.animation as animation + +def update_line(num, data, line): + line.set_data(data[...,:num]) + return line, + +# Set up formatting for the movie files +Writer = animation.writers['ffmpeg'] +writer = Writer(fps=15, metadata=dict(artist='Me'), bitrate=1800) + + +fig1 = plt.figure() + +data = np.random.rand(2, 25) +l, = plt.plot([], [], 'r-') +plt.xlim(0, 1) +plt.ylim(0, 1) +plt.xlabel('x') +plt.title('test') +line_ani = animation.FuncAnimation(fig1, update_line, 25, fargs=(data, l), + interval=50, blit=True) +line_ani.save('lines.mp4', writer=writer) + +fig2 = plt.figure() + +x = np.arange(-9, 10) +y = np.arange(-9, 10).reshape(-1, 1) +base = np.hypot(x, y) +ims = [] +for add in np.arange(15): + ims.append((plt.pcolor(x, y, base + add, norm=plt.Normalize(0, 30)),)) + +im_ani = animation.ArtistAnimation(fig2, ims, interval=50, repeat_delay=3000, + blit=True) +im_ani.save('im.mp4', writer=writer) diff -Nru matplotlib-1.1.1/doc/mpl_examples/animation/dynamic_image2.py matplotlib-1.2.0/doc/mpl_examples/animation/dynamic_image2.py --- matplotlib-1.1.1/doc/mpl_examples/animation/dynamic_image2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/animation/dynamic_image2.py 2012-10-31 00:11:13.000000000 +0000 @@ -26,7 +26,7 @@ ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True, repeat_delay=1000) -ani.save('dynamic_images.mp4') +#ani.save('dynamic_images.mp4') plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/animation/moviewriter.py matplotlib-1.2.0/doc/mpl_examples/animation/moviewriter.py --- matplotlib-1.1.1/doc/mpl_examples/animation/moviewriter.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/animation/moviewriter.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,32 @@ +# This example uses a MovieWriter directly to grab individual frames and +# write them to a file. This avoids any event loop integration, but has +# the advantage of working with even the Agg backend. This is not recommended +# for use in an interactive setting. +# -*- noplot -*- + +import numpy as np +import matplotlib +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import matplotlib.animation as manimation + +FFMpegWriter = manimation.writers['ffmpeg'] +metadata = dict(title='Movie Test', artist='Matplotlib', + comment='Movie support!') +writer = FFMpegWriter(fps=15, metadata=metadata) + +fig = plt.figure() +l, = plt.plot([], [], 'k-o') + +plt.xlim(-5, 5) +plt.ylim(-5, 5) + +x0,y0 = 0, 0 + +with writer.saving(fig, "writer_test.mp4", 100): + for i in range(100): + x0 += 0.1 * np.random.randn() + y0 += 0.1 * np.random.randn() + l.set_data(x0, y0) + writer.grab_frame() + diff -Nru matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/animate_decay_tk_blit.py matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/animate_decay_tk_blit.py --- matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/animate_decay_tk_blit.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/animate_decay_tk_blit.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import time, sys import numpy as np import matplotlib.pyplot as plt @@ -44,7 +45,7 @@ if run.cnt==1000: # print the timing info and quit - print 'FPS:' , 1000/(time.time()-tstart) + print('FPS:' , 1000/(time.time()-tstart)) sys.exit() run.cnt += 1 diff -Nru matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/animation_blit_fltk.py matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/animation_blit_fltk.py --- matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/animation_blit_fltk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/animation_blit_fltk.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import sys import fltk import matplotlib @@ -37,7 +38,7 @@ self.cnt+=1 if self.cnt==1000: # print the timing info and quit - print 'FPS:' , 1000/(time.time()-self.tstart) + print('FPS:' , 1000/(time.time()-self.tstart)) sys.exit() return True diff -Nru matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/animation_blit_gtk.py matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/animation_blit_gtk.py --- matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/animation_blit_gtk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/animation_blit_gtk.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import print_function + # For detailed comments on animation and the techniques used here, see # the wiki entry # http://www.scipy.org/wikis/topical_software/MatplotlibAnimation @@ -30,7 +32,7 @@ tstart = time.time() def update_line(*args): - print 'you are here', update_line.cnt + print('you are here', update_line.cnt) if update_line.background is None: update_line.background = canvas.copy_from_bbox(ax.bbox) @@ -46,7 +48,7 @@ if update_line.cnt==1000: # print the timing info and quit - print 'FPS:' , 1000/(time.time()-tstart) + print('FPS:' , 1000/(time.time()-tstart)) gtk.mainquit() raise SystemExit diff -Nru matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/animation_blit_gtk2.py matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/animation_blit_gtk2.py --- matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/animation_blit_gtk2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/animation_blit_gtk2.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import print_function + """ This example utlizes restore_region with optional bbox and xy arguments. The plot is continuously shifted to the left. Instead of @@ -137,7 +139,7 @@ dt = (time.time()-tstart) if dt>15: # print the timing info and quit - print 'FPS:' , self.cnt/dt + print('FPS:' , self.cnt/dt) gtk.main_quit() raise SystemExit diff -Nru matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/animation_blit_qt.py matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/animation_blit_qt.py --- matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/animation_blit_qt.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/animation_blit_qt.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,8 @@ # For detailed comments on animation and the techniqes used here, see # the wiki entry http://www.scipy.org/Cookbook/Matplotlib/Animations +from __future__ import print_function + import os, sys import matplotlib matplotlib.use('QtAgg') # qt3 example @@ -47,7 +49,7 @@ if self.cnt==ITERS: # print the timing info and quit - print 'FPS:' , ITERS/(time.time()-self.tstart) + print('FPS:', ITERS/(time.time()-self.tstart)) sys.exit() else: diff -Nru matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/animation_blit_qt4.py matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/animation_blit_qt4.py --- matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/animation_blit_qt4.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/animation_blit_qt4.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,8 @@ # For detailed comments on animation and the techniqes used here, see # the wiki entry http://www.scipy.org/Cookbook/Matplotlib/Animations +from __future__ import print_function + import os import sys @@ -63,7 +65,7 @@ self.draw() if self.cnt==ITERS: # print the timing info and quit - print 'FPS:' , ITERS/(time.time()-self.tstart) + print('FPS:' , ITERS/(time.time()-self.tstart)) sys.exit() else: self.cnt += 1 diff -Nru matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/animation_blit_tk.py matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/animation_blit_tk.py --- matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/animation_blit_tk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/animation_blit_tk.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,8 @@ # For detailed comments on animation and the techniqes used here, see # the wiki entry http://www.scipy.org/Cookbook/Matplotlib/Animations +from __future__ import print_function + import matplotlib matplotlib.use('TkAgg') @@ -34,7 +36,7 @@ if run.cnt==1000: # print the timing info and quit - print 'FPS:' , 1000/(time.time()-tstart) + print('FPS:', 1000/(time.time()-tstart)) sys.exit() run.cnt += 1 diff -Nru matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/animation_blit_wx.py matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/animation_blit_wx.py --- matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/animation_blit_wx.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/animation_blit_wx.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,6 +2,8 @@ # the wiki entry # http://www.scipy.org/wikis/topical_software/MatplotlibAnimation +from __future__ import print_function + # The number of blits() to make before exiting NBLITS = 1000 @@ -58,11 +60,11 @@ if update_line.cnt == NBLITS: # print the timing info and quit frame_time = time.time() - tstart - print '%d frames: %.2f seconds' % (NBLITS, frame_time) - print '%d blits: %.2f seconds' % (NBLITS, blit_time) - print - print 'FPS: %.2f' % (NBLITS/frame_time) - print 'BPS: %.2f' % (NBLITS/blit_time) + print('%d frames: %.2f seconds' % (NBLITS, frame_time)) + print('%d blits: %.2f seconds' % (NBLITS, blit_time)) + print() + print('FPS: %.2f' % (NBLITS/frame_time)) + print('BPS: %.2f' % (NBLITS/blit_time)) sys.exit() update_line.cnt += 1 diff -Nru matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/dynamic_image_gtkagg.py matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/dynamic_image_gtkagg.py --- matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/dynamic_image_gtkagg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/dynamic_image_gtkagg.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,6 @@ #!/usr/bin/env python + +from __future__ import print_function """ An animated image """ @@ -34,7 +36,7 @@ manager.canvas.draw() cnt += 1 if cnt==50: - print 'FPS', cnt/(time.time() - tstart) + print('FPS', cnt/(time.time() - tstart)) return False return True diff -Nru matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/movie_demo.py matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/movie_demo.py --- matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/movie_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/movie_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -15,6 +15,8 @@ # the script to suit your own needs. # +from __future__ import print_function + import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt # For plotting graphs. @@ -28,9 +30,9 @@ # Python interpreter, and matplotlib. The version of # Mencoder is printed when it is called. # -print 'Executing on', os.uname() -print 'Python version', sys.version -print 'matplotlib version', matplotlib.__version__ +print('Executing on', os.uname()) +print('Python version', sys.version) +print('matplotlib version', matplotlib.__version__) not_found_msg = """ The mencoder command was not found; @@ -42,7 +44,7 @@ try: subprocess.check_call(['mencoder']) except subprocess.CalledProcessError: - print "mencoder command was found" + print("mencoder command was found") pass # mencoder is found, but returns non-zero exit as expected # This is a quick and dirty check; it leaves some spurious output # for the user to puzzle over. @@ -61,7 +63,7 @@ # distributed Gaussian noise at each time step. # -print 'Initializing data set...' # Let the user know what's happening. +print('Initializing data set...') # Let the user know what's happening. # Initialize variables needed to create and store the example data set. numberOfTimeSteps = 100 # Number of frames we want in the movie. @@ -78,7 +80,7 @@ mean = mean + meaninc stddev = stddev + stddevinc -print 'Done.' # Let the user know what's happening. +print('Done.') # Let the user know what's happening. # # Now that we have an example data set (x,y) to work with, we can @@ -113,7 +115,7 @@ # # Let the user know what's happening. # - print 'Wrote file', filename + print('Wrote file', filename) # # Clear the figure to make way for the next image. @@ -147,10 +149,10 @@ #os.spawnvp(os.P_WAIT, 'mencoder', command) -print "\n\nabout to execute:\n%s\n\n" % ' '.join(command) +print("\n\nabout to execute:\n%s\n\n" % ' '.join(command)) subprocess.check_call(command) -print "\n\n The movie was written to 'output.avi'" +print("\n\n The movie was written to 'output.avi'") -print "\n\n You may want to delete *.png now.\n\n" +print("\n\n You may want to delete *.png now.\n\n") diff -Nru matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/simple_anim_gtk.py matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/simple_anim_gtk.py --- matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/simple_anim_gtk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/simple_anim_gtk.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,7 @@ """ A simple example of an animated plot using a gtk backend """ +from __future__ import print_function import time import numpy as np import matplotlib @@ -20,11 +21,11 @@ for i in np.arange(1,200): line.set_ydata(np.sin(x+i/10.0)) # update the data fig.canvas.draw() # redraw the canvas - print 'FPS:' , 200/(time.time()-tstart) + print('FPS:' , 200/(time.time()-tstart)) raise SystemExit import gobject -print 'adding idle' +print('adding idle') gobject.idle_add(animate) -print 'showing' +print('showing') plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/simple_anim_tkagg.py matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/simple_anim_tkagg.py --- matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/simple_anim_tkagg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/simple_anim_tkagg.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,9 @@ #!/usr/bin/env python + """ A simple example of an animated plot in tkagg """ +from __future__ import print_function import time import numpy as np import matplotlib @@ -19,7 +21,7 @@ for i in np.arange(1,200): line.set_ydata(np.sin(x+i/10.0)) # update the data fig.canvas.draw() # redraw the canvas - print 'FPS:' , 200/(time.time()-tstart) + print('FPS:' , 200/(time.time()-tstart)) win = fig.canvas.manager.window fig.canvas.manager.window.after(100, animate) diff -Nru matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/simple_idle_wx.py matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/simple_idle_wx.py --- matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/simple_idle_wx.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/simple_idle_wx.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,7 @@ """ A simple example of an animated plot using a wx backend """ +from __future__ import print_function import time import numpy as np import matplotlib @@ -18,7 +19,7 @@ def update_line(idleevent): if update_line.i==200: return False - print 'animate', update_line.i + print('animate', update_line.i) line.set_ydata(np.sin(t+update_line.i/10.)) fig.canvas.draw_idle() # redraw the canvas update_line.i += 1 diff -Nru matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/simple_timer_wx.py matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/simple_timer_wx.py --- matplotlib-1.1.1/doc/mpl_examples/animation/old_animation/simple_timer_wx.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/animation/old_animation/simple_timer_wx.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function """ A simple example of an animated plot using a wx backend """ @@ -19,7 +20,7 @@ def update_line(event): if update_line.i==200: return False - print 'update', update_line.i + print('update', update_line.i) line.set_ydata(np.sin(t+update_line.i/10.)) fig.canvas.draw() # redraw the canvas update_line.i += 1 diff -Nru matplotlib-1.1.1/doc/mpl_examples/animation/simple_3danim.py matplotlib-1.2.0/doc/mpl_examples/animation/simple_3danim.py --- matplotlib-1.1.1/doc/mpl_examples/animation/simple_3danim.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/animation/simple_3danim.py 2012-10-31 00:11:13.000000000 +0000 @@ -15,7 +15,7 @@ """ lineData = np.empty((dims, length)) lineData[:, 0] = np.random.rand(dims) - for index in xrange(1, length) : + for index in range(1, length) : # scaling the random numbers by 0.1 so # movement is small compared to position. # subtraction by 0.5 is to change the range to [-0.5, 0.5] @@ -37,7 +37,7 @@ ax = p3.Axes3D(fig) # Fifty lines of random 3-D lines -data = [Gen_RandLine(25, 3) for index in xrange(50)] +data = [Gen_RandLine(25, 3) for index in range(50)] # Creating fifty line objects. # NOTE: Can't pass empty arrays into 3d version of plot() diff -Nru matplotlib-1.1.1/doc/mpl_examples/api/README.txt matplotlib-1.2.0/doc/mpl_examples/api/README.txt --- matplotlib-1.1.1/doc/mpl_examples/api/README.txt 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/api/README.txt 2012-10-31 00:11:13.000000000 +0000 @@ -5,23 +5,15 @@ procedural state machine. For robust, production level scripts, or for applications or web application servers, we recommend you use the matplotlib API directly as it gives you the maximum control over your -figures, axes and plottng commands. There are a few documentation -resources for the API +figures, axes and plottng commands. - - the matplotlib artist tutorial : - http://matplotlib.sourceforge.net/pycon/artist_api_tut.pdf - - - the "leftwich tutorial" : - http://matplotlib.sourceforge.net/leftwich_tut.txt - - The example agg_oo.py is the simplest example of using the Agg - backend which is readily ported to other output formats. This - example is a good starting point if your are a web application - developer. Many of the other examples in this directory use - matplotlib.pyplot just to create the figure and show calls, and use - the API for everything else. This is a good solution for production - quality scripts. For full fledged GUI applications, see the - user_interfaces examples. +The example agg_oo.py is the simplest example of using the Agg backend +which is readily ported to other output formats. This example is a +good starting point if your are a web application developer. Many of +the other examples in this directory use matplotlib.pyplot just to +create the figure and show calls, and use the API for everything else. +This is a good solution for production quality scripts. For full +fledged GUI applications, see the user_interfaces examples. Example style guide =================== diff -Nru matplotlib-1.1.1/doc/mpl_examples/api/artist_demo.py matplotlib-1.2.0/doc/mpl_examples/api/artist_demo.py --- matplotlib-1.1.1/doc/mpl_examples/api/artist_demo.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/api/artist_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,17 +1,17 @@ """ Show examples of matplotlib artists -http://matplotlib.sourceforge.net/api/artist_api.html +http://matplotlib.org/api/artist_api.html Several examples of standard matplotlib graphics primitives (artists) are drawn using matplotlib API. Full list of artists and the documentation is available at -http://matplotlib.sourceforge.net/api/artist_api.html +http://matplotlib.org/api/artist_api.html Copyright (c) 2010, Bartosz Telenczuk License: This work is licensed under the BSD. A copy should be included with this source code, and is also available at -http://www.opensource.org/licenses/bsd-license.php +http://www.opensource.org/licenses/bsd-license.php """ @@ -69,7 +69,7 @@ plt.text(pos[0,5], pos[1,5]-0.15, "Arrow", ha="center", family=font, size=14) -# add a path patch +# add a path patch Path = mpath.Path verts = np.array([ (0.158, -0.257), @@ -83,7 +83,7 @@ (0.158, -0.257), ]) verts = verts-verts.mean(0) -codes = [Path.MOVETO, +codes = [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, Path.LINETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, Path.CLOSEPOLY] @@ -95,7 +95,7 @@ # add a fancy box fancybox = mpatches.FancyBboxPatch( - pos[:,7]-np.array([0.025, 0.05]), 0.05, 0.1, + pos[:,7]-np.array([0.025, 0.05]), 0.05, 0.1, boxstyle=mpatches.BoxStyle("Round", pad=0.02)) patches.append(fancybox) plt.text(pos[0,7], pos[1,7]-0.15, "FancyBoxPatch", ha="center", diff -Nru matplotlib-1.1.1/doc/mpl_examples/api/bbox_intersect.py matplotlib-1.2.0/doc/mpl_examples/api/bbox_intersect.py --- matplotlib-1.1.1/doc/mpl_examples/api/bbox_intersect.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/api/bbox_intersect.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,21 +1,19 @@ -from pylab import * import numpy as np +import matplotlib.pyplot as plt from matplotlib.transforms import Bbox from matplotlib.path import Path -from matplotlib.patches import Rectangle -rect = Rectangle((-1, -1), 2, 2, facecolor="#aaaaaa") -gca().add_patch(rect) +rect = plt.Rectangle((-1, -1), 2, 2, facecolor="#aaaaaa") +plt.gca().add_patch(rect) bbox = Bbox.from_bounds(-1, -1, 2, 2) for i in range(12): - vertices = (np.random.random((4, 2)) - 0.5) * 6.0 - vertices = np.ma.masked_array(vertices, [[False, False], [True, True], [False, False], [False, False]]) + vertices = (np.random.random((2, 2)) - 0.5) * 6.0 path = Path(vertices) if path.intersects_bbox(bbox): color = 'r' else: color = 'b' - plot(vertices[:,0], vertices[:,1], color=color) + plt.plot(vertices[:,0], vertices[:,1], color=color) -show() +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/api/clippath_demo.py matplotlib-1.2.0/doc/mpl_examples/api/clippath_demo.py --- matplotlib-1.1.1/doc/mpl_examples/api/clippath_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/api/clippath_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,7 +3,6 @@ """ import numpy as np import matplotlib.pyplot as plt -import matplotlib.path as path import matplotlib.patches as patches diff -Nru matplotlib-1.1.1/doc/mpl_examples/api/collections_demo.py matplotlib-1.2.0/doc/mpl_examples/api/collections_demo.py --- matplotlib-1.1.1/doc/mpl_examples/api/collections_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/api/collections_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -17,31 +17,31 @@ ''' -import matplotlib.pyplot as P -from matplotlib import collections, axes, transforms +import matplotlib.pyplot as plt +from matplotlib import collections, transforms from matplotlib.colors import colorConverter -import numpy as N +import numpy as np nverts = 50 npts = 100 # Make some spirals -r = N.array(range(nverts)) -theta = N.array(range(nverts)) * (2*N.pi)/(nverts-1) -xx = r * N.sin(theta) -yy = r * N.cos(theta) -spiral = zip(xx,yy) +r = np.array(range(nverts)) +theta = np.array(range(nverts)) * (2*np.pi)/(nverts-1) +xx = r * np.sin(theta) +yy = r * np.cos(theta) +spiral = list(zip(xx,yy)) # Make some offsets -rs = N.random.RandomState([12345678]) +rs = np.random.RandomState([12345678]) xo = rs.randn(npts) yo = rs.randn(npts) -xyo = zip(xo, yo) +xyo = list(zip(xo, yo)) # Make a list of colors cycling through the rgbcmyk series. colors = [colorConverter.to_rgba(c) for c in ('r','g','b','c','y','m','k')] -fig = P.figure() +fig = plt.figure() a = fig.add_subplot(2,2,1) col = collections.LineCollection([spiral], offsets=xyo, @@ -88,7 +88,7 @@ a = fig.add_subplot(2,2,3) col = collections.RegularPolyCollection(7, - sizes = N.fabs(xx)*10.0, offsets=xyo, + sizes = np.fabs(xx)*10.0, offsets=xyo, transOffset=a.transData) trans = transforms.Affine2D().scale(fig.dpi/72.0) col.set_transform(trans) # the points to pixels transform @@ -108,13 +108,13 @@ ncurves = 20 offs = (0.1, 0.0) -yy = N.linspace(0, 2*N.pi, nverts) -ym = N.amax(yy) -xx = (0.2 + (ym-yy)/ym)**2 * N.cos(yy-0.4) * 0.5 +yy = np.linspace(0, 2*np.pi, nverts) +ym = np.amax(yy) +xx = (0.2 + (ym-yy)/ym)**2 * np.cos(yy-0.4) * 0.5 segs = [] for i in range(ncurves): xxx = xx + 0.02*rs.randn(nverts) - curve = zip(xxx, yy*100) + curve = list(zip(xxx, yy*100)) segs.append(curve) col = collections.LineCollection(segs, offsets=offs) @@ -128,6 +128,6 @@ a.set_ylim(a.get_ylim()[::-1]) -P.show() +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/api/colorbar_only.py matplotlib-1.2.0/doc/mpl_examples/api/colorbar_only.py --- matplotlib-1.1.1/doc/mpl_examples/api/colorbar_only.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/api/colorbar_only.py 2012-10-31 00:11:13.000000000 +0000 @@ -6,8 +6,9 @@ # Make a figure and axes with dimensions as desired. fig = pyplot.figure(figsize=(8,3)) -ax1 = fig.add_axes([0.05, 0.65, 0.9, 0.15]) -ax2 = fig.add_axes([0.05, 0.25, 0.9, 0.15]) +ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15]) +ax2 = fig.add_axes([0.05, 0.475, 0.9, 0.15]) +ax3 = fig.add_axes([0.05, 0.15, 0.9, 0.15]) # Set the colormap and norm to correspond to the data for which # the colorbar will be used. @@ -47,5 +48,27 @@ orientation='horizontal') cb2.set_label('Discrete intervals, some other units') +# The third example illustrates the use of custom length colorbar +# extensions, used on a colorbar with discrete intervals. +cmap = mpl.colors.ListedColormap([[0., .4, 1.], [0., .8, 1.], + [1., .8, 0.], [1., .4, 0.]]) +cmap.set_over((1., 0., 0.)) +cmap.set_under((0., 0., 1.)) + +bounds = [-1., -.5, 0., .5, 1.] +norm = mpl.colors.BoundaryNorm(bounds, cmap.N) +cb3 = mpl.colorbar.ColorbarBase(ax3, cmap=cmap, + norm=norm, + boundaries=[-10]+bounds+[10], + extend='both', + # Make the length of each extension + # the same as the length of the + # interior colors: + extendfrac='auto', + ticks=bounds, + spacing='uniform', + orientation='horizontal') +cb3.set_label('Custom extension lengths, some other units') + pyplot.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/api/custom_projection_example.py matplotlib-1.2.0/doc/mpl_examples/api/custom_projection_example.py --- matplotlib-1.1.1/doc/mpl_examples/api/custom_projection_example.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/api/custom_projection_example.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,10 @@ +from __future__ import unicode_literals + from matplotlib.axes import Axes -from matplotlib import cbook from matplotlib.patches import Circle from matplotlib.path import Path -from matplotlib.ticker import Formatter, Locator, NullLocator, FixedLocator, NullFormatter -from matplotlib.transforms import Affine2D, Affine2DBase, Bbox, \ - BboxTransformTo, IdentityTransform, Transform, TransformWrapper +from matplotlib.ticker import NullLocator, Formatter, FixedLocator +from matplotlib.transforms import Affine2D, BboxTransformTo, Transform from matplotlib.projections import register_projection import matplotlib.spines as mspines import matplotlib.axis as maxis @@ -280,7 +280,7 @@ else: ew = 'W' # \u00b0 : degree symbol - return u'%f\u00b0%s, %f\u00b0%s' % (abs(lat), ns, abs(long), ew) + return '%f\u00b0%s, %f\u00b0%s' % (abs(lat), ns, abs(long), ew) class DegreeFormatter(Formatter): """ @@ -294,7 +294,7 @@ degrees = (x / np.pi) * 180.0 degrees = round(degrees / self._round_to) * self._round_to # \u00b0 : degree symbol - return u"%d\u00b0" % degrees + return "%d\u00b0" % degrees def set_longitude_grid(self, degrees): """ @@ -308,7 +308,7 @@ # by degrees. number = (360.0 / degrees) + 1 self.xaxis.set_major_locator( - FixedLocator( + plt.FixedLocator( np.linspace(-np.pi, np.pi, number, True)[1:-1])) # Set the formatter to display the tick labels in degrees, # rather than radians. @@ -446,11 +446,12 @@ # it. register_projection(HammerAxes) -# Now make a simple example using the custom projection. -from pylab import * +if __name__ == '__main__': + import matplotlib.pyplot as plt + # Now make a simple example using the custom projection. + plt.subplot(111, projection="custom_hammer") + p = plt.plot([-1, 1, 1], [-1, -1, 1], "o-") + plt.grid(True) -subplot(111, projection="custom_hammer") -p = plot([-1, 1, 1], [-1, -1, 1], "o-") -grid(True) + plt.show() -show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/api/custom_scale_example.py matplotlib-1.2.0/doc/mpl_examples/api/custom_scale_example.py --- matplotlib-1.1.1/doc/mpl_examples/api/custom_scale_example.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/api/custom_scale_example.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,11 @@ +from __future__ import unicode_literals + +import numpy as np +from numpy import ma from matplotlib import scale as mscale from matplotlib import transforms as mtransforms +from matplotlib.ticker import Formatter, FixedLocator + class MercatorLatitudeScale(mscale.ScaleBase): """ @@ -67,7 +73,7 @@ class DegreeFormatter(Formatter): def __call__(self, x, pos=None): # \u00b0 : degree symbol - return u"%d\u00b0" % ((x / np.pi) * 180.0) + return "%d\u00b0" % ((x / np.pi) * 180.0) deg2rad = np.pi / 180.0 axis.set_major_locator(FixedLocator( @@ -148,18 +154,20 @@ # that ``matplotlib`` can find it. mscale.register_scale(MercatorLatitudeScale) -from pylab import * -import numpy as np -t = arange(-180.0, 180.0, 0.1) -s = t / 360.0 * np.pi +if __name__ == '__main__': + import matplotlib.pyplot as plt + + t = np.arange(-180.0, 180.0, 0.1) + s = t / 360.0 * np.pi + + plt.plot(t, s, '-', lw=2) + plt.gca().set_yscale('mercator') -plot(t, s, '-', lw=2) -gca().set_yscale('mercator') + plt.xlabel('Longitude') + plt.ylabel('Latitude') + plt.title('Mercator: Projection of the Oppressor') + plt.grid(True) -xlabel('Longitude') -ylabel('Latitude') -title('Mercator: Projection of the Oppressor') -grid(True) + plt.show() -show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/api/date_demo.py matplotlib-1.2.0/doc/mpl_examples/api/date_demo.py --- matplotlib-1.1.1/doc/mpl_examples/api/date_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/api/date_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -13,10 +13,8 @@ """ import datetime import numpy as np -import matplotlib import matplotlib.pyplot as plt import matplotlib.dates as mdates -import matplotlib.mlab as mlab import matplotlib.cbook as cbook years = mdates.YearLocator() # every year diff -Nru matplotlib-1.1.1/doc/mpl_examples/api/date_index_formatter.py matplotlib-1.2.0/doc/mpl_examples/api/date_index_formatter.py --- matplotlib-1.1.1/doc/mpl_examples/api/date_index_formatter.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/api/date_index_formatter.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,6 +3,7 @@ to leave out days on which there is no data, eh weekends. The example below shows how to use an 'index formatter' to achieve the desired plot """ +from __future__ import print_function import numpy as np import matplotlib.pyplot as plt import matplotlib.mlab as mlab @@ -10,7 +11,7 @@ import matplotlib.ticker as ticker datafile = cbook.get_sample_data('aapl.csv', asfileobj=False) -print 'loading', datafile +print ('loading %s' % datafile) r = mlab.csv2rec(datafile) r.sort() diff -Nru matplotlib-1.1.1/doc/mpl_examples/api/fahrenheit_celcius_scales.py matplotlib-1.2.0/doc/mpl_examples/api/fahrenheit_celcius_scales.py --- matplotlib-1.1.1/doc/mpl_examples/api/fahrenheit_celcius_scales.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/api/fahrenheit_celcius_scales.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -""" -Shoiw how to display two scales on the left and right y axis -- Fahrenheit and Celcius -""" - -import matplotlib.pyplot as plt - -fig = plt.figure() -ax1 = fig.add_subplot(111) # the Fahrenheit scale -ax2 = ax1.twinx() # the Celcius scale - -def Tc(Tf): - return (5./9.)*(Tf-32) - - -def update_ax2(ax1): - y1, y2 = ax1.get_ylim() - ax2.set_ylim(Tc(y1), Tc(y2)) - ax2.figure.canvas.draw() - -# automatically update ylim of ax2 when ylim of ax1 changes. -ax1.callbacks.connect("ylim_changed", update_ax2) -ax1.plot([78, 79, 79, 77]) - -ax1.set_title('Two scales: Fahrenheit and Celcius') -ax1.set_ylabel('Fahrenheit') -ax2.set_ylabel('Celcius') - -plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/api/fahrenheit_celsius_scales.py matplotlib-1.2.0/doc/mpl_examples/api/fahrenheit_celsius_scales.py --- matplotlib-1.1.1/doc/mpl_examples/api/fahrenheit_celsius_scales.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/api/fahrenheit_celsius_scales.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,28 @@ +""" +Show how to display two scales on the left and right y axis -- Fahrenheit and Celsius +""" + +import matplotlib.pyplot as plt + +fig = plt.figure() +ax1 = fig.add_subplot(111) # the Fahrenheit scale +ax2 = ax1.twinx() # the Celsius scale + +def Tc(Tf): + return (5./9.)*(Tf-32) + + +def update_ax2(ax1): + y1, y2 = ax1.get_ylim() + ax2.set_ylim(Tc(y1), Tc(y2)) + ax2.figure.canvas.draw() + +# automatically update ylim of ax2 when ylim of ax1 changes. +ax1.callbacks.connect("ylim_changed", update_ax2) +ax1.plot([78, 79, 79, 77]) + +ax1.set_title('Two scales: Fahrenheit and Celsius') +ax1.set_ylabel('Fahrenheit') +ax2.set_ylabel('Celsius') + +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/api/logo2.py matplotlib-1.2.0/doc/mpl_examples/api/logo2.py --- matplotlib-1.1.1/doc/mpl_examples/api/logo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/api/logo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -6,8 +6,6 @@ import matplotlib as mpl import matplotlib.pyplot as plt import matplotlib.cm as cm -import matplotlib.mlab as mlab -from pylab import rand mpl.rcParams['xtick.labelsize'] = 10 mpl.rcParams['ytick.labelsize'] = 12 diff -Nru matplotlib-1.1.1/doc/mpl_examples/api/patch_collection.py matplotlib-1.2.0/doc/mpl_examples/api/patch_collection.py --- matplotlib-1.1.1/doc/mpl_examples/api/patch_collection.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/api/patch_collection.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,26 +1,28 @@ +import numpy as np import matplotlib from matplotlib.patches import Circle, Wedge, Polygon from matplotlib.collections import PatchCollection -import pylab +import matplotlib.pyplot as plt -fig=pylab.figure() + +fig=plt.figure() ax=fig.add_subplot(111) resolution = 50 # the number of vertices N = 3 -x = pylab.rand(N) -y = pylab.rand(N) -radii = 0.1*pylab.rand(N) +x = np.random.rand(N) +y = np.random.rand(N) +radii = 0.1*np.random.rand(N) patches = [] for x1,y1,r in zip(x, y, radii): circle = Circle((x1,y1), r) patches.append(circle) -x = pylab.rand(N) -y = pylab.rand(N) -radii = 0.1*pylab.rand(N) -theta1 = 360.0*pylab.rand(N) -theta2 = 360.0*pylab.rand(N) +x = np.random.rand(N) +y = np.random.rand(N) +radii = 0.1*np.random.rand(N) +theta1 = 360.0*np.random.rand(N) +theta2 = 360.0*np.random.rand(N) for x1,y1,r,t1,t2 in zip(x, y, radii, theta1, theta2): wedge = Wedge((x1,y1), r, t1, t2) patches.append(wedge) @@ -34,13 +36,13 @@ ] for i in range(N): - polygon = Polygon(pylab.rand(N,2), True) + polygon = Polygon(np.random.rand(N,2), True) patches.append(polygon) -colors = 100*pylab.rand(len(patches)) +colors = 100*np.random.rand(len(patches)) p = PatchCollection(patches, cmap=matplotlib.cm.jet, alpha=0.4) -p.set_array(pylab.array(colors)) +p.set_array(np.array(colors)) ax.add_collection(p) -pylab.colorbar(p) +plt.colorbar(p) -pylab.show() +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/api/radar_chart.py matplotlib-1.2.0/doc/mpl_examples/api/radar_chart.py --- matplotlib-1.1.1/doc/mpl_examples/api/radar_chart.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/api/radar_chart.py 2012-10-31 00:11:13.000000000 +0000 @@ -46,7 +46,7 @@ patch_dict = {'polygon': draw_poly_patch, 'circle': draw_circle_patch} if frame not in patch_dict: - raise ValueError, 'unknown value for `frame`: %s' % frame + raise ValueError('unknown value for `frame`: %s' % frame) class RadarAxes(PolarAxes): @@ -133,7 +133,8 @@ # 4)Inclusion of both gas-phase speciesis present... data = { 'column names': - ['Sulfate', 'Nitrate', 'EC', 'OC1', 'OC2', 'OC3', 'OP', 'CO', 'O3'], + ['Sulfate', 'Nitrate', 'EC', 'OC1', 'OC2', 'OC3', 'OP', 'CO', + 'O3'], 'Basecase': [[0.88, 0.01, 0.03, 0.03, 0.00, 0.06, 0.01, 0.00, 0.00], [0.07, 0.95, 0.04, 0.05, 0.00, 0.02, 0.01, 0.00, 0.00], @@ -157,8 +158,7 @@ [0.09, 0.95, 0.02, 0.03, 0.00, 0.01, 0.13, 0.06, 0.00], [0.01, 0.02, 0.71, 0.24, 0.13, 0.16, 0.00, 0.50, 0.00], [0.01, 0.03, 0.00, 0.28, 0.24, 0.23, 0.00, 0.44, 0.88], - [0.02, 0.00, 0.18, 0.45, 0.64, 0.55, 0.86, 0.00, 0.16]] - } + [0.02, 0.00, 0.18, 0.45, 0.64, 0.55, 0.86, 0.00, 0.16]]} return data @@ -185,12 +185,11 @@ ax.set_varlabels(spoke_labels) # add legend relative to top-left plot - plt.subplot(2,2,1) + plt.subplot(2, 2, 1) labels = ('Factor 1', 'Factor 2', 'Factor 3', 'Factor 4', 'Factor 5') legend = plt.legend(labels, loc=(0.9, .95), labelspacing=0.1) plt.setp(legend.get_texts(), fontsize='small') - plt.figtext(0.5, 0.965, '5-Factor Solution Profiles Across Four Scenarios', - ha='center', color='black', weight='bold', size='large') + plt.figtext(0.5, 0.965, '5-Factor Solution Profiles Across Four Scenarios', + ha='center', color='black', weight='bold', size='large') plt.show() - diff -Nru matplotlib-1.1.1/doc/mpl_examples/api/sankey_demo_links.py matplotlib-1.2.0/doc/mpl_examples/api/sankey_demo_links.py --- matplotlib-1.1.1/doc/mpl_examples/api/sankey_demo_links.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/api/sankey_demo_links.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,31 +1,35 @@ """Demonstrate/test the Sankey class by producing a long chain of connections. """ -import numpy as np -import matplotlib.pyplot as plt -from matplotlib.sankey import Sankey from itertools import cycle +import matplotlib.pyplot as plt +from matplotlib.sankey import Sankey + links_per_side = 6 + + def side(sankey, n=1): - """Generate a side chain. - """ + """Generate a side chain.""" prior = len(sankey.diagrams) colors = cycle(['orange', 'b', 'g', 'r', 'c', 'm', 'y']) for i in range(0, 2*n, 2): sankey.add(flows=[1, -1], orientations=[-1, -1], - patchlabel=str(prior+i), facecolor=colors.next(), + patchlabel=str(prior+i), facecolor=next(colors), prior=prior+i-1, connect=(1, 0), alpha=0.5) sankey.add(flows=[1, -1], orientations=[1, 1], - patchlabel=str(prior+i+1), facecolor=colors.next(), + patchlabel=str(prior+i+1), facecolor=next(colors), prior=prior+i, connect=(1, 0), alpha=0.5) + + def corner(sankey): - """Generate a corner link. - """ + """Generate a corner link.""" prior = len(sankey.diagrams) sankey.add(flows=[1, -1], orientations=[0, 1], patchlabel=str(prior), facecolor='k', prior=prior-1, connect=(1, 0), alpha=0.5) + + fig = plt.figure() ax = fig.add_subplot(1, 1, 1, xticks=[], yticks=[], title="Why would you want to do this?\n(But you could.)") diff -Nru matplotlib-1.1.1/doc/mpl_examples/api/sankey_demo_old.py matplotlib-1.2.0/doc/mpl_examples/api/sankey_demo_old.py --- matplotlib-1.1.1/doc/mpl_examples/api/sankey_demo_old.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/api/sankey_demo_old.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,12 @@ #!/usr/bin/env python +from __future__ import print_function + __author__ = "Yannick Copin " __version__ = "Time-stamp: <10/02/2010 16:49 ycopin@lyopc548.in2p3.fr>" -import numpy as N +import numpy as np + def sankey(ax, outputs=[100.], outlabels=None, @@ -11,143 +14,142 @@ dx=40, dy=10, outangle=45, w=3, inangle=30, offset=2, **kwargs): """Draw a Sankey diagram. -outputs: array of outputs, should sum up to 100% -outlabels: output labels (same length as outputs), -or None (use default labels) or '' (no labels) -inputs and inlabels: similar for inputs -dx: horizontal elongation -dy: vertical elongation -outangle: output arrow angle [deg] -w: output arrow shoulder -inangle: input dip angle -offset: text offset -**kwargs: propagated to Patch (e.g. fill=False) - -Return (patch,[intexts,outtexts]).""" + outputs: array of outputs, should sum up to 100% + outlabels: output labels (same length as outputs), + or None (use default labels) or '' (no labels) + inputs and inlabels: similar for inputs + dx: horizontal elongation + dy: vertical elongation + outangle: output arrow angle [deg] + w: output arrow shoulder + inangle: input dip angle + offset: text offset + **kwargs: propagated to Patch (e.g. fill=False) + Return (patch,[intexts,outtexts]). + """ import matplotlib.patches as mpatches from matplotlib.path import Path - outs = N.absolute(outputs) - outsigns = N.sign(outputs) - outsigns[-1] = 0 # Last output - - ins = N.absolute(inputs) - insigns = N.sign(inputs) - insigns[0] = 0 # First input + outs = np.absolute(outputs) + outsigns = np.sign(outputs) + outsigns[-1] = 0 # Last output + + ins = np.absolute(inputs) + insigns = np.sign(inputs) + insigns[0] = 0 # First input - assert sum(outs)==100, "Outputs don't sum up to 100%" - assert sum(ins)==100, "Inputs don't sum up to 100%" + assert sum(outs) == 100, "Outputs don't sum up to 100%" + assert sum(ins) == 100, "Inputs don't sum up to 100%" def add_output(path, loss, sign=1): - h = (loss/2+w)*N.tan(outangle/180.*N.pi) # Arrow tip height - move,(x,y) = path[-1] # Use last point as reference - if sign==0: # Final loss (horizontal) - path.extend([(Path.LINETO,[x+dx,y]), - (Path.LINETO,[x+dx,y+w]), - (Path.LINETO,[x+dx+h,y-loss/2]), # Tip - (Path.LINETO,[x+dx,y-loss-w]), - (Path.LINETO,[x+dx,y-loss])]) - outtips.append((sign,path[-3][1])) - else: # Intermediate loss (vertical) - path.extend([(Path.CURVE4,[x+dx/2,y]), - (Path.CURVE4,[x+dx,y]), - (Path.CURVE4,[x+dx,y+sign*dy]), - (Path.LINETO,[x+dx-w,y+sign*dy]), - (Path.LINETO,[x+dx+loss/2,y+sign*(dy+h)]), # Tip - (Path.LINETO,[x+dx+loss+w,y+sign*dy]), - (Path.LINETO,[x+dx+loss,y+sign*dy]), - (Path.CURVE3,[x+dx+loss,y-sign*loss]), - (Path.CURVE3,[x+dx/2+loss,y-sign*loss])]) - outtips.append((sign,path[-5][1])) + h = (loss/2 + w)*np.tan(outangle/180. * np.pi) # Arrow tip height + move, (x, y) = path[-1] # Use last point as reference + if sign == 0: # Final loss (horizontal) + path.extend([(Path.LINETO, [x+dx, y]), + (Path.LINETO, [x+dx, y+w]), + (Path.LINETO, [x+dx+h, y-loss/2]), # Tip + (Path.LINETO, [x+dx, y-loss-w]), + (Path.LINETO, [x+dx, y-loss])]) + outtips.append((sign, path[-3][1])) + else: # Intermediate loss (vertical) + path.extend([(Path.CURVE4, [x+dx/2, y]), + (Path.CURVE4, [x+dx, y]), + (Path.CURVE4, [x+dx, y+sign*dy]), + (Path.LINETO, [x+dx-w, y+sign*dy]), + (Path.LINETO, [x+dx+loss/2, y+sign*(dy+h)]), # Tip + (Path.LINETO, [x+dx+loss+w, y+sign*dy]), + (Path.LINETO, [x+dx+loss, y+sign*dy]), + (Path.CURVE3, [x+dx+loss, y-sign*loss]), + (Path.CURVE3, [x+dx/2+loss, y-sign*loss])]) + outtips.append((sign, path[-5][1])) def add_input(path, gain, sign=1): - h = (gain/2)*N.tan(inangle/180.*N.pi) # Dip depth - move,(x,y) = path[-1] # Use last point as reference - if sign==0: # First gain (horizontal) - path.extend([(Path.LINETO,[x-dx,y]), - (Path.LINETO,[x-dx+h,y+gain/2]), # Dip - (Path.LINETO,[x-dx,y+gain])]) - xd,yd = path[-2][1] # Dip position - indips.append((sign,[xd-h,yd])) - else: # Intermediate gain (vertical) - path.extend([(Path.CURVE4,[x-dx/2,y]), - (Path.CURVE4,[x-dx,y]), - (Path.CURVE4,[x-dx,y+sign*dy]), - (Path.LINETO,[x-dx-gain/2,y+sign*(dy-h)]), # Dip - (Path.LINETO,[x-dx-gain,y+sign*dy]), - (Path.CURVE3,[x-dx-gain,y-sign*gain]), - (Path.CURVE3,[x-dx/2-gain,y-sign*gain])]) - xd,yd = path[-4][1] # Dip position - indips.append((sign,[xd,yd+sign*h])) - - outtips = [] # Output arrow tip dir. and positions - urpath = [(Path.MOVETO,[0,100])] # 1st point of upper right path - lrpath = [(Path.LINETO,[0,0])] # 1st point of lower right path - for loss,sign in zip(outs,outsigns): + h = (gain/2)*np.tan(inangle/180. * np.pi) # Dip depth + move, (x, y) = path[-1] # Use last point as reference + if sign == 0: # First gain (horizontal) + path.extend([(Path.LINETO, [x-dx, y]), + (Path.LINETO, [x-dx+h, y+gain/2]), # Dip + (Path.LINETO, [x-dx, y+gain])]) + xd, yd = path[-2][1] # Dip position + indips.append((sign, [xd-h, yd])) + else: # Intermediate gain (vertical) + path.extend([(Path.CURVE4, [x-dx/2, y]), + (Path.CURVE4, [x-dx, y]), + (Path.CURVE4, [x-dx, y+sign*dy]), + (Path.LINETO, [x-dx-gain/2, y+sign*(dy-h)]), # Dip + (Path.LINETO, [x-dx-gain, y+sign*dy]), + (Path.CURVE3, [x-dx-gain, y-sign*gain]), + (Path.CURVE3, [x-dx/2-gain, y-sign*gain])]) + xd, yd = path[-4][1] # Dip position + indips.append((sign, [xd, yd+sign*h])) + + outtips = [] # Output arrow tip dir. and positions + urpath = [(Path.MOVETO, [0, 100])] # 1st point of upper right path + lrpath = [(Path.LINETO, [0, 0])] # 1st point of lower right path + for loss, sign in zip(outs, outsigns): add_output(sign>=0 and urpath or lrpath, loss, sign=sign) - indips = [] # Input arrow tip dir. and positions - llpath = [(Path.LINETO,[0,0])] # 1st point of lower left path - ulpath = [(Path.MOVETO,[0,100])] # 1st point of upper left path - for gain,sign in zip(ins,insigns)[::-1]: + indips = [] # Input arrow tip dir. and positions + llpath = [(Path.LINETO, [0, 0])] # 1st point of lower left path + ulpath = [(Path.MOVETO, [0, 100])] # 1st point of upper left path + for gain, sign in reversed(list(zip(ins, insigns))): add_input(sign<=0 and llpath or ulpath, gain, sign=sign) def revert(path): """A path is not just revertable by path[::-1] because of Bezier -curves.""" + curves.""" rpath = [] nextmove = Path.LINETO - for move,pos in path[::-1]: - rpath.append((nextmove,pos)) + for move, pos in path[::-1]: + rpath.append((nextmove, pos)) nextmove = move return rpath # Concatenate subpathes in correct order path = urpath + revert(lrpath) + llpath + revert(ulpath) - codes,verts = zip(*path) - verts = N.array(verts) + codes, verts = zip(*path) + verts = np.array(verts) # Path patch - path = Path(verts,codes) + path = Path(verts, codes) patch = mpatches.PathPatch(path, **kwargs) ax.add_patch(patch) - if False: # DEBUG - print "urpath", urpath - print "lrpath", revert(lrpath) - print "llpath", llpath - print "ulpath", revert(ulpath) - - xs,ys = zip(*verts) - ax.plot(xs,ys,'go-') + if False: # DEBUG + print("urpath", urpath) + print("lrpath", revert(lrpath)) + print("llpath", llpath) + print("ulpath", revert(ulpath)) + xs, ys = zip(*verts) + ax.plot(xs, ys, 'go-') # Labels - def set_labels(labels,values): + def set_labels(labels, values): """Set or check labels according to values.""" - if labels=='': # No labels + if labels == '': # No labels return labels - elif labels is None: # Default labels - return [ '%2d%%' % val for val in values ] + elif labels is None: # Default labels + return ['%2d%%' % val for val in values] else: - assert len(labels)==len(values) + assert len(labels) == len(values) return labels - def put_labels(labels,positions,output=True): + def put_labels(labels, positions, output=True): """Put labels to positions.""" texts = [] lbls = output and labels or labels[::-1] - for i,label in enumerate(lbls): - s,(x,y) = positions[i] # Label direction and position - if s==0: - t = ax.text(x+offset,y,label, + for i, label in enumerate(lbls): + s, (x, y) = positions[i] # Label direction and position + if s == 0: + t = ax.text(x+offset, y, label, ha=output and 'left' or 'right', va='center') - elif s>0: - t = ax.text(x,y+offset,label, ha='center', va='bottom') + elif s > 0: + t = ax.text(x, y+offset, label, ha='center', va='bottom') else: - t = ax.text(x,y-offset,label, ha='center', va='top') + t = ax.text(x, y-offset, label, ha='center', va='top') texts.append(t) return texts @@ -158,32 +160,30 @@ intexts = put_labels(inlabels, indips, output=False) # Axes management - ax.set_xlim(verts[:,0].min()-dx, verts[:,0].max()+dx) - ax.set_ylim(verts[:,1].min()-dy, verts[:,1].max()+dy) + ax.set_xlim(verts[:, 0].min()-dx, verts[:, 0].max()+dx) + ax.set_ylim(verts[:, 1].min()-dy, verts[:, 1].max()+dy) ax.set_aspect('equal', adjustable='datalim') - return patch,[intexts,outtexts] + return patch, [intexts, outtexts] + if __name__=='__main__': - import matplotlib.pyplot as P + import matplotlib.pyplot as plt - outputs = [10.,-20.,5.,15.,-10.,40.] - outlabels = ['First','Second','Third','Fourth','Fifth','Hurray!'] - outlabels = [ s+'\n%d%%' % abs(l) for l,s in zip(outputs,outlabels) ] - - inputs = [60.,-25.,15.] - - fig = P.figure() - ax = fig.add_subplot(1,1,1, xticks=[],yticks=[], - title="Sankey diagram" - ) - - patch,(intexts,outtexts) = sankey(ax, outputs=outputs, outlabels=outlabels, - inputs=inputs, inlabels=None, - fc='g', alpha=0.2) + outputs = [10., -20., 5., 15., -10., 40.] + outlabels = ['First', 'Second', 'Third', 'Fourth', 'Fifth', 'Hurray!'] + outlabels = [s+'\n%d%%' % abs(l) for l, s in zip(outputs, outlabels)] + + inputs = [60., -25., 15.] + + fig = plt.figure() + ax = fig.add_subplot(1, 1, 1, xticks=[], yticks=[], title="Sankey diagram") + + patch, (intexts, outtexts) = sankey(ax, outputs=outputs, + outlabels=outlabels, inputs=inputs, + inlabels=None, fc='g', alpha=0.2) outtexts[1].set_color('r') outtexts[-1].set_fontweight('bold') - P.show() - + plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/api/scatter_piecharts.py matplotlib-1.2.0/doc/mpl_examples/api/scatter_piecharts.py --- matplotlib-1.1.1/doc/mpl_examples/api/scatter_piecharts.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/api/scatter_piecharts.py 2012-10-31 00:11:13.000000000 +0000 @@ -20,16 +20,16 @@ # some points on a circle cos,sin x = [0] + np.cos(np.linspace(0, 2*math.pi*r1, 10)).tolist() y = [0] + np.sin(np.linspace(0, 2*math.pi*r1, 10)).tolist() -xy1 = zip(x,y) +xy1 = list(zip(x,y)) # ... x = [0] + np.cos(np.linspace(2*math.pi*r1, 2*math.pi*r2, 10)).tolist() y = [0] + np.sin(np.linspace(2*math.pi*r1, 2*math.pi*r2, 10)).tolist() -xy2 = zip(x,y) +xy2 = list(zip(x,y)) x = [0] + np.cos(np.linspace(2*math.pi*r2, 2*math.pi, 10)).tolist() y = [0] + np.sin(np.linspace(2*math.pi*r2, 2*math.pi, 10)).tolist() -xy3 = zip(x,y) +xy3 = list(zip(x,y)) fig = plt.figure() diff -Nru matplotlib-1.1.1/doc/mpl_examples/api/watermark_image.py matplotlib-1.2.0/doc/mpl_examples/api/watermark_image.py --- matplotlib-1.1.1/doc/mpl_examples/api/watermark_image.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/api/watermark_image.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,7 @@ """ Use a PNG file as a watermark """ +from __future__ import print_function import numpy as np import matplotlib import matplotlib.cbook as cbook @@ -8,7 +9,7 @@ import matplotlib.pyplot as plt datafile = cbook.get_sample_data('logo2.png', asfileobj=False) -print 'loading', datafile +print ('loading %s' % datafile) im = image.imread(datafile) im[:,:,-1] = 0.5 # set the alpha channel diff -Nru matplotlib-1.1.1/doc/mpl_examples/axes_grid/demo_edge_colorbar.py matplotlib-1.2.0/doc/mpl_examples/axes_grid/demo_edge_colorbar.py --- matplotlib-1.1.1/doc/mpl_examples/axes_grid/demo_edge_colorbar.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/axes_grid/demo_edge_colorbar.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,89 @@ +import matplotlib.pyplot as plt +from mpl_toolkits.axes_grid1 import AxesGrid + +def get_demo_image(): + import numpy as np + from matplotlib.cbook import get_sample_data + f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False) + z = np.load(f) + # z is a numpy array of 15x15 + return z, (-3,4,-4,3) + + +def demo_bottom_cbar(fig): + """ + A grid of 2x2 images with a colorbar for each column. + """ + grid = AxesGrid(fig, 121, # similar to subplot(132) + nrows_ncols = (2, 2), + axes_pad = 0.10, + share_all=True, + label_mode = "1", + cbar_location = "bottom", + cbar_mode="edge", + cbar_pad = 0.25, + cbar_size = "15%", + direction="column" + ) + + Z, extent = get_demo_image() + cmaps = [plt.get_cmap("autumn"), plt.get_cmap("summer")] + for i in range(4): + im = grid[i].imshow(Z, extent=extent, interpolation="nearest", + cmap=cmaps[i//2]) + if i % 2: + cbar = grid.cbar_axes[i//2].colorbar(im) + + for cax in grid.cbar_axes: + cax.toggle_label(True) + cax.axis[cax.orientation].set_label("Bar") + + # This affects all axes as share_all = True. + grid.axes_llc.set_xticks([-2, 0, 2]) + grid.axes_llc.set_yticks([-2, 0, 2]) + + +def demo_right_cbar(fig): + """ + A grid of 2x2 images. Each row has its own colorbar. + """ + + grid = AxesGrid(F, 122, # similar to subplot(122) + nrows_ncols = (2, 2), + axes_pad = 0.10, + label_mode = "1", + share_all = True, + cbar_location="right", + cbar_mode="edge", + cbar_size="7%", + cbar_pad="2%", + ) + Z, extent = get_demo_image() + cmaps = [plt.get_cmap("spring"), plt.get_cmap("winter")] + for i in range(4): + im = grid[i].imshow(Z, extent=extent, interpolation="nearest", + cmap=cmaps[i//2]) + if i % 2: + grid.cbar_axes[i//2].colorbar(im) + + for cax in grid.cbar_axes: + cax.toggle_label(True) + cax.axis[cax.orientation].set_label('Foo') + + # This affects all axes because we set share_all = True. + grid.axes_llc.set_xticks([-2, 0, 2]) + grid.axes_llc.set_yticks([-2, 0, 2]) + + + +if 1: + F = plt.figure(1, (5.5, 2.5)) + + F.subplots_adjust(left=0.05, right=0.93) + + demo_bottom_cbar(F) + demo_right_cbar(F) + + plt.draw() + plt.show() + diff -Nru matplotlib-1.1.1/doc/mpl_examples/event_handling/close_event.py matplotlib-1.2.0/doc/mpl_examples/event_handling/close_event.py --- matplotlib-1.1.1/doc/mpl_examples/event_handling/close_event.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/event_handling/close_event.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,8 @@ +from __future__ import print_function import matplotlib.pyplot as plt def handle_close(evt): - print 'Closed Figure!' + print('Closed Figure!') fig = plt.figure() fig.canvas.mpl_connect('close_event', handle_close) diff -Nru matplotlib-1.1.1/doc/mpl_examples/event_handling/data_browser.py matplotlib-1.2.0/doc/mpl_examples/event_handling/data_browser.py --- matplotlib-1.1.1/doc/mpl_examples/event_handling/data_browser.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/event_handling/data_browser.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,22 +1,11 @@ import numpy as np -from pylab import figure, show -X = np.random.rand(100, 200) -xs = np.mean(X, axis=1) -ys = np.std(X, axis=1) - -fig = figure() -ax = fig.add_subplot(211) -ax.set_title('click on point to plot time series') -line, = ax.plot(xs, ys, 'o', picker=5) # 5 points tolerance -ax2 = fig.add_subplot(212) - class PointBrowser: """ Click on a point to select and highlight it -- the data that generated the point will be shown in the lower axes. Use the 'n' - and 'p' keys to browse through the next and pervious points + and 'p' keys to browse through the next and previous points """ def __init__(self): self.lastind = 0 @@ -74,9 +63,23 @@ fig.canvas.draw() -browser = PointBrowser() +if __name__ == '__main__': + import matplotlib.pyplot as plt + + X = np.random.rand(100, 200) + xs = np.mean(X, axis=1) + ys = np.std(X, axis=1) + + fig = plt.figure() + ax = fig.add_subplot(211) + ax.set_title('click on point to plot time series') + line, = ax.plot(xs, ys, 'o', picker=5) # 5 points tolerance + ax2 = fig.add_subplot(212) + + browser = PointBrowser() + + fig.canvas.mpl_connect('pick_event', browser.onpick) + fig.canvas.mpl_connect('key_press_event', browser.onpress) -fig.canvas.mpl_connect('pick_event', browser.onpick) -fig.canvas.mpl_connect('key_press_event', browser.onpress) + plt.show() -show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/event_handling/figure_axes_enter_leave.py matplotlib-1.2.0/doc/mpl_examples/event_handling/figure_axes_enter_leave.py --- matplotlib-1.1.1/doc/mpl_examples/event_handling/figure_axes_enter_leave.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/event_handling/figure_axes_enter_leave.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,25 +2,26 @@ Illustrate the figure and axes enter and leave events by changing the frame colors on enter and leave """ +from __future__ import print_function import matplotlib.pyplot as plt def enter_axes(event): - print 'enter_axes', event.inaxes + print('enter_axes', event.inaxes) event.inaxes.patch.set_facecolor('yellow') event.canvas.draw() def leave_axes(event): - print 'leave_axes', event.inaxes + print('leave_axes', event.inaxes) event.inaxes.patch.set_facecolor('white') event.canvas.draw() def enter_figure(event): - print 'enter_figure', event.canvas.figure + print('enter_figure', event.canvas.figure) event.canvas.figure.patch.set_facecolor('red') event.canvas.draw() def leave_figure(event): - print 'leave_figure', event.canvas.figure + print('leave_figure', event.canvas.figure) event.canvas.figure.patch.set_facecolor('grey') event.canvas.draw() diff -Nru matplotlib-1.1.1/doc/mpl_examples/event_handling/idle_and_timeout.py matplotlib-1.2.0/doc/mpl_examples/event_handling/idle_and_timeout.py --- matplotlib-1.1.1/doc/mpl_examples/event_handling/idle_and_timeout.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/event_handling/idle_and_timeout.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function """ Demonstrate/test the idle and timeout API @@ -18,7 +19,7 @@ N = 100 def on_idle(event): on_idle.count +=1 - print 'idle', on_idle.count + print('idle', on_idle.count) line1.set_ydata(np.sin(2*np.pi*t*(N-on_idle.count)/float(N))) event.canvas.draw() # test boolean return removal diff -Nru matplotlib-1.1.1/doc/mpl_examples/event_handling/keypress_demo.py matplotlib-1.2.0/doc/mpl_examples/event_handling/keypress_demo.py --- matplotlib-1.1.1/doc/mpl_examples/event_handling/keypress_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/event_handling/keypress_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,23 +1,26 @@ #!/usr/bin/env python + """ Show how to connect to keypress events """ -import numpy as n -from pylab import figure, show +from __future__ import print_function +import numpy as np +import matplotlib.pyplot as plt + def press(event): - print 'press', event.key + print('press', event.key) if event.key=='x': visible = xl.get_visible() xl.set_visible(not visible) fig.canvas.draw() -fig = figure() +fig = plt.figure() ax = fig.add_subplot(111) fig.canvas.mpl_connect('key_press_event', press) -ax.plot(n.random.rand(12), n.random.rand(12), 'go') +ax.plot(np.random.rand(12), np.random.rand(12), 'go') xl = ax.set_xlabel('easy come, easy go') -show() +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/event_handling/lasso_demo.py matplotlib-1.2.0/doc/mpl_examples/event_handling/lasso_demo.py --- matplotlib-1.1.1/doc/mpl_examples/event_handling/lasso_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/event_handling/lasso_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -4,21 +4,20 @@ selected points This is currently a proof-of-concept implementation (though it is -usable as is). There will be some refinement of the API and the -inside polygon detection routine. +usable as is). There will be some refinement of the API. """ from matplotlib.widgets import Lasso -from matplotlib.nxutils import points_inside_poly from matplotlib.colors import colorConverter from matplotlib.collections import RegularPolyCollection +from matplotlib import path -from matplotlib.pyplot import figure, show +import matplotlib.pyplot as plt from numpy import nonzero from numpy.random import rand -class Datum: +class Datum(object): colorin = colorConverter.to_rgba('red') - colorout = colorConverter.to_rgba('green') + colorout = colorConverter.to_rgba('blue') def __init__(self, x, y, include=False): self.x = x self.y = y @@ -26,7 +25,7 @@ else: self.color = self.colorout -class LassoManager: +class LassoManager(object): def __init__(self, ax, data): self.axes = ax self.canvas = ax.figure.canvas @@ -46,13 +45,13 @@ ax.add_collection(self.collection) self.cid = self.canvas.mpl_connect('button_press_event', self.onpress) - self.ind = None def callback(self, verts): facecolors = self.collection.get_facecolors() - ind = nonzero(points_inside_poly(self.xys, verts))[0] - for i in range(self.Nxy): - if i in ind: + p = path.Path(verts) + ind = p.contains_points(self.xys) + for i in range(len(self.xys)): + if ind[i]: facecolors[i] = Datum.colorin else: facecolors[i] = Datum.colorout @@ -60,7 +59,7 @@ self.canvas.draw_idle() self.canvas.widgetlock.release(self.lasso) del self.lasso - self.ind = ind + def onpress(self, event): if self.canvas.widgetlock.locked(): return if event.inaxes is None: return @@ -72,8 +71,7 @@ data = [Datum(*xy) for xy in rand(100, 2)] - fig = figure() - ax = fig.add_subplot(111, xlim=(0,1), ylim=(0,1), autoscale_on=False) + ax = plt.axes(xlim=(0,1), ylim=(0,1), autoscale_on=False) lman = LassoManager(ax, data) - show() + plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/event_handling/legend_picking.py matplotlib-1.2.0/doc/mpl_examples/event_handling/legend_picking.py --- matplotlib-1.1.1/doc/mpl_examples/event_handling/legend_picking.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/event_handling/legend_picking.py 2012-10-31 00:11:13.000000000 +0000 @@ -28,7 +28,7 @@ def onpick(event): # on the pick event, find the orig line corresponding to the - # legend proxy line, and toggle the visibilit + # legend proxy line, and toggle the visibility legline = event.artist origline = lined[legline] vis = not origline.get_visible() diff -Nru matplotlib-1.1.1/doc/mpl_examples/event_handling/path_editor.py matplotlib-1.2.0/doc/mpl_examples/event_handling/path_editor.py --- matplotlib-1.1.1/doc/mpl_examples/event_handling/path_editor.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/event_handling/path_editor.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,7 +2,6 @@ import matplotlib.path as mpath import matplotlib.patches as mpatches import matplotlib.pyplot as plt -import matplotlib.mlab as mlab Path = mpath.Path diff -Nru matplotlib-1.1.1/doc/mpl_examples/event_handling/pick_event_demo.py matplotlib-1.2.0/doc/mpl_examples/event_handling/pick_event_demo.py --- matplotlib-1.1.1/doc/mpl_examples/event_handling/pick_event_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/event_handling/pick_event_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,8 +1,9 @@ #!/usr/bin/env python + """ -You can enable picking by setting the"picker" property of an artist -(eg a matplotlib Line2D, Text, Patch, Polygon, AxesImage, +You can enable picking by setting the "picker" property of an artist +(for example, a matplotlib Line2D, Text, Patch, Polygon, AxesImage, etc...) There are a variety of meanings of the picker property @@ -14,27 +15,27 @@ the artist float - if picker is a number it is interpreted as an - epsilon tolerance in points and the the artist will fire + epsilon tolerance in points and the artist will fire off an event if it's data is within epsilon of the mouse event. For some artists like lines and patch collections, the artist may provide additional data to the pick event - that is generated, eg the indices of the data within + that is generated, for example, the indices of the data within epsilon of the pick event - function - if picker is callable, it is a user supplied + function - if picker is callable, it is a user supplied function which determines whether the artist is hit by the mouse event. hit, props = picker(artist, mouseevent) - to determine the hit test. if the mouse event is over the + to determine the hit test. If the mouse event is over the artist, return hit=True and props is a dictionary of properties you want added to the PickEvent attributes After you have enabled an artist for picking by setting the "picker" property, you need to connect to the figure canvas pick_event to get -pick callbacks on mouse press events. Eg, +pick callbacks on mouse press events. For example, def pick_handler(event): mouseevent = event.mouseevent @@ -46,9 +47,9 @@ your callback is always fired with two attributes: mouseevent - the mouse event that generate the pick event. The - mouse event in turn has attributes like x and y (the coords in - display space, eg pixels from left, bottom) and xdata, ydata (the - coords in data space). Additionaly, you can get information about + mouse event in turn has attributes like x and y (the coordinates in + display space, such as pixels from left, bottom) and xdata, ydata (the + coords in data space). Additionally, you can get information about which buttons were pressed, which keys were pressed, which Axes the mouse is over, etc. See matplotlib.backend_bases.MouseEvent for details. @@ -57,18 +58,19 @@ Additionally, certain artists like Line2D and PatchCollection may attach additional meta data like the indices into the data that meet -the picker criteria (eg all the points in the line that are within the -specified epsilon tolerance) +the picker criteria (for example, all the points in the line that are within +the specified epsilon tolerance) The examples below illustrate each of these methods. """ +from __future__ import print_function from matplotlib.pyplot import figure, show from matplotlib.lines import Line2D -from matplotlib.patches import Patch, Rectangle +from matplotlib.patches import Rectangle from matplotlib.text import Text from matplotlib.image import AxesImage -import numpy as npy +import numpy as np from numpy.random import rand if 1: # simple picking, lines, rectangles and text @@ -92,13 +94,13 @@ xdata = thisline.get_xdata() ydata = thisline.get_ydata() ind = event.ind - print 'onpick1 line:', zip(npy.take(xdata, ind), npy.take(ydata, ind)) + print('onpick1 line:', zip(np.take(xdata, ind), np.take(ydata, ind))) elif isinstance(event.artist, Rectangle): patch = event.artist - print 'onpick1 patch:', patch.get_path() + print('onpick1 patch:', patch.get_path()) elif isinstance(event.artist, Text): text = event.artist - print 'onpick1 text:', text.get_text() + print('onpick1 text:', text.get_text()) @@ -124,19 +126,19 @@ xdata = line.get_xdata() ydata = line.get_ydata() maxd = 0.05 - d = npy.sqrt((xdata-mouseevent.xdata)**2. + (ydata-mouseevent.ydata)**2.) + d = np.sqrt((xdata-mouseevent.xdata)**2. + (ydata-mouseevent.ydata)**2.) - ind = npy.nonzero(npy.less_equal(d, maxd)) + ind = np.nonzero(np.less_equal(d, maxd)) if len(ind): - pickx = npy.take(xdata, ind) - picky = npy.take(ydata, ind) + pickx = np.take(xdata, ind) + picky = np.take(ydata, ind) props = dict(ind=ind, pickx=pickx, picky=picky) return True, props else: return False, dict() def onpick2(event): - print 'onpick2 line:', event.pickx, event.picky + print('onpick2 line:', event.pickx, event.picky) fig = figure() ax1 = fig.add_subplot(111) @@ -150,7 +152,7 @@ x, y, c, s = rand(4, 100) def onpick3(event): ind = event.ind - print 'onpick3 scatter:', ind, npy.take(x, ind), npy.take(y, ind) + print('onpick3 scatter:', ind, np.take(x, ind), np.take(y, ind)) fig = figure() ax1 = fig.add_subplot(111) @@ -172,7 +174,7 @@ if isinstance(artist, AxesImage): im = artist A = im.get_array() - print 'onpick4 image', A.shape + print('onpick4 image', A.shape) fig.canvas.mpl_connect('pick_event', onpick4) diff -Nru matplotlib-1.1.1/doc/mpl_examples/event_handling/pick_event_demo2.py matplotlib-1.2.0/doc/mpl_examples/event_handling/pick_event_demo2.py --- matplotlib-1.1.1/doc/mpl_examples/event_handling/pick_event_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/event_handling/pick_event_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,17 +1,17 @@ """ -compute the mean and stddev of 100 data sets and plot mean vs stddev. -When you click on one of the mu, sigma points, plot the raw data from -the dataset that generated the mean and stddev +compute the mean and standard deviation (stddev) of 100 data sets and plot +mean vs stddev. When you click on one of the mu, sigma points, plot the raw +data from the dataset that generated the mean and stddev. """ import numpy -from pylab import figure, show +import matplotlib.pyplot as plt X = numpy.random.rand(100, 1000) xs = numpy.mean(X, axis=1) ys = numpy.std(X, axis=1) -fig = figure() +fig = plt.figure() ax = fig.add_subplot(111) ax.set_title('click on point to plot time series') line, = ax.plot(xs, ys, 'o', picker=5) # 5 points tolerance @@ -25,19 +25,19 @@ if not N: return True - figi = figure() + figi = plt.figure() for subplotnum, dataind in enumerate(event.ind): ax = figi.add_subplot(N,1,subplotnum+1) ax.plot(X[dataind]) ax.text(0.05, 0.9, 'mu=%1.3f\nsigma=%1.3f'%(xs[dataind], ys[dataind]), transform=ax.transAxes, va='top') - ax.set_ylim(-0.5, 1.5) + ax.set_ylim(-0.5, 1.5) figi.show() return True fig.canvas.mpl_connect('pick_event', onpick) -show() +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/event_handling/pipong.py matplotlib-1.2.0/doc/mpl_examples/event_handling/pipong.py --- matplotlib-1.1.1/doc/mpl_examples/event_handling/pipong.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/event_handling/pipong.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,8 +1,10 @@ #!/usr/bin/env python # A matplotlib based game of Pong illustrating one way to write interactive -# animation which are easily ported to multiply backends +# animation which are easily ported to multiple backends # pipong.py was written by Paul Ivanov +from __future__ import print_function + import numpy as np import matplotlib.pyplot as plt from numpy.random import randn, randint @@ -200,7 +202,7 @@ if self.cnt==50000: # just so we don't get carried away - print "...and you've been playing for too long!!!" + print("...and you've been playing for too long!!!") plt.close() self.cnt += 1 diff -Nru matplotlib-1.1.1/doc/mpl_examples/event_handling/poly_editor.py matplotlib-1.2.0/doc/mpl_examples/event_handling/poly_editor.py --- matplotlib-1.1.1/doc/mpl_examples/event_handling/poly_editor.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/event_handling/poly_editor.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,9 +3,9 @@ matplotlib event handling to interact with objects on the canvas """ +import numpy as np +from matplotlib.lines import Line2D from matplotlib.artist import Artist -from matplotlib.patches import Polygon, CirclePolygon -from numpy import sqrt, nonzero, equal, array, asarray, dot, amin, cos, sin from matplotlib.mlab import dist_point_to_segment @@ -36,7 +36,7 @@ self.poly = poly x, y = zip(*self.poly.xy) - self.line = Line2D(x,y,marker='o', markerfacecolor='r', animated=True) + self.line = Line2D(x, y, marker='o', markerfacecolor='r', animated=True) self.ax.add_line(self.line) #self._update_line(poly) @@ -69,11 +69,11 @@ 'get the index of the vertex under point if within epsilon tolerance' # display coords - xy = asarray(self.poly.xy) + xy = np.asarray(self.poly.xy) xyt = self.poly.get_transform().transform(xy) xt, yt = xyt[:, 0], xyt[:, 1] - d = sqrt((xt-event.x)**2 + (yt-event.y)**2) - indseq = nonzero(equal(d, amin(d)))[0] + d = np.sqrt((xt-event.x)**2 + (yt-event.y)**2) + indseq = np.nonzero(np.equal(d, np.amin(d)))[0] ind = indseq[0] if d[ind]>=self.epsilon: @@ -114,7 +114,7 @@ s1 = xys[i+1] d = dist_point_to_segment(p, s0, s1) if d<=self.epsilon: - self.poly.xy = array( + self.poly.xy = np.array( list(self.poly.xy[:i]) + [(event.xdata, event.ydata)] + list(self.poly.xy[i:])) @@ -141,31 +141,26 @@ self.canvas.blit(self.ax.bbox) +if __name__ == '__main__': + import matplotlib.pyplot as plt + from matplotlib.patches import Polygon + + fig = plt.figure() + theta = np.arange(0, 2*np.pi, 0.1) + r = 1.5 + + xs = r*np.cos(theta) + ys = r*np.sin(theta) + + poly = Polygon(list(zip(xs, ys)), animated=True) + + ax = plt.subplot(111) + ax.add_patch(poly) + p = PolygonInteractor(ax, poly) + + #ax.add_line(p.line) + ax.set_title('Click and drag a point to move it') + ax.set_xlim((-2,2)) + ax.set_ylim((-2,2)) + plt.show() -from pylab import * - - - - - -fig = figure() -theta = arange(0, 2*pi, 0.1) -r = 1.5 - -xs = r*cos(theta) -ys = r*sin(theta) - -poly = Polygon(zip(xs, ys,), animated=True) - - - - -ax = subplot(111) -ax.add_patch(poly) -p = PolygonInteractor( ax, poly) - -#ax.add_line(p.line) -ax.set_title('Click and drag a point to move it') -ax.set_xlim((-2,2)) -ax.set_ylim((-2,2)) -show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/event_handling/pong_gtk.py matplotlib-1.2.0/doc/mpl_examples/event_handling/pong_gtk.py --- matplotlib-1.1.1/doc/mpl_examples/event_handling/pong_gtk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/event_handling/pong_gtk.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import print_function + # For detailed comments on animation and the techniques used here, see # the wiki entry # http://www.scipy.org/wikis/topical_software/MatplotlibAnimation @@ -10,10 +12,8 @@ import matplotlib matplotlib.use('GTKAgg') -import numpy as np import matplotlib.pyplot as plt import pipong -from numpy.random import randn, randint fig = plt.figure() @@ -33,4 +33,4 @@ tstart = time.time() plt.grid() # to ensure proper background restore plt.show() -print 'FPS:' , animation.cnt/(time.time()-tstart) +print('FPS:' , animation.cnt/(time.time()-tstart)) diff -Nru matplotlib-1.1.1/doc/mpl_examples/event_handling/pong_qt.py matplotlib-1.2.0/doc/mpl_examples/event_handling/pong_qt.py --- matplotlib-1.1.1/doc/mpl_examples/event_handling/pong_qt.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/event_handling/pong_qt.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,8 @@ # For detailed comments on animation and the techniqes used here, see # the wiki entry http://www.scipy.org/Cookbook/Matplotlib/Animations -import os, sys +from __future__ import print_function + import matplotlib matplotlib.use('QtAgg') # qt3 example @@ -14,12 +15,9 @@ FALSE = 0 ITERS = 1000 -import pylab as p import matplotlib.pyplot as plt -import numpy as np import time import pipong -from numpy.random import randn, randint class BlitQT(QObject): def __init__(self): @@ -39,4 +37,4 @@ app.startTimer(10) plt.show() -print 'FPS:' , app.animation.cnt/(time.time()-app.tstart) +print('FPS:' , app.animation.cnt/(time.time()-app.tstart)) diff -Nru matplotlib-1.1.1/doc/mpl_examples/event_handling/test_mouseclicks.py matplotlib-1.2.0/doc/mpl_examples/event_handling/test_mouseclicks.py --- matplotlib-1.1.1/doc/mpl_examples/event_handling/test_mouseclicks.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/event_handling/test_mouseclicks.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,35 @@ +#!/usr/bin/env python +from __future__ import print_function + +import matplotlib +#matplotlib.use("WxAgg") +#matplotlib.use("TkAgg") +#matplotlib.use("GTKAgg") +#matplotlib.use("QtAgg") +#matplotlib.use("Qt4Agg") +#matplotlib.use("CocoaAgg") +#matplotlib.use("MacOSX") +import matplotlib.pyplot as plt + +#print("***** TESTING WITH BACKEND: %s"%matplotlib.get_backend() + " *****") + + +def OnClick(event): + if event.dblclick: + print("DBLCLICK", event) + else: + print("DOWN ", event) + + +def OnRelease(event): + print("UP ", event) + + +fig = plt.gcf() +cid_up = fig.canvas.mpl_connect('button_press_event', OnClick) +cid_down = fig.canvas.mpl_connect('button_release_event', OnRelease) + +plt.gca().text(0.5, 0.5, "Click on the canvas to test mouse events.", + ha="center", va="center") + +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/event_handling/viewlims.py matplotlib-1.2.0/doc/mpl_examples/event_handling/viewlims.py --- matplotlib-1.1.1/doc/mpl_examples/event_handling/viewlims.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/event_handling/viewlims.py 2012-10-31 00:11:13.000000000 +0000 @@ -30,7 +30,7 @@ threshold_time = np.zeros((self.height, self.width)) z = np.zeros(threshold_time.shape, dtype=np.complex) mask = np.ones(threshold_time.shape, dtype=np.bool) - for i in xrange(self.niter): + for i in range(self.niter): z[mask] = z[mask]**self.power + c[mask] mask = (np.abs(z) < self.radius) threshold_time += mask diff -Nru matplotlib-1.1.1/doc/mpl_examples/event_handling/zoom_window.py matplotlib-1.2.0/doc/mpl_examples/event_handling/zoom_window.py --- matplotlib-1.1.1/doc/mpl_examples/event_handling/zoom_window.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/event_handling/zoom_window.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,10 @@ """ -This example shows how to connect events in one window, eg a mouse +This example shows how to connect events in one window, for example, a mouse press, to another figure window. If you click on a point in the first window, the z and y limits of the second will be adjusted so that the center of the zoom in the second -window will be the x,y coords of the clicked point. +window will be the x,y coordinates of the clicked point. Note the diameter of the circles in the scatter are defined in points**2, so their size is independent of the zoom diff -Nru matplotlib-1.1.1/doc/mpl_examples/misc/developer_commit_history.py matplotlib-1.2.0/doc/mpl_examples/misc/developer_commit_history.py --- matplotlib-1.1.1/doc/mpl_examples/misc/developer_commit_history.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/misc/developer_commit_history.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function """ report how many days it has been since each developer committed. You must do an diff -Nru matplotlib-1.1.1/doc/mpl_examples/misc/font_indexing.py matplotlib-1.2.0/doc/mpl_examples/misc/font_indexing.py --- matplotlib-1.1.1/doc/mpl_examples/misc/font_indexing.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/misc/font_indexing.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,6 +3,7 @@ tables relate to one another. Mainly for mpl developers.... """ +from __future__ import print_function import matplotlib from matplotlib.ft2font import FT2Font, KERNING_DEFAULT, KERNING_UNFITTED, KERNING_UNSCALED @@ -34,8 +35,8 @@ code = coded['A'] glyph = font.load_char(code) #print glyph.bbox -print glyphd['A'], glyphd['V'], coded['A'], coded['V'] -print 'AV', font.get_kerning(glyphd['A'], glyphd['V'], KERNING_DEFAULT) -print 'AV', font.get_kerning(glyphd['A'], glyphd['V'], KERNING_UNFITTED) -print 'AV', font.get_kerning(glyphd['A'], glyphd['V'], KERNING_UNSCALED) -print 'AV', font.get_kerning(glyphd['A'], glyphd['T'], KERNING_UNSCALED) +print(glyphd['A'], glyphd['V'], coded['A'], coded['V']) +print('AV', font.get_kerning(glyphd['A'], glyphd['V'], KERNING_DEFAULT)) +print('AV', font.get_kerning(glyphd['A'], glyphd['V'], KERNING_UNFITTED)) +print('AV', font.get_kerning(glyphd['A'], glyphd['V'], KERNING_UNSCALED)) +print('AV', font.get_kerning(glyphd['A'], glyphd['T'], KERNING_UNSCALED)) diff -Nru matplotlib-1.1.1/doc/mpl_examples/misc/ftface_props.py matplotlib-1.2.0/doc/mpl_examples/misc/ftface_props.py --- matplotlib-1.1.1/doc/mpl_examples/misc/ftface_props.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/misc/ftface_props.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,6 @@ #!/usr/bin/env python + +from __future__ import print_function """ This is a demo script to show you how to use all the properties of an FT2Font object. These describe global font properties. For @@ -29,48 +31,48 @@ FT_STYLE_FLAG_ITALIC = 1 << 0 FT_STYLE_FLAG_BOLD = 1 << 1 -print 'Num faces :', font.num_faces # number of faces in file -print 'Num glyphs :', font.num_glyphs # number of glyphs in the face -print 'Family name :', font.family_name # face family name -print 'Syle name :', font.style_name # face syle name -print 'PS name :', font.postscript_name # the postscript name -print 'Num fixed :', font.num_fixed_sizes # number of embedded bitmap in face +print('Num faces :', font.num_faces) # number of faces in file +print('Num glyphs :', font.num_glyphs) # number of glyphs in the face +print('Family name :', font.family_name) # face family name +print('Syle name :', font.style_name) # face syle name +print('PS name :', font.postscript_name) # the postscript name +print('Num fixed :', font.num_fixed_sizes) # number of embedded bitmap in face # the following are only available if face.scalable if font.scalable: # the face global bounding box (xmin, ymin, xmax, ymax) - print 'Bbox :', font.bbox + print('Bbox :', font.bbox) # number of font units covered by the EM - print 'EM :', font.units_per_EM + print('EM :', font.units_per_EM) # the ascender in 26.6 units - print 'Ascender :', font.ascender + print('Ascender :', font.ascender) # the descender in 26.6 units - print 'Descender :', font.descender + print('Descender :', font.descender) # the height in 26.6 units - print 'Height :', font.height + print('Height :', font.height) # maximum horizontal cursor advance - print 'Max adv width :', font.max_advance_width + print('Max adv width :', font.max_advance_width) # same for vertical layout - print 'Max adv height :', font.max_advance_height + print('Max adv height :', font.max_advance_height) # vertical position of the underline bar - print 'Underline pos :', font.underline_position + print('Underline pos :', font.underline_position) # vertical thickness of the underline - print 'Underline thickness :', font.underline_thickness + print('Underline thickness :', font.underline_thickness) -print 'Italics :', font.style_flags & FT_STYLE_FLAG_ITALIC != 0 -print 'Bold :', font.style_flags & FT_STYLE_FLAG_BOLD != 0 -print 'Scalable :', font.style_flags & FT_FACE_FLAG_SCALABLE != 0 -print 'Fixed sizes :', font.style_flags & FT_FACE_FLAG_FIXED_SIZES != 0 -print 'Fixed width :', font.style_flags & FT_FACE_FLAG_FIXED_WIDTH != 0 -print 'SFNT :', font.style_flags & FT_FACE_FLAG_SFNT != 0 -print 'Horizontal :', font.style_flags & FT_FACE_FLAG_HORIZONTAL != 0 -print 'Vertical :', font.style_flags & FT_FACE_FLAG_VERTICAL != 0 -print 'Kerning :', font.style_flags & FT_FACE_FLAG_KERNING != 0 -print 'Fast glyphs :', font.style_flags & FT_FACE_FLAG_FAST_GLYPHS != 0 -print 'Mult. masters :', font.style_flags & FT_FACE_FLAG_MULTIPLE_MASTERS != 0 -print 'Glyph names :', font.style_flags & FT_FACE_FLAG_GLYPH_NAMES != 0 +print('Italics :', font.style_flags & FT_STYLE_FLAG_ITALIC != 0) +print('Bold :', font.style_flags & FT_STYLE_FLAG_BOLD != 0) +print('Scalable :', font.style_flags & FT_FACE_FLAG_SCALABLE != 0) +print('Fixed sizes :', font.style_flags & FT_FACE_FLAG_FIXED_SIZES != 0) +print('Fixed width :', font.style_flags & FT_FACE_FLAG_FIXED_WIDTH != 0) +print('SFNT :', font.style_flags & FT_FACE_FLAG_SFNT != 0) +print('Horizontal :', font.style_flags & FT_FACE_FLAG_HORIZONTAL != 0) +print('Vertical :', font.style_flags & FT_FACE_FLAG_VERTICAL != 0) +print('Kerning :', font.style_flags & FT_FACE_FLAG_KERNING != 0) +print('Fast glyphs :', font.style_flags & FT_FACE_FLAG_FAST_GLYPHS != 0) +print('Mult. masters :', font.style_flags & FT_FACE_FLAG_MULTIPLE_MASTERS != 0) +print('Glyph names :', font.style_flags & FT_FACE_FLAG_GLYPH_NAMES != 0) -print dir(font) +print(dir(font)) cmap = font.get_charmap() -print font.get_kerning +print(font.get_kerning) diff -Nru matplotlib-1.1.1/doc/mpl_examples/misc/image_thumbnail.py matplotlib-1.2.0/doc/mpl_examples/misc/image_thumbnail.py --- matplotlib-1.1.1/doc/mpl_examples/misc/image_thumbnail.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/misc/image_thumbnail.py 2012-10-31 00:11:13.000000000 +0000 @@ -4,17 +4,18 @@ image types transparently if your have PIL installed """ +from __future__ import print_function # build thumbnails of all images in a directory import sys, os, glob import matplotlib.image as image if len(sys.argv)!=2: - print 'Usage: python %s IMAGEDIR'%__file__ + print('Usage: python %s IMAGEDIR'%__file__) raise SystemExit indir = sys.argv[1] if not os.path.isdir(indir): - print 'Could not find input directory "%s"'%indir + print('Could not find input directory "%s"'%indir) raise SystemExit outdir = 'thumbs' @@ -25,5 +26,5 @@ basedir, basename = os.path.split(fname) outfile = os.path.join(outdir, basename) fig = image.thumbnail(fname, outfile, scale=0.15) - print 'saved thumbnail of %s to %s'%(fname, outfile) + print('saved thumbnail of %s to %s'%(fname, outfile)) diff -Nru matplotlib-1.1.1/doc/mpl_examples/misc/multiprocess.py matplotlib-1.2.0/doc/mpl_examples/misc/multiprocess.py --- matplotlib-1.1.1/doc/mpl_examples/misc/multiprocess.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/misc/multiprocess.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,6 +3,8 @@ #Written by Robert Cimrman #Requires >= Python 2.6 for the multiprocessing module or having the #standalone processing module installed + +from __future__ import print_function import time try: from multiprocessing import Process, Pipe @@ -48,7 +50,7 @@ return call_back def __call__(self, pipe): - print 'starting plotter...' + print('starting plotter...') self.pipe = pipe self.fig = plt.figure() @@ -56,7 +58,7 @@ self.ax = self.fig.add_subplot(111) self.gid = gobject.timeout_add(1000, self.poll_draw()) - print '...done' + print('...done') plt.show() @@ -79,7 +81,7 @@ def main(): pl = NBPlot() - for ii in xrange(10): + for ii in range(10): pl.plot() time.sleep(0.5) raw_input('press Enter...') diff -Nru matplotlib-1.1.1/doc/mpl_examples/misc/rc_traits.py matplotlib-1.2.0/doc/mpl_examples/misc/rc_traits.py --- matplotlib-1.1.1/doc/mpl_examples/misc/rc_traits.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/misc/rc_traits.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,8 +3,10 @@ # matplotlib does not ship with enthought.traits, so you will need to # install it separately. +from __future__ import print_function + import sys, os, re -import enthought.traits.api as traits +import traits.api as traits from matplotlib.cbook import is_string_like from matplotlib.artist import Artist @@ -140,11 +142,11 @@ rc = RC() rc.lines.color = 'r' if doprint: - print 'RC' + print('RC') rc.print_traits() - print 'RC lines' + print('RC lines') rc.lines.print_traits() - print 'RC patches' + print('RC patches') rc.patch.print_traits() @@ -182,13 +184,13 @@ p.facecolor = (1,.5,.5,.25) p.facecolor = 0.25 p.fill = 'f' -print 'p.facecolor', type(p.facecolor), p.facecolor -print 'p.fill', type(p.fill), p.fill -if p.fill_: print 'fill' -else: print 'no fill' +print('p.facecolor', type(p.facecolor), p.facecolor) +print('p.fill', type(p.fill), p.fill) +if p.fill_: print('fill') +else: print('no fill') if doprint: - print - print 'Patch' + print() + print('Patch') p.print_traits() diff -Nru matplotlib-1.1.1/doc/mpl_examples/misc/rec_groupby_demo.py matplotlib-1.2.0/doc/mpl_examples/misc/rec_groupby_demo.py --- matplotlib-1.1.1/doc/mpl_examples/misc/rec_groupby_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/misc/rec_groupby_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,10 @@ +from __future__ import print_function import numpy as np import matplotlib.mlab as mlab import matplotlib.cbook as cbook datafile = cbook.get_sample_data('aapl.csv', asfileobj=False) -print 'loading', datafile +print('loading', datafile) r = mlab.csv2rec(datafile) r.sort() @@ -44,19 +45,19 @@ ) # you can summarize over a single variable, like years or months -print 'summary by years' +print('summary by years') ry = mlab.rec_groupby(rsum, ('years',), stats) -print mlab. rec2txt(ry) +print(mlab. rec2txt(ry)) -print 'summary by months' +print('summary by months') rm = mlab.rec_groupby(rsum, ('months',), stats) -print mlab.rec2txt(rm) +print(mlab.rec2txt(rm)) # or over multiple variables like years and months -print 'summary by year and month' +print('summary by year and month') rym = mlab.rec_groupby(rsum, ('years','months'), stats) -print mlab.rec2txt(rym) +print(mlab.rec2txt(rym)) -print 'summary by volume' +print('summary by volume') rv = mlab.rec_groupby(rsum, ('volcode',), stats) -print mlab.rec2txt(rv) +print(mlab.rec2txt(rv)) diff -Nru matplotlib-1.1.1/doc/mpl_examples/misc/rec_join_demo.py matplotlib-1.2.0/doc/mpl_examples/misc/rec_join_demo.py --- matplotlib-1.1.1/doc/mpl_examples/misc/rec_join_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/misc/rec_join_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,10 @@ +from __future__ import print_function import numpy as np import matplotlib.mlab as mlab import matplotlib.cbook as cbook datafile = cbook.get_sample_data('aapl.csv', asfileobj=False) -print 'loading', datafile +print('loading', datafile) r = mlab.csv2rec(datafile) r.sort() @@ -17,14 +18,14 @@ r2.high = r.high[-17:-5] r2.marker = np.arange(12) -print "r1:" -print mlab.rec2txt(r1) -print "r2:" -print mlab.rec2txt(r2) +print("r1:") +print(mlab.rec2txt(r1)) +print("r2:") +print(mlab.rec2txt(r2)) defaults = {'marker':-1, 'close':np.NaN, 'low':-4444.} for s in ('inner', 'outer', 'leftouter'): rec = mlab.rec_join(['date', 'high'], r1, r2, jointype=s, defaults=defaults) - print "\n%sjoin :\n%s" % (s, mlab.rec2txt(rec)) + print("\n%sjoin :\n%s" % (s, mlab.rec2txt(rec))) diff -Nru matplotlib-1.1.1/doc/mpl_examples/misc/sample_data_demo.py matplotlib-1.2.0/doc/mpl_examples/misc/sample_data_demo.py --- matplotlib-1.1.1/doc/mpl_examples/misc/sample_data_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/misc/sample_data_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,11 +2,12 @@ Grab mpl data from the ~/.matplotlib/sample_data cache if it exists, else fetch it from github and cache it """ +from __future__ import print_function import matplotlib.cbook as cbook import matplotlib.pyplot as plt fname = cbook.get_sample_data('lena.png', asfileobj=False) -print 'fname', fname +print('fname', fname) im = plt.imread(fname) plt.imshow(im) plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/misc/sample_data_test.py matplotlib-1.2.0/doc/mpl_examples/misc/sample_data_test.py --- matplotlib-1.1.1/doc/mpl_examples/misc/sample_data_test.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/misc/sample_data_test.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -""" -Demonstrate how get_sample_data works with git revisions in the data. - - git clone git@github.com/matplotlib/sample_data.git - -and edit testdata.csv to add a new row. After committing the changes, -when you rerun this script you will get the updated data (and the new -git version will be cached in ~/.matplotlib/sample_data) -""" - -import matplotlib.mlab as mlab -import matplotlib.cbook as cbook - -# get the file handle to the cached data and print the contents -datafile = 'testdir/subdir/testsub.csv' -fh = cbook.get_sample_data(datafile) -print fh.read() - -# make sure we can read it using csv2rec -fh.seek(0) -r = mlab.csv2rec(fh) - -print mlab.rec2txt(r) - -fh.close() - diff -Nru matplotlib-1.1.1/doc/mpl_examples/misc/svg_filter_line.py matplotlib-1.2.0/doc/mpl_examples/misc/svg_filter_line.py --- matplotlib-1.1.1/doc/mpl_examples/misc/svg_filter_line.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/misc/svg_filter_line.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,9 +2,10 @@ Demonstrate SVG filtering effects which might be used with mpl. Note that the filtering effects are only effective if your svg rederer -support it. +support it. """ +from __future__ import print_function import matplotlib matplotlib.use("Svg") @@ -68,7 +69,7 @@ """ -# read in the saved svg +# read in the saved svg tree, xmlid = ET.XMLID(f.getvalue()) # insert the filter definition in the svg dom tree. @@ -81,5 +82,5 @@ shadow.set("filter",'url(#dropshadow)') fn = "svg_filter_line.svg" -print "Saving '%s'" % fn +print("Saving '%s'" % fn) ET.ElementTree(tree).write(fn) diff -Nru matplotlib-1.1.1/doc/mpl_examples/misc/tight_bbox_test.py matplotlib-1.2.0/doc/mpl_examples/misc/tight_bbox_test.py --- matplotlib-1.1.1/doc/mpl_examples/misc/tight_bbox_test.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/misc/tight_bbox_test.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import matplotlib.pyplot as plt import numpy as np @@ -9,6 +10,6 @@ plt.ylabel("My y-label") plt.title("Check saved figures for their bboxes") for ext in ["png", "pdf", "svg", "svgz", "eps"]: - print "saving tight_bbox_test.%s" % (ext,) + print("saving tight_bbox_test.%s" % (ext,)) plt.savefig("tight_bbox_test.%s" % (ext,), bbox_inches="tight") plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/mplot3d/contour3d_demo.py matplotlib-1.2.0/doc/mpl_examples/mplot3d/contour3d_demo.py --- matplotlib-1.1.1/doc/mpl_examples/mplot3d/contour3d_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/mplot3d/contour3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,11 @@ from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt +from matplotlib import cm fig = plt.figure() ax = fig.add_subplot(111, projection='3d') X, Y, Z = axes3d.get_test_data(0.05) -cset = ax.contour(X, Y, Z) +cset = ax.contour(X, Y, Z, cmap=cm.coolwarm) ax.clabel(cset, fontsize=9, inline=1) plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/mplot3d/contour3d_demo2.py matplotlib-1.2.0/doc/mpl_examples/mplot3d/contour3d_demo2.py --- matplotlib-1.1.1/doc/mpl_examples/mplot3d/contour3d_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/mplot3d/contour3d_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,11 @@ from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt +from matplotlib import cm fig = plt.figure() ax = fig.gca(projection='3d') X, Y, Z = axes3d.get_test_data(0.05) -cset = ax.contour(X, Y, Z, extend3d=True) +cset = ax.contour(X, Y, Z, extend3d=True, cmap=cm.coolwarm) ax.clabel(cset, fontsize=9, inline=1) plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/mplot3d/contour3d_demo3.py matplotlib-1.2.0/doc/mpl_examples/mplot3d/contour3d_demo3.py --- matplotlib-1.1.1/doc/mpl_examples/mplot3d/contour3d_demo3.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/mplot3d/contour3d_demo3.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,13 +1,14 @@ from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt +from matplotlib import cm fig = plt.figure() ax = fig.gca(projection='3d') X, Y, Z = axes3d.get_test_data(0.05) ax.plot_surface(X, Y, Z, rstride=8, cstride=8, alpha=0.3) -cset = ax.contour(X, Y, Z, zdir='z', offset=-100) -cset = ax.contour(X, Y, Z, zdir='x', offset=-40) -cset = ax.contour(X, Y, Z, zdir='y', offset=40) +cset = ax.contour(X, Y, Z, zdir='z', offset=-100, cmap=cm.coolwarm) +cset = ax.contour(X, Y, Z, zdir='x', offset=-40, cmap=cm.coolwarm) +cset = ax.contour(X, Y, Z, zdir='y', offset=40, cmap=cm.coolwarm) ax.set_xlabel('X') ax.set_xlim(-40, 40) diff -Nru matplotlib-1.1.1/doc/mpl_examples/mplot3d/contourf3d_demo.py matplotlib-1.2.0/doc/mpl_examples/mplot3d/contourf3d_demo.py --- matplotlib-1.1.1/doc/mpl_examples/mplot3d/contourf3d_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/mplot3d/contourf3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,11 @@ from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt +from matplotlib import cm fig = plt.figure() ax = fig.gca(projection='3d') X, Y, Z = axes3d.get_test_data(0.05) -cset = ax.contourf(X, Y, Z) +cset = ax.contourf(X, Y, Z, cmap=cm.coolwarm) ax.clabel(cset, fontsize=9, inline=1) plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/mplot3d/contourf3d_demo2.py matplotlib-1.2.0/doc/mpl_examples/mplot3d/contourf3d_demo2.py --- matplotlib-1.1.1/doc/mpl_examples/mplot3d/contourf3d_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/mplot3d/contourf3d_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -5,14 +5,15 @@ from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt +from matplotlib import cm fig = plt.figure() ax = fig.gca(projection='3d') X, Y, Z = axes3d.get_test_data(0.05) ax.plot_surface(X, Y, Z, rstride=8, cstride=8, alpha=0.3) -cset = ax.contourf(X, Y, Z, zdir='z', offset=-100) -cset = ax.contourf(X, Y, Z, zdir='x', offset=-40) -cset = ax.contourf(X, Y, Z, zdir='y', offset=40) +cset = ax.contourf(X, Y, Z, zdir='z', offset=-100, cmap=cm.coolwarm) +cset = ax.contourf(X, Y, Z, zdir='x', offset=-40, cmap=cm.coolwarm) +cset = ax.contourf(X, Y, Z, zdir='y', offset=40, cmap=cm.coolwarm) ax.set_xlabel('X') ax.set_xlim(-40, 40) diff -Nru matplotlib-1.1.1/doc/mpl_examples/mplot3d/lorenz_attractor.py matplotlib-1.2.0/doc/mpl_examples/mplot3d/lorenz_attractor.py --- matplotlib-1.1.1/doc/mpl_examples/mplot3d/lorenz_attractor.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/mplot3d/lorenz_attractor.py 2012-10-31 00:11:13.000000000 +0000 @@ -30,7 +30,7 @@ xs[0], ys[0], zs[0] = (0., 1., 1.05) # Stepping through "time". -for i in xrange(stepCnt) : +for i in range(stepCnt) : # Derivatives of the X, Y, Z state x_dot, y_dot, z_dot = lorenz(xs[i], ys[i], zs[i]) xs[i + 1] = xs[i] + (x_dot * dt) diff -Nru matplotlib-1.1.1/doc/mpl_examples/mplot3d/pathpatch3d_demo.py matplotlib-1.2.0/doc/mpl_examples/mplot3d/pathpatch3d_demo.py --- matplotlib-1.1.1/doc/mpl_examples/mplot3d/pathpatch3d_demo.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/mplot3d/pathpatch3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,14 +1,15 @@ import matplotlib.pyplot as plt from matplotlib.patches import Circle, PathPatch +# register Axes3D class with matplotlib by importing Axes3D from mpl_toolkits.mplot3d import Axes3D import mpl_toolkits.mplot3d.art3d as art3d from matplotlib.text import TextPath from matplotlib.transforms import Affine2D -def text3d(ax, (x, y, z), s, zdir="z", size=None, angle=0, usetex=False, - **kwargs): +def text3d(ax, xyz, s, zdir="z", size=None, angle=0, usetex=False, **kwargs): + x, y, z = xyz if zdir == "y": xy1, z1 = (x, z), y elif zdir == "y": @@ -34,13 +35,14 @@ text3d(ax, (4, -2, 0), "X-axis", zdir="z", size=.5, usetex=False, ec="none", fc="k") -text3d(ax, (12, 4, 0), "Y-axis", zdir="z", size=.5, usetex=False, angle=.5*3.14159, - ec="none", fc="k") -text3d(ax, (12, 10, 4), "Z-axis", zdir="y", size=.5, usetex=False, angle=.5*3.14159, - ec="none", fc="k") +text3d(ax, (12, 4, 0), "Y-axis", zdir="z", size=.5, usetex=False, + angle=.5*3.14159, ec="none", fc="k") +text3d(ax, (12, 10, 4), "Z-axis", zdir="y", size=.5, usetex=False, + angle=.5*3.14159, ec="none", fc="k") text3d(ax, (1, 5, 0), - r"$\displaystyle G_{\mu\nu} + \Lambda g_{\mu\nu} = \frac{8\pi G}{c^4} T_{\mu\nu} $", + r"$\displaystyle G_{\mu\nu} + \Lambda g_{\mu\nu} = " + r"\frac{8\pi G}{c^4} T_{\mu\nu} $", zdir="z", size=1, usetex=True, ec="none", fc="k") @@ -49,4 +51,3 @@ ax.set_zlim3d(0, 10) plt.show() - diff -Nru matplotlib-1.1.1/doc/mpl_examples/mplot3d/polys3d_demo.py matplotlib-1.2.0/doc/mpl_examples/mplot3d/polys3d_demo.py --- matplotlib-1.1.1/doc/mpl_examples/mplot3d/polys3d_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/mplot3d/polys3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -15,7 +15,7 @@ for z in zs: ys = np.random.rand(len(xs)) ys[0], ys[-1] = 0, 0 - verts.append(zip(xs, ys)) + verts.append(list(zip(xs, ys))) poly = PolyCollection(verts, facecolors = [cc('r'), cc('g'), cc('b'), cc('y')]) diff -Nru matplotlib-1.1.1/doc/mpl_examples/mplot3d/subplot3d_demo.py matplotlib-1.2.0/doc/mpl_examples/mplot3d/subplot3d_demo.py --- matplotlib-1.1.1/doc/mpl_examples/mplot3d/subplot3d_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/mplot3d/subplot3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -17,7 +17,7 @@ X, Y = np.meshgrid(X, Y) R = np.sqrt(X**2 + Y**2) Z = np.sin(R) -surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet, +surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False) ax.set_zlim3d(-1.01, 1.01) diff -Nru matplotlib-1.1.1/doc/mpl_examples/mplot3d/surface3d_demo.py matplotlib-1.2.0/doc/mpl_examples/mplot3d/surface3d_demo.py --- matplotlib-1.1.1/doc/mpl_examples/mplot3d/surface3d_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/mplot3d/surface3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -11,7 +11,7 @@ X, Y = np.meshgrid(X, Y) R = np.sqrt(X**2 + Y**2) Z = np.sin(R) -surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet, +surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False) ax.set_zlim(-1.01, 1.01) diff -Nru matplotlib-1.1.1/doc/mpl_examples/mplot3d/surface3d_radial_demo.py matplotlib-1.2.0/doc/mpl_examples/mplot3d/surface3d_radial_demo.py --- matplotlib-1.1.1/doc/mpl_examples/mplot3d/surface3d_radial_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/mplot3d/surface3d_radial_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -18,7 +18,7 @@ X,Y = R*np.cos(P),R*np.sin(P) Z = ((R**2 - 1)**2) -ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet) +ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.YlGnBu_r) ax.set_zlim3d(0, 1) ax.set_xlabel(r'$\phi_\mathrm{real}$') ax.set_ylabel(r'$\phi_\mathrm{im}$') diff -Nru matplotlib-1.1.1/doc/mpl_examples/mplot3d/trisurf3d_demo.py matplotlib-1.2.0/doc/mpl_examples/mplot3d/trisurf3d_demo.py --- matplotlib-1.1.1/doc/mpl_examples/mplot3d/trisurf3d_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/mplot3d/trisurf3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,32 @@ +from mpl_toolkits.mplot3d import Axes3D +from matplotlib import cm +import matplotlib.pyplot as plt +import numpy as np + +n_angles = 36 +n_radii = 8 + +# An array of radii +# Does not include radius r=0, this is to eliminate duplicate points +radii = np.linspace(0.125, 1.0, n_radii) + +# An array of angles +angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False) + +# Repeat all angles for each radius +angles = np.repeat(angles[...,np.newaxis], n_radii, axis=1) + +# Convert polar (radii, angles) coords to cartesian (x, y) coords +# (0, 0) is added here. There are no duplicate points in the (x, y) plane +x = np.append(0, (radii*np.cos(angles)).flatten()) +y = np.append(0, (radii*np.sin(angles)).flatten()) + +# Pringle surface +z = np.sin(-x*y) + +fig = plt.figure() +ax = fig.gca(projection='3d') + +ax.plot_trisurf(x, y, z, cmap=cm.jet, linewidth=0.2) + +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/mplot3d/wire3d_animation_demo.py matplotlib-1.2.0/doc/mpl_examples/mplot3d/wire3d_animation_demo.py --- matplotlib-1.1.1/doc/mpl_examples/mplot3d/wire3d_animation_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/mplot3d/wire3d_animation_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function """ A very simple 'animation' of a 3D plot """ @@ -34,4 +35,4 @@ plt.draw() -print 'FPS: %f' % (100 / (time.time() - tstart)) +print ('FPS: %f' % (100 / (time.time() - tstart))) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/agg_buffer_to_array.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/agg_buffer_to_array.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/agg_buffer_to_array.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/agg_buffer_to_array.py 2012-11-08 02:24:12.000000000 +0000 @@ -1,5 +1,4 @@ import matplotlib -matplotlib.use('Agg') from pylab import figure, show import numpy as np @@ -10,10 +9,12 @@ ax.set_title('a simple figure') fig.canvas.draw() -# grab rhe pixel buffer and dumpy it into a numpy array -buf = fig.canvas.buffer_rgba(0,0) +# grab the pixel buffer and dump it into a numpy array +buf = fig.canvas.buffer_rgba() l, b, w, h = fig.bbox.bounds -X = np.fromstring(buf, np.uint8) +# The array needs to be copied, because the underlying buffer +# may be reallocated when the window is resized. +X = np.frombuffer(buf, np.uint8).copy() X.shape = h,w,4 # now display the array X as an Axes in a new figure diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/anchored_artists.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/anchored_artists.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/anchored_artists.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/anchored_artists.py 2012-10-31 00:11:13.000000000 +0000 @@ -22,7 +22,7 @@ pad=0.1, borderpad=0.1, sep=2, prop=None, frameon=True): """ Draw a horizontal bar with the size in data coordinate of the give axes. - A label will be drawn underneath (center-alinged). + A label will be drawn underneath (center-aligned). pad, borderpad in fraction of the legend font size (or prop) sep in points. diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/animation_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/animation_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/animation_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/animation_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -23,8 +23,5 @@ z = z + 2 p.set_data(z) - print "step", i + print("step", i) plt.pause(0.5) - - - diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/annotation_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/annotation_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/annotation_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/annotation_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -113,7 +113,7 @@ if 1: - # You can also use polar notation on a catesian axes. Here the + # You can also use polar notation on a cartesian axes. Here the # native coordinate system ('data') is cartesian, so you need to # specify the xycoords and textcoords as 'polar' if you want to # use (theta, radius) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/anscombe.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/anscombe.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/anscombe.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/anscombe.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,6 @@ #!/usr/bin/env python + +from __future__ import print_function """ Edward Tufte uses this example from Anscombe to show 4 datasets of x and y that have the same mean, standard deviation, and regression @@ -38,7 +40,7 @@ subplot(223) plot(x,y3,'ks', xfit, fit(xfit), 'r-', lw=2) axis([2,20,2,14]) -text(3,12, 'IIII', fontsize=20) +text(3,12, 'III', fontsize=20) setp(gca(), yticks=(4,8,12), xticks=(0,10,20)) subplot(224) @@ -52,6 +54,6 @@ #verify the stats pairs = (x,y1), (x,y2), (x,y3), (x4,y4) for x,y in pairs: - print 'mean=%1.2f, std=%1.2f, r=%1.2f'%(mean(y), std(y), corrcoef(x,y)[0][1]) + print ('mean=%1.2f, std=%1.2f, r=%1.2f'%(mean(y), std(y), corrcoef(x,y)[0][1])) show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/arrow_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/arrow_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/arrow_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/arrow_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -199,7 +199,7 @@ elif where == 'center': orig_position = array([[length/2.0, 3*max_arrow_width]]) else: - raise ValueError, "Got unknown position parameter %s" % where + raise ValueError("Got unknown position parameter %s" % where) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/arrow_simple_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/arrow_simple_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/arrow_simple_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/arrow_simple_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,5 @@ +import matplotlib.pyplot as plt + +ax = plt.axes() +ax.arrow(0, 0, 0.5, 0.5, head_width=0.05, head_length=0.1, fc='k', ec='k') +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/axes_zoom_effect.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/axes_zoom_effect.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/axes_zoom_effect.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/axes_zoom_effect.py 2012-10-31 00:11:13.000000000 +0000 @@ -30,7 +30,7 @@ def zoom_effect01(ax1, ax2, xmin, xmax, **kwargs): - u""" + """ ax1 : the main axes ax1 : the zoomed axes (xmin,xmax) : the limits of the colored area in both plot axes. @@ -68,7 +68,7 @@ def zoom_effect02(ax1, ax2, **kwargs): - u""" + """ ax1 : the main axes ax1 : the zoomed axes diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/axhspan_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/axhspan_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/axhspan_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/axhspan_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -14,7 +14,7 @@ # draw a default vline at x=1 that spans the yrange l = plt.axvline(x=1) -# draw a thick blue vline at x=0 that spans the the upper quadrant of +# draw a thick blue vline at x=0 that spans the upper quadrant of # the yrange l = plt.axvline(x=0, ymin=0.75, linewidth=4, color='b') diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/boxplot_demo2.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/boxplot_demo2.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/boxplot_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/boxplot_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -80,7 +80,7 @@ medianY.append(med.get_ydata()[j]) plt.plot(medianX, medianY, 'k') medians[i] = medianY[0] - # Finally, overplot the sample averages, with horixzontal alignment + # Finally, overplot the sample averages, with horizontal alignment # in the center of each box plt.plot([np.average(med.get_xdata())], [np.average(data[i])], color='w', marker='*', markeredgecolor='k') diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/boxplot_demo3.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/boxplot_demo3.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/boxplot_demo3.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/boxplot_demo3.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,26 +2,48 @@ import matplotlib.transforms as mtransforms import numpy as np +def fakeBootStrapper(n): + ''' + This is just a placeholder for the user's method of + bootstrapping the median and its confidence intervals. + + Returns an arbitrary median and confidence intervals + packed into a tuple + ''' + if n == 1: + med = 0.1 + CI = (-0.25, 0.25) + else: + med = 0.2 + CI = (-0.35, 0.50) + + return med, CI + + + np.random.seed(2) inc = 0.1 -e1 = np.random.uniform(0,1, size=(500,)) -e2 = np.random.uniform(0,1, size=(500,)) -e3 = np.random.uniform(0,1 + inc, size=(500,)) -e4 = np.random.uniform(0,1 + 2*inc, size=(500,)) +e1 = np.random.normal(0, 1, size=(500,)) +e2 = np.random.normal(0, 1, size=(500,)) +e3 = np.random.normal(0, 1 + inc, size=(500,)) +e4 = np.random.normal(0, 1 + 2*inc, size=(500,)) treatments = [e1,e2,e3,e4] +med1, CI1 = fakeBootStrapper(1) +med2, CI2 = fakeBootStrapper(2) +medians = [None, None, med1, med2] +conf_intervals = [None, None, CI1, CI2] fig = plt.figure() ax = fig.add_subplot(111) pos = np.array(range(len(treatments)))+1 -bp = ax.boxplot( treatments, sym='k+', patch_artist=True, - positions=pos, notch=1, bootstrap=5000 ) -text_transform= mtransforms.blended_transform_factory(ax.transData, - ax.transAxes) +bp = ax.boxplot(treatments, sym='k+', positions=pos, + notch=1, bootstrap=5000, + usermedians=medians, + conf_intervals=conf_intervals) + ax.set_xlabel('treatment') ax.set_ylabel('response') -ax.set_ylim(-0.2, 1.4) plt.setp(bp['whiskers'], color='k', linestyle='-' ) plt.setp(bp['fliers'], markersize=3.0) -fig.subplots_adjust(right=0.99,top=0.99) plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/centered_ticklabels.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/centered_ticklabels.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/centered_ticklabels.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/centered_ticklabels.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,10 @@ # sometimes it is nice to have ticklabels centered. mpl currently # associates a label with a tick, and the label can be aligned -# 'center', 'feft', or 'right' using the horizontal alignment property: +# 'center', 'left', or 'right' using the horizontal alignment property: # # # for label in ax.xaxis.get_xticklabels(): -# label.set_horizntal_alignment('right') +# label.set_horizontalalignment('right') # # # but this doesn't help center the label between ticks. One solution @@ -21,7 +21,7 @@ import matplotlib.pyplot as plt # load some financial data; apple's stock price -fh = cbook.get_sample_data('aapl.npy') +fh = cbook.get_sample_data('aapl.npy.gz') r = np.load(fh); fh.close() r = r[-250:] # get the last 250 days diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/colorbar_tick_labelling_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/colorbar_tick_labelling_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/colorbar_tick_labelling_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/colorbar_tick_labelling_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -5,7 +5,7 @@ import matplotlib.pyplot as plt import numpy as np - +from matplotlib import cm from numpy.random import randn # Make plot with vertical (default) colorbar @@ -14,7 +14,7 @@ data = np.clip(randn(250, 250), -1, 1) -cax = ax.imshow(data, interpolation='nearest') +cax = ax.imshow(data, interpolation='nearest', cmap=cm.coolwarm) ax.set_title('Gaussian noise with vertical colorbar') # Add colorbar, make sure to specify tick locations to match desired ticklabels @@ -27,7 +27,7 @@ data = np.clip(randn(250, 250), -1, 1) -cax = ax.imshow(data, interpolation='nearest') +cax = ax.imshow(data, interpolation='nearest', cmap=cm.afmhot) ax.set_title('Gaussian noise with horizontal colorbar') cbar = fig.colorbar(cax, ticks=[-1, 0, 1], orientation='horizontal') diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/contour_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/contour_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/contour_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/contour_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -35,6 +35,16 @@ plt.title('Simplest default with labels') +# contour labels can be placed manually by providing list of positions +# (in data coordinate). See ginput_manual_clabel.py for interactive +# placement. +plt.figure() +CS = plt.contour(X, Y, Z) +manual_locations = [(-1, -1.4), (-0.62, -0.7), (-2, 0.5), (1.7, 1.2), (2.0, 1.4), (2.4, 1.7)] +plt.clabel(CS, inline=1, fontsize=10, manual=manual_locations) +plt.title('labels at selected locations') + + # You can force all the contours to be the same color. plt.figure() CS = plt.contour(X, Y, Z, 6, diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/contour_image.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/contour_image.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/contour_image.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/contour_image.py 2012-10-31 00:11:13.000000000 +0000 @@ -26,13 +26,17 @@ levels = arange(-2.0, 1.601, 0.4) # Boost the upper limit to avoid truncation # errors. +norm = cm.colors.Normalize(vmax=abs(Z).max(), vmin=-abs(Z).max()) +cmap = cm.PRGn + figure() subplot(2,2,1) cset1 = contourf(X, Y, Z, levels, - cmap=cm.get_cmap('jet', len(levels)-1), + cmap=cm.get_cmap(cmap, len(levels)-1), + norm=norm, ) # It is not necessary, but for the colormap, we need only the # number of levels minus 1. To avoid discretization error, use @@ -65,7 +69,7 @@ subplot(2,2,2) -imshow(Z, extent=extent) +imshow(Z, extent=extent, cmap=cmap, norm=norm) v = axis() contour(Z, levels, hold='on', colors = 'k', origin='upper', extent=extent) @@ -74,7 +78,7 @@ subplot(2,2,3) -imshow(Z, origin='lower', extent=extent) +imshow(Z, origin='lower', extent=extent, cmap=cmap, norm=norm) v = axis() contour(Z, levels, hold='on', colors = 'k', origin='lower', extent=extent) @@ -89,7 +93,7 @@ # This is intentional. The Z values are defined at the center of each # image pixel (each color block on the following subplot), so the # domain that is contoured does not extend beyond these pixel centers. -im = imshow(Z, interpolation='nearest', extent=extent) +im = imshow(Z, interpolation='nearest', extent=extent, cmap=cmap, norm=norm) v = axis() contour(Z, levels, hold='on', colors = 'k', origin='image', extent=extent) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/contour_label_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/contour_label_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/contour_label_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/contour_label_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -50,7 +50,11 @@ CS.levels = [nf(val) for val in CS.levels ] # Label levels with specially formatted floats -plt.clabel(CS, CS.levels, inline=True, fmt='%r %%', fontsize=10) +if plt.rcParams["text.usetex"]: + fmt = r'%r \%%' +else: + fmt = '%r %%' +plt.clabel(CS, CS.levels, inline=True, fmt=fmt, fontsize=10) ################################################## # Label contours with arbitrary strings using a diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/contourf_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/contourf_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/contourf_demo.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/contourf_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,39 +1,41 @@ #!/usr/bin/env python -from pylab import * +import numpy as np +import matplotlib.pyplot as plt + origin = 'lower' #origin = 'upper' delta = 0.025 -x = y = arange(-3.0, 3.01, delta) -X, Y = meshgrid(x, y) -Z1 = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) -Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1) +x = y = np.arange(-3.0, 3.01, delta) +X, Y = np.meshgrid(x, y) +Z1 = plt.mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) +Z2 = plt.mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1) Z = 10 * (Z1 - Z2) nr, nc = Z.shape # put NaNs in one corner: -Z[-nr//6:, -nc//6:] = nan +Z[-nr//6:, -nc//6:] = np.nan # contourf will convert these to masked -Z = ma.array(Z) +Z = np.ma.array(Z) # mask another corner: -Z[:nr//6, :nc//6] = ma.masked +Z[:nr//6, :nc//6] = np.ma.masked # mask a circle in the middle: -interior = sqrt((X**2) + (Y**2)) < 0.5 -Z[interior] = ma.masked +interior = np.sqrt((X**2) + (Y**2)) < 0.5 +Z[interior] = np.ma.masked # We are using automatic selection of contour levels; # this is usually not such a good idea, because they don't # occur on nice boundaries, but we do it here for purposes # of illustration. -CS = contourf(X, Y, Z, 10, # [-1, -0.1, 0, 0.1], +CS = plt.contourf(X, Y, Z, 10, # [-1, -0.1, 0, 0.1], #alpha=0.5, - cmap=cm.bone, + cmap=plt.cm.bone, origin=origin) # Note that in the following, we explicitly pass in a subset of @@ -41,28 +43,28 @@ # We could pass in additional levels to provide extra resolution, # or leave out the levels kwarg to use all of the original levels. -CS2 = contour(CS, levels=CS.levels[::2], +CS2 = plt.contour(CS, levels=CS.levels[::2], colors = 'r', origin=origin, hold='on') -title('Nonsense (3 masked regions)') -xlabel('word length anomaly') -ylabel('sentence length anomaly') +plt.title('Nonsense (3 masked regions)') +plt.xlabel('word length anomaly') +plt.ylabel('sentence length anomaly') # Make a colorbar for the ContourSet returned by the contourf call. -cbar = colorbar(CS) +cbar = plt.colorbar(CS) cbar.ax.set_ylabel('verbosity coefficient') # Add the contour line levels to the colorbar cbar.add_lines(CS2) -figure() +plt.figure() # Now make a contour plot with the levels specified, # and with the colormap generated automatically from a list # of colors. levels = [-1.5, -1, -0.5, 0, 0.5, 1] -CS3 = contourf(X, Y, Z, levels, +CS3 = plt.contourf(X, Y, Z, levels, colors = ('r', 'g', 'b'), origin=origin, extend='both') @@ -72,16 +74,34 @@ CS3.cmap.set_under('yellow') CS3.cmap.set_over('cyan') -CS4 = contour(X, Y, Z, levels, +CS4 = plt.contour(X, Y, Z, levels, colors = ('k',), linewidths = (3,), origin = origin) -title('Listed colors (3 masked regions)') -clabel(CS4, fmt = '%2.1f', colors = 'w', fontsize=14) +plt.title('Listed colors (3 masked regions)') +plt.clabel(CS4, fmt = '%2.1f', colors = 'w', fontsize=14) # Notice that the colorbar command gets all the information it # needs from the ContourSet object, CS3. -colorbar(CS3) +plt.colorbar(CS3) + +# Illustrate all 4 possible "extend" settings: +extends = ["neither", "both", "min", "max"] +cmap = plt.cm.get_cmap("winter") +cmap.set_under("magenta") +cmap.set_over("yellow") +# Note: contouring simply excludes masked or nan regions, so +# instead of using the "bad" colormap value for them, it draws +# nothing at all in them. Therefore the following would have +# no effect: +#cmap.set_bad("red") + +fig, axs = plt.subplots(2,2) +for ax, extend in zip(axs.ravel(), extends): + cs = ax.contourf(X, Y, Z, levels, cmap=cmap, extend=extend, origin=origin) + fig.colorbar(cs, ax=ax, shrink=0.9) + ax.set_title("extend = %s" % extend) + ax.locator_params(nbins=4) -show() +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/contourf_hatching.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/contourf_hatching.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/contourf_hatching.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/contourf_hatching.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,45 @@ +import matplotlib.pyplot as plt +import numpy as np + + +# invent some numbers, turning the x and y arrays into simple +# 2d arrays, which make combining them together easier. +x = np.linspace(-3, 5, 150).reshape(1, -1) +y = np.linspace(-3, 5, 120).reshape(-1, 1) +z = np.cos(x) + np.sin(y) + +# we no longer need x and y to be 2 dimensional, so flatten them. +x, y = x.flatten(), y.flatten() + + +# --------------------------------------------- +# | Plot #1 | +# --------------------------------------------- +# the simplest hatched plot with a colorbar +fig = plt.figure() +cs = plt.contourf(x, y, z, hatches=['-', '/', '\\', '//'], + cmap=plt.get_cmap('gray'), + extend='both', alpha=0.5 + ) +plt.colorbar() + + +# --------------------------------------------- +# | Plot #2 | +# --------------------------------------------- +# a plot of hatches without color with a legend +plt.figure() +n_levels = 6 +plt.contour(x, y, z, n_levels, colors='black', linestyles='-') +cs = plt.contourf(x, y, z, n_levels, colors='none', + hatches=['.', '/', '\\', None, '\\\\', '*'], + extend='lower' + ) + +# create a legend for the contour set +artists, labels = cs.legend_elements() +plt.legend(artists, labels, handleheight=2) + + + +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/contourf_log.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/contourf_log.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/contourf_log.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/contourf_log.py 2012-10-31 00:11:13.000000000 +0000 @@ -5,7 +5,7 @@ from matplotlib import pyplot as P import numpy as np from numpy import ma -from matplotlib import colors, ticker +from matplotlib import colors, ticker, cm from matplotlib.mlab import bivariate_normal N = 100 @@ -30,7 +30,7 @@ # Automatic selection of levels works; setting the # log locator tells contourf to use a log scale: -cs = P.contourf(X, Y, z, locator=ticker.LogLocator()) +cs = P.contourf(X, Y, z, locator=ticker.LogLocator(), cmap=cm.PuBu_r) # Alternatively, you can manually set the levels # and the norm: diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/coords_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/coords_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/coords_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/coords_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,8 +1,10 @@ #!/usr/bin/env python + """ An example of how to interact with the plotting canvas by connecting to move and click events """ +from __future__ import print_function import sys from pylab import * @@ -18,20 +20,20 @@ if event.inaxes: ax = event.inaxes # the axes instance - print 'data coords', event.xdata, event.ydata + print ('data coords %f %f' % (event.xdata, event.ydata)) def on_click(event): # get the x and y coords, flip y from top to bottom x, y = event.x, event.y if event.button==1: if event.inaxes is not None: - print 'data coords', event.xdata, event.ydata + print ('data coords %f %f' % (event.xdata, event.ydata)) binding_id = connect('motion_notify_event', on_move) connect('button_press_event', on_click) if "test_disconnect" in sys.argv: - print "disconnecting console coordinate printout..." + print ("disconnecting console coordinate printout...") disconnect(binding_id) show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/cursor_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/cursor_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/cursor_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/cursor_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,6 @@ #!/usr/bin/env python # -*- noplot -*- + """ This example shows how to use matplotlib to provide a data cursor. It @@ -9,6 +10,7 @@ Faster cursoring is possible using native GUI drawing, as in wxcursor_demo.py """ +from __future__ import print_function from pylab import * @@ -61,7 +63,7 @@ self.ly.set_xdata(x ) self.txt.set_text( 'x=%1.2f, y=%1.2f'%(x,y) ) - print 'x=%1.2f, y=%1.2f'%(x,y) + print ('x=%1.2f, y=%1.2f'%(x,y)) draw() t = arange(0.0, 1.0, 0.01) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/custom_cmap.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/custom_cmap.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/custom_cmap.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/custom_cmap.py 2012-10-31 00:11:13.000000000 +0000 @@ -103,6 +103,16 @@ (1.0, 0.0, 0.0)) } +# Make a modified version of cdict3 with some transparency +# in the middle of the range. +cdict4 = cdict3.copy() +cdict4['alpha'] = ((0.0, 1.0, 1.0), + # (0.25,1.0, 1.0), + (0.5, 0.3, 0.3), + # (0.75,1.0, 1.0), + (1.0, 1.0, 1.0)) + + # Now we will use this example to illustrate 3 ways of # handling custom colormaps. # First, the most direct and explicit: @@ -121,20 +131,27 @@ # leave everything to register_cmap: plt.register_cmap(name='BlueRed3', data=cdict3) # optional lut kwarg +plt.register_cmap(name='BlueRedAlpha', data=cdict4) + +# Make some illustrative fake data: x = np.arange(0, np.pi, 0.1) y = np.arange(0, 2*np.pi, 0.1) X, Y = np.meshgrid(x,y) -Z = np.cos(X) * np.sin(Y) +Z = np.cos(X) * np.sin(Y) * 10 + +# Make the figure: -plt.figure(figsize=(10,4)) -plt.subplots_adjust(wspace=0.3) +plt.figure(figsize=(6,9)) +plt.subplots_adjust(left=0.02, bottom=0.06, right=0.95, top=0.94, wspace=0.05) -plt.subplot(1,3,1) +# Make 4 subplots: + +plt.subplot(2,2,1) plt.imshow(Z, interpolation='nearest', cmap=blue_red1) plt.colorbar() -plt.subplot(1,3,2) +plt.subplot(2,2,2) cmap = plt.get_cmap('BlueRed2') plt.imshow(Z, interpolation='nearest', cmap=cmap) plt.colorbar() @@ -145,24 +162,32 @@ plt.rcParams['image.cmap'] = 'BlueRed3' -# Also see below for an alternative, particularly for -# interactive use. - -plt.subplot(1,3,3) +plt.subplot(2,2,3) plt.imshow(Z, interpolation='nearest') plt.colorbar() +plt.title("Alpha = 1") -# Or as yet another variation, we could replace the rcParams +# Or as yet another variation, we can replace the rcParams # specification *before* the imshow with the following *after* -# imshow: -# -# plt.set_cmap('BlueRed3') -# +# imshow. # This sets the new default *and* sets the colormap of the last # image-like item plotted via pyplot, if any. +# +plt.subplot(2,2,4) +# Draw a line with low zorder so it will be behind the image. +plt.plot([0, 10*np.pi], [0, 20*np.pi], color='c', lw=20, zorder=-1) + +plt.imshow(Z, interpolation='nearest') +plt.colorbar() + +# Here it is: changing the colormap for the current image and its +# colorbar after they have been plotted. +plt.set_cmap('BlueRedAlpha') +plt.title("Varying alpha") +# -plt.suptitle('Custom Blue-Red colormaps') +plt.suptitle('Custom Blue-Red colormaps', fontsize=16) plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/custom_figure_class.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/custom_figure_class.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/custom_figure_class.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/custom_figure_class.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,5 @@ """ -You can pass a custom Figure constructor to figure if youy want to derive from the default Figure. This simple example creates a figure with a figure title +You can pass a custom Figure constructor to figure if you want to derive from the default Figure. This simple example creates a figure with a figure title """ from matplotlib.pyplot import figure, show from matplotlib.figure import Figure diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/custom_ticker1.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/custom_ticker1.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/custom_ticker1.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/custom_ticker1.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,9 @@ #!/usr/bin/env python """ -The new ticker code was designed to explicity support user customized +The new ticker code was designed to explicitly support user customized ticking. The documentation -http://matplotlib.sourceforge.net/matplotlib.ticker.html details this +http://matplotlib.org/matplotlib.ticker.html details this process. That code defines a lot of preset tickers but was primarily designed to be user extensible. diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/customize_rc.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/customize_rc.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/customize_rc.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/customize_rc.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,6 @@ """ -I'm not trying to make a good liking figure here, but just to show +I'm not trying to make a good looking figure here, but just to show some examples of customizing rc params on the fly If you like to work interactively, and need to create different sets @@ -36,7 +36,7 @@ rc('xtick.major', size=5, pad=7) rc('xtick', labelsize=15) -# using aliases for color, linestyle and linewith; gray, solid, thick +# using aliases for color, linestyle and linewidth; gray, solid, thick rc('grid', c='0.5', ls='-', lw=5) rc('lines', lw=2, color='g') subplot(312) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/dashpointlabel.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/dashpointlabel.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/dashpointlabel.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/dashpointlabel.py 2012-10-31 00:11:13.000000000 +0000 @@ -21,7 +21,7 @@ (x,y) = zip(*DATA) ax.plot(x, y, marker='o') -for i in xrange(len(DATA)): +for i in range(len(DATA)): (x,y) = DATA[i] (dd, dl, r, dr, dp) = dash_style[i] #print 'dashlen call', dl diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/data_helper.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/data_helper.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/data_helper.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/data_helper.py 2012-10-31 00:11:13.000000000 +0000 @@ -11,13 +11,13 @@ """ ticker1, ticker2 = 'INTC', 'AAPL' - file1 = cbook.get_sample_data('INTC.dat', asfileobj=False) - file2 = cbook.get_sample_data('AAPL.dat', asfileobj=False) - M1 = fromstring( file(file1, 'rb').read(), ' 1: + fontname = sys.argv[1] +else: + fontname = os.path.join(matplotlib.get_data_path(), + 'fonts', 'ttf', 'Vera.ttf') + font = FT2Font(fontname) -codes = font.get_charmap().items() +codes = list(font.get_charmap().items()) codes.sort() # a 16,16 array of character strings -chars = [ ['' for c in range(16)] for r in range(16)] -colors = [ [(0.95,0.95,0.95) for c in range(16)] for r in range(16)] +chars = [['' for c in range(16)] for r in range(16)] +colors = [[(0.95, 0.95, 0.95) for c in range(16)] for r in range(16)] -figure(figsize=(8,4),dpi=120) +figure(figsize=(8, 4), dpi=120) for ccode, glyphind in codes: - if ccode>=256: continue - r,c = divmod(ccode,16) + if ccode >= 256: + continue + r, c = divmod(ccode, 16) s = unichr(ccode) chars[r][c] = s - - -lightgrn = (0.5,0.8,0.5) +lightgrn = (0.5, 0.8, 0.5) title(fontname) tab = table(cellText=chars, rowLabels=labelr, @@ -50,7 +64,7 @@ for key, cell in tab.get_celld().items(): row, col = key - if row>0 and col>0: - cell.set_text_props(fontproperties=FontProperties(fname=sys.argv[1])) + if row > 0 and col > 0: + cell.set_text_props(fontproperties=FontProperties(fname=fontname)) axis('off') show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/ganged_plots.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/ganged_plots.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/ganged_plots.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/ganged_plots.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,7 @@ #!/usr/bin/env python """ To create plots that share a common axes (visually) you can set the -hspace bewtween the subplots close to zero (do not use zero itself). +hspace between the subplots close to zero (do not use zero itself). Normally you'll want to turn off the tick labels on all but one of the axes. diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/ginput_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/ginput_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/ginput_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/ginput_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,11 @@ # -*- noplot -*- +from __future__ import print_function + from pylab import arange, plot, sin, ginput, show t = arange(10) plot(t, sin(t)) -print "Please click" +print("Please click") x = ginput(3) -print "clicked",x +print("clicked",x) show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/ginput_manual_clabel.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/ginput_manual_clabel.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/ginput_manual_clabel.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/ginput_manual_clabel.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python # -*- noplot -*- + +from __future__ import print_function """ This provides examples of uses of interactive functions, such as ginput, waitforbuttonpress and manual clabel placement. @@ -18,7 +20,7 @@ import matplotlib.pyplot as plt def tellme(s): - print s + print(s) plt.title(s,fontsize=16) plt.draw() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/griddata_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/griddata_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/griddata_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/griddata_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -16,7 +16,8 @@ zi = griddata(x,y,z,xi,yi,interp='linear') # contour the gridded data, plotting dots at the nonuniform data points. CS = plt.contour(xi,yi,zi,15,linewidths=0.5,colors='k') -CS = plt.contourf(xi,yi,zi,15,cmap=plt.cm.jet) +CS = plt.contourf(xi,yi,zi,15,cmap=plt.cm.rainbow, + vmax=abs(zi).max(), vmin=-abs(zi).max()) plt.colorbar() # draw colorbar # plot data points. plt.scatter(x,y,marker='o',c='b',s=5,zorder=10) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/hexbin_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/hexbin_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/hexbin_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/hexbin_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -6,9 +6,9 @@ """ import numpy as np -import matplotlib.cm as cm -import matplotlib.pyplot as plt +import matplotlib.pyplot as plt +np.random.seed(0) n = 100000 x = np.random.standard_normal(n) y = 2.0 + 3.0 * x + 4.0 * np.random.standard_normal(n) @@ -19,18 +19,17 @@ plt.subplots_adjust(hspace=0.5) plt.subplot(121) -plt.hexbin(x,y, cmap=cm.jet) +plt.hexbin(x,y, cmap=plt.cm.YlOrRd_r) plt.axis([xmin, xmax, ymin, ymax]) plt.title("Hexagon binning") cb = plt.colorbar() cb.set_label('counts') plt.subplot(122) -plt.hexbin(x,y,bins='log', cmap=cm.jet) +plt.hexbin(x,y,bins='log', cmap=plt.cm.YlOrRd_r) plt.axis([xmin, xmax, ymin, ymax]) plt.title("With a log color scale") cb = plt.colorbar() cb.set_label('log10(N)') plt.show() - diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/hexbin_demo2.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/hexbin_demo2.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/hexbin_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/hexbin_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -39,14 +39,15 @@ gridsize=30 plt.subplot(211) -plt.hexbin(x,y, C=z, gridsize=gridsize, marginals=True) +plt.hexbin(x,y, C=z, gridsize=gridsize, marginals=True, cmap=plt.cm.RdBu, + vmax=abs(z).max(), vmin=-abs(z).max()) plt.axis([xmin, xmax, ymin, ymax]) cb = plt.colorbar() cb.set_label('mean value') plt.subplot(212) -plt.hexbin(x,y, gridsize=gridsize) +plt.hexbin(x,y, gridsize=gridsize, cmap=plt.cm.Blues_r) plt.axis([xmin, xmax, ymin, ymax]) cb = plt.colorbar() cb.set_label('N observations') diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/hist2d_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/hist2d_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/hist2d_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/hist2d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,7 @@ +from pylab import * +x = randn(1000) +y = randn(1000)+5 + +#normal distribution center at x=0 and y=5 +hist2d(x,y,bins=40) +show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/hist2d_log_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/hist2d_log_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/hist2d_log_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/hist2d_log_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,10 @@ +from matplotlib.colors import LogNorm +from pylab import * + +#normal distribution center at x=0 and y=5 +x = randn(100000) +y = randn(100000)+5 + +hist2d(x, y, bins=40, norm=LogNorm()) +colorbar() +show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/histogram_demo_extended.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/histogram_demo_extended.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/histogram_demo_extended.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/histogram_demo_extended.py 2012-10-31 00:11:13.000000000 +0000 @@ -82,7 +82,19 @@ # P.figure() -n, bins, patches = P.hist(x, 10, normed=1, histtype='barstacked') +n, bins, patches = P.hist(x, 10, normed=1, histtype='bar', stacked=True) + +P.show() + +# +# we can also stack using the step histtype +# + +P.figure() + +n, bins, patches = P.hist(x, 10, histtype='step', stacked=True, fill=True) + +P.show() # # finally: make a multiple-histogram of data-sets with different length diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/histogram_percent_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/histogram_percent_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/histogram_percent_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/histogram_percent_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,29 @@ +import matplotlib +from numpy.random import randn +import matplotlib.pyplot as plt +from matplotlib.ticker import FuncFormatter + +def to_percent(y, position): + # Ignore the passed in position. This has the effect of scaling the default + # tick locations. + s = str(100 * y) + + # The percent symbol needs escaping in latex + if matplotlib.rcParams['text.usetex'] == True: + return s + r'$\%$' + else: + return s + '%' + +x = randn(5000) + +# Make a normed histogram. It'll be multiplied by 100 later. +plt.hist(x, bins=50, normed=True) + +# Create the formatter using the function to_percent. This multiplies all the +# default labels by 100, making them all percentages +formatter = FuncFormatter(to_percent) + +# Set the formatter +plt.gca().yaxis.set_major_formatter(formatter) + +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/image_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/image_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/image_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/image_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -11,8 +11,9 @@ Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1) Z = Z2-Z1 # difference of Gaussians -im = plt.imshow(Z, interpolation='bilinear', cmap=cm.gray, - origin='lower', extent=[-3,3,-3,3]) +im = plt.imshow(Z, interpolation='bilinear', cmap=cm.RdYlGn, + origin='lower', extent=[-3,3,-3,3], + vmax=abs(Z).max(), vmin=-abs(Z).max()) plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/image_demo2.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/image_demo2.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/image_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/image_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,12 +1,13 @@ #!/usr/bin/env python + +from __future__ import print_function from pylab import * import matplotlib.cbook as cbook w, h = 512, 512 -datafile = cbook.get_sample_data('ct.raw', asfileobj=False) -print 'loading', datafile -s = file(datafile, 'rb').read() +datafile = cbook.get_sample_data('ct.raw.gz', asfileobj=True) +s = datafile.read() A = fromstring(s, uint16).astype(float) A *= 1.0/max(A) A.shape = w, h @@ -33,4 +34,3 @@ setp(gca(), 'xticklabels', []) show() - diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/image_demo3.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/image_demo3.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/image_demo3.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/image_demo3.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,7 +2,7 @@ from pylab import * try: from PIL import Image -except ImportError, exc: +except ImportError: raise SystemExit("PIL must be installed to run this example") import matplotlib.cbook as cbook @@ -15,7 +15,7 @@ figure(figsize=figsize) ax = axes([0,0,1,1], frameon=False) ax.set_axis_off() -im = imshow(lena, origin='lower') +im = imshow(lena) show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/image_nonuniform.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/image_nonuniform.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/image_nonuniform.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/image_nonuniform.py 2012-10-31 00:11:13.000000000 +0000 @@ -7,6 +7,7 @@ from matplotlib.pyplot import figure, show import numpy as np from matplotlib.image import NonUniformImage +from matplotlib import cm interp='nearest' @@ -19,7 +20,8 @@ fig = figure() fig.suptitle('NonUniformImage class') ax = fig.add_subplot(221) -im = NonUniformImage(ax, interpolation=interp, extent=(-4,4,-4,4)) +im = NonUniformImage(ax, interpolation=interp, extent=(-4,4,-4,4), + cmap=cm.Purples) im.set_data(x, y, z) ax.images.append(im) ax.set_xlim(-4,4) @@ -27,7 +29,8 @@ ax.set_title(interp) ax = fig.add_subplot(222) -im = NonUniformImage(ax, interpolation=interp, extent=(-64,64,-4,4)) +im = NonUniformImage(ax, interpolation=interp, extent=(-64,64,-4,4), + cmap=cm.Purples) im.set_data(x2, y, z) ax.images.append(im) ax.set_xlim(-64,64) @@ -37,7 +40,8 @@ interp = 'bilinear' ax = fig.add_subplot(223) -im = NonUniformImage(ax, interpolation=interp, extent=(-4,4,-4,4)) +im = NonUniformImage(ax, interpolation=interp, extent=(-4,4,-4,4), + cmap=cm.Purples) im.set_data(x, y, z) ax.images.append(im) ax.set_xlim(-4,4) @@ -45,7 +49,8 @@ ax.set_title(interp) ax = fig.add_subplot(224) -im = NonUniformImage(ax, interpolation=interp, extent=(-64,64,-4,4)) +im = NonUniformImage(ax, interpolation=interp, extent=(-64,64,-4,4), + cmap=cm.Purples) im.set_data(x2, y, z) ax.images.append(im) ax.set_xlim(-64,64) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/image_origin.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/image_origin.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/image_origin.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/image_origin.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,7 +3,7 @@ You can specify whether images should be plotted with the array origin x[0,0] in the upper left or upper right by using the origin parameter. You can also control the default be setting image.origin in your -matplotlibrc file; see http://matplotlib.sourceforge.net/matplotlibrc +matplotlibrc file; see http://matplotlib.org/matplotlibrc """ from pylab import * diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/image_slices_viewer.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/image_slices_viewer.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/image_slices_viewer.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/image_slices_viewer.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import numpy from matplotlib.pyplot import figure, show @@ -17,7 +18,7 @@ self.update() def onscroll(self, event): - print event.button, event.step + print ("%s %s" % (event.button, event.step)) if event.button=='up': self.ind = numpy.clip(self.ind+1, 0, self.slices-1) else: diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/integral_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/integral_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/integral_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/integral_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -17,7 +17,7 @@ # make the shaded region ix = arange(a, b, 0.01) iy = func(ix) -verts = [(a,0)] + zip(ix,iy) + [(b,0)] +verts = [(a,0)] + list(zip(ix,iy)) + [(b,0)] poly = Polygon(verts, facecolor='0.8', edgecolor='k') ax.add_patch(poly) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/line_collection2.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/line_collection2.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/line_collection2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/line_collection2.py 2012-10-31 00:11:13.000000000 +0000 @@ -21,7 +21,7 @@ # where onoffseq is an even length tuple of on and off ink in points. # If linestyle is omitted, 'solid' is used # See matplotlib.collections.LineCollection for more information -line_segments = LineCollection([zip(x,y) for y in ys], # Make a sequence of x,y pairs +line_segments = LineCollection([list(zip(x,y)) for y in ys], # Make a sequence of x,y pairs linewidths = (0.5,1,1.5,2), linestyles = 'solid') line_segments.set_array(x) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/load_converter.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/load_converter.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/load_converter.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/load_converter.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function from matplotlib.dates import strpdate2num #from matplotlib.mlab import load import numpy as np @@ -5,7 +6,7 @@ import matplotlib.cbook as cbook datafile = cbook.get_sample_data('msft.csv', asfileobj=False) -print 'loading', datafile +print('loading', datafile) dates, closes = np.loadtxt( datafile, delimiter=',', diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/loadrec.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/loadrec.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/loadrec.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/loadrec.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,12 +1,13 @@ +from __future__ import print_function from matplotlib import mlab from pylab import figure, show import matplotlib.cbook as cbook datafile = cbook.get_sample_data('msft.csv', asfileobj=False) -print 'loading', datafile +print('loading', datafile) a = mlab.csv2rec(datafile) a.sort() -print a.dtype +print(a.dtype) fig = figure() ax = fig.add_subplot(111) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/logo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/logo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/logo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/logo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,11 +1,13 @@ #!/usr/bin/env python # This file generates the matplotlib web page logo + +from __future__ import print_function from pylab import * import matplotlib.cbook as cbook # convert data to mV datafile = cbook.get_sample_data('membrane.dat', asfileobj=False) -print 'loading', datafile +print('loading', datafile) x = 1000*0.1*fromstring(file(datafile, 'rb').read(), float32) # 0.0005 is the sample interval diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/major_minor_demo1.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/major_minor_demo1.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/major_minor_demo1.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/major_minor_demo1.py 2012-10-31 00:11:13.000000000 +0000 @@ -19,7 +19,7 @@ some base. The FormatStrFormatter uses a string format string (eg '%d' or '%1.2f' or '%1.1f cm' ) to format the tick -The pylab interface grid command chnages the grid settings of the +The pylab interface grid command changes the grid settings of the major ticks of the y and y axis together. If you want to control the grid of the minor ticks for a given axis, use for example diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/manual_axis.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/manual_axis.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/manual_axis.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/manual_axis.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,7 @@ """ The techniques here are no longer required with the new support for spines in matplotlib -- see -http://matplotlib.sourceforge.net/examples/pylab_examples/spine_placement_demo.html. +http://matplotlib.org/examples/pylab_examples/spine_placement_demo.html. This example should be considered deprecated and is left just for demo purposes for folks wanting to make a pseudo-axis @@ -55,4 +55,3 @@ make_yaxis(ax, 0, offset=5, **props) show() - diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/mathtext_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/mathtext_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/mathtext_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/mathtext_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,6 @@ #!/usr/bin/env python """ -Use matplotlib's internal LaTex parser and layout engine. For true +Use matplotlib's internal LaTeX parser and layout engine. For true latex rendering, see the text.usetex option """ import numpy as np diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/mathtext_examples.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/mathtext_examples.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/mathtext_examples.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/mathtext_examples.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import print_function + import os, sys, re import gc @@ -38,7 +40,7 @@ r"$\gamma = \frac{x=\frac{6}{8}}{y} \delta$", r'$\limsup_{x\to\infty}$', r'$\oint^\infty_0$', - r"$f^\prime$", + r"$f^'$", r'$\frac{x_2888}{y}$', r"$\sqrt[3]{\frac{X_2}{Y}}=5$", r"$\sqrt[5]{\prod^\frac{x}{2\pi^2}_\infty}$", diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/movie_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/movie_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/movie_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/movie_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,8 @@ #!/usr/bin/env python # -*- noplot -*- +from __future__ import print_function + import os, sys from pylab import * @@ -11,11 +13,11 @@ cla() imshow(rand(5,5), interpolation='nearest') fname = '_tmp%03d.png'%i - print 'Saving frame', fname + print('Saving frame', fname) savefig(fname) files.append(fname) -print 'Making movie animation.mpg - this make take a while' +print('Making movie animation.mpg - this make take a while') os.system("mencoder 'mf://_tmp*.png' -mf type=png:fps=10 -ovc lavc -lavcopts vcodec=wmv2 -oac copy -o animation.mpg") #os.system("convert _tmp*.png animation.mng") diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/mri_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/mri_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/mri_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/mri_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,14 +1,15 @@ #!/usr/bin/env python + +from __future__ import print_function from pylab import * import matplotlib.cbook as cbook # data are 256x256 16 bit integers -dfile = cbook.get_sample_data('s1045.ima', asfileobj=False) -print 'loading image', dfile -im = np.fromstring(file(dfile, 'rb').read(), np.uint16).astype(float) +dfile = cbook.get_sample_data('s1045.ima.gz') +im = np.fromstring(dfile.read(), np.uint16).astype(float) im.shape = 256, 256 #imshow(im, ColormapJet(256)) -imshow(im, cmap=cm.jet) +imshow(im, cmap=cm.gray) axis('off') show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/mri_with_eeg.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/mri_with_eeg.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/mri_with_eeg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/mri_with_eeg.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,10 @@ #!/usr/bin/env python + """ This now uses the imshow command instead of pcolor which *is much faster* """ -from __future__ import division +from __future__ import division, print_function import numpy as np @@ -14,14 +15,13 @@ if 1: # load the data # data are 256x256 16 bit integers - dfile = cbook.get_sample_data('s1045.ima', asfileobj=False) - print 'loading image', dfile - im = np.fromstring(file(dfile, 'rb').read(), np.uint16).astype(float) + dfile = cbook.get_sample_data('s1045.ima.gz') + im = np.fromstring(dfile.read(), np.uint16).astype(float) im.shape = 256, 256 if 1: # plot the MRI in pcolor subplot(221) - imshow(im, cmap=cm.jet) + imshow(im, cmap=cm.gray) axis('off') if 1: # plot the histogram of MRI intensity @@ -40,8 +40,8 @@ numSamples, numRows = 800,4 eegfile = cbook.get_sample_data('eeg.dat', asfileobj=False) - print 'loading eeg', eegfile - data = np.fromstring(file(eegfile, 'rb').read(), float) + print ('loading eeg %s' % eegfile) + data = np.fromstring(open(eegfile, 'rb').read(), float) data.shape = numSamples, numRows t = 10.0 * np.arange(numSamples, dtype=float)/numSamples ticklocs = [] diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/pcolor_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/pcolor_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/pcolor_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/pcolor_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -19,7 +19,7 @@ X,Y = meshgrid(x, y) Z = func3(X, Y) -pcolor(X, Y, Z) +pcolor(X, Y, Z, cmap=cm.RdBu, vmax=abs(Z).max(), vmin=-abs(Z).max()) colorbar() axis([-3,3,-3,3]) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/pcolor_demo2.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/pcolor_demo2.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/pcolor_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/pcolor_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -20,7 +20,7 @@ ax = subplot(111) -im = imshow(Z, cmap=cm.jet) +im = imshow(Z, cmap=cm.RdBu, vmax=abs(Z).max(), vmin=-abs(Z).max()) #im.set_interpolation('nearest') #im.set_interpolation('bicubic') im.set_interpolation('bilinear') diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/pcolor_log.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/pcolor_log.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/pcolor_log.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/pcolor_log.py 2012-10-31 00:11:13.000000000 +0000 @@ -15,11 +15,11 @@ Z1 = bivariate_normal(X, Y, 0.1, 0.2, 1.0, 1.0) + 0.1*bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) subplot(2,1,1) -pcolor(X, Y, Z1, norm=LogNorm(vmin=Z1.min(), vmax=Z1.max())) +pcolor(X, Y, Z1, norm=LogNorm(vmin=Z1.min(), vmax=Z1.max()), cmap=cm.PuBu_r) colorbar() subplot(2,1,2) -pcolor(X, Y, Z1) +pcolor(X, Y, Z1, cmap=cm.PuBu_r) colorbar() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/pie_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/pie_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/pie_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/pie_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,10 +3,8 @@ http://matplotlib.sf.net/matplotlib.pylab.html#-pie for the docstring. This example shows a basic pie chart with labels optional features, -like autolabeling the percentage, offsetting a slice with "explode" -and adding a shadow. - -Requires matplotlib0-0.70 or later +like autolabeling the percentage, offsetting a slice with "explode", +adding a shadow, and changing the starting angle. """ from pylab import * @@ -15,11 +13,18 @@ figure(1, figsize=(6,6)) ax = axes([0.1, 0.1, 0.8, 0.8]) +# The slices will be ordered and plotted counter-clockwise. labels = 'Frogs', 'Hogs', 'Dogs', 'Logs' -fracs = [15,30,45, 10] - +fracs = [15, 30, 45, 10] explode=(0, 0.05, 0, 0) -pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%', shadow=True) + +pie(fracs, explode=explode, labels=labels, + autopct='%1.1f%%', shadow=True, startangle=90) + # The default startangle is 0, which would start + # the Frogs slice on the x-axis. With startangle=90, + # everything is rotated counter-clockwise by 90 degrees, + # so the plotting starts on the positive y-axis. + title('Raining Hogs and Dogs', bbox={'facecolor':'0.8', 'pad':5}) show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/pie_demo2.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/pie_demo2.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/pie_demo2.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/pie_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,60 @@ +""" +Make a pie charts of varying size - see +http://matplotlib.sf.net/matplotlib.pylab.html#-pie for the docstring. + +This example shows a basic pie charts with labels optional features, +like autolabeling the percentage, offsetting a slice with "explode" +and adding a shadow, in different sizes. + +""" +from pylab import * +from matplotlib.gridspec import GridSpec + +# Some data + +labels = 'Frogs', 'Hogs', 'Dogs', 'Logs' +fracs = [15,30,45, 10] + +explode=(0, 0.05, 0, 0) + +# Make square figures and axes + +the_grid = GridSpec(2, 2) + +figure(1, figsize=(6,6)) + +subplot(the_grid[0, 0]) + +pie(fracs, labels=labels, autopct='%1.1f%%', shadow=True) + +subplot(the_grid[0, 1]) + +pie(fracs, explode=explode, labels=labels, autopct='%.0f%%', shadow=True) + +subplot(the_grid[1, 0]) + +patches, texts, autotexts = pie(fracs, labels=labels, + autopct='%.0f%%', + shadow=True, radius=0.5) + +# Make the labels on the small plot easier to read. +for t in texts: + t.set_size('smaller') +for t in autotexts: + t.set_size('x-small') +autotexts[0].set_color('y') + +subplot(the_grid[1, 1]) + +patches, texts, autotexts = pie(fracs, explode=explode, + labels=labels, autopct='%.0f%%', + shadow=False, radius=0.5) + # Turn off shadow for tiny plot + # with exploded slice. +for t in texts: + t.set_size('smaller') +for t in autotexts: + t.set_size('x-small') +autotexts[0].set_color('y') + +show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/polar_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/polar_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/polar_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/polar_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -9,7 +9,7 @@ # PolarAxes) -- other axes plotting functions may work on PolarAxes # but haven't been tested and may need tweaking. # -# you can get get a PolarSubplot instance by doing, for example +# you can get a PolarSubplot instance by doing, for example # # subplot(211, polar=True) # diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/polar_scatter.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/polar_scatter.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/polar_scatter.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/polar_scatter.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,8 +1,8 @@ #!/usr/bin/env python # a polar scatter plot; size increases radially in this example and # color increases with angle (just to verify the symbols are being -# scattered correctlu). In a real example, this would be wasting -# dimensionlaity of the plot +# scattered correctly). In a real example, this would be wasting +# dimensionality of the plot from pylab import * N = 150 @@ -11,8 +11,7 @@ area = 200*r**2*rand(N) colors = theta ax = subplot(111, polar=True) -c = scatter(theta, r, c=colors, s=area) +c = scatter(theta, r, c=colors, s=area, cmap=cm.hsv) c.set_alpha(0.75) - show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/poormans_contour.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/poormans_contour.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/poormans_contour.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/poormans_contour.py 2012-10-31 00:11:13.000000000 +0000 @@ -18,9 +18,10 @@ Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1) Z = Z2 - Z1 # difference of Gaussians -cmap = cm.get_cmap('jet', 10) # 10 discrete colors +cmap = cm.get_cmap('PiYG', 11) # 11 discrete colors -im = imshow(Z, cmap=cmap, interpolation='bilinear') +im = imshow(Z, cmap=cmap, interpolation='bilinear', + vmax=abs(Z).max(), vmin=-abs(Z).max()) axis('off') colorbar() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/psd_demo2.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/psd_demo2.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/psd_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/psd_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -22,7 +22,7 @@ ax2.psd(y, NFFT=len(t), pad_to=len(t)*4, Fs=fs) plt.title('zero padding') -#Plot the PSD with different block sizes, Zero pad to the length of the orignal +#Plot the PSD with different block sizes, Zero pad to the length of the original #data sequence. ax3 = fig.add_subplot(2, 3, 5, sharex=ax2, sharey=ax2) ax3.psd(y, NFFT=len(t), pad_to=len(t), Fs=fs) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/pythonic_matplotlib.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/pythonic_matplotlib.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/pythonic_matplotlib.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/pythonic_matplotlib.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,7 @@ #!/usr/bin/env python """ Some people prefer to write more pythonic, object oriented, code -rather than use the pylab interface to matplotlib. This example show +rather than use the pylab interface to matplotlib. This example shows you how. Unless you are an application developer, I recommend using part of the diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/scatter_custom_symbol.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/scatter_custom_symbol.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/scatter_custom_symbol.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/scatter_custom_symbol.py 2012-10-31 00:11:13.000000000 +0000 @@ -6,7 +6,7 @@ rx, ry = 3., 1. area = rx * ry * pi theta = arange(0, 2*pi+0.01, 0.1) -verts = zip(rx/area*cos(theta), ry/area*sin(theta)) +verts = list(zip(rx/area*cos(theta), ry/area*sin(theta))) x,y,s,c = rand(4, 30) s*= 10**2. diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/scatter_profile.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/scatter_profile.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/scatter_profile.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/scatter_profile.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,6 @@ #!/usr/bin/env python # -*- noplot -*- + """ N Classic Base renderer Ext renderer 20 0.22 0.14 0.14 @@ -8,15 +9,16 @@ 10000 3.30 1.31 0.53 50000 19.30 6.53 1.98 """ -from pylab import * +from __future__ import print_function +import pylab import time for N in (20,100,1000,10000,50000): tstart = time.time() - x = 0.9*rand(N) - y = 0.9*rand(N) - s = 20*rand(N) - scatter(x,y,s) - print '%d symbols in %1.2f s' % (N, time.time()-tstart) + x = 0.9*pylab.rand(N) + y = 0.9*pylab.rand(N) + s = 20*pylab.rand(N) + pylab.scatter(x,y,s) + print ('%d symbols in %1.2f s' % (N, time.time()-tstart)) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/scatter_star_poly.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/scatter_star_poly.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/scatter_star_poly.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/scatter_star_poly.py 2012-10-31 00:11:13.000000000 +0000 @@ -12,7 +12,7 @@ plt.subplot(322) plt.scatter(x,y,s=80, c=z, marker=(5,0)) -verts = zip([-1.,1.,1.,-1.],[-1.,-1.,1.,-1.]) +verts = list(zip([-1.,1.,1.,-1.],[-1.,-1.,1.,-1.])) plt.subplot(323) plt.scatter(x,y,s=80, c=z, marker=(verts,0)) # equivalent: diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/set_and_get.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/set_and_get.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/set_and_get.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/set_and_get.py 2012-10-31 00:11:13.000000000 +0000 @@ -21,8 +21,8 @@ >>> setp(line) set operates on a single instance or a list of instances. If you are - in quey mode introspecting the possible values, only the first - instance in the sequnce is used. When actually setting values, all + in query mode introspecting the possible values, only the first + instance in the sequence is used. When actually setting values, all the instances will be set. Eg, suppose you have a list of two lines, the following will make both lines thicker and red @@ -52,7 +52,7 @@ color = b ... long listing skipped ... -Alisases: +Aliases: To reduce keystrokes in interactive mode, a number of properties have short aliases, eg 'lw' for 'linewidth' and 'mec' for @@ -64,6 +64,7 @@ """ +from __future__ import print_function from pylab import * @@ -77,20 +78,20 @@ setp(l2, linewidth=1, color='g') # line2 is thicker and green -print 'Line setters' +print ('Line setters') setp(l1) -print 'Line getters' +print ('Line getters') getp(l1) -print 'Rectangle setters' +print ('Rectangle setters') setp(gca().patch) -print 'Rectangle getters' +print ('Rectangle getters') getp(gca().patch) t = title('Hi mom') -print 'Text setters' +print ('Text setters') setp(t) -print 'Text getters' +print ('Text getters') getp(t) show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/shading_example.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/shading_example.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/shading_example.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/shading_example.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,7 +3,7 @@ from matplotlib.colors import LightSource # example showing how to make shaded relief plots -# like mathematica +# like Mathematica # (http://reference.wolfram.com/mathematica/ref/ReliefPlot.html) # or Generic Mapping Tools # (http://gmt.soest.hawaii.edu/gmt/doc/gmt/html/GMT_Docs/node145.html) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/simple_plot.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/simple_plot.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/simple_plot.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/simple_plot.py 2012-11-01 19:19:04.000000000 +0000 @@ -8,4 +8,5 @@ ylabel('voltage (mV)') title('About as simple as it gets, folks') grid(True) +savefig("test.png") show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/simple_plot_fps.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/simple_plot_fps.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/simple_plot_fps.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/simple_plot_fps.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,11 @@ #!/usr/bin/env python + """ Example: simple line plot. Show how to make and save a simple line plot with labels, title and grid """ # -*- noplot -*- +from __future__ import print_function from pylab import * ion() @@ -22,11 +24,11 @@ frames = 100.0 t = time.time() c = time.clock() -for i in xrange(int(frames)): +for i in range(int(frames)): part = i / frames axis([0.0, 1.0 - part, -1.0 + part, 1.0 - part]) wallclock = time.time() - t user = time.clock() - c -print "wallclock:", wallclock -print "user:", user -print "fps:", frames / wallclock +print ("wallclock:", wallclock) +print ("user:", user) +print ("fps:", frames / wallclock) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/specgram_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/specgram_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/specgram_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/specgram_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -25,5 +25,6 @@ ax1 = subplot(211) plot(t, x) subplot(212, sharex=ax1) -Pxx, freqs, bins, im = specgram(x, NFFT=NFFT, Fs=Fs, noverlap=900) +Pxx, freqs, bins, im = specgram(x, NFFT=NFFT, Fs=Fs, noverlap=900, + cmap=cm.gist_heat) show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/spine_placement_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/spine_placement_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/spine_placement_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/spine_placement_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +import sys import matplotlib.pyplot as plt import numpy as np from matplotlib.pyplot import show @@ -8,7 +9,7 @@ ax = fig.add_subplot(1,2,1) ax.set_title('dropped spines') ax.plot(x,y) -for loc, spine in ax.spines.iteritems(): +for loc, spine in ax.spines.items(): if loc in ['left','bottom']: spine.set_position(('outward',10)) # outward by 10 points elif loc in ['right','top']: @@ -80,7 +81,7 @@ # ---------------------------------------------------- def adjust_spines(ax,spines): - for loc, spine in ax.spines.iteritems(): + for loc, spine in ax.spines.items(): if loc in spines: spine.set_position(('outward',10)) # outward by 10 points spine.set_smart_bounds(True) @@ -141,7 +142,10 @@ # x ax.set_xlim((0,2*np.pi)) ax.set_xticks([0,np.pi,2*np.pi]) -pichr = unichr(0x03C0) +if sys.version_info[0] < 3: + pichr = unichr(0x03C0) +else: + pichr = chr(0x03C0) ax.set_xticklabels(['0',pichr,'2 '+pichr]) # y diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/stackplot_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/stackplot_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/stackplot_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/stackplot_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,18 @@ +import numpy as np +from matplotlib import pyplot as plt + +fnx = lambda : np.random.randint(5, 50, 10) +y = np.row_stack((fnx(), fnx(), fnx())) +x = np.arange(10) + +y1, y2, y3 = fnx(), fnx(), fnx() + +fig = plt.figure() +ax = fig.add_subplot(111) +ax.stackplot(x, y) +plt.show() + +fig = plt.figure() +ax = fig.add_subplot(111) +ax.stackplot(x, y1, y2, y3) +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/stix_fonts_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/stix_fonts_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/stix_fonts_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/stix_fonts_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import unicode_literals + import os, sys, re import gc @@ -17,9 +19,6 @@ if sys.maxunicode > 0xffff: s = r'Direct Unicode: $\u23ce \mathrm{\ue0f2 \U0001D538}$' - stests.append( - unicode(s, encoding="unicode_escape") - ) from pylab import * diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/streamplot_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/streamplot_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/streamplot_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/streamplot_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,19 @@ +import numpy as np +import matplotlib.pyplot as plt + +Y, X = np.mgrid[-3:3:100j, -3:3:100j] +U = -1 - X**2 + Y +V = 1 + X - Y**2 +speed = np.sqrt(U*U + V*V) + +plt.streamplot(X, Y, U, V, color=U, linewidth=2, cmap=plt.cm.autumn) +plt.colorbar() + +f, (ax1, ax2) = plt.subplots(ncols=2) +ax1.streamplot(X, Y, U, V, density=[0.5, 1]) + +lw = 5*speed/speed.max() +ax2.streamplot(X, Y, U, V, density=0.6, color='k', linewidth=lw) + +plt.show() + diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/streamplot_with_mask.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/streamplot_with_mask.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/streamplot_with_mask.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/streamplot_with_mask.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,23 @@ +""" +Demonstrate the use of the `streamplot` function using a masked array +and NaN values. +""" +import numpy as np +import matplotlib.pyplot as plt + +w = 3 +Y, X = np.mgrid[-w:w:100j, -w:w:100j] +U = -1 - X**2 + Y +V = 1 + X - Y**2 +speed = np.sqrt(U*U + V*V) + +mask = np.zeros(U.shape, dtype=bool) +mask[40:60, 40:60] = 1 +U = np.ma.array(U, mask=mask) +U[:20, :20] = np.nan + +plt.streamplot(X, Y, U, V, color='r') +plt.imshow(~mask, extent=(-w, w, -w, w), alpha=0.5, interpolation='nearest') + +plt.show() + diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/subplots_adjust.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/subplots_adjust.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/subplots_adjust.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/subplots_adjust.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,9 +2,9 @@ subplot(211) -imshow(rand(100,100)) +imshow(rand(100,100), cmap=cm.BuPu_r) subplot(212) -imshow(rand(100,100)) +imshow(rand(100,100), cmap=cm.BuPu_r) subplots_adjust(bottom=0.1, right=0.8, top=0.9) cax = axes([0.85, 0.1, 0.075, 0.8]) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/subplots_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/subplots_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/subplots_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/subplots_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -10,8 +10,8 @@ import numpy as np # Simple data to display in various forms -x = np.linspace(0, 2*np.pi, 400) -y = np.sin(x**2) +x = np.linspace(0, 2 * np.pi, 400) +y = np.sin(x ** 2) plt.close('all') @@ -37,25 +37,33 @@ ax1.plot(x, y) ax1.set_title('Sharing both axes') ax2.scatter(x, y) -ax3.scatter(x, 2*y**2-1,color='r') +ax3.scatter(x, 2 * y ** 2 - 1, color='r') # Fine-tune figure; make subplots close to each other and hide x ticks for # all but bottom plot. f.subplots_adjust(hspace=0) plt.setp([a.get_xticklabels() for a in f.axes[:-1]], visible=False) +# row and column sharing +f, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, sharex='col', sharey='row') +ax1.plot(x, y) +ax1.set_title('Sharing x per column, y per row') +ax2.scatter(x, y) +ax3.scatter(x, 2 * y ** 2 - 1, color='r') +ax4.plot(x, 2 * y ** 2 - 1, color='r') + # Four axes, returned as a 2-d array f, axarr = plt.subplots(2, 2) -axarr[0,0].plot(x, y) -axarr[0,0].set_title('Axis [0,0]') -axarr[0,1].scatter(x, y) -axarr[0,1].set_title('Axis [0,1]') -axarr[1,0].plot(x, y**2) -axarr[1,0].set_title('Axis [1,0]') -axarr[1,1].scatter(x, y**2) -axarr[1,1].set_title('Axis [1,1]') +axarr[0, 0].plot(x, y) +axarr[0, 0].set_title('Axis [0,0]') +axarr[0, 1].scatter(x, y) +axarr[0, 1].set_title('Axis [0,1]') +axarr[1, 0].plot(x, y ** 2) +axarr[1, 0].set_title('Axis [1,0]') +axarr[1, 1].scatter(x, y ** 2) +axarr[1, 1].set_title('Axis [1,1]') # Fine-tune figure; hide x ticks for top plots and y ticks for right plots -plt.setp([a.get_xticklabels() for a in axarr[0,:]], visible=False) -plt.setp([a.get_yticklabels() for a in axarr[:,1]], visible=False) +plt.setp([a.get_xticklabels() for a in axarr[0, :]], visible=False) +plt.setp([a.get_yticklabels() for a in axarr[:, 1]], visible=False) # Four polar axes plt.subplots(2, 2, subplot_kw=dict(polar=True)) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/table_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/table_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/table_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/table_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -71,7 +71,7 @@ cellText = [] width = 0.4 # the width of the bars yoff = array([0.0] * len(colLabels)) # the bottom values for stacked bar chart -for row in xrange(rows): +for row in range(rows): bar(ind, data[row], width, bottom=yoff, color=colours[row]) yoff = yoff + data[row] cellText.append(['%1.1f' % (x/1000.0) for x in yoff]) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/tex_unicode_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/tex_unicode_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/tex_unicode_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/tex_unicode_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -4,12 +4,13 @@ This demo is tex_demo.py modified to have unicode. See that file for more information. """ -from matplotlib import rcParams -rcParams['text.usetex']=True -rcParams['text.latex.unicode']=True +from __future__ import unicode_literals +import matplotlib as mpl +mpl.rcParams['text.usetex']=True +mpl.rcParams['text.latex.unicode']=True from numpy import arange, cos, pi -from matplotlib.pyplot import figure, axes, plot, xlabel, ylabel, title, \ - grid, savefig, show +from matplotlib.pyplot import (figure, axes, plot, xlabel, ylabel, title, + grid, savefig, show) figure(1, figsize=(6,4)) ax = axes([0.1, 0.1, 0.8, 0.7]) @@ -18,7 +19,7 @@ plot(t, s) xlabel(r'\textbf{time (s)}') -ylabel(ur'\textit{Velocity (\u00B0/sec)}', fontsize=16) +ylabel(r'\textit{Velocity (\u00B0/sec)}', fontsize=16) title(r"\TeX\ is Number $\displaystyle\sum_{n=1}^\infty\frac{-e^{i\pi}}{2^n}$!", fontsize=16, color='r') grid(True) diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/text_rotation.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/text_rotation.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/text_rotation.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/text_rotation.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,6 @@ #!/usr/bin/env python """ -The way matplotlib does text layout is counter-intuituve to some, so +The way matplotlib does text layout is counter-intuitive to some, so this example is designed to make it a little clearer. The text is aligned by it's bounding box (the rectangular box that surrounds the ink rectangle). The order of operations is basically rotation then diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/text_rotation_relative_to_line.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/text_rotation_relative_to_line.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/text_rotation_relative_to_line.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/text_rotation_relative_to_line.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,7 +2,7 @@ """ Text objects in matplotlib are normally rotated with respect to the screen coordinate system (i.e., 45 degrees rotation plots text along a -line that is inbetween horizontal and vertical no matter how the axes +line that is in between horizontal and vertical no matter how the axes are changed). However, at times one wants to rotate text with respect to something on the plot. In this case, the correct angle won't be the angle of that object in the plot coordinate system, but the angle diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/to_numeric.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/to_numeric.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/to_numeric.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/to_numeric.py 2012-10-31 00:11:13.000000000 +0000 @@ -5,16 +5,17 @@ rendering """ -from pylab import * +import pylab from matplotlib.backends.backend_agg import FigureCanvasAgg + try: from PIL import Image -except ImportError, exc: +except ImportError: raise SystemExit("PIL must be installed to run this example") -plot([1,2,3]) +pylab.plot([1,2,3]) -canvas = get_current_fig_manager().canvas +canvas = pylab.get_current_fig_manager().canvas agg = canvas.switch_backends(FigureCanvasAgg) agg.draw() @@ -25,9 +26,9 @@ w, h = int(w), int(h) -X = fromstring(s, uint8) +X = pylab.fromstring(s, pylab.uint8) X.shape = h, w, 3 im = Image.fromstring( "RGB", (w,h), s) -# im.show() +im.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/tricontour_vs_griddata.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/tricontour_vs_griddata.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/tricontour_vs_griddata.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/tricontour_vs_griddata.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,7 @@ """ Comparison of griddata and tricontour for an unstructured triangular grid. """ +from __future__ import print_function import matplotlib.pyplot as plt import matplotlib.tri as tri import numpy as np @@ -23,25 +24,27 @@ yi = np.linspace(-2.1,2.1,ngridy) zi = griddata(x,y,z,xi,yi,interp='linear') plt.contour(xi,yi,zi,15,linewidths=0.5,colors='k') -plt.contourf(xi,yi,zi,15,cmap=plt.cm.jet) +plt.contourf(xi,yi,zi,15,cmap=plt.cm.rainbow, + norm=plt.normalize(vmax=abs(zi).max(), vmin=-abs(zi).max())) plt.colorbar() # draw colorbar plt.plot(x, y, 'ko', ms=3) plt.xlim(-2,2) plt.ylim(-2,2) plt.title('griddata and contour (%d points, %d grid points)' % (npts, ngridx*ngridy)) -print 'griddata and contour seconds:', time.clock() - start +print ('griddata and contour seconds: %f' % (time.clock() - start)) # tricontour. start = time.clock() plt.subplot(212) triang = tri.Triangulation(x, y) plt.tricontour(x, y, z, 15, linewidths=0.5, colors='k') -plt.tricontourf(x, y, z, 15, cmap=plt.cm.jet) +plt.tricontourf(x, y, z, 15, cmap=plt.cm.rainbow, + norm=plt.normalize(vmax=abs(zi).max(), vmin=-abs(zi).max())) plt.colorbar() plt.plot(x, y, 'ko', ms=3) plt.xlim(-2,2) plt.ylim(-2,2) plt.title('tricontour (%d points)' % npts) -print 'tricontour seconds:', time.clock() - start +print ('tricontour seconds: %f' % (time.clock() - start)) plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/tripcolor_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/tripcolor_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/tripcolor_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/tripcolor_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -32,12 +32,19 @@ mask = np.where(xmid*xmid + ymid*ymid < min_radius*min_radius, 1, 0) triang.set_mask(mask) -# pcolor plot. +# tripcolor plot. plt.figure() plt.gca().set_aspect('equal') -plt.tripcolor(triang, z, shading='faceted') +plt.tripcolor(triang, z, shading='flat', cmap=plt.cm.rainbow) plt.colorbar() -plt.title('tripcolor of Delaunay triangulation') +plt.title('tripcolor of Delaunay triangulation, flat shading') + +# Illustrate Gouraud shading. +plt.figure() +plt.gca().set_aspect('equal') +plt.tripcolor(triang, z, shading='gouraud', cmap=plt.cm.rainbow) +plt.colorbar() +plt.title('tripcolor of Delaunay triangulation, gouraud shading') # You can specify your own triangulation rather than perform a Delaunay @@ -63,9 +70,6 @@ [-0.057,0.916],[-0.025,0.933],[-0.077,0.990],[-0.059,0.993] ]) x = xy[:,0]*180/3.14159 y = xy[:,1]*180/3.14159 -x0 = -5 -y0 = 52 -z = np.exp(-0.01*( (x-x0)*(x-x0) + (y-y0)*(y-y0) )) triangles = np.asarray([ [67,66, 1],[65, 2,66],[ 1,66, 2],[64, 2,65],[63, 3,64],[60,59,57], @@ -83,13 +87,21 @@ [32,31,33],[39,38,72],[33,72,38],[33,38,34],[37,35,38],[34,38,35], [35,37,36] ]) +xmid = x[triangles].mean(axis=1) +ymid = y[triangles].mean(axis=1) +x0 = -5 +y0 = 52 +zfaces = np.exp(-0.01*( (xmid-x0)*(xmid-x0) + (ymid-y0)*(ymid-y0) )) + # Rather than create a Triangulation object, can simply pass x, y and triangles # arrays to tripcolor directly. It would be better to use a Triangulation object # if the same triangulation was to be used more than once to save duplicated # calculations. +# Can specify one color value per face rather than one per point by using the +# facecolors kwarg. plt.figure() plt.gca().set_aspect('equal') -plt.tripcolor(x, y, triangles, z, shading='faceted') +plt.tripcolor(x, y, triangles, facecolors=zfaces, edgecolors='k') plt.colorbar() plt.title('tripcolor of user-specified triangulation') plt.xlabel('Longitude (degrees)') diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/unicode_demo.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/unicode_demo.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/unicode_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/unicode_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,12 +1,15 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -from pylab import * -plot([1,2,4]) -title(u'Développés et fabriqués') -xlabel(u"réactivité nous permettent d'être sélectionnés et adoptés") -ylabel(u'André was here!') -text( 0.5, 2.5, u'Institut für Festkörperphysik', rotation=45) -text( 1, 1.5, u'AVA (check kerning)') +from __future__ import unicode_literals -show() +import pylab + +pylab.plot([1, 2, 4]) +pylab.title('Développés et fabriqués') +pylab.xlabel("réactivité nous permettent d'être sélectionnés et adoptés") +pylab.ylabel('André was here!') +pylab.text( 0.5, 2.5, 'Institut für Festkörperphysik', rotation=45) +pylab.text( 1, 1.5, 'AVA (check kerning)') + +pylab.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/pylab_examples/usetex_baseline_test.py matplotlib-1.2.0/doc/mpl_examples/pylab_examples/usetex_baseline_test.py --- matplotlib-1.1.1/doc/mpl_examples/pylab_examples/usetex_baseline_test.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/pylab_examples/usetex_baseline_test.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,6 +3,10 @@ import matplotlib.pyplot as plt import matplotlib.axes as maxes +from matplotlib import rcParams +rcParams['text.usetex']=True +rcParams['text.latex.unicode']=True + class Axes(maxes.Axes): """ A hackish way to simultaneously draw texts w/ usetex=True and diff -Nru matplotlib-1.1.1/doc/mpl_examples/tests/backend_driver.py matplotlib-1.2.0/doc/mpl_examples/tests/backend_driver.py --- matplotlib-1.1.1/doc/mpl_examples/tests/backend_driver.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/tests/backend_driver.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,6 @@ #!/usr/bin/env python + +from __future__ import print_function, division """ This is used to drive many of the examples across the backends, for regression testing, and comparing backend efficiency. @@ -7,11 +9,10 @@ switch, which takes a comma-separated list, or as separate arguments, e.g. - python backend_driver.py agg ps cairo.png cairo.ps + python backend_driver.py agg ps -would test the agg and ps backends, and the cairo backend with output -to png and ps files. If no arguments are given, a default list of -backends will be tested. +would test the agg and ps backends. If no arguments are given, a +default list of backends will be tested. Interspersed with the backend arguments can be switches for the Python interpreter executing the tests. If entering such arguments causes an @@ -19,14 +20,12 @@ switches with a --. """ -from __future__ import division import os, time, sys, glob, string from optparse import OptionParser import matplotlib.rcsetup as rcsetup from matplotlib.cbook import Bunch, dedent all_backends = list(rcsetup.all_backends) # to leave the original list alone -all_backends.extend(['cairo.png', 'cairo.ps', 'cairo.pdf', 'cairo.svg']) # actual physical directory for each dir dirs = dict(pylab = os.path.join('..', 'pylab_examples'), @@ -160,6 +159,7 @@ 'pcolor_log.py', 'pcolor_small.py', 'pie_demo.py', + 'pie_demo2.py', 'plotfile_demo.py', 'polar_bar.py', 'polar_demo.py', @@ -285,7 +285,7 @@ missing = list(pyfiles-flist-exclude) missing.sort() if missing: - print '%s files not tested: %s'%(dir, ', '.join(missing)) + print ('%s files not tested: %s'%(dir, ', '.join(missing))) def report_all_missing(directories): for f in directories: @@ -323,7 +323,7 @@ if os.path.exists(path): import glob for fname in os.listdir(path): - os.unlink(os.path.join(path,fname)) + os.unlink(os.path.join(path, fname)) else: os.mkdir(backend) failures = [] @@ -338,34 +338,35 @@ fpath, fname = os.path.split(fullpath) if fname in exclude: - print '\tSkipping %s, known to fail on backend: %s'%backend + print ('\tSkipping %s, known to fail on backend: %s'%backend) continue basename, ext = os.path.splitext(fname) - outfile = os.path.join(path,basename) + outfile = os.path.join(path, basename) tmpfile_name = '_tmp_%s.py' % basename - tmpfile = file(tmpfile_name, 'w') + tmpfile = open(tmpfile_name, 'w') - for line in file(fullpath): + future_imports = 'from __future__ import division, print_function' + for line in open(fullpath): line_lstrip = line.lstrip() if line_lstrip.startswith("#"): tmpfile.write(line) - else: - break + elif 'unicode_literals' in line: + future_imports = future_imports + ', unicode_literals' tmpfile.writelines(( - 'from __future__ import division\n', + future_imports+'\n', 'import sys\n', - 'sys.path.append("%s")\n'%fpath, + 'sys.path.append("%s")\n' % fpath.replace('\\', '\\\\'), 'import matplotlib\n', 'matplotlib.use("%s")\n' % backend, 'from pylab import savefig\n', 'import numpy\n', 'numpy.seterr(invalid="ignore")\n', )) - for line in file(fullpath): + for line in open(fullpath): line_lstrip = line.lstrip() - if (line_lstrip.startswith('from __future__ import division') or + if (line_lstrip.startswith('from __future__ import') or line_lstrip.startswith('matplotlib.use') or line_lstrip.startswith('savefig') or line_lstrip.startswith('show')): @@ -381,7 +382,7 @@ program = [x % {'name': basename} for x in python] ret = run(program + [tmpfile_name] + switches) end_time = time.time() - print (end_time - start_time), ret + print ("%s %s" % ((end_time - start_time), ret)) #os.system('%s %s %s' % (python, tmpfile_name, ' '.join(switches))) os.remove(tmpfile_name) if ret: @@ -405,8 +406,7 @@ help=dedent(''' Run tests only for these backends; comma-separated list of one or more of: agg, ps, svg, pdf, template, cairo, - cairo.png, cairo.ps, cairo.pdf, cairo.svg. Default is everything - except cairo.''')) + Default is everything except cairo.''')) op.add_option('--clean', action='store_true', dest='clean', help='Remove result directories, run no tests') op.add_option('-c', '--coverage', action='store_true', dest='coverage', @@ -418,7 +418,7 @@ switches = [x for x in args if x.startswith('--')] backends = [x.lower() for x in args if not x.startswith('--')] if options.backends: - backends += map(string.lower, options.backends.split(',')) + backends += [be.lower() for be in options.backends.split(',')] result = Bunch( dirs = options.dirs.split(','), @@ -430,7 +430,7 @@ if 'pylab_examples' in result.dirs: result.dirs[result.dirs.index('pylab_examples')] = 'pylab' #print result - return result + return (result) if __name__ == '__main__': times = {} @@ -443,28 +443,28 @@ for d in localdirs: if d.lower() not in all_backends_set: continue - print 'removing %s'%d + print ('removing %s'%d) for fname in glob.glob(os.path.join(d, '*')): os.remove(fname) os.rmdir(d) for fname in glob.glob('_tmp*.py'): os.remove(fname) - print 'all clean...' + print ('all clean...') raise SystemExit if options.coverage: python = ['coverage.py', '-x'] elif options.valgrind: python = ['valgrind', '--tool=memcheck', '--leak-check=yes', - '--log-file=%(name)s', 'python'] + '--log-file=%(name)s', sys.executable] elif sys.platform == 'win32': python = [sys.executable] else: - python = ['python'] + python = [sys.executable] report_all_missing(options.dirs) for backend in options.backends: - print 'testing %s %s' % (backend, ' '.join(options.switches)) + print ('testing %s %s' % (backend, ' '.join(options.switches))) t0 = time.time() failures[backend] = \ drive(backend, options.dirs, python, options.switches) @@ -473,10 +473,10 @@ # print times for backend, elapsed in times.items(): - print 'Backend %s took %1.2f minutes to complete' % (backend, elapsed) + print ('Backend %s took %1.2f minutes to complete' % (backend, elapsed)) failed = failures[backend] if failed: - print ' Failures: ', failed + print (' Failures: %s' % failed) if 'template' in times: - print '\ttemplate ratio %1.3f, template residual %1.3f' % ( - elapsed/times['template'], elapsed-times['template']) + print ('\ttemplate ratio %1.3f, template residual %1.3f' % ( + elapsed/times['template'], elapsed-times['template'])) diff -Nru matplotlib-1.1.1/doc/mpl_examples/units/bar_demo2.py matplotlib-1.2.0/doc/mpl_examples/units/bar_demo2.py --- matplotlib-1.1.1/doc/mpl_examples/units/bar_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/units/bar_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -9,13 +9,14 @@ """ import numpy as np from basic_units import cm, inch -from pylab import figure, show +import matplotlib.pyplot as plt + cms = cm *np.arange(0, 10, 2) bottom=0*cm width=0.8*cm -fig = figure() +fig = plt.figure() ax1 = fig.add_subplot(2,2,1) ax1.bar(cms, cms, bottom=bottom) @@ -32,4 +33,4 @@ #fig.savefig('simple_conversion_plot.png') ax4.set_xlim(2*cm, 6*cm) # cm are converted to inches -show() +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/units/bar_unit_demo.py matplotlib-1.2.0/doc/mpl_examples/units/bar_unit_demo.py --- matplotlib-1.1.1/doc/mpl_examples/units/bar_unit_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/units/bar_unit_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,13 +1,14 @@ #!/usr/bin/env python import numpy as np from basic_units import cm, inch -from pylab import figure, show +import matplotlib.pyplot as plt + N = 5 menMeans = (150*cm, 160*cm, 146*cm, 172*cm, 155*cm) menStd = ( 20*cm, 30*cm, 32*cm, 10*cm, 20*cm) -fig = figure() +fig = plt.figure() ax = fig.add_subplot(111) ind = np.arange(N) # the x locations for the groups @@ -27,5 +28,5 @@ ax.yaxis.set_units(inch) ax.autoscale_view() -#savefig('barchart_demo') -show() +#plt.savefig('barchart_demo') +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/units/basic_units.py matplotlib-1.2.0/doc/mpl_examples/units/basic_units.py --- matplotlib-1.1.1/doc/mpl_examples/units/basic_units.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/units/basic_units.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,5 @@ import math + import numpy as np import matplotlib.units as units @@ -6,35 +7,42 @@ from matplotlib.axes import Axes from matplotlib.cbook import iterable + class ProxyDelegate(object): def __init__(self, fn_name, proxy_type): self.proxy_type = proxy_type self.fn_name = fn_name + def __get__(self, obj, objtype=None): return self.proxy_type(self.fn_name, obj) + class TaggedValueMeta (type): def __init__(cls, name, bases, dict): for fn_name in cls._proxies.keys(): try: dummy = getattr(cls, fn_name) except AttributeError: - setattr(cls, fn_name, ProxyDelegate(fn_name, cls._proxies[fn_name])) + setattr(cls, fn_name, + ProxyDelegate(fn_name, cls._proxies[fn_name])) + class PassThroughProxy(object): def __init__(self, fn_name, obj): self.fn_name = fn_name self.target = obj.proxy_target + def __call__(self, *args): - #print 'passthrough', self.target, self.fn_name fn = getattr(self.target, self.fn_name) ret = fn(*args) return ret + class ConvertArgsProxy(PassThroughProxy): def __init__(self, fn_name, obj): PassThroughProxy.__init__(self, fn_name, obj) self.unit = obj.unit + def __call__(self, *args): converted_args = [] for a in args: @@ -45,16 +53,19 @@ converted_args = tuple([c.get_value() for c in converted_args]) return PassThroughProxy.__call__(self, *converted_args) + class ConvertReturnProxy(PassThroughProxy): def __init__(self, fn_name, obj): PassThroughProxy.__init__(self, fn_name, obj) self.unit = obj.unit + def __call__(self, *args): ret = PassThroughProxy.__call__(self, *args) if (type(ret) == type(NotImplemented)): return NotImplemented return TaggedValue(ret, self.unit) + class ConvertAllProxy(PassThroughProxy): def __init__(self, fn_name, obj): PassThroughProxy.__init__(self, fn_name, obj) @@ -91,184 +102,186 @@ return NotImplemented return TaggedValue(ret, ret_unit) -class TaggedValue (object): - __metaclass__ = TaggedValueMeta - _proxies = {'__add__':ConvertAllProxy, - '__sub__':ConvertAllProxy, - '__mul__':ConvertAllProxy, - '__rmul__':ConvertAllProxy, - '__cmp__':ConvertAllProxy, - '__lt__':ConvertAllProxy, - '__gt__':ConvertAllProxy, - '__len__':PassThroughProxy} - - def __new__(cls, value, unit): - # generate a new subclass for value - value_class = type(value) - try: - subcls = type('TaggedValue_of_%s' % (value_class.__name__), - tuple([cls, value_class]), - {}) - if subcls not in units.registry: - units.registry[subcls] = basicConverter - return object.__new__(subcls, value, unit) - except TypeError: - if cls not in units.registry: - units.registry[cls] = basicConverter - return object.__new__(cls, value, unit) - - def __init__(self, value, unit): - self.value = value - self.unit = unit - self.proxy_target = self.value - - def get_compressed_copy(self, mask): - compressed_value = np.ma.masked_array(self.value, mask=mask).compressed() - return TaggedValue(compressed_value, self.unit) - - def __getattribute__(self, name): - if (name.startswith('__')): - return object.__getattribute__(self, name) - variable = object.__getattribute__(self, 'value') - if (hasattr(variable, name) and name not in self.__class__.__dict__): - return getattr(variable, name) - return object.__getattribute__(self, name) - - def __array__(self, t = None, context = None): - if t is not None: - return np.asarray(self.value).astype(t) - else: - return np.asarray(self.value, 'O') +class _TaggedValue(object): - def __array_wrap__(self, array, context): - return TaggedValue(array, self.unit) + _proxies = {'__add__': ConvertAllProxy, + '__sub__': ConvertAllProxy, + '__mul__': ConvertAllProxy, + '__rmul__': ConvertAllProxy, + '__cmp__': ConvertAllProxy, + '__lt__': ConvertAllProxy, + '__gt__': ConvertAllProxy, + '__len__': PassThroughProxy} + + def __new__(cls, value, unit): + # generate a new subclass for value + value_class = type(value) + try: + subcls = type('TaggedValue_of_%s' % (value_class.__name__), + tuple([cls, value_class]), + {}) + if subcls not in units.registry: + units.registry[subcls] = basicConverter + return object.__new__(subcls, value, unit) + except TypeError: + if cls not in units.registry: + units.registry[cls] = basicConverter + return object.__new__(cls, value, unit) - def __repr__(self): - return 'TaggedValue(' + repr(self.value) + ', ' + repr(self.unit) + ')' + def __init__(self, value, unit): + self.value = value + self.unit = unit + self.proxy_target = self.value - def __str__(self): - return str(self.value) + ' in ' + str(self.unit) + def __getattribute__(self, name): + if (name.startswith('__')): + return object.__getattribute__(self, name) + variable = object.__getattribute__(self, 'value') + if (hasattr(variable, name) and name not in self.__class__.__dict__): + return getattr(variable, name) + return object.__getattribute__(self, name) + + def __array__(self, t=None, context=None): + if t is not None: + return np.asarray(self.value).astype(t) + else: + return np.asarray(self.value, 'O') - def __iter__(self): - class IteratorProxy(object): - def __init__(self, iter, unit): - self.iter = iter - self.unit = unit - def next(self): - value = self.iter.next() - return TaggedValue(value, self.unit) - return IteratorProxy(iter(self.value), self.unit) - - def get_compressed_copy(self, mask): - new_value = np.ma.masked_array(self.value, mask=mask).compressed() - return TaggedValue(new_value, self.unit) - - def convert_to(self, unit): - #print 'convert to', unit, self.unit - if (unit == self.unit or not unit): - return self - new_value = self.unit.convert_value_to(self.value, unit) - return TaggedValue(new_value, unit) + def __array_wrap__(self, array, context): + return TaggedValue(array, self.unit) + + def __repr__(self): + return 'TaggedValue(' + repr(self.value) + ', ' + repr(self.unit) + ')' + + def __str__(self): + return str(self.value) + ' in ' + str(self.unit) + + def __len__(self): + return len(self.value) + + def __iter__(self): + class IteratorProxy(object): + def __init__(self, iter, unit): + self.iter = iter + self.unit = unit + + def __next__(self): + value = next(self.iter) + return TaggedValue(value, self.unit) + next = __next__ # for Python 2 + return IteratorProxy(iter(self.value), self.unit) - def get_value(self): - return self.value + def get_compressed_copy(self, mask): + new_value = np.ma.masked_array(self.value, mask=mask).compressed() + return TaggedValue(new_value, self.unit) - def get_unit(self): - return self.unit + def convert_to(self, unit): + if (unit == self.unit or not unit): + return self + new_value = self.unit.convert_value_to(self.value, unit) + return TaggedValue(new_value, unit) + + def get_value(self): + return self.value + + def get_unit(self): + return self.unit + + +TaggedValue = TaggedValueMeta('TaggedValue', (_TaggedValue, ), {}) class BasicUnit(object): - def __init__(self, name, fullname=None): - self.name = name - if fullname is None: fullname = name - self.fullname = fullname - self.conversions = dict() - - - def __repr__(self): - return 'BasicUnit(%s)'%self.name - - def __str__(self): - return self.fullname - - def __call__(self, value): - return TaggedValue(value, self) - - def __mul__(self, rhs): - value = rhs - unit = self - if hasattr(rhs, 'get_unit'): - value = rhs.get_value() - unit = rhs.get_unit() - unit = unit_resolver('__mul__', (self, unit)) - if (unit == NotImplemented): - return NotImplemented - return TaggedValue(value, unit) - - def __rmul__(self, lhs): - return self*lhs - - def __array_wrap__(self, array, context): - return TaggedValue(array, self) - - def __array__(self, t=None, context=None): - ret = np.array([1]) - if t is not None: - return ret.astype(t) - else: - return ret + def __init__(self, name, fullname=None): + self.name = name + if fullname is None: + fullname = name + self.fullname = fullname + self.conversions = dict() + + def __repr__(self): + return 'BasicUnit(%s)'%self.name + + def __str__(self): + return self.fullname + + def __call__(self, value): + return TaggedValue(value, self) + + def __mul__(self, rhs): + value = rhs + unit = self + if hasattr(rhs, 'get_unit'): + value = rhs.get_value() + unit = rhs.get_unit() + unit = unit_resolver('__mul__', (self, unit)) + if (unit == NotImplemented): + return NotImplemented + return TaggedValue(value, unit) - def add_conversion_factor(self, unit, factor): - def convert(x): - return x*factor - self.conversions[unit] = convert + def __rmul__(self, lhs): + return self*lhs - def add_conversion_fn(self, unit, fn): - self.conversions[unit] = fn + def __array_wrap__(self, array, context): + return TaggedValue(array, self) - def get_conversion_fn(self, unit): - return self.conversions[unit] + def __array__(self, t=None, context=None): + ret = np.array([1]) + if t is not None: + return ret.astype(t) + else: + return ret - def convert_value_to(self, value, unit): - #print 'convert value to: value ="%s", unit="%s"'%(value, type(unit)), self.conversions - conversion_fn = self.conversions[unit] - ret = conversion_fn(value) - return ret + def add_conversion_factor(self, unit, factor): + def convert(x): + return x*factor + self.conversions[unit] = convert + + def add_conversion_fn(self, unit, fn): + self.conversions[unit] = fn + + def get_conversion_fn(self, unit): + return self.conversions[unit] + + def convert_value_to(self, value, unit): + conversion_fn = self.conversions[unit] + ret = conversion_fn(value) + return ret + def get_unit(self): + return self - def get_unit(self): - return self class UnitResolver(object): - def addition_rule(self, units): - for unit_1, unit_2 in zip(units[:-1], units[1:]): - if (unit_1 != unit_2): - return NotImplemented - return units[0] - def multiplication_rule(self, units): - non_null = [u for u in units if u] - if (len(non_null) > 1): - return NotImplemented - return non_null[0] - - op_dict = { - '__mul__':multiplication_rule, - '__rmul__':multiplication_rule, - '__add__':addition_rule, - '__radd__':addition_rule, - '__sub__':addition_rule, - '__rsub__':addition_rule, - } - - def __call__(self, operation, units): - if (operation not in self.op_dict): - return NotImplemented + def addition_rule(self, units): + for unit_1, unit_2 in zip(units[:-1], units[1:]): + if (unit_1 != unit_2): + return NotImplemented + return units[0] + + def multiplication_rule(self, units): + non_null = [u for u in units if u] + if (len(non_null) > 1): + return NotImplemented + return non_null[0] - return self.op_dict[operation](self, units) + op_dict = { + '__mul__': multiplication_rule, + '__rmul__': multiplication_rule, + '__add__': addition_rule, + '__radd__': addition_rule, + '__sub__': addition_rule, + '__rsub__': addition_rule} + + def __call__(self, operation, units): + if (operation not in self.op_dict): + return NotImplemented + + return self.op_dict[operation](self, units) -unit_resolver = UnitResolver() +unit_resolver = UnitResolver() cm = BasicUnit('cm', 'centimeters') inch = BasicUnit('inch', 'inches') @@ -284,22 +297,23 @@ hertz = BasicUnit('Hz', 'Hertz') minutes = BasicUnit('min', 'minutes') -secs.add_conversion_fn(hertz, lambda x:1./x) +secs.add_conversion_fn(hertz, lambda x: 1./x) secs.add_conversion_factor(minutes, 1/60.0) + # radians formatting -def rad_fn(x,pos=None): - n = int((x / np.pi) * 2.0 + 0.25) - if n == 0: - return '0' - elif n == 1: - return r'$\pi/2$' - elif n == 2: - return r'$\pi$' - elif n % 2 == 0: - return r'$%s\pi$' % (n/2,) - else: - return r'$%s\pi/2$' % (n,) +def rad_fn(x, pos=None): + n = int((x / np.pi) * 2.0 + 0.25) + if n == 0: + return '0' + elif n == 1: + return r'$\pi/2$' + elif n == 2: + return r'$\pi$' + elif n % 2 == 0: + return r'$%s\pi$' % (n/2,) + else: + return r'$%s\pi/2$' % (n,) class BasicUnitConverter(units.ConversionInterface): @@ -310,16 +324,16 @@ if unit==radians: return units.AxisInfo( - majloc=ticker.MultipleLocator(base=np.pi/2), - majfmt=ticker.FuncFormatter(rad_fn), - label=unit.fullname, - ) + majloc=ticker.MultipleLocator(base=np.pi/2), + majfmt=ticker.FuncFormatter(rad_fn), + label=unit.fullname, + ) elif unit==degrees: return units.AxisInfo( - majloc=ticker.AutoLocator(), - majfmt=ticker.FormatStrFormatter(r'$%i^\circ$'), - label=unit.fullname, - ) + majloc=ticker.AutoLocator(), + majfmt=ticker.FormatStrFormatter(r'$%i^\circ$'), + label=unit.fullname, + ) elif unit is not None: if hasattr(unit, 'fullname'): return units.AxisInfo(label=unit.fullname) @@ -331,7 +345,6 @@ def convert(val, unit, axis): if units.ConversionInterface.is_numlike(val): return val - #print 'convert checking iterable' if iterable(val): return [thisval.convert_to(unit).get_value() for thisval in val] else: @@ -346,17 +359,13 @@ return x.unit +def cos(x): + if iterable(x): + return [math.cos(val.convert_to(radians).get_value()) for val in x] + else: + return math.cos(x.convert_to(radians).get_value()) -def cos( x ): - if ( iterable(x) ): - result = [] - for val in x: - result.append( math.cos( val.convert_to( radians ).get_value() ) ) - return result - else: - return math.cos( x.convert_to( radians ).get_value() ) basicConverter = BasicUnitConverter() units.registry[BasicUnit] = basicConverter units.registry[TaggedValue] = basicConverter - diff -Nru matplotlib-1.1.1/doc/mpl_examples/units/ellipse_with_units.py matplotlib-1.2.0/doc/mpl_examples/units/ellipse_with_units.py --- matplotlib-1.1.1/doc/mpl_examples/units/ellipse_with_units.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/units/ellipse_with_units.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,31 +2,32 @@ Compare the ellipse generated with arcs versus a polygonal approximation """ from basic_units import cm -import numpy as npy +import numpy as np from matplotlib import patches -from pylab import figure, show +import matplotlib.pyplot as plt + xcenter, ycenter = 0.38*cm, 0.52*cm #xcenter, ycenter = 0., 0. width, height = 1e-1*cm, 3e-1*cm angle = -30 -theta = npy.arange(0.0, 360.0, 1.0)*npy.pi/180.0 -x = 0.5 * width * npy.cos(theta) -y = 0.5 * height * npy.sin(theta) - -rtheta = angle*npy.pi/180. -R = npy.array([ - [npy.cos(rtheta), -npy.sin(rtheta)], - [npy.sin(rtheta), npy.cos(rtheta)], +theta = np.arange(0.0, 360.0, 1.0)*np.pi/180.0 +x = 0.5 * width * np.cos(theta) +y = 0.5 * height * np.sin(theta) + +rtheta = angle*np.pi/180. +R = np.array([ + [np.cos(rtheta), -np.sin(rtheta)], + [np.sin(rtheta), np.cos(rtheta)], ]) -x, y = npy.dot(R, npy.array([x, y])) +x, y = np.dot(R, np.array([x, y])) x += xcenter y += ycenter -fig = figure() +fig = plt.figure() ax = fig.add_subplot(211, aspect='auto') ax.fill(x, y, alpha=0.2, facecolor='yellow', edgecolor='yellow', linewidth=1, zorder=1) @@ -46,7 +47,7 @@ #fig.savefig('ellipse_compare.png') fig.savefig('ellipse_compare') -fig = figure() +fig = plt.figure() ax = fig.add_subplot(211, aspect='auto') ax.fill(x, y, alpha=0.2, facecolor='yellow', edgecolor='yellow', linewidth=1, zorder=1) @@ -66,4 +67,4 @@ #fig.savefig('arc_compare.png') fig.savefig('arc_compare') -show() +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/units/evans_test.py matplotlib-1.2.0/doc/mpl_examples/units/evans_test.py --- matplotlib-1.1.1/doc/mpl_examples/units/evans_test.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/units/evans_test.py 2012-10-31 00:11:13.000000000 +0000 @@ -4,13 +4,11 @@ Here the "unit" is just a scalar conversion factor, but this example shows mpl is entirely agnostic to what kind of units client packages use """ - -import matplotlib - from matplotlib.cbook import iterable import matplotlib.units as units import matplotlib.ticker as ticker -from pylab import figure, show +import matplotlib.pyplot as plt + class Foo: def __init__( self, val, unit=1.0 ): @@ -71,7 +69,7 @@ # plot specifying units -fig = figure() +fig = plt.figure() fig.suptitle("Custom units") fig.subplots_adjust(bottom=0.2) ax = fig.add_subplot(1,2,2) @@ -90,4 +88,4 @@ label.set_rotation(30) label.set_ha('right') -show() +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/units/units_sample.py matplotlib-1.2.0/doc/mpl_examples/units/units_sample.py --- matplotlib-1.1.1/doc/mpl_examples/units/units_sample.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/units/units_sample.py 2012-10-31 00:11:13.000000000 +0000 @@ -8,12 +8,12 @@ """ from basic_units import cm, inch -from pylab import figure, show +import matplotlib.pyplot as plt import numpy cms = cm *numpy.arange(0, 10, 2) -fig = figure() +fig = plt.figure() ax1 = fig.add_subplot(2,2,1) ax1.plot(cms, cms) @@ -30,4 +30,4 @@ #fig.savefig('simple_conversion_plot.png') ax4.set_xlim(3*cm, 6*cm) # cm are converted to inches -show() +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_gtk2.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_gtk2.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_gtk2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_gtk2.py 2012-10-31 00:11:13.000000000 +0000 @@ -17,6 +17,8 @@ #from matplotlib.backends.backend_gtk import NavigationToolbar2GTK as NavigationToolbar from matplotlib.backends.backend_gtkagg import NavigationToolbar2GTKAgg as NavigationToolbar +# implement the default mpl key bindings +from matplotlib.backend_bases import key_press_handler win = gtk.Window() win.connect("destroy", lambda x: gtk.main_quit()) @@ -40,5 +42,11 @@ vbox.pack_start(toolbar, False, False) +def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvas, toolbar) + +canvas.mpl_connect('key_press_event', on_key_event) + win.show_all() gtk.main() diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_gtk3.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_gtk3.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_gtk3.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_gtk3.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,20 +1,17 @@ #!/usr/bin/env python """ -demonstrate adding a FigureCanvasGTK/GTKAgg widget to a gtk.ScrolledWindow +demonstrate adding a FigureCanvasGTK3Agg widget to a Gtk.ScrolledWindow +using GTK3 accessed via pygobject """ -import gtk +from gi.repository import Gtk from matplotlib.figure import Figure from numpy import arange, sin, pi +from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas -# uncomment to select /GTK/GTKAgg/GTKCairo -#from matplotlib.backends.backend_gtk import FigureCanvasGTK as FigureCanvas -from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas -#from matplotlib.backends.backend_gtkcairo import FigureCanvasGTKCairo as FigureCanvas - -win = gtk.Window() -win.connect("destroy", lambda x: gtk.main_quit()) +win = Gtk.Window() +win.connect("delete-event", Gtk.main_quit ) win.set_default_size(400,300) win.set_title("Embedding in GTK") @@ -24,17 +21,15 @@ s = sin(2*pi*t) a.plot(t,s) -sw = gtk.ScrolledWindow() +sw = Gtk.ScrolledWindow() win.add (sw) # A scrolled window border goes outside the scrollbars and viewport sw.set_border_width (10) -# policy: ALWAYS, AUTOMATIC, NEVER -sw.set_policy (hscrollbar_policy=gtk.POLICY_AUTOMATIC, - vscrollbar_policy=gtk.POLICY_ALWAYS) -canvas = FigureCanvas(f) # a gtk.DrawingArea +canvas = FigureCanvas(f) # a Gtk.DrawingArea canvas.set_size_request(800,600) sw.add_with_viewport (canvas) win.show_all() -gtk.main() +Gtk.main() + diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_gtk3_panzoom.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_gtk3_panzoom.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_gtk3_panzoom.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_gtk3_panzoom.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,37 @@ +#!/usr/bin/env python +""" +demonstrate NavigationToolbar with GTK3 accessed via pygobject +""" + +from gi.repository import Gtk + +from matplotlib.figure import Figure +from numpy import arange, sin, pi +from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas +from matplotlib.backends.backend_gtk3 import NavigationToolbar2GTK3 as NavigationToolbar + +win = Gtk.Window() +win.connect("delete-event", Gtk.main_quit ) +win.set_default_size(400,300) +win.set_title("Embedding in GTK") + +f = Figure(figsize=(5,4), dpi=100) +a = f.add_subplot(1,1,1) +t = arange(0.0,3.0,0.01) +s = sin(2*pi*t) +a.plot(t,s) + +vbox = Gtk.VBox() +win.add(vbox) + +# Add canvas to vbox +canvas = FigureCanvas(f) # a Gtk.DrawingArea +vbox.pack_start(canvas, True, True, 0) + +# Create toolbar +toolbar = NavigationToolbar(canvas, win) +vbox.pack_start(toolbar, False, False, 0) + +win.show_all() +Gtk.main() + diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_qt.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_qt.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_qt.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_qt.py 2012-10-31 00:11:13.000000000 +0000 @@ -8,6 +8,7 @@ # modified with no restriction; raw copies as well as modified versions # may be distributed without limitation. +from __future__ import unicode_literals import sys, os, random from qt import * @@ -75,7 +76,7 @@ def update_figure(self): # Build a list of 4 random integers between 0 and 10 (both inclusive) - l = [ random.randint(0, 10) for i in xrange(4) ] + l = [ random.randint(0, 10) for i in range(4) ] self.axes.plot([0, 1, 2, 3], l, 'r') self.draw() @@ -118,7 +119,7 @@ def about(self): QMessageBox.about(self, "About %s" % progname, -u"""%(prog)s version %(version)s +"""%(prog)s version %(version)s Copyright \N{COPYRIGHT SIGN} 2005 Florent Rougon This program is a simple example of a Qt application embedding matplotlib diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_qt4.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_qt4.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_qt4.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_qt4.py 2012-10-31 00:11:13.000000000 +0000 @@ -9,6 +9,7 @@ # modified with no restriction; raw copies as well as modified versions # may be distributed without limitation. +from __future__ import unicode_literals import sys, os, random from PyQt4 import QtGui, QtCore @@ -64,7 +65,7 @@ def update_figure(self): # Build a list of 4 random integers between 0 and 10 (both inclusive) - l = [ random.randint(0, 10) for i in xrange(4) ] + l = [ random.randint(0, 10) for i in range(4) ] self.axes.plot([0, 1, 2, 3], l, 'r') self.draw() @@ -107,16 +108,16 @@ self.fileQuit() def about(self): - QtGui.QMessageBox.about(self, "About %s" % progname, -u"""%(prog)s version %(version)s -Copyright \N{COPYRIGHT SIGN} 2005 Florent Rougon, 2006 Darren Dale + QtGui.QMessageBox.about(self, "About", +"""embedding_in_qt4.py example +Copyright 2005 Florent Rougon, 2006 Darren Dale This program is a simple example of a Qt4 application embedding matplotlib canvases. It may be used and modified with no restriction; raw copies as well as modified versions may be distributed without limitation.""" -% {"prog": progname, "version": progversion}) +) qApp = QtGui.QApplication(sys.argv) diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_qt4_wtoolbar.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_qt4_wtoolbar.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_qt4_wtoolbar.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_qt4_wtoolbar.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,67 @@ +from __future__ import print_function + +import sys + +import numpy as np +from matplotlib.figure import Figure +from matplotlib.backend_bases import key_press_handler +from matplotlib.backends.backend_qt4agg import ( + FigureCanvasQTAgg as FigureCanvas, + NavigationToolbar2QTAgg as NavigationToolbar) +from PyQt4.QtCore import * +from PyQt4.QtGui import * + + +class AppForm(QMainWindow): + def __init__(self, parent=None): + QMainWindow.__init__(self, parent) + #self.x, self.y = self.get_data() + self.data = self.get_data2() + self.create_main_frame() + self.on_draw() + + def create_main_frame(self): + self.main_frame = QWidget() + + self.fig = Figure((5.0, 4.0), dpi=100) + self.canvas = FigureCanvas(self.fig) + self.canvas.setParent(self.main_frame) + self.canvas.setFocusPolicy(Qt.StrongFocus) + self.canvas.setFocus() + + self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame) + + self.canvas.mpl_connect('key_press_event', self.on_key_press) + + vbox = QVBoxLayout() + vbox.addWidget(self.canvas) # the matplotlib canvas + vbox.addWidget(self.mpl_toolbar) + self.main_frame.setLayout(vbox) + self.setCentralWidget(self.main_frame) + + def get_data2(self): + return np.arange(20).reshape([4, 5]).copy() + + def on_draw(self): + self.fig.clear() + self.axes = self.fig.add_subplot(111) + #self.axes.plot(self.x, self.y, 'ro') + self.axes.imshow(self.data, interpolation='nearest') + #self.axes.plot([1,2,3]) + self.canvas.draw() + + def on_key_press(self, event): + print('you pressed', event.key) + # implement the default mpl key press events described at + # http://matplotlib.org/users/navigation_toolbar.html#navigation-keyboard-shortcuts + key_press_handler(event, self.canvas, self.mpl_toolbar) + + +def main(): + app = QApplication(sys.argv) + form = AppForm() + form.show() + app.exec_() + +if __name__ == "__main__": + main() diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_tk.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_tk.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_tk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_tk.py 2012-10-31 00:11:13.000000000 +0000 @@ -5,10 +5,17 @@ from numpy import arange, sin, pi from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +# implement the default mpl key bindings +from matplotlib.backend_bases import key_press_handler + + from matplotlib.figure import Figure -import Tkinter as Tk import sys +if sys.version_info[0] < 3: + import Tkinter as Tk +else: + import tkinter as Tk root = Tk.Tk() root.wm_title("Embedding in TK") @@ -31,6 +38,12 @@ toolbar.update() canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) +def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvas, toolbar) + +canvas.mpl_connect('key_press_event', on_key_event) + def _quit(): root.quit() # stops mainloop root.destroy() # this is necessary on Windows to prevent diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_tk2.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_tk2.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_tk2.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_tk2.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,45 @@ +#!/usr/bin/env python +import matplotlib +matplotlib.use('TkAgg') + +from numpy import arange, sin, pi +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +from matplotlib.figure import Figure + +import sys +if sys.version_info[0] < 3: + import Tkinter as Tk +else: + import tkinter as Tk + +def destroy(e): sys.exit() + +root = Tk.Tk() +root.wm_title("Embedding in TK") +#root.bind("", destroy) + + +f = Figure(figsize=(5,4), dpi=100) +a = f.add_subplot(111) +t = arange(0.0,3.0,0.01) +s = sin(2*pi*t) + +a.plot(t,s) +a.set_title('Tk embedding') +a.set_xlabel('X axis label') +a.set_ylabel('Y label') + + +# a tk.DrawingArea +canvas = FigureCanvasTkAgg(f, master=root) +canvas.show() +canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) + +#toolbar = NavigationToolbar2TkAgg( canvas, root ) +#toolbar.update() +canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) + +button = Tk.Button(master=root, text='Quit', command=sys.exit) +button.pack(side=Tk.BOTTOM) + +Tk.mainloop() diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_wx2.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_wx2.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_wx2.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_wx2.py 2012-10-31 00:11:13.000000000 +0000 @@ -32,7 +32,7 @@ wx.Frame.__init__(self,None,-1, 'CanvasFrame',size=(550,350)) - self.SetBackgroundColour(wx.NamedColor("WHITE")) + self.SetBackgroundColour(wx.NamedColour("WHITE")) self.figure = Figure() self.axes = self.figure.add_subplot(111) diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_wx3.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_wx3.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_wx3.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_wx3.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,5 @@ #!/usr/bin/env python + """ Copyright (C) 2003-2004 Andrew Straw, Jeremy O'Donoghue and others @@ -18,6 +19,7 @@ Thanks to matplotlib and wx teams for creating such great software! """ +from __future__ import print_function # Used to guarantee to use at least Wx2.8 import wxversion @@ -30,7 +32,7 @@ import matplotlib.cbook as cbook from matplotlib.backends.backend_wxagg import Toolbar, FigureCanvasWxAgg from matplotlib.figure import Figure -import numpy as npy +import numpy as np import wx import wx.xrc as xrc @@ -63,14 +65,14 @@ def init_plot_data(self): a = self.fig.add_subplot(111) - x = npy.arange(120.0)*2*npy.pi/60.0 - y = npy.arange(100.0)*2*npy.pi/50.0 - self.x, self.y = npy.meshgrid(x, y) - z = npy.sin(self.x) + npy.cos(self.y) + x = np.arange(120.0)*2*np.pi/60.0 + y = np.arange(100.0)*2*np.pi/50.0 + self.x, self.y = np.meshgrid(x, y) + z = np.sin(self.x) + np.cos(self.y) self.im = a.imshow( z, cmap=cm.jet)#, interpolation='nearest') - zmax = npy.amax(z) - ERR_TOL - ymax_i, xmax_i = npy.nonzero(z >= zmax) + zmax = np.amax(z) - ERR_TOL + ymax_i, xmax_i = np.nonzero(z >= zmax) if self.im.origin == 'upper': ymax_i = z.shape[0]-ymax_i self.lines = a.plot(xmax_i,ymax_i,'ko') @@ -83,13 +85,13 @@ return self.toolbar def OnWhiz(self,evt): - self.x += npy.pi/15 - self.y += npy.pi/20 - z = npy.sin(self.x) + npy.cos(self.y) + self.x += np.pi/15 + self.y += np.pi/20 + z = np.sin(self.x) + np.cos(self.y) self.im.set_array(z) - zmax = npy.amax(z) - ERR_TOL - ymax_i, xmax_i = npy.nonzero(z >= zmax) + zmax = np.amax(z) - ERR_TOL + ymax_i, xmax_i = np.nonzero(z >= zmax) if self.im.origin == 'upper': ymax_i = z.shape[0]-ymax_i self.lines[0].set_data(xmax_i,ymax_i) @@ -103,7 +105,7 @@ class MyApp(wx.App): def OnInit(self): xrcfile = cbook.get_sample_data('embedding_in_wx3.xrc', asfileobj=False) - print 'loading', xrcfile + print('loading', xrcfile) self.res = xrc.XmlResource(xrcfile) diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_wx4.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_wx4.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/embedding_in_wx4.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/embedding_in_wx4.py 2012-10-31 00:11:13.000000000 +0000 @@ -61,7 +61,7 @@ wx.Frame.__init__(self,None,-1, 'CanvasFrame',size=(550,350)) - self.SetBackgroundColour(wx.NamedColor("WHITE")) + self.SetBackgroundColour(wx.NamedColour("WHITE")) self.figure = Figure(figsize=(5,4), dpi=100) self.axes = self.figure.add_subplot(111) diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/interactive.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/interactive.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/interactive.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/interactive.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,5 @@ #!/usr/bin/env python + """Multithreaded interactive interpreter with GTK and Matplotlib support. WARNING: @@ -21,6 +22,8 @@ Also borrows liberally from code.py in the Python standard library.""" +from __future__ import print_function + __author__ = "Fernando Perez " import sys @@ -123,11 +126,11 @@ self.ready.acquire() if self._kill: - print 'Closing threads...', + print('Closing threads...') sys.stdout.flush() for tokill in self.on_kill: tokill() - print 'Done.' + print('Done.') if self.code_to_run is not None: self.ready.notify() @@ -215,19 +218,19 @@ try: inFile = file(fname, 'r') except IOError: - print '*** ERROR *** Could not read file <%s>' % fname + print('*** ERROR *** Could not read file <%s>' % fname) else: - print '*** Executing file <%s>:' % fname + print('*** Executing file <%s>:' % fname) for line in inFile: if line.lstrip().find('show()')==0: continue - print '>>', line, + print('>>', line) push(line) inFile.close() matplotlib.interactive(1) # turn on interaction if __name__ == '__main__': - print "This demo is not presently functional, so running" - print "it as a script has been disabled." + print("This demo is not presently functional, so running") + print("it as a script has been disabled.") sys.exit() # Quick sys.argv hack to extract the option and leave filenames in sys.argv. # For real option handling, use optparse or getopt. diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/interactive2.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/interactive2.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/interactive2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/interactive2.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import print_function + # GTK Interactive Console # (C) 2003, Jon Anderson # See www.python.org/2.2/license.html for @@ -367,7 +369,7 @@ if len(sys.argv)>1: fname = sys.argv[1] if not os.path.exists(fname): - print >> sys.stderr, '%s does not exist' % fname + print('%s does not exist' % fname) for line in file(fname): line = line.strip() diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/lineprops_dialog_gtk.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/lineprops_dialog_gtk.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/lineprops_dialog_gtk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/lineprops_dialog_gtk.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,7 +3,7 @@ from matplotlib.backends.backend_gtk import DialogLineprops import numpy as np -from pylab import figure, show +import matplotlib.pyplot as plt def f(t): s1 = np.cos(2*np.pi*t) @@ -14,12 +14,12 @@ t2 = np.arange(0.0, 5.0, 0.02) t3 = np.arange(0.0, 2.0, 0.01) -fig = figure() +fig = plt.figure() ax = fig.add_subplot(111) l1, = ax.plot(t1, f(t1), 'bo', label='line 1') l2, = ax.plot(t2, f(t2), 'k--', label='line 2') dlg = DialogLineprops([l1,l2]) dlg.show() -show() +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/mathtext_wx.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/mathtext_wx.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/mathtext_wx.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/mathtext_wx.py 2012-10-31 00:11:13.000000000 +0000 @@ -37,7 +37,7 @@ class CanvasFrame(wx.Frame): def __init__(self, parent, title): wx.Frame.__init__(self, parent, -1, title, size=(550, 350)) - self.SetBackgroundColour(wx.NamedColor("WHITE")) + self.SetBackgroundColour(wx.NamedColour("WHITE")) self.figure = Figure() self.axes = self.figure.add_subplot(111) diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/mpl_with_glade.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/mpl_with_glade.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/mpl_with_glade.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/mpl_with_glade.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,6 @@ #!/usr/bin/env python + +from __future__ import print_function import matplotlib matplotlib.use('GTK') @@ -64,15 +66,15 @@ self.canvas.grab_focus() def keypress(widget, event): - print 'key press' + print('key press') def buttonpress(widget, event): - print 'button press' + print('button press') self.canvas.connect('key_press_event', keypress) self.canvas.connect('button_press_event', buttonpress) def onselect(xmin, xmax): - print xmin, xmax + print(xmin, xmax) span = SpanSelector(self.axis, onselect, 'horizontal', useblit=False, rectprops=dict(alpha=0.5, facecolor='red') ) diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/printing_in_wx.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/printing_in_wx.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/printing_in_wx.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/printing_in_wx.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,8 @@ #!/usr/bin/env python # printing_in_wx.py # + +from __future__ import print_function """ This examples demonstrates Printing (ie, to a printer) with a matplotlib figure using a wx Frame. This borrows the data from @@ -166,7 +168,7 @@ self.canvas.print_figure(path,dpi=300) if (path.find(thisdir) == 0): path = path[len(thisdir)+1:] - print 'Saved plot to %s' % path + print('Saved plot to %s' % path) def onExit(self,event=None): self.Destroy() diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/pylab_with_gtk.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/pylab_with_gtk.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/pylab_with_gtk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/pylab_with_gtk.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,17 +2,19 @@ An example of how to use pylab to manage your figure windows, but modify the GUI by accessing the underlying gtk widgets """ +from __future__ import print_function import matplotlib matplotlib.use('GTKAgg') -from pylab import get_current_fig_manager, subplot, plot, legend, connect, show +import matplotlib.pyplot as plt -ax = subplot(111) -plot([1,2,3], 'ro-', label='easy as 1 2 3') -plot([1,4,9], 'gs--', label='easy as 1 2 3 squared') -legend() +ax = plt.subplot(111) +plt.plot([1,2,3], 'ro-', label='easy as 1 2 3') +plt.plot([1,4,9], 'gs--', label='easy as 1 2 3 squared') +plt.legend() -manager = get_current_fig_manager() + +manager = plt.get_current_fig_manager() # you can also access the window or vbox attributes this way toolbar = manager.toolbar @@ -23,7 +25,7 @@ button.show() def clicked(button): - print 'hi mom' + print('hi mom') button.connect('clicked', clicked) toolitem = gtk.ToolItem() @@ -49,6 +51,6 @@ else: label.set_markup('x,y=(%f, %f)'%(event.xdata, event.ydata)) -connect('motion_notify_event', update) +plt.connect('motion_notify_event', update) -show() +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/rec_edit_gtk_custom.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/rec_edit_gtk_custom.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/rec_edit_gtk_custom.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/rec_edit_gtk_custom.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,6 +3,7 @@ formatting of the cells and show how to limit string entries to a list of strings """ +from __future__ import print_function import gtk import numpy as np import matplotlib.mlab as mlab @@ -28,7 +29,7 @@ treeview = gtktools.RecTreeView(liststore, constant=constant) def mycallback(liststore, rownum, colname, oldval, newval): - print 'verify: old=%s, new=%s, rec=%s'%(oldval, newval, liststore.r[rownum][colname]) + print('verify: old=%s, new=%s, rec=%s'%(oldval, newval, liststore.r[rownum][colname])) liststore.callbacks.connect('cell_changed', mycallback) diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/svg_histogram.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/svg_histogram.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/svg_histogram.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/svg_histogram.py 2012-10-31 00:11:13.000000000 +0000 @@ -5,19 +5,38 @@ Demonstrate how to create an interactive histogram, in which bars are hidden or shown by cliking on legend markers. -The interactivity is encoded in ecmascript and inserted in the SVG code -in a post-processing step. To render the image, open it in a web -browser. SVG is supported in most web browsers used by Linux and OSX -users. Windows IE9 supports SVG, but earlier versions do not. +The interactivity is encoded in ecmascript (javascript) and inserted in +the SVG code in a post-processing step. To render the image, open it in +a web browser. SVG is supported in most web browsers used by Linux and +OSX users. Windows IE9 supports SVG, but earlier versions do not. + +Notes +----- +The matplotlib backend lets us assign ids to each object. This is the +mechanism used here to relate matplotlib objects created in python and +the corresponding SVG constructs that are parsed in the second step. +While flexible, ids are cumbersome to use for large collection of +objects. Two mechanisms could be used to simplify things: + * systematic grouping of objects into SVG tags, + * assingning classes to each SVG object according to its origin. + +For example, instead of modifying the properties of each individual bar, +the bars from the `hist` function could either be grouped in +a PatchCollection, or be assigned a class="hist_##" attribute. + +CSS could also be used more extensively to replace repetitive markup +troughout the generated SVG. __author__="david.huard@gmail.com" """ + import numpy as np import matplotlib.pyplot as plt import xml.etree.ElementTree as ET from StringIO import StringIO +import json plt.rcParams['svg.embed_char_paths'] = 'none' @@ -26,16 +45,7 @@ # space with ns0. ET.register_namespace("","http://www.w3.org/2000/svg") - -def python2js(d): - """Return a string representation of a python dictionary in - ecmascript object syntax.""" - - objs = [] - for key, value in d.items(): - objs.append( key + ':' + str(value) ) - - return '{' + ', '.join(objs) + '}' + # --- Create histogram, legend and title --- @@ -62,7 +72,11 @@ # Set ids for the legend patches for i, t in enumerate(leg.get_patches()): t.set_gid('leg_patch_%d'%i) - + +# Set ids for the text patches +for i, t in enumerate(leg.get_texts()): + t.set_gid('leg_text_%d'%i) + # Save SVG in a fake file object. f = StringIO() plt.savefig(f, format="svg") @@ -77,10 +91,15 @@ for i, t in enumerate(leg.get_patches()): el = xmlid['leg_patch_%d'%i] el.set('cursor', 'pointer') - el.set('opacity', '1.0') - el.set('onclick', "toggle_element(evt, 'hist_%d')"%i) + el.set('onclick', "toggle_hist(this)") -# Create script defining the function `toggle_element`. +# Add attributes to the text objects. +for i, t in enumerate(leg.get_texts()): + el = xmlid['leg_text_%d'%i] + el.set('cursor', 'pointer') + el.set('onclick', "toggle_hist(this)") + +# Create script defining the function `toggle_hist`. # We create a global variable `container` that stores the patches id # belonging to each histogram. Then a function "toggle_element" sets the # visibility attribute of all patches of each histogram and the opacity @@ -91,37 +110,46 @@ -"""%python2js(hist_patches) +"""%json.dumps(hist_patches) +# Add a transition effect +css = tree.getchildren()[0][0] +css.text = css.text + "g {-webkit-transition:opacity 0.4s ease-out;-moz-transition:opacity 0.4s ease-out;}" + # Insert the script and save to file. tree.insert(0, ET.XML(script)) diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/svg_tooltip.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/svg_tooltip.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/svg_tooltip.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/svg_tooltip.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,125 @@ +""" +SVG tooltip example +=================== + +This example shows how to create a tooltip that will show up when +hovering over a matplotlib patch. + +Although it is possible to create the tooltip from CSS or javascript, +here we create it in matplotlib and simply toggle its visibility on +when hovering over the patch. This approach provides total control over +the tooltip placement and appearance, at the expense of more code up +front. + +The alternative approach would be to put the tooltip content in `title` +atttributes of SVG objects. Then, using an existing js/CSS library, it +would be relatively straightforward to create the tooltip in the +browser. The content would be dictated by the `title` attribute, and +the appearance by the CSS. + + +:author: David Huard +""" + + +import matplotlib.pyplot as plt +import xml.etree.ElementTree as ET +from StringIO import StringIO + +ET.register_namespace("","http://www.w3.org/2000/svg") + +fig = plt.figure() +ax = fig.add_subplot(111) + +# Create patches to which tooltips will be assigned. +circle = plt.Circle((0,0), 5, fc='blue') +rect = plt.Rectangle((-5, 10), 10, 5, fc='green') + +ax.add_patch(circle) +ax.add_patch(rect) + +# Create the tooltips +circle_tip = ax.annotate('This is a blue circle.', + xy=(0,0), + xytext=(30,-30), + textcoords='offset points', + color='w', + ha='left', + bbox=dict(boxstyle='round,pad=.5', fc=(.1,.1,.1,.92), ec=(1.,1.,1.), lw=1, zorder=1), + ) + +rect_tip = ax.annotate('This is a green rectangle.', + xy=(-5,10), + xytext=(30,40), + textcoords='offset points', + color='w', + ha='left', + bbox=dict(boxstyle='round,pad=.5', fc=(.1,.1,.1,.92), ec=(1.,1.,1.), lw=1, zorder=1), + ) + + +# Set id for the patches +for i, t in enumerate(ax.patches): + t.set_gid('patch_%d'%i) + +# Set id for the annotations +for i, t in enumerate(ax.texts): + t.set_gid('tooltip_%d'%i) + + +# Save the figure in a fake file object +ax.set_xlim(-30, 30) +ax.set_ylim(-30, 30) +ax.set_aspect('equal') + +f = StringIO() +plt.savefig(f, format="svg") + +# --- Add interactivity --- + +# Create XML tree from the SVG file. +tree, xmlid = ET.XMLID(f.getvalue()) +tree.set('onload', 'init(evt)') + +# Hide the tooltips +for i, t in enumerate(ax.texts): + el = xmlid['tooltip_%d'%i] + el.set('visibility', 'hidden') + +# Assign onmouseover and onmouseout callbacks to patches. +for i, t in enumerate(ax.patches): + el = xmlid['patch_%d'%i] + el.set('onmouseover', "ShowTooltip(this)") + el.set('onmouseout', "HideTooltip(this)") + +# This is the script defining the ShowTooltip and HideTooltip functions. +script = """ + + """ + +# Insert the script at the top of the file and save it. +tree.insert(0, ET.XML(script)) +ET.ElementTree(tree).write('svg_tooltip.svg') diff -Nru matplotlib-1.1.1/doc/mpl_examples/user_interfaces/wxcursor_demo.py matplotlib-1.2.0/doc/mpl_examples/user_interfaces/wxcursor_demo.py --- matplotlib-1.1.1/doc/mpl_examples/user_interfaces/wxcursor_demo.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/user_interfaces/wxcursor_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -18,7 +18,7 @@ wx.Frame.__init__(self,None,-1, 'CanvasFrame',size=(550,350)) - self.SetBackgroundColour(wx.NamedColor("WHITE")) + self.SetBackgroundColour(wx.NamedColour("WHITE")) self.figure = Figure() self.axes = self.figure.add_subplot(111) diff -Nru matplotlib-1.1.1/doc/mpl_examples/widgets/lasso_selector_demo.py matplotlib-1.2.0/doc/mpl_examples/widgets/lasso_selector_demo.py --- matplotlib-1.1.1/doc/mpl_examples/widgets/lasso_selector_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/widgets/lasso_selector_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,89 @@ +from __future__ import print_function + +import numpy as np + +from matplotlib.widgets import LassoSelector +from matplotlib.path import Path + +try: + raw_input +except NameError: + # Python 3 + raw_input = input + + +class SelectFromCollection(object): + """Select indices from a matplotlib collection using `LassoSelector`. + + Selected indices are saved in the `ind` attribute. This tool highlights + selected points by fading them out (i.e., reducing their alpha values). + If your collection has alpha < 1, this tool will permanently alter them. + + Note that this tool selects collection objects based on their *origins* + (i.e., `offsets`). + + Parameters + ---------- + ax : :class:`~matplotlib.axes.Axes` + Axes to interact with. + + collection : :class:`matplotlib.collections.Collection` subclass + Collection you want to select from. + + alpha_other : 0 <= float <= 1 + To highlight a selection, this tool sets all selected points to an + alpha value of 1 and non-selected points to `alpha_other`. + """ + def __init__(self, ax, collection, alpha_other=0.3): + self.canvas = ax.figure.canvas + self.collection = collection + self.alpha_other = alpha_other + + self.xys = collection.get_offsets() + self.Npts = len(self.xys) + + # Ensure that we have separate colors for each object + self.fc = collection.get_facecolors() + if len(self.fc) == 0: + raise ValueError('Collection must have a facecolor') + elif len(self.fc) == 1: + self.fc = np.tile(self.fc, self.Npts).reshape(self.Npts, -1) + + self.lasso = LassoSelector(ax, onselect=self.onselect) + self.ind = [] + + def onselect(self, verts): + path = Path(verts) + self.ind = np.nonzero([path.contains_point(xy) for xy in self.xys])[0] + self.fc[:, -1] = self.alpha_other + self.fc[self.ind, -1] = 1 + self.collection.set_facecolors(self.fc) + self.canvas.draw_idle() + + def disconnect(self): + self.lasso.disconnect_events() + self.fc[:, -1] = 1 + self.collection.set_facecolors(self.fc) + self.canvas.draw_idle() + + +if __name__ == '__main__': + import matplotlib.pyplot as plt + + plt.ion() + data = np.random.rand(100, 2) + + subplot_kw = dict(xlim=(0, 1), ylim=(0, 1), autoscale_on=False) + fig, ax = plt.subplots(subplot_kw=subplot_kw) + + pts = ax.scatter(data[:, 0], data[:, 1], s=80) + selector = SelectFromCollection(ax, pts) + + plt.draw() + raw_input('Press any key to accept selected points') + print("Selected points:") + print(selector.xys[selector.ind]) + selector.disconnect() + + # Block end of script so you can check that the lasso is disconnected. + raw_input('Press any key to quit') diff -Nru matplotlib-1.1.1/doc/mpl_examples/widgets/menu.py matplotlib-1.2.0/doc/mpl_examples/widgets/menu.py --- matplotlib-1.1.1/doc/mpl_examples/widgets/menu.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/widgets/menu.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import division, print_function import numpy as np import matplotlib import matplotlib.colors as colors @@ -75,7 +76,7 @@ self.on_select(self) def set_extent(self, x, y, w, h): - print x, y, w, h + print(x, y, w, h) self.rect.set_x(x) self.rect.set_y(y) self.rect.set_width(w) @@ -171,7 +172,7 @@ menuitems = [] for label in ('open', 'close', 'save', 'save as', 'quit'): def on_select(item): - print 'you selected', item.labelstr + print('you selected %s' % item.labelstr) item = MenuItem(fig, label, props=props, hoverprops=hoverprops, on_select=on_select) menuitems.append(item) diff -Nru matplotlib-1.1.1/doc/mpl_examples/widgets/multicursor.py matplotlib-1.2.0/doc/mpl_examples/widgets/multicursor.py --- matplotlib-1.1.1/doc/mpl_examples/widgets/multicursor.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/widgets/multicursor.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,11 @@ +import numpy as np +import matplotlib.pyplot as plt from matplotlib.widgets import MultiCursor -from pylab import figure, show, pi, arange, sin -t = arange(0.0, 2.0, 0.01) -s1 = sin(2*pi*t) -s2 = sin(4*pi*t) -fig = figure() +t = np.arange(0.0, 2.0, 0.01) +s1 = np.sin(2*np.pi*t) +s2 = np.sin(4*np.pi*t) +fig = plt.figure() ax1 = fig.add_subplot(211) ax1.plot(t, s1) @@ -13,4 +14,4 @@ ax2.plot(t, s2) multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1) -show() +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/widgets/radio_buttons.py matplotlib-1.2.0/doc/mpl_examples/widgets/radio_buttons.py --- matplotlib-1.1.1/doc/mpl_examples/widgets/radio_buttons.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/widgets/radio_buttons.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,36 +1,38 @@ +import numpy as np +import matplotlib.pyplot as plt from matplotlib.widgets import RadioButtons -from pylab import * -t = arange(0.0, 2.0, 0.01) -s0 = sin(2*pi*t) -s1 = sin(4*pi*t) -s2 = sin(8*pi*t) -ax = subplot(111) +t = np.arange(0.0, 2.0, 0.01) +s0 = np.sin(2*np.pi*t) +s1 = np.sin(4*np.pi*t) +s2 = np.sin(8*np.pi*t) + +ax = plt.subplot(111) l, = ax.plot(t, s0, lw=2, color='red') -subplots_adjust(left=0.3) +plt.subplots_adjust(left=0.3) axcolor = 'lightgoldenrodyellow' -rax = axes([0.05, 0.7, 0.15, 0.15], axisbg=axcolor) +rax = plt.axes([0.05, 0.7, 0.15, 0.15], axisbg=axcolor) radio = RadioButtons(rax, ('2 Hz', '4 Hz', '8 Hz')) def hzfunc(label): hzdict = {'2 Hz':s0, '4 Hz':s1, '8 Hz':s2} ydata = hzdict[label] l.set_ydata(ydata) - draw() + plt.draw() radio.on_clicked(hzfunc) -rax = axes([0.05, 0.4, 0.15, 0.15], axisbg=axcolor) +rax = plt.axes([0.05, 0.4, 0.15, 0.15], axisbg=axcolor) radio2 = RadioButtons(rax, ('red', 'blue', 'green')) def colorfunc(label): l.set_color(label) - draw() + plt.draw() radio2.on_clicked(colorfunc) -rax = axes([0.05, 0.1, 0.15, 0.15], axisbg=axcolor) +rax = plt.axes([0.05, 0.1, 0.15, 0.15], axisbg=axcolor) radio3 = RadioButtons(rax, ('-', '--', '-.', 'steps', ':')) def stylefunc(label): l.set_linestyle(label) - draw() + plt.draw() radio3.on_clicked(stylefunc) -show() +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/widgets/rectangle_selector.py matplotlib-1.2.0/doc/mpl_examples/widgets/rectangle_selector.py --- matplotlib-1.1.1/doc/mpl_examples/widgets/rectangle_selector.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/widgets/rectangle_selector.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function """ Do a mouseclick somewhere, move the mouse to some destination, release the button. This class gives click- and release-events and also draws @@ -15,16 +16,16 @@ 'eclick and erelease are the press and release events' x1, y1 = eclick.xdata, eclick.ydata x2, y2 = erelease.xdata, erelease.ydata - print "(%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1, y1, x2, y2) - print " The button you used were: ", eclick.button, erelease.button + print ("(%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1, y1, x2, y2)) + print (" The button you used were: %s %s" % (eclick.button, erelease.button)) def toggle_selector(event): - print ' Key pressed.' + print (' Key pressed.') if event.key in ['Q', 'q'] and toggle_selector.RS.active: - print ' RectangleSelector deactivated.' + print (' RectangleSelector deactivated.') toggle_selector.RS.set_active(False) if event.key in ['A', 'a'] and not toggle_selector.RS.active: - print ' RectangleSelector activated.' + print (' RectangleSelector activated.') toggle_selector.RS.set_active(True) @@ -36,7 +37,7 @@ plt.plot(x, +np.cos(.2*np.pi*x), lw=3.5, c='r', alpha=.5) plt.plot(x, -np.sin(.2*np.pi*x), lw=3.5, c='g', alpha=.3) -print "\n click --> release" +print ("\n click --> release") # drawtype is 'box' or 'line' or 'none' toggle_selector.RS = RectangleSelector(current_ax, line_select_callback, diff -Nru matplotlib-1.1.1/doc/mpl_examples/widgets/slider_demo.py matplotlib-1.2.0/doc/mpl_examples/widgets/slider_demo.py --- matplotlib-1.1.1/doc/mpl_examples/widgets/slider_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/widgets/slider_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,18 +1,19 @@ -from pylab import * +import numpy as np +import matplotlib.pyplot as plt from matplotlib.widgets import Slider, Button, RadioButtons -ax = subplot(111) -subplots_adjust(left=0.25, bottom=0.25) -t = arange(0.0, 1.0, 0.001) +ax = plt.subplot(111) +plt.subplots_adjust(left=0.25, bottom=0.25) +t = np.arange(0.0, 1.0, 0.001) a0 = 5 f0 = 3 -s = a0*sin(2*pi*f0*t) -l, = plot(t,s, lw=2, color='red') -axis([0, 1, -10, 10]) +s = a0*np.sin(2*np.pi*f0*t) +l, = plt.plot(t,s, lw=2, color='red') +plt.axis([0, 1, -10, 10]) axcolor = 'lightgoldenrodyellow' -axfreq = axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor) -axamp = axes([0.25, 0.15, 0.65, 0.03], axisbg=axcolor) +axfreq = plt.axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor) +axamp = plt.axes([0.25, 0.15, 0.65, 0.03], axisbg=axcolor) sfreq = Slider(axfreq, 'Freq', 0.1, 30.0, valinit=f0) samp = Slider(axamp, 'Amp', 0.1, 10.0, valinit=a0) @@ -20,24 +21,24 @@ def update(val): amp = samp.val freq = sfreq.val - l.set_ydata(amp*sin(2*pi*freq*t)) - draw() + l.set_ydata(amp*np.sin(2*np.pi*freq*t)) + plt.draw() sfreq.on_changed(update) samp.on_changed(update) -resetax = axes([0.8, 0.025, 0.1, 0.04]) +resetax = plt.axes([0.8, 0.025, 0.1, 0.04]) button = Button(resetax, 'Reset', color=axcolor, hovercolor='0.975') def reset(event): sfreq.reset() samp.reset() button.on_clicked(reset) -rax = axes([0.025, 0.5, 0.15, 0.15], axisbg=axcolor) +rax = plt.axes([0.025, 0.5, 0.15, 0.15], axisbg=axcolor) radio = RadioButtons(rax, ('red', 'blue', 'green'), active=0) def colorfunc(label): l.set_color(label) - draw() + plt.draw() radio.on_clicked(colorfunc) -show() +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_examples/widgets/span_selector.py matplotlib-1.2.0/doc/mpl_examples/widgets/span_selector.py --- matplotlib-1.1.1/doc/mpl_examples/widgets/span_selector.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_examples/widgets/span_selector.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,15 +3,15 @@ The SpanSelector is a mouse widget to select a xmin/xmax range and plot the detail view of the selected region in the lower axes """ -import numpy as npy -from pylab import figure, show +import numpy as np +import matplotlib.pyplot as plt from matplotlib.widgets import SpanSelector -fig = figure(figsize=(8,6)) +fig = plt.figure(figsize=(8,6)) ax = fig.add_subplot(211, axisbg='#FFFFCC') -x = npy.arange(0.0, 5.0, 0.01) -y = npy.sin(2*npy.pi*x) + 0.5*npy.random.randn(len(x)) +x = np.arange(0.0, 5.0, 0.01) +y = np.sin(2*np.pi*x) + 0.5*np.random.randn(len(x)) ax.plot(x, y, '-') ax.set_ylim(-2,2) @@ -22,7 +22,7 @@ def onselect(xmin, xmax): - indmin, indmax = npy.searchsorted(x, (xmin, xmax)) + indmin, indmax = np.searchsorted(x, (xmin, xmax)) indmax = min(len(x)-1, indmax) thisx = x[indmin:indmax] @@ -37,4 +37,4 @@ rectprops=dict(alpha=0.5, facecolor='red') ) -show() +plt.show() diff -Nru matplotlib-1.1.1/doc/mpl_toolkits/axes_grid/examples/demo_edge_colorbar.py matplotlib-1.2.0/doc/mpl_toolkits/axes_grid/examples/demo_edge_colorbar.py --- matplotlib-1.1.1/doc/mpl_toolkits/axes_grid/examples/demo_edge_colorbar.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_toolkits/axes_grid/examples/demo_edge_colorbar.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,89 @@ +import matplotlib.pyplot as plt +from mpl_toolkits.axes_grid1 import AxesGrid + +def get_demo_image(): + import numpy as np + from matplotlib.cbook import get_sample_data + f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False) + z = np.load(f) + # z is a numpy array of 15x15 + return z, (-3,4,-4,3) + + +def demo_bottom_cbar(fig): + """ + A grid of 2x2 images with a colorbar for each column. + """ + grid = AxesGrid(fig, 121, # similar to subplot(132) + nrows_ncols = (2, 2), + axes_pad = 0.10, + share_all=True, + label_mode = "1", + cbar_location = "bottom", + cbar_mode="edge", + cbar_pad = 0.25, + cbar_size = "15%", + direction="column" + ) + + Z, extent = get_demo_image() + cmaps = [plt.get_cmap("autumn"), plt.get_cmap("summer")] + for i in range(4): + im = grid[i].imshow(Z, extent=extent, interpolation="nearest", + cmap=cmaps[i//2]) + if i % 2: + cbar = grid.cbar_axes[i//2].colorbar(im) + + for cax in grid.cbar_axes: + cax.toggle_label(True) + cax.axis[cax.orientation].set_label("Bar") + + # This affects all axes as share_all = True. + grid.axes_llc.set_xticks([-2, 0, 2]) + grid.axes_llc.set_yticks([-2, 0, 2]) + + +def demo_right_cbar(fig): + """ + A grid of 2x2 images. Each row has its own colorbar. + """ + + grid = AxesGrid(F, 122, # similar to subplot(122) + nrows_ncols = (2, 2), + axes_pad = 0.10, + label_mode = "1", + share_all = True, + cbar_location="right", + cbar_mode="edge", + cbar_size="7%", + cbar_pad="2%", + ) + Z, extent = get_demo_image() + cmaps = [plt.get_cmap("spring"), plt.get_cmap("winter")] + for i in range(4): + im = grid[i].imshow(Z, extent=extent, interpolation="nearest", + cmap=cmaps[i//2]) + if i % 2: + grid.cbar_axes[i//2].colorbar(im) + + for cax in grid.cbar_axes: + cax.toggle_label(True) + cax.axis[cax.orientation].set_label('Foo') + + # This affects all axes because we set share_all = True. + grid.axes_llc.set_xticks([-2, 0, 2]) + grid.axes_llc.set_yticks([-2, 0, 2]) + + + +if 1: + F = plt.figure(1, (5.5, 2.5)) + + F.subplots_adjust(left=0.05, right=0.93) + + demo_bottom_cbar(F) + demo_right_cbar(F) + + plt.draw() + plt.show() + diff -Nru matplotlib-1.1.1/doc/mpl_toolkits/index.rst matplotlib-1.2.0/doc/mpl_toolkits/index.rst --- matplotlib-1.1.1/doc/mpl_toolkits/index.rst 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_toolkits/index.rst 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,12 @@ .. _toolkits-index: +.. toctree:: + :hidden: + + axes_grid/index.rst + mplot3d/index.rst + + ######## Toolkits ######## diff -Nru matplotlib-1.1.1/doc/mpl_toolkits/mplot3d/tutorial.rst matplotlib-1.2.0/doc/mpl_toolkits/mplot3d/tutorial.rst --- matplotlib-1.1.1/doc/mpl_toolkits/mplot3d/tutorial.rst 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/mpl_toolkits/mplot3d/tutorial.rst 2012-10-31 00:11:13.000000000 +0000 @@ -64,6 +64,15 @@ .. plot:: mpl_examples/mplot3d/surface3d_demo2.py .. plot:: mpl_examples/mplot3d/surface3d_demo3.py +.. _trisurface: + +Tri-Surface plots +================= +.. automethod:: Axes3D.plot_trisurf + +.. plot:: mpl_examples/mplot3d/trisurf3d_demo.py + + .. _contour3d: Contour plots diff -Nru matplotlib-1.1.1/doc/pyplots/README matplotlib-1.2.0/doc/pyplots/README --- matplotlib-1.1.1/doc/pyplots/README 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/pyplots/README 2012-10-31 00:11:13.000000000 +0000 @@ -8,8 +8,3 @@ plotmap.py: basemap toolkit - - some data files - do a svn co - https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/trunk/htdocs/screenshots/data/ - to get the data and then set the datadir variable in the - plotmap.py file to point to this data direcotry diff -Nru matplotlib-1.1.1/doc/pyplots/make.py matplotlib-1.2.0/doc/pyplots/make.py --- matplotlib-1.1.1/doc/pyplots/make.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/pyplots/make.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,75 @@ +#!/usr/bin/env python + +from __future__ import print_function +import sys, os, glob +import matplotlib +import IPython.Shell +#matplotlib.rcdefaults() +matplotlib.use('Agg') + +mplshell = IPython.Shell.MatplotlibShell('mpl') + +formats = [('png', 100), + ('hires.png', 200), + ('pdf', 72)] + +def figs(): + print('making figs') + import matplotlib.pyplot as plt + for fname in glob.glob('*.py'): + if fname.split('/')[-1] == __file__.split('/')[-1]: continue + basename, ext = os.path.splitext(fname) + imagefiles = dict([('%s.%s'%(basename, format), dpi) + for format, dpi in formats]) + all_exists = True + for imagefile in imagefiles: + if not os.path.exists(imagefile): + all_exists = False + break + + if all_exists: + print(' already have %s'%fname) + else: + print(' building %s'%fname) + plt.close('all') # we need to clear between runs + mplshell.magic_run(basename) + for imagefile, dpi in imagefiles.iteritems(): + # todo: this will get called even if the run script + # fails and exits, thus creating a stub pdf and png + # iles preventing them from getting built successfully + # later + plt.savefig(imagefile, dpi=dpi) + print('all figures made') + + +def clean(): + patterns = (['#*', '*~', '*pyc'] + + ['*.%s' % format for format, dpi in formats]) + for pattern in patterns: + for fname in glob.glob(pattern): + os.remove(fname) + print('all clean') + + + +def all(): + figs() + +funcd = {'figs':figs, + 'clean':clean, + 'all':all, + } + +if len(sys.argv)>1: + for arg in sys.argv[1:]: + func = funcd.get(arg) + if func is None: + raise SystemExit('Do not know how to handle %s; valid args are'%( + arg, funcd.keys())) + func() +else: + all() + + + + diff -Nru matplotlib-1.1.1/doc/pyplots/matplotlibrc matplotlib-1.2.0/doc/pyplots/matplotlibrc --- matplotlib-1.1.1/doc/pyplots/matplotlibrc 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/pyplots/matplotlibrc 2012-10-31 00:11:13.000000000 +0000 @@ -1,314 +1,3 @@ -### MATPLOTLIBRC FORMAT - -# This is a sample matplotlib configuration file. It should be placed -# in HOME/.matplotlib/matplotlibrc (unix/linux like systems) and -# C:\Documents and Settings\yourname\.matplotlib (win32 systems) -# -# By default, the installer will overwrite the existing file in the -# install path, so if you want to preserve your's, please move it to -# your HOME dir and set the environment variable if necessary. -# -# This file is best viewed in a editor which supports python mode -# syntax highlighting -# -# Blank lines, or lines starting with a comment symbol, are ignored, -# as are trailing comments. Other lines must have the format -# -# key : val # optional comment -# -# Colors: for the color values below, you can either use -# - a matplotlib color string, such as r, k, or b -# - an rgb tuple, such as (1.0, 0.5, 0.0) -# - a hex string, such as ff00ff (no '#' symbol) -# - a scalar grayscale intensity such as 0.75 -# - a legal html color name, eg red, blue, darkslategray - -#### CONFIGURATION BEGINS HERE -# the default backend; one of GTK GTKAgg GTKCairo FltkAgg QtAgg TkAgg -# WX WXAgg Agg Cairo GD GDK Paint PS PDF SVG Template +# local matplotlibrc for generating image files in this directory backend : Agg -#maskedarray : False # True to use external maskedarray module - # instead of numpy.ma; this is a temporary - # setting for testing maskedarray. -#interactive : False # see http://matplotlib.sourceforge.net/interactive.html -#toolbar : toolbar2 # None | classic | toolbar2 -#timezone : UTC # a pytz timezone string, eg US/Central or Europe/Paris - -# Where your matplotlib data lives if you installed to a non-default -# location. This is where the matplotlib fonts, bitmaps, etc reside -#datapath : /home/jdhunter/mpldata - - -### LINES -# See http://matplotlib.sourceforge.net/matplotlib.lines.html for more -# information on line properties. -#lines.linewidth : 1.0 # line width in points -#lines.linestyle : - # solid line -#lines.color : blue -#lines.marker : None # the default marker -#lines.markeredgewidth : 0.5 # the line width around the marker symbol -#lines.markersize : 6 # markersize, in points -#lines.dash_joinstyle : miter # miter|round|bevel -#lines.dash_capstyle : butt # butt|round|projecting -#lines.solid_joinstyle : miter # miter|round|bevel -#lines.solid_capstyle : projecting # butt|round|projecting -#lines.antialiased : True # render lines in antialised (no jaggies) - -### PATCHES -# Patches are graphical objects that fill 2D space, like polygons or -# circles. See -# http://matplotlib.sourceforge.net/matplotlib.patches.html for more -# information on patch properties -#patch.linewidth : 1.0 # edge width in points -#patch.facecolor : blue -#patch.edgecolor : black -#patch.antialiased : True # render patches in antialised (no jaggies) - -### FONT -# -# font properties used by text.Text. See -# http://matplotlib.sourceforge.net/matplotlib.font_manager.html for more -# information on font properties. The 6 font properties used for font -# matching are given below with their default values. -# -# The font.family property has five values: 'serif' (e.g. Times), -# 'sans-serif' (e.g. Helvetica), 'cursive' (e.g. Zapf-Chancery), -# 'fantasy' (e.g. Western), and 'monospace' (e.g. Courier). Each of -# these font families has a default list of font names in decreasing -# order of priority associated with them. -# -# The font.style property has three values: normal (or roman), italic -# or oblique. The oblique style will be used for italic, if it is not -# present. -# -# The font.variant property has two values: normal or small-caps. For -# TrueType fonts, which are scalable fonts, small-caps is equivalent -# to using a font size of 'smaller', or about 83% of the current font -# size. -# -# The font.weight property has effectively 13 values: normal, bold, -# bolder, lighter, 100, 200, 300, ..., 900. Normal is the same as -# 400, and bold is 700. bolder and lighter are relative values with -# respect to the current weight. -# -# The font.stretch property has 11 values: ultra-condensed, -# extra-condensed, condensed, semi-condensed, normal, semi-expanded, -# expanded, extra-expanded, ultra-expanded, wider, and narrower. This -# property is not currently implemented. -# -# The font.size property is the default font size for text, given in pts. -# 12pt is the standard value. -# -#font.family : sans-serif -#font.style : normal -#font.variant : normal -#font.weight : medium -#font.stretch : normal -# note that font.size controls default text sizes. To configure -# special text sizes tick labels, axes, labels, title, etc, see the rc -# settings for axes and ticks. Special text sizes can be defined -# relative to font.size, using the following values: xx-small, x-small, -# small, medium, large, x-large, xx-large, larger, or smaller -#font.size : 12.0 -#font.serif : Bitstream Vera Serif, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif -#font.sans-serif : Bitstream Vera Sans, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif -#font.cursive : Apple Chancery, Textile, Zapf Chancery, Sand, cursive -#font.fantasy : Comic Sans MS, Chicago, Charcoal, Impact, Western, fantasy -#font.monospace : Bitstream Vera Sans Mono, Andale Mono, Nimbus Mono L, Courier New, Courier, Fixed, Terminal, monospace - -### TEXT -# text properties used by text.Text. See -# http://matplotlib.sourceforge.net/matplotlib.text.html for more -# information on text properties - -#text.color : black - -### LaTeX customizations. See http://www.scipy.org/Wiki/Cookbook/Matplotlib/UsingTex -#text.usetex : False # use latex for all text handling. The following fonts - # are supported through the usual rc parameter settings: - # new century schoolbook, bookman, times, palatino, - # zapf chancery, charter, serif, sans-serif, helvetica, - # avant garde, courier, monospace, computer modern roman, - # computer modern sans serif, computer modern typewriter - # If another font is desired which can loaded using the - # LaTeX \usepackage command, please inquire at the - # matplotlib mailing list -#text.latex.unicode : False # use "ucs" and "inputenc" LaTeX packages for handling - # unicode strings. -#text.latex.preamble : # IMPROPER USE OF THIS FEATURE WILL LEAD TO LATEX FAILURES - # AND IS THEREFORE UNSUPPORTED. PLEASE DO NOT ASK FOR HELP - # IF THIS FEATURE DOES NOT DO WHAT YOU EXPECT IT TO. - # preamble is a comma separated list of LaTeX statements - # that are included in the LaTeX document preamble. - # An example: - # text.latex.preamble : \usepackage{bm},\usepackage{euler} - # The following packages are always loaded with usetex, so - # beware of package collisions: color, geometry, graphicx, - # type1cm, textcomp. Adobe Postscript (PSSNFS) font packages - # may also be loaded, depending on your font settings -#text.dvipnghack : False # some versions of dvipng don't handle - # alpha channel properly. Use True to correct and flush - # ~/.matplotlib/tex.cache before testing -#text.markup : 'plain' # Affects how text, such as titles and labels, are - # interpreted by default. - # 'plain': As plain, unformatted text - # 'tex': As TeX-like text. Text between $'s will be - # formatted as a TeX math expression. - # This setting has no effect when text.usetex is True. - # In that case, all text will be sent to TeX for - # processing. - -# The following settings allow you to select the fonts in math mode. -# They map from a TeX font name to a fontconfig font pattern. -# These settings are only used if mathtext.fontset is 'custom'. -#mathtext.cal : cursive -#mathtext.rm : serif -#mathtext.tt : monospace -#mathtext.it : serif:italic -#mathtext.bf : serif:bold -#mathtext.sf : sans -#mathtext.fontset : cm # Should be 'cm' (Computer Modern), 'stix', - # 'stixsans' or 'custom' -#mathtext.fallback_to_cm : True # When True, use symbols from the Computer Modern - # fonts when a symbol can not be found in one of - # the custom math fonts. - -### AXES -# default face and edge color, default tick sizes, -# default fontsizes for ticklabels, and so on. See -# http://matplotlib.sourceforge.net/matplotlib.axes.html#Axes -#axes.hold : True # whether to clear the axes by default on -#axes.facecolor : white # axes background color -#axes.edgecolor : black # axes edge color -#axes.linewidth : 1.0 # edge linewidth -#axes.grid : False # display grid or not -#axes.titlesize : 14 # fontsize of the axes title -#axes.labelsize : 12 # fontsize of the x any y labels -#axes.labelcolor : black -#axes.axisbelow : False # whether axis gridlines and ticks are below - # the axes elements (lines, text, etc) -#axes.formatter.limits : -7, 7 # use scientific notation if log10 - # of the axis range is smaller than the - # first or larger than the second - -#polaraxes.grid : True # display grid on polar axes - -### TICKS -# see http://matplotlib.sourceforge.net/matplotlib.axis.html#Ticks -#xtick.major.size : 4 # major tick size in points -#xtick.minor.size : 2 # minor tick size in points -#xtick.major.pad : 4 # distance to major tick label in points -#xtick.minor.pad : 4 # distance to the minor tick label in points -#xtick.color : k # color of the tick labels -#xtick.labelsize : 12 # fontsize of the tick labels -#xtick.direction : in # direction: in or out - -#ytick.major.size : 4 # major tick size in points -#ytick.minor.size : 2 # minor tick size in points -#ytick.major.pad : 4 # distance to major tick label in points -#ytick.minor.pad : 4 # distance to the minor tick label in points -#ytick.color : k # color of the tick labels -#ytick.labelsize : 12 # fontsize of the tick labels -#ytick.direction : in # direction: in or out - - -### GRIDS -#grid.color : black # grid color -#grid.linestyle : : # dotted -#grid.linewidth : 0.5 # in points - -### Legend -#legend.isaxes : True -#legend.numpoints : 2 # the number of points in the legend line -#legend.fontsize : 14 -#legend.pad : 0.2 # the fractional whitespace inside the legend border -#legend.markerscale : 1.0 # the relative size of legend markers vs. original -# the following dimensions are in axes coords -#legend.labelsep : 0.010 # the vertical space between the legend entries -#legend.handlelen : 0.05 # the length of the legend lines -#legend.handletextsep : 0.02 # the space between the legend line and legend text -#legend.axespad : 0.02 # the border between the axes and legend edge -#legend.shadow : False - -### FIGURE -# See http://matplotlib.sourceforge.net/matplotlib.figure.html#Figure figure.figsize : 6, 4 # figure size in inches -#figure.dpi : 80 # figure dots per inch -#figure.facecolor : 0.75 # figure facecolor; 0.75 is scalar gray -#figure.edgecolor : white # figure edgecolor - -# The figure subplot parameters. All dimensions are fraction of the -# figure width or height -#figure.subplot.left : 0.15 # the left side of the subplots of the figure -#figure.subplot.right : 0.9 # the right side of the subplots of the figure -#figure.subplot.bottom : 0.15 # the bottom of the subplots of the figure -#figure.subplot.top : 0.9 # the top of the subplots of the figure -#figure.subplot.wspace : 0.2 # the amount of width reserved for blank space between subplots -#figure.subplot.hspace : 0.2 # the amount of height reserved for white space between subplots - -#figure.autolayout : False # when True, adjust the axes so that text doesn't overlap - -### IMAGES -#image.aspect : equal # equal | auto | a number -#image.interpolation : bilinear # see help(imshow) for options -#image.cmap : jet # gray | jet etc... -#image.lut : 256 # the size of the colormap lookup table -#image.origin : upper # lower | upper - - -### CONTOUR PLOTS -#contour.negative_linestyle : dashed # dashed | solid - -### SAVING FIGURES -# the default savefig params can be different for the GUI backends. -# Eg, you may want a higher resolution, or to make the figure -# background white -#savefig.dpi : 100 # figure dots per inch -#savefig.facecolor : white # figure facecolor when saving -#savefig.edgecolor : white # figure edgecolor when saving - -#cairo.format : png # png, ps, pdf, svg - -# tk backend params -#tk.window_focus : False # Maintain shell focus for TkAgg -#tk.pythoninspect : False # tk sets PYTHONINSEPCT - -# ps backend params -#ps.papersize : letter # auto, letter, legal, ledger, A0-A10, B0-B10 -#ps.useafm : False # use of afm fonts, results in small files -#ps.usedistiller : False # can be: None, ghostscript or xpdf - # Experimental: may produce smaller files. - # xpdf intended for production of publication quality files, - # but requires ghostscript, xpdf and ps2eps -#ps.distiller.res : 6000 # dpi -#ps.fonttype : 3 # Output Type 3 (Type3) or Type 42 (TrueType) - -# pdf backend params -#pdf.compression : 6 # integer from 0 to 9 - # 0 disables compression (good for debugging) -#pdf.fonttype : 3 # Output Type 3 (Type3) or Type 42 (TrueType) - -# svg backend params -#svg.image_inline : True # write raster image data directly into the svg file -#svg.image_noscale : False # suppress scaling of raster data embedded in SVG -#svg.embed_chars : True # embed character outlines in the SVG file - -# Set the verbose flags. This controls how much information -# matplotlib gives you at runtime and where it goes. The verbosity -# levels are: silent, helpful, debug, debug-annoying. Any level is -# inclusive of all the levels below it. If you setting is debug, -# you'll get all the debug and helpful messages. When submitting -# problems to the mailing-list, please set verbose to helpful or debug -# and paste the output into your report. -# -# The fileo gives the destination for any calls to verbose.report. -# These objects can a filename, or a filehandle like sys.stdout. -# -# You can override the rc default verbosity from the command line by -# giving the flags --verbose-LEVEL where LEVEL is one of the legal -# levels, eg --verbose-helpful. -# -# You can access the verbose instance in your code -# from matplotlib import verbose. -#verbose.level : silent # one of silent, helpful, debug, debug-annoying -#verbose.fileo : sys.stdout # a log filename, sys.stdout or sys.stderr diff -Nru matplotlib-1.1.1/doc/sphinxext/gen_gallery.py matplotlib-1.2.0/doc/sphinxext/gen_gallery.py --- matplotlib-1.1.1/doc/sphinxext/gen_gallery.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/sphinxext/gen_gallery.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,5 @@ +# -*- coding: UTF-8 -*- + # generate a thumbnail gallery of examples template = """\ {%% extends "layout.html" %%} @@ -9,6 +11,11 @@

Click on any image to see full size image and source code


+
  • Gallery
      +%s +
    +
  • + %s {%% endblock %%} """ @@ -16,7 +23,7 @@ import os, glob, re, sys, warnings import matplotlib.image as image -multiimage = re.compile('(.*)_\d\d') +multiimage = re.compile('(.*?)(_\d\d){1,2}') def make_thumbnail(args): image.thumbnail(args[0], args[1], 0.3) @@ -42,15 +49,33 @@ 'matplotlib_icon', ]) - data = [] thumbnails = {} + rows = [] + toc_rows = [] + + link_template = """\ + %s + """ + + header_template = """
    \ +

    %s

    """ + + toc_template = """\ +
  • %s
  • """ + + dirs = ('api', 'pylab_examples', 'mplot3d', 'widgets', 'axes_grid' ) + + for subdir in dirs : + rows.append(header_template % (subdir, subdir, subdir)) + toc_rows.append(toc_template % (subdir, subdir)) - for subdir in ('api', 'pylab_examples', 'mplot3d', 'widgets', 'axes_grid' ): origdir = os.path.join('build', rootdir, subdir) thumbdir = os.path.join(outdir, rootdir, subdir, 'thumbnails') if not os.path.exists(thumbdir): os.makedirs(thumbdir) + data = [] + for filename in sorted(glob.glob(os.path.join(origdir, '*.png'))): if filename.endswith("hires.png"): continue @@ -68,31 +93,32 @@ thumbnails[orig_path] = thumb_path m = multiimage.match(basename) - if m is None: - pyfile = '%s.py'%basename - else: + if m is not None: basename = m.group(1) - pyfile = '%s.py'%basename data.append((subdir, basename, os.path.join(rootdir, subdir, 'thumbnails', filename))) - link_template = """\ - %s - """ - if len(data) == 0: - warnings.warn("No thumbnails were found") - rows = [] - for (subdir, basename, thumbfile) in data: - if thumbfile is not None: - link = 'examples/%s/%s.html'%(subdir, basename) - rows.append(link_template%(link, thumbfile, basename)) + + for (subdir, basename, thumbfile) in data: + if thumbfile is not None: + link = 'examples/%s/%s.html'%(subdir, basename) + rows.append(link_template%(link, thumbfile, basename)) + + if len(data) == 0: + warnings.warn("No thumbnails were found in %s" % subdir) + + # Close out the
    opened up at the top of this loop + rows.append("
    ") + + content = template % ('\n'.join(toc_rows), + '\n'.join(rows)) # Only write out the file if the contents have actually changed. # Otherwise, this triggers a full rebuild of the docs - content = template%'\n'.join(rows) + gallery_path = os.path.join(app.builder.srcdir, '_templates', 'gallery.html') if os.path.exists(gallery_path): fh = file(gallery_path, 'r') diff -Nru matplotlib-1.1.1/doc/sphinxext/gen_rst.py matplotlib-1.2.0/doc/sphinxext/gen_rst.py --- matplotlib-1.1.1/doc/sphinxext/gen_rst.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/sphinxext/gen_rst.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,7 @@ """ generate the rst files for the examples by iterating over the pylab examples """ +from __future__ import print_function import os, glob import os @@ -152,7 +153,7 @@ fhindex.close() - print + print() def setup(app): app.connect('builder-inited', generate_example_rst) diff -Nru matplotlib-1.1.1/doc/sphinxext/github.py matplotlib-1.2.0/doc/sphinxext/github.py --- matplotlib-1.1.1/doc/sphinxext/github.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/sphinxext/github.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,155 @@ +"""Define text roles for GitHub + +* ghissue - Issue +* ghpull - Pull Request +* ghuser - User + +Adapted from bitbucket example here: +https://bitbucket.org/birkenfeld/sphinx-contrib/src/tip/bitbucket/sphinxcontrib/bitbucket.py + +Authors +------- + +* Doug Hellmann +* Min RK +""" +# +# Original Copyright (c) 2010 Doug Hellmann. All rights reserved. +# + +from docutils import nodes, utils +from docutils.parsers.rst.roles import set_classes + +def make_link_node(rawtext, app, type, slug, options): + """Create a link to a github resource. + + :param rawtext: Text being replaced with link node. + :param app: Sphinx application context + :param type: Link type (issues, changeset, etc.) + :param slug: ID of the thing to link to + :param options: Options dictionary passed to role func. + """ + + try: + base = app.config.github_project_url + if not base: + raise AttributeError + if not base.endswith('/'): + base += '/' + except AttributeError as err: + raise ValueError('github_project_url configuration value is not set (%s)' % str(err)) + + ref = base + type + '/' + slug + '/' + set_classes(options) + prefix = "#" + if type == 'pull': + prefix = "PR " + prefix + node = nodes.reference(rawtext, prefix + utils.unescape(slug), refuri=ref, + **options) + return node + +def ghissue_role(name, rawtext, text, lineno, inliner, options={}, content=[]): + """Link to a GitHub issue. + + Returns 2 part tuple containing list of nodes to insert into the + document and a list of system messages. Both are allowed to be + empty. + + :param name: The role name used in the document. + :param rawtext: The entire markup snippet, with role. + :param text: The text marked with the role. + :param lineno: The line number where rawtext appears in the input. + :param inliner: The inliner instance that called us. + :param options: Directive options for customization. + :param content: The directive content for customization. + """ + + try: + issue_num = int(text) + if issue_num <= 0: + raise ValueError + except ValueError: + msg = inliner.reporter.error( + 'GitHub issue number must be a number greater than or equal to 1; ' + '"%s" is invalid.' % text, line=lineno) + prb = inliner.problematic(rawtext, rawtext, msg) + return [prb], [msg] + app = inliner.document.settings.env.app + #app.info('issue %r' % text) + if 'pull' in name.lower(): + category = 'pull' + elif 'issue' in name.lower(): + category = 'issues' + else: + msg = inliner.reporter.error( + 'GitHub roles include "ghpull" and "ghissue", ' + '"%s" is invalid.' % name, line=lineno) + prb = inliner.problematic(rawtext, rawtext, msg) + return [prb], [msg] + node = make_link_node(rawtext, app, category, str(issue_num), options) + return [node], [] + +def ghuser_role(name, rawtext, text, lineno, inliner, options={}, content=[]): + """Link to a GitHub user. + + Returns 2 part tuple containing list of nodes to insert into the + document and a list of system messages. Both are allowed to be + empty. + + :param name: The role name used in the document. + :param rawtext: The entire markup snippet, with role. + :param text: The text marked with the role. + :param lineno: The line number where rawtext appears in the input. + :param inliner: The inliner instance that called us. + :param options: Directive options for customization. + :param content: The directive content for customization. + """ + app = inliner.document.settings.env.app + #app.info('user link %r' % text) + ref = 'https://www.github.com/' + text + node = nodes.reference(rawtext, text, refuri=ref, **options) + return [node], [] + +def ghcommit_role(name, rawtext, text, lineno, inliner, options={}, content=[]): + """Link to a GitHub commit. + + Returns 2 part tuple containing list of nodes to insert into the + document and a list of system messages. Both are allowed to be + empty. + + :param name: The role name used in the document. + :param rawtext: The entire markup snippet, with role. + :param text: The text marked with the role. + :param lineno: The line number where rawtext appears in the input. + :param inliner: The inliner instance that called us. + :param options: Directive options for customization. + :param content: The directive content for customization. + """ + app = inliner.document.settings.env.app + #app.info('user link %r' % text) + try: + base = app.config.github_project_url + if not base: + raise AttributeError + if not base.endswith('/'): + base += '/' + except AttributeError as err: + raise ValueError('github_project_url configuration value is not set (%s)' % str(err)) + + ref = base + text + node = nodes.reference(rawtext, text[:6], refuri=ref, **options) + return [node], [] + + +def setup(app): + """Install the plugin. + + :param app: Sphinx application context. + """ + app.info('Initializing GitHub plugin') + app.add_role('ghissue', ghissue_role) + app.add_role('ghpull', ghissue_role) + app.add_role('ghuser', ghuser_role) + app.add_role('ghcommit', ghcommit_role) + app.add_config_value('github_project_url', None, 'env') + return diff -Nru matplotlib-1.1.1/doc/sphinxext/math_symbol_table.py matplotlib-1.2.0/doc/sphinxext/math_symbol_table.py --- matplotlib-1.1.1/doc/sphinxext/math_symbol_table.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/sphinxext/math_symbol_table.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function symbols = [ ["Lower-case Greek", 5, @@ -141,7 +142,7 @@ # Do some verification of the tables from matplotlib import _mathtext_data - print "SYMBOLS NOT IN STIX:" + print("SYMBOLS NOT IN STIX:") all_symbols = {} for category, columns, syms in symbols: if category == "Standard Function Names": @@ -151,9 +152,9 @@ if len(sym) > 1: all_symbols[sym[1:]] = None if sym[1:] not in _mathtext_data.tex2uni: - print sym + print(sym) - print "SYMBOLS NOT IN TABLE:" + print("SYMBOLS NOT IN TABLE:") for sym in _mathtext_data.tex2uni: if sym not in all_symbols: - print sym + print(sym) diff -Nru matplotlib-1.1.1/doc/users/credits.rst matplotlib-1.2.0/doc/users/credits.rst --- matplotlib-1.1.1/doc/users/credits.rst 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/users/credits.rst 2012-10-31 00:11:13.000000000 +0000 @@ -6,19 +6,22 @@ matplotlib was written by John Hunter and is now developed and -maintained by a number of -`active `_ -developers. - -Special thanks to those who have made valuable contributions -(roughly in order of first contribution by date) +maintained by a number of `active +`_ developers. +The current lead developer of matplotlib is Michael Droettboom. + +Special thanks to those who have made valuable contributions (roughly +in order of first contribution by date). Any list like this is bound +to be incomplete and can't capture the thousands and thousands of +contributions over the years from these and others: Jeremy O'Donoghue wrote the wx backend -Andrew Straw provided much of the log scaling architecture, the fill - command, PIL support for imshow, and provided many examples. He - also wrote the support for dropped axis spines and the `buildbot +Andrew Straw + Provided much of the log scaling architecture, the fill command, PIL + support for imshow, and provided many examples. He also wrote the + support for dropped axis spines and the `buildbot `_ unit testing infrastructure which triggers the JPL/James Evans platform specific builds and regression test image comparisons from svn matplotlib across @@ -177,7 +180,39 @@ matplotlib, and Jonathon Taylor and Reinier Heeres ported it to the refactored transform trunk. -Jae-Joon Lee implemented fancy arrows and boxes, rewrote the legend +Jae-Joon Lee + Implemented fancy arrows and boxes, rewrote the legend support to handle multiple columns and fancy text boxes, wrote the axes grid toolkit, and has made numerous contributions to the code and documentation + +Paul Ivanov + Has worked on getting matplotlib integrated better with other tools, + such as Sage and IPython, and getting the test infrastructure + faster, lighter and meaner. Listen to his podcast. + +Tony Yu + Has been involved in matplotlib since the early days, and recently + has contributed stream plotting among many other improvements. He + is the author of mpltools. + +Michiel de Hoon + Wrote and maintains the macosx backend. + +Ian Thomas + Contributed, among other things, the triangulation (tricolor and + tripcontour) methods. + +Benjamin Root + Has significantly improved the capabilities of the 3D plotting. He + has improved matplotlib's documentation and code quality throughout, + and does invaluable triaging of pull requests and bugs. + +Phil Elson + Fixed some deep-seated bugs in the transforms framework, and has + been laser-focused on improving polish throughout matplotlib, + tackling things that have been considered to large and daunting for + a long time. + +Damon McDougall + Added triangulated 3D surfaces and stack plots to matplotlib. diff -Nru matplotlib-1.1.1/doc/users/github_stats.rst matplotlib-1.2.0/doc/users/github_stats.rst --- matplotlib-1.1.1/doc/users/github_stats.rst 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/users/github_stats.rst 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,442 @@ +.. _github-stats: + +Github stats +============ + +GitHub stats for 2012/06/30 - 2012/09/07 (tag: v1.1.1) + +These lists are automatically generated, and may be incomplete or contain duplicates. + +The following 71 authors contributed 1151 commits. + +* Aaron Boushley +* Ahmet Bakan +* Amy +* Andrew Dawson +* Arnaud Gardelein +* Ben Gamari +* Ben Root +* Bradley M. Froehle +* Brett Graham +* Bussonnier Matthias +* C\. Gohlke +* Christoph Dann +* Christoph Gohlke +* Corey Farwell +* Craig M +* Craig Tenney +* Damon McDougall +* Daniel Hyams +* Darren Dale +* David Huard +* Eric Firing +* Ezra Peisach +* Gellule Xg +* Graham Poulter +* Hubert Holin +* Ian Thomas +* Ignas Anikevicius (gns_ank) +* Jack (aka Daniel) Kelly +* Jack Kelly +* Jae-Joon Lee +* James R. Evans +* Jason Grout +* Jens H. Nielsen +* Joe Kington +* John Hunter +* Jonathan Waltman +* Jouni K. Seppänen +* Lance Hepler +* Marc Abramowitz +* Martin Spacek +* Matthew Emmett +* Matthias BUSSONNIER +* Michael Droettboom +* Michiel de Hoon +* Mike Kaufman +* Neil +* Nelle Varoquaux +* Nikolay Vyahhi +* Paul Ivanov +* Peter Würtz +* Phil Elson +* Piti Ongmongkolkul +* Robert Johansson +* Russell Owen +* Ryan May +* Simon Cross +* Stefan van der Walt +* Takafumi Arakaki +* Thomas A Caswell +* Thomas Kluyver +* Thomas Robitaille +* Tobias Hoppe +* Tony S Yu +* Zach Pincus +* bev-a-tron +* endolith +* goir +* mcelrath +* pelson +* pwuertz +* vbr + + +We closed a total of 349 issues, 123 pull requests and 226 regular issues; +this is the full list (generated with the script +:file:`tools/github_stats.py`): + +Pull Requests (123): + +* :ghpull:`1168`: PEP8 compliance on artist.py +* :ghpull:`1213`: Include username in tempdir +* :ghpull:`1182`: Bezier pep8 +* :ghpull:`1206`: README and links fixes +* :ghpull:`1192`: Issue835 2: replacement for #835 +* :ghpull:`1187`: Add a *simple* arrow example +* :ghpull:`1120`: FAIL: matplotlib.tests.test_transforms.test_pre_transform_plotting.test on Python 3.x +* :ghpull:`714`: Initial rework of gen_gallery.py +* :ghpull:`1150`: the affine matrix is calculated in the display coordinate for interpolation='none' +* :ghpull:`1145`: Fix formatter reset when twin{x,y}() is called +* :ghpull:`1201`: Fix typo in object-oriented API +* :ghpull:`1061`: Add log option to Axes.hist2d +* :ghpull:`1125`: Reduce object-oriented boilerplate for users +* :ghpull:`1195`: Fixed pickle tests to use the BufferIO object for python3 support. +* :ghpull:`1198`: Fixed python2.6 support (by removing use of viewvalues on a dict). +* :ghpull:`1197`: Handled future division changes for python3 (fixes #1194). +* :ghpull:`1162`: FIX nose.tools.assert_is is only supported with python2.7 +* :ghpull:`803`: Return arrow collection as 2nd argument of streamplot. +* :ghpull:`1189`: BUG: Fix streamplot when velocity component is exactly zero. +* :ghpull:`1191`: Small bugfixes to the new pickle support. +* :ghpull:`1146`: Fix invalid transformation in InvertedSymmetricalLogTransform. +* :ghpull:`1169`: Subplot.twin[xy] returns a Subplot instance +* :ghpull:`1183`: FIX undefined elements were used at several places in the mlab module +* :ghpull:`498`: get_sample_data still broken on v.1.1.x +* :ghpull:`1170`: Uses tight_layout.get_subplotspec_list to check if all axes are compatible w/ tight_layout +* :ghpull:`1174`: closes #1173 - backporting python2.7 subprocess's check_output to be abl... +* :ghpull:`1175`: Pickling support added. Various whitespace fixes as a result of reading *lots* of code. +* :ghpull:`1098`: suppress exception upon quitting with qt4agg on osx +* :ghpull:`1171`: backend_pgf: handle OSError when testing for xelatex/pdflatex +* :ghpull:`1164`: doc: note contourf hatching in whats_new.rst +* :ghpull:`1153`: PEP8 on artist +* :ghpull:`1163`: tight_layout: fix regression for figures with non SubplotBase Axes +* :ghpull:`1159`: FIX assert_raises cannot be called with ``with`` +* :ghpull:`1160`: backend_pgf: clarifications and fixes in documentation +* :ghpull:`1154`: six inclusion for dateutil on py3 doesn't work +* :ghpull:`1149`: Add Phil Elson's percentage histogram example +* :ghpull:`1158`: FIX - typo in lib/matplotlib/testing/compare.py +* :ghpull:`1155`: workaround for fixed dpi assumption in adjust_bbox_pdf +* :ghpull:`1142`: What's New: Python 3 paragraph +* :ghpull:`1130`: Fix writing pdf on stdout +* :ghpull:`832`: MPLCONFIGDIR tries to be created in read-only home +* :ghpull:`1140`: BUG: Fix fill_between when NaN values are present +* :ghpull:`1144`: Added tripcolor whats_new section. +* :ghpull:`1010`: Port part of errorfill from Tony Yu's mpltools. +* :ghpull:`1141`: backend_pgf: fix parentheses typo +* :ghpull:`1114`: Make grid accept alpha rcParam +* :ghpull:`1124`: PGF backend, fix #1116, #1118 and #1128 +* :ghpull:`983`: Issues with dateutil and pytz +* :ghpull:`1133`: figure.py: import warnings, and make imports absolute +* :ghpull:`1132`: clean out obsolete matplotlibrc-related bits to close #1123 +* :ghpull:`1131`: Cleanup after the gca test. +* :ghpull:`563`: sankey.add() has mutable defaults +* :ghpull:`731`: Plot limit with transform +* :ghpull:`1107`: Added %s support for labels. +* :ghpull:`774`: Allow automatic use of tight_layout. +* :ghpull:`1122`: DOC: Add streamplot description to What's New page +* :ghpull:`1111`: Fixed transoffset example from failing. +* :ghpull:`840`: Documentation Errors for specgram +* :ghpull:`1088`: For a text artist, if it has a _bbox_patch associated with it, the contains test should reflect this. +* :ghpull:`986`: Add texinfo build target in doc/make.py +* :ghpull:`1076`: PGF backend for XeLaTeX/LuaLaTeX support +* :ghpull:`1090`: External transform api +* :ghpull:`1108`: Fix documentation warnings +* :ghpull:`861`: Add rcfile function (which loads rc params from a given file). +* :ghpull:`1062`: increased the padding on FileMovieWritter.frame_format_str +* :ghpull:`1100`: Doc multi version master +* :ghpull:`1105`: Fixed comma between tests. +* :ghpull:`1095`: Colormap byteorder bug +* :ghpull:`1103`: colorbar: correct error introduced in commit 089024; closes #1102 +* :ghpull:`1067`: Support multi-version documentation on the website +* :ghpull:`1031`: Added 'capthick' kwarg to errorbar() +* :ghpull:`1074`: Added broadcasting support in some mplot3d methods +* :ghpull:`1064`: Locator interface +* :ghpull:`850`: Added tripcolor triangle-centred colour values. +* :ghpull:`1093`: Exposed the callback id for the default key press handler so that it can be easily diabled. Fixes #215. +* :ghpull:`1065`: fixed conversion from pt to inch in tight_layout +* :ghpull:`1082`: doc: in pcolormesh docstring, say what it does. +* :ghpull:`1078`: doc: note that IDLE doesn't work with interactive mode. +* :ghpull:`1071`: patches.polygon: fix bug in handling of path closing, #1018. +* :ghpull:`1057`: Contour norm scaling +* :ghpull:`1056`: Test framework cleanups +* :ghpull:`778`: Make tests faster +* :ghpull:`1024`: broken links in the gallery +* :ghpull:`1054`: stix_fonts_demo.py fails with bad refcount +* :ghpull:`960`: Fixed logformatting for non integer bases. +* :ghpull:`897`: GUI icon in Tkinter +* :ghpull:`1053`: Move Python 3 import of reload() to the module that uses it +* :ghpull:`1049`: Update examples/user_interfaces/embedding_in_wx2.py +* :ghpull:`1050`: Update examples/user_interfaces/embedding_in_wx4.py +* :ghpull:`1051`: Update examples/user_interfaces/mathtext_wx.py +* :ghpull:`1052`: Update examples/user_interfaces/wxcursor_demo.py +* :ghpull:`1047`: Enable building on Python 3.3 for Windows +* :ghpull:`1036`: Move all figures to the front with a non-interactive show() in macosx backend. +* :ghpull:`1042`: Three more plot_directive configuration options +* :ghpull:`1022`: contour: map extended ranges to "under" and "over" values +* :ghpull:`1007`: modifying GTK3 example to use pygobject, and adding a simple example to demonstrate NavigationToolbar in GTK3 +* :ghpull:`1004`: Added savefig.bbox option to matplotlibrc +* :ghpull:`976`: Fix embedding_in_qt4_wtoolbar.py on Python 3 +* :ghpull:`1034`: MdH = allow compilation on recent Mac OS X without compiler warnings +* :ghpull:`1028`: Fix use() so that it is possible to reset the rcParam. +* :ghpull:`1033`: Py3k: reload->imp.reload +* :ghpull:`1002`: Fixed potential overflow exception in the lines.contains() method +* :ghpull:`1025`: Timers +* :ghpull:`989`: Animation subprocess bug +* :ghpull:`898`: Added warnings for easily confusible subplot/subplots invokations +* :ghpull:`963`: Add detection of file extension for file-like objects +* :ghpull:`973`: Fix sankey.py pep8 and py3 compatibility +* :ghpull:`972`: Force closing PIL image files +* :ghpull:`981`: Fix pathpatch3d_demo.py on Python 3 +* :ghpull:`980`: Fix basic_units.py on Python 3. PEP8 and PyLint cleanup. +* :ghpull:`1014`: qt4: remove duplicate file save button; and remove trailing whitespace +* :ghpull:`1011`: fix for bug #996 and related issues +* :ghpull:`985`: support current and future FreeBSD releases +* :ghpull:`1000`: Fix traceback for vlines/hlines, when an empty list or array passed in for x/y. +* :ghpull:`994`: Fix bug in pcolorfast introduced by #901 +* :ghpull:`993`: Fix typo +* :ghpull:`908`: use Qt window title as default savefig filename +* :ghpull:`971`: Close fd temp file following rec2csv_bad_shape test +* :ghpull:`851`: Simple GUI interface enhancements +* :ghpull:`979`: Fix test_mouseclicks.py on Python 3 +* :ghpull:`977`: Fix lasso_selector_demo.py on Python 3 +* :ghpull:`970`: Fix tiff and jpeg export via PIL +* :ghpull:`961`: Issue 807 auto minor locator + +Issues (226): + +* :ghissue:`1096`: Documentation bug: pyplot.arrow does not list enough keywords to successfully draw an arrow +* :ghissue:`1168`: PEP8 compliance on artist.py +* :ghissue:`1213`: Include username in tempdir +* :ghissue:`1182`: Bezier pep8 +* :ghissue:`1177`: Handled baseline image folder identification for non matplotlib projects. +* :ghissue:`1091`: Update README.txt for v1.2 +* :ghissue:`1206`: README and links fixes +* :ghissue:`1192`: Issue835 2: replacement for #835 +* :ghissue:`1187`: Add a *simple* arrow example +* :ghissue:`1120`: FAIL: matplotlib.tests.test_transforms.test_pre_transform_plotting.test on Python 3.x +* :ghissue:`835`: add documentation for figure show method in backend_bases and backend_template +* :ghissue:`714`: Initial rework of gen_gallery.py +* :ghissue:`1150`: the affine matrix is calculated in the display coordinate for interpolation='none' +* :ghissue:`1087`: Update whats new section +* :ghissue:`385`: BUG: plot_directive: look for plot script files relative to the .rst file +* :ghissue:`1110`: twiny overrides formatter and adds another x-axis +* :ghissue:`1145`: Fix formatter reset when twin{x,y}() is called +* :ghissue:`547`: undocumented scatter marker definition change +* :ghissue:`1201`: Fix typo in object-oriented API +* :ghissue:`1061`: Add log option to Axes.hist2d +* :ghissue:`1094`: Feature request - make it simpler to use full OO interface +* :ghissue:`1125`: Reduce object-oriented boilerplate for users +* :ghissue:`1085`: Images shifted relative to other plot feature in vector graphic output formats +* :ghissue:`1195`: Fixed pickle tests to use the BufferIO object for python3 support. +* :ghissue:`1198`: Fixed python2.6 support (by removing use of viewvalues on a dict). +* :ghissue:`1194`: Streamplot result python version dependent +* :ghissue:`1197`: Handled future division changes for python3 (fixes #1194). +* :ghissue:`557`: Crash during date axis setup +* :ghissue:`600`: errorbar(): kwarg 'markevery' not working as expected. +* :ghissue:`174`: Memory leak in example simple_idle_wx.py +* :ghissue:`232`: format in plot_direcitive sphinx>=1.0.6 compatible patch +* :ghissue:`1162`: FIX nose.tools.assert_is is only supported with python2.7 +* :ghissue:`1165`: tight_layout fails on twinx, twiny +* :ghissue:`803`: Return arrow collection as 2nd argument of streamplot. +* :ghissue:`1189`: BUG: Fix streamplot when velocity component is exactly zero. +* :ghissue:`1191`: Small bugfixes to the new pickle support. +* :ghissue:`323`: native format for figures +* :ghissue:`1146`: Fix invalid transformation in InvertedSymmetricalLogTransform. +* :ghissue:`1169`: Subplot.twin[xy] returns a Subplot instance +* :ghissue:`1183`: FIX undefined elements were used at several places in the mlab module +* :ghissue:`498`: get_sample_data still broken on v.1.1.x +* :ghissue:`1170`: Uses tight_layout.get_subplotspec_list to check if all axes are compatible w/ tight_layout +* :ghissue:`1173`: The PGF backend only works on python2.7 and + +* :ghissue:`1174`: closes #1173 - backporting python2.7 subprocess's check_output to be abl... +* :ghissue:`1175`: Pickling support added. Various whitespace fixes as a result of reading *lots* of code. +* :ghissue:`1179`: Attempt at making travis output shorter. +* :ghissue:`1020`: Picklable figures +* :ghissue:`1098`: suppress exception upon quitting with qt4agg on osx +* :ghissue:`1171`: backend_pgf: handle OSError when testing for xelatex/pdflatex +* :ghissue:`1164`: doc: note contourf hatching in whats_new.rst +* :ghissue:`606`: Unable to configure grid using axisartist +* :ghissue:`1153`: PEP8 on artist +* :ghissue:`1163`: tight_layout: fix regression for figures with non SubplotBase Axes +* :ghissue:`1117`: ERROR: matplotlib.tests.test_axes.test_contour_colorbar.test fails on Python 3 +* :ghissue:`1159`: FIX assert_raises cannot be called with ``with`` +* :ghissue:`206`: hist normed=True problem? +* :ghissue:`1160`: backend_pgf: clarifications and fixes in documentation +* :ghissue:`1154`: six inclusion for dateutil on py3 doesn't work +* :ghissue:`320`: hist plot in percent +* :ghissue:`1149`: Add Phil Elson's percentage histogram example +* :ghissue:`1158`: FIX - typo in lib/matplotlib/testing/compare.py +* :ghissue:`1135`: Problems with bbox_inches='tight' +* :ghissue:`1155`: workaround for fixed dpi assumption in adjust_bbox_pdf +* :ghissue:`1142`: What's New: Python 3 paragraph +* :ghissue:`1138`: tight_bbox made assumptions about the display-units without checking the figure +* :ghissue:`1130`: Fix writing pdf on stdout +* :ghissue:`832`: MPLCONFIGDIR tries to be created in read-only home +* :ghissue:`1140`: BUG: Fix fill_between when NaN values are present +* :ghissue:`1144`: Added tripcolor whats_new section. +* :ghissue:`1010`: Port part of errorfill from Tony Yu's mpltools. +* :ghissue:`1141`: backend_pgf: fix parentheses typo +* :ghissue:`1114`: Make grid accept alpha rcParam +* :ghissue:`1118`: ERROR: matplotlib.tests.test_backend_pgf.test_pdflatex on Python 3.x +* :ghissue:`1116`: ERROR: matplotlib.tests.test_backend_pgf.test_xelatex +* :ghissue:`1124`: PGF backend, fix #1116, #1118 and #1128 +* :ghissue:`745`: Cannot run tests with Python 3.x on MacOS 10.7 +* :ghissue:`983`: Issues with dateutil and pytz +* :ghissue:`1137`: PGF/Tikz: savefig could not handle a filename +* :ghissue:`1128`: PGF back-end fails on simple graph +* :ghissue:`1133`: figure.py: import warnings, and make imports absolute +* :ghissue:`1123`: Rationalize the number of ancillary (default matplotlibrc) files +* :ghissue:`1132`: clean out obsolete matplotlibrc-related bits to close #1123 +* :ghissue:`1131`: Cleanup after the gca test. +* :ghissue:`563`: sankey.add() has mutable defaults +* :ghissue:`238`: patch for qt4 backend +* :ghissue:`731`: Plot limit with transform +* :ghissue:`1107`: Added %s support for labels. +* :ghissue:`720`: Bug with bbox_inches='tight' +* :ghissue:`1084`: doc/mpl_examples/pylab_examples/transoffset.py not working as expected +* :ghissue:`774`: Allow automatic use of tight_layout. +* :ghissue:`1122`: DOC: Add streamplot description to What's New page +* :ghissue:`1111`: Fixed transoffset example from failing. +* :ghissue:`840`: Documentation Errors for specgram +* :ghissue:`1088`: For a text artist, if it has a _bbox_patch associated with it, the contains test should reflect this. +* :ghissue:`1119`: ERROR: matplotlib.tests.test_image.test_imread_pil_uint16 on Python 3.x +* :ghissue:`353`: Improved output of text in SVG and PDF +* :ghissue:`291`: size information from print_figure +* :ghissue:`986`: Add texinfo build target in doc/make.py +* :ghissue:`1076`: PGF backend for XeLaTeX/LuaLaTeX support +* :ghissue:`1090`: External transform api +* :ghissue:`1108`: Fix documentation warnings +* :ghissue:`811`: Allow tripcolor to directly plot triangle-centered functions +* :ghissue:`1005`: imshow with big-endian data types on OS X +* :ghissue:`892`: Update animation.py docstrings to "raw" Sphinx format +* :ghissue:`861`: Add rcfile function (which loads rc params from a given file). +* :ghissue:`988`: Trim white spaces while saving from Navigation toolbar +* :ghissue:`670`: Add a printer button to the navigation toolbar +* :ghissue:`1062`: increased the padding on FileMovieWritter.frame_format_str +* :ghissue:`188`: MacOSX backend brings up GUI unnecessarily +* :ghissue:`1041`: make.osx SDK location needs updating +* :ghissue:`1043`: Fix show command for Qt backend to raise window to top +* :ghissue:`1046`: test failing on master +* :ghissue:`962`: Bug with figure.savefig(): using AGG, PIL, JPG and StringIO +* :ghissue:`1045`: 1.1.1 not in pypi +* :ghissue:`1100`: Doc multi version master +* :ghissue:`1106`: Published docs for v1.1.1 missing pyplot.polar +* :ghissue:`569`: 3D bar graphs with variable depth +* :ghissue:`359`: new plot style: stackplot +* :ghissue:`297`: pip/easy_install installs old version of matplotlib +* :ghissue:`152`: Scatter3D: arguments (c,s,...) are not taken into account +* :ghissue:`1105`: Fixed comma between tests. +* :ghissue:`1095`: Colormap byteorder bug +* :ghissue:`1102`: examples/pylab_examples/contour_demo.py fails +* :ghissue:`1103`: colorbar: correct error introduced in commit 089024; closes #1102 +* :ghissue:`1067`: Support multi-version documentation on the website +* :ghissue:`1031`: Added 'capthick' kwarg to errorbar() +* :ghissue:`1074`: Added broadcasting support in some mplot3d methods +* :ghissue:`1032`: Axesbase +* :ghissue:`1064`: Locator interface +* :ghissue:`850`: Added tripcolor triangle-centred colour values. +* :ghissue:`1059`: Matplotlib figure window freezes during interactive mode +* :ghissue:`215`: skipping mpl-axes-interaction during key_press_event\'s +* :ghissue:`1093`: Exposed the callback id for the default key press handler so that it can be easily diabled. Fixes #215. +* :ghissue:`909`: Log Formatter for tick labels can't handle non-integer base +* :ghissue:`1065`: fixed conversion from pt to inch in tight_layout +* :ghissue:`1086`: Problem with subplot / matplotlib.dates interaction +* :ghissue:`782`: mplot3d: grid doesn't update after adding a slider to figure? +* :ghissue:`703`: pcolormesh help not helpful +* :ghissue:`1082`: doc: in pcolormesh docstring, say what it does. +* :ghissue:`1068`: Add stairstep plotting functionality +* :ghissue:`1078`: doc: note that IDLE doesn't work with interactive mode. +* :ghissue:`704`: ignore case in `edgecolors` keyword in `pcolormesh` (and possibly other places) +* :ghissue:`708`: set_clim not working with NonUniformImage +* :ghissue:`768`: Add "tight_layout" button to toolbar +* :ghissue:`791`: v1.1.1 release candidate testing +* :ghissue:`844`: imsave/imshow and cmaps +* :ghissue:`939`: test failure: matplotlib.tests.test_mathtext.mathfont_stix_14_test.test +* :ghissue:`875`: Replace "jet" with "hot" as the default colormap +* :ghissue:`881`: "Qualitative" colormaps represented as continuous +* :ghissue:`1072`: For a text artist, if it has a _bbox_patch associated with it, the conta... +* :ghissue:`1071`: patches.polygon: fix bug in handling of path closing, #1018. +* :ghissue:`1018`: BUG: check for closed path in Polygon.set_xy() +* :ghissue:`1066`: fix limit calculation of step* histogram +* :ghissue:`1073`: Mplot3d/input broadcast +* :ghissue:`906`: User-specified medians and conf. intervals in boxplots +* :ghissue:`899`: Update for building matplotlib under Mac OS X 10.7 Lion and XCode > 4.2 +* :ghissue:`1057`: Contour norm scaling +* :ghissue:`1035`: Added a GTK3 implementation of the SubplotTool window. +* :ghissue:`807`: Crash when using zoom tools on a plot: AutoMinorLocator after MultipleLocator gives "ValueError: Need at least two major ticks to find minor tick locations" +* :ghissue:`1023`: New button to toolbar for tight_layout. +* :ghissue:`1056`: Test framework cleanups +* :ghissue:`778`: Make tests faster +* :ghissue:`1048`: some matplotlib examples incompatible with wxpython 2.9 +* :ghissue:`1024`: broken links in the gallery +* :ghissue:`1054`: stix_fonts_demo.py fails with bad refcount +* :ghissue:`960`: Fixed logformatting for non integer bases. +* :ghissue:`897`: GUI icon in Tkinter +* :ghissue:`1053`: Move Python 3 import of reload() to the module that uses it +* :ghissue:`1049`: Update examples/user_interfaces/embedding_in_wx2.py +* :ghissue:`1050`: Update examples/user_interfaces/embedding_in_wx4.py +* :ghissue:`1051`: Update examples/user_interfaces/mathtext_wx.py +* :ghissue:`1052`: Update examples/user_interfaces/wxcursor_demo.py +* :ghissue:`1047`: Enable building on Python 3.3 for Windows +* :ghissue:`819`: Add new plot style: stackplot +* :ghissue:`1036`: Move all figures to the front with a non-interactive show() in macosx backend. +* :ghissue:`1042`: Three more plot_directive configuration options +* :ghissue:`1044`: plots not being displayed in OSX 10.8 +* :ghissue:`1022`: contour: map extended ranges to "under" and "over" values +* :ghissue:`1007`: modifying GTK3 example to use pygobject, and adding a simple example to demonstrate NavigationToolbar in GTK3 +* :ghissue:`1004`: Added savefig.bbox option to matplotlibrc +* :ghissue:`976`: Fix embedding_in_qt4_wtoolbar.py on Python 3 +* :ghissue:`1013`: compilation warnings in _macosx.m +* :ghissue:`1034`: MdH = allow compilation on recent Mac OS X without compiler warnings +* :ghissue:`964`: Animation clear_temp=False reuses old frames +* :ghissue:`1028`: Fix use() so that it is possible to reset the rcParam. +* :ghissue:`1033`: Py3k: reload->imp.reload +* :ghissue:`1002`: Fixed potential overflow exception in the lines.contains() method +* :ghissue:`1025`: Timers +* :ghissue:`989`: Animation subprocess bug +* :ghissue:`898`: Added warnings for easily confusible subplot/subplots invokations +* :ghissue:`963`: Add detection of file extension for file-like objects +* :ghissue:`973`: Fix sankey.py pep8 and py3 compatibility +* :ghissue:`972`: Force closing PIL image files +* :ghissue:`981`: Fix pathpatch3d_demo.py on Python 3 +* :ghissue:`980`: Fix basic_units.py on Python 3. PEP8 and PyLint cleanup. +* :ghissue:`996`: macosx backend broken by #901: QuadMesh fails so colorbar fails +* :ghissue:`1017`: axes.Axes.step() function not documented +* :ghissue:`1014`: qt4: remove duplicate file save button; and remove trailing whitespace +* :ghissue:`655`: implement path_effects for Line2D objects +* :ghissue:`999`: pcolormesh edgecolor of "None" +* :ghissue:`1011`: fix for bug #996 and related issues +* :ghissue:`1009`: Simplify import statement +* :ghissue:`982`: Supported FreeBSD10 as per #225 +* :ghissue:`225`: Add support for FreeBSD >6.x +* :ghissue:`985`: support current and future FreeBSD releases +* :ghissue:`1006`: MacOSX backend throws exception when plotting a quadmesh +* :ghissue:`1000`: Fix traceback for vlines/hlines, when an empty list or array passed in for x/y. +* :ghissue:`1001`: Bug fix for issue #955 +* :ghissue:`994`: Fix bug in pcolorfast introduced by #901 +* :ghissue:`993`: Fix typo +* :ghissue:`908`: use Qt window title as default savefig filename +* :ghissue:`830`: standard key for closing figure ("q") +* :ghissue:`971`: Close fd temp file following rec2csv_bad_shape test +* :ghissue:`851`: Simple GUI interface enhancements +* :ghissue:`979`: Fix test_mouseclicks.py on Python 3 +* :ghissue:`977`: Fix lasso_selector_demo.py on Python 3 +* :ghissue:`970`: Fix tiff and jpeg export via PIL +* :ghissue:`707`: key_press_event in pyqt4 embedded matplotlib +* :ghissue:`243`: Debug version/symbols for win32 +* :ghissue:`255`: Classes in _transforms.h in global namespace +* :ghissue:`961`: Issue 807 auto minor locator +* :ghissue:`345`: string symbol markers ("scattertext" plot) +* :ghissue:`247`: DLL load failed +* :ghissue:`808`: pip install matplotlib fails +* :ghissue:`168`: setupext.py incorrect for Mac OS X +* :ghissue:`213`: Fixing library path in setupext.py for Mac diff -Nru matplotlib-1.1.1/doc/users/gridspec.rst matplotlib-1.2.0/doc/users/gridspec.rst --- matplotlib-1.1.1/doc/users/gridspec.rst 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/users/gridspec.rst 2012-10-31 00:11:13.000000000 +0000 @@ -134,7 +134,7 @@ Here's a more sophisticated example of nested gridspec where we put a box around each cell of the outer 4x4 grid, by hiding appropriate -spines in each of the inner 3x3 grids. :: +spines in each of the inner 3x3 grids. .. plot:: users/plotting/examples/demo_gridspec06.py diff -Nru matplotlib-1.1.1/doc/users/image_tutorial.rst matplotlib-1.2.0/doc/users/image_tutorial.rst --- matplotlib-1.1.1/doc/users/image_tutorial.rst 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/users/image_tutorial.rst 2012-10-31 00:11:13.000000000 +0000 @@ -181,7 +181,7 @@ .. sourcecode:: ipython - In [7]: imgplot = mpimg.imshow(lum_img) + In [7]: imgplot = plt.imshow(lum_img) .. plot:: @@ -226,7 +226,9 @@ imgplot = plt.imshow(lum_img) imgplot.set_cmap('spectral') -There are many other colormap schemes available. See the `list and images of the colormaps `_. +There are many other colormap schemes available. See the `list and +images of the colormaps +`_. .. _`Color Bars`: @@ -291,7 +293,7 @@ .. sourcecode:: ipython - In[11]: imgplot.set_clim=(0.0,0.7) + In[11]: imgplot.set_clim(0.0,0.7) .. plot:: @@ -335,7 +337,7 @@ In [9]: img = Image.open('stinkbug.png') # Open image as PIL image object In [10]: rsize = img.resize((img.size[0]/10,img.size[1]/10)) # Use PIL to resize In [11]: rsizeArr = np.asarray(rsize) # Get array back - In [12]: imgplot = mpimg.imshow(rsizeArr) + In [12]: imgplot = plt.imshow(rsizeArr) .. plot:: diff -Nru matplotlib-1.1.1/doc/users/index.rst matplotlib-1.2.0/doc/users/index.rst --- matplotlib-1.1.1/doc/users/index.rst 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/users/index.rst 2012-10-31 00:11:13.000000000 +0000 @@ -31,6 +31,7 @@ recipes.rst screenshots.rst whats_new.rst + github_stats.rst license.rst credits.rst diff -Nru matplotlib-1.1.1/doc/users/index_text.rst matplotlib-1.2.0/doc/users/index_text.rst --- matplotlib-1.1.1/doc/users/index_text.rst 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/users/index_text.rst 2012-10-31 00:11:13.000000000 +0000 @@ -8,6 +8,7 @@ text_intro.rst text_props.rst mathtext.rst + pgf.rst usetex.rst annotations_intro.rst diff -Nru matplotlib-1.1.1/doc/users/legend_guide.rst matplotlib-1.2.0/doc/users/legend_guide.rst --- matplotlib-1.1.1/doc/users/legend_guide.rst 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/users/legend_guide.rst 2012-10-31 00:11:13.000000000 +0000 @@ -123,7 +123,7 @@ By specifying the keyword argument *ncol*, you can have a multi-column legend. Also, mode="expand" horizontally expand the legend to fill the axes area. See `legend_demo3.py -`_ +`_ for example. diff -Nru matplotlib-1.1.1/doc/users/navigation_toolbar.rst matplotlib-1.2.0/doc/users/navigation_toolbar.rst --- matplotlib-1.1.1/doc/users/navigation_toolbar.rst 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/users/navigation_toolbar.rst 2012-10-31 00:11:13.000000000 +0000 @@ -76,28 +76,31 @@ ``svg`` and ``pdf``. +.. _key-event-handling: + Navigation Keyboard Shortcuts ----------------------------- The following table holds all the default keys, which can be overwritten by use of your matplotlibrc (#keymap.\*). -================================== ============================================== +================================== ================================================= Command Keyboard Shortcut(s) -================================== ============================================== +================================== ================================================= Home/Reset **h** or **r** or **home** Back **c** or **left arrow** or **backspace** Forward **v** or **right arrow** Pan/Zoom **p** Zoom-to-rect **o** -Save **s** -Toggle fullscreen **f** -Constrain pan/zoom to x axis hold **x** -Constrain pan/zoom to y axis hold **y** -Preserve aspect ratio hold **CONTROL** -Toggle grid **g** -Toggle x axis scale (log/linear) **L** or **k** -Toggle y axis scale (log/linear) **l** -================================== ============================================== +Save **ctrl** + **s** +Toggle fullscreen **ctrl** + **f** +Close plot **ctrl** + **w** +Constrain pan/zoom to x axis hold **x** when panning/zooming with mouse +Constrain pan/zoom to y axis hold **y** when panning/zooming with mouse +Preserve aspect ratio hold **CONTROL** when panning/zooming with mouse +Toggle grid **g** when mouse is over an axes +Toggle x axis scale (log/linear) **L** or **k** when mouse is over an axes +Toggle y axis scale (log/linear) **l** when mouse is over an axes +================================== ================================================= If you are using :mod:`matplotlib.pyplot` the toolbar will be created automatically for every figure. If you are writing your own user diff -Nru matplotlib-1.1.1/doc/users/pgf.rst matplotlib-1.2.0/doc/users/pgf.rst --- matplotlib-1.1.1/doc/users/pgf.rst 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/users/pgf.rst 2012-11-08 13:38:09.000000000 +0000 @@ -0,0 +1,158 @@ +.. _pgf-tutorial: + +********************************* +Typesetting With XeLaTeX/LuaLaTeX +********************************* + +Using the ``pgf`` backend, matplotlib can export figures as pgf drawing commands +that can be processed with pdflatex, xelatex or lualatex. XeLaTeX and LuaLaTeX +have full unicode support and can use any font that is installed in the operating +system, making use of advanced typographic features of OpenType, AAT and +Graphite. Pgf pictures created by ``plt.savefig('figure.pgf')`` can be +embedded as raw commands in LaTeX documents. Figures can also be directly +compiled and saved to PDF with ``plt.savefig('figure.pdf')`` by either +switching to the backend + +.. code-block:: python + + matplotlib.use('pgf') + +or registering it for handling pdf output + +.. code-block:: python + + from matplotlib.backends.backend_pgf import FigureCanvasPgf + matplotlib.backend_bases.register_backend('pdf', FigureCanvasPgf) + +The second method allows you to keep using regular interactive backends and to +save xelatex, lualatex or pdflatex compiled PDF files from the graphical user interface. + +Matplotlib's pgf support requires a recent LaTeX_ installation that includes +the TikZ/PGF packages (such as TeXLive_), preferably with XeLaTeX or LuaLaTeX +installed. If either pdftocairo or ghostscript is present on your system, +figures can optionally be saved to PNG images as well. The executables +for all applications must be located on your :envvar:`PATH`. + +Rc parameters that control the behavior of the pgf backend: + + ================= ===================================================== + Parameter Documentation + ================= ===================================================== + pgf.preamble Lines to be included in the LaTeX preamble + pgf.rcfonts Setup fonts from rc params using the fontspec package + pgf.texsystem Either "xelatex", "lualatex" or "pdflatex" + ================= ===================================================== + +.. note:: + + TeX defines a set of secial characters, such as:: + + # $ % & ~ _ ^ \ { } + + Generally, these characters must be escaped correctly. For convenience, + some characters (_,^,%) are automatically escaped outside of math + environments. + +.. _pgf-rcfonts: + +Font specification +================== + +The fonts used for obtaining the size of text elements or when compiling +figures to PDF are usually defined in the matplotlib rc parameters. You can +also use the LaTeX default Computer Modern fonts by clearing the lists for +``font.serif``, ``font.sans-serif`` or ``font.monospace``. Please note that +the glyph coverage of these fonts is very limited. If you want to keep the +Computer Modern font face but require extended unicode support, consider +installing the `Computer Modern Unicode `_ +fonts *CMU Serif*, *CMU Sans Serif*, etc. + +When saving to ``.pgf``, the font configuration matplotlib used for the +layout of the figure is included in the header of the text file. + +.. literalinclude:: plotting/examples/pgf_fonts.py + :end-before: plt.savefig + +.. image:: /_static/pgf_fonts.* + + +.. _pgf-preamble: + +Custom preamble +=============== + +Full customization is possible by adding your own commands to the preamble. +Use the ``pgf.preamble`` parameter if you want to configure the math fonts or +for loading additional packages. Also, if you want to do the font configuration +yourself instead of using the fonts specified in the rc parameters, make sure +to disable ``pgf.rcfonts``. + +.. htmlonly:: + + .. literalinclude:: plotting/examples/pgf_preamble.py + :end-before: plt.savefig + +.. latexonly:: + + .. literalinclude:: plotting/examples/pgf_preamble.py + :end-before: import matplotlib.pyplot as plt + +.. image:: /_static/pgf_preamble.* + + +.. _pgf-texsystem: + +Choosing the TeX system +======================= + +The TeX system to be used by matplotlib is chosen by the ``pgf.texsystem`` +parameter. Possible values are ``'xelatex'`` (default), ``'lualatex'`` and +``'pdflatex'``. Please note that when selecting pdflatex the fonts and +unicode handling must be configured in the preamble. + +.. literalinclude:: plotting/examples/pgf_texsystem.py + :end-before: plt.savefig + +.. image:: /_static/pgf_texsystem.* + + +.. _pgf-troubleshooting: + +Troubleshooting +=============== + +* Please note that the TeX packages found in some Linux distributions and + MiKTeX installations are dramatically outdated. Make sure to update your + package catalog and upgrade or install a recent TeX distribution. + +* On Windows, the :envvar:`PATH` environment variable may need to be modified + to include the directories containing the latex, dvipng and ghostscript + executables. See :ref:`environment-variables` and + :ref:`setting-windows-environment-variables` for details. + +* A limitation on Windows causes the backend to keep file handles that have + been opened by your application open. As a result, it may not be possible + to delete the corresponding files until the application closes (see + `#1324 `_). + +* Sometimes the font rendering in figures that are saved to png images is + very bad. This happens when the pdftocairo tool is not available and + ghostscript is used for the pdf to png conversion. + +* Make sure what you are trying to do is possible in a LaTeX document, + that your LaTeX syntax is valid and that you are using raw strings + if necessary to avoid unintended escape sequences. + +* The ``pgf.preamble`` rc setting provides lots of flexibility, and lots of + ways to cause problems. When experiencing problems, try to minimalize or + disable the custom preamble. + +* If the font configuration used by matplotlib differs from the font setting + in yout LaTeX document, the alignment of text elements in imported figures + may be off. Check the header of your ``.pgf`` file if you are unsure about + the fonts matplotlib used for the layout. + +* If you still need help, please see :ref:`reporting-problems` + +.. _LaTeX: http://www.tug.org +.. _TeXLive: http://www.tug.org/texlive/ diff -Nru matplotlib-1.1.1/doc/users/plotting/examples/demo_gridspec06.py matplotlib-1.2.0/doc/users/plotting/examples/demo_gridspec06.py --- matplotlib-1.1.1/doc/users/plotting/examples/demo_gridspec06.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/users/plotting/examples/demo_gridspec06.py 2012-10-31 00:11:13.000000000 +0000 @@ -18,7 +18,7 @@ def squiggle_xy(a, b, c, d, i=np.arange(0.0, 2*np.pi, 0.05)): return np.sin(i*a)*np.cos(i*b), np.sin(i*c)*np.cos(i*d) -f = plt.figure(figsize=(8, 8)) +fig = plt.figure(figsize=(8, 8)) # gridspec inside gridspec outer_grid = gridspec.GridSpec(4, 4, wspace=0.0, hspace=0.0) @@ -28,13 +28,13 @@ subplot_spec=outer_grid[i], wspace=0.0, hspace=0.0) a, b = int(i/4)+1,i%4+1 for j, (c, d) in enumerate(product(range(1, 4), repeat=2)): - ax = plt.Subplot(f, inner_grid[j]) + ax = plt.Subplot(fig, inner_grid[j]) ax.plot(*squiggle_xy(a, b, c, d)) ax.set_xticks([]) ax.set_yticks([]) - f.add_subplot(ax) + fig.add_subplot(ax) -all_axes = f.get_axes() +all_axes = fig.get_axes() #show only the outside spines for ax in all_axes: diff -Nru matplotlib-1.1.1/doc/users/plotting/examples/pgf_fonts.py matplotlib-1.2.0/doc/users/plotting/examples/pgf_fonts.py --- matplotlib-1.1.1/doc/users/plotting/examples/pgf_fonts.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/users/plotting/examples/pgf_fonts.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +import matplotlib as mpl +mpl.use("pgf") +pgf_with_rc_fonts = { + "font.family": "serif", + "font.serif": [], # use latex default serif font + "font.sans-serif": ["DejaVu Sans"], # use a specific sans-serif font +} +mpl.rcParams.update(pgf_with_rc_fonts) + +import matplotlib.pyplot as plt +plt.figure(figsize=(4.5,2.5)) +plt.plot(range(5)) +plt.text(0.5, 3., "serif") +plt.text(0.5, 2., "monospace", family="monospace") +plt.text(2.5, 2., "sans-serif", family="sans-serif") +plt.text(2.5, 1., "comic sans", family="Comic Sans MS") +plt.xlabel(u"µ is not $\\mu$") +plt.tight_layout(.5) + +plt.savefig("pgf_fonts.pdf") +plt.savefig("pgf_fonts.png") diff -Nru matplotlib-1.1.1/doc/users/plotting/examples/pgf_preamble.py matplotlib-1.2.0/doc/users/plotting/examples/pgf_preamble.py --- matplotlib-1.1.1/doc/users/plotting/examples/pgf_preamble.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/users/plotting/examples/pgf_preamble.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- + +import matplotlib as mpl +mpl.use("pgf") +pgf_with_custom_preamble = { + "font.family": "serif", # use serif/main font for text elements + "text.usetex": True, # use inline math for ticks + "pgf.rcfonts": False, # don't setup fonts from rc parameters + "pgf.preamble": [ + r"\usepackage{units}", # load additional packages + r"\usepackage{metalogo}", # load additional packages + r"\usepackage{unicode-math}", # unicode math setup + r"\setmathfont{XITS Math}", + r"\setmainfont{DejaVu Serif}", # font setup via preamble + ] +} +mpl.rcParams.update(pgf_with_custom_preamble) + +import matplotlib.pyplot as plt +plt.figure(figsize=(4.5,2.5)) +plt.plot(range(5)) +plt.xlabel(u"unicode text: я, ψ, €, ü, \\unitfrac[10]{°}{µm}") +plt.ylabel(u"\\XeLaTeX") +plt.legend([u"unicode math: $λ=∑_i^∞ μ_i^2$"]) +plt.tight_layout(.5) + +plt.savefig("pgf_preamble.pdf") +plt.savefig("pgf_preamble.png") diff -Nru matplotlib-1.1.1/doc/users/plotting/examples/pgf_texsystem.py matplotlib-1.2.0/doc/users/plotting/examples/pgf_texsystem.py --- matplotlib-1.1.1/doc/users/plotting/examples/pgf_texsystem.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/doc/users/plotting/examples/pgf_texsystem.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +import matplotlib as mpl +mpl.use("pgf") +pgf_with_pdflatex = { + "pgf.texsystem": "pdflatex", + "pgf.preamble": [ + r"\usepackage[utf8x]{inputenc}", + r"\usepackage[T1]{fontenc}", + r"\usepackage{cmbright}", + ] +} +mpl.rcParams.update(pgf_with_pdflatex) + +import matplotlib.pyplot as plt +plt.figure(figsize=(4.5,2.5)) +plt.plot(range(5)) +plt.text(0.5, 3., "serif", family="serif") +plt.text(0.5, 2., "monospace", family="monospace") +plt.text(2.5, 2., "sans-serif", family="sans-serif") +plt.xlabel(u"µ is not $\\mu$") +plt.tight_layout(.5) + +plt.savefig("pgf_texsystem.pdf") +plt.savefig("pgf_texsystem.png") diff -Nru matplotlib-1.1.1/doc/users/pyplot_tutorial.rst matplotlib-1.2.0/doc/users/pyplot_tutorial.rst --- matplotlib-1.1.1/doc/users/pyplot_tutorial.rst 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/users/pyplot_tutorial.rst 2012-10-31 00:11:13.000000000 +0000 @@ -16,13 +16,13 @@ .. plot:: pyplots/pyplot_simple.py :include-source: -You may be wondering why the x-axis ranges from 0-2 and the y-axis -from 1-3. If you provide a single list or array to the +You may be wondering why the x-axis ranges from 0-3 and the y-axis +from 1-4. If you provide a single list or array to the :func:`~matplotlib.pyplot.plot` command, matplotlib assumes it is a sequence of y values, and automatically generates the x values for you. Since python ranges start with 0, the default x vector has the same length as y but starts with 0. Hence the x data are -``[0,1,2]``. +``[0,1,2,3]``. :func:`~matplotlib.pyplot.plot` is a versatile command, and will take an arbitrary number of arguments. For example, to plot x versus y, diff -Nru matplotlib-1.1.1/doc/users/shell.rst matplotlib-1.2.0/doc/users/shell.rst --- matplotlib-1.1.1/doc/users/shell.rst 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/doc/users/shell.rst 2012-10-31 00:11:13.000000000 +0000 @@ -66,15 +66,15 @@ ========================= If you can't use ipython, and still want to use matplotlib/pylab from -an interactive python shell, eg the plain-ole standard python -interactive interpreter, or the interpreter in your favorite IDE, you +an interactive python shell, e.g. the plain-ole standard python +interactive interpreter, you are going to need to understand what a matplotlib backend is :ref:`what-is-a-backend`. -With the TkAgg backend, that uses the Tkinter user interface toolkit, -you can use matplotlib from an arbitrary python shell. Just set your +With the TkAgg backend, which uses the Tkinter user interface toolkit, +you can use matplotlib from an arbitrary non-gui python shell. Just set your ``backend : TkAgg`` and ``interactive : True`` in your :file:`matplotlibrc` file (see :ref:`customizing-matplotlib`) and fire up python. Then:: @@ -83,18 +83,22 @@ >>> plot([1,2,3]) >>> xlabel('hi mom') -should work out of the box. Note, in batch mode, ie when making +should work out of the box. This is also likely to work with recent +versions of the qt4agg and gtkagg backends, and with the macosx backend +on the Macintosh. Note, in batch mode, +i.e. when making figures from scripts, interactive mode can be slow since it redraws the figure with each command. So you may want to think carefully -before making this the default behavior. +before making this the default behavior via the :file:`matplotlibrc` +file instead of using the functions listed in the next section. -For other user interface toolkits and their corresponding matplotlib -backends, the situation is complicated by the GUI mainloop which takes -over the entire process. The solution is to run the GUI in a separate -thread, and this is the tricky part that ipython solves for all the -major toolkits that matplotlib supports. There are reports that -upcoming versions of pygtk will place nicely with the standard python -shell, so stay tuned. +Gui shells are at best problematic, because they have to run a +mainloop, but interactive plotting also involves a mainloop. Ipython +has sorted all this out for the primary matplotlib backends. There +may be other shells and IDEs that also work with matplotlib in interactive +mode, but one obvious candidate does not: +the python IDLE IDE is a Tkinter gui app that does +not support pylab interactive mode, regardless of backend. .. _controlling-interactive: diff -Nru matplotlib-1.1.1/doc/users/tight_layout_guide.rst matplotlib-1.2.0/doc/users/tight_layout_guide.rst --- matplotlib-1.1.1/doc/users/tight_layout_guide.rst 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/users/tight_layout_guide.rst 2012-10-31 00:11:13.000000000 +0000 @@ -13,9 +13,9 @@ Simple Example ============== -In matplotlib location of axes (including subplots) are specified in -normalized figure coordinate. It can happen that your axis labels or -titles (or sometimes even ticklabels) go outside the figure area thus +In matplotlib, the location of axes (including subplots) are specified in +normalized figure coordinates. It can happen that your axis labels or +titles (or sometimes even ticklabels) go outside the figure area, and are thus clipped. .. plot:: @@ -35,7 +35,7 @@ fig, ax = plt.subplots() example_plot(ax, fontsize=24) -To prevent this, the location of axes need to be adjusted. For +To prevent this, the location of axes needs to be adjusted. For subplots, this can be done by adjusting the subplot params (:ref:`howto-subplots-adjust`). Matplotlib v1.1 introduces a new command :func:`~matplotlib.pyplot.tight_layout` that does this @@ -48,7 +48,7 @@ plt.tight_layout() When you have multiple subplots, often you see labels of different -axes overlaps each other. +axes overlapping each other. .. plot:: :include-source: @@ -62,8 +62,8 @@ example_plot(ax4) -*tight_layout* will also adjust spacing betweens subplots to minimize -the overlaps. +:func:`~matplotlib.pyplot.tight_layout` will also adjust spacing between +subplots to minimize the overlaps. .. plot:: :include-source: @@ -72,7 +72,7 @@ plt.tight_layout() :func:`~matplotlib.pyplot.tight_layout` can take keyword arguments of -*pad*, *w_pad* and *h_pad*. These controls the extra pad around the +*pad*, *w_pad* and *h_pad*. These control the extra padding around the figure border and between subplots. The pads are specified in fraction of fontsize. @@ -83,9 +83,9 @@ plt.tight_layout(pad=0.4, w_pad=0.5, h_pad=1.0) :func:`~matplotlib.pyplot.tight_layout` will work even if the sizes of -subplot are different as far as their grid specification is -compatible. In the example below, *ax1* and *ax2* are subplots of 2x2 -grid, while *ax3* is of 1x2 grid. +subplots are different as far as their grid specification is +compatible. In the example below, *ax1* and *ax2* are subplots of a 2x2 +grid, while *ax3* is of a 1x2 grid. .. plot:: @@ -152,11 +152,13 @@ Caveats ------- - * *tight_layout* only considers ticklabels, axis labels, and titles. Thus, other atists may be clipped and also may overlap. + * :func:`~matplotlib.pyplot.tight_layout` only considers ticklabels, axis + labels, and titles. Thus, other artists may be clipped and also may + overlap. * It assumes that the extra space needed for ticklabels, axis labels, and titles is independent of original location of axes. This is - often True, but there are rare cases it is not. + often true, but there are rare cases where it is not. * pad=0 clips some of the texts by a few pixels. This may be a bug or a limitation of the current algorithm and it is not clear why it @@ -169,7 +171,7 @@ Use with GridSpec ----------------- -GridSpec has its own tight_layout method +GridSpec has its own :func:`~matplotlib.gridspec.GridSpec.tight_layout` method (the pyplot api :func:`~matplotlib.pyplot.tight_layout` also works). .. plot:: @@ -191,9 +193,9 @@ gs1.tight_layout(fig) -You may provide an optional *rect* parameter, which specify the bbox -that the subplots will be fit in. The coordinate must be in normalized -figure coordinate and the default is (0, 0, 1, 1). +You may provide an optional *rect* parameter, which specifies the bounding box +that the subplots will be fit inside. The coordinates must be in normalized +figure coordinates and the default is (0, 0, 1, 1). .. plot:: :include-source: @@ -202,7 +204,7 @@ gs1.tight_layout(fig, rect=[0, 0, 0.5, 1]) -For example, this can be used for a figure with multiple grid_spec's. +For example, this can be used for a figure with multiple gridspecs. .. plot:: :include-source: @@ -230,13 +232,13 @@ gs2.update(top=top, bottom=bottom) -While this should be mostly good enough, but adjusting top and bottom -may requires adjustment in hspace also. To update hspace & vspace, we -call tight_layout again with updated rect argument. Note the rect -argument specifies area including the ticklabels etc. Thus we will -increase the bottom (which is 0 in normal case) by the difference -between the *bottom* from above and bottom of each gridspec. Same -thing for top. +While this should be mostly good enough, adjusting top and bottom +may require adjustment of hspace also. To update hspace & vspace, we +call :func:`~matplotlib.gridspec.GridSpec.tight_layout` again with updated +rect argument. Note that the rect argument specifies the area including the +ticklabels, etc. Thus, we will increase the bottom (which is 0 for the normal +case) by the difference between the *bottom* from above and the bottom of each +gridspec. Same thing for the top. .. plot:: :include-source: @@ -256,7 +258,7 @@ Use with AxesGrid1 ------------------ -While limited, axes_grid1 toolkit is also supported. +While limited, the axes_grid1 toolkit is also supported. .. plot:: @@ -282,8 +284,8 @@ Colorbar -------- -If you create colorbar with :func:`~matplotlib.pyplot.colorbar` -command, the created colorbar is an instance of Axes not Subplot, thus +If you create a colorbar with the :func:`~matplotlib.pyplot.colorbar` +command, the created colorbar is an instance of Axes, *not* Subplot, so tight_layout does not work. With Matplotlib v1.1, you may create a colobar as a subplot using the gridspec. diff -Nru matplotlib-1.1.1/doc/users/whats_new.rst matplotlib-1.2.0/doc/users/whats_new.rst --- matplotlib-1.1.1/doc/users/whats_new.rst 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/users/whats_new.rst 2012-11-08 13:38:09.000000000 +0000 @@ -5,13 +5,212 @@ ************************ This page just covers the highlights -- for the full story, see the -`CHANGELOG `_ +`CHANGELOG `_ + +For a list of all of the issues and pull requests since the last +revision, see the :ref:`github-stats`. .. note:: Matplotlib version 1.1 is the last major release compatible with Python - versions 2.4 to 2.7. The next major release will support + versions 2.4 to 2.7. matplotlib 1.2 and later require versions 2.6, 2.7, and 3.1 and higher. +.. _whats-new-1-2: + +new in matplotlib-1.2 +===================== + +Python 3.x support +------------------ + +Matplotlib 1.2 is the first version to support Python 3.x, +specifically Python 3.1 and 3.2. To make this happen in a reasonable +way, we also had to drop support for Python versions earlier than 2.6. + +This work was done by Michael Droettboom, the Cape Town Python Users' +Group, many others and supported financially in part by the SAGE +project. + +The following GUI backends work under Python 3.x: Gtk3Cairo, Qt4Agg, +TkAgg and MacOSX. The other GUI backends do not yet have adequate +bindings for Python 3.x, but continue to work on Python 2.6 and 2.7, +particularly the Qt and QtAgg backends (which have been +deprecated). The non-GUI backends, such as PDF, PS and SVG, work on +both Python 2.x and 3.x. + +Features that depend on the Python Imaging Library, such as JPEG +handling, do not work, since the version of PIL for Python 3.x is not +sufficiently mature. + +PGF/TikZ backend +---------------- +Peter Würtz wrote a backend that allows matplotlib to export figures as +drawing commands for LaTeX. These can be processed by PdfLaTeX, XeLaTeX or +LuaLaTeX using the PGF/TikZ package. Usage examples and documentation are +found in :ref:`pgf-tutorial`. + +.. image:: /_static/pgf_preamble.* + +Locator interface +----------------- + +Philip Elson exposed the intelligence behind the tick Locator classes with a +simple interface. For instance, to get no more than 5 sensible steps which +span the values 10 and 19.5:: + + >>> import matplotlib.ticker as mticker + >>> locator = mticker.MaxNLocator(nbins=5) + >>> print(locator.tick_values(10, 19.5)) + [ 10. 12. 14. 16. 18. 20.] + +Tri-Surface Plots +----------------- + +Damon McDougall added a new plotting method for the +:mod:`~mpl_toolkits.mplot3d` toolkit called +:meth:`~mpl_toolkits.mplot3d.axes3d.Axes3D.plot_trisurf`. + +.. plot:: mpl_examples/mplot3d/trisurf3d_demo.py + +Control the lengths of colorbar extensions +------------------------------------------ + +Andrew Dawson added a new keyword argument *extendfrac* to +:meth:`~matplotlib.pyplot.colorbar` to control the length of +minimum and maximum colorbar extensions. + +.. plot:: + + import matplotlib.pyplot as plt + import numpy as np + + x = y = np.linspace(0., 2*np.pi, 100) + X, Y = np.meshgrid(x, y) + Z = np.cos(X) * np.sin(0.5*Y) + + clevs = [-.75, -.5, -.25, 0., .25, .5, .75] + cmap = plt.cm.get_cmap(name='jet', lut=8) + + ax1 = plt.subplot(211) + cs1 = plt.contourf(x, y, Z, clevs, cmap=cmap, extend='both') + cb1 = plt.colorbar(orientation='horizontal', extendfrac=None) + cb1.set_label('Default length colorbar extensions') + + ax2 = plt.subplot(212) + cs2 = plt.contourf(x, y, Z, clevs, cmap=cmap, extend='both') + cb2 = plt.colorbar(orientation='horizontal', extendfrac='auto') + cb2.set_label('Custom length colorbar extensions') + + plt.show() + + +Figures are picklable +--------------------- + +Philip Elson added an experimental feature to make figures picklable +for quick and easy short-term storage of plots. Pickle files +are not designed for long term storage, are unsupported when restoring a pickle +saved in another matplotlib version and are insecure when restoring a pickle +from an untrusted source. Having said this, they are useful for short term +storage for later modification inside matplotlib. + + +Set default bounding box in matplotlibrc +------------------------------------------ + +Two new defaults are available in the matplotlibrc configuration file: +``savefig.bbox``, which can be set to 'standard' or 'tight', and +``savefig.pad_inches``, which controls the bounding box padding. + + +New Boxplot Functionality +------------------------- + +Users can now incorporate their own methods for computing the median and its +confidence intervals into the :meth:`~matplotlib.axes.boxplot` method. For +every column of data passed to boxplot, the user can specify an accompanying +median and confidence interval. + +.. plot:: mpl_examples/pylab_examples/boxplot_demo3.py + + +New RC parameter functionality +------------------------------ + +Matthew Emmett added a function and a context manager to help manage RC +parameters: :func:`~matplotlib.rc_file` and :class:`~matplotlib.rc_context`. +To load RC parameters from a file:: + + >>> mpl.rc_file('mpl.rc') + +To temporarily use RC parameters:: + + >>> with mpl.rc_context(fname='mpl.rc', rc={'text.usetex': True}): + >>> ... + + +Streamplot +---------- + +Tom Flannaghan and Tony Yu have added a new +:meth:`~matplotlib.pyplot.streamplot` function to plot the streamlines of +a vector field. This has been a long-requested feature and complements the +existing :meth:`~matplotlib.pyplot.quiver` function for plotting vector fields. +In addition to simply plotting the streamlines of the vector field, +:meth:`~matplotlib.pyplot.streamplot` allows users to map the colors and/or +line widths of the streamlines to a separate parameter, such as the speed or +local intensity of the vector field. + +.. plot:: mpl_examples/pylab_examples/streamplot_demo.py + + +New hist functionality +---------------------- + +Nic Eggert added a new `stacked` kwarg to :meth:`~matplotlib.pyplot.hist` that +allows creation of stacked histograms using any of the histogram types. +Previously, this functionality was only available by using the `barstacked` +histogram type. Now, when `stacked=True` is passed to the function, any of the +histogram types can be stacked. The `barstacked` histogram type retains its +previous functionality for backwards compatibility. + +Updated shipped dependencies +---------------------------- + +The following dependencies that ship with matplotlib and are +optionally installed alongside it have been updated: + + - `pytz ` 2012d + + - `dateutil ` 1.5 on Python 2.x, + and 2.1 on Python 3.x + + +Face-centred colors in tripcolor plots +-------------------------------------- + +Ian Thomas extended :meth:`~matplotlib.pyplot.tripcolor` to allow one color +value to be specified for each triangular face rather than for each point in +a triangulation. + +.. plot:: mpl_examples/pylab_examples/tripcolor_demo.py + +Hatching patterns in filled contour plots, with legends +------------------------------------------------------- + +Phil Elson added support for hatching to +:func:`~matplotlib.pyplot.contourf`, together with the ability +to use a legend to identify contoured ranges. + +.. plot:: mpl_examples/pylab_examples/contourf_hatching.py + +Known issues in the matplotlib-1.2 release +------------------------------------------ + +- When using the Qt4Agg backend with IPython 0.11 or later, the save + dialog will not display. This should be fixed in a future version + of IPython. + .. _whats-new-1-1: new in matplotlib-1.1 diff -Nru matplotlib-1.1.1/doc/utils/pylab_names.py matplotlib-1.2.0/doc/utils/pylab_names.py --- matplotlib-1.1.1/doc/utils/pylab_names.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/doc/utils/pylab_names.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function """ autogenerate some tables for pylab namespace """ @@ -14,7 +15,7 @@ doc = getattr(o, '__doc__', None) if doc is not None: doc = ' - '.join([line for line in doc.split('\n') if line.strip()][:2]) - + mod = getattr(o, '__module__', None) if mod is None: mod = 'unknown' @@ -25,7 +26,7 @@ k = ':class:`~%s.%s`'%(mod, k) else: k = ':func:`~%s.%s`'%(mod, k) - mod = ':mod:`%s`'%mod + mod = ':mod:`%s`'%mod elif mod.startswith('numpy'): #k = '`%s <%s>`_'%(k, 'http://scipy.org/Numpy_Example_List_With_Doc#%s'%k) k = '`%s <%s>`_'%(k, 'http://sd-2116.dedibox.fr/pydocweb/doc/%s.%s'%(mod, k)) @@ -40,21 +41,21 @@ mods.sort() for mod in mods: border = '*'*len(mod) - print mod - print border + print(mod) + print(border) - print + print() funcs, docs = zip(*modd[mod]) maxfunc = max([len(f) for f in funcs]) maxdoc = max(40, max([len(d) for d in docs]) ) border = ' '.join(['='*maxfunc, '='*maxdoc]) - print border - print ' '.join(['symbol'.ljust(maxfunc), 'description'.ljust(maxdoc)]) - print border + print(border) + print(' '.join(['symbol'.ljust(maxfunc), 'description'.ljust(maxdoc)])) + print(border) for func, doc in modd[mod]: row = ' '.join([func.ljust(maxfunc), doc.ljust(maxfunc)]) - print row + print(row) - print border - print + print(border) + print() #break diff -Nru matplotlib-1.1.1/examples/animation/basic_example.py matplotlib-1.2.0/examples/animation/basic_example.py --- matplotlib-1.1.1/examples/animation/basic_example.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/animation/basic_example.py 2012-10-31 00:11:13.000000000 +0000 @@ -29,6 +29,6 @@ im_ani = animation.ArtistAnimation(fig2, ims, interval=50, repeat_delay=3000, blit=True) -#im_ani.save('im.mp4') +#im_ani.save('im.mp4', metadata={'artist':'Guido'}) plt.show() diff -Nru matplotlib-1.1.1/examples/animation/basic_example_writer.py matplotlib-1.2.0/examples/animation/basic_example_writer.py --- matplotlib-1.1.1/examples/animation/basic_example_writer.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/animation/basic_example_writer.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,42 @@ +# Same as basic_example, but writes files using a single MovieWriter instance +# without putting on screen +# -*- noplot -*- +import numpy as np +import matplotlib +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import matplotlib.animation as animation + +def update_line(num, data, line): + line.set_data(data[...,:num]) + return line, + +# Set up formatting for the movie files +Writer = animation.writers['ffmpeg'] +writer = Writer(fps=15, metadata=dict(artist='Me'), bitrate=1800) + + +fig1 = plt.figure() + +data = np.random.rand(2, 25) +l, = plt.plot([], [], 'r-') +plt.xlim(0, 1) +plt.ylim(0, 1) +plt.xlabel('x') +plt.title('test') +line_ani = animation.FuncAnimation(fig1, update_line, 25, fargs=(data, l), + interval=50, blit=True) +line_ani.save('lines.mp4', writer=writer) + +fig2 = plt.figure() + +x = np.arange(-9, 10) +y = np.arange(-9, 10).reshape(-1, 1) +base = np.hypot(x, y) +ims = [] +for add in np.arange(15): + ims.append((plt.pcolor(x, y, base + add, norm=plt.Normalize(0, 30)),)) + +im_ani = animation.ArtistAnimation(fig2, ims, interval=50, repeat_delay=3000, + blit=True) +im_ani.save('im.mp4', writer=writer) diff -Nru matplotlib-1.1.1/examples/animation/dynamic_image2.py matplotlib-1.2.0/examples/animation/dynamic_image2.py --- matplotlib-1.1.1/examples/animation/dynamic_image2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/animation/dynamic_image2.py 2012-10-31 00:11:13.000000000 +0000 @@ -26,7 +26,7 @@ ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True, repeat_delay=1000) -ani.save('dynamic_images.mp4') +#ani.save('dynamic_images.mp4') plt.show() diff -Nru matplotlib-1.1.1/examples/animation/moviewriter.py matplotlib-1.2.0/examples/animation/moviewriter.py --- matplotlib-1.1.1/examples/animation/moviewriter.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/animation/moviewriter.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,32 @@ +# This example uses a MovieWriter directly to grab individual frames and +# write them to a file. This avoids any event loop integration, but has +# the advantage of working with even the Agg backend. This is not recommended +# for use in an interactive setting. +# -*- noplot -*- + +import numpy as np +import matplotlib +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import matplotlib.animation as manimation + +FFMpegWriter = manimation.writers['ffmpeg'] +metadata = dict(title='Movie Test', artist='Matplotlib', + comment='Movie support!') +writer = FFMpegWriter(fps=15, metadata=metadata) + +fig = plt.figure() +l, = plt.plot([], [], 'k-o') + +plt.xlim(-5, 5) +plt.ylim(-5, 5) + +x0,y0 = 0, 0 + +with writer.saving(fig, "writer_test.mp4", 100): + for i in range(100): + x0 += 0.1 * np.random.randn() + y0 += 0.1 * np.random.randn() + l.set_data(x0, y0) + writer.grab_frame() + diff -Nru matplotlib-1.1.1/examples/animation/old_animation/animate_decay_tk_blit.py matplotlib-1.2.0/examples/animation/old_animation/animate_decay_tk_blit.py --- matplotlib-1.1.1/examples/animation/old_animation/animate_decay_tk_blit.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/animation/old_animation/animate_decay_tk_blit.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import time, sys import numpy as np import matplotlib.pyplot as plt @@ -44,7 +45,7 @@ if run.cnt==1000: # print the timing info and quit - print 'FPS:' , 1000/(time.time()-tstart) + print('FPS:' , 1000/(time.time()-tstart)) sys.exit() run.cnt += 1 diff -Nru matplotlib-1.1.1/examples/animation/old_animation/animation_blit_fltk.py matplotlib-1.2.0/examples/animation/old_animation/animation_blit_fltk.py --- matplotlib-1.1.1/examples/animation/old_animation/animation_blit_fltk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/animation/old_animation/animation_blit_fltk.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import sys import fltk import matplotlib @@ -37,7 +38,7 @@ self.cnt+=1 if self.cnt==1000: # print the timing info and quit - print 'FPS:' , 1000/(time.time()-self.tstart) + print('FPS:' , 1000/(time.time()-self.tstart)) sys.exit() return True diff -Nru matplotlib-1.1.1/examples/animation/old_animation/animation_blit_gtk.py matplotlib-1.2.0/examples/animation/old_animation/animation_blit_gtk.py --- matplotlib-1.1.1/examples/animation/old_animation/animation_blit_gtk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/animation/old_animation/animation_blit_gtk.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import print_function + # For detailed comments on animation and the techniques used here, see # the wiki entry # http://www.scipy.org/wikis/topical_software/MatplotlibAnimation @@ -30,7 +32,7 @@ tstart = time.time() def update_line(*args): - print 'you are here', update_line.cnt + print('you are here', update_line.cnt) if update_line.background is None: update_line.background = canvas.copy_from_bbox(ax.bbox) @@ -46,7 +48,7 @@ if update_line.cnt==1000: # print the timing info and quit - print 'FPS:' , 1000/(time.time()-tstart) + print('FPS:' , 1000/(time.time()-tstart)) gtk.mainquit() raise SystemExit diff -Nru matplotlib-1.1.1/examples/animation/old_animation/animation_blit_gtk2.py matplotlib-1.2.0/examples/animation/old_animation/animation_blit_gtk2.py --- matplotlib-1.1.1/examples/animation/old_animation/animation_blit_gtk2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/animation/old_animation/animation_blit_gtk2.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import print_function + """ This example utlizes restore_region with optional bbox and xy arguments. The plot is continuously shifted to the left. Instead of @@ -137,7 +139,7 @@ dt = (time.time()-tstart) if dt>15: # print the timing info and quit - print 'FPS:' , self.cnt/dt + print('FPS:' , self.cnt/dt) gtk.main_quit() raise SystemExit diff -Nru matplotlib-1.1.1/examples/animation/old_animation/animation_blit_qt.py matplotlib-1.2.0/examples/animation/old_animation/animation_blit_qt.py --- matplotlib-1.1.1/examples/animation/old_animation/animation_blit_qt.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/animation/old_animation/animation_blit_qt.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,8 @@ # For detailed comments on animation and the techniqes used here, see # the wiki entry http://www.scipy.org/Cookbook/Matplotlib/Animations +from __future__ import print_function + import os, sys import matplotlib matplotlib.use('QtAgg') # qt3 example @@ -47,7 +49,7 @@ if self.cnt==ITERS: # print the timing info and quit - print 'FPS:' , ITERS/(time.time()-self.tstart) + print('FPS:', ITERS/(time.time()-self.tstart)) sys.exit() else: diff -Nru matplotlib-1.1.1/examples/animation/old_animation/animation_blit_qt4.py matplotlib-1.2.0/examples/animation/old_animation/animation_blit_qt4.py --- matplotlib-1.1.1/examples/animation/old_animation/animation_blit_qt4.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/animation/old_animation/animation_blit_qt4.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,8 @@ # For detailed comments on animation and the techniqes used here, see # the wiki entry http://www.scipy.org/Cookbook/Matplotlib/Animations +from __future__ import print_function + import os import sys @@ -63,7 +65,7 @@ self.draw() if self.cnt==ITERS: # print the timing info and quit - print 'FPS:' , ITERS/(time.time()-self.tstart) + print('FPS:' , ITERS/(time.time()-self.tstart)) sys.exit() else: self.cnt += 1 diff -Nru matplotlib-1.1.1/examples/animation/old_animation/animation_blit_tk.py matplotlib-1.2.0/examples/animation/old_animation/animation_blit_tk.py --- matplotlib-1.1.1/examples/animation/old_animation/animation_blit_tk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/animation/old_animation/animation_blit_tk.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,8 @@ # For detailed comments on animation and the techniqes used here, see # the wiki entry http://www.scipy.org/Cookbook/Matplotlib/Animations +from __future__ import print_function + import matplotlib matplotlib.use('TkAgg') @@ -34,7 +36,7 @@ if run.cnt==1000: # print the timing info and quit - print 'FPS:' , 1000/(time.time()-tstart) + print('FPS:', 1000/(time.time()-tstart)) sys.exit() run.cnt += 1 diff -Nru matplotlib-1.1.1/examples/animation/old_animation/animation_blit_wx.py matplotlib-1.2.0/examples/animation/old_animation/animation_blit_wx.py --- matplotlib-1.1.1/examples/animation/old_animation/animation_blit_wx.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/animation/old_animation/animation_blit_wx.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,6 +2,8 @@ # the wiki entry # http://www.scipy.org/wikis/topical_software/MatplotlibAnimation +from __future__ import print_function + # The number of blits() to make before exiting NBLITS = 1000 @@ -58,11 +60,11 @@ if update_line.cnt == NBLITS: # print the timing info and quit frame_time = time.time() - tstart - print '%d frames: %.2f seconds' % (NBLITS, frame_time) - print '%d blits: %.2f seconds' % (NBLITS, blit_time) - print - print 'FPS: %.2f' % (NBLITS/frame_time) - print 'BPS: %.2f' % (NBLITS/blit_time) + print('%d frames: %.2f seconds' % (NBLITS, frame_time)) + print('%d blits: %.2f seconds' % (NBLITS, blit_time)) + print() + print('FPS: %.2f' % (NBLITS/frame_time)) + print('BPS: %.2f' % (NBLITS/blit_time)) sys.exit() update_line.cnt += 1 diff -Nru matplotlib-1.1.1/examples/animation/old_animation/dynamic_image_gtkagg.py matplotlib-1.2.0/examples/animation/old_animation/dynamic_image_gtkagg.py --- matplotlib-1.1.1/examples/animation/old_animation/dynamic_image_gtkagg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/animation/old_animation/dynamic_image_gtkagg.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,6 @@ #!/usr/bin/env python + +from __future__ import print_function """ An animated image """ @@ -34,7 +36,7 @@ manager.canvas.draw() cnt += 1 if cnt==50: - print 'FPS', cnt/(time.time() - tstart) + print('FPS', cnt/(time.time() - tstart)) return False return True diff -Nru matplotlib-1.1.1/examples/animation/old_animation/movie_demo.py matplotlib-1.2.0/examples/animation/old_animation/movie_demo.py --- matplotlib-1.1.1/examples/animation/old_animation/movie_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/animation/old_animation/movie_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -15,6 +15,8 @@ # the script to suit your own needs. # +from __future__ import print_function + import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt # For plotting graphs. @@ -28,9 +30,9 @@ # Python interpreter, and matplotlib. The version of # Mencoder is printed when it is called. # -print 'Executing on', os.uname() -print 'Python version', sys.version -print 'matplotlib version', matplotlib.__version__ +print('Executing on', os.uname()) +print('Python version', sys.version) +print('matplotlib version', matplotlib.__version__) not_found_msg = """ The mencoder command was not found; @@ -42,7 +44,7 @@ try: subprocess.check_call(['mencoder']) except subprocess.CalledProcessError: - print "mencoder command was found" + print("mencoder command was found") pass # mencoder is found, but returns non-zero exit as expected # This is a quick and dirty check; it leaves some spurious output # for the user to puzzle over. @@ -61,7 +63,7 @@ # distributed Gaussian noise at each time step. # -print 'Initializing data set...' # Let the user know what's happening. +print('Initializing data set...') # Let the user know what's happening. # Initialize variables needed to create and store the example data set. numberOfTimeSteps = 100 # Number of frames we want in the movie. @@ -78,7 +80,7 @@ mean = mean + meaninc stddev = stddev + stddevinc -print 'Done.' # Let the user know what's happening. +print('Done.') # Let the user know what's happening. # # Now that we have an example data set (x,y) to work with, we can @@ -113,7 +115,7 @@ # # Let the user know what's happening. # - print 'Wrote file', filename + print('Wrote file', filename) # # Clear the figure to make way for the next image. @@ -147,10 +149,10 @@ #os.spawnvp(os.P_WAIT, 'mencoder', command) -print "\n\nabout to execute:\n%s\n\n" % ' '.join(command) +print("\n\nabout to execute:\n%s\n\n" % ' '.join(command)) subprocess.check_call(command) -print "\n\n The movie was written to 'output.avi'" +print("\n\n The movie was written to 'output.avi'") -print "\n\n You may want to delete *.png now.\n\n" +print("\n\n You may want to delete *.png now.\n\n") diff -Nru matplotlib-1.1.1/examples/animation/old_animation/simple_anim_gtk.py matplotlib-1.2.0/examples/animation/old_animation/simple_anim_gtk.py --- matplotlib-1.1.1/examples/animation/old_animation/simple_anim_gtk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/animation/old_animation/simple_anim_gtk.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,7 @@ """ A simple example of an animated plot using a gtk backend """ +from __future__ import print_function import time import numpy as np import matplotlib @@ -20,11 +21,11 @@ for i in np.arange(1,200): line.set_ydata(np.sin(x+i/10.0)) # update the data fig.canvas.draw() # redraw the canvas - print 'FPS:' , 200/(time.time()-tstart) + print('FPS:' , 200/(time.time()-tstart)) raise SystemExit import gobject -print 'adding idle' +print('adding idle') gobject.idle_add(animate) -print 'showing' +print('showing') plt.show() diff -Nru matplotlib-1.1.1/examples/animation/old_animation/simple_anim_tkagg.py matplotlib-1.2.0/examples/animation/old_animation/simple_anim_tkagg.py --- matplotlib-1.1.1/examples/animation/old_animation/simple_anim_tkagg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/animation/old_animation/simple_anim_tkagg.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,9 @@ #!/usr/bin/env python + """ A simple example of an animated plot in tkagg """ +from __future__ import print_function import time import numpy as np import matplotlib @@ -19,7 +21,7 @@ for i in np.arange(1,200): line.set_ydata(np.sin(x+i/10.0)) # update the data fig.canvas.draw() # redraw the canvas - print 'FPS:' , 200/(time.time()-tstart) + print('FPS:' , 200/(time.time()-tstart)) win = fig.canvas.manager.window fig.canvas.manager.window.after(100, animate) diff -Nru matplotlib-1.1.1/examples/animation/old_animation/simple_idle_wx.py matplotlib-1.2.0/examples/animation/old_animation/simple_idle_wx.py --- matplotlib-1.1.1/examples/animation/old_animation/simple_idle_wx.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/animation/old_animation/simple_idle_wx.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,7 @@ """ A simple example of an animated plot using a wx backend """ +from __future__ import print_function import time import numpy as np import matplotlib @@ -18,7 +19,7 @@ def update_line(idleevent): if update_line.i==200: return False - print 'animate', update_line.i + print('animate', update_line.i) line.set_ydata(np.sin(t+update_line.i/10.)) fig.canvas.draw_idle() # redraw the canvas update_line.i += 1 diff -Nru matplotlib-1.1.1/examples/animation/old_animation/simple_timer_wx.py matplotlib-1.2.0/examples/animation/old_animation/simple_timer_wx.py --- matplotlib-1.1.1/examples/animation/old_animation/simple_timer_wx.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/animation/old_animation/simple_timer_wx.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function """ A simple example of an animated plot using a wx backend """ @@ -19,7 +20,7 @@ def update_line(event): if update_line.i==200: return False - print 'update', update_line.i + print('update', update_line.i) line.set_ydata(np.sin(t+update_line.i/10.)) fig.canvas.draw() # redraw the canvas update_line.i += 1 diff -Nru matplotlib-1.1.1/examples/animation/simple_3danim.py matplotlib-1.2.0/examples/animation/simple_3danim.py --- matplotlib-1.1.1/examples/animation/simple_3danim.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/animation/simple_3danim.py 2012-10-31 00:11:13.000000000 +0000 @@ -15,7 +15,7 @@ """ lineData = np.empty((dims, length)) lineData[:, 0] = np.random.rand(dims) - for index in xrange(1, length) : + for index in range(1, length) : # scaling the random numbers by 0.1 so # movement is small compared to position. # subtraction by 0.5 is to change the range to [-0.5, 0.5] @@ -37,7 +37,7 @@ ax = p3.Axes3D(fig) # Fifty lines of random 3-D lines -data = [Gen_RandLine(25, 3) for index in xrange(50)] +data = [Gen_RandLine(25, 3) for index in range(50)] # Creating fifty line objects. # NOTE: Can't pass empty arrays into 3d version of plot() diff -Nru matplotlib-1.1.1/examples/api/README.txt matplotlib-1.2.0/examples/api/README.txt --- matplotlib-1.1.1/examples/api/README.txt 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/examples/api/README.txt 2012-10-31 00:11:13.000000000 +0000 @@ -5,23 +5,15 @@ procedural state machine. For robust, production level scripts, or for applications or web application servers, we recommend you use the matplotlib API directly as it gives you the maximum control over your -figures, axes and plottng commands. There are a few documentation -resources for the API +figures, axes and plottng commands. - - the matplotlib artist tutorial : - http://matplotlib.sourceforge.net/pycon/artist_api_tut.pdf - - - the "leftwich tutorial" : - http://matplotlib.sourceforge.net/leftwich_tut.txt - - The example agg_oo.py is the simplest example of using the Agg - backend which is readily ported to other output formats. This - example is a good starting point if your are a web application - developer. Many of the other examples in this directory use - matplotlib.pyplot just to create the figure and show calls, and use - the API for everything else. This is a good solution for production - quality scripts. For full fledged GUI applications, see the - user_interfaces examples. +The example agg_oo.py is the simplest example of using the Agg backend +which is readily ported to other output formats. This example is a +good starting point if your are a web application developer. Many of +the other examples in this directory use matplotlib.pyplot just to +create the figure and show calls, and use the API for everything else. +This is a good solution for production quality scripts. For full +fledged GUI applications, see the user_interfaces examples. Example style guide =================== diff -Nru matplotlib-1.1.1/examples/api/artist_demo.py matplotlib-1.2.0/examples/api/artist_demo.py --- matplotlib-1.1.1/examples/api/artist_demo.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/examples/api/artist_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,17 +1,17 @@ """ Show examples of matplotlib artists -http://matplotlib.sourceforge.net/api/artist_api.html +http://matplotlib.org/api/artist_api.html Several examples of standard matplotlib graphics primitives (artists) are drawn using matplotlib API. Full list of artists and the documentation is available at -http://matplotlib.sourceforge.net/api/artist_api.html +http://matplotlib.org/api/artist_api.html Copyright (c) 2010, Bartosz Telenczuk License: This work is licensed under the BSD. A copy should be included with this source code, and is also available at -http://www.opensource.org/licenses/bsd-license.php +http://www.opensource.org/licenses/bsd-license.php """ @@ -69,7 +69,7 @@ plt.text(pos[0,5], pos[1,5]-0.15, "Arrow", ha="center", family=font, size=14) -# add a path patch +# add a path patch Path = mpath.Path verts = np.array([ (0.158, -0.257), @@ -83,7 +83,7 @@ (0.158, -0.257), ]) verts = verts-verts.mean(0) -codes = [Path.MOVETO, +codes = [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, Path.LINETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, Path.CLOSEPOLY] @@ -95,7 +95,7 @@ # add a fancy box fancybox = mpatches.FancyBboxPatch( - pos[:,7]-np.array([0.025, 0.05]), 0.05, 0.1, + pos[:,7]-np.array([0.025, 0.05]), 0.05, 0.1, boxstyle=mpatches.BoxStyle("Round", pad=0.02)) patches.append(fancybox) plt.text(pos[0,7], pos[1,7]-0.15, "FancyBoxPatch", ha="center", diff -Nru matplotlib-1.1.1/examples/api/bbox_intersect.py matplotlib-1.2.0/examples/api/bbox_intersect.py --- matplotlib-1.1.1/examples/api/bbox_intersect.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/api/bbox_intersect.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,21 +1,19 @@ -from pylab import * import numpy as np +import matplotlib.pyplot as plt from matplotlib.transforms import Bbox from matplotlib.path import Path -from matplotlib.patches import Rectangle -rect = Rectangle((-1, -1), 2, 2, facecolor="#aaaaaa") -gca().add_patch(rect) +rect = plt.Rectangle((-1, -1), 2, 2, facecolor="#aaaaaa") +plt.gca().add_patch(rect) bbox = Bbox.from_bounds(-1, -1, 2, 2) for i in range(12): - vertices = (np.random.random((4, 2)) - 0.5) * 6.0 - vertices = np.ma.masked_array(vertices, [[False, False], [True, True], [False, False], [False, False]]) + vertices = (np.random.random((2, 2)) - 0.5) * 6.0 path = Path(vertices) if path.intersects_bbox(bbox): color = 'r' else: color = 'b' - plot(vertices[:,0], vertices[:,1], color=color) + plt.plot(vertices[:,0], vertices[:,1], color=color) -show() +plt.show() diff -Nru matplotlib-1.1.1/examples/api/clippath_demo.py matplotlib-1.2.0/examples/api/clippath_demo.py --- matplotlib-1.1.1/examples/api/clippath_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/api/clippath_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,7 +3,6 @@ """ import numpy as np import matplotlib.pyplot as plt -import matplotlib.path as path import matplotlib.patches as patches diff -Nru matplotlib-1.1.1/examples/api/collections_demo.py matplotlib-1.2.0/examples/api/collections_demo.py --- matplotlib-1.1.1/examples/api/collections_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/api/collections_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -17,31 +17,31 @@ ''' -import matplotlib.pyplot as P -from matplotlib import collections, axes, transforms +import matplotlib.pyplot as plt +from matplotlib import collections, transforms from matplotlib.colors import colorConverter -import numpy as N +import numpy as np nverts = 50 npts = 100 # Make some spirals -r = N.array(range(nverts)) -theta = N.array(range(nverts)) * (2*N.pi)/(nverts-1) -xx = r * N.sin(theta) -yy = r * N.cos(theta) -spiral = zip(xx,yy) +r = np.array(range(nverts)) +theta = np.array(range(nverts)) * (2*np.pi)/(nverts-1) +xx = r * np.sin(theta) +yy = r * np.cos(theta) +spiral = list(zip(xx,yy)) # Make some offsets -rs = N.random.RandomState([12345678]) +rs = np.random.RandomState([12345678]) xo = rs.randn(npts) yo = rs.randn(npts) -xyo = zip(xo, yo) +xyo = list(zip(xo, yo)) # Make a list of colors cycling through the rgbcmyk series. colors = [colorConverter.to_rgba(c) for c in ('r','g','b','c','y','m','k')] -fig = P.figure() +fig = plt.figure() a = fig.add_subplot(2,2,1) col = collections.LineCollection([spiral], offsets=xyo, @@ -88,7 +88,7 @@ a = fig.add_subplot(2,2,3) col = collections.RegularPolyCollection(7, - sizes = N.fabs(xx)*10.0, offsets=xyo, + sizes = np.fabs(xx)*10.0, offsets=xyo, transOffset=a.transData) trans = transforms.Affine2D().scale(fig.dpi/72.0) col.set_transform(trans) # the points to pixels transform @@ -108,13 +108,13 @@ ncurves = 20 offs = (0.1, 0.0) -yy = N.linspace(0, 2*N.pi, nverts) -ym = N.amax(yy) -xx = (0.2 + (ym-yy)/ym)**2 * N.cos(yy-0.4) * 0.5 +yy = np.linspace(0, 2*np.pi, nverts) +ym = np.amax(yy) +xx = (0.2 + (ym-yy)/ym)**2 * np.cos(yy-0.4) * 0.5 segs = [] for i in range(ncurves): xxx = xx + 0.02*rs.randn(nverts) - curve = zip(xxx, yy*100) + curve = list(zip(xxx, yy*100)) segs.append(curve) col = collections.LineCollection(segs, offsets=offs) @@ -128,6 +128,6 @@ a.set_ylim(a.get_ylim()[::-1]) -P.show() +plt.show() diff -Nru matplotlib-1.1.1/examples/api/colorbar_only.py matplotlib-1.2.0/examples/api/colorbar_only.py --- matplotlib-1.1.1/examples/api/colorbar_only.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/api/colorbar_only.py 2012-10-31 00:11:13.000000000 +0000 @@ -6,8 +6,9 @@ # Make a figure and axes with dimensions as desired. fig = pyplot.figure(figsize=(8,3)) -ax1 = fig.add_axes([0.05, 0.65, 0.9, 0.15]) -ax2 = fig.add_axes([0.05, 0.25, 0.9, 0.15]) +ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15]) +ax2 = fig.add_axes([0.05, 0.475, 0.9, 0.15]) +ax3 = fig.add_axes([0.05, 0.15, 0.9, 0.15]) # Set the colormap and norm to correspond to the data for which # the colorbar will be used. @@ -47,5 +48,27 @@ orientation='horizontal') cb2.set_label('Discrete intervals, some other units') +# The third example illustrates the use of custom length colorbar +# extensions, used on a colorbar with discrete intervals. +cmap = mpl.colors.ListedColormap([[0., .4, 1.], [0., .8, 1.], + [1., .8, 0.], [1., .4, 0.]]) +cmap.set_over((1., 0., 0.)) +cmap.set_under((0., 0., 1.)) + +bounds = [-1., -.5, 0., .5, 1.] +norm = mpl.colors.BoundaryNorm(bounds, cmap.N) +cb3 = mpl.colorbar.ColorbarBase(ax3, cmap=cmap, + norm=norm, + boundaries=[-10]+bounds+[10], + extend='both', + # Make the length of each extension + # the same as the length of the + # interior colors: + extendfrac='auto', + ticks=bounds, + spacing='uniform', + orientation='horizontal') +cb3.set_label('Custom extension lengths, some other units') + pyplot.show() diff -Nru matplotlib-1.1.1/examples/api/custom_projection_example.py matplotlib-1.2.0/examples/api/custom_projection_example.py --- matplotlib-1.1.1/examples/api/custom_projection_example.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/api/custom_projection_example.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,10 @@ +from __future__ import unicode_literals + from matplotlib.axes import Axes -from matplotlib import cbook from matplotlib.patches import Circle from matplotlib.path import Path -from matplotlib.ticker import Formatter, Locator, NullLocator, FixedLocator, NullFormatter -from matplotlib.transforms import Affine2D, Affine2DBase, Bbox, \ - BboxTransformTo, IdentityTransform, Transform, TransformWrapper +from matplotlib.ticker import NullLocator, Formatter, FixedLocator +from matplotlib.transforms import Affine2D, BboxTransformTo, Transform from matplotlib.projections import register_projection import matplotlib.spines as mspines import matplotlib.axis as maxis @@ -280,7 +280,7 @@ else: ew = 'W' # \u00b0 : degree symbol - return u'%f\u00b0%s, %f\u00b0%s' % (abs(lat), ns, abs(long), ew) + return '%f\u00b0%s, %f\u00b0%s' % (abs(lat), ns, abs(long), ew) class DegreeFormatter(Formatter): """ @@ -294,7 +294,7 @@ degrees = (x / np.pi) * 180.0 degrees = round(degrees / self._round_to) * self._round_to # \u00b0 : degree symbol - return u"%d\u00b0" % degrees + return "%d\u00b0" % degrees def set_longitude_grid(self, degrees): """ @@ -308,7 +308,7 @@ # by degrees. number = (360.0 / degrees) + 1 self.xaxis.set_major_locator( - FixedLocator( + plt.FixedLocator( np.linspace(-np.pi, np.pi, number, True)[1:-1])) # Set the formatter to display the tick labels in degrees, # rather than radians. @@ -446,11 +446,12 @@ # it. register_projection(HammerAxes) -# Now make a simple example using the custom projection. -from pylab import * +if __name__ == '__main__': + import matplotlib.pyplot as plt + # Now make a simple example using the custom projection. + plt.subplot(111, projection="custom_hammer") + p = plt.plot([-1, 1, 1], [-1, -1, 1], "o-") + plt.grid(True) -subplot(111, projection="custom_hammer") -p = plot([-1, 1, 1], [-1, -1, 1], "o-") -grid(True) + plt.show() -show() diff -Nru matplotlib-1.1.1/examples/api/custom_scale_example.py matplotlib-1.2.0/examples/api/custom_scale_example.py --- matplotlib-1.1.1/examples/api/custom_scale_example.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/api/custom_scale_example.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,11 @@ +from __future__ import unicode_literals + +import numpy as np +from numpy import ma from matplotlib import scale as mscale from matplotlib import transforms as mtransforms +from matplotlib.ticker import Formatter, FixedLocator + class MercatorLatitudeScale(mscale.ScaleBase): """ @@ -67,7 +73,7 @@ class DegreeFormatter(Formatter): def __call__(self, x, pos=None): # \u00b0 : degree symbol - return u"%d\u00b0" % ((x / np.pi) * 180.0) + return "%d\u00b0" % ((x / np.pi) * 180.0) deg2rad = np.pi / 180.0 axis.set_major_locator(FixedLocator( @@ -148,18 +154,20 @@ # that ``matplotlib`` can find it. mscale.register_scale(MercatorLatitudeScale) -from pylab import * -import numpy as np -t = arange(-180.0, 180.0, 0.1) -s = t / 360.0 * np.pi +if __name__ == '__main__': + import matplotlib.pyplot as plt + + t = np.arange(-180.0, 180.0, 0.1) + s = t / 360.0 * np.pi + + plt.plot(t, s, '-', lw=2) + plt.gca().set_yscale('mercator') -plot(t, s, '-', lw=2) -gca().set_yscale('mercator') + plt.xlabel('Longitude') + plt.ylabel('Latitude') + plt.title('Mercator: Projection of the Oppressor') + plt.grid(True) -xlabel('Longitude') -ylabel('Latitude') -title('Mercator: Projection of the Oppressor') -grid(True) + plt.show() -show() diff -Nru matplotlib-1.1.1/examples/api/date_demo.py matplotlib-1.2.0/examples/api/date_demo.py --- matplotlib-1.1.1/examples/api/date_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/api/date_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -13,10 +13,8 @@ """ import datetime import numpy as np -import matplotlib import matplotlib.pyplot as plt import matplotlib.dates as mdates -import matplotlib.mlab as mlab import matplotlib.cbook as cbook years = mdates.YearLocator() # every year diff -Nru matplotlib-1.1.1/examples/api/date_index_formatter.py matplotlib-1.2.0/examples/api/date_index_formatter.py --- matplotlib-1.1.1/examples/api/date_index_formatter.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/api/date_index_formatter.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,6 +3,7 @@ to leave out days on which there is no data, eh weekends. The example below shows how to use an 'index formatter' to achieve the desired plot """ +from __future__ import print_function import numpy as np import matplotlib.pyplot as plt import matplotlib.mlab as mlab @@ -10,7 +11,7 @@ import matplotlib.ticker as ticker datafile = cbook.get_sample_data('aapl.csv', asfileobj=False) -print 'loading', datafile +print ('loading %s' % datafile) r = mlab.csv2rec(datafile) r.sort() diff -Nru matplotlib-1.1.1/examples/api/fahrenheit_celcius_scales.py matplotlib-1.2.0/examples/api/fahrenheit_celcius_scales.py --- matplotlib-1.1.1/examples/api/fahrenheit_celcius_scales.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/api/fahrenheit_celcius_scales.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -""" -Shoiw how to display two scales on the left and right y axis -- Fahrenheit and Celcius -""" - -import matplotlib.pyplot as plt - -fig = plt.figure() -ax1 = fig.add_subplot(111) # the Fahrenheit scale -ax2 = ax1.twinx() # the Celcius scale - -def Tc(Tf): - return (5./9.)*(Tf-32) - - -def update_ax2(ax1): - y1, y2 = ax1.get_ylim() - ax2.set_ylim(Tc(y1), Tc(y2)) - ax2.figure.canvas.draw() - -# automatically update ylim of ax2 when ylim of ax1 changes. -ax1.callbacks.connect("ylim_changed", update_ax2) -ax1.plot([78, 79, 79, 77]) - -ax1.set_title('Two scales: Fahrenheit and Celcius') -ax1.set_ylabel('Fahrenheit') -ax2.set_ylabel('Celcius') - -plt.show() diff -Nru matplotlib-1.1.1/examples/api/fahrenheit_celsius_scales.py matplotlib-1.2.0/examples/api/fahrenheit_celsius_scales.py --- matplotlib-1.1.1/examples/api/fahrenheit_celsius_scales.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/api/fahrenheit_celsius_scales.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,28 @@ +""" +Show how to display two scales on the left and right y axis -- Fahrenheit and Celsius +""" + +import matplotlib.pyplot as plt + +fig = plt.figure() +ax1 = fig.add_subplot(111) # the Fahrenheit scale +ax2 = ax1.twinx() # the Celsius scale + +def Tc(Tf): + return (5./9.)*(Tf-32) + + +def update_ax2(ax1): + y1, y2 = ax1.get_ylim() + ax2.set_ylim(Tc(y1), Tc(y2)) + ax2.figure.canvas.draw() + +# automatically update ylim of ax2 when ylim of ax1 changes. +ax1.callbacks.connect("ylim_changed", update_ax2) +ax1.plot([78, 79, 79, 77]) + +ax1.set_title('Two scales: Fahrenheit and Celsius') +ax1.set_ylabel('Fahrenheit') +ax2.set_ylabel('Celsius') + +plt.show() diff -Nru matplotlib-1.1.1/examples/api/logo2.py matplotlib-1.2.0/examples/api/logo2.py --- matplotlib-1.1.1/examples/api/logo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/api/logo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -6,8 +6,6 @@ import matplotlib as mpl import matplotlib.pyplot as plt import matplotlib.cm as cm -import matplotlib.mlab as mlab -from pylab import rand mpl.rcParams['xtick.labelsize'] = 10 mpl.rcParams['ytick.labelsize'] = 12 diff -Nru matplotlib-1.1.1/examples/api/patch_collection.py matplotlib-1.2.0/examples/api/patch_collection.py --- matplotlib-1.1.1/examples/api/patch_collection.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/api/patch_collection.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,26 +1,28 @@ +import numpy as np import matplotlib from matplotlib.patches import Circle, Wedge, Polygon from matplotlib.collections import PatchCollection -import pylab +import matplotlib.pyplot as plt -fig=pylab.figure() + +fig=plt.figure() ax=fig.add_subplot(111) resolution = 50 # the number of vertices N = 3 -x = pylab.rand(N) -y = pylab.rand(N) -radii = 0.1*pylab.rand(N) +x = np.random.rand(N) +y = np.random.rand(N) +radii = 0.1*np.random.rand(N) patches = [] for x1,y1,r in zip(x, y, radii): circle = Circle((x1,y1), r) patches.append(circle) -x = pylab.rand(N) -y = pylab.rand(N) -radii = 0.1*pylab.rand(N) -theta1 = 360.0*pylab.rand(N) -theta2 = 360.0*pylab.rand(N) +x = np.random.rand(N) +y = np.random.rand(N) +radii = 0.1*np.random.rand(N) +theta1 = 360.0*np.random.rand(N) +theta2 = 360.0*np.random.rand(N) for x1,y1,r,t1,t2 in zip(x, y, radii, theta1, theta2): wedge = Wedge((x1,y1), r, t1, t2) patches.append(wedge) @@ -34,13 +36,13 @@ ] for i in range(N): - polygon = Polygon(pylab.rand(N,2), True) + polygon = Polygon(np.random.rand(N,2), True) patches.append(polygon) -colors = 100*pylab.rand(len(patches)) +colors = 100*np.random.rand(len(patches)) p = PatchCollection(patches, cmap=matplotlib.cm.jet, alpha=0.4) -p.set_array(pylab.array(colors)) +p.set_array(np.array(colors)) ax.add_collection(p) -pylab.colorbar(p) +plt.colorbar(p) -pylab.show() +plt.show() diff -Nru matplotlib-1.1.1/examples/api/radar_chart.py matplotlib-1.2.0/examples/api/radar_chart.py --- matplotlib-1.1.1/examples/api/radar_chart.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/api/radar_chart.py 2012-10-31 00:11:13.000000000 +0000 @@ -46,7 +46,7 @@ patch_dict = {'polygon': draw_poly_patch, 'circle': draw_circle_patch} if frame not in patch_dict: - raise ValueError, 'unknown value for `frame`: %s' % frame + raise ValueError('unknown value for `frame`: %s' % frame) class RadarAxes(PolarAxes): @@ -133,7 +133,8 @@ # 4)Inclusion of both gas-phase speciesis present... data = { 'column names': - ['Sulfate', 'Nitrate', 'EC', 'OC1', 'OC2', 'OC3', 'OP', 'CO', 'O3'], + ['Sulfate', 'Nitrate', 'EC', 'OC1', 'OC2', 'OC3', 'OP', 'CO', + 'O3'], 'Basecase': [[0.88, 0.01, 0.03, 0.03, 0.00, 0.06, 0.01, 0.00, 0.00], [0.07, 0.95, 0.04, 0.05, 0.00, 0.02, 0.01, 0.00, 0.00], @@ -157,8 +158,7 @@ [0.09, 0.95, 0.02, 0.03, 0.00, 0.01, 0.13, 0.06, 0.00], [0.01, 0.02, 0.71, 0.24, 0.13, 0.16, 0.00, 0.50, 0.00], [0.01, 0.03, 0.00, 0.28, 0.24, 0.23, 0.00, 0.44, 0.88], - [0.02, 0.00, 0.18, 0.45, 0.64, 0.55, 0.86, 0.00, 0.16]] - } + [0.02, 0.00, 0.18, 0.45, 0.64, 0.55, 0.86, 0.00, 0.16]]} return data @@ -185,12 +185,11 @@ ax.set_varlabels(spoke_labels) # add legend relative to top-left plot - plt.subplot(2,2,1) + plt.subplot(2, 2, 1) labels = ('Factor 1', 'Factor 2', 'Factor 3', 'Factor 4', 'Factor 5') legend = plt.legend(labels, loc=(0.9, .95), labelspacing=0.1) plt.setp(legend.get_texts(), fontsize='small') - plt.figtext(0.5, 0.965, '5-Factor Solution Profiles Across Four Scenarios', - ha='center', color='black', weight='bold', size='large') + plt.figtext(0.5, 0.965, '5-Factor Solution Profiles Across Four Scenarios', + ha='center', color='black', weight='bold', size='large') plt.show() - diff -Nru matplotlib-1.1.1/examples/api/sankey_demo_links.py matplotlib-1.2.0/examples/api/sankey_demo_links.py --- matplotlib-1.1.1/examples/api/sankey_demo_links.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/examples/api/sankey_demo_links.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,31 +1,35 @@ """Demonstrate/test the Sankey class by producing a long chain of connections. """ -import numpy as np -import matplotlib.pyplot as plt -from matplotlib.sankey import Sankey from itertools import cycle +import matplotlib.pyplot as plt +from matplotlib.sankey import Sankey + links_per_side = 6 + + def side(sankey, n=1): - """Generate a side chain. - """ + """Generate a side chain.""" prior = len(sankey.diagrams) colors = cycle(['orange', 'b', 'g', 'r', 'c', 'm', 'y']) for i in range(0, 2*n, 2): sankey.add(flows=[1, -1], orientations=[-1, -1], - patchlabel=str(prior+i), facecolor=colors.next(), + patchlabel=str(prior+i), facecolor=next(colors), prior=prior+i-1, connect=(1, 0), alpha=0.5) sankey.add(flows=[1, -1], orientations=[1, 1], - patchlabel=str(prior+i+1), facecolor=colors.next(), + patchlabel=str(prior+i+1), facecolor=next(colors), prior=prior+i, connect=(1, 0), alpha=0.5) + + def corner(sankey): - """Generate a corner link. - """ + """Generate a corner link.""" prior = len(sankey.diagrams) sankey.add(flows=[1, -1], orientations=[0, 1], patchlabel=str(prior), facecolor='k', prior=prior-1, connect=(1, 0), alpha=0.5) + + fig = plt.figure() ax = fig.add_subplot(1, 1, 1, xticks=[], yticks=[], title="Why would you want to do this?\n(But you could.)") diff -Nru matplotlib-1.1.1/examples/api/sankey_demo_old.py matplotlib-1.2.0/examples/api/sankey_demo_old.py --- matplotlib-1.1.1/examples/api/sankey_demo_old.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/api/sankey_demo_old.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,12 @@ #!/usr/bin/env python +from __future__ import print_function + __author__ = "Yannick Copin " __version__ = "Time-stamp: <10/02/2010 16:49 ycopin@lyopc548.in2p3.fr>" -import numpy as N +import numpy as np + def sankey(ax, outputs=[100.], outlabels=None, @@ -11,143 +14,142 @@ dx=40, dy=10, outangle=45, w=3, inangle=30, offset=2, **kwargs): """Draw a Sankey diagram. -outputs: array of outputs, should sum up to 100% -outlabels: output labels (same length as outputs), -or None (use default labels) or '' (no labels) -inputs and inlabels: similar for inputs -dx: horizontal elongation -dy: vertical elongation -outangle: output arrow angle [deg] -w: output arrow shoulder -inangle: input dip angle -offset: text offset -**kwargs: propagated to Patch (e.g. fill=False) - -Return (patch,[intexts,outtexts]).""" + outputs: array of outputs, should sum up to 100% + outlabels: output labels (same length as outputs), + or None (use default labels) or '' (no labels) + inputs and inlabels: similar for inputs + dx: horizontal elongation + dy: vertical elongation + outangle: output arrow angle [deg] + w: output arrow shoulder + inangle: input dip angle + offset: text offset + **kwargs: propagated to Patch (e.g. fill=False) + Return (patch,[intexts,outtexts]). + """ import matplotlib.patches as mpatches from matplotlib.path import Path - outs = N.absolute(outputs) - outsigns = N.sign(outputs) - outsigns[-1] = 0 # Last output - - ins = N.absolute(inputs) - insigns = N.sign(inputs) - insigns[0] = 0 # First input + outs = np.absolute(outputs) + outsigns = np.sign(outputs) + outsigns[-1] = 0 # Last output + + ins = np.absolute(inputs) + insigns = np.sign(inputs) + insigns[0] = 0 # First input - assert sum(outs)==100, "Outputs don't sum up to 100%" - assert sum(ins)==100, "Inputs don't sum up to 100%" + assert sum(outs) == 100, "Outputs don't sum up to 100%" + assert sum(ins) == 100, "Inputs don't sum up to 100%" def add_output(path, loss, sign=1): - h = (loss/2+w)*N.tan(outangle/180.*N.pi) # Arrow tip height - move,(x,y) = path[-1] # Use last point as reference - if sign==0: # Final loss (horizontal) - path.extend([(Path.LINETO,[x+dx,y]), - (Path.LINETO,[x+dx,y+w]), - (Path.LINETO,[x+dx+h,y-loss/2]), # Tip - (Path.LINETO,[x+dx,y-loss-w]), - (Path.LINETO,[x+dx,y-loss])]) - outtips.append((sign,path[-3][1])) - else: # Intermediate loss (vertical) - path.extend([(Path.CURVE4,[x+dx/2,y]), - (Path.CURVE4,[x+dx,y]), - (Path.CURVE4,[x+dx,y+sign*dy]), - (Path.LINETO,[x+dx-w,y+sign*dy]), - (Path.LINETO,[x+dx+loss/2,y+sign*(dy+h)]), # Tip - (Path.LINETO,[x+dx+loss+w,y+sign*dy]), - (Path.LINETO,[x+dx+loss,y+sign*dy]), - (Path.CURVE3,[x+dx+loss,y-sign*loss]), - (Path.CURVE3,[x+dx/2+loss,y-sign*loss])]) - outtips.append((sign,path[-5][1])) + h = (loss/2 + w)*np.tan(outangle/180. * np.pi) # Arrow tip height + move, (x, y) = path[-1] # Use last point as reference + if sign == 0: # Final loss (horizontal) + path.extend([(Path.LINETO, [x+dx, y]), + (Path.LINETO, [x+dx, y+w]), + (Path.LINETO, [x+dx+h, y-loss/2]), # Tip + (Path.LINETO, [x+dx, y-loss-w]), + (Path.LINETO, [x+dx, y-loss])]) + outtips.append((sign, path[-3][1])) + else: # Intermediate loss (vertical) + path.extend([(Path.CURVE4, [x+dx/2, y]), + (Path.CURVE4, [x+dx, y]), + (Path.CURVE4, [x+dx, y+sign*dy]), + (Path.LINETO, [x+dx-w, y+sign*dy]), + (Path.LINETO, [x+dx+loss/2, y+sign*(dy+h)]), # Tip + (Path.LINETO, [x+dx+loss+w, y+sign*dy]), + (Path.LINETO, [x+dx+loss, y+sign*dy]), + (Path.CURVE3, [x+dx+loss, y-sign*loss]), + (Path.CURVE3, [x+dx/2+loss, y-sign*loss])]) + outtips.append((sign, path[-5][1])) def add_input(path, gain, sign=1): - h = (gain/2)*N.tan(inangle/180.*N.pi) # Dip depth - move,(x,y) = path[-1] # Use last point as reference - if sign==0: # First gain (horizontal) - path.extend([(Path.LINETO,[x-dx,y]), - (Path.LINETO,[x-dx+h,y+gain/2]), # Dip - (Path.LINETO,[x-dx,y+gain])]) - xd,yd = path[-2][1] # Dip position - indips.append((sign,[xd-h,yd])) - else: # Intermediate gain (vertical) - path.extend([(Path.CURVE4,[x-dx/2,y]), - (Path.CURVE4,[x-dx,y]), - (Path.CURVE4,[x-dx,y+sign*dy]), - (Path.LINETO,[x-dx-gain/2,y+sign*(dy-h)]), # Dip - (Path.LINETO,[x-dx-gain,y+sign*dy]), - (Path.CURVE3,[x-dx-gain,y-sign*gain]), - (Path.CURVE3,[x-dx/2-gain,y-sign*gain])]) - xd,yd = path[-4][1] # Dip position - indips.append((sign,[xd,yd+sign*h])) - - outtips = [] # Output arrow tip dir. and positions - urpath = [(Path.MOVETO,[0,100])] # 1st point of upper right path - lrpath = [(Path.LINETO,[0,0])] # 1st point of lower right path - for loss,sign in zip(outs,outsigns): + h = (gain/2)*np.tan(inangle/180. * np.pi) # Dip depth + move, (x, y) = path[-1] # Use last point as reference + if sign == 0: # First gain (horizontal) + path.extend([(Path.LINETO, [x-dx, y]), + (Path.LINETO, [x-dx+h, y+gain/2]), # Dip + (Path.LINETO, [x-dx, y+gain])]) + xd, yd = path[-2][1] # Dip position + indips.append((sign, [xd-h, yd])) + else: # Intermediate gain (vertical) + path.extend([(Path.CURVE4, [x-dx/2, y]), + (Path.CURVE4, [x-dx, y]), + (Path.CURVE4, [x-dx, y+sign*dy]), + (Path.LINETO, [x-dx-gain/2, y+sign*(dy-h)]), # Dip + (Path.LINETO, [x-dx-gain, y+sign*dy]), + (Path.CURVE3, [x-dx-gain, y-sign*gain]), + (Path.CURVE3, [x-dx/2-gain, y-sign*gain])]) + xd, yd = path[-4][1] # Dip position + indips.append((sign, [xd, yd+sign*h])) + + outtips = [] # Output arrow tip dir. and positions + urpath = [(Path.MOVETO, [0, 100])] # 1st point of upper right path + lrpath = [(Path.LINETO, [0, 0])] # 1st point of lower right path + for loss, sign in zip(outs, outsigns): add_output(sign>=0 and urpath or lrpath, loss, sign=sign) - indips = [] # Input arrow tip dir. and positions - llpath = [(Path.LINETO,[0,0])] # 1st point of lower left path - ulpath = [(Path.MOVETO,[0,100])] # 1st point of upper left path - for gain,sign in zip(ins,insigns)[::-1]: + indips = [] # Input arrow tip dir. and positions + llpath = [(Path.LINETO, [0, 0])] # 1st point of lower left path + ulpath = [(Path.MOVETO, [0, 100])] # 1st point of upper left path + for gain, sign in reversed(list(zip(ins, insigns))): add_input(sign<=0 and llpath or ulpath, gain, sign=sign) def revert(path): """A path is not just revertable by path[::-1] because of Bezier -curves.""" + curves.""" rpath = [] nextmove = Path.LINETO - for move,pos in path[::-1]: - rpath.append((nextmove,pos)) + for move, pos in path[::-1]: + rpath.append((nextmove, pos)) nextmove = move return rpath # Concatenate subpathes in correct order path = urpath + revert(lrpath) + llpath + revert(ulpath) - codes,verts = zip(*path) - verts = N.array(verts) + codes, verts = zip(*path) + verts = np.array(verts) # Path patch - path = Path(verts,codes) + path = Path(verts, codes) patch = mpatches.PathPatch(path, **kwargs) ax.add_patch(patch) - if False: # DEBUG - print "urpath", urpath - print "lrpath", revert(lrpath) - print "llpath", llpath - print "ulpath", revert(ulpath) - - xs,ys = zip(*verts) - ax.plot(xs,ys,'go-') + if False: # DEBUG + print("urpath", urpath) + print("lrpath", revert(lrpath)) + print("llpath", llpath) + print("ulpath", revert(ulpath)) + xs, ys = zip(*verts) + ax.plot(xs, ys, 'go-') # Labels - def set_labels(labels,values): + def set_labels(labels, values): """Set or check labels according to values.""" - if labels=='': # No labels + if labels == '': # No labels return labels - elif labels is None: # Default labels - return [ '%2d%%' % val for val in values ] + elif labels is None: # Default labels + return ['%2d%%' % val for val in values] else: - assert len(labels)==len(values) + assert len(labels) == len(values) return labels - def put_labels(labels,positions,output=True): + def put_labels(labels, positions, output=True): """Put labels to positions.""" texts = [] lbls = output and labels or labels[::-1] - for i,label in enumerate(lbls): - s,(x,y) = positions[i] # Label direction and position - if s==0: - t = ax.text(x+offset,y,label, + for i, label in enumerate(lbls): + s, (x, y) = positions[i] # Label direction and position + if s == 0: + t = ax.text(x+offset, y, label, ha=output and 'left' or 'right', va='center') - elif s>0: - t = ax.text(x,y+offset,label, ha='center', va='bottom') + elif s > 0: + t = ax.text(x, y+offset, label, ha='center', va='bottom') else: - t = ax.text(x,y-offset,label, ha='center', va='top') + t = ax.text(x, y-offset, label, ha='center', va='top') texts.append(t) return texts @@ -158,32 +160,30 @@ intexts = put_labels(inlabels, indips, output=False) # Axes management - ax.set_xlim(verts[:,0].min()-dx, verts[:,0].max()+dx) - ax.set_ylim(verts[:,1].min()-dy, verts[:,1].max()+dy) + ax.set_xlim(verts[:, 0].min()-dx, verts[:, 0].max()+dx) + ax.set_ylim(verts[:, 1].min()-dy, verts[:, 1].max()+dy) ax.set_aspect('equal', adjustable='datalim') - return patch,[intexts,outtexts] + return patch, [intexts, outtexts] + if __name__=='__main__': - import matplotlib.pyplot as P + import matplotlib.pyplot as plt - outputs = [10.,-20.,5.,15.,-10.,40.] - outlabels = ['First','Second','Third','Fourth','Fifth','Hurray!'] - outlabels = [ s+'\n%d%%' % abs(l) for l,s in zip(outputs,outlabels) ] - - inputs = [60.,-25.,15.] - - fig = P.figure() - ax = fig.add_subplot(1,1,1, xticks=[],yticks=[], - title="Sankey diagram" - ) - - patch,(intexts,outtexts) = sankey(ax, outputs=outputs, outlabels=outlabels, - inputs=inputs, inlabels=None, - fc='g', alpha=0.2) + outputs = [10., -20., 5., 15., -10., 40.] + outlabels = ['First', 'Second', 'Third', 'Fourth', 'Fifth', 'Hurray!'] + outlabels = [s+'\n%d%%' % abs(l) for l, s in zip(outputs, outlabels)] + + inputs = [60., -25., 15.] + + fig = plt.figure() + ax = fig.add_subplot(1, 1, 1, xticks=[], yticks=[], title="Sankey diagram") + + patch, (intexts, outtexts) = sankey(ax, outputs=outputs, + outlabels=outlabels, inputs=inputs, + inlabels=None, fc='g', alpha=0.2) outtexts[1].set_color('r') outtexts[-1].set_fontweight('bold') - P.show() - + plt.show() diff -Nru matplotlib-1.1.1/examples/api/scatter_piecharts.py matplotlib-1.2.0/examples/api/scatter_piecharts.py --- matplotlib-1.1.1/examples/api/scatter_piecharts.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/api/scatter_piecharts.py 2012-10-31 00:11:13.000000000 +0000 @@ -20,16 +20,16 @@ # some points on a circle cos,sin x = [0] + np.cos(np.linspace(0, 2*math.pi*r1, 10)).tolist() y = [0] + np.sin(np.linspace(0, 2*math.pi*r1, 10)).tolist() -xy1 = zip(x,y) +xy1 = list(zip(x,y)) # ... x = [0] + np.cos(np.linspace(2*math.pi*r1, 2*math.pi*r2, 10)).tolist() y = [0] + np.sin(np.linspace(2*math.pi*r1, 2*math.pi*r2, 10)).tolist() -xy2 = zip(x,y) +xy2 = list(zip(x,y)) x = [0] + np.cos(np.linspace(2*math.pi*r2, 2*math.pi, 10)).tolist() y = [0] + np.sin(np.linspace(2*math.pi*r2, 2*math.pi, 10)).tolist() -xy3 = zip(x,y) +xy3 = list(zip(x,y)) fig = plt.figure() diff -Nru matplotlib-1.1.1/examples/api/watermark_image.py matplotlib-1.2.0/examples/api/watermark_image.py --- matplotlib-1.1.1/examples/api/watermark_image.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/api/watermark_image.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,7 @@ """ Use a PNG file as a watermark """ +from __future__ import print_function import numpy as np import matplotlib import matplotlib.cbook as cbook @@ -8,7 +9,7 @@ import matplotlib.pyplot as plt datafile = cbook.get_sample_data('logo2.png', asfileobj=False) -print 'loading', datafile +print ('loading %s' % datafile) im = image.imread(datafile) im[:,:,-1] = 0.5 # set the alpha channel diff -Nru matplotlib-1.1.1/examples/axes_grid/demo_edge_colorbar.py matplotlib-1.2.0/examples/axes_grid/demo_edge_colorbar.py --- matplotlib-1.1.1/examples/axes_grid/demo_edge_colorbar.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/axes_grid/demo_edge_colorbar.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,89 @@ +import matplotlib.pyplot as plt +from mpl_toolkits.axes_grid1 import AxesGrid + +def get_demo_image(): + import numpy as np + from matplotlib.cbook import get_sample_data + f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False) + z = np.load(f) + # z is a numpy array of 15x15 + return z, (-3,4,-4,3) + + +def demo_bottom_cbar(fig): + """ + A grid of 2x2 images with a colorbar for each column. + """ + grid = AxesGrid(fig, 121, # similar to subplot(132) + nrows_ncols = (2, 2), + axes_pad = 0.10, + share_all=True, + label_mode = "1", + cbar_location = "bottom", + cbar_mode="edge", + cbar_pad = 0.25, + cbar_size = "15%", + direction="column" + ) + + Z, extent = get_demo_image() + cmaps = [plt.get_cmap("autumn"), plt.get_cmap("summer")] + for i in range(4): + im = grid[i].imshow(Z, extent=extent, interpolation="nearest", + cmap=cmaps[i//2]) + if i % 2: + cbar = grid.cbar_axes[i//2].colorbar(im) + + for cax in grid.cbar_axes: + cax.toggle_label(True) + cax.axis[cax.orientation].set_label("Bar") + + # This affects all axes as share_all = True. + grid.axes_llc.set_xticks([-2, 0, 2]) + grid.axes_llc.set_yticks([-2, 0, 2]) + + +def demo_right_cbar(fig): + """ + A grid of 2x2 images. Each row has its own colorbar. + """ + + grid = AxesGrid(F, 122, # similar to subplot(122) + nrows_ncols = (2, 2), + axes_pad = 0.10, + label_mode = "1", + share_all = True, + cbar_location="right", + cbar_mode="edge", + cbar_size="7%", + cbar_pad="2%", + ) + Z, extent = get_demo_image() + cmaps = [plt.get_cmap("spring"), plt.get_cmap("winter")] + for i in range(4): + im = grid[i].imshow(Z, extent=extent, interpolation="nearest", + cmap=cmaps[i//2]) + if i % 2: + grid.cbar_axes[i//2].colorbar(im) + + for cax in grid.cbar_axes: + cax.toggle_label(True) + cax.axis[cax.orientation].set_label('Foo') + + # This affects all axes because we set share_all = True. + grid.axes_llc.set_xticks([-2, 0, 2]) + grid.axes_llc.set_yticks([-2, 0, 2]) + + + +if 1: + F = plt.figure(1, (5.5, 2.5)) + + F.subplots_adjust(left=0.05, right=0.93) + + demo_bottom_cbar(F) + demo_right_cbar(F) + + plt.draw() + plt.show() + diff -Nru matplotlib-1.1.1/examples/event_handling/close_event.py matplotlib-1.2.0/examples/event_handling/close_event.py --- matplotlib-1.1.1/examples/event_handling/close_event.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/event_handling/close_event.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,8 @@ +from __future__ import print_function import matplotlib.pyplot as plt def handle_close(evt): - print 'Closed Figure!' + print('Closed Figure!') fig = plt.figure() fig.canvas.mpl_connect('close_event', handle_close) diff -Nru matplotlib-1.1.1/examples/event_handling/data_browser.py matplotlib-1.2.0/examples/event_handling/data_browser.py --- matplotlib-1.1.1/examples/event_handling/data_browser.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/event_handling/data_browser.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,22 +1,11 @@ import numpy as np -from pylab import figure, show -X = np.random.rand(100, 200) -xs = np.mean(X, axis=1) -ys = np.std(X, axis=1) - -fig = figure() -ax = fig.add_subplot(211) -ax.set_title('click on point to plot time series') -line, = ax.plot(xs, ys, 'o', picker=5) # 5 points tolerance -ax2 = fig.add_subplot(212) - class PointBrowser: """ Click on a point to select and highlight it -- the data that generated the point will be shown in the lower axes. Use the 'n' - and 'p' keys to browse through the next and pervious points + and 'p' keys to browse through the next and previous points """ def __init__(self): self.lastind = 0 @@ -74,9 +63,23 @@ fig.canvas.draw() -browser = PointBrowser() +if __name__ == '__main__': + import matplotlib.pyplot as plt + + X = np.random.rand(100, 200) + xs = np.mean(X, axis=1) + ys = np.std(X, axis=1) + + fig = plt.figure() + ax = fig.add_subplot(211) + ax.set_title('click on point to plot time series') + line, = ax.plot(xs, ys, 'o', picker=5) # 5 points tolerance + ax2 = fig.add_subplot(212) + + browser = PointBrowser() + + fig.canvas.mpl_connect('pick_event', browser.onpick) + fig.canvas.mpl_connect('key_press_event', browser.onpress) -fig.canvas.mpl_connect('pick_event', browser.onpick) -fig.canvas.mpl_connect('key_press_event', browser.onpress) + plt.show() -show() diff -Nru matplotlib-1.1.1/examples/event_handling/figure_axes_enter_leave.py matplotlib-1.2.0/examples/event_handling/figure_axes_enter_leave.py --- matplotlib-1.1.1/examples/event_handling/figure_axes_enter_leave.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/event_handling/figure_axes_enter_leave.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,25 +2,26 @@ Illustrate the figure and axes enter and leave events by changing the frame colors on enter and leave """ +from __future__ import print_function import matplotlib.pyplot as plt def enter_axes(event): - print 'enter_axes', event.inaxes + print('enter_axes', event.inaxes) event.inaxes.patch.set_facecolor('yellow') event.canvas.draw() def leave_axes(event): - print 'leave_axes', event.inaxes + print('leave_axes', event.inaxes) event.inaxes.patch.set_facecolor('white') event.canvas.draw() def enter_figure(event): - print 'enter_figure', event.canvas.figure + print('enter_figure', event.canvas.figure) event.canvas.figure.patch.set_facecolor('red') event.canvas.draw() def leave_figure(event): - print 'leave_figure', event.canvas.figure + print('leave_figure', event.canvas.figure) event.canvas.figure.patch.set_facecolor('grey') event.canvas.draw() diff -Nru matplotlib-1.1.1/examples/event_handling/idle_and_timeout.py matplotlib-1.2.0/examples/event_handling/idle_and_timeout.py --- matplotlib-1.1.1/examples/event_handling/idle_and_timeout.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/event_handling/idle_and_timeout.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function """ Demonstrate/test the idle and timeout API @@ -18,7 +19,7 @@ N = 100 def on_idle(event): on_idle.count +=1 - print 'idle', on_idle.count + print('idle', on_idle.count) line1.set_ydata(np.sin(2*np.pi*t*(N-on_idle.count)/float(N))) event.canvas.draw() # test boolean return removal diff -Nru matplotlib-1.1.1/examples/event_handling/keypress_demo.py matplotlib-1.2.0/examples/event_handling/keypress_demo.py --- matplotlib-1.1.1/examples/event_handling/keypress_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/event_handling/keypress_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,23 +1,26 @@ #!/usr/bin/env python + """ Show how to connect to keypress events """ -import numpy as n -from pylab import figure, show +from __future__ import print_function +import numpy as np +import matplotlib.pyplot as plt + def press(event): - print 'press', event.key + print('press', event.key) if event.key=='x': visible = xl.get_visible() xl.set_visible(not visible) fig.canvas.draw() -fig = figure() +fig = plt.figure() ax = fig.add_subplot(111) fig.canvas.mpl_connect('key_press_event', press) -ax.plot(n.random.rand(12), n.random.rand(12), 'go') +ax.plot(np.random.rand(12), np.random.rand(12), 'go') xl = ax.set_xlabel('easy come, easy go') -show() +plt.show() diff -Nru matplotlib-1.1.1/examples/event_handling/lasso_demo.py matplotlib-1.2.0/examples/event_handling/lasso_demo.py --- matplotlib-1.1.1/examples/event_handling/lasso_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/event_handling/lasso_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -4,21 +4,20 @@ selected points This is currently a proof-of-concept implementation (though it is -usable as is). There will be some refinement of the API and the -inside polygon detection routine. +usable as is). There will be some refinement of the API. """ from matplotlib.widgets import Lasso -from matplotlib.nxutils import points_inside_poly from matplotlib.colors import colorConverter from matplotlib.collections import RegularPolyCollection +from matplotlib import path -from matplotlib.pyplot import figure, show +import matplotlib.pyplot as plt from numpy import nonzero from numpy.random import rand -class Datum: +class Datum(object): colorin = colorConverter.to_rgba('red') - colorout = colorConverter.to_rgba('green') + colorout = colorConverter.to_rgba('blue') def __init__(self, x, y, include=False): self.x = x self.y = y @@ -26,7 +25,7 @@ else: self.color = self.colorout -class LassoManager: +class LassoManager(object): def __init__(self, ax, data): self.axes = ax self.canvas = ax.figure.canvas @@ -46,13 +45,13 @@ ax.add_collection(self.collection) self.cid = self.canvas.mpl_connect('button_press_event', self.onpress) - self.ind = None def callback(self, verts): facecolors = self.collection.get_facecolors() - ind = nonzero(points_inside_poly(self.xys, verts))[0] - for i in range(self.Nxy): - if i in ind: + p = path.Path(verts) + ind = p.contains_points(self.xys) + for i in range(len(self.xys)): + if ind[i]: facecolors[i] = Datum.colorin else: facecolors[i] = Datum.colorout @@ -60,7 +59,7 @@ self.canvas.draw_idle() self.canvas.widgetlock.release(self.lasso) del self.lasso - self.ind = ind + def onpress(self, event): if self.canvas.widgetlock.locked(): return if event.inaxes is None: return @@ -72,8 +71,7 @@ data = [Datum(*xy) for xy in rand(100, 2)] - fig = figure() - ax = fig.add_subplot(111, xlim=(0,1), ylim=(0,1), autoscale_on=False) + ax = plt.axes(xlim=(0,1), ylim=(0,1), autoscale_on=False) lman = LassoManager(ax, data) - show() + plt.show() diff -Nru matplotlib-1.1.1/examples/event_handling/legend_picking.py matplotlib-1.2.0/examples/event_handling/legend_picking.py --- matplotlib-1.1.1/examples/event_handling/legend_picking.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/event_handling/legend_picking.py 2012-10-31 00:11:13.000000000 +0000 @@ -28,7 +28,7 @@ def onpick(event): # on the pick event, find the orig line corresponding to the - # legend proxy line, and toggle the visibilit + # legend proxy line, and toggle the visibility legline = event.artist origline = lined[legline] vis = not origline.get_visible() diff -Nru matplotlib-1.1.1/examples/event_handling/path_editor.py matplotlib-1.2.0/examples/event_handling/path_editor.py --- matplotlib-1.1.1/examples/event_handling/path_editor.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/event_handling/path_editor.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,7 +2,6 @@ import matplotlib.path as mpath import matplotlib.patches as mpatches import matplotlib.pyplot as plt -import matplotlib.mlab as mlab Path = mpath.Path diff -Nru matplotlib-1.1.1/examples/event_handling/pick_event_demo.py matplotlib-1.2.0/examples/event_handling/pick_event_demo.py --- matplotlib-1.1.1/examples/event_handling/pick_event_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/event_handling/pick_event_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,8 +1,9 @@ #!/usr/bin/env python + """ -You can enable picking by setting the"picker" property of an artist -(eg a matplotlib Line2D, Text, Patch, Polygon, AxesImage, +You can enable picking by setting the "picker" property of an artist +(for example, a matplotlib Line2D, Text, Patch, Polygon, AxesImage, etc...) There are a variety of meanings of the picker property @@ -14,27 +15,27 @@ the artist float - if picker is a number it is interpreted as an - epsilon tolerance in points and the the artist will fire + epsilon tolerance in points and the artist will fire off an event if it's data is within epsilon of the mouse event. For some artists like lines and patch collections, the artist may provide additional data to the pick event - that is generated, eg the indices of the data within + that is generated, for example, the indices of the data within epsilon of the pick event - function - if picker is callable, it is a user supplied + function - if picker is callable, it is a user supplied function which determines whether the artist is hit by the mouse event. hit, props = picker(artist, mouseevent) - to determine the hit test. if the mouse event is over the + to determine the hit test. If the mouse event is over the artist, return hit=True and props is a dictionary of properties you want added to the PickEvent attributes After you have enabled an artist for picking by setting the "picker" property, you need to connect to the figure canvas pick_event to get -pick callbacks on mouse press events. Eg, +pick callbacks on mouse press events. For example, def pick_handler(event): mouseevent = event.mouseevent @@ -46,9 +47,9 @@ your callback is always fired with two attributes: mouseevent - the mouse event that generate the pick event. The - mouse event in turn has attributes like x and y (the coords in - display space, eg pixels from left, bottom) and xdata, ydata (the - coords in data space). Additionaly, you can get information about + mouse event in turn has attributes like x and y (the coordinates in + display space, such as pixels from left, bottom) and xdata, ydata (the + coords in data space). Additionally, you can get information about which buttons were pressed, which keys were pressed, which Axes the mouse is over, etc. See matplotlib.backend_bases.MouseEvent for details. @@ -57,18 +58,19 @@ Additionally, certain artists like Line2D and PatchCollection may attach additional meta data like the indices into the data that meet -the picker criteria (eg all the points in the line that are within the -specified epsilon tolerance) +the picker criteria (for example, all the points in the line that are within +the specified epsilon tolerance) The examples below illustrate each of these methods. """ +from __future__ import print_function from matplotlib.pyplot import figure, show from matplotlib.lines import Line2D -from matplotlib.patches import Patch, Rectangle +from matplotlib.patches import Rectangle from matplotlib.text import Text from matplotlib.image import AxesImage -import numpy as npy +import numpy as np from numpy.random import rand if 1: # simple picking, lines, rectangles and text @@ -92,13 +94,13 @@ xdata = thisline.get_xdata() ydata = thisline.get_ydata() ind = event.ind - print 'onpick1 line:', zip(npy.take(xdata, ind), npy.take(ydata, ind)) + print('onpick1 line:', zip(np.take(xdata, ind), np.take(ydata, ind))) elif isinstance(event.artist, Rectangle): patch = event.artist - print 'onpick1 patch:', patch.get_path() + print('onpick1 patch:', patch.get_path()) elif isinstance(event.artist, Text): text = event.artist - print 'onpick1 text:', text.get_text() + print('onpick1 text:', text.get_text()) @@ -124,19 +126,19 @@ xdata = line.get_xdata() ydata = line.get_ydata() maxd = 0.05 - d = npy.sqrt((xdata-mouseevent.xdata)**2. + (ydata-mouseevent.ydata)**2.) + d = np.sqrt((xdata-mouseevent.xdata)**2. + (ydata-mouseevent.ydata)**2.) - ind = npy.nonzero(npy.less_equal(d, maxd)) + ind = np.nonzero(np.less_equal(d, maxd)) if len(ind): - pickx = npy.take(xdata, ind) - picky = npy.take(ydata, ind) + pickx = np.take(xdata, ind) + picky = np.take(ydata, ind) props = dict(ind=ind, pickx=pickx, picky=picky) return True, props else: return False, dict() def onpick2(event): - print 'onpick2 line:', event.pickx, event.picky + print('onpick2 line:', event.pickx, event.picky) fig = figure() ax1 = fig.add_subplot(111) @@ -150,7 +152,7 @@ x, y, c, s = rand(4, 100) def onpick3(event): ind = event.ind - print 'onpick3 scatter:', ind, npy.take(x, ind), npy.take(y, ind) + print('onpick3 scatter:', ind, np.take(x, ind), np.take(y, ind)) fig = figure() ax1 = fig.add_subplot(111) @@ -172,7 +174,7 @@ if isinstance(artist, AxesImage): im = artist A = im.get_array() - print 'onpick4 image', A.shape + print('onpick4 image', A.shape) fig.canvas.mpl_connect('pick_event', onpick4) diff -Nru matplotlib-1.1.1/examples/event_handling/pick_event_demo2.py matplotlib-1.2.0/examples/event_handling/pick_event_demo2.py --- matplotlib-1.1.1/examples/event_handling/pick_event_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/event_handling/pick_event_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,17 +1,17 @@ """ -compute the mean and stddev of 100 data sets and plot mean vs stddev. -When you click on one of the mu, sigma points, plot the raw data from -the dataset that generated the mean and stddev +compute the mean and standard deviation (stddev) of 100 data sets and plot +mean vs stddev. When you click on one of the mu, sigma points, plot the raw +data from the dataset that generated the mean and stddev. """ import numpy -from pylab import figure, show +import matplotlib.pyplot as plt X = numpy.random.rand(100, 1000) xs = numpy.mean(X, axis=1) ys = numpy.std(X, axis=1) -fig = figure() +fig = plt.figure() ax = fig.add_subplot(111) ax.set_title('click on point to plot time series') line, = ax.plot(xs, ys, 'o', picker=5) # 5 points tolerance @@ -25,19 +25,19 @@ if not N: return True - figi = figure() + figi = plt.figure() for subplotnum, dataind in enumerate(event.ind): ax = figi.add_subplot(N,1,subplotnum+1) ax.plot(X[dataind]) ax.text(0.05, 0.9, 'mu=%1.3f\nsigma=%1.3f'%(xs[dataind], ys[dataind]), transform=ax.transAxes, va='top') - ax.set_ylim(-0.5, 1.5) + ax.set_ylim(-0.5, 1.5) figi.show() return True fig.canvas.mpl_connect('pick_event', onpick) -show() +plt.show() diff -Nru matplotlib-1.1.1/examples/event_handling/pipong.py matplotlib-1.2.0/examples/event_handling/pipong.py --- matplotlib-1.1.1/examples/event_handling/pipong.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/event_handling/pipong.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,8 +1,10 @@ #!/usr/bin/env python # A matplotlib based game of Pong illustrating one way to write interactive -# animation which are easily ported to multiply backends +# animation which are easily ported to multiple backends # pipong.py was written by Paul Ivanov +from __future__ import print_function + import numpy as np import matplotlib.pyplot as plt from numpy.random import randn, randint @@ -200,7 +202,7 @@ if self.cnt==50000: # just so we don't get carried away - print "...and you've been playing for too long!!!" + print("...and you've been playing for too long!!!") plt.close() self.cnt += 1 diff -Nru matplotlib-1.1.1/examples/event_handling/poly_editor.py matplotlib-1.2.0/examples/event_handling/poly_editor.py --- matplotlib-1.1.1/examples/event_handling/poly_editor.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/event_handling/poly_editor.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,9 +3,9 @@ matplotlib event handling to interact with objects on the canvas """ +import numpy as np +from matplotlib.lines import Line2D from matplotlib.artist import Artist -from matplotlib.patches import Polygon, CirclePolygon -from numpy import sqrt, nonzero, equal, array, asarray, dot, amin, cos, sin from matplotlib.mlab import dist_point_to_segment @@ -36,7 +36,7 @@ self.poly = poly x, y = zip(*self.poly.xy) - self.line = Line2D(x,y,marker='o', markerfacecolor='r', animated=True) + self.line = Line2D(x, y, marker='o', markerfacecolor='r', animated=True) self.ax.add_line(self.line) #self._update_line(poly) @@ -69,11 +69,11 @@ 'get the index of the vertex under point if within epsilon tolerance' # display coords - xy = asarray(self.poly.xy) + xy = np.asarray(self.poly.xy) xyt = self.poly.get_transform().transform(xy) xt, yt = xyt[:, 0], xyt[:, 1] - d = sqrt((xt-event.x)**2 + (yt-event.y)**2) - indseq = nonzero(equal(d, amin(d)))[0] + d = np.sqrt((xt-event.x)**2 + (yt-event.y)**2) + indseq = np.nonzero(np.equal(d, np.amin(d)))[0] ind = indseq[0] if d[ind]>=self.epsilon: @@ -114,7 +114,7 @@ s1 = xys[i+1] d = dist_point_to_segment(p, s0, s1) if d<=self.epsilon: - self.poly.xy = array( + self.poly.xy = np.array( list(self.poly.xy[:i]) + [(event.xdata, event.ydata)] + list(self.poly.xy[i:])) @@ -141,31 +141,26 @@ self.canvas.blit(self.ax.bbox) +if __name__ == '__main__': + import matplotlib.pyplot as plt + from matplotlib.patches import Polygon + + fig = plt.figure() + theta = np.arange(0, 2*np.pi, 0.1) + r = 1.5 + + xs = r*np.cos(theta) + ys = r*np.sin(theta) + + poly = Polygon(list(zip(xs, ys)), animated=True) + + ax = plt.subplot(111) + ax.add_patch(poly) + p = PolygonInteractor(ax, poly) + + #ax.add_line(p.line) + ax.set_title('Click and drag a point to move it') + ax.set_xlim((-2,2)) + ax.set_ylim((-2,2)) + plt.show() -from pylab import * - - - - - -fig = figure() -theta = arange(0, 2*pi, 0.1) -r = 1.5 - -xs = r*cos(theta) -ys = r*sin(theta) - -poly = Polygon(zip(xs, ys,), animated=True) - - - - -ax = subplot(111) -ax.add_patch(poly) -p = PolygonInteractor( ax, poly) - -#ax.add_line(p.line) -ax.set_title('Click and drag a point to move it') -ax.set_xlim((-2,2)) -ax.set_ylim((-2,2)) -show() diff -Nru matplotlib-1.1.1/examples/event_handling/pong_gtk.py matplotlib-1.2.0/examples/event_handling/pong_gtk.py --- matplotlib-1.1.1/examples/event_handling/pong_gtk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/event_handling/pong_gtk.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import print_function + # For detailed comments on animation and the techniques used here, see # the wiki entry # http://www.scipy.org/wikis/topical_software/MatplotlibAnimation @@ -10,10 +12,8 @@ import matplotlib matplotlib.use('GTKAgg') -import numpy as np import matplotlib.pyplot as plt import pipong -from numpy.random import randn, randint fig = plt.figure() @@ -33,4 +33,4 @@ tstart = time.time() plt.grid() # to ensure proper background restore plt.show() -print 'FPS:' , animation.cnt/(time.time()-tstart) +print('FPS:' , animation.cnt/(time.time()-tstart)) diff -Nru matplotlib-1.1.1/examples/event_handling/pong_qt.py matplotlib-1.2.0/examples/event_handling/pong_qt.py --- matplotlib-1.1.1/examples/event_handling/pong_qt.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/event_handling/pong_qt.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,8 @@ # For detailed comments on animation and the techniqes used here, see # the wiki entry http://www.scipy.org/Cookbook/Matplotlib/Animations -import os, sys +from __future__ import print_function + import matplotlib matplotlib.use('QtAgg') # qt3 example @@ -14,12 +15,9 @@ FALSE = 0 ITERS = 1000 -import pylab as p import matplotlib.pyplot as plt -import numpy as np import time import pipong -from numpy.random import randn, randint class BlitQT(QObject): def __init__(self): @@ -39,4 +37,4 @@ app.startTimer(10) plt.show() -print 'FPS:' , app.animation.cnt/(time.time()-app.tstart) +print('FPS:' , app.animation.cnt/(time.time()-app.tstart)) diff -Nru matplotlib-1.1.1/examples/event_handling/test_mouseclicks.py matplotlib-1.2.0/examples/event_handling/test_mouseclicks.py --- matplotlib-1.1.1/examples/event_handling/test_mouseclicks.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/event_handling/test_mouseclicks.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,35 @@ +#!/usr/bin/env python +from __future__ import print_function + +import matplotlib +#matplotlib.use("WxAgg") +#matplotlib.use("TkAgg") +#matplotlib.use("GTKAgg") +#matplotlib.use("QtAgg") +#matplotlib.use("Qt4Agg") +#matplotlib.use("CocoaAgg") +#matplotlib.use("MacOSX") +import matplotlib.pyplot as plt + +#print("***** TESTING WITH BACKEND: %s"%matplotlib.get_backend() + " *****") + + +def OnClick(event): + if event.dblclick: + print("DBLCLICK", event) + else: + print("DOWN ", event) + + +def OnRelease(event): + print("UP ", event) + + +fig = plt.gcf() +cid_up = fig.canvas.mpl_connect('button_press_event', OnClick) +cid_down = fig.canvas.mpl_connect('button_release_event', OnRelease) + +plt.gca().text(0.5, 0.5, "Click on the canvas to test mouse events.", + ha="center", va="center") + +plt.show() diff -Nru matplotlib-1.1.1/examples/event_handling/viewlims.py matplotlib-1.2.0/examples/event_handling/viewlims.py --- matplotlib-1.1.1/examples/event_handling/viewlims.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/event_handling/viewlims.py 2012-10-31 00:11:13.000000000 +0000 @@ -30,7 +30,7 @@ threshold_time = np.zeros((self.height, self.width)) z = np.zeros(threshold_time.shape, dtype=np.complex) mask = np.ones(threshold_time.shape, dtype=np.bool) - for i in xrange(self.niter): + for i in range(self.niter): z[mask] = z[mask]**self.power + c[mask] mask = (np.abs(z) < self.radius) threshold_time += mask diff -Nru matplotlib-1.1.1/examples/event_handling/zoom_window.py matplotlib-1.2.0/examples/event_handling/zoom_window.py --- matplotlib-1.1.1/examples/event_handling/zoom_window.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/event_handling/zoom_window.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,10 @@ """ -This example shows how to connect events in one window, eg a mouse +This example shows how to connect events in one window, for example, a mouse press, to another figure window. If you click on a point in the first window, the z and y limits of the second will be adjusted so that the center of the zoom in the second -window will be the x,y coords of the clicked point. +window will be the x,y coordinates of the clicked point. Note the diameter of the circles in the scatter are defined in points**2, so their size is independent of the zoom diff -Nru matplotlib-1.1.1/examples/misc/developer_commit_history.py matplotlib-1.2.0/examples/misc/developer_commit_history.py --- matplotlib-1.1.1/examples/misc/developer_commit_history.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/misc/developer_commit_history.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function """ report how many days it has been since each developer committed. You must do an diff -Nru matplotlib-1.1.1/examples/misc/font_indexing.py matplotlib-1.2.0/examples/misc/font_indexing.py --- matplotlib-1.1.1/examples/misc/font_indexing.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/misc/font_indexing.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,6 +3,7 @@ tables relate to one another. Mainly for mpl developers.... """ +from __future__ import print_function import matplotlib from matplotlib.ft2font import FT2Font, KERNING_DEFAULT, KERNING_UNFITTED, KERNING_UNSCALED @@ -34,8 +35,8 @@ code = coded['A'] glyph = font.load_char(code) #print glyph.bbox -print glyphd['A'], glyphd['V'], coded['A'], coded['V'] -print 'AV', font.get_kerning(glyphd['A'], glyphd['V'], KERNING_DEFAULT) -print 'AV', font.get_kerning(glyphd['A'], glyphd['V'], KERNING_UNFITTED) -print 'AV', font.get_kerning(glyphd['A'], glyphd['V'], KERNING_UNSCALED) -print 'AV', font.get_kerning(glyphd['A'], glyphd['T'], KERNING_UNSCALED) +print(glyphd['A'], glyphd['V'], coded['A'], coded['V']) +print('AV', font.get_kerning(glyphd['A'], glyphd['V'], KERNING_DEFAULT)) +print('AV', font.get_kerning(glyphd['A'], glyphd['V'], KERNING_UNFITTED)) +print('AV', font.get_kerning(glyphd['A'], glyphd['V'], KERNING_UNSCALED)) +print('AV', font.get_kerning(glyphd['A'], glyphd['T'], KERNING_UNSCALED)) diff -Nru matplotlib-1.1.1/examples/misc/ftface_props.py matplotlib-1.2.0/examples/misc/ftface_props.py --- matplotlib-1.1.1/examples/misc/ftface_props.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/misc/ftface_props.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,6 @@ #!/usr/bin/env python + +from __future__ import print_function """ This is a demo script to show you how to use all the properties of an FT2Font object. These describe global font properties. For @@ -29,48 +31,48 @@ FT_STYLE_FLAG_ITALIC = 1 << 0 FT_STYLE_FLAG_BOLD = 1 << 1 -print 'Num faces :', font.num_faces # number of faces in file -print 'Num glyphs :', font.num_glyphs # number of glyphs in the face -print 'Family name :', font.family_name # face family name -print 'Syle name :', font.style_name # face syle name -print 'PS name :', font.postscript_name # the postscript name -print 'Num fixed :', font.num_fixed_sizes # number of embedded bitmap in face +print('Num faces :', font.num_faces) # number of faces in file +print('Num glyphs :', font.num_glyphs) # number of glyphs in the face +print('Family name :', font.family_name) # face family name +print('Syle name :', font.style_name) # face syle name +print('PS name :', font.postscript_name) # the postscript name +print('Num fixed :', font.num_fixed_sizes) # number of embedded bitmap in face # the following are only available if face.scalable if font.scalable: # the face global bounding box (xmin, ymin, xmax, ymax) - print 'Bbox :', font.bbox + print('Bbox :', font.bbox) # number of font units covered by the EM - print 'EM :', font.units_per_EM + print('EM :', font.units_per_EM) # the ascender in 26.6 units - print 'Ascender :', font.ascender + print('Ascender :', font.ascender) # the descender in 26.6 units - print 'Descender :', font.descender + print('Descender :', font.descender) # the height in 26.6 units - print 'Height :', font.height + print('Height :', font.height) # maximum horizontal cursor advance - print 'Max adv width :', font.max_advance_width + print('Max adv width :', font.max_advance_width) # same for vertical layout - print 'Max adv height :', font.max_advance_height + print('Max adv height :', font.max_advance_height) # vertical position of the underline bar - print 'Underline pos :', font.underline_position + print('Underline pos :', font.underline_position) # vertical thickness of the underline - print 'Underline thickness :', font.underline_thickness + print('Underline thickness :', font.underline_thickness) -print 'Italics :', font.style_flags & FT_STYLE_FLAG_ITALIC != 0 -print 'Bold :', font.style_flags & FT_STYLE_FLAG_BOLD != 0 -print 'Scalable :', font.style_flags & FT_FACE_FLAG_SCALABLE != 0 -print 'Fixed sizes :', font.style_flags & FT_FACE_FLAG_FIXED_SIZES != 0 -print 'Fixed width :', font.style_flags & FT_FACE_FLAG_FIXED_WIDTH != 0 -print 'SFNT :', font.style_flags & FT_FACE_FLAG_SFNT != 0 -print 'Horizontal :', font.style_flags & FT_FACE_FLAG_HORIZONTAL != 0 -print 'Vertical :', font.style_flags & FT_FACE_FLAG_VERTICAL != 0 -print 'Kerning :', font.style_flags & FT_FACE_FLAG_KERNING != 0 -print 'Fast glyphs :', font.style_flags & FT_FACE_FLAG_FAST_GLYPHS != 0 -print 'Mult. masters :', font.style_flags & FT_FACE_FLAG_MULTIPLE_MASTERS != 0 -print 'Glyph names :', font.style_flags & FT_FACE_FLAG_GLYPH_NAMES != 0 +print('Italics :', font.style_flags & FT_STYLE_FLAG_ITALIC != 0) +print('Bold :', font.style_flags & FT_STYLE_FLAG_BOLD != 0) +print('Scalable :', font.style_flags & FT_FACE_FLAG_SCALABLE != 0) +print('Fixed sizes :', font.style_flags & FT_FACE_FLAG_FIXED_SIZES != 0) +print('Fixed width :', font.style_flags & FT_FACE_FLAG_FIXED_WIDTH != 0) +print('SFNT :', font.style_flags & FT_FACE_FLAG_SFNT != 0) +print('Horizontal :', font.style_flags & FT_FACE_FLAG_HORIZONTAL != 0) +print('Vertical :', font.style_flags & FT_FACE_FLAG_VERTICAL != 0) +print('Kerning :', font.style_flags & FT_FACE_FLAG_KERNING != 0) +print('Fast glyphs :', font.style_flags & FT_FACE_FLAG_FAST_GLYPHS != 0) +print('Mult. masters :', font.style_flags & FT_FACE_FLAG_MULTIPLE_MASTERS != 0) +print('Glyph names :', font.style_flags & FT_FACE_FLAG_GLYPH_NAMES != 0) -print dir(font) +print(dir(font)) cmap = font.get_charmap() -print font.get_kerning +print(font.get_kerning) diff -Nru matplotlib-1.1.1/examples/misc/image_thumbnail.py matplotlib-1.2.0/examples/misc/image_thumbnail.py --- matplotlib-1.1.1/examples/misc/image_thumbnail.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/misc/image_thumbnail.py 2012-10-31 00:11:13.000000000 +0000 @@ -4,17 +4,18 @@ image types transparently if your have PIL installed """ +from __future__ import print_function # build thumbnails of all images in a directory import sys, os, glob import matplotlib.image as image if len(sys.argv)!=2: - print 'Usage: python %s IMAGEDIR'%__file__ + print('Usage: python %s IMAGEDIR'%__file__) raise SystemExit indir = sys.argv[1] if not os.path.isdir(indir): - print 'Could not find input directory "%s"'%indir + print('Could not find input directory "%s"'%indir) raise SystemExit outdir = 'thumbs' @@ -25,5 +26,5 @@ basedir, basename = os.path.split(fname) outfile = os.path.join(outdir, basename) fig = image.thumbnail(fname, outfile, scale=0.15) - print 'saved thumbnail of %s to %s'%(fname, outfile) + print('saved thumbnail of %s to %s'%(fname, outfile)) diff -Nru matplotlib-1.1.1/examples/misc/multiprocess.py matplotlib-1.2.0/examples/misc/multiprocess.py --- matplotlib-1.1.1/examples/misc/multiprocess.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/misc/multiprocess.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,6 +3,8 @@ #Written by Robert Cimrman #Requires >= Python 2.6 for the multiprocessing module or having the #standalone processing module installed + +from __future__ import print_function import time try: from multiprocessing import Process, Pipe @@ -48,7 +50,7 @@ return call_back def __call__(self, pipe): - print 'starting plotter...' + print('starting plotter...') self.pipe = pipe self.fig = plt.figure() @@ -56,7 +58,7 @@ self.ax = self.fig.add_subplot(111) self.gid = gobject.timeout_add(1000, self.poll_draw()) - print '...done' + print('...done') plt.show() @@ -79,7 +81,7 @@ def main(): pl = NBPlot() - for ii in xrange(10): + for ii in range(10): pl.plot() time.sleep(0.5) raw_input('press Enter...') diff -Nru matplotlib-1.1.1/examples/misc/rc_traits.py matplotlib-1.2.0/examples/misc/rc_traits.py --- matplotlib-1.1.1/examples/misc/rc_traits.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/misc/rc_traits.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,8 +3,10 @@ # matplotlib does not ship with enthought.traits, so you will need to # install it separately. +from __future__ import print_function + import sys, os, re -import enthought.traits.api as traits +import traits.api as traits from matplotlib.cbook import is_string_like from matplotlib.artist import Artist @@ -140,11 +142,11 @@ rc = RC() rc.lines.color = 'r' if doprint: - print 'RC' + print('RC') rc.print_traits() - print 'RC lines' + print('RC lines') rc.lines.print_traits() - print 'RC patches' + print('RC patches') rc.patch.print_traits() @@ -182,13 +184,13 @@ p.facecolor = (1,.5,.5,.25) p.facecolor = 0.25 p.fill = 'f' -print 'p.facecolor', type(p.facecolor), p.facecolor -print 'p.fill', type(p.fill), p.fill -if p.fill_: print 'fill' -else: print 'no fill' +print('p.facecolor', type(p.facecolor), p.facecolor) +print('p.fill', type(p.fill), p.fill) +if p.fill_: print('fill') +else: print('no fill') if doprint: - print - print 'Patch' + print() + print('Patch') p.print_traits() diff -Nru matplotlib-1.1.1/examples/misc/rec_groupby_demo.py matplotlib-1.2.0/examples/misc/rec_groupby_demo.py --- matplotlib-1.1.1/examples/misc/rec_groupby_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/misc/rec_groupby_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,10 @@ +from __future__ import print_function import numpy as np import matplotlib.mlab as mlab import matplotlib.cbook as cbook datafile = cbook.get_sample_data('aapl.csv', asfileobj=False) -print 'loading', datafile +print('loading', datafile) r = mlab.csv2rec(datafile) r.sort() @@ -44,19 +45,19 @@ ) # you can summarize over a single variable, like years or months -print 'summary by years' +print('summary by years') ry = mlab.rec_groupby(rsum, ('years',), stats) -print mlab. rec2txt(ry) +print(mlab. rec2txt(ry)) -print 'summary by months' +print('summary by months') rm = mlab.rec_groupby(rsum, ('months',), stats) -print mlab.rec2txt(rm) +print(mlab.rec2txt(rm)) # or over multiple variables like years and months -print 'summary by year and month' +print('summary by year and month') rym = mlab.rec_groupby(rsum, ('years','months'), stats) -print mlab.rec2txt(rym) +print(mlab.rec2txt(rym)) -print 'summary by volume' +print('summary by volume') rv = mlab.rec_groupby(rsum, ('volcode',), stats) -print mlab.rec2txt(rv) +print(mlab.rec2txt(rv)) diff -Nru matplotlib-1.1.1/examples/misc/rec_join_demo.py matplotlib-1.2.0/examples/misc/rec_join_demo.py --- matplotlib-1.1.1/examples/misc/rec_join_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/misc/rec_join_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,10 @@ +from __future__ import print_function import numpy as np import matplotlib.mlab as mlab import matplotlib.cbook as cbook datafile = cbook.get_sample_data('aapl.csv', asfileobj=False) -print 'loading', datafile +print('loading', datafile) r = mlab.csv2rec(datafile) r.sort() @@ -17,14 +18,14 @@ r2.high = r.high[-17:-5] r2.marker = np.arange(12) -print "r1:" -print mlab.rec2txt(r1) -print "r2:" -print mlab.rec2txt(r2) +print("r1:") +print(mlab.rec2txt(r1)) +print("r2:") +print(mlab.rec2txt(r2)) defaults = {'marker':-1, 'close':np.NaN, 'low':-4444.} for s in ('inner', 'outer', 'leftouter'): rec = mlab.rec_join(['date', 'high'], r1, r2, jointype=s, defaults=defaults) - print "\n%sjoin :\n%s" % (s, mlab.rec2txt(rec)) + print("\n%sjoin :\n%s" % (s, mlab.rec2txt(rec))) diff -Nru matplotlib-1.1.1/examples/misc/sample_data_demo.py matplotlib-1.2.0/examples/misc/sample_data_demo.py --- matplotlib-1.1.1/examples/misc/sample_data_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/misc/sample_data_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,11 +2,12 @@ Grab mpl data from the ~/.matplotlib/sample_data cache if it exists, else fetch it from github and cache it """ +from __future__ import print_function import matplotlib.cbook as cbook import matplotlib.pyplot as plt fname = cbook.get_sample_data('lena.png', asfileobj=False) -print 'fname', fname +print('fname', fname) im = plt.imread(fname) plt.imshow(im) plt.show() diff -Nru matplotlib-1.1.1/examples/misc/sample_data_test.py matplotlib-1.2.0/examples/misc/sample_data_test.py --- matplotlib-1.1.1/examples/misc/sample_data_test.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/misc/sample_data_test.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -""" -Demonstrate how get_sample_data works with git revisions in the data. - - git clone git@github.com/matplotlib/sample_data.git - -and edit testdata.csv to add a new row. After committing the changes, -when you rerun this script you will get the updated data (and the new -git version will be cached in ~/.matplotlib/sample_data) -""" - -import matplotlib.mlab as mlab -import matplotlib.cbook as cbook - -# get the file handle to the cached data and print the contents -datafile = 'testdir/subdir/testsub.csv' -fh = cbook.get_sample_data(datafile) -print fh.read() - -# make sure we can read it using csv2rec -fh.seek(0) -r = mlab.csv2rec(fh) - -print mlab.rec2txt(r) - -fh.close() - diff -Nru matplotlib-1.1.1/examples/misc/svg_filter_line.py matplotlib-1.2.0/examples/misc/svg_filter_line.py --- matplotlib-1.1.1/examples/misc/svg_filter_line.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/misc/svg_filter_line.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,9 +2,10 @@ Demonstrate SVG filtering effects which might be used with mpl. Note that the filtering effects are only effective if your svg rederer -support it. +support it. """ +from __future__ import print_function import matplotlib matplotlib.use("Svg") @@ -68,7 +69,7 @@ """ -# read in the saved svg +# read in the saved svg tree, xmlid = ET.XMLID(f.getvalue()) # insert the filter definition in the svg dom tree. @@ -81,5 +82,5 @@ shadow.set("filter",'url(#dropshadow)') fn = "svg_filter_line.svg" -print "Saving '%s'" % fn +print("Saving '%s'" % fn) ET.ElementTree(tree).write(fn) diff -Nru matplotlib-1.1.1/examples/misc/tight_bbox_test.py matplotlib-1.2.0/examples/misc/tight_bbox_test.py --- matplotlib-1.1.1/examples/misc/tight_bbox_test.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/misc/tight_bbox_test.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import matplotlib.pyplot as plt import numpy as np @@ -9,6 +10,6 @@ plt.ylabel("My y-label") plt.title("Check saved figures for their bboxes") for ext in ["png", "pdf", "svg", "svgz", "eps"]: - print "saving tight_bbox_test.%s" % (ext,) + print("saving tight_bbox_test.%s" % (ext,)) plt.savefig("tight_bbox_test.%s" % (ext,), bbox_inches="tight") plt.show() diff -Nru matplotlib-1.1.1/examples/mplot3d/contour3d_demo.py matplotlib-1.2.0/examples/mplot3d/contour3d_demo.py --- matplotlib-1.1.1/examples/mplot3d/contour3d_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/mplot3d/contour3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,11 @@ from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt +from matplotlib import cm fig = plt.figure() ax = fig.add_subplot(111, projection='3d') X, Y, Z = axes3d.get_test_data(0.05) -cset = ax.contour(X, Y, Z) +cset = ax.contour(X, Y, Z, cmap=cm.coolwarm) ax.clabel(cset, fontsize=9, inline=1) plt.show() diff -Nru matplotlib-1.1.1/examples/mplot3d/contour3d_demo2.py matplotlib-1.2.0/examples/mplot3d/contour3d_demo2.py --- matplotlib-1.1.1/examples/mplot3d/contour3d_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/mplot3d/contour3d_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,11 @@ from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt +from matplotlib import cm fig = plt.figure() ax = fig.gca(projection='3d') X, Y, Z = axes3d.get_test_data(0.05) -cset = ax.contour(X, Y, Z, extend3d=True) +cset = ax.contour(X, Y, Z, extend3d=True, cmap=cm.coolwarm) ax.clabel(cset, fontsize=9, inline=1) plt.show() diff -Nru matplotlib-1.1.1/examples/mplot3d/contour3d_demo3.py matplotlib-1.2.0/examples/mplot3d/contour3d_demo3.py --- matplotlib-1.1.1/examples/mplot3d/contour3d_demo3.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/mplot3d/contour3d_demo3.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,13 +1,14 @@ from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt +from matplotlib import cm fig = plt.figure() ax = fig.gca(projection='3d') X, Y, Z = axes3d.get_test_data(0.05) ax.plot_surface(X, Y, Z, rstride=8, cstride=8, alpha=0.3) -cset = ax.contour(X, Y, Z, zdir='z', offset=-100) -cset = ax.contour(X, Y, Z, zdir='x', offset=-40) -cset = ax.contour(X, Y, Z, zdir='y', offset=40) +cset = ax.contour(X, Y, Z, zdir='z', offset=-100, cmap=cm.coolwarm) +cset = ax.contour(X, Y, Z, zdir='x', offset=-40, cmap=cm.coolwarm) +cset = ax.contour(X, Y, Z, zdir='y', offset=40, cmap=cm.coolwarm) ax.set_xlabel('X') ax.set_xlim(-40, 40) diff -Nru matplotlib-1.1.1/examples/mplot3d/contourf3d_demo.py matplotlib-1.2.0/examples/mplot3d/contourf3d_demo.py --- matplotlib-1.1.1/examples/mplot3d/contourf3d_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/mplot3d/contourf3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,11 @@ from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt +from matplotlib import cm fig = plt.figure() ax = fig.gca(projection='3d') X, Y, Z = axes3d.get_test_data(0.05) -cset = ax.contourf(X, Y, Z) +cset = ax.contourf(X, Y, Z, cmap=cm.coolwarm) ax.clabel(cset, fontsize=9, inline=1) plt.show() diff -Nru matplotlib-1.1.1/examples/mplot3d/contourf3d_demo2.py matplotlib-1.2.0/examples/mplot3d/contourf3d_demo2.py --- matplotlib-1.1.1/examples/mplot3d/contourf3d_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/mplot3d/contourf3d_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -5,14 +5,15 @@ from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt +from matplotlib import cm fig = plt.figure() ax = fig.gca(projection='3d') X, Y, Z = axes3d.get_test_data(0.05) ax.plot_surface(X, Y, Z, rstride=8, cstride=8, alpha=0.3) -cset = ax.contourf(X, Y, Z, zdir='z', offset=-100) -cset = ax.contourf(X, Y, Z, zdir='x', offset=-40) -cset = ax.contourf(X, Y, Z, zdir='y', offset=40) +cset = ax.contourf(X, Y, Z, zdir='z', offset=-100, cmap=cm.coolwarm) +cset = ax.contourf(X, Y, Z, zdir='x', offset=-40, cmap=cm.coolwarm) +cset = ax.contourf(X, Y, Z, zdir='y', offset=40, cmap=cm.coolwarm) ax.set_xlabel('X') ax.set_xlim(-40, 40) diff -Nru matplotlib-1.1.1/examples/mplot3d/lorenz_attractor.py matplotlib-1.2.0/examples/mplot3d/lorenz_attractor.py --- matplotlib-1.1.1/examples/mplot3d/lorenz_attractor.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/mplot3d/lorenz_attractor.py 2012-10-31 00:11:13.000000000 +0000 @@ -30,7 +30,7 @@ xs[0], ys[0], zs[0] = (0., 1., 1.05) # Stepping through "time". -for i in xrange(stepCnt) : +for i in range(stepCnt) : # Derivatives of the X, Y, Z state x_dot, y_dot, z_dot = lorenz(xs[i], ys[i], zs[i]) xs[i + 1] = xs[i] + (x_dot * dt) diff -Nru matplotlib-1.1.1/examples/mplot3d/pathpatch3d_demo.py matplotlib-1.2.0/examples/mplot3d/pathpatch3d_demo.py --- matplotlib-1.1.1/examples/mplot3d/pathpatch3d_demo.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/examples/mplot3d/pathpatch3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,14 +1,15 @@ import matplotlib.pyplot as plt from matplotlib.patches import Circle, PathPatch +# register Axes3D class with matplotlib by importing Axes3D from mpl_toolkits.mplot3d import Axes3D import mpl_toolkits.mplot3d.art3d as art3d from matplotlib.text import TextPath from matplotlib.transforms import Affine2D -def text3d(ax, (x, y, z), s, zdir="z", size=None, angle=0, usetex=False, - **kwargs): +def text3d(ax, xyz, s, zdir="z", size=None, angle=0, usetex=False, **kwargs): + x, y, z = xyz if zdir == "y": xy1, z1 = (x, z), y elif zdir == "y": @@ -34,13 +35,14 @@ text3d(ax, (4, -2, 0), "X-axis", zdir="z", size=.5, usetex=False, ec="none", fc="k") -text3d(ax, (12, 4, 0), "Y-axis", zdir="z", size=.5, usetex=False, angle=.5*3.14159, - ec="none", fc="k") -text3d(ax, (12, 10, 4), "Z-axis", zdir="y", size=.5, usetex=False, angle=.5*3.14159, - ec="none", fc="k") +text3d(ax, (12, 4, 0), "Y-axis", zdir="z", size=.5, usetex=False, + angle=.5*3.14159, ec="none", fc="k") +text3d(ax, (12, 10, 4), "Z-axis", zdir="y", size=.5, usetex=False, + angle=.5*3.14159, ec="none", fc="k") text3d(ax, (1, 5, 0), - r"$\displaystyle G_{\mu\nu} + \Lambda g_{\mu\nu} = \frac{8\pi G}{c^4} T_{\mu\nu} $", + r"$\displaystyle G_{\mu\nu} + \Lambda g_{\mu\nu} = " + r"\frac{8\pi G}{c^4} T_{\mu\nu} $", zdir="z", size=1, usetex=True, ec="none", fc="k") @@ -49,4 +51,3 @@ ax.set_zlim3d(0, 10) plt.show() - diff -Nru matplotlib-1.1.1/examples/mplot3d/polys3d_demo.py matplotlib-1.2.0/examples/mplot3d/polys3d_demo.py --- matplotlib-1.1.1/examples/mplot3d/polys3d_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/mplot3d/polys3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -15,7 +15,7 @@ for z in zs: ys = np.random.rand(len(xs)) ys[0], ys[-1] = 0, 0 - verts.append(zip(xs, ys)) + verts.append(list(zip(xs, ys))) poly = PolyCollection(verts, facecolors = [cc('r'), cc('g'), cc('b'), cc('y')]) diff -Nru matplotlib-1.1.1/examples/mplot3d/subplot3d_demo.py matplotlib-1.2.0/examples/mplot3d/subplot3d_demo.py --- matplotlib-1.1.1/examples/mplot3d/subplot3d_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/mplot3d/subplot3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -17,7 +17,7 @@ X, Y = np.meshgrid(X, Y) R = np.sqrt(X**2 + Y**2) Z = np.sin(R) -surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet, +surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False) ax.set_zlim3d(-1.01, 1.01) diff -Nru matplotlib-1.1.1/examples/mplot3d/surface3d_demo.py matplotlib-1.2.0/examples/mplot3d/surface3d_demo.py --- matplotlib-1.1.1/examples/mplot3d/surface3d_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/mplot3d/surface3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -11,7 +11,7 @@ X, Y = np.meshgrid(X, Y) R = np.sqrt(X**2 + Y**2) Z = np.sin(R) -surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet, +surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False) ax.set_zlim(-1.01, 1.01) diff -Nru matplotlib-1.1.1/examples/mplot3d/surface3d_radial_demo.py matplotlib-1.2.0/examples/mplot3d/surface3d_radial_demo.py --- matplotlib-1.1.1/examples/mplot3d/surface3d_radial_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/mplot3d/surface3d_radial_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -18,7 +18,7 @@ X,Y = R*np.cos(P),R*np.sin(P) Z = ((R**2 - 1)**2) -ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet) +ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.YlGnBu_r) ax.set_zlim3d(0, 1) ax.set_xlabel(r'$\phi_\mathrm{real}$') ax.set_ylabel(r'$\phi_\mathrm{im}$') diff -Nru matplotlib-1.1.1/examples/mplot3d/trisurf3d_demo.py matplotlib-1.2.0/examples/mplot3d/trisurf3d_demo.py --- matplotlib-1.1.1/examples/mplot3d/trisurf3d_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/mplot3d/trisurf3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,32 @@ +from mpl_toolkits.mplot3d import Axes3D +from matplotlib import cm +import matplotlib.pyplot as plt +import numpy as np + +n_angles = 36 +n_radii = 8 + +# An array of radii +# Does not include radius r=0, this is to eliminate duplicate points +radii = np.linspace(0.125, 1.0, n_radii) + +# An array of angles +angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False) + +# Repeat all angles for each radius +angles = np.repeat(angles[...,np.newaxis], n_radii, axis=1) + +# Convert polar (radii, angles) coords to cartesian (x, y) coords +# (0, 0) is added here. There are no duplicate points in the (x, y) plane +x = np.append(0, (radii*np.cos(angles)).flatten()) +y = np.append(0, (radii*np.sin(angles)).flatten()) + +# Pringle surface +z = np.sin(-x*y) + +fig = plt.figure() +ax = fig.gca(projection='3d') + +ax.plot_trisurf(x, y, z, cmap=cm.jet, linewidth=0.2) + +plt.show() diff -Nru matplotlib-1.1.1/examples/mplot3d/wire3d_animation_demo.py matplotlib-1.2.0/examples/mplot3d/wire3d_animation_demo.py --- matplotlib-1.1.1/examples/mplot3d/wire3d_animation_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/mplot3d/wire3d_animation_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function """ A very simple 'animation' of a 3D plot """ @@ -34,4 +35,4 @@ plt.draw() -print 'FPS: %f' % (100 / (time.time() - tstart)) +print ('FPS: %f' % (100 / (time.time() - tstart))) diff -Nru matplotlib-1.1.1/examples/pylab_examples/agg_buffer_to_array.py matplotlib-1.2.0/examples/pylab_examples/agg_buffer_to_array.py --- matplotlib-1.1.1/examples/pylab_examples/agg_buffer_to_array.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/agg_buffer_to_array.py 2012-11-08 02:24:12.000000000 +0000 @@ -1,5 +1,4 @@ import matplotlib -matplotlib.use('Agg') from pylab import figure, show import numpy as np @@ -10,10 +9,12 @@ ax.set_title('a simple figure') fig.canvas.draw() -# grab rhe pixel buffer and dumpy it into a numpy array -buf = fig.canvas.buffer_rgba(0,0) +# grab the pixel buffer and dump it into a numpy array +buf = fig.canvas.buffer_rgba() l, b, w, h = fig.bbox.bounds -X = np.fromstring(buf, np.uint8) +# The array needs to be copied, because the underlying buffer +# may be reallocated when the window is resized. +X = np.frombuffer(buf, np.uint8).copy() X.shape = h,w,4 # now display the array X as an Axes in a new figure diff -Nru matplotlib-1.1.1/examples/pylab_examples/anchored_artists.py matplotlib-1.2.0/examples/pylab_examples/anchored_artists.py --- matplotlib-1.1.1/examples/pylab_examples/anchored_artists.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/anchored_artists.py 2012-10-31 00:11:13.000000000 +0000 @@ -22,7 +22,7 @@ pad=0.1, borderpad=0.1, sep=2, prop=None, frameon=True): """ Draw a horizontal bar with the size in data coordinate of the give axes. - A label will be drawn underneath (center-alinged). + A label will be drawn underneath (center-aligned). pad, borderpad in fraction of the legend font size (or prop) sep in points. diff -Nru matplotlib-1.1.1/examples/pylab_examples/animation_demo.py matplotlib-1.2.0/examples/pylab_examples/animation_demo.py --- matplotlib-1.1.1/examples/pylab_examples/animation_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/animation_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -23,8 +23,5 @@ z = z + 2 p.set_data(z) - print "step", i + print("step", i) plt.pause(0.5) - - - diff -Nru matplotlib-1.1.1/examples/pylab_examples/annotation_demo.py matplotlib-1.2.0/examples/pylab_examples/annotation_demo.py --- matplotlib-1.1.1/examples/pylab_examples/annotation_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/annotation_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -113,7 +113,7 @@ if 1: - # You can also use polar notation on a catesian axes. Here the + # You can also use polar notation on a cartesian axes. Here the # native coordinate system ('data') is cartesian, so you need to # specify the xycoords and textcoords as 'polar' if you want to # use (theta, radius) diff -Nru matplotlib-1.1.1/examples/pylab_examples/anscombe.py matplotlib-1.2.0/examples/pylab_examples/anscombe.py --- matplotlib-1.1.1/examples/pylab_examples/anscombe.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/anscombe.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,6 @@ #!/usr/bin/env python + +from __future__ import print_function """ Edward Tufte uses this example from Anscombe to show 4 datasets of x and y that have the same mean, standard deviation, and regression @@ -38,7 +40,7 @@ subplot(223) plot(x,y3,'ks', xfit, fit(xfit), 'r-', lw=2) axis([2,20,2,14]) -text(3,12, 'IIII', fontsize=20) +text(3,12, 'III', fontsize=20) setp(gca(), yticks=(4,8,12), xticks=(0,10,20)) subplot(224) @@ -52,6 +54,6 @@ #verify the stats pairs = (x,y1), (x,y2), (x,y3), (x4,y4) for x,y in pairs: - print 'mean=%1.2f, std=%1.2f, r=%1.2f'%(mean(y), std(y), corrcoef(x,y)[0][1]) + print ('mean=%1.2f, std=%1.2f, r=%1.2f'%(mean(y), std(y), corrcoef(x,y)[0][1])) show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/arrow_demo.py matplotlib-1.2.0/examples/pylab_examples/arrow_demo.py --- matplotlib-1.1.1/examples/pylab_examples/arrow_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/arrow_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -199,7 +199,7 @@ elif where == 'center': orig_position = array([[length/2.0, 3*max_arrow_width]]) else: - raise ValueError, "Got unknown position parameter %s" % where + raise ValueError("Got unknown position parameter %s" % where) diff -Nru matplotlib-1.1.1/examples/pylab_examples/arrow_simple_demo.py matplotlib-1.2.0/examples/pylab_examples/arrow_simple_demo.py --- matplotlib-1.1.1/examples/pylab_examples/arrow_simple_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/arrow_simple_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,5 @@ +import matplotlib.pyplot as plt + +ax = plt.axes() +ax.arrow(0, 0, 0.5, 0.5, head_width=0.05, head_length=0.1, fc='k', ec='k') +plt.show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/axes_zoom_effect.py matplotlib-1.2.0/examples/pylab_examples/axes_zoom_effect.py --- matplotlib-1.1.1/examples/pylab_examples/axes_zoom_effect.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/axes_zoom_effect.py 2012-10-31 00:11:13.000000000 +0000 @@ -30,7 +30,7 @@ def zoom_effect01(ax1, ax2, xmin, xmax, **kwargs): - u""" + """ ax1 : the main axes ax1 : the zoomed axes (xmin,xmax) : the limits of the colored area in both plot axes. @@ -68,7 +68,7 @@ def zoom_effect02(ax1, ax2, **kwargs): - u""" + """ ax1 : the main axes ax1 : the zoomed axes diff -Nru matplotlib-1.1.1/examples/pylab_examples/axhspan_demo.py matplotlib-1.2.0/examples/pylab_examples/axhspan_demo.py --- matplotlib-1.1.1/examples/pylab_examples/axhspan_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/axhspan_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -14,7 +14,7 @@ # draw a default vline at x=1 that spans the yrange l = plt.axvline(x=1) -# draw a thick blue vline at x=0 that spans the the upper quadrant of +# draw a thick blue vline at x=0 that spans the upper quadrant of # the yrange l = plt.axvline(x=0, ymin=0.75, linewidth=4, color='b') diff -Nru matplotlib-1.1.1/examples/pylab_examples/boxplot_demo2.py matplotlib-1.2.0/examples/pylab_examples/boxplot_demo2.py --- matplotlib-1.1.1/examples/pylab_examples/boxplot_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/boxplot_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -80,7 +80,7 @@ medianY.append(med.get_ydata()[j]) plt.plot(medianX, medianY, 'k') medians[i] = medianY[0] - # Finally, overplot the sample averages, with horixzontal alignment + # Finally, overplot the sample averages, with horizontal alignment # in the center of each box plt.plot([np.average(med.get_xdata())], [np.average(data[i])], color='w', marker='*', markeredgecolor='k') diff -Nru matplotlib-1.1.1/examples/pylab_examples/boxplot_demo3.py matplotlib-1.2.0/examples/pylab_examples/boxplot_demo3.py --- matplotlib-1.1.1/examples/pylab_examples/boxplot_demo3.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/boxplot_demo3.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,26 +2,48 @@ import matplotlib.transforms as mtransforms import numpy as np +def fakeBootStrapper(n): + ''' + This is just a placeholder for the user's method of + bootstrapping the median and its confidence intervals. + + Returns an arbitrary median and confidence intervals + packed into a tuple + ''' + if n == 1: + med = 0.1 + CI = (-0.25, 0.25) + else: + med = 0.2 + CI = (-0.35, 0.50) + + return med, CI + + + np.random.seed(2) inc = 0.1 -e1 = np.random.uniform(0,1, size=(500,)) -e2 = np.random.uniform(0,1, size=(500,)) -e3 = np.random.uniform(0,1 + inc, size=(500,)) -e4 = np.random.uniform(0,1 + 2*inc, size=(500,)) +e1 = np.random.normal(0, 1, size=(500,)) +e2 = np.random.normal(0, 1, size=(500,)) +e3 = np.random.normal(0, 1 + inc, size=(500,)) +e4 = np.random.normal(0, 1 + 2*inc, size=(500,)) treatments = [e1,e2,e3,e4] +med1, CI1 = fakeBootStrapper(1) +med2, CI2 = fakeBootStrapper(2) +medians = [None, None, med1, med2] +conf_intervals = [None, None, CI1, CI2] fig = plt.figure() ax = fig.add_subplot(111) pos = np.array(range(len(treatments)))+1 -bp = ax.boxplot( treatments, sym='k+', patch_artist=True, - positions=pos, notch=1, bootstrap=5000 ) -text_transform= mtransforms.blended_transform_factory(ax.transData, - ax.transAxes) +bp = ax.boxplot(treatments, sym='k+', positions=pos, + notch=1, bootstrap=5000, + usermedians=medians, + conf_intervals=conf_intervals) + ax.set_xlabel('treatment') ax.set_ylabel('response') -ax.set_ylim(-0.2, 1.4) plt.setp(bp['whiskers'], color='k', linestyle='-' ) plt.setp(bp['fliers'], markersize=3.0) -fig.subplots_adjust(right=0.99,top=0.99) plt.show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/centered_ticklabels.py matplotlib-1.2.0/examples/pylab_examples/centered_ticklabels.py --- matplotlib-1.1.1/examples/pylab_examples/centered_ticklabels.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/centered_ticklabels.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,10 @@ # sometimes it is nice to have ticklabels centered. mpl currently # associates a label with a tick, and the label can be aligned -# 'center', 'feft', or 'right' using the horizontal alignment property: +# 'center', 'left', or 'right' using the horizontal alignment property: # # # for label in ax.xaxis.get_xticklabels(): -# label.set_horizntal_alignment('right') +# label.set_horizontalalignment('right') # # # but this doesn't help center the label between ticks. One solution @@ -21,7 +21,7 @@ import matplotlib.pyplot as plt # load some financial data; apple's stock price -fh = cbook.get_sample_data('aapl.npy') +fh = cbook.get_sample_data('aapl.npy.gz') r = np.load(fh); fh.close() r = r[-250:] # get the last 250 days diff -Nru matplotlib-1.1.1/examples/pylab_examples/colorbar_tick_labelling_demo.py matplotlib-1.2.0/examples/pylab_examples/colorbar_tick_labelling_demo.py --- matplotlib-1.1.1/examples/pylab_examples/colorbar_tick_labelling_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/colorbar_tick_labelling_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -5,7 +5,7 @@ import matplotlib.pyplot as plt import numpy as np - +from matplotlib import cm from numpy.random import randn # Make plot with vertical (default) colorbar @@ -14,7 +14,7 @@ data = np.clip(randn(250, 250), -1, 1) -cax = ax.imshow(data, interpolation='nearest') +cax = ax.imshow(data, interpolation='nearest', cmap=cm.coolwarm) ax.set_title('Gaussian noise with vertical colorbar') # Add colorbar, make sure to specify tick locations to match desired ticklabels @@ -27,7 +27,7 @@ data = np.clip(randn(250, 250), -1, 1) -cax = ax.imshow(data, interpolation='nearest') +cax = ax.imshow(data, interpolation='nearest', cmap=cm.afmhot) ax.set_title('Gaussian noise with horizontal colorbar') cbar = fig.colorbar(cax, ticks=[-1, 0, 1], orientation='horizontal') diff -Nru matplotlib-1.1.1/examples/pylab_examples/contour_demo.py matplotlib-1.2.0/examples/pylab_examples/contour_demo.py --- matplotlib-1.1.1/examples/pylab_examples/contour_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/contour_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -35,6 +35,16 @@ plt.title('Simplest default with labels') +# contour labels can be placed manually by providing list of positions +# (in data coordinate). See ginput_manual_clabel.py for interactive +# placement. +plt.figure() +CS = plt.contour(X, Y, Z) +manual_locations = [(-1, -1.4), (-0.62, -0.7), (-2, 0.5), (1.7, 1.2), (2.0, 1.4), (2.4, 1.7)] +plt.clabel(CS, inline=1, fontsize=10, manual=manual_locations) +plt.title('labels at selected locations') + + # You can force all the contours to be the same color. plt.figure() CS = plt.contour(X, Y, Z, 6, diff -Nru matplotlib-1.1.1/examples/pylab_examples/contour_image.py matplotlib-1.2.0/examples/pylab_examples/contour_image.py --- matplotlib-1.1.1/examples/pylab_examples/contour_image.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/contour_image.py 2012-10-31 00:11:13.000000000 +0000 @@ -26,13 +26,17 @@ levels = arange(-2.0, 1.601, 0.4) # Boost the upper limit to avoid truncation # errors. +norm = cm.colors.Normalize(vmax=abs(Z).max(), vmin=-abs(Z).max()) +cmap = cm.PRGn + figure() subplot(2,2,1) cset1 = contourf(X, Y, Z, levels, - cmap=cm.get_cmap('jet', len(levels)-1), + cmap=cm.get_cmap(cmap, len(levels)-1), + norm=norm, ) # It is not necessary, but for the colormap, we need only the # number of levels minus 1. To avoid discretization error, use @@ -65,7 +69,7 @@ subplot(2,2,2) -imshow(Z, extent=extent) +imshow(Z, extent=extent, cmap=cmap, norm=norm) v = axis() contour(Z, levels, hold='on', colors = 'k', origin='upper', extent=extent) @@ -74,7 +78,7 @@ subplot(2,2,3) -imshow(Z, origin='lower', extent=extent) +imshow(Z, origin='lower', extent=extent, cmap=cmap, norm=norm) v = axis() contour(Z, levels, hold='on', colors = 'k', origin='lower', extent=extent) @@ -89,7 +93,7 @@ # This is intentional. The Z values are defined at the center of each # image pixel (each color block on the following subplot), so the # domain that is contoured does not extend beyond these pixel centers. -im = imshow(Z, interpolation='nearest', extent=extent) +im = imshow(Z, interpolation='nearest', extent=extent, cmap=cmap, norm=norm) v = axis() contour(Z, levels, hold='on', colors = 'k', origin='image', extent=extent) diff -Nru matplotlib-1.1.1/examples/pylab_examples/contour_label_demo.py matplotlib-1.2.0/examples/pylab_examples/contour_label_demo.py --- matplotlib-1.1.1/examples/pylab_examples/contour_label_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/contour_label_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -50,7 +50,11 @@ CS.levels = [nf(val) for val in CS.levels ] # Label levels with specially formatted floats -plt.clabel(CS, CS.levels, inline=True, fmt='%r %%', fontsize=10) +if plt.rcParams["text.usetex"]: + fmt = r'%r \%%' +else: + fmt = '%r %%' +plt.clabel(CS, CS.levels, inline=True, fmt=fmt, fontsize=10) ################################################## # Label contours with arbitrary strings using a diff -Nru matplotlib-1.1.1/examples/pylab_examples/contourf_demo.py matplotlib-1.2.0/examples/pylab_examples/contourf_demo.py --- matplotlib-1.1.1/examples/pylab_examples/contourf_demo.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/contourf_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,39 +1,41 @@ #!/usr/bin/env python -from pylab import * +import numpy as np +import matplotlib.pyplot as plt + origin = 'lower' #origin = 'upper' delta = 0.025 -x = y = arange(-3.0, 3.01, delta) -X, Y = meshgrid(x, y) -Z1 = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) -Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1) +x = y = np.arange(-3.0, 3.01, delta) +X, Y = np.meshgrid(x, y) +Z1 = plt.mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) +Z2 = plt.mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1) Z = 10 * (Z1 - Z2) nr, nc = Z.shape # put NaNs in one corner: -Z[-nr//6:, -nc//6:] = nan +Z[-nr//6:, -nc//6:] = np.nan # contourf will convert these to masked -Z = ma.array(Z) +Z = np.ma.array(Z) # mask another corner: -Z[:nr//6, :nc//6] = ma.masked +Z[:nr//6, :nc//6] = np.ma.masked # mask a circle in the middle: -interior = sqrt((X**2) + (Y**2)) < 0.5 -Z[interior] = ma.masked +interior = np.sqrt((X**2) + (Y**2)) < 0.5 +Z[interior] = np.ma.masked # We are using automatic selection of contour levels; # this is usually not such a good idea, because they don't # occur on nice boundaries, but we do it here for purposes # of illustration. -CS = contourf(X, Y, Z, 10, # [-1, -0.1, 0, 0.1], +CS = plt.contourf(X, Y, Z, 10, # [-1, -0.1, 0, 0.1], #alpha=0.5, - cmap=cm.bone, + cmap=plt.cm.bone, origin=origin) # Note that in the following, we explicitly pass in a subset of @@ -41,28 +43,28 @@ # We could pass in additional levels to provide extra resolution, # or leave out the levels kwarg to use all of the original levels. -CS2 = contour(CS, levels=CS.levels[::2], +CS2 = plt.contour(CS, levels=CS.levels[::2], colors = 'r', origin=origin, hold='on') -title('Nonsense (3 masked regions)') -xlabel('word length anomaly') -ylabel('sentence length anomaly') +plt.title('Nonsense (3 masked regions)') +plt.xlabel('word length anomaly') +plt.ylabel('sentence length anomaly') # Make a colorbar for the ContourSet returned by the contourf call. -cbar = colorbar(CS) +cbar = plt.colorbar(CS) cbar.ax.set_ylabel('verbosity coefficient') # Add the contour line levels to the colorbar cbar.add_lines(CS2) -figure() +plt.figure() # Now make a contour plot with the levels specified, # and with the colormap generated automatically from a list # of colors. levels = [-1.5, -1, -0.5, 0, 0.5, 1] -CS3 = contourf(X, Y, Z, levels, +CS3 = plt.contourf(X, Y, Z, levels, colors = ('r', 'g', 'b'), origin=origin, extend='both') @@ -72,16 +74,34 @@ CS3.cmap.set_under('yellow') CS3.cmap.set_over('cyan') -CS4 = contour(X, Y, Z, levels, +CS4 = plt.contour(X, Y, Z, levels, colors = ('k',), linewidths = (3,), origin = origin) -title('Listed colors (3 masked regions)') -clabel(CS4, fmt = '%2.1f', colors = 'w', fontsize=14) +plt.title('Listed colors (3 masked regions)') +plt.clabel(CS4, fmt = '%2.1f', colors = 'w', fontsize=14) # Notice that the colorbar command gets all the information it # needs from the ContourSet object, CS3. -colorbar(CS3) +plt.colorbar(CS3) + +# Illustrate all 4 possible "extend" settings: +extends = ["neither", "both", "min", "max"] +cmap = plt.cm.get_cmap("winter") +cmap.set_under("magenta") +cmap.set_over("yellow") +# Note: contouring simply excludes masked or nan regions, so +# instead of using the "bad" colormap value for them, it draws +# nothing at all in them. Therefore the following would have +# no effect: +#cmap.set_bad("red") + +fig, axs = plt.subplots(2,2) +for ax, extend in zip(axs.ravel(), extends): + cs = ax.contourf(X, Y, Z, levels, cmap=cmap, extend=extend, origin=origin) + fig.colorbar(cs, ax=ax, shrink=0.9) + ax.set_title("extend = %s" % extend) + ax.locator_params(nbins=4) -show() +plt.show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/contourf_hatching.py matplotlib-1.2.0/examples/pylab_examples/contourf_hatching.py --- matplotlib-1.1.1/examples/pylab_examples/contourf_hatching.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/contourf_hatching.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,45 @@ +import matplotlib.pyplot as plt +import numpy as np + + +# invent some numbers, turning the x and y arrays into simple +# 2d arrays, which make combining them together easier. +x = np.linspace(-3, 5, 150).reshape(1, -1) +y = np.linspace(-3, 5, 120).reshape(-1, 1) +z = np.cos(x) + np.sin(y) + +# we no longer need x and y to be 2 dimensional, so flatten them. +x, y = x.flatten(), y.flatten() + + +# --------------------------------------------- +# | Plot #1 | +# --------------------------------------------- +# the simplest hatched plot with a colorbar +fig = plt.figure() +cs = plt.contourf(x, y, z, hatches=['-', '/', '\\', '//'], + cmap=plt.get_cmap('gray'), + extend='both', alpha=0.5 + ) +plt.colorbar() + + +# --------------------------------------------- +# | Plot #2 | +# --------------------------------------------- +# a plot of hatches without color with a legend +plt.figure() +n_levels = 6 +plt.contour(x, y, z, n_levels, colors='black', linestyles='-') +cs = plt.contourf(x, y, z, n_levels, colors='none', + hatches=['.', '/', '\\', None, '\\\\', '*'], + extend='lower' + ) + +# create a legend for the contour set +artists, labels = cs.legend_elements() +plt.legend(artists, labels, handleheight=2) + + + +plt.show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/contourf_log.py matplotlib-1.2.0/examples/pylab_examples/contourf_log.py --- matplotlib-1.1.1/examples/pylab_examples/contourf_log.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/contourf_log.py 2012-10-31 00:11:13.000000000 +0000 @@ -5,7 +5,7 @@ from matplotlib import pyplot as P import numpy as np from numpy import ma -from matplotlib import colors, ticker +from matplotlib import colors, ticker, cm from matplotlib.mlab import bivariate_normal N = 100 @@ -30,7 +30,7 @@ # Automatic selection of levels works; setting the # log locator tells contourf to use a log scale: -cs = P.contourf(X, Y, z, locator=ticker.LogLocator()) +cs = P.contourf(X, Y, z, locator=ticker.LogLocator(), cmap=cm.PuBu_r) # Alternatively, you can manually set the levels # and the norm: diff -Nru matplotlib-1.1.1/examples/pylab_examples/coords_demo.py matplotlib-1.2.0/examples/pylab_examples/coords_demo.py --- matplotlib-1.1.1/examples/pylab_examples/coords_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/coords_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,8 +1,10 @@ #!/usr/bin/env python + """ An example of how to interact with the plotting canvas by connecting to move and click events """ +from __future__ import print_function import sys from pylab import * @@ -18,20 +20,20 @@ if event.inaxes: ax = event.inaxes # the axes instance - print 'data coords', event.xdata, event.ydata + print ('data coords %f %f' % (event.xdata, event.ydata)) def on_click(event): # get the x and y coords, flip y from top to bottom x, y = event.x, event.y if event.button==1: if event.inaxes is not None: - print 'data coords', event.xdata, event.ydata + print ('data coords %f %f' % (event.xdata, event.ydata)) binding_id = connect('motion_notify_event', on_move) connect('button_press_event', on_click) if "test_disconnect" in sys.argv: - print "disconnecting console coordinate printout..." + print ("disconnecting console coordinate printout...") disconnect(binding_id) show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/cursor_demo.py matplotlib-1.2.0/examples/pylab_examples/cursor_demo.py --- matplotlib-1.1.1/examples/pylab_examples/cursor_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/cursor_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,6 @@ #!/usr/bin/env python # -*- noplot -*- + """ This example shows how to use matplotlib to provide a data cursor. It @@ -9,6 +10,7 @@ Faster cursoring is possible using native GUI drawing, as in wxcursor_demo.py """ +from __future__ import print_function from pylab import * @@ -61,7 +63,7 @@ self.ly.set_xdata(x ) self.txt.set_text( 'x=%1.2f, y=%1.2f'%(x,y) ) - print 'x=%1.2f, y=%1.2f'%(x,y) + print ('x=%1.2f, y=%1.2f'%(x,y)) draw() t = arange(0.0, 1.0, 0.01) diff -Nru matplotlib-1.1.1/examples/pylab_examples/custom_cmap.py matplotlib-1.2.0/examples/pylab_examples/custom_cmap.py --- matplotlib-1.1.1/examples/pylab_examples/custom_cmap.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/custom_cmap.py 2012-10-31 00:11:13.000000000 +0000 @@ -103,6 +103,16 @@ (1.0, 0.0, 0.0)) } +# Make a modified version of cdict3 with some transparency +# in the middle of the range. +cdict4 = cdict3.copy() +cdict4['alpha'] = ((0.0, 1.0, 1.0), + # (0.25,1.0, 1.0), + (0.5, 0.3, 0.3), + # (0.75,1.0, 1.0), + (1.0, 1.0, 1.0)) + + # Now we will use this example to illustrate 3 ways of # handling custom colormaps. # First, the most direct and explicit: @@ -121,20 +131,27 @@ # leave everything to register_cmap: plt.register_cmap(name='BlueRed3', data=cdict3) # optional lut kwarg +plt.register_cmap(name='BlueRedAlpha', data=cdict4) + +# Make some illustrative fake data: x = np.arange(0, np.pi, 0.1) y = np.arange(0, 2*np.pi, 0.1) X, Y = np.meshgrid(x,y) -Z = np.cos(X) * np.sin(Y) +Z = np.cos(X) * np.sin(Y) * 10 + +# Make the figure: -plt.figure(figsize=(10,4)) -plt.subplots_adjust(wspace=0.3) +plt.figure(figsize=(6,9)) +plt.subplots_adjust(left=0.02, bottom=0.06, right=0.95, top=0.94, wspace=0.05) -plt.subplot(1,3,1) +# Make 4 subplots: + +plt.subplot(2,2,1) plt.imshow(Z, interpolation='nearest', cmap=blue_red1) plt.colorbar() -plt.subplot(1,3,2) +plt.subplot(2,2,2) cmap = plt.get_cmap('BlueRed2') plt.imshow(Z, interpolation='nearest', cmap=cmap) plt.colorbar() @@ -145,24 +162,32 @@ plt.rcParams['image.cmap'] = 'BlueRed3' -# Also see below for an alternative, particularly for -# interactive use. - -plt.subplot(1,3,3) +plt.subplot(2,2,3) plt.imshow(Z, interpolation='nearest') plt.colorbar() +plt.title("Alpha = 1") -# Or as yet another variation, we could replace the rcParams +# Or as yet another variation, we can replace the rcParams # specification *before* the imshow with the following *after* -# imshow: -# -# plt.set_cmap('BlueRed3') -# +# imshow. # This sets the new default *and* sets the colormap of the last # image-like item plotted via pyplot, if any. +# +plt.subplot(2,2,4) +# Draw a line with low zorder so it will be behind the image. +plt.plot([0, 10*np.pi], [0, 20*np.pi], color='c', lw=20, zorder=-1) + +plt.imshow(Z, interpolation='nearest') +plt.colorbar() + +# Here it is: changing the colormap for the current image and its +# colorbar after they have been plotted. +plt.set_cmap('BlueRedAlpha') +plt.title("Varying alpha") +# -plt.suptitle('Custom Blue-Red colormaps') +plt.suptitle('Custom Blue-Red colormaps', fontsize=16) plt.show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/custom_figure_class.py matplotlib-1.2.0/examples/pylab_examples/custom_figure_class.py --- matplotlib-1.1.1/examples/pylab_examples/custom_figure_class.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/custom_figure_class.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,5 @@ """ -You can pass a custom Figure constructor to figure if youy want to derive from the default Figure. This simple example creates a figure with a figure title +You can pass a custom Figure constructor to figure if you want to derive from the default Figure. This simple example creates a figure with a figure title """ from matplotlib.pyplot import figure, show from matplotlib.figure import Figure diff -Nru matplotlib-1.1.1/examples/pylab_examples/custom_ticker1.py matplotlib-1.2.0/examples/pylab_examples/custom_ticker1.py --- matplotlib-1.1.1/examples/pylab_examples/custom_ticker1.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/custom_ticker1.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,9 @@ #!/usr/bin/env python """ -The new ticker code was designed to explicity support user customized +The new ticker code was designed to explicitly support user customized ticking. The documentation -http://matplotlib.sourceforge.net/matplotlib.ticker.html details this +http://matplotlib.org/matplotlib.ticker.html details this process. That code defines a lot of preset tickers but was primarily designed to be user extensible. diff -Nru matplotlib-1.1.1/examples/pylab_examples/customize_rc.py matplotlib-1.2.0/examples/pylab_examples/customize_rc.py --- matplotlib-1.1.1/examples/pylab_examples/customize_rc.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/customize_rc.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,6 @@ """ -I'm not trying to make a good liking figure here, but just to show +I'm not trying to make a good looking figure here, but just to show some examples of customizing rc params on the fly If you like to work interactively, and need to create different sets @@ -36,7 +36,7 @@ rc('xtick.major', size=5, pad=7) rc('xtick', labelsize=15) -# using aliases for color, linestyle and linewith; gray, solid, thick +# using aliases for color, linestyle and linewidth; gray, solid, thick rc('grid', c='0.5', ls='-', lw=5) rc('lines', lw=2, color='g') subplot(312) diff -Nru matplotlib-1.1.1/examples/pylab_examples/dashpointlabel.py matplotlib-1.2.0/examples/pylab_examples/dashpointlabel.py --- matplotlib-1.1.1/examples/pylab_examples/dashpointlabel.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/dashpointlabel.py 2012-10-31 00:11:13.000000000 +0000 @@ -21,7 +21,7 @@ (x,y) = zip(*DATA) ax.plot(x, y, marker='o') -for i in xrange(len(DATA)): +for i in range(len(DATA)): (x,y) = DATA[i] (dd, dl, r, dr, dp) = dash_style[i] #print 'dashlen call', dl diff -Nru matplotlib-1.1.1/examples/pylab_examples/data_helper.py matplotlib-1.2.0/examples/pylab_examples/data_helper.py --- matplotlib-1.1.1/examples/pylab_examples/data_helper.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/data_helper.py 2012-10-31 00:11:13.000000000 +0000 @@ -11,13 +11,13 @@ """ ticker1, ticker2 = 'INTC', 'AAPL' - file1 = cbook.get_sample_data('INTC.dat', asfileobj=False) - file2 = cbook.get_sample_data('AAPL.dat', asfileobj=False) - M1 = fromstring( file(file1, 'rb').read(), ' 1: + fontname = sys.argv[1] +else: + fontname = os.path.join(matplotlib.get_data_path(), + 'fonts', 'ttf', 'Vera.ttf') + font = FT2Font(fontname) -codes = font.get_charmap().items() +codes = list(font.get_charmap().items()) codes.sort() # a 16,16 array of character strings -chars = [ ['' for c in range(16)] for r in range(16)] -colors = [ [(0.95,0.95,0.95) for c in range(16)] for r in range(16)] +chars = [['' for c in range(16)] for r in range(16)] +colors = [[(0.95, 0.95, 0.95) for c in range(16)] for r in range(16)] -figure(figsize=(8,4),dpi=120) +figure(figsize=(8, 4), dpi=120) for ccode, glyphind in codes: - if ccode>=256: continue - r,c = divmod(ccode,16) + if ccode >= 256: + continue + r, c = divmod(ccode, 16) s = unichr(ccode) chars[r][c] = s - - -lightgrn = (0.5,0.8,0.5) +lightgrn = (0.5, 0.8, 0.5) title(fontname) tab = table(cellText=chars, rowLabels=labelr, @@ -50,7 +64,7 @@ for key, cell in tab.get_celld().items(): row, col = key - if row>0 and col>0: - cell.set_text_props(fontproperties=FontProperties(fname=sys.argv[1])) + if row > 0 and col > 0: + cell.set_text_props(fontproperties=FontProperties(fname=fontname)) axis('off') show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/ganged_plots.py matplotlib-1.2.0/examples/pylab_examples/ganged_plots.py --- matplotlib-1.1.1/examples/pylab_examples/ganged_plots.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/ganged_plots.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,7 @@ #!/usr/bin/env python """ To create plots that share a common axes (visually) you can set the -hspace bewtween the subplots close to zero (do not use zero itself). +hspace between the subplots close to zero (do not use zero itself). Normally you'll want to turn off the tick labels on all but one of the axes. diff -Nru matplotlib-1.1.1/examples/pylab_examples/ginput_demo.py matplotlib-1.2.0/examples/pylab_examples/ginput_demo.py --- matplotlib-1.1.1/examples/pylab_examples/ginput_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/ginput_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,11 @@ # -*- noplot -*- +from __future__ import print_function + from pylab import arange, plot, sin, ginput, show t = arange(10) plot(t, sin(t)) -print "Please click" +print("Please click") x = ginput(3) -print "clicked",x +print("clicked",x) show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/ginput_manual_clabel.py matplotlib-1.2.0/examples/pylab_examples/ginput_manual_clabel.py --- matplotlib-1.1.1/examples/pylab_examples/ginput_manual_clabel.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/ginput_manual_clabel.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python # -*- noplot -*- + +from __future__ import print_function """ This provides examples of uses of interactive functions, such as ginput, waitforbuttonpress and manual clabel placement. @@ -18,7 +20,7 @@ import matplotlib.pyplot as plt def tellme(s): - print s + print(s) plt.title(s,fontsize=16) plt.draw() diff -Nru matplotlib-1.1.1/examples/pylab_examples/griddata_demo.py matplotlib-1.2.0/examples/pylab_examples/griddata_demo.py --- matplotlib-1.1.1/examples/pylab_examples/griddata_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/griddata_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -16,7 +16,8 @@ zi = griddata(x,y,z,xi,yi,interp='linear') # contour the gridded data, plotting dots at the nonuniform data points. CS = plt.contour(xi,yi,zi,15,linewidths=0.5,colors='k') -CS = plt.contourf(xi,yi,zi,15,cmap=plt.cm.jet) +CS = plt.contourf(xi,yi,zi,15,cmap=plt.cm.rainbow, + vmax=abs(zi).max(), vmin=-abs(zi).max()) plt.colorbar() # draw colorbar # plot data points. plt.scatter(x,y,marker='o',c='b',s=5,zorder=10) diff -Nru matplotlib-1.1.1/examples/pylab_examples/hexbin_demo.py matplotlib-1.2.0/examples/pylab_examples/hexbin_demo.py --- matplotlib-1.1.1/examples/pylab_examples/hexbin_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/hexbin_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -6,9 +6,9 @@ """ import numpy as np -import matplotlib.cm as cm -import matplotlib.pyplot as plt +import matplotlib.pyplot as plt +np.random.seed(0) n = 100000 x = np.random.standard_normal(n) y = 2.0 + 3.0 * x + 4.0 * np.random.standard_normal(n) @@ -19,18 +19,17 @@ plt.subplots_adjust(hspace=0.5) plt.subplot(121) -plt.hexbin(x,y, cmap=cm.jet) +plt.hexbin(x,y, cmap=plt.cm.YlOrRd_r) plt.axis([xmin, xmax, ymin, ymax]) plt.title("Hexagon binning") cb = plt.colorbar() cb.set_label('counts') plt.subplot(122) -plt.hexbin(x,y,bins='log', cmap=cm.jet) +plt.hexbin(x,y,bins='log', cmap=plt.cm.YlOrRd_r) plt.axis([xmin, xmax, ymin, ymax]) plt.title("With a log color scale") cb = plt.colorbar() cb.set_label('log10(N)') plt.show() - diff -Nru matplotlib-1.1.1/examples/pylab_examples/hexbin_demo2.py matplotlib-1.2.0/examples/pylab_examples/hexbin_demo2.py --- matplotlib-1.1.1/examples/pylab_examples/hexbin_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/hexbin_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -39,14 +39,15 @@ gridsize=30 plt.subplot(211) -plt.hexbin(x,y, C=z, gridsize=gridsize, marginals=True) +plt.hexbin(x,y, C=z, gridsize=gridsize, marginals=True, cmap=plt.cm.RdBu, + vmax=abs(z).max(), vmin=-abs(z).max()) plt.axis([xmin, xmax, ymin, ymax]) cb = plt.colorbar() cb.set_label('mean value') plt.subplot(212) -plt.hexbin(x,y, gridsize=gridsize) +plt.hexbin(x,y, gridsize=gridsize, cmap=plt.cm.Blues_r) plt.axis([xmin, xmax, ymin, ymax]) cb = plt.colorbar() cb.set_label('N observations') diff -Nru matplotlib-1.1.1/examples/pylab_examples/hist2d_demo.py matplotlib-1.2.0/examples/pylab_examples/hist2d_demo.py --- matplotlib-1.1.1/examples/pylab_examples/hist2d_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/hist2d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,7 @@ +from pylab import * +x = randn(1000) +y = randn(1000)+5 + +#normal distribution center at x=0 and y=5 +hist2d(x,y,bins=40) +show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/hist2d_log_demo.py matplotlib-1.2.0/examples/pylab_examples/hist2d_log_demo.py --- matplotlib-1.1.1/examples/pylab_examples/hist2d_log_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/hist2d_log_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,10 @@ +from matplotlib.colors import LogNorm +from pylab import * + +#normal distribution center at x=0 and y=5 +x = randn(100000) +y = randn(100000)+5 + +hist2d(x, y, bins=40, norm=LogNorm()) +colorbar() +show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/histogram_demo_extended.py matplotlib-1.2.0/examples/pylab_examples/histogram_demo_extended.py --- matplotlib-1.1.1/examples/pylab_examples/histogram_demo_extended.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/histogram_demo_extended.py 2012-10-31 00:11:13.000000000 +0000 @@ -82,7 +82,19 @@ # P.figure() -n, bins, patches = P.hist(x, 10, normed=1, histtype='barstacked') +n, bins, patches = P.hist(x, 10, normed=1, histtype='bar', stacked=True) + +P.show() + +# +# we can also stack using the step histtype +# + +P.figure() + +n, bins, patches = P.hist(x, 10, histtype='step', stacked=True, fill=True) + +P.show() # # finally: make a multiple-histogram of data-sets with different length diff -Nru matplotlib-1.1.1/examples/pylab_examples/histogram_percent_demo.py matplotlib-1.2.0/examples/pylab_examples/histogram_percent_demo.py --- matplotlib-1.1.1/examples/pylab_examples/histogram_percent_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/histogram_percent_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,29 @@ +import matplotlib +from numpy.random import randn +import matplotlib.pyplot as plt +from matplotlib.ticker import FuncFormatter + +def to_percent(y, position): + # Ignore the passed in position. This has the effect of scaling the default + # tick locations. + s = str(100 * y) + + # The percent symbol needs escaping in latex + if matplotlib.rcParams['text.usetex'] == True: + return s + r'$\%$' + else: + return s + '%' + +x = randn(5000) + +# Make a normed histogram. It'll be multiplied by 100 later. +plt.hist(x, bins=50, normed=True) + +# Create the formatter using the function to_percent. This multiplies all the +# default labels by 100, making them all percentages +formatter = FuncFormatter(to_percent) + +# Set the formatter +plt.gca().yaxis.set_major_formatter(formatter) + +plt.show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/image_demo.py matplotlib-1.2.0/examples/pylab_examples/image_demo.py --- matplotlib-1.1.1/examples/pylab_examples/image_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/image_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -11,8 +11,9 @@ Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1) Z = Z2-Z1 # difference of Gaussians -im = plt.imshow(Z, interpolation='bilinear', cmap=cm.gray, - origin='lower', extent=[-3,3,-3,3]) +im = plt.imshow(Z, interpolation='bilinear', cmap=cm.RdYlGn, + origin='lower', extent=[-3,3,-3,3], + vmax=abs(Z).max(), vmin=-abs(Z).max()) plt.show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/image_demo2.py matplotlib-1.2.0/examples/pylab_examples/image_demo2.py --- matplotlib-1.1.1/examples/pylab_examples/image_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/image_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,12 +1,13 @@ #!/usr/bin/env python + +from __future__ import print_function from pylab import * import matplotlib.cbook as cbook w, h = 512, 512 -datafile = cbook.get_sample_data('ct.raw', asfileobj=False) -print 'loading', datafile -s = file(datafile, 'rb').read() +datafile = cbook.get_sample_data('ct.raw.gz', asfileobj=True) +s = datafile.read() A = fromstring(s, uint16).astype(float) A *= 1.0/max(A) A.shape = w, h @@ -33,4 +34,3 @@ setp(gca(), 'xticklabels', []) show() - diff -Nru matplotlib-1.1.1/examples/pylab_examples/image_demo3.py matplotlib-1.2.0/examples/pylab_examples/image_demo3.py --- matplotlib-1.1.1/examples/pylab_examples/image_demo3.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/image_demo3.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,7 +2,7 @@ from pylab import * try: from PIL import Image -except ImportError, exc: +except ImportError: raise SystemExit("PIL must be installed to run this example") import matplotlib.cbook as cbook @@ -15,7 +15,7 @@ figure(figsize=figsize) ax = axes([0,0,1,1], frameon=False) ax.set_axis_off() -im = imshow(lena, origin='lower') +im = imshow(lena) show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/image_nonuniform.py matplotlib-1.2.0/examples/pylab_examples/image_nonuniform.py --- matplotlib-1.1.1/examples/pylab_examples/image_nonuniform.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/image_nonuniform.py 2012-10-31 00:11:13.000000000 +0000 @@ -7,6 +7,7 @@ from matplotlib.pyplot import figure, show import numpy as np from matplotlib.image import NonUniformImage +from matplotlib import cm interp='nearest' @@ -19,7 +20,8 @@ fig = figure() fig.suptitle('NonUniformImage class') ax = fig.add_subplot(221) -im = NonUniformImage(ax, interpolation=interp, extent=(-4,4,-4,4)) +im = NonUniformImage(ax, interpolation=interp, extent=(-4,4,-4,4), + cmap=cm.Purples) im.set_data(x, y, z) ax.images.append(im) ax.set_xlim(-4,4) @@ -27,7 +29,8 @@ ax.set_title(interp) ax = fig.add_subplot(222) -im = NonUniformImage(ax, interpolation=interp, extent=(-64,64,-4,4)) +im = NonUniformImage(ax, interpolation=interp, extent=(-64,64,-4,4), + cmap=cm.Purples) im.set_data(x2, y, z) ax.images.append(im) ax.set_xlim(-64,64) @@ -37,7 +40,8 @@ interp = 'bilinear' ax = fig.add_subplot(223) -im = NonUniformImage(ax, interpolation=interp, extent=(-4,4,-4,4)) +im = NonUniformImage(ax, interpolation=interp, extent=(-4,4,-4,4), + cmap=cm.Purples) im.set_data(x, y, z) ax.images.append(im) ax.set_xlim(-4,4) @@ -45,7 +49,8 @@ ax.set_title(interp) ax = fig.add_subplot(224) -im = NonUniformImage(ax, interpolation=interp, extent=(-64,64,-4,4)) +im = NonUniformImage(ax, interpolation=interp, extent=(-64,64,-4,4), + cmap=cm.Purples) im.set_data(x2, y, z) ax.images.append(im) ax.set_xlim(-64,64) diff -Nru matplotlib-1.1.1/examples/pylab_examples/image_origin.py matplotlib-1.2.0/examples/pylab_examples/image_origin.py --- matplotlib-1.1.1/examples/pylab_examples/image_origin.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/image_origin.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,7 +3,7 @@ You can specify whether images should be plotted with the array origin x[0,0] in the upper left or upper right by using the origin parameter. You can also control the default be setting image.origin in your -matplotlibrc file; see http://matplotlib.sourceforge.net/matplotlibrc +matplotlibrc file; see http://matplotlib.org/matplotlibrc """ from pylab import * diff -Nru matplotlib-1.1.1/examples/pylab_examples/image_slices_viewer.py matplotlib-1.2.0/examples/pylab_examples/image_slices_viewer.py --- matplotlib-1.1.1/examples/pylab_examples/image_slices_viewer.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/image_slices_viewer.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import numpy from matplotlib.pyplot import figure, show @@ -17,7 +18,7 @@ self.update() def onscroll(self, event): - print event.button, event.step + print ("%s %s" % (event.button, event.step)) if event.button=='up': self.ind = numpy.clip(self.ind+1, 0, self.slices-1) else: diff -Nru matplotlib-1.1.1/examples/pylab_examples/integral_demo.py matplotlib-1.2.0/examples/pylab_examples/integral_demo.py --- matplotlib-1.1.1/examples/pylab_examples/integral_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/integral_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -17,7 +17,7 @@ # make the shaded region ix = arange(a, b, 0.01) iy = func(ix) -verts = [(a,0)] + zip(ix,iy) + [(b,0)] +verts = [(a,0)] + list(zip(ix,iy)) + [(b,0)] poly = Polygon(verts, facecolor='0.8', edgecolor='k') ax.add_patch(poly) diff -Nru matplotlib-1.1.1/examples/pylab_examples/line_collection2.py matplotlib-1.2.0/examples/pylab_examples/line_collection2.py --- matplotlib-1.1.1/examples/pylab_examples/line_collection2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/line_collection2.py 2012-10-31 00:11:13.000000000 +0000 @@ -21,7 +21,7 @@ # where onoffseq is an even length tuple of on and off ink in points. # If linestyle is omitted, 'solid' is used # See matplotlib.collections.LineCollection for more information -line_segments = LineCollection([zip(x,y) for y in ys], # Make a sequence of x,y pairs +line_segments = LineCollection([list(zip(x,y)) for y in ys], # Make a sequence of x,y pairs linewidths = (0.5,1,1.5,2), linestyles = 'solid') line_segments.set_array(x) diff -Nru matplotlib-1.1.1/examples/pylab_examples/load_converter.py matplotlib-1.2.0/examples/pylab_examples/load_converter.py --- matplotlib-1.1.1/examples/pylab_examples/load_converter.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/load_converter.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function from matplotlib.dates import strpdate2num #from matplotlib.mlab import load import numpy as np @@ -5,7 +6,7 @@ import matplotlib.cbook as cbook datafile = cbook.get_sample_data('msft.csv', asfileobj=False) -print 'loading', datafile +print('loading', datafile) dates, closes = np.loadtxt( datafile, delimiter=',', diff -Nru matplotlib-1.1.1/examples/pylab_examples/loadrec.py matplotlib-1.2.0/examples/pylab_examples/loadrec.py --- matplotlib-1.1.1/examples/pylab_examples/loadrec.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/loadrec.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,12 +1,13 @@ +from __future__ import print_function from matplotlib import mlab from pylab import figure, show import matplotlib.cbook as cbook datafile = cbook.get_sample_data('msft.csv', asfileobj=False) -print 'loading', datafile +print('loading', datafile) a = mlab.csv2rec(datafile) a.sort() -print a.dtype +print(a.dtype) fig = figure() ax = fig.add_subplot(111) diff -Nru matplotlib-1.1.1/examples/pylab_examples/logo.py matplotlib-1.2.0/examples/pylab_examples/logo.py --- matplotlib-1.1.1/examples/pylab_examples/logo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/logo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,11 +1,13 @@ #!/usr/bin/env python # This file generates the matplotlib web page logo + +from __future__ import print_function from pylab import * import matplotlib.cbook as cbook # convert data to mV datafile = cbook.get_sample_data('membrane.dat', asfileobj=False) -print 'loading', datafile +print('loading', datafile) x = 1000*0.1*fromstring(file(datafile, 'rb').read(), float32) # 0.0005 is the sample interval diff -Nru matplotlib-1.1.1/examples/pylab_examples/major_minor_demo1.py matplotlib-1.2.0/examples/pylab_examples/major_minor_demo1.py --- matplotlib-1.1.1/examples/pylab_examples/major_minor_demo1.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/major_minor_demo1.py 2012-10-31 00:11:13.000000000 +0000 @@ -19,7 +19,7 @@ some base. The FormatStrFormatter uses a string format string (eg '%d' or '%1.2f' or '%1.1f cm' ) to format the tick -The pylab interface grid command chnages the grid settings of the +The pylab interface grid command changes the grid settings of the major ticks of the y and y axis together. If you want to control the grid of the minor ticks for a given axis, use for example diff -Nru matplotlib-1.1.1/examples/pylab_examples/manual_axis.py matplotlib-1.2.0/examples/pylab_examples/manual_axis.py --- matplotlib-1.1.1/examples/pylab_examples/manual_axis.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/manual_axis.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,7 @@ """ The techniques here are no longer required with the new support for spines in matplotlib -- see -http://matplotlib.sourceforge.net/examples/pylab_examples/spine_placement_demo.html. +http://matplotlib.org/examples/pylab_examples/spine_placement_demo.html. This example should be considered deprecated and is left just for demo purposes for folks wanting to make a pseudo-axis @@ -55,4 +55,3 @@ make_yaxis(ax, 0, offset=5, **props) show() - diff -Nru matplotlib-1.1.1/examples/pylab_examples/mathtext_demo.py matplotlib-1.2.0/examples/pylab_examples/mathtext_demo.py --- matplotlib-1.1.1/examples/pylab_examples/mathtext_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/mathtext_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,6 @@ #!/usr/bin/env python """ -Use matplotlib's internal LaTex parser and layout engine. For true +Use matplotlib's internal LaTeX parser and layout engine. For true latex rendering, see the text.usetex option """ import numpy as np diff -Nru matplotlib-1.1.1/examples/pylab_examples/mathtext_examples.py matplotlib-1.2.0/examples/pylab_examples/mathtext_examples.py --- matplotlib-1.1.1/examples/pylab_examples/mathtext_examples.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/mathtext_examples.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import print_function + import os, sys, re import gc @@ -38,7 +40,7 @@ r"$\gamma = \frac{x=\frac{6}{8}}{y} \delta$", r'$\limsup_{x\to\infty}$', r'$\oint^\infty_0$', - r"$f^\prime$", + r"$f^'$", r'$\frac{x_2888}{y}$', r"$\sqrt[3]{\frac{X_2}{Y}}=5$", r"$\sqrt[5]{\prod^\frac{x}{2\pi^2}_\infty}$", diff -Nru matplotlib-1.1.1/examples/pylab_examples/movie_demo.py matplotlib-1.2.0/examples/pylab_examples/movie_demo.py --- matplotlib-1.1.1/examples/pylab_examples/movie_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/movie_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,8 @@ #!/usr/bin/env python # -*- noplot -*- +from __future__ import print_function + import os, sys from pylab import * @@ -11,11 +13,11 @@ cla() imshow(rand(5,5), interpolation='nearest') fname = '_tmp%03d.png'%i - print 'Saving frame', fname + print('Saving frame', fname) savefig(fname) files.append(fname) -print 'Making movie animation.mpg - this make take a while' +print('Making movie animation.mpg - this make take a while') os.system("mencoder 'mf://_tmp*.png' -mf type=png:fps=10 -ovc lavc -lavcopts vcodec=wmv2 -oac copy -o animation.mpg") #os.system("convert _tmp*.png animation.mng") diff -Nru matplotlib-1.1.1/examples/pylab_examples/mri_demo.py matplotlib-1.2.0/examples/pylab_examples/mri_demo.py --- matplotlib-1.1.1/examples/pylab_examples/mri_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/mri_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,14 +1,15 @@ #!/usr/bin/env python + +from __future__ import print_function from pylab import * import matplotlib.cbook as cbook # data are 256x256 16 bit integers -dfile = cbook.get_sample_data('s1045.ima', asfileobj=False) -print 'loading image', dfile -im = np.fromstring(file(dfile, 'rb').read(), np.uint16).astype(float) +dfile = cbook.get_sample_data('s1045.ima.gz') +im = np.fromstring(dfile.read(), np.uint16).astype(float) im.shape = 256, 256 #imshow(im, ColormapJet(256)) -imshow(im, cmap=cm.jet) +imshow(im, cmap=cm.gray) axis('off') show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/mri_with_eeg.py matplotlib-1.2.0/examples/pylab_examples/mri_with_eeg.py --- matplotlib-1.1.1/examples/pylab_examples/mri_with_eeg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/mri_with_eeg.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,10 @@ #!/usr/bin/env python + """ This now uses the imshow command instead of pcolor which *is much faster* """ -from __future__ import division +from __future__ import division, print_function import numpy as np @@ -14,14 +15,13 @@ if 1: # load the data # data are 256x256 16 bit integers - dfile = cbook.get_sample_data('s1045.ima', asfileobj=False) - print 'loading image', dfile - im = np.fromstring(file(dfile, 'rb').read(), np.uint16).astype(float) + dfile = cbook.get_sample_data('s1045.ima.gz') + im = np.fromstring(dfile.read(), np.uint16).astype(float) im.shape = 256, 256 if 1: # plot the MRI in pcolor subplot(221) - imshow(im, cmap=cm.jet) + imshow(im, cmap=cm.gray) axis('off') if 1: # plot the histogram of MRI intensity @@ -40,8 +40,8 @@ numSamples, numRows = 800,4 eegfile = cbook.get_sample_data('eeg.dat', asfileobj=False) - print 'loading eeg', eegfile - data = np.fromstring(file(eegfile, 'rb').read(), float) + print ('loading eeg %s' % eegfile) + data = np.fromstring(open(eegfile, 'rb').read(), float) data.shape = numSamples, numRows t = 10.0 * np.arange(numSamples, dtype=float)/numSamples ticklocs = [] diff -Nru matplotlib-1.1.1/examples/pylab_examples/pcolor_demo.py matplotlib-1.2.0/examples/pylab_examples/pcolor_demo.py --- matplotlib-1.1.1/examples/pylab_examples/pcolor_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/pcolor_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -19,7 +19,7 @@ X,Y = meshgrid(x, y) Z = func3(X, Y) -pcolor(X, Y, Z) +pcolor(X, Y, Z, cmap=cm.RdBu, vmax=abs(Z).max(), vmin=-abs(Z).max()) colorbar() axis([-3,3,-3,3]) diff -Nru matplotlib-1.1.1/examples/pylab_examples/pcolor_demo2.py matplotlib-1.2.0/examples/pylab_examples/pcolor_demo2.py --- matplotlib-1.1.1/examples/pylab_examples/pcolor_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/pcolor_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -20,7 +20,7 @@ ax = subplot(111) -im = imshow(Z, cmap=cm.jet) +im = imshow(Z, cmap=cm.RdBu, vmax=abs(Z).max(), vmin=-abs(Z).max()) #im.set_interpolation('nearest') #im.set_interpolation('bicubic') im.set_interpolation('bilinear') diff -Nru matplotlib-1.1.1/examples/pylab_examples/pcolor_log.py matplotlib-1.2.0/examples/pylab_examples/pcolor_log.py --- matplotlib-1.1.1/examples/pylab_examples/pcolor_log.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/pcolor_log.py 2012-10-31 00:11:13.000000000 +0000 @@ -15,11 +15,11 @@ Z1 = bivariate_normal(X, Y, 0.1, 0.2, 1.0, 1.0) + 0.1*bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) subplot(2,1,1) -pcolor(X, Y, Z1, norm=LogNorm(vmin=Z1.min(), vmax=Z1.max())) +pcolor(X, Y, Z1, norm=LogNorm(vmin=Z1.min(), vmax=Z1.max()), cmap=cm.PuBu_r) colorbar() subplot(2,1,2) -pcolor(X, Y, Z1) +pcolor(X, Y, Z1, cmap=cm.PuBu_r) colorbar() diff -Nru matplotlib-1.1.1/examples/pylab_examples/pie_demo.py matplotlib-1.2.0/examples/pylab_examples/pie_demo.py --- matplotlib-1.1.1/examples/pylab_examples/pie_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/pie_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,10 +3,8 @@ http://matplotlib.sf.net/matplotlib.pylab.html#-pie for the docstring. This example shows a basic pie chart with labels optional features, -like autolabeling the percentage, offsetting a slice with "explode" -and adding a shadow. - -Requires matplotlib0-0.70 or later +like autolabeling the percentage, offsetting a slice with "explode", +adding a shadow, and changing the starting angle. """ from pylab import * @@ -15,11 +13,18 @@ figure(1, figsize=(6,6)) ax = axes([0.1, 0.1, 0.8, 0.8]) +# The slices will be ordered and plotted counter-clockwise. labels = 'Frogs', 'Hogs', 'Dogs', 'Logs' -fracs = [15,30,45, 10] - +fracs = [15, 30, 45, 10] explode=(0, 0.05, 0, 0) -pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%', shadow=True) + +pie(fracs, explode=explode, labels=labels, + autopct='%1.1f%%', shadow=True, startangle=90) + # The default startangle is 0, which would start + # the Frogs slice on the x-axis. With startangle=90, + # everything is rotated counter-clockwise by 90 degrees, + # so the plotting starts on the positive y-axis. + title('Raining Hogs and Dogs', bbox={'facecolor':'0.8', 'pad':5}) show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/pie_demo2.py matplotlib-1.2.0/examples/pylab_examples/pie_demo2.py --- matplotlib-1.1.1/examples/pylab_examples/pie_demo2.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/pie_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,60 @@ +""" +Make a pie charts of varying size - see +http://matplotlib.sf.net/matplotlib.pylab.html#-pie for the docstring. + +This example shows a basic pie charts with labels optional features, +like autolabeling the percentage, offsetting a slice with "explode" +and adding a shadow, in different sizes. + +""" +from pylab import * +from matplotlib.gridspec import GridSpec + +# Some data + +labels = 'Frogs', 'Hogs', 'Dogs', 'Logs' +fracs = [15,30,45, 10] + +explode=(0, 0.05, 0, 0) + +# Make square figures and axes + +the_grid = GridSpec(2, 2) + +figure(1, figsize=(6,6)) + +subplot(the_grid[0, 0]) + +pie(fracs, labels=labels, autopct='%1.1f%%', shadow=True) + +subplot(the_grid[0, 1]) + +pie(fracs, explode=explode, labels=labels, autopct='%.0f%%', shadow=True) + +subplot(the_grid[1, 0]) + +patches, texts, autotexts = pie(fracs, labels=labels, + autopct='%.0f%%', + shadow=True, radius=0.5) + +# Make the labels on the small plot easier to read. +for t in texts: + t.set_size('smaller') +for t in autotexts: + t.set_size('x-small') +autotexts[0].set_color('y') + +subplot(the_grid[1, 1]) + +patches, texts, autotexts = pie(fracs, explode=explode, + labels=labels, autopct='%.0f%%', + shadow=False, radius=0.5) + # Turn off shadow for tiny plot + # with exploded slice. +for t in texts: + t.set_size('smaller') +for t in autotexts: + t.set_size('x-small') +autotexts[0].set_color('y') + +show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/polar_demo.py matplotlib-1.2.0/examples/pylab_examples/polar_demo.py --- matplotlib-1.1.1/examples/pylab_examples/polar_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/polar_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -9,7 +9,7 @@ # PolarAxes) -- other axes plotting functions may work on PolarAxes # but haven't been tested and may need tweaking. # -# you can get get a PolarSubplot instance by doing, for example +# you can get a PolarSubplot instance by doing, for example # # subplot(211, polar=True) # diff -Nru matplotlib-1.1.1/examples/pylab_examples/polar_scatter.py matplotlib-1.2.0/examples/pylab_examples/polar_scatter.py --- matplotlib-1.1.1/examples/pylab_examples/polar_scatter.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/polar_scatter.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,8 +1,8 @@ #!/usr/bin/env python # a polar scatter plot; size increases radially in this example and # color increases with angle (just to verify the symbols are being -# scattered correctlu). In a real example, this would be wasting -# dimensionlaity of the plot +# scattered correctly). In a real example, this would be wasting +# dimensionality of the plot from pylab import * N = 150 @@ -11,8 +11,7 @@ area = 200*r**2*rand(N) colors = theta ax = subplot(111, polar=True) -c = scatter(theta, r, c=colors, s=area) +c = scatter(theta, r, c=colors, s=area, cmap=cm.hsv) c.set_alpha(0.75) - show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/poormans_contour.py matplotlib-1.2.0/examples/pylab_examples/poormans_contour.py --- matplotlib-1.1.1/examples/pylab_examples/poormans_contour.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/poormans_contour.py 2012-10-31 00:11:13.000000000 +0000 @@ -18,9 +18,10 @@ Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1) Z = Z2 - Z1 # difference of Gaussians -cmap = cm.get_cmap('jet', 10) # 10 discrete colors +cmap = cm.get_cmap('PiYG', 11) # 11 discrete colors -im = imshow(Z, cmap=cmap, interpolation='bilinear') +im = imshow(Z, cmap=cmap, interpolation='bilinear', + vmax=abs(Z).max(), vmin=-abs(Z).max()) axis('off') colorbar() diff -Nru matplotlib-1.1.1/examples/pylab_examples/psd_demo2.py matplotlib-1.2.0/examples/pylab_examples/psd_demo2.py --- matplotlib-1.1.1/examples/pylab_examples/psd_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/psd_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -22,7 +22,7 @@ ax2.psd(y, NFFT=len(t), pad_to=len(t)*4, Fs=fs) plt.title('zero padding') -#Plot the PSD with different block sizes, Zero pad to the length of the orignal +#Plot the PSD with different block sizes, Zero pad to the length of the original #data sequence. ax3 = fig.add_subplot(2, 3, 5, sharex=ax2, sharey=ax2) ax3.psd(y, NFFT=len(t), pad_to=len(t), Fs=fs) diff -Nru matplotlib-1.1.1/examples/pylab_examples/pythonic_matplotlib.py matplotlib-1.2.0/examples/pylab_examples/pythonic_matplotlib.py --- matplotlib-1.1.1/examples/pylab_examples/pythonic_matplotlib.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/pythonic_matplotlib.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,7 @@ #!/usr/bin/env python """ Some people prefer to write more pythonic, object oriented, code -rather than use the pylab interface to matplotlib. This example show +rather than use the pylab interface to matplotlib. This example shows you how. Unless you are an application developer, I recommend using part of the diff -Nru matplotlib-1.1.1/examples/pylab_examples/scatter_custom_symbol.py matplotlib-1.2.0/examples/pylab_examples/scatter_custom_symbol.py --- matplotlib-1.1.1/examples/pylab_examples/scatter_custom_symbol.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/scatter_custom_symbol.py 2012-10-31 00:11:13.000000000 +0000 @@ -6,7 +6,7 @@ rx, ry = 3., 1. area = rx * ry * pi theta = arange(0, 2*pi+0.01, 0.1) -verts = zip(rx/area*cos(theta), ry/area*sin(theta)) +verts = list(zip(rx/area*cos(theta), ry/area*sin(theta))) x,y,s,c = rand(4, 30) s*= 10**2. diff -Nru matplotlib-1.1.1/examples/pylab_examples/scatter_profile.py matplotlib-1.2.0/examples/pylab_examples/scatter_profile.py --- matplotlib-1.1.1/examples/pylab_examples/scatter_profile.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/scatter_profile.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,6 @@ #!/usr/bin/env python # -*- noplot -*- + """ N Classic Base renderer Ext renderer 20 0.22 0.14 0.14 @@ -8,15 +9,16 @@ 10000 3.30 1.31 0.53 50000 19.30 6.53 1.98 """ -from pylab import * +from __future__ import print_function +import pylab import time for N in (20,100,1000,10000,50000): tstart = time.time() - x = 0.9*rand(N) - y = 0.9*rand(N) - s = 20*rand(N) - scatter(x,y,s) - print '%d symbols in %1.2f s' % (N, time.time()-tstart) + x = 0.9*pylab.rand(N) + y = 0.9*pylab.rand(N) + s = 20*pylab.rand(N) + pylab.scatter(x,y,s) + print ('%d symbols in %1.2f s' % (N, time.time()-tstart)) diff -Nru matplotlib-1.1.1/examples/pylab_examples/scatter_star_poly.py matplotlib-1.2.0/examples/pylab_examples/scatter_star_poly.py --- matplotlib-1.1.1/examples/pylab_examples/scatter_star_poly.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/scatter_star_poly.py 2012-10-31 00:11:13.000000000 +0000 @@ -12,7 +12,7 @@ plt.subplot(322) plt.scatter(x,y,s=80, c=z, marker=(5,0)) -verts = zip([-1.,1.,1.,-1.],[-1.,-1.,1.,-1.]) +verts = list(zip([-1.,1.,1.,-1.],[-1.,-1.,1.,-1.])) plt.subplot(323) plt.scatter(x,y,s=80, c=z, marker=(verts,0)) # equivalent: diff -Nru matplotlib-1.1.1/examples/pylab_examples/set_and_get.py matplotlib-1.2.0/examples/pylab_examples/set_and_get.py --- matplotlib-1.1.1/examples/pylab_examples/set_and_get.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/set_and_get.py 2012-10-31 00:11:13.000000000 +0000 @@ -21,8 +21,8 @@ >>> setp(line) set operates on a single instance or a list of instances. If you are - in quey mode introspecting the possible values, only the first - instance in the sequnce is used. When actually setting values, all + in query mode introspecting the possible values, only the first + instance in the sequence is used. When actually setting values, all the instances will be set. Eg, suppose you have a list of two lines, the following will make both lines thicker and red @@ -52,7 +52,7 @@ color = b ... long listing skipped ... -Alisases: +Aliases: To reduce keystrokes in interactive mode, a number of properties have short aliases, eg 'lw' for 'linewidth' and 'mec' for @@ -64,6 +64,7 @@ """ +from __future__ import print_function from pylab import * @@ -77,20 +78,20 @@ setp(l2, linewidth=1, color='g') # line2 is thicker and green -print 'Line setters' +print ('Line setters') setp(l1) -print 'Line getters' +print ('Line getters') getp(l1) -print 'Rectangle setters' +print ('Rectangle setters') setp(gca().patch) -print 'Rectangle getters' +print ('Rectangle getters') getp(gca().patch) t = title('Hi mom') -print 'Text setters' +print ('Text setters') setp(t) -print 'Text getters' +print ('Text getters') getp(t) show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/shading_example.py matplotlib-1.2.0/examples/pylab_examples/shading_example.py --- matplotlib-1.1.1/examples/pylab_examples/shading_example.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/shading_example.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,7 +3,7 @@ from matplotlib.colors import LightSource # example showing how to make shaded relief plots -# like mathematica +# like Mathematica # (http://reference.wolfram.com/mathematica/ref/ReliefPlot.html) # or Generic Mapping Tools # (http://gmt.soest.hawaii.edu/gmt/doc/gmt/html/GMT_Docs/node145.html) diff -Nru matplotlib-1.1.1/examples/pylab_examples/simple_plot.py matplotlib-1.2.0/examples/pylab_examples/simple_plot.py --- matplotlib-1.1.1/examples/pylab_examples/simple_plot.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/simple_plot.py 2012-11-01 19:19:04.000000000 +0000 @@ -8,4 +8,5 @@ ylabel('voltage (mV)') title('About as simple as it gets, folks') grid(True) +savefig("test.png") show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/simple_plot_fps.py matplotlib-1.2.0/examples/pylab_examples/simple_plot_fps.py --- matplotlib-1.1.1/examples/pylab_examples/simple_plot_fps.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/simple_plot_fps.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,11 @@ #!/usr/bin/env python + """ Example: simple line plot. Show how to make and save a simple line plot with labels, title and grid """ # -*- noplot -*- +from __future__ import print_function from pylab import * ion() @@ -22,11 +24,11 @@ frames = 100.0 t = time.time() c = time.clock() -for i in xrange(int(frames)): +for i in range(int(frames)): part = i / frames axis([0.0, 1.0 - part, -1.0 + part, 1.0 - part]) wallclock = time.time() - t user = time.clock() - c -print "wallclock:", wallclock -print "user:", user -print "fps:", frames / wallclock +print ("wallclock:", wallclock) +print ("user:", user) +print ("fps:", frames / wallclock) diff -Nru matplotlib-1.1.1/examples/pylab_examples/specgram_demo.py matplotlib-1.2.0/examples/pylab_examples/specgram_demo.py --- matplotlib-1.1.1/examples/pylab_examples/specgram_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/specgram_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -25,5 +25,6 @@ ax1 = subplot(211) plot(t, x) subplot(212, sharex=ax1) -Pxx, freqs, bins, im = specgram(x, NFFT=NFFT, Fs=Fs, noverlap=900) +Pxx, freqs, bins, im = specgram(x, NFFT=NFFT, Fs=Fs, noverlap=900, + cmap=cm.gist_heat) show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/spine_placement_demo.py matplotlib-1.2.0/examples/pylab_examples/spine_placement_demo.py --- matplotlib-1.1.1/examples/pylab_examples/spine_placement_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/spine_placement_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +import sys import matplotlib.pyplot as plt import numpy as np from matplotlib.pyplot import show @@ -8,7 +9,7 @@ ax = fig.add_subplot(1,2,1) ax.set_title('dropped spines') ax.plot(x,y) -for loc, spine in ax.spines.iteritems(): +for loc, spine in ax.spines.items(): if loc in ['left','bottom']: spine.set_position(('outward',10)) # outward by 10 points elif loc in ['right','top']: @@ -80,7 +81,7 @@ # ---------------------------------------------------- def adjust_spines(ax,spines): - for loc, spine in ax.spines.iteritems(): + for loc, spine in ax.spines.items(): if loc in spines: spine.set_position(('outward',10)) # outward by 10 points spine.set_smart_bounds(True) @@ -141,7 +142,10 @@ # x ax.set_xlim((0,2*np.pi)) ax.set_xticks([0,np.pi,2*np.pi]) -pichr = unichr(0x03C0) +if sys.version_info[0] < 3: + pichr = unichr(0x03C0) +else: + pichr = chr(0x03C0) ax.set_xticklabels(['0',pichr,'2 '+pichr]) # y diff -Nru matplotlib-1.1.1/examples/pylab_examples/stackplot_demo.py matplotlib-1.2.0/examples/pylab_examples/stackplot_demo.py --- matplotlib-1.1.1/examples/pylab_examples/stackplot_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/stackplot_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,18 @@ +import numpy as np +from matplotlib import pyplot as plt + +fnx = lambda : np.random.randint(5, 50, 10) +y = np.row_stack((fnx(), fnx(), fnx())) +x = np.arange(10) + +y1, y2, y3 = fnx(), fnx(), fnx() + +fig = plt.figure() +ax = fig.add_subplot(111) +ax.stackplot(x, y) +plt.show() + +fig = plt.figure() +ax = fig.add_subplot(111) +ax.stackplot(x, y1, y2, y3) +plt.show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/stix_fonts_demo.py matplotlib-1.2.0/examples/pylab_examples/stix_fonts_demo.py --- matplotlib-1.1.1/examples/pylab_examples/stix_fonts_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/stix_fonts_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import unicode_literals + import os, sys, re import gc @@ -17,9 +19,6 @@ if sys.maxunicode > 0xffff: s = r'Direct Unicode: $\u23ce \mathrm{\ue0f2 \U0001D538}$' - stests.append( - unicode(s, encoding="unicode_escape") - ) from pylab import * diff -Nru matplotlib-1.1.1/examples/pylab_examples/streamplot_demo.py matplotlib-1.2.0/examples/pylab_examples/streamplot_demo.py --- matplotlib-1.1.1/examples/pylab_examples/streamplot_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/streamplot_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,19 @@ +import numpy as np +import matplotlib.pyplot as plt + +Y, X = np.mgrid[-3:3:100j, -3:3:100j] +U = -1 - X**2 + Y +V = 1 + X - Y**2 +speed = np.sqrt(U*U + V*V) + +plt.streamplot(X, Y, U, V, color=U, linewidth=2, cmap=plt.cm.autumn) +plt.colorbar() + +f, (ax1, ax2) = plt.subplots(ncols=2) +ax1.streamplot(X, Y, U, V, density=[0.5, 1]) + +lw = 5*speed/speed.max() +ax2.streamplot(X, Y, U, V, density=0.6, color='k', linewidth=lw) + +plt.show() + diff -Nru matplotlib-1.1.1/examples/pylab_examples/streamplot_with_mask.py matplotlib-1.2.0/examples/pylab_examples/streamplot_with_mask.py --- matplotlib-1.1.1/examples/pylab_examples/streamplot_with_mask.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/streamplot_with_mask.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,23 @@ +""" +Demonstrate the use of the `streamplot` function using a masked array +and NaN values. +""" +import numpy as np +import matplotlib.pyplot as plt + +w = 3 +Y, X = np.mgrid[-w:w:100j, -w:w:100j] +U = -1 - X**2 + Y +V = 1 + X - Y**2 +speed = np.sqrt(U*U + V*V) + +mask = np.zeros(U.shape, dtype=bool) +mask[40:60, 40:60] = 1 +U = np.ma.array(U, mask=mask) +U[:20, :20] = np.nan + +plt.streamplot(X, Y, U, V, color='r') +plt.imshow(~mask, extent=(-w, w, -w, w), alpha=0.5, interpolation='nearest') + +plt.show() + diff -Nru matplotlib-1.1.1/examples/pylab_examples/subplots_adjust.py matplotlib-1.2.0/examples/pylab_examples/subplots_adjust.py --- matplotlib-1.1.1/examples/pylab_examples/subplots_adjust.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/subplots_adjust.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,9 +2,9 @@ subplot(211) -imshow(rand(100,100)) +imshow(rand(100,100), cmap=cm.BuPu_r) subplot(212) -imshow(rand(100,100)) +imshow(rand(100,100), cmap=cm.BuPu_r) subplots_adjust(bottom=0.1, right=0.8, top=0.9) cax = axes([0.85, 0.1, 0.075, 0.8]) diff -Nru matplotlib-1.1.1/examples/pylab_examples/subplots_demo.py matplotlib-1.2.0/examples/pylab_examples/subplots_demo.py --- matplotlib-1.1.1/examples/pylab_examples/subplots_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/subplots_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -10,8 +10,8 @@ import numpy as np # Simple data to display in various forms -x = np.linspace(0, 2*np.pi, 400) -y = np.sin(x**2) +x = np.linspace(0, 2 * np.pi, 400) +y = np.sin(x ** 2) plt.close('all') @@ -37,25 +37,33 @@ ax1.plot(x, y) ax1.set_title('Sharing both axes') ax2.scatter(x, y) -ax3.scatter(x, 2*y**2-1,color='r') +ax3.scatter(x, 2 * y ** 2 - 1, color='r') # Fine-tune figure; make subplots close to each other and hide x ticks for # all but bottom plot. f.subplots_adjust(hspace=0) plt.setp([a.get_xticklabels() for a in f.axes[:-1]], visible=False) +# row and column sharing +f, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, sharex='col', sharey='row') +ax1.plot(x, y) +ax1.set_title('Sharing x per column, y per row') +ax2.scatter(x, y) +ax3.scatter(x, 2 * y ** 2 - 1, color='r') +ax4.plot(x, 2 * y ** 2 - 1, color='r') + # Four axes, returned as a 2-d array f, axarr = plt.subplots(2, 2) -axarr[0,0].plot(x, y) -axarr[0,0].set_title('Axis [0,0]') -axarr[0,1].scatter(x, y) -axarr[0,1].set_title('Axis [0,1]') -axarr[1,0].plot(x, y**2) -axarr[1,0].set_title('Axis [1,0]') -axarr[1,1].scatter(x, y**2) -axarr[1,1].set_title('Axis [1,1]') +axarr[0, 0].plot(x, y) +axarr[0, 0].set_title('Axis [0,0]') +axarr[0, 1].scatter(x, y) +axarr[0, 1].set_title('Axis [0,1]') +axarr[1, 0].plot(x, y ** 2) +axarr[1, 0].set_title('Axis [1,0]') +axarr[1, 1].scatter(x, y ** 2) +axarr[1, 1].set_title('Axis [1,1]') # Fine-tune figure; hide x ticks for top plots and y ticks for right plots -plt.setp([a.get_xticklabels() for a in axarr[0,:]], visible=False) -plt.setp([a.get_yticklabels() for a in axarr[:,1]], visible=False) +plt.setp([a.get_xticklabels() for a in axarr[0, :]], visible=False) +plt.setp([a.get_yticklabels() for a in axarr[:, 1]], visible=False) # Four polar axes plt.subplots(2, 2, subplot_kw=dict(polar=True)) diff -Nru matplotlib-1.1.1/examples/pylab_examples/table_demo.py matplotlib-1.2.0/examples/pylab_examples/table_demo.py --- matplotlib-1.1.1/examples/pylab_examples/table_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/table_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -71,7 +71,7 @@ cellText = [] width = 0.4 # the width of the bars yoff = array([0.0] * len(colLabels)) # the bottom values for stacked bar chart -for row in xrange(rows): +for row in range(rows): bar(ind, data[row], width, bottom=yoff, color=colours[row]) yoff = yoff + data[row] cellText.append(['%1.1f' % (x/1000.0) for x in yoff]) diff -Nru matplotlib-1.1.1/examples/pylab_examples/tex_unicode_demo.py matplotlib-1.2.0/examples/pylab_examples/tex_unicode_demo.py --- matplotlib-1.1.1/examples/pylab_examples/tex_unicode_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/tex_unicode_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -4,12 +4,13 @@ This demo is tex_demo.py modified to have unicode. See that file for more information. """ -from matplotlib import rcParams -rcParams['text.usetex']=True -rcParams['text.latex.unicode']=True +from __future__ import unicode_literals +import matplotlib as mpl +mpl.rcParams['text.usetex']=True +mpl.rcParams['text.latex.unicode']=True from numpy import arange, cos, pi -from matplotlib.pyplot import figure, axes, plot, xlabel, ylabel, title, \ - grid, savefig, show +from matplotlib.pyplot import (figure, axes, plot, xlabel, ylabel, title, + grid, savefig, show) figure(1, figsize=(6,4)) ax = axes([0.1, 0.1, 0.8, 0.7]) @@ -18,7 +19,7 @@ plot(t, s) xlabel(r'\textbf{time (s)}') -ylabel(ur'\textit{Velocity (\u00B0/sec)}', fontsize=16) +ylabel(r'\textit{Velocity (\u00B0/sec)}', fontsize=16) title(r"\TeX\ is Number $\displaystyle\sum_{n=1}^\infty\frac{-e^{i\pi}}{2^n}$!", fontsize=16, color='r') grid(True) diff -Nru matplotlib-1.1.1/examples/pylab_examples/text_rotation.py matplotlib-1.2.0/examples/pylab_examples/text_rotation.py --- matplotlib-1.1.1/examples/pylab_examples/text_rotation.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/text_rotation.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,6 @@ #!/usr/bin/env python """ -The way matplotlib does text layout is counter-intuituve to some, so +The way matplotlib does text layout is counter-intuitive to some, so this example is designed to make it a little clearer. The text is aligned by it's bounding box (the rectangular box that surrounds the ink rectangle). The order of operations is basically rotation then diff -Nru matplotlib-1.1.1/examples/pylab_examples/text_rotation_relative_to_line.py matplotlib-1.2.0/examples/pylab_examples/text_rotation_relative_to_line.py --- matplotlib-1.1.1/examples/pylab_examples/text_rotation_relative_to_line.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/text_rotation_relative_to_line.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,7 +2,7 @@ """ Text objects in matplotlib are normally rotated with respect to the screen coordinate system (i.e., 45 degrees rotation plots text along a -line that is inbetween horizontal and vertical no matter how the axes +line that is in between horizontal and vertical no matter how the axes are changed). However, at times one wants to rotate text with respect to something on the plot. In this case, the correct angle won't be the angle of that object in the plot coordinate system, but the angle diff -Nru matplotlib-1.1.1/examples/pylab_examples/to_numeric.py matplotlib-1.2.0/examples/pylab_examples/to_numeric.py --- matplotlib-1.1.1/examples/pylab_examples/to_numeric.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/to_numeric.py 2012-10-31 00:11:13.000000000 +0000 @@ -5,16 +5,17 @@ rendering """ -from pylab import * +import pylab from matplotlib.backends.backend_agg import FigureCanvasAgg + try: from PIL import Image -except ImportError, exc: +except ImportError: raise SystemExit("PIL must be installed to run this example") -plot([1,2,3]) +pylab.plot([1,2,3]) -canvas = get_current_fig_manager().canvas +canvas = pylab.get_current_fig_manager().canvas agg = canvas.switch_backends(FigureCanvasAgg) agg.draw() @@ -25,9 +26,9 @@ w, h = int(w), int(h) -X = fromstring(s, uint8) +X = pylab.fromstring(s, pylab.uint8) X.shape = h, w, 3 im = Image.fromstring( "RGB", (w,h), s) -# im.show() +im.show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/tricontour_vs_griddata.py matplotlib-1.2.0/examples/pylab_examples/tricontour_vs_griddata.py --- matplotlib-1.1.1/examples/pylab_examples/tricontour_vs_griddata.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/tricontour_vs_griddata.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,7 @@ """ Comparison of griddata and tricontour for an unstructured triangular grid. """ +from __future__ import print_function import matplotlib.pyplot as plt import matplotlib.tri as tri import numpy as np @@ -23,25 +24,27 @@ yi = np.linspace(-2.1,2.1,ngridy) zi = griddata(x,y,z,xi,yi,interp='linear') plt.contour(xi,yi,zi,15,linewidths=0.5,colors='k') -plt.contourf(xi,yi,zi,15,cmap=plt.cm.jet) +plt.contourf(xi,yi,zi,15,cmap=plt.cm.rainbow, + norm=plt.normalize(vmax=abs(zi).max(), vmin=-abs(zi).max())) plt.colorbar() # draw colorbar plt.plot(x, y, 'ko', ms=3) plt.xlim(-2,2) plt.ylim(-2,2) plt.title('griddata and contour (%d points, %d grid points)' % (npts, ngridx*ngridy)) -print 'griddata and contour seconds:', time.clock() - start +print ('griddata and contour seconds: %f' % (time.clock() - start)) # tricontour. start = time.clock() plt.subplot(212) triang = tri.Triangulation(x, y) plt.tricontour(x, y, z, 15, linewidths=0.5, colors='k') -plt.tricontourf(x, y, z, 15, cmap=plt.cm.jet) +plt.tricontourf(x, y, z, 15, cmap=plt.cm.rainbow, + norm=plt.normalize(vmax=abs(zi).max(), vmin=-abs(zi).max())) plt.colorbar() plt.plot(x, y, 'ko', ms=3) plt.xlim(-2,2) plt.ylim(-2,2) plt.title('tricontour (%d points)' % npts) -print 'tricontour seconds:', time.clock() - start +print ('tricontour seconds: %f' % (time.clock() - start)) plt.show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/tripcolor_demo.py matplotlib-1.2.0/examples/pylab_examples/tripcolor_demo.py --- matplotlib-1.1.1/examples/pylab_examples/tripcolor_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/tripcolor_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -32,12 +32,19 @@ mask = np.where(xmid*xmid + ymid*ymid < min_radius*min_radius, 1, 0) triang.set_mask(mask) -# pcolor plot. +# tripcolor plot. plt.figure() plt.gca().set_aspect('equal') -plt.tripcolor(triang, z, shading='faceted') +plt.tripcolor(triang, z, shading='flat', cmap=plt.cm.rainbow) plt.colorbar() -plt.title('tripcolor of Delaunay triangulation') +plt.title('tripcolor of Delaunay triangulation, flat shading') + +# Illustrate Gouraud shading. +plt.figure() +plt.gca().set_aspect('equal') +plt.tripcolor(triang, z, shading='gouraud', cmap=plt.cm.rainbow) +plt.colorbar() +plt.title('tripcolor of Delaunay triangulation, gouraud shading') # You can specify your own triangulation rather than perform a Delaunay @@ -63,9 +70,6 @@ [-0.057,0.916],[-0.025,0.933],[-0.077,0.990],[-0.059,0.993] ]) x = xy[:,0]*180/3.14159 y = xy[:,1]*180/3.14159 -x0 = -5 -y0 = 52 -z = np.exp(-0.01*( (x-x0)*(x-x0) + (y-y0)*(y-y0) )) triangles = np.asarray([ [67,66, 1],[65, 2,66],[ 1,66, 2],[64, 2,65],[63, 3,64],[60,59,57], @@ -83,13 +87,21 @@ [32,31,33],[39,38,72],[33,72,38],[33,38,34],[37,35,38],[34,38,35], [35,37,36] ]) +xmid = x[triangles].mean(axis=1) +ymid = y[triangles].mean(axis=1) +x0 = -5 +y0 = 52 +zfaces = np.exp(-0.01*( (xmid-x0)*(xmid-x0) + (ymid-y0)*(ymid-y0) )) + # Rather than create a Triangulation object, can simply pass x, y and triangles # arrays to tripcolor directly. It would be better to use a Triangulation object # if the same triangulation was to be used more than once to save duplicated # calculations. +# Can specify one color value per face rather than one per point by using the +# facecolors kwarg. plt.figure() plt.gca().set_aspect('equal') -plt.tripcolor(x, y, triangles, z, shading='faceted') +plt.tripcolor(x, y, triangles, facecolors=zfaces, edgecolors='k') plt.colorbar() plt.title('tripcolor of user-specified triangulation') plt.xlabel('Longitude (degrees)') diff -Nru matplotlib-1.1.1/examples/pylab_examples/unicode_demo.py matplotlib-1.2.0/examples/pylab_examples/unicode_demo.py --- matplotlib-1.1.1/examples/pylab_examples/unicode_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/unicode_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,12 +1,15 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -from pylab import * -plot([1,2,4]) -title(u'Développés et fabriqués') -xlabel(u"réactivité nous permettent d'être sélectionnés et adoptés") -ylabel(u'André was here!') -text( 0.5, 2.5, u'Institut für Festkörperphysik', rotation=45) -text( 1, 1.5, u'AVA (check kerning)') +from __future__ import unicode_literals -show() +import pylab + +pylab.plot([1, 2, 4]) +pylab.title('Développés et fabriqués') +pylab.xlabel("réactivité nous permettent d'être sélectionnés et adoptés") +pylab.ylabel('André was here!') +pylab.text( 0.5, 2.5, 'Institut für Festkörperphysik', rotation=45) +pylab.text( 1, 1.5, 'AVA (check kerning)') + +pylab.show() diff -Nru matplotlib-1.1.1/examples/pylab_examples/usetex_baseline_test.py matplotlib-1.2.0/examples/pylab_examples/usetex_baseline_test.py --- matplotlib-1.1.1/examples/pylab_examples/usetex_baseline_test.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/pylab_examples/usetex_baseline_test.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,6 +3,10 @@ import matplotlib.pyplot as plt import matplotlib.axes as maxes +from matplotlib import rcParams +rcParams['text.usetex']=True +rcParams['text.latex.unicode']=True + class Axes(maxes.Axes): """ A hackish way to simultaneously draw texts w/ usetex=True and diff -Nru matplotlib-1.1.1/examples/tests/backend_driver.py matplotlib-1.2.0/examples/tests/backend_driver.py --- matplotlib-1.1.1/examples/tests/backend_driver.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/tests/backend_driver.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,6 @@ #!/usr/bin/env python + +from __future__ import print_function, division """ This is used to drive many of the examples across the backends, for regression testing, and comparing backend efficiency. @@ -7,11 +9,10 @@ switch, which takes a comma-separated list, or as separate arguments, e.g. - python backend_driver.py agg ps cairo.png cairo.ps + python backend_driver.py agg ps -would test the agg and ps backends, and the cairo backend with output -to png and ps files. If no arguments are given, a default list of -backends will be tested. +would test the agg and ps backends. If no arguments are given, a +default list of backends will be tested. Interspersed with the backend arguments can be switches for the Python interpreter executing the tests. If entering such arguments causes an @@ -19,14 +20,12 @@ switches with a --. """ -from __future__ import division import os, time, sys, glob, string from optparse import OptionParser import matplotlib.rcsetup as rcsetup from matplotlib.cbook import Bunch, dedent all_backends = list(rcsetup.all_backends) # to leave the original list alone -all_backends.extend(['cairo.png', 'cairo.ps', 'cairo.pdf', 'cairo.svg']) # actual physical directory for each dir dirs = dict(pylab = os.path.join('..', 'pylab_examples'), @@ -160,6 +159,7 @@ 'pcolor_log.py', 'pcolor_small.py', 'pie_demo.py', + 'pie_demo2.py', 'plotfile_demo.py', 'polar_bar.py', 'polar_demo.py', @@ -285,7 +285,7 @@ missing = list(pyfiles-flist-exclude) missing.sort() if missing: - print '%s files not tested: %s'%(dir, ', '.join(missing)) + print ('%s files not tested: %s'%(dir, ', '.join(missing))) def report_all_missing(directories): for f in directories: @@ -323,7 +323,7 @@ if os.path.exists(path): import glob for fname in os.listdir(path): - os.unlink(os.path.join(path,fname)) + os.unlink(os.path.join(path, fname)) else: os.mkdir(backend) failures = [] @@ -338,34 +338,35 @@ fpath, fname = os.path.split(fullpath) if fname in exclude: - print '\tSkipping %s, known to fail on backend: %s'%backend + print ('\tSkipping %s, known to fail on backend: %s'%backend) continue basename, ext = os.path.splitext(fname) - outfile = os.path.join(path,basename) + outfile = os.path.join(path, basename) tmpfile_name = '_tmp_%s.py' % basename - tmpfile = file(tmpfile_name, 'w') + tmpfile = open(tmpfile_name, 'w') - for line in file(fullpath): + future_imports = 'from __future__ import division, print_function' + for line in open(fullpath): line_lstrip = line.lstrip() if line_lstrip.startswith("#"): tmpfile.write(line) - else: - break + elif 'unicode_literals' in line: + future_imports = future_imports + ', unicode_literals' tmpfile.writelines(( - 'from __future__ import division\n', + future_imports+'\n', 'import sys\n', - 'sys.path.append("%s")\n'%fpath, + 'sys.path.append("%s")\n' % fpath.replace('\\', '\\\\'), 'import matplotlib\n', 'matplotlib.use("%s")\n' % backend, 'from pylab import savefig\n', 'import numpy\n', 'numpy.seterr(invalid="ignore")\n', )) - for line in file(fullpath): + for line in open(fullpath): line_lstrip = line.lstrip() - if (line_lstrip.startswith('from __future__ import division') or + if (line_lstrip.startswith('from __future__ import') or line_lstrip.startswith('matplotlib.use') or line_lstrip.startswith('savefig') or line_lstrip.startswith('show')): @@ -381,7 +382,7 @@ program = [x % {'name': basename} for x in python] ret = run(program + [tmpfile_name] + switches) end_time = time.time() - print (end_time - start_time), ret + print ("%s %s" % ((end_time - start_time), ret)) #os.system('%s %s %s' % (python, tmpfile_name, ' '.join(switches))) os.remove(tmpfile_name) if ret: @@ -405,8 +406,7 @@ help=dedent(''' Run tests only for these backends; comma-separated list of one or more of: agg, ps, svg, pdf, template, cairo, - cairo.png, cairo.ps, cairo.pdf, cairo.svg. Default is everything - except cairo.''')) + Default is everything except cairo.''')) op.add_option('--clean', action='store_true', dest='clean', help='Remove result directories, run no tests') op.add_option('-c', '--coverage', action='store_true', dest='coverage', @@ -418,7 +418,7 @@ switches = [x for x in args if x.startswith('--')] backends = [x.lower() for x in args if not x.startswith('--')] if options.backends: - backends += map(string.lower, options.backends.split(',')) + backends += [be.lower() for be in options.backends.split(',')] result = Bunch( dirs = options.dirs.split(','), @@ -430,7 +430,7 @@ if 'pylab_examples' in result.dirs: result.dirs[result.dirs.index('pylab_examples')] = 'pylab' #print result - return result + return (result) if __name__ == '__main__': times = {} @@ -443,28 +443,28 @@ for d in localdirs: if d.lower() not in all_backends_set: continue - print 'removing %s'%d + print ('removing %s'%d) for fname in glob.glob(os.path.join(d, '*')): os.remove(fname) os.rmdir(d) for fname in glob.glob('_tmp*.py'): os.remove(fname) - print 'all clean...' + print ('all clean...') raise SystemExit if options.coverage: python = ['coverage.py', '-x'] elif options.valgrind: python = ['valgrind', '--tool=memcheck', '--leak-check=yes', - '--log-file=%(name)s', 'python'] + '--log-file=%(name)s', sys.executable] elif sys.platform == 'win32': python = [sys.executable] else: - python = ['python'] + python = [sys.executable] report_all_missing(options.dirs) for backend in options.backends: - print 'testing %s %s' % (backend, ' '.join(options.switches)) + print ('testing %s %s' % (backend, ' '.join(options.switches))) t0 = time.time() failures[backend] = \ drive(backend, options.dirs, python, options.switches) @@ -473,10 +473,10 @@ # print times for backend, elapsed in times.items(): - print 'Backend %s took %1.2f minutes to complete' % (backend, elapsed) + print ('Backend %s took %1.2f minutes to complete' % (backend, elapsed)) failed = failures[backend] if failed: - print ' Failures: ', failed + print (' Failures: %s' % failed) if 'template' in times: - print '\ttemplate ratio %1.3f, template residual %1.3f' % ( - elapsed/times['template'], elapsed-times['template']) + print ('\ttemplate ratio %1.3f, template residual %1.3f' % ( + elapsed/times['template'], elapsed-times['template'])) diff -Nru matplotlib-1.1.1/examples/units/bar_demo2.py matplotlib-1.2.0/examples/units/bar_demo2.py --- matplotlib-1.1.1/examples/units/bar_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/units/bar_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -9,13 +9,14 @@ """ import numpy as np from basic_units import cm, inch -from pylab import figure, show +import matplotlib.pyplot as plt + cms = cm *np.arange(0, 10, 2) bottom=0*cm width=0.8*cm -fig = figure() +fig = plt.figure() ax1 = fig.add_subplot(2,2,1) ax1.bar(cms, cms, bottom=bottom) @@ -32,4 +33,4 @@ #fig.savefig('simple_conversion_plot.png') ax4.set_xlim(2*cm, 6*cm) # cm are converted to inches -show() +plt.show() diff -Nru matplotlib-1.1.1/examples/units/bar_unit_demo.py matplotlib-1.2.0/examples/units/bar_unit_demo.py --- matplotlib-1.1.1/examples/units/bar_unit_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/units/bar_unit_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,13 +1,14 @@ #!/usr/bin/env python import numpy as np from basic_units import cm, inch -from pylab import figure, show +import matplotlib.pyplot as plt + N = 5 menMeans = (150*cm, 160*cm, 146*cm, 172*cm, 155*cm) menStd = ( 20*cm, 30*cm, 32*cm, 10*cm, 20*cm) -fig = figure() +fig = plt.figure() ax = fig.add_subplot(111) ind = np.arange(N) # the x locations for the groups @@ -27,5 +28,5 @@ ax.yaxis.set_units(inch) ax.autoscale_view() -#savefig('barchart_demo') -show() +#plt.savefig('barchart_demo') +plt.show() diff -Nru matplotlib-1.1.1/examples/units/basic_units.py matplotlib-1.2.0/examples/units/basic_units.py --- matplotlib-1.1.1/examples/units/basic_units.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/units/basic_units.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,5 @@ import math + import numpy as np import matplotlib.units as units @@ -6,35 +7,42 @@ from matplotlib.axes import Axes from matplotlib.cbook import iterable + class ProxyDelegate(object): def __init__(self, fn_name, proxy_type): self.proxy_type = proxy_type self.fn_name = fn_name + def __get__(self, obj, objtype=None): return self.proxy_type(self.fn_name, obj) + class TaggedValueMeta (type): def __init__(cls, name, bases, dict): for fn_name in cls._proxies.keys(): try: dummy = getattr(cls, fn_name) except AttributeError: - setattr(cls, fn_name, ProxyDelegate(fn_name, cls._proxies[fn_name])) + setattr(cls, fn_name, + ProxyDelegate(fn_name, cls._proxies[fn_name])) + class PassThroughProxy(object): def __init__(self, fn_name, obj): self.fn_name = fn_name self.target = obj.proxy_target + def __call__(self, *args): - #print 'passthrough', self.target, self.fn_name fn = getattr(self.target, self.fn_name) ret = fn(*args) return ret + class ConvertArgsProxy(PassThroughProxy): def __init__(self, fn_name, obj): PassThroughProxy.__init__(self, fn_name, obj) self.unit = obj.unit + def __call__(self, *args): converted_args = [] for a in args: @@ -45,16 +53,19 @@ converted_args = tuple([c.get_value() for c in converted_args]) return PassThroughProxy.__call__(self, *converted_args) + class ConvertReturnProxy(PassThroughProxy): def __init__(self, fn_name, obj): PassThroughProxy.__init__(self, fn_name, obj) self.unit = obj.unit + def __call__(self, *args): ret = PassThroughProxy.__call__(self, *args) if (type(ret) == type(NotImplemented)): return NotImplemented return TaggedValue(ret, self.unit) + class ConvertAllProxy(PassThroughProxy): def __init__(self, fn_name, obj): PassThroughProxy.__init__(self, fn_name, obj) @@ -91,184 +102,186 @@ return NotImplemented return TaggedValue(ret, ret_unit) -class TaggedValue (object): - __metaclass__ = TaggedValueMeta - _proxies = {'__add__':ConvertAllProxy, - '__sub__':ConvertAllProxy, - '__mul__':ConvertAllProxy, - '__rmul__':ConvertAllProxy, - '__cmp__':ConvertAllProxy, - '__lt__':ConvertAllProxy, - '__gt__':ConvertAllProxy, - '__len__':PassThroughProxy} - - def __new__(cls, value, unit): - # generate a new subclass for value - value_class = type(value) - try: - subcls = type('TaggedValue_of_%s' % (value_class.__name__), - tuple([cls, value_class]), - {}) - if subcls not in units.registry: - units.registry[subcls] = basicConverter - return object.__new__(subcls, value, unit) - except TypeError: - if cls not in units.registry: - units.registry[cls] = basicConverter - return object.__new__(cls, value, unit) - - def __init__(self, value, unit): - self.value = value - self.unit = unit - self.proxy_target = self.value - - def get_compressed_copy(self, mask): - compressed_value = np.ma.masked_array(self.value, mask=mask).compressed() - return TaggedValue(compressed_value, self.unit) - - def __getattribute__(self, name): - if (name.startswith('__')): - return object.__getattribute__(self, name) - variable = object.__getattribute__(self, 'value') - if (hasattr(variable, name) and name not in self.__class__.__dict__): - return getattr(variable, name) - return object.__getattribute__(self, name) - - def __array__(self, t = None, context = None): - if t is not None: - return np.asarray(self.value).astype(t) - else: - return np.asarray(self.value, 'O') +class _TaggedValue(object): - def __array_wrap__(self, array, context): - return TaggedValue(array, self.unit) + _proxies = {'__add__': ConvertAllProxy, + '__sub__': ConvertAllProxy, + '__mul__': ConvertAllProxy, + '__rmul__': ConvertAllProxy, + '__cmp__': ConvertAllProxy, + '__lt__': ConvertAllProxy, + '__gt__': ConvertAllProxy, + '__len__': PassThroughProxy} + + def __new__(cls, value, unit): + # generate a new subclass for value + value_class = type(value) + try: + subcls = type('TaggedValue_of_%s' % (value_class.__name__), + tuple([cls, value_class]), + {}) + if subcls not in units.registry: + units.registry[subcls] = basicConverter + return object.__new__(subcls, value, unit) + except TypeError: + if cls not in units.registry: + units.registry[cls] = basicConverter + return object.__new__(cls, value, unit) - def __repr__(self): - return 'TaggedValue(' + repr(self.value) + ', ' + repr(self.unit) + ')' + def __init__(self, value, unit): + self.value = value + self.unit = unit + self.proxy_target = self.value - def __str__(self): - return str(self.value) + ' in ' + str(self.unit) + def __getattribute__(self, name): + if (name.startswith('__')): + return object.__getattribute__(self, name) + variable = object.__getattribute__(self, 'value') + if (hasattr(variable, name) and name not in self.__class__.__dict__): + return getattr(variable, name) + return object.__getattribute__(self, name) + + def __array__(self, t=None, context=None): + if t is not None: + return np.asarray(self.value).astype(t) + else: + return np.asarray(self.value, 'O') - def __iter__(self): - class IteratorProxy(object): - def __init__(self, iter, unit): - self.iter = iter - self.unit = unit - def next(self): - value = self.iter.next() - return TaggedValue(value, self.unit) - return IteratorProxy(iter(self.value), self.unit) - - def get_compressed_copy(self, mask): - new_value = np.ma.masked_array(self.value, mask=mask).compressed() - return TaggedValue(new_value, self.unit) - - def convert_to(self, unit): - #print 'convert to', unit, self.unit - if (unit == self.unit or not unit): - return self - new_value = self.unit.convert_value_to(self.value, unit) - return TaggedValue(new_value, unit) + def __array_wrap__(self, array, context): + return TaggedValue(array, self.unit) + + def __repr__(self): + return 'TaggedValue(' + repr(self.value) + ', ' + repr(self.unit) + ')' + + def __str__(self): + return str(self.value) + ' in ' + str(self.unit) + + def __len__(self): + return len(self.value) + + def __iter__(self): + class IteratorProxy(object): + def __init__(self, iter, unit): + self.iter = iter + self.unit = unit + + def __next__(self): + value = next(self.iter) + return TaggedValue(value, self.unit) + next = __next__ # for Python 2 + return IteratorProxy(iter(self.value), self.unit) - def get_value(self): - return self.value + def get_compressed_copy(self, mask): + new_value = np.ma.masked_array(self.value, mask=mask).compressed() + return TaggedValue(new_value, self.unit) - def get_unit(self): - return self.unit + def convert_to(self, unit): + if (unit == self.unit or not unit): + return self + new_value = self.unit.convert_value_to(self.value, unit) + return TaggedValue(new_value, unit) + + def get_value(self): + return self.value + + def get_unit(self): + return self.unit + + +TaggedValue = TaggedValueMeta('TaggedValue', (_TaggedValue, ), {}) class BasicUnit(object): - def __init__(self, name, fullname=None): - self.name = name - if fullname is None: fullname = name - self.fullname = fullname - self.conversions = dict() - - - def __repr__(self): - return 'BasicUnit(%s)'%self.name - - def __str__(self): - return self.fullname - - def __call__(self, value): - return TaggedValue(value, self) - - def __mul__(self, rhs): - value = rhs - unit = self - if hasattr(rhs, 'get_unit'): - value = rhs.get_value() - unit = rhs.get_unit() - unit = unit_resolver('__mul__', (self, unit)) - if (unit == NotImplemented): - return NotImplemented - return TaggedValue(value, unit) - - def __rmul__(self, lhs): - return self*lhs - - def __array_wrap__(self, array, context): - return TaggedValue(array, self) - - def __array__(self, t=None, context=None): - ret = np.array([1]) - if t is not None: - return ret.astype(t) - else: - return ret + def __init__(self, name, fullname=None): + self.name = name + if fullname is None: + fullname = name + self.fullname = fullname + self.conversions = dict() + + def __repr__(self): + return 'BasicUnit(%s)'%self.name + + def __str__(self): + return self.fullname + + def __call__(self, value): + return TaggedValue(value, self) + + def __mul__(self, rhs): + value = rhs + unit = self + if hasattr(rhs, 'get_unit'): + value = rhs.get_value() + unit = rhs.get_unit() + unit = unit_resolver('__mul__', (self, unit)) + if (unit == NotImplemented): + return NotImplemented + return TaggedValue(value, unit) - def add_conversion_factor(self, unit, factor): - def convert(x): - return x*factor - self.conversions[unit] = convert + def __rmul__(self, lhs): + return self*lhs - def add_conversion_fn(self, unit, fn): - self.conversions[unit] = fn + def __array_wrap__(self, array, context): + return TaggedValue(array, self) - def get_conversion_fn(self, unit): - return self.conversions[unit] + def __array__(self, t=None, context=None): + ret = np.array([1]) + if t is not None: + return ret.astype(t) + else: + return ret - def convert_value_to(self, value, unit): - #print 'convert value to: value ="%s", unit="%s"'%(value, type(unit)), self.conversions - conversion_fn = self.conversions[unit] - ret = conversion_fn(value) - return ret + def add_conversion_factor(self, unit, factor): + def convert(x): + return x*factor + self.conversions[unit] = convert + + def add_conversion_fn(self, unit, fn): + self.conversions[unit] = fn + + def get_conversion_fn(self, unit): + return self.conversions[unit] + + def convert_value_to(self, value, unit): + conversion_fn = self.conversions[unit] + ret = conversion_fn(value) + return ret + def get_unit(self): + return self - def get_unit(self): - return self class UnitResolver(object): - def addition_rule(self, units): - for unit_1, unit_2 in zip(units[:-1], units[1:]): - if (unit_1 != unit_2): - return NotImplemented - return units[0] - def multiplication_rule(self, units): - non_null = [u for u in units if u] - if (len(non_null) > 1): - return NotImplemented - return non_null[0] - - op_dict = { - '__mul__':multiplication_rule, - '__rmul__':multiplication_rule, - '__add__':addition_rule, - '__radd__':addition_rule, - '__sub__':addition_rule, - '__rsub__':addition_rule, - } - - def __call__(self, operation, units): - if (operation not in self.op_dict): - return NotImplemented + def addition_rule(self, units): + for unit_1, unit_2 in zip(units[:-1], units[1:]): + if (unit_1 != unit_2): + return NotImplemented + return units[0] + + def multiplication_rule(self, units): + non_null = [u for u in units if u] + if (len(non_null) > 1): + return NotImplemented + return non_null[0] - return self.op_dict[operation](self, units) + op_dict = { + '__mul__': multiplication_rule, + '__rmul__': multiplication_rule, + '__add__': addition_rule, + '__radd__': addition_rule, + '__sub__': addition_rule, + '__rsub__': addition_rule} + + def __call__(self, operation, units): + if (operation not in self.op_dict): + return NotImplemented + + return self.op_dict[operation](self, units) -unit_resolver = UnitResolver() +unit_resolver = UnitResolver() cm = BasicUnit('cm', 'centimeters') inch = BasicUnit('inch', 'inches') @@ -284,22 +297,23 @@ hertz = BasicUnit('Hz', 'Hertz') minutes = BasicUnit('min', 'minutes') -secs.add_conversion_fn(hertz, lambda x:1./x) +secs.add_conversion_fn(hertz, lambda x: 1./x) secs.add_conversion_factor(minutes, 1/60.0) + # radians formatting -def rad_fn(x,pos=None): - n = int((x / np.pi) * 2.0 + 0.25) - if n == 0: - return '0' - elif n == 1: - return r'$\pi/2$' - elif n == 2: - return r'$\pi$' - elif n % 2 == 0: - return r'$%s\pi$' % (n/2,) - else: - return r'$%s\pi/2$' % (n,) +def rad_fn(x, pos=None): + n = int((x / np.pi) * 2.0 + 0.25) + if n == 0: + return '0' + elif n == 1: + return r'$\pi/2$' + elif n == 2: + return r'$\pi$' + elif n % 2 == 0: + return r'$%s\pi$' % (n/2,) + else: + return r'$%s\pi/2$' % (n,) class BasicUnitConverter(units.ConversionInterface): @@ -310,16 +324,16 @@ if unit==radians: return units.AxisInfo( - majloc=ticker.MultipleLocator(base=np.pi/2), - majfmt=ticker.FuncFormatter(rad_fn), - label=unit.fullname, - ) + majloc=ticker.MultipleLocator(base=np.pi/2), + majfmt=ticker.FuncFormatter(rad_fn), + label=unit.fullname, + ) elif unit==degrees: return units.AxisInfo( - majloc=ticker.AutoLocator(), - majfmt=ticker.FormatStrFormatter(r'$%i^\circ$'), - label=unit.fullname, - ) + majloc=ticker.AutoLocator(), + majfmt=ticker.FormatStrFormatter(r'$%i^\circ$'), + label=unit.fullname, + ) elif unit is not None: if hasattr(unit, 'fullname'): return units.AxisInfo(label=unit.fullname) @@ -331,7 +345,6 @@ def convert(val, unit, axis): if units.ConversionInterface.is_numlike(val): return val - #print 'convert checking iterable' if iterable(val): return [thisval.convert_to(unit).get_value() for thisval in val] else: @@ -346,17 +359,13 @@ return x.unit +def cos(x): + if iterable(x): + return [math.cos(val.convert_to(radians).get_value()) for val in x] + else: + return math.cos(x.convert_to(radians).get_value()) -def cos( x ): - if ( iterable(x) ): - result = [] - for val in x: - result.append( math.cos( val.convert_to( radians ).get_value() ) ) - return result - else: - return math.cos( x.convert_to( radians ).get_value() ) basicConverter = BasicUnitConverter() units.registry[BasicUnit] = basicConverter units.registry[TaggedValue] = basicConverter - diff -Nru matplotlib-1.1.1/examples/units/ellipse_with_units.py matplotlib-1.2.0/examples/units/ellipse_with_units.py --- matplotlib-1.1.1/examples/units/ellipse_with_units.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/units/ellipse_with_units.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,31 +2,32 @@ Compare the ellipse generated with arcs versus a polygonal approximation """ from basic_units import cm -import numpy as npy +import numpy as np from matplotlib import patches -from pylab import figure, show +import matplotlib.pyplot as plt + xcenter, ycenter = 0.38*cm, 0.52*cm #xcenter, ycenter = 0., 0. width, height = 1e-1*cm, 3e-1*cm angle = -30 -theta = npy.arange(0.0, 360.0, 1.0)*npy.pi/180.0 -x = 0.5 * width * npy.cos(theta) -y = 0.5 * height * npy.sin(theta) - -rtheta = angle*npy.pi/180. -R = npy.array([ - [npy.cos(rtheta), -npy.sin(rtheta)], - [npy.sin(rtheta), npy.cos(rtheta)], +theta = np.arange(0.0, 360.0, 1.0)*np.pi/180.0 +x = 0.5 * width * np.cos(theta) +y = 0.5 * height * np.sin(theta) + +rtheta = angle*np.pi/180. +R = np.array([ + [np.cos(rtheta), -np.sin(rtheta)], + [np.sin(rtheta), np.cos(rtheta)], ]) -x, y = npy.dot(R, npy.array([x, y])) +x, y = np.dot(R, np.array([x, y])) x += xcenter y += ycenter -fig = figure() +fig = plt.figure() ax = fig.add_subplot(211, aspect='auto') ax.fill(x, y, alpha=0.2, facecolor='yellow', edgecolor='yellow', linewidth=1, zorder=1) @@ -46,7 +47,7 @@ #fig.savefig('ellipse_compare.png') fig.savefig('ellipse_compare') -fig = figure() +fig = plt.figure() ax = fig.add_subplot(211, aspect='auto') ax.fill(x, y, alpha=0.2, facecolor='yellow', edgecolor='yellow', linewidth=1, zorder=1) @@ -66,4 +67,4 @@ #fig.savefig('arc_compare.png') fig.savefig('arc_compare') -show() +plt.show() diff -Nru matplotlib-1.1.1/examples/units/evans_test.py matplotlib-1.2.0/examples/units/evans_test.py --- matplotlib-1.1.1/examples/units/evans_test.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/units/evans_test.py 2012-10-31 00:11:13.000000000 +0000 @@ -4,13 +4,11 @@ Here the "unit" is just a scalar conversion factor, but this example shows mpl is entirely agnostic to what kind of units client packages use """ - -import matplotlib - from matplotlib.cbook import iterable import matplotlib.units as units import matplotlib.ticker as ticker -from pylab import figure, show +import matplotlib.pyplot as plt + class Foo: def __init__( self, val, unit=1.0 ): @@ -71,7 +69,7 @@ # plot specifying units -fig = figure() +fig = plt.figure() fig.suptitle("Custom units") fig.subplots_adjust(bottom=0.2) ax = fig.add_subplot(1,2,2) @@ -90,4 +88,4 @@ label.set_rotation(30) label.set_ha('right') -show() +plt.show() diff -Nru matplotlib-1.1.1/examples/units/units_sample.py matplotlib-1.2.0/examples/units/units_sample.py --- matplotlib-1.1.1/examples/units/units_sample.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/units/units_sample.py 2012-10-31 00:11:13.000000000 +0000 @@ -8,12 +8,12 @@ """ from basic_units import cm, inch -from pylab import figure, show +import matplotlib.pyplot as plt import numpy cms = cm *numpy.arange(0, 10, 2) -fig = figure() +fig = plt.figure() ax1 = fig.add_subplot(2,2,1) ax1.plot(cms, cms) @@ -30,4 +30,4 @@ #fig.savefig('simple_conversion_plot.png') ax4.set_xlim(3*cm, 6*cm) # cm are converted to inches -show() +plt.show() diff -Nru matplotlib-1.1.1/examples/user_interfaces/embedding_in_gtk2.py matplotlib-1.2.0/examples/user_interfaces/embedding_in_gtk2.py --- matplotlib-1.1.1/examples/user_interfaces/embedding_in_gtk2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/embedding_in_gtk2.py 2012-10-31 00:11:13.000000000 +0000 @@ -17,6 +17,8 @@ #from matplotlib.backends.backend_gtk import NavigationToolbar2GTK as NavigationToolbar from matplotlib.backends.backend_gtkagg import NavigationToolbar2GTKAgg as NavigationToolbar +# implement the default mpl key bindings +from matplotlib.backend_bases import key_press_handler win = gtk.Window() win.connect("destroy", lambda x: gtk.main_quit()) @@ -40,5 +42,11 @@ vbox.pack_start(toolbar, False, False) +def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvas, toolbar) + +canvas.mpl_connect('key_press_event', on_key_event) + win.show_all() gtk.main() diff -Nru matplotlib-1.1.1/examples/user_interfaces/embedding_in_gtk3.py matplotlib-1.2.0/examples/user_interfaces/embedding_in_gtk3.py --- matplotlib-1.1.1/examples/user_interfaces/embedding_in_gtk3.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/embedding_in_gtk3.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,20 +1,17 @@ #!/usr/bin/env python """ -demonstrate adding a FigureCanvasGTK/GTKAgg widget to a gtk.ScrolledWindow +demonstrate adding a FigureCanvasGTK3Agg widget to a Gtk.ScrolledWindow +using GTK3 accessed via pygobject """ -import gtk +from gi.repository import Gtk from matplotlib.figure import Figure from numpy import arange, sin, pi +from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas -# uncomment to select /GTK/GTKAgg/GTKCairo -#from matplotlib.backends.backend_gtk import FigureCanvasGTK as FigureCanvas -from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas -#from matplotlib.backends.backend_gtkcairo import FigureCanvasGTKCairo as FigureCanvas - -win = gtk.Window() -win.connect("destroy", lambda x: gtk.main_quit()) +win = Gtk.Window() +win.connect("delete-event", Gtk.main_quit ) win.set_default_size(400,300) win.set_title("Embedding in GTK") @@ -24,17 +21,15 @@ s = sin(2*pi*t) a.plot(t,s) -sw = gtk.ScrolledWindow() +sw = Gtk.ScrolledWindow() win.add (sw) # A scrolled window border goes outside the scrollbars and viewport sw.set_border_width (10) -# policy: ALWAYS, AUTOMATIC, NEVER -sw.set_policy (hscrollbar_policy=gtk.POLICY_AUTOMATIC, - vscrollbar_policy=gtk.POLICY_ALWAYS) -canvas = FigureCanvas(f) # a gtk.DrawingArea +canvas = FigureCanvas(f) # a Gtk.DrawingArea canvas.set_size_request(800,600) sw.add_with_viewport (canvas) win.show_all() -gtk.main() +Gtk.main() + diff -Nru matplotlib-1.1.1/examples/user_interfaces/embedding_in_gtk3_panzoom.py matplotlib-1.2.0/examples/user_interfaces/embedding_in_gtk3_panzoom.py --- matplotlib-1.1.1/examples/user_interfaces/embedding_in_gtk3_panzoom.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/embedding_in_gtk3_panzoom.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,37 @@ +#!/usr/bin/env python +""" +demonstrate NavigationToolbar with GTK3 accessed via pygobject +""" + +from gi.repository import Gtk + +from matplotlib.figure import Figure +from numpy import arange, sin, pi +from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas +from matplotlib.backends.backend_gtk3 import NavigationToolbar2GTK3 as NavigationToolbar + +win = Gtk.Window() +win.connect("delete-event", Gtk.main_quit ) +win.set_default_size(400,300) +win.set_title("Embedding in GTK") + +f = Figure(figsize=(5,4), dpi=100) +a = f.add_subplot(1,1,1) +t = arange(0.0,3.0,0.01) +s = sin(2*pi*t) +a.plot(t,s) + +vbox = Gtk.VBox() +win.add(vbox) + +# Add canvas to vbox +canvas = FigureCanvas(f) # a Gtk.DrawingArea +vbox.pack_start(canvas, True, True, 0) + +# Create toolbar +toolbar = NavigationToolbar(canvas, win) +vbox.pack_start(toolbar, False, False, 0) + +win.show_all() +Gtk.main() + diff -Nru matplotlib-1.1.1/examples/user_interfaces/embedding_in_qt.py matplotlib-1.2.0/examples/user_interfaces/embedding_in_qt.py --- matplotlib-1.1.1/examples/user_interfaces/embedding_in_qt.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/embedding_in_qt.py 2012-10-31 00:11:13.000000000 +0000 @@ -8,6 +8,7 @@ # modified with no restriction; raw copies as well as modified versions # may be distributed without limitation. +from __future__ import unicode_literals import sys, os, random from qt import * @@ -75,7 +76,7 @@ def update_figure(self): # Build a list of 4 random integers between 0 and 10 (both inclusive) - l = [ random.randint(0, 10) for i in xrange(4) ] + l = [ random.randint(0, 10) for i in range(4) ] self.axes.plot([0, 1, 2, 3], l, 'r') self.draw() @@ -118,7 +119,7 @@ def about(self): QMessageBox.about(self, "About %s" % progname, -u"""%(prog)s version %(version)s +"""%(prog)s version %(version)s Copyright \N{COPYRIGHT SIGN} 2005 Florent Rougon This program is a simple example of a Qt application embedding matplotlib diff -Nru matplotlib-1.1.1/examples/user_interfaces/embedding_in_qt4.py matplotlib-1.2.0/examples/user_interfaces/embedding_in_qt4.py --- matplotlib-1.1.1/examples/user_interfaces/embedding_in_qt4.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/embedding_in_qt4.py 2012-10-31 00:11:13.000000000 +0000 @@ -9,6 +9,7 @@ # modified with no restriction; raw copies as well as modified versions # may be distributed without limitation. +from __future__ import unicode_literals import sys, os, random from PyQt4 import QtGui, QtCore @@ -64,7 +65,7 @@ def update_figure(self): # Build a list of 4 random integers between 0 and 10 (both inclusive) - l = [ random.randint(0, 10) for i in xrange(4) ] + l = [ random.randint(0, 10) for i in range(4) ] self.axes.plot([0, 1, 2, 3], l, 'r') self.draw() @@ -107,16 +108,16 @@ self.fileQuit() def about(self): - QtGui.QMessageBox.about(self, "About %s" % progname, -u"""%(prog)s version %(version)s -Copyright \N{COPYRIGHT SIGN} 2005 Florent Rougon, 2006 Darren Dale + QtGui.QMessageBox.about(self, "About", +"""embedding_in_qt4.py example +Copyright 2005 Florent Rougon, 2006 Darren Dale This program is a simple example of a Qt4 application embedding matplotlib canvases. It may be used and modified with no restriction; raw copies as well as modified versions may be distributed without limitation.""" -% {"prog": progname, "version": progversion}) +) qApp = QtGui.QApplication(sys.argv) diff -Nru matplotlib-1.1.1/examples/user_interfaces/embedding_in_qt4_wtoolbar.py matplotlib-1.2.0/examples/user_interfaces/embedding_in_qt4_wtoolbar.py --- matplotlib-1.1.1/examples/user_interfaces/embedding_in_qt4_wtoolbar.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/embedding_in_qt4_wtoolbar.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,67 @@ +from __future__ import print_function + +import sys + +import numpy as np +from matplotlib.figure import Figure +from matplotlib.backend_bases import key_press_handler +from matplotlib.backends.backend_qt4agg import ( + FigureCanvasQTAgg as FigureCanvas, + NavigationToolbar2QTAgg as NavigationToolbar) +from PyQt4.QtCore import * +from PyQt4.QtGui import * + + +class AppForm(QMainWindow): + def __init__(self, parent=None): + QMainWindow.__init__(self, parent) + #self.x, self.y = self.get_data() + self.data = self.get_data2() + self.create_main_frame() + self.on_draw() + + def create_main_frame(self): + self.main_frame = QWidget() + + self.fig = Figure((5.0, 4.0), dpi=100) + self.canvas = FigureCanvas(self.fig) + self.canvas.setParent(self.main_frame) + self.canvas.setFocusPolicy(Qt.StrongFocus) + self.canvas.setFocus() + + self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame) + + self.canvas.mpl_connect('key_press_event', self.on_key_press) + + vbox = QVBoxLayout() + vbox.addWidget(self.canvas) # the matplotlib canvas + vbox.addWidget(self.mpl_toolbar) + self.main_frame.setLayout(vbox) + self.setCentralWidget(self.main_frame) + + def get_data2(self): + return np.arange(20).reshape([4, 5]).copy() + + def on_draw(self): + self.fig.clear() + self.axes = self.fig.add_subplot(111) + #self.axes.plot(self.x, self.y, 'ro') + self.axes.imshow(self.data, interpolation='nearest') + #self.axes.plot([1,2,3]) + self.canvas.draw() + + def on_key_press(self, event): + print('you pressed', event.key) + # implement the default mpl key press events described at + # http://matplotlib.org/users/navigation_toolbar.html#navigation-keyboard-shortcuts + key_press_handler(event, self.canvas, self.mpl_toolbar) + + +def main(): + app = QApplication(sys.argv) + form = AppForm() + form.show() + app.exec_() + +if __name__ == "__main__": + main() diff -Nru matplotlib-1.1.1/examples/user_interfaces/embedding_in_tk.py matplotlib-1.2.0/examples/user_interfaces/embedding_in_tk.py --- matplotlib-1.1.1/examples/user_interfaces/embedding_in_tk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/embedding_in_tk.py 2012-10-31 00:11:13.000000000 +0000 @@ -5,10 +5,17 @@ from numpy import arange, sin, pi from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +# implement the default mpl key bindings +from matplotlib.backend_bases import key_press_handler + + from matplotlib.figure import Figure -import Tkinter as Tk import sys +if sys.version_info[0] < 3: + import Tkinter as Tk +else: + import tkinter as Tk root = Tk.Tk() root.wm_title("Embedding in TK") @@ -31,6 +38,12 @@ toolbar.update() canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) +def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvas, toolbar) + +canvas.mpl_connect('key_press_event', on_key_event) + def _quit(): root.quit() # stops mainloop root.destroy() # this is necessary on Windows to prevent diff -Nru matplotlib-1.1.1/examples/user_interfaces/embedding_in_tk2.py matplotlib-1.2.0/examples/user_interfaces/embedding_in_tk2.py --- matplotlib-1.1.1/examples/user_interfaces/embedding_in_tk2.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/embedding_in_tk2.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,45 @@ +#!/usr/bin/env python +import matplotlib +matplotlib.use('TkAgg') + +from numpy import arange, sin, pi +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +from matplotlib.figure import Figure + +import sys +if sys.version_info[0] < 3: + import Tkinter as Tk +else: + import tkinter as Tk + +def destroy(e): sys.exit() + +root = Tk.Tk() +root.wm_title("Embedding in TK") +#root.bind("", destroy) + + +f = Figure(figsize=(5,4), dpi=100) +a = f.add_subplot(111) +t = arange(0.0,3.0,0.01) +s = sin(2*pi*t) + +a.plot(t,s) +a.set_title('Tk embedding') +a.set_xlabel('X axis label') +a.set_ylabel('Y label') + + +# a tk.DrawingArea +canvas = FigureCanvasTkAgg(f, master=root) +canvas.show() +canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) + +#toolbar = NavigationToolbar2TkAgg( canvas, root ) +#toolbar.update() +canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) + +button = Tk.Button(master=root, text='Quit', command=sys.exit) +button.pack(side=Tk.BOTTOM) + +Tk.mainloop() diff -Nru matplotlib-1.1.1/examples/user_interfaces/embedding_in_wx2.py matplotlib-1.2.0/examples/user_interfaces/embedding_in_wx2.py --- matplotlib-1.1.1/examples/user_interfaces/embedding_in_wx2.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/embedding_in_wx2.py 2012-10-31 00:11:13.000000000 +0000 @@ -32,7 +32,7 @@ wx.Frame.__init__(self,None,-1, 'CanvasFrame',size=(550,350)) - self.SetBackgroundColour(wx.NamedColor("WHITE")) + self.SetBackgroundColour(wx.NamedColour("WHITE")) self.figure = Figure() self.axes = self.figure.add_subplot(111) diff -Nru matplotlib-1.1.1/examples/user_interfaces/embedding_in_wx3.py matplotlib-1.2.0/examples/user_interfaces/embedding_in_wx3.py --- matplotlib-1.1.1/examples/user_interfaces/embedding_in_wx3.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/embedding_in_wx3.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,5 @@ #!/usr/bin/env python + """ Copyright (C) 2003-2004 Andrew Straw, Jeremy O'Donoghue and others @@ -18,6 +19,7 @@ Thanks to matplotlib and wx teams for creating such great software! """ +from __future__ import print_function # Used to guarantee to use at least Wx2.8 import wxversion @@ -30,7 +32,7 @@ import matplotlib.cbook as cbook from matplotlib.backends.backend_wxagg import Toolbar, FigureCanvasWxAgg from matplotlib.figure import Figure -import numpy as npy +import numpy as np import wx import wx.xrc as xrc @@ -63,14 +65,14 @@ def init_plot_data(self): a = self.fig.add_subplot(111) - x = npy.arange(120.0)*2*npy.pi/60.0 - y = npy.arange(100.0)*2*npy.pi/50.0 - self.x, self.y = npy.meshgrid(x, y) - z = npy.sin(self.x) + npy.cos(self.y) + x = np.arange(120.0)*2*np.pi/60.0 + y = np.arange(100.0)*2*np.pi/50.0 + self.x, self.y = np.meshgrid(x, y) + z = np.sin(self.x) + np.cos(self.y) self.im = a.imshow( z, cmap=cm.jet)#, interpolation='nearest') - zmax = npy.amax(z) - ERR_TOL - ymax_i, xmax_i = npy.nonzero(z >= zmax) + zmax = np.amax(z) - ERR_TOL + ymax_i, xmax_i = np.nonzero(z >= zmax) if self.im.origin == 'upper': ymax_i = z.shape[0]-ymax_i self.lines = a.plot(xmax_i,ymax_i,'ko') @@ -83,13 +85,13 @@ return self.toolbar def OnWhiz(self,evt): - self.x += npy.pi/15 - self.y += npy.pi/20 - z = npy.sin(self.x) + npy.cos(self.y) + self.x += np.pi/15 + self.y += np.pi/20 + z = np.sin(self.x) + np.cos(self.y) self.im.set_array(z) - zmax = npy.amax(z) - ERR_TOL - ymax_i, xmax_i = npy.nonzero(z >= zmax) + zmax = np.amax(z) - ERR_TOL + ymax_i, xmax_i = np.nonzero(z >= zmax) if self.im.origin == 'upper': ymax_i = z.shape[0]-ymax_i self.lines[0].set_data(xmax_i,ymax_i) @@ -103,7 +105,7 @@ class MyApp(wx.App): def OnInit(self): xrcfile = cbook.get_sample_data('embedding_in_wx3.xrc', asfileobj=False) - print 'loading', xrcfile + print('loading', xrcfile) self.res = xrc.XmlResource(xrcfile) diff -Nru matplotlib-1.1.1/examples/user_interfaces/embedding_in_wx4.py matplotlib-1.2.0/examples/user_interfaces/embedding_in_wx4.py --- matplotlib-1.1.1/examples/user_interfaces/embedding_in_wx4.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/embedding_in_wx4.py 2012-10-31 00:11:13.000000000 +0000 @@ -61,7 +61,7 @@ wx.Frame.__init__(self,None,-1, 'CanvasFrame',size=(550,350)) - self.SetBackgroundColour(wx.NamedColor("WHITE")) + self.SetBackgroundColour(wx.NamedColour("WHITE")) self.figure = Figure(figsize=(5,4), dpi=100) self.axes = self.figure.add_subplot(111) diff -Nru matplotlib-1.1.1/examples/user_interfaces/interactive.py matplotlib-1.2.0/examples/user_interfaces/interactive.py --- matplotlib-1.1.1/examples/user_interfaces/interactive.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/interactive.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,5 @@ #!/usr/bin/env python + """Multithreaded interactive interpreter with GTK and Matplotlib support. WARNING: @@ -21,6 +22,8 @@ Also borrows liberally from code.py in the Python standard library.""" +from __future__ import print_function + __author__ = "Fernando Perez " import sys @@ -123,11 +126,11 @@ self.ready.acquire() if self._kill: - print 'Closing threads...', + print('Closing threads...') sys.stdout.flush() for tokill in self.on_kill: tokill() - print 'Done.' + print('Done.') if self.code_to_run is not None: self.ready.notify() @@ -215,19 +218,19 @@ try: inFile = file(fname, 'r') except IOError: - print '*** ERROR *** Could not read file <%s>' % fname + print('*** ERROR *** Could not read file <%s>' % fname) else: - print '*** Executing file <%s>:' % fname + print('*** Executing file <%s>:' % fname) for line in inFile: if line.lstrip().find('show()')==0: continue - print '>>', line, + print('>>', line) push(line) inFile.close() matplotlib.interactive(1) # turn on interaction if __name__ == '__main__': - print "This demo is not presently functional, so running" - print "it as a script has been disabled." + print("This demo is not presently functional, so running") + print("it as a script has been disabled.") sys.exit() # Quick sys.argv hack to extract the option and leave filenames in sys.argv. # For real option handling, use optparse or getopt. diff -Nru matplotlib-1.1.1/examples/user_interfaces/interactive2.py matplotlib-1.2.0/examples/user_interfaces/interactive2.py --- matplotlib-1.1.1/examples/user_interfaces/interactive2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/interactive2.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import print_function + # GTK Interactive Console # (C) 2003, Jon Anderson # See www.python.org/2.2/license.html for @@ -367,7 +369,7 @@ if len(sys.argv)>1: fname = sys.argv[1] if not os.path.exists(fname): - print >> sys.stderr, '%s does not exist' % fname + print('%s does not exist' % fname) for line in file(fname): line = line.strip() diff -Nru matplotlib-1.1.1/examples/user_interfaces/lineprops_dialog_gtk.py matplotlib-1.2.0/examples/user_interfaces/lineprops_dialog_gtk.py --- matplotlib-1.1.1/examples/user_interfaces/lineprops_dialog_gtk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/lineprops_dialog_gtk.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,7 +3,7 @@ from matplotlib.backends.backend_gtk import DialogLineprops import numpy as np -from pylab import figure, show +import matplotlib.pyplot as plt def f(t): s1 = np.cos(2*np.pi*t) @@ -14,12 +14,12 @@ t2 = np.arange(0.0, 5.0, 0.02) t3 = np.arange(0.0, 2.0, 0.01) -fig = figure() +fig = plt.figure() ax = fig.add_subplot(111) l1, = ax.plot(t1, f(t1), 'bo', label='line 1') l2, = ax.plot(t2, f(t2), 'k--', label='line 2') dlg = DialogLineprops([l1,l2]) dlg.show() -show() +plt.show() diff -Nru matplotlib-1.1.1/examples/user_interfaces/mathtext_wx.py matplotlib-1.2.0/examples/user_interfaces/mathtext_wx.py --- matplotlib-1.1.1/examples/user_interfaces/mathtext_wx.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/mathtext_wx.py 2012-10-31 00:11:13.000000000 +0000 @@ -37,7 +37,7 @@ class CanvasFrame(wx.Frame): def __init__(self, parent, title): wx.Frame.__init__(self, parent, -1, title, size=(550, 350)) - self.SetBackgroundColour(wx.NamedColor("WHITE")) + self.SetBackgroundColour(wx.NamedColour("WHITE")) self.figure = Figure() self.axes = self.figure.add_subplot(111) diff -Nru matplotlib-1.1.1/examples/user_interfaces/mpl_with_glade.py matplotlib-1.2.0/examples/user_interfaces/mpl_with_glade.py --- matplotlib-1.1.1/examples/user_interfaces/mpl_with_glade.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/mpl_with_glade.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,6 @@ #!/usr/bin/env python + +from __future__ import print_function import matplotlib matplotlib.use('GTK') @@ -64,15 +66,15 @@ self.canvas.grab_focus() def keypress(widget, event): - print 'key press' + print('key press') def buttonpress(widget, event): - print 'button press' + print('button press') self.canvas.connect('key_press_event', keypress) self.canvas.connect('button_press_event', buttonpress) def onselect(xmin, xmax): - print xmin, xmax + print(xmin, xmax) span = SpanSelector(self.axis, onselect, 'horizontal', useblit=False, rectprops=dict(alpha=0.5, facecolor='red') ) diff -Nru matplotlib-1.1.1/examples/user_interfaces/printing_in_wx.py matplotlib-1.2.0/examples/user_interfaces/printing_in_wx.py --- matplotlib-1.1.1/examples/user_interfaces/printing_in_wx.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/printing_in_wx.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,8 @@ #!/usr/bin/env python # printing_in_wx.py # + +from __future__ import print_function """ This examples demonstrates Printing (ie, to a printer) with a matplotlib figure using a wx Frame. This borrows the data from @@ -166,7 +168,7 @@ self.canvas.print_figure(path,dpi=300) if (path.find(thisdir) == 0): path = path[len(thisdir)+1:] - print 'Saved plot to %s' % path + print('Saved plot to %s' % path) def onExit(self,event=None): self.Destroy() diff -Nru matplotlib-1.1.1/examples/user_interfaces/pylab_with_gtk.py matplotlib-1.2.0/examples/user_interfaces/pylab_with_gtk.py --- matplotlib-1.1.1/examples/user_interfaces/pylab_with_gtk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/pylab_with_gtk.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,17 +2,19 @@ An example of how to use pylab to manage your figure windows, but modify the GUI by accessing the underlying gtk widgets """ +from __future__ import print_function import matplotlib matplotlib.use('GTKAgg') -from pylab import get_current_fig_manager, subplot, plot, legend, connect, show +import matplotlib.pyplot as plt -ax = subplot(111) -plot([1,2,3], 'ro-', label='easy as 1 2 3') -plot([1,4,9], 'gs--', label='easy as 1 2 3 squared') -legend() +ax = plt.subplot(111) +plt.plot([1,2,3], 'ro-', label='easy as 1 2 3') +plt.plot([1,4,9], 'gs--', label='easy as 1 2 3 squared') +plt.legend() -manager = get_current_fig_manager() + +manager = plt.get_current_fig_manager() # you can also access the window or vbox attributes this way toolbar = manager.toolbar @@ -23,7 +25,7 @@ button.show() def clicked(button): - print 'hi mom' + print('hi mom') button.connect('clicked', clicked) toolitem = gtk.ToolItem() @@ -49,6 +51,6 @@ else: label.set_markup('x,y=(%f, %f)'%(event.xdata, event.ydata)) -connect('motion_notify_event', update) +plt.connect('motion_notify_event', update) -show() +plt.show() diff -Nru matplotlib-1.1.1/examples/user_interfaces/rec_edit_gtk_custom.py matplotlib-1.2.0/examples/user_interfaces/rec_edit_gtk_custom.py --- matplotlib-1.1.1/examples/user_interfaces/rec_edit_gtk_custom.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/rec_edit_gtk_custom.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,6 +3,7 @@ formatting of the cells and show how to limit string entries to a list of strings """ +from __future__ import print_function import gtk import numpy as np import matplotlib.mlab as mlab @@ -28,7 +29,7 @@ treeview = gtktools.RecTreeView(liststore, constant=constant) def mycallback(liststore, rownum, colname, oldval, newval): - print 'verify: old=%s, new=%s, rec=%s'%(oldval, newval, liststore.r[rownum][colname]) + print('verify: old=%s, new=%s, rec=%s'%(oldval, newval, liststore.r[rownum][colname])) liststore.callbacks.connect('cell_changed', mycallback) diff -Nru matplotlib-1.1.1/examples/user_interfaces/svg_histogram.py matplotlib-1.2.0/examples/user_interfaces/svg_histogram.py --- matplotlib-1.1.1/examples/user_interfaces/svg_histogram.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/svg_histogram.py 2012-10-31 00:11:13.000000000 +0000 @@ -5,19 +5,38 @@ Demonstrate how to create an interactive histogram, in which bars are hidden or shown by cliking on legend markers. -The interactivity is encoded in ecmascript and inserted in the SVG code -in a post-processing step. To render the image, open it in a web -browser. SVG is supported in most web browsers used by Linux and OSX -users. Windows IE9 supports SVG, but earlier versions do not. +The interactivity is encoded in ecmascript (javascript) and inserted in +the SVG code in a post-processing step. To render the image, open it in +a web browser. SVG is supported in most web browsers used by Linux and +OSX users. Windows IE9 supports SVG, but earlier versions do not. + +Notes +----- +The matplotlib backend lets us assign ids to each object. This is the +mechanism used here to relate matplotlib objects created in python and +the corresponding SVG constructs that are parsed in the second step. +While flexible, ids are cumbersome to use for large collection of +objects. Two mechanisms could be used to simplify things: + * systematic grouping of objects into SVG tags, + * assingning classes to each SVG object according to its origin. + +For example, instead of modifying the properties of each individual bar, +the bars from the `hist` function could either be grouped in +a PatchCollection, or be assigned a class="hist_##" attribute. + +CSS could also be used more extensively to replace repetitive markup +troughout the generated SVG. __author__="david.huard@gmail.com" """ + import numpy as np import matplotlib.pyplot as plt import xml.etree.ElementTree as ET from StringIO import StringIO +import json plt.rcParams['svg.embed_char_paths'] = 'none' @@ -26,16 +45,7 @@ # space with ns0. ET.register_namespace("","http://www.w3.org/2000/svg") - -def python2js(d): - """Return a string representation of a python dictionary in - ecmascript object syntax.""" - - objs = [] - for key, value in d.items(): - objs.append( key + ':' + str(value) ) - - return '{' + ', '.join(objs) + '}' + # --- Create histogram, legend and title --- @@ -62,7 +72,11 @@ # Set ids for the legend patches for i, t in enumerate(leg.get_patches()): t.set_gid('leg_patch_%d'%i) - + +# Set ids for the text patches +for i, t in enumerate(leg.get_texts()): + t.set_gid('leg_text_%d'%i) + # Save SVG in a fake file object. f = StringIO() plt.savefig(f, format="svg") @@ -77,10 +91,15 @@ for i, t in enumerate(leg.get_patches()): el = xmlid['leg_patch_%d'%i] el.set('cursor', 'pointer') - el.set('opacity', '1.0') - el.set('onclick', "toggle_element(evt, 'hist_%d')"%i) + el.set('onclick', "toggle_hist(this)") -# Create script defining the function `toggle_element`. +# Add attributes to the text objects. +for i, t in enumerate(leg.get_texts()): + el = xmlid['leg_text_%d'%i] + el.set('cursor', 'pointer') + el.set('onclick', "toggle_hist(this)") + +# Create script defining the function `toggle_hist`. # We create a global variable `container` that stores the patches id # belonging to each histogram. Then a function "toggle_element" sets the # visibility attribute of all patches of each histogram and the opacity @@ -91,37 +110,46 @@ -"""%python2js(hist_patches) +"""%json.dumps(hist_patches) +# Add a transition effect +css = tree.getchildren()[0][0] +css.text = css.text + "g {-webkit-transition:opacity 0.4s ease-out;-moz-transition:opacity 0.4s ease-out;}" + # Insert the script and save to file. tree.insert(0, ET.XML(script)) diff -Nru matplotlib-1.1.1/examples/user_interfaces/svg_tooltip.py matplotlib-1.2.0/examples/user_interfaces/svg_tooltip.py --- matplotlib-1.1.1/examples/user_interfaces/svg_tooltip.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/svg_tooltip.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,125 @@ +""" +SVG tooltip example +=================== + +This example shows how to create a tooltip that will show up when +hovering over a matplotlib patch. + +Although it is possible to create the tooltip from CSS or javascript, +here we create it in matplotlib and simply toggle its visibility on +when hovering over the patch. This approach provides total control over +the tooltip placement and appearance, at the expense of more code up +front. + +The alternative approach would be to put the tooltip content in `title` +atttributes of SVG objects. Then, using an existing js/CSS library, it +would be relatively straightforward to create the tooltip in the +browser. The content would be dictated by the `title` attribute, and +the appearance by the CSS. + + +:author: David Huard +""" + + +import matplotlib.pyplot as plt +import xml.etree.ElementTree as ET +from StringIO import StringIO + +ET.register_namespace("","http://www.w3.org/2000/svg") + +fig = plt.figure() +ax = fig.add_subplot(111) + +# Create patches to which tooltips will be assigned. +circle = plt.Circle((0,0), 5, fc='blue') +rect = plt.Rectangle((-5, 10), 10, 5, fc='green') + +ax.add_patch(circle) +ax.add_patch(rect) + +# Create the tooltips +circle_tip = ax.annotate('This is a blue circle.', + xy=(0,0), + xytext=(30,-30), + textcoords='offset points', + color='w', + ha='left', + bbox=dict(boxstyle='round,pad=.5', fc=(.1,.1,.1,.92), ec=(1.,1.,1.), lw=1, zorder=1), + ) + +rect_tip = ax.annotate('This is a green rectangle.', + xy=(-5,10), + xytext=(30,40), + textcoords='offset points', + color='w', + ha='left', + bbox=dict(boxstyle='round,pad=.5', fc=(.1,.1,.1,.92), ec=(1.,1.,1.), lw=1, zorder=1), + ) + + +# Set id for the patches +for i, t in enumerate(ax.patches): + t.set_gid('patch_%d'%i) + +# Set id for the annotations +for i, t in enumerate(ax.texts): + t.set_gid('tooltip_%d'%i) + + +# Save the figure in a fake file object +ax.set_xlim(-30, 30) +ax.set_ylim(-30, 30) +ax.set_aspect('equal') + +f = StringIO() +plt.savefig(f, format="svg") + +# --- Add interactivity --- + +# Create XML tree from the SVG file. +tree, xmlid = ET.XMLID(f.getvalue()) +tree.set('onload', 'init(evt)') + +# Hide the tooltips +for i, t in enumerate(ax.texts): + el = xmlid['tooltip_%d'%i] + el.set('visibility', 'hidden') + +# Assign onmouseover and onmouseout callbacks to patches. +for i, t in enumerate(ax.patches): + el = xmlid['patch_%d'%i] + el.set('onmouseover', "ShowTooltip(this)") + el.set('onmouseout', "HideTooltip(this)") + +# This is the script defining the ShowTooltip and HideTooltip functions. +script = """ + + """ + +# Insert the script at the top of the file and save it. +tree.insert(0, ET.XML(script)) +ET.ElementTree(tree).write('svg_tooltip.svg') diff -Nru matplotlib-1.1.1/examples/user_interfaces/wxcursor_demo.py matplotlib-1.2.0/examples/user_interfaces/wxcursor_demo.py --- matplotlib-1.1.1/examples/user_interfaces/wxcursor_demo.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/examples/user_interfaces/wxcursor_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -18,7 +18,7 @@ wx.Frame.__init__(self,None,-1, 'CanvasFrame',size=(550,350)) - self.SetBackgroundColour(wx.NamedColor("WHITE")) + self.SetBackgroundColour(wx.NamedColour("WHITE")) self.figure = Figure() self.axes = self.figure.add_subplot(111) diff -Nru matplotlib-1.1.1/examples/widgets/lasso_selector_demo.py matplotlib-1.2.0/examples/widgets/lasso_selector_demo.py --- matplotlib-1.1.1/examples/widgets/lasso_selector_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/examples/widgets/lasso_selector_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,89 @@ +from __future__ import print_function + +import numpy as np + +from matplotlib.widgets import LassoSelector +from matplotlib.path import Path + +try: + raw_input +except NameError: + # Python 3 + raw_input = input + + +class SelectFromCollection(object): + """Select indices from a matplotlib collection using `LassoSelector`. + + Selected indices are saved in the `ind` attribute. This tool highlights + selected points by fading them out (i.e., reducing their alpha values). + If your collection has alpha < 1, this tool will permanently alter them. + + Note that this tool selects collection objects based on their *origins* + (i.e., `offsets`). + + Parameters + ---------- + ax : :class:`~matplotlib.axes.Axes` + Axes to interact with. + + collection : :class:`matplotlib.collections.Collection` subclass + Collection you want to select from. + + alpha_other : 0 <= float <= 1 + To highlight a selection, this tool sets all selected points to an + alpha value of 1 and non-selected points to `alpha_other`. + """ + def __init__(self, ax, collection, alpha_other=0.3): + self.canvas = ax.figure.canvas + self.collection = collection + self.alpha_other = alpha_other + + self.xys = collection.get_offsets() + self.Npts = len(self.xys) + + # Ensure that we have separate colors for each object + self.fc = collection.get_facecolors() + if len(self.fc) == 0: + raise ValueError('Collection must have a facecolor') + elif len(self.fc) == 1: + self.fc = np.tile(self.fc, self.Npts).reshape(self.Npts, -1) + + self.lasso = LassoSelector(ax, onselect=self.onselect) + self.ind = [] + + def onselect(self, verts): + path = Path(verts) + self.ind = np.nonzero([path.contains_point(xy) for xy in self.xys])[0] + self.fc[:, -1] = self.alpha_other + self.fc[self.ind, -1] = 1 + self.collection.set_facecolors(self.fc) + self.canvas.draw_idle() + + def disconnect(self): + self.lasso.disconnect_events() + self.fc[:, -1] = 1 + self.collection.set_facecolors(self.fc) + self.canvas.draw_idle() + + +if __name__ == '__main__': + import matplotlib.pyplot as plt + + plt.ion() + data = np.random.rand(100, 2) + + subplot_kw = dict(xlim=(0, 1), ylim=(0, 1), autoscale_on=False) + fig, ax = plt.subplots(subplot_kw=subplot_kw) + + pts = ax.scatter(data[:, 0], data[:, 1], s=80) + selector = SelectFromCollection(ax, pts) + + plt.draw() + raw_input('Press any key to accept selected points') + print("Selected points:") + print(selector.xys[selector.ind]) + selector.disconnect() + + # Block end of script so you can check that the lasso is disconnected. + raw_input('Press any key to quit') diff -Nru matplotlib-1.1.1/examples/widgets/menu.py matplotlib-1.2.0/examples/widgets/menu.py --- matplotlib-1.1.1/examples/widgets/menu.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/widgets/menu.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import division, print_function import numpy as np import matplotlib import matplotlib.colors as colors @@ -75,7 +76,7 @@ self.on_select(self) def set_extent(self, x, y, w, h): - print x, y, w, h + print(x, y, w, h) self.rect.set_x(x) self.rect.set_y(y) self.rect.set_width(w) @@ -171,7 +172,7 @@ menuitems = [] for label in ('open', 'close', 'save', 'save as', 'quit'): def on_select(item): - print 'you selected', item.labelstr + print('you selected %s' % item.labelstr) item = MenuItem(fig, label, props=props, hoverprops=hoverprops, on_select=on_select) menuitems.append(item) diff -Nru matplotlib-1.1.1/examples/widgets/multicursor.py matplotlib-1.2.0/examples/widgets/multicursor.py --- matplotlib-1.1.1/examples/widgets/multicursor.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/widgets/multicursor.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,11 @@ +import numpy as np +import matplotlib.pyplot as plt from matplotlib.widgets import MultiCursor -from pylab import figure, show, pi, arange, sin -t = arange(0.0, 2.0, 0.01) -s1 = sin(2*pi*t) -s2 = sin(4*pi*t) -fig = figure() +t = np.arange(0.0, 2.0, 0.01) +s1 = np.sin(2*np.pi*t) +s2 = np.sin(4*np.pi*t) +fig = plt.figure() ax1 = fig.add_subplot(211) ax1.plot(t, s1) @@ -13,4 +14,4 @@ ax2.plot(t, s2) multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1) -show() +plt.show() diff -Nru matplotlib-1.1.1/examples/widgets/radio_buttons.py matplotlib-1.2.0/examples/widgets/radio_buttons.py --- matplotlib-1.1.1/examples/widgets/radio_buttons.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/widgets/radio_buttons.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,36 +1,38 @@ +import numpy as np +import matplotlib.pyplot as plt from matplotlib.widgets import RadioButtons -from pylab import * -t = arange(0.0, 2.0, 0.01) -s0 = sin(2*pi*t) -s1 = sin(4*pi*t) -s2 = sin(8*pi*t) -ax = subplot(111) +t = np.arange(0.0, 2.0, 0.01) +s0 = np.sin(2*np.pi*t) +s1 = np.sin(4*np.pi*t) +s2 = np.sin(8*np.pi*t) + +ax = plt.subplot(111) l, = ax.plot(t, s0, lw=2, color='red') -subplots_adjust(left=0.3) +plt.subplots_adjust(left=0.3) axcolor = 'lightgoldenrodyellow' -rax = axes([0.05, 0.7, 0.15, 0.15], axisbg=axcolor) +rax = plt.axes([0.05, 0.7, 0.15, 0.15], axisbg=axcolor) radio = RadioButtons(rax, ('2 Hz', '4 Hz', '8 Hz')) def hzfunc(label): hzdict = {'2 Hz':s0, '4 Hz':s1, '8 Hz':s2} ydata = hzdict[label] l.set_ydata(ydata) - draw() + plt.draw() radio.on_clicked(hzfunc) -rax = axes([0.05, 0.4, 0.15, 0.15], axisbg=axcolor) +rax = plt.axes([0.05, 0.4, 0.15, 0.15], axisbg=axcolor) radio2 = RadioButtons(rax, ('red', 'blue', 'green')) def colorfunc(label): l.set_color(label) - draw() + plt.draw() radio2.on_clicked(colorfunc) -rax = axes([0.05, 0.1, 0.15, 0.15], axisbg=axcolor) +rax = plt.axes([0.05, 0.1, 0.15, 0.15], axisbg=axcolor) radio3 = RadioButtons(rax, ('-', '--', '-.', 'steps', ':')) def stylefunc(label): l.set_linestyle(label) - draw() + plt.draw() radio3.on_clicked(stylefunc) -show() +plt.show() diff -Nru matplotlib-1.1.1/examples/widgets/rectangle_selector.py matplotlib-1.2.0/examples/widgets/rectangle_selector.py --- matplotlib-1.1.1/examples/widgets/rectangle_selector.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/widgets/rectangle_selector.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function """ Do a mouseclick somewhere, move the mouse to some destination, release the button. This class gives click- and release-events and also draws @@ -15,16 +16,16 @@ 'eclick and erelease are the press and release events' x1, y1 = eclick.xdata, eclick.ydata x2, y2 = erelease.xdata, erelease.ydata - print "(%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1, y1, x2, y2) - print " The button you used were: ", eclick.button, erelease.button + print ("(%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1, y1, x2, y2)) + print (" The button you used were: %s %s" % (eclick.button, erelease.button)) def toggle_selector(event): - print ' Key pressed.' + print (' Key pressed.') if event.key in ['Q', 'q'] and toggle_selector.RS.active: - print ' RectangleSelector deactivated.' + print (' RectangleSelector deactivated.') toggle_selector.RS.set_active(False) if event.key in ['A', 'a'] and not toggle_selector.RS.active: - print ' RectangleSelector activated.' + print (' RectangleSelector activated.') toggle_selector.RS.set_active(True) @@ -36,7 +37,7 @@ plt.plot(x, +np.cos(.2*np.pi*x), lw=3.5, c='r', alpha=.5) plt.plot(x, -np.sin(.2*np.pi*x), lw=3.5, c='g', alpha=.3) -print "\n click --> release" +print ("\n click --> release") # drawtype is 'box' or 'line' or 'none' toggle_selector.RS = RectangleSelector(current_ax, line_select_callback, diff -Nru matplotlib-1.1.1/examples/widgets/slider_demo.py matplotlib-1.2.0/examples/widgets/slider_demo.py --- matplotlib-1.1.1/examples/widgets/slider_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/widgets/slider_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,18 +1,19 @@ -from pylab import * +import numpy as np +import matplotlib.pyplot as plt from matplotlib.widgets import Slider, Button, RadioButtons -ax = subplot(111) -subplots_adjust(left=0.25, bottom=0.25) -t = arange(0.0, 1.0, 0.001) +ax = plt.subplot(111) +plt.subplots_adjust(left=0.25, bottom=0.25) +t = np.arange(0.0, 1.0, 0.001) a0 = 5 f0 = 3 -s = a0*sin(2*pi*f0*t) -l, = plot(t,s, lw=2, color='red') -axis([0, 1, -10, 10]) +s = a0*np.sin(2*np.pi*f0*t) +l, = plt.plot(t,s, lw=2, color='red') +plt.axis([0, 1, -10, 10]) axcolor = 'lightgoldenrodyellow' -axfreq = axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor) -axamp = axes([0.25, 0.15, 0.65, 0.03], axisbg=axcolor) +axfreq = plt.axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor) +axamp = plt.axes([0.25, 0.15, 0.65, 0.03], axisbg=axcolor) sfreq = Slider(axfreq, 'Freq', 0.1, 30.0, valinit=f0) samp = Slider(axamp, 'Amp', 0.1, 10.0, valinit=a0) @@ -20,24 +21,24 @@ def update(val): amp = samp.val freq = sfreq.val - l.set_ydata(amp*sin(2*pi*freq*t)) - draw() + l.set_ydata(amp*np.sin(2*np.pi*freq*t)) + plt.draw() sfreq.on_changed(update) samp.on_changed(update) -resetax = axes([0.8, 0.025, 0.1, 0.04]) +resetax = plt.axes([0.8, 0.025, 0.1, 0.04]) button = Button(resetax, 'Reset', color=axcolor, hovercolor='0.975') def reset(event): sfreq.reset() samp.reset() button.on_clicked(reset) -rax = axes([0.025, 0.5, 0.15, 0.15], axisbg=axcolor) +rax = plt.axes([0.025, 0.5, 0.15, 0.15], axisbg=axcolor) radio = RadioButtons(rax, ('red', 'blue', 'green'), active=0) def colorfunc(label): l.set_color(label) - draw() + plt.draw() radio.on_clicked(colorfunc) -show() +plt.show() diff -Nru matplotlib-1.1.1/examples/widgets/span_selector.py matplotlib-1.2.0/examples/widgets/span_selector.py --- matplotlib-1.1.1/examples/widgets/span_selector.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/examples/widgets/span_selector.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,15 +3,15 @@ The SpanSelector is a mouse widget to select a xmin/xmax range and plot the detail view of the selected region in the lower axes """ -import numpy as npy -from pylab import figure, show +import numpy as np +import matplotlib.pyplot as plt from matplotlib.widgets import SpanSelector -fig = figure(figsize=(8,6)) +fig = plt.figure(figsize=(8,6)) ax = fig.add_subplot(211, axisbg='#FFFFCC') -x = npy.arange(0.0, 5.0, 0.01) -y = npy.sin(2*npy.pi*x) + 0.5*npy.random.randn(len(x)) +x = np.arange(0.0, 5.0, 0.01) +y = np.sin(2*np.pi*x) + 0.5*np.random.randn(len(x)) ax.plot(x, y, '-') ax.set_ylim(-2,2) @@ -22,7 +22,7 @@ def onselect(xmin, xmax): - indmin, indmax = npy.searchsorted(x, (xmin, xmax)) + indmin, indmax = np.searchsorted(x, (xmin, xmax)) indmax = min(len(x)-1, indmax) thisx = x[indmin:indmax] @@ -37,4 +37,4 @@ rectprops=dict(alpha=0.5, facecolor='red') ) -show() +plt.show() diff -Nru matplotlib-1.1.1/lib/dateutil/LICENSE matplotlib-1.2.0/lib/dateutil/LICENSE --- matplotlib-1.1.1/lib/dateutil/LICENSE 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil/LICENSE 1970-01-01 00:00:00.000000000 +0000 @@ -1,259 +0,0 @@ -A. HISTORY OF THE SOFTWARE -========================== - -Python was created in the early 1990s by Guido van Rossum at Stichting -Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands -as a successor of a language called ABC. Guido remains Python's -principal author, although it includes many contributions from others. - -In 1995, Guido continued his work on Python at the Corporation for -National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) -in Reston, Virginia where he released several versions of the -software. - -In May 2000, Guido and the Python core development team moved to -BeOpen.com to form the BeOpen PythonLabs team. In October of the same -year, the PythonLabs team moved to Digital Creations (now Zope -Corporation, see http://www.zope.com). In 2001, the Python Software -Foundation (PSF, see http://www.python.org/psf/) was formed, a -non-profit organization created specifically to own Python-related -Intellectual Property. Zope Corporation is a sponsoring member of -the PSF. - -All Python releases are Open Source (see http://www.opensource.org for -the Open Source Definition). Historically, most, but not all, Python -releases have also been GPL-compatible; the table below summarizes -the various releases. - - Release Derived Year Owner GPL- - from compatible? (1) - - 0.9.0 thru 1.2 1991-1995 CWI yes - 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes - 1.6 1.5.2 2000 CNRI no - 2.0 1.6 2000 BeOpen.com no - 1.6.1 1.6 2001 CNRI yes (2) - 2.1 2.0+1.6.1 2001 PSF no - 2.0.1 2.0+1.6.1 2001 PSF yes - 2.1.1 2.1+2.0.1 2001 PSF yes - 2.2 2.1.1 2001 PSF yes - 2.1.2 2.1.1 2002 PSF yes - 2.1.3 2.1.2 2002 PSF yes - 2.2.1 2.2 2002 PSF yes - 2.2.2 2.2.1 2002 PSF yes - 2.2.3 2.2.2 2003 PSF yes - 2.3 2.2.2 2002-2003 PSF yes - -Footnotes: - -(1) GPL-compatible doesn't mean that we're distributing Python under - the GPL. All Python licenses, unlike the GPL, let you distribute - a modified version without making your changes open source. The - GPL-compatible licenses make it possible to combine Python with - other software that is released under the GPL; the others don't. - -(2) According to Richard Stallman, 1.6.1 is not GPL-compatible, - because its license has a choice of law clause. According to - CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 - is "not incompatible" with the GPL. - -Thanks to the many outside volunteers who have worked under Guido's -direction to make these releases possible. - - -B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON -=============================================================== - -PSF LICENSE AGREEMENT FOR PYTHON 2.3 ------------------------------------- - -1. This LICENSE AGREEMENT is between the Python Software Foundation -("PSF"), and the Individual or Organization ("Licensee") accessing and -otherwise using Python 2.3 software in source or binary form and its -associated documentation. - -2. Subject to the terms and conditions of this License Agreement, PSF -hereby grants Licensee a nonexclusive, royalty-free, world-wide -license to reproduce, analyze, test, perform and/or display publicly, -prepare derivative works, distribute, and otherwise use Python 2.3 -alone or in any derivative version, provided, however, that PSF's -License Agreement and PSF's notice of copyright, i.e., "Copyright (c) -2001, 2002, 2003 Python Software Foundation; All Rights Reserved" are -retained in Python 2.3 alone or in any derivative version prepared by -Licensee. - -3. In the event Licensee prepares a derivative work that is based on -or incorporates Python 2.3 or any part thereof, and wants to make -the derivative work available to others as provided herein, then -Licensee hereby agrees to include in any such work a brief summary of -the changes made to Python 2.3. - -4. PSF is making Python 2.3 available to Licensee on an "AS IS" -basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR -IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND -DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS -FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.3 WILL NOT -INFRINGE ANY THIRD PARTY RIGHTS. - -5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON -2.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS -A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.3, -OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. - -6. This License Agreement will automatically terminate upon a material -breach of its terms and conditions. - -7. Nothing in this License Agreement shall be deemed to create any -relationship of agency, partnership, or joint venture between PSF and -Licensee. This License Agreement does not grant permission to use PSF -trademarks or trade name in a trademark sense to endorse or promote -products or services of Licensee, or any third party. - -8. By copying, installing or otherwise using Python 2.3, Licensee -agrees to be bound by the terms and conditions of this License -Agreement. - - -BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 -------------------------------------------- - -BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 - -1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an -office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the -Individual or Organization ("Licensee") accessing and otherwise using -this software in source or binary form and its associated -documentation ("the Software"). - -2. Subject to the terms and conditions of this BeOpen Python License -Agreement, BeOpen hereby grants Licensee a non-exclusive, -royalty-free, world-wide license to reproduce, analyze, test, perform -and/or display publicly, prepare derivative works, distribute, and -otherwise use the Software alone or in any derivative version, -provided, however, that the BeOpen Python License is retained in the -Software, alone or in any derivative version prepared by Licensee. - -3. BeOpen is making the Software available to Licensee on an "AS IS" -basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR -IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND -DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS -FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT -INFRINGE ANY THIRD PARTY RIGHTS. - -4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE -SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS -AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY -DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. - -5. This License Agreement will automatically terminate upon a material -breach of its terms and conditions. - -6. This License Agreement shall be governed by and interpreted in all -respects by the law of the State of California, excluding conflict of -law provisions. Nothing in this License Agreement shall be deemed to -create any relationship of agency, partnership, or joint venture -between BeOpen and Licensee. This License Agreement does not grant -permission to use BeOpen trademarks or trade names in a trademark -sense to endorse or promote products or services of Licensee, or any -third party. As an exception, the "BeOpen Python" logos available at -http://www.pythonlabs.com/logos.html may be used according to the -permissions granted on that web page. - -7. By copying, installing or otherwise using the software, Licensee -agrees to be bound by the terms and conditions of this License -Agreement. - - -CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 ---------------------------------------- - -1. This LICENSE AGREEMENT is between the Corporation for National -Research Initiatives, having an office at 1895 Preston White Drive, -Reston, VA 20191 ("CNRI"), and the Individual or Organization -("Licensee") accessing and otherwise using Python 1.6.1 software in -source or binary form and its associated documentation. - -2. Subject to the terms and conditions of this License Agreement, CNRI -hereby grants Licensee a nonexclusive, royalty-free, world-wide -license to reproduce, analyze, test, perform and/or display publicly, -prepare derivative works, distribute, and otherwise use Python 1.6.1 -alone or in any derivative version, provided, however, that CNRI's -License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) -1995-2001 Corporation for National Research Initiatives; All Rights -Reserved" are retained in Python 1.6.1 alone or in any derivative -version prepared by Licensee. Alternately, in lieu of CNRI's License -Agreement, Licensee may substitute the following text (omitting the -quotes): "Python 1.6.1 is made available subject to the terms and -conditions in CNRI's License Agreement. This Agreement together with -Python 1.6.1 may be located on the Internet using the following -unique, persistent identifier (known as a handle): 1895.22/1013. This -Agreement may also be obtained from a proxy server on the Internet -using the following URL: http://hdl.handle.net/1895.22/1013". - -3. In the event Licensee prepares a derivative work that is based on -or incorporates Python 1.6.1 or any part thereof, and wants to make -the derivative work available to others as provided herein, then -Licensee hereby agrees to include in any such work a brief summary of -the changes made to Python 1.6.1. - -4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" -basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR -IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND -DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS -FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT -INFRINGE ANY THIRD PARTY RIGHTS. - -5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON -1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS -A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, -OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. - -6. This License Agreement will automatically terminate upon a material -breach of its terms and conditions. - -7. This License Agreement shall be governed by the federal -intellectual property law of the United States, including without -limitation the federal copyright law, and, to the extent such -U.S. federal law does not apply, by the law of the Commonwealth of -Virginia, excluding Virginia's conflict of law provisions. -Notwithstanding the foregoing, with regard to derivative works based -on Python 1.6.1 that incorporate non-separable material that was -previously distributed under the GNU General Public License (GPL), the -law of the Commonwealth of Virginia shall govern this License -Agreement only as to issues arising under or with respect to -Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this -License Agreement shall be deemed to create any relationship of -agency, partnership, or joint venture between CNRI and Licensee. This -License Agreement does not grant permission to use CNRI trademarks or -trade name in a trademark sense to endorse or promote products or -services of Licensee, or any third party. - -8. By clicking on the "ACCEPT" button where indicated, or by copying, -installing or otherwise using Python 1.6.1, Licensee agrees to be -bound by the terms and conditions of this License Agreement. - - ACCEPT - - -CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 --------------------------------------------------- - -Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, -The Netherlands. All rights reserved. - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Stichting Mathematisch -Centrum or CWI not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior -permission. - -STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO -THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE -FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff -Nru matplotlib-1.1.1/lib/dateutil/NEWS matplotlib-1.2.0/lib/dateutil/NEWS --- matplotlib-1.1.1/lib/dateutil/NEWS 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil/NEWS 1970-01-01 00:00:00.000000000 +0000 @@ -1,143 +0,0 @@ - -Version 1.5 ------------ - -- As reported by Mathieu Bridon, rrules were matching the bysecond rules - incorrectly against byminute in some circumstances when the SECONDLY - frequency was in use, due to a copy & paste bug. The problem has been - unittested and corrected. - -- Adam Ryan reported a problem in the relativedelta implementation which - affected the yearday parameter in the month of January specifically. - This has been unittested and fixed. - -- Updated timezone information. - - -Version 1.4.1 -------------- - -- Updated timezone information. - - -Version 1.4 ------------ - -- Fixed another parser precision problem on conversion of decimal seconds - to microseconds, as reported by Erik Brown. Now these issues are gone - for real since it's not using floating point arithmetic anymore. - -- Fixed case where tzrange.utcoffset and tzrange.dst() might fail due - to a date being used where a datetime was expected (reported and fixed - by Lennart Regebro). - -- Prevent tzstr from introducing daylight timings in strings that didn't - specify them (reported by Lennart Regebro). - -- Calls like gettz("GMT+3") and gettz("UTC-2") will now return the - expected values, instead of the TZ variable behavior. - -- Fixed DST signal handling in zoneinfo files. Reported by - Nicholas F. Fabry and John-Mark Gurney. - - -Version 1.3 ------------ - -- Fixed precision problem on conversion of decimal seconds to - microseconds, as reported by Skip Montanaro. - -- Fixed bug in constructor of parser, and converted parser classes to - new-style classes. Original report and patch by Michael Elsdrfer. - -- Initialize tzid and comps in tz.py, to prevent the code from ever - raising a NameError (even with broken files). Johan Dahlin suggested - the fix after a pyflakes run. - -- Version is now published in dateutil.__version__, as requested - by Darren Dale. - -- All code is compatible with new-style division. - - -Version 1.2 ------------ - -- Now tzfile will round timezones to full-minutes if necessary, - since Python's datetime doesn't support sub-minute offsets. - Thanks to Ilpo Nyyssnen for reporting the issue. - -- Removed bare string exceptions, as reported and fixed by - Wilfredo Snchez Vega. - -- Fix bug in leap count parsing (reported and fixed by Eugene Oden). - - -Version 1.1 ------------ - -- Fixed rrule byyearday handling. Abramo Bagnara pointed out that - RFC2445 allows negative numbers. - -- Fixed --prefix handling in setup.py (by Sidnei da Silva). - -- Now tz.gettz() returns a tzlocal instance when not given any - arguments and no other timezone information is found. - -- Updating timezone information to version 2005q. - - -Version 1.0 ------------ - -- Fixed parsing of XXhXXm formatted time after day/month/year - has been parsed. - -- Added patch by Jeffrey Harris optimizing rrule.__contains__. - - -Version 0.9 ------------ - -- Fixed pickling of timezone types, as reported by - Andreas Khler. - -- Implemented internal timezone information with binary - timezone files [1]. datautil.tz.gettz() function will now - try to use the system timezone files, and fallback to - the internal versions. It's also possible to ask for - the internal versions directly by using - dateutil.zoneinfo.gettz(). - -- New tzwin timezone type, allowing access to Windows - internal timezones (contributed by Jeffrey Harris). - -- Fixed parsing of unicode date strings. - -- Accept parserinfo instances as the parser constructor - parameter, besides parserinfo (sub)classes. - -- Changed weekday to spell the not-set n value as None - instead of 0. - -- Fixed other reported bugs. - -[1] http://www.twinsun.com/tz/tz-link.htm - - -Version 0.5 ------------ - -- Removed FREQ_ prefix from rrule frequency constants - WARNING: this breaks compatibility with previous versions. - -- Fixed rrule.between() for cases where "after" is achieved - before even starting, as reported by Andreas Khler. - -- Fixed two digit zero-year parsing (such as 31-Dec-00), as - reported by Jim Abramson, and included test case for this. - -- Sort exdate and rdate before iterating over them, so that - it's not necessary to sort them before adding to the rruleset, - as reported by Nicholas Piper. - diff -Nru matplotlib-1.1.1/lib/dateutil/README matplotlib-1.2.0/lib/dateutil/README --- matplotlib-1.1.1/lib/dateutil/README 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,1970 +0,0 @@ -## This file is in the moin format. The latest version is found -## at https://moin.conectiva.com.br/DateUtil - -== Contents == -[[TableOfContents]] - -== Description == -The '''dateutil''' module provides powerful extensions to -the standard '''datetime''' module, available in Python 2.3+. - -== Features == - - * Computing of relative deltas (next month, next year, - next monday, last week of month, etc); - - * Computing of relative deltas between two given - date and/or datetime objects; - - * Computing of dates based on very flexible recurrence rules, - using a superset of the - [ftp://ftp.rfc-editor.org/in-notes/rfc2445.txt iCalendar] - specification. Parsing of RFC strings is supported as well. - - * Generic parsing of dates in almost any string format; - - * Timezone (tzinfo) implementations for tzfile(5) format - files (/etc/localtime, /usr/share/zoneinfo, etc), TZ - environment string (in all known formats), iCalendar - format files, given ranges (with help from relative deltas), - local machine timezone, fixed offset timezone, UTC timezone, - and Windows registry-based time zones. - - * Internal up-to-date world timezone information based on - Olson's database. - - * Computing of Easter Sunday dates for any given year, - using Western, Orthodox or Julian algorithms; - - * More than 400 test cases. - -== Quick example == -Here's a snapshot, just to give an idea about the power of the -package. For more examples, look at the documentation below. - -Suppose you want to know how much time is left, in -years/months/days/etc, before the next easter happening on a -year with a Friday 13th in August, and you want to get today's -date out of the "date" unix system command. Here is the code: -{{{ -from dateutil.relativedelta import * -from dateutil.easter import * -from dateutil.rrule import * -from dateutil.parser import * -from datetime import * -import commands -import os -now = parse(commands.getoutput("date")) -today = now.date() -year = rrule(YEARLY,bymonth=8,bymonthday=13,byweekday=FR)[0].year -rdelta = relativedelta(easter(year), today) -print "Today is:", today -print "Year with next Aug 13th on a Friday is:", year -print "How far is the Easter of that year:", rdelta -print "And the Easter of that year is:", today+rdelta -}}} - -And here's the output: -{{{ -Today is: 2003-10-11 -Year with next Aug 13th on a Friday is: 2004 -How far is the Easter of that year: relativedelta(months=+6) -And the Easter of that year is: 2004-04-11 -}}} - -{i} Being exactly 6 months ahead was '''really''' a coincidence :) - -== Download == -The following files are available. - * attachment:python-dateutil-1.0.tar.bz2 - * attachment:python-dateutil-1.0-1.noarch.rpm - -== Author == -The dateutil module was written by GustavoNiemeyer . - -== Documentation == -The following modules are available. - -=== relativedelta === -This module offers the '''relativedelta''' type, which is based -on the specification of the excelent work done by M.-A. Lemburg in his -[http://www.egenix.com/files/python/mxDateTime.html mxDateTime] -extension. However, notice that this type '''does not''' implement the -same algorithm as his work. Do not expect it to behave like -{{{mxDateTime}}}'s counterpart. - -==== relativedelta type ==== - -There's two different ways to build a relativedelta instance. The -first one is passing it two {{{date}}}/{{{datetime}}} instances: -{{{ -relativedelta(datetime1, datetime2) -}}} - -This will build the relative difference between {{{datetime1}}} and -{{{datetime2}}}, so that the following constraint is always true: -{{{ -datetime2+relativedelta(datetime1, datetime2) == datetime1 -}}} - -Notice that instead of {{{datetime}}} instances, you may use -{{{date}}} instances, or a mix of both. - -And the other way is to use any of the following keyword arguments: - - year, month, day, hour, minute, second, microsecond:: - Absolute information. - - years, months, weeks, days, hours, minutes, seconds, microseconds:: - Relative information, may be negative. - - weekday:: - One of the weekday instances ({{{MO}}}, {{{TU}}}, etc). These - instances may receive a parameter {{{n}}}, specifying the {{{n}}}th - weekday, which could be positive or negative (like {{{MO(+2)}}} or - {{{MO(-3)}}}. Not specifying it is the same as specifying {{{+1}}}. - You can also use an integer, where {{{0=MO}}}. Notice that, - for example, if the calculated date is already Monday, using - {{{MO}}} or {{{MO(+1)}}} (which is the same thing in this context), - won't change the day. - - leapdays:: - Will add given days to the date found, but only if the computed - year is a leap year and the computed date is post 28 of february. - - yearday, nlyearday:: - Set the yearday or the non-leap year day (jump leap days). - These are converted to {{{day}}}/{{{month}}}/{{{leapdays}}} - information. - -==== Behavior of operations ==== -If you're curious about exactly how the relative delta will act -on operations, here is a description of its behavior. - - 1. Calculate the absolute year, using the {{{year}}} argument, or the - original datetime year, if the argument is not present. - 1. Add the relative {{{years}}} argument to the absolute year. - 1. Do steps 1 and 2 for {{{month}}}/{{{months}}}. - 1. Calculate the absolute day, using the {{{day}}} argument, or the - original datetime day, if the argument is not present. Then, subtract - from the day until it fits in the year and month found after their - operations. - 1. Add the relative {{{days}}} argument to the absolute day. Notice - that the {{{weeks}}} argument is multiplied by 7 and added to {{{days}}}. - 1. If {{{leapdays}}} is present, the computed year is a leap year, and - the computed month is after february, remove one day from the found date. - 1. Do steps 1 and 2 for {{{hour}}}/{{{hours}}}, {{{minute}}}/{{{minutes}}}, - {{{second}}}/{{{seconds}}}, {{{microsecond}}}/{{{microseconds}}}. - 1. If the {{{weekday}}} argument is present, calculate the {{{n}}}th - occurrence of the given weekday. - -==== Examples ==== - -Let's begin our trip. -{{{ ->>> from datetime import *; from dateutil.relativedelta import * ->>> import calendar -}}} - -Store some values. -{{{ ->>> NOW = datetime.now() ->>> TODAY = date.today() ->>> NOW -datetime.datetime(2003, 9, 17, 20, 54, 47, 282310) ->>> TODAY -datetime.date(2003, 9, 17) -}}} - -Next month. -{{{ ->>> NOW+relativedelta(months=+1) -datetime.datetime(2003, 10, 17, 20, 54, 47, 282310) -}}} - -Next month, plus one week. -{{{ ->>> NOW+relativedelta(months=+1, weeks=+1) -datetime.datetime(2003, 10, 24, 20, 54, 47, 282310) -}}} - -Next month, plus one week, at 10am. -{{{ ->>> TODAY+relativedelta(months=+1, weeks=+1, hour=10) -datetime.datetime(2003, 10, 24, 10, 0) -}}} - -Let's try the other way around. Notice that the -hour setting we get in the relativedelta is relative, -since it's a difference, and the weeks parameter -has gone. -{{{ ->>> relativedelta(datetime(2003, 10, 24, 10, 0), TODAY) -relativedelta(months=+1, days=+7, hours=+10) -}}} - -One month before one year. -{{{ ->>> NOW+relativedelta(years=+1, months=-1) -datetime.datetime(2004, 8, 17, 20, 54, 47, 282310) -}}} - -How does it handle months with different numbers of days? -Notice that adding one month will never cross the month -boundary. -{{{ ->>> date(2003,1,27)+relativedelta(months=+1) -datetime.date(2003, 2, 27) ->>> date(2003,1,31)+relativedelta(months=+1) -datetime.date(2003, 2, 28) ->>> date(2003,1,31)+relativedelta(months=+2) -datetime.date(2003, 3, 31) -}}} - -The logic for years is the same, even on leap years. -{{{ ->>> date(2000,2,28)+relativedelta(years=+1) -datetime.date(2001, 2, 28) ->>> date(2000,2,29)+relativedelta(years=+1) -datetime.date(2001, 2, 28) - ->>> date(1999,2,28)+relativedelta(years=+1) -datetime.date(2000, 2, 28) ->>> date(1999,3,1)+relativedelta(years=+1) -datetime.date(2000, 3, 1) - ->>> date(2001,2,28)+relativedelta(years=-1) -datetime.date(2000, 2, 28) ->>> date(2001,3,1)+relativedelta(years=-1) -datetime.date(2000, 3, 1) -}}} - -Next friday. -{{{ ->>> TODAY+relativedelta(weekday=FR) -datetime.date(2003, 9, 19) - ->>> TODAY+relativedelta(weekday=calendar.FRIDAY) -datetime.date(2003, 9, 19) -}}} - -Last friday in this month. -{{{ ->>> TODAY+relativedelta(day=31, weekday=FR(-1)) -datetime.date(2003, 9, 26) -}}} - -Next wednesday (it's today!). -{{{ ->>> TODAY+relativedelta(weekday=WE(+1)) -datetime.date(2003, 9, 17) -}}} - -Next wednesday, but not today. -{{{ ->>> TODAY+relativedelta(days=+1, weekday=WE(+1)) -datetime.date(2003, 9, 24) -}}} - -Following -[http://www.cl.cam.ac.uk/~mgk25/iso-time.html ISO year week number notation] -find the first day of the 15th week of 1997. -{{{ ->>> datetime(1997,1,1)+relativedelta(day=4, weekday=MO(-1), weeks=+14) -datetime.datetime(1997, 4, 7, 0, 0) -}}} - -How long ago has the millennium changed? -{{{ ->>> relativedelta(NOW, date(2001,1,1)) -relativedelta(years=+2, months=+8, days=+16, - hours=+20, minutes=+54, seconds=+47, microseconds=+282310) -}}} - -How old is John? -{{{ ->>> johnbirthday = datetime(1978, 4, 5, 12, 0) ->>> relativedelta(NOW, johnbirthday) -relativedelta(years=+25, months=+5, days=+12, - hours=+8, minutes=+54, seconds=+47, microseconds=+282310) -}}} - -It works with dates too. -{{{ ->>> relativedelta(TODAY, johnbirthday) -relativedelta(years=+25, months=+5, days=+11, hours=+12) -}}} - -Obtain today's date using the yearday: -{{{ ->>> date(2003, 1, 1)+relativedelta(yearday=260) -datetime.date(2003, 9, 17) -}}} - -We can use today's date, since yearday should be absolute -in the given year: -{{{ ->>> TODAY+relativedelta(yearday=260) -datetime.date(2003, 9, 17) -}}} - -Last year it should be in the same day: -{{{ ->>> date(2002, 1, 1)+relativedelta(yearday=260) -datetime.date(2002, 9, 17) -}}} - -But not in a leap year: -{{{ ->>> date(2000, 1, 1)+relativedelta(yearday=260) -datetime.date(2000, 9, 16) -}}} - -We can use the non-leap year day to ignore this: -{{{ ->>> date(2000, 1, 1)+relativedelta(nlyearday=260) -datetime.date(2000, 9, 17) -}}} - -=== rrule === -The rrule module offers a small, complete, and very fast, implementation -of the recurrence rules documented in the -[ftp://ftp.rfc-editor.org/in-notes/rfc2445.txt iCalendar RFC], including -support for caching of results. - -==== rrule type ==== -That's the base of the rrule operation. It accepts all the keywords -defined in the RFC as its constructor parameters (except {{{byday}}}, -which was renamed to {{{byweekday}}}) and more. The constructor -prototype is: -{{{ -rrule(freq) -}}} - -Where {{{freq}}} must be one of {{{YEARLY}}}, {{{MONTHLY}}}, -{{{WEEKLY}}}, {{{DAILY}}}, {{{HOURLY}}}, {{{MINUTELY}}}, -or {{{SECONDLY}}}. - -Additionally, it supports the following keyword arguments: - - cache:: - If given, it must be a boolean value specifying to enable - or disable caching of results. If you will use the same - {{{rrule}}} instance multiple times, enabling caching will - improve the performance considerably. - - dtstart:: - The recurrence start. Besides being the base for the - recurrence, missing parameters in the final recurrence - instances will also be extracted from this date. If not - given, {{{datetime.now()}}} will be used instead. - - interval:: - The interval between each {{{freq}}} iteration. For example, - when using {{{YEARLY}}}, an interval of {{{2}}} means - once every two years, but with {{{HOURLY}}}, it means - once every two hours. The default interval is {{{1}}}. - - wkst:: - The week start day. Must be one of the {{{MO}}}, {{{TU}}}, - {{{WE}}} constants, or an integer, specifying the first day - of the week. This will affect recurrences based on weekly - periods. The default week start is got from - {{{calendar.firstweekday()}}}, and may be modified by - {{{calendar.setfirstweekday()}}}. - - count:: - How many occurrences will be generated. - - until:: - If given, this must be a {{{datetime}}} instance, that will - specify the limit of the recurrence. If a recurrence instance - happens to be the same as the {{{datetime}}} instance given - in the {{{until}}} keyword, this will be the last occurrence. - - bysetpos:: - If given, it must be either an integer, or a sequence of - integers, positive or negative. Each given integer will - specify an occurrence number, corresponding to the nth - occurrence of the rule inside the frequency period. For - example, a {{{bysetpos}}} of {{{-1}}} if combined with a - {{{MONTHLY}}} frequency, and a {{{byweekday}}} of - {{{(MO, TU, WE, TH, FR)}}}, will result in the last work - day of every month. - - bymonth:: - If given, it must be either an integer, or a sequence of - integers, meaning the months to apply the recurrence to. - - bymonthday:: - If given, it must be either an integer, or a sequence of - integers, meaning the month days to apply the recurrence to. - - byyearday:: - If given, it must be either an integer, or a sequence of - integers, meaning the year days to apply the recurrence to. - - byweekno:: - If given, it must be either an integer, or a sequence of - integers, meaning the week numbers to apply the recurrence - to. Week numbers have the meaning described in ISO8601, - that is, the first week of the year is that containing at - least four days of the new year. - - byweekday:: - If given, it must be either an integer ({{{0 == MO}}}), a - sequence of integers, one of the weekday constants - ({{{MO}}}, {{{TU}}}, etc), or a sequence of these constants. - When given, these variables will define the weekdays where - the recurrence will be applied. It's also possible to use - an argument {{{n}}} for the weekday instances, which will - mean the {{{n}}}''th'' occurrence of this weekday in the - period. For example, with {{{MONTHLY}}}, or with - {{{YEARLY}}} and {{{BYMONTH}}}, using {{{FR(+1)}}} - in {{{byweekday}}} will specify the first friday of the - month where the recurrence happens. Notice that in the RFC - documentation, this is specified as {{{BYDAY}}}, but was - renamed to avoid the ambiguity of that keyword. - - byhour:: - If given, it must be either an integer, or a sequence of - integers, meaning the hours to apply the recurrence to. - - byminute:: - If given, it must be either an integer, or a sequence of - integers, meaning the minutes to apply the recurrence to. - - bysecond:: - If given, it must be either an integer, or a sequence of - integers, meaning the seconds to apply the recurrence to. - - byeaster:: - If given, it must be either an integer, or a sequence of - integers, positive or negative. Each integer will define - an offset from the Easter Sunday. Passing the offset - {{{0}}} to {{{byeaster}}} will yield the Easter Sunday - itself. This is an extension to the RFC specification. - -==== rrule methods ==== -The following methods are available in {{{rrule}}} instances: - - rrule.before(dt, inc=False):: - Returns the last recurrence before the given {{{datetime}}} - instance. The {{{inc}}} keyword defines what happens if - {{{dt}}} '''is''' an occurrence. With {{{inc == True}}}, - if {{{dt}}} itself is an occurrence, it will be returned. - - rrule.after(dt, inc=False):: - Returns the first recurrence after the given {{{datetime}}} - instance. The {{{inc}}} keyword defines what happens if - {{{dt}}} '''is''' an occurrence. With {{{inc == True}}}, - if {{{dt}}} itself is an occurrence, it will be returned. - - rrule.between(after, before, inc=False):: - Returns all the occurrences of the rrule between {{{after}}} - and {{{before}}}. The {{{inc}}} keyword defines what happens - if {{{after}}} and/or {{{before}}} are themselves occurrences. - With {{{inc == True}}}, they will be included in the list, - if they are found in the recurrence set. - - rrule.count():: - Returns the number of recurrences in this set. It will have - go trough the whole recurrence, if this hasn't been done - before. - -Besides these methods, {{{rrule}}} instances also support -the {{{__getitem__()}}} and {{{__contains__()}}} special methods, -meaning that these are valid expressions: -{{{ -rr = rrule(...) -if datetime(...) in rr: - ... -print rr[0] -print rr[-1] -print rr[1:2] -print rr[::-2] -}}} - -The getitem/slicing mechanism is smart enough to avoid getting the whole -recurrence set, if possible. - -==== Notes ==== - - * The rrule type has no {{{byday}}} keyword. The equivalent keyword - has been replaced by the {{{byweekday}}} keyword, to remove the - ambiguity present in the original keyword. - - * Unlike documented in the RFC, the starting datetime ({{{dtstart}}}) - is not the first recurrence instance, unless it does fit in the - specified rules. In a python module context, this behavior makes more - sense than otherwise. Notice that you can easily get the original - behavior by using a rruleset and adding the {{{dtstart}}} as an - {{{rdate}}} recurrence. - - * Unlike documented in the RFC, every keyword is valid on every - frequency (the RFC documents that {{{byweekno}}} is only valid - on yearly frequencies, for example). - - * In addition to the documented keywords, a {{{byeaster}}} keyword - was introduced, making it easy to compute recurrent events relative - to the Easter Sunday. - -==== rrule examples ==== -These examples were converted from the RFC. - -Prepare the environment. -{{{ ->>> from dateutil.rrule import * ->>> from dateutil.parser import * ->>> from datetime import * - ->>> import pprint ->>> import sys ->>> sys.displayhook = pprint.pprint -}}} - -Daily, for 10 occurrences. -{{{ ->>> list(rrule(DAILY, count=10, - dtstart=parse("19970902T090000"))) -[datetime.datetime(1997, 9, 2, 9, 0), - datetime.datetime(1997, 9, 3, 9, 0), - datetime.datetime(1997, 9, 4, 9, 0), - datetime.datetime(1997, 9, 5, 9, 0), - datetime.datetime(1997, 9, 6, 9, 0), - datetime.datetime(1997, 9, 7, 9, 0), - datetime.datetime(1997, 9, 8, 9, 0), - datetime.datetime(1997, 9, 9, 9, 0), - datetime.datetime(1997, 9, 10, 9, 0), - datetime.datetime(1997, 9, 11, 9, 0)] -}}} - -Daily until December 24, 1997 -{{{ ->>> list(rrule(DAILY, - dtstart=parse("19970902T090000"), - until=parse("19971224T000000"))) -[datetime.datetime(1997, 9, 2, 9, 0), - datetime.datetime(1997, 9, 3, 9, 0), - datetime.datetime(1997, 9, 4, 9, 0), - (...) - datetime.datetime(1997, 12, 21, 9, 0), - datetime.datetime(1997, 12, 22, 9, 0), - datetime.datetime(1997, 12, 23, 9, 0)] -}}} - -Every other day, 5 occurrences. -{{{ ->>> list(rrule(DAILY, interval=2, count=5, - dtstart=parse("19970902T090000"))) -[datetime.datetime(1997, 9, 2, 9, 0), - datetime.datetime(1997, 9, 4, 9, 0), - datetime.datetime(1997, 9, 6, 9, 0), - datetime.datetime(1997, 9, 8, 9, 0), - datetime.datetime(1997, 9, 10, 9, 0)] -}}} - -Every 10 days, 5 occurrences. -{{{ ->>> list(rrule(DAILY, interval=10, count=5, - dtstart=parse("19970902T090000"))) -[datetime.datetime(1997, 9, 2, 9, 0), - datetime.datetime(1997, 9, 12, 9, 0), - datetime.datetime(1997, 9, 22, 9, 0), - datetime.datetime(1997, 10, 2, 9, 0), - datetime.datetime(1997, 10, 12, 9, 0)] -}}} - -Everyday in January, for 3 years. -{{{ ->>> list(rrule(YEARLY, bymonth=1, byweekday=range(7), - dtstart=parse("19980101T090000"), - until=parse("20000131T090000"))) -[datetime.datetime(1998, 1, 1, 9, 0), - datetime.datetime(1998, 1, 2, 9, 0), - (...) - datetime.datetime(1998, 1, 30, 9, 0), - datetime.datetime(1998, 1, 31, 9, 0), - datetime.datetime(1999, 1, 1, 9, 0), - datetime.datetime(1999, 1, 2, 9, 0), - (...) - datetime.datetime(1999, 1, 30, 9, 0), - datetime.datetime(1999, 1, 31, 9, 0), - datetime.datetime(2000, 1, 1, 9, 0), - datetime.datetime(2000, 1, 2, 9, 0), - (...) - datetime.datetime(2000, 1, 29, 9, 0), - datetime.datetime(2000, 1, 31, 9, 0)] -}}} - -Same thing, in another way. -{{{ ->>> list(rrule(DAILY, bymonth=1, - dtstart=parse("19980101T090000"), - until=parse("20000131T090000"))) -(...) -}}} - -Weekly for 10 occurrences. -{{{ ->>> list(rrule(WEEKLY, count=10, - dtstart=parse("19970902T090000"))) -[datetime.datetime(1997, 9, 2, 9, 0), - datetime.datetime(1997, 9, 9, 9, 0), - datetime.datetime(1997, 9, 16, 9, 0), - datetime.datetime(1997, 9, 23, 9, 0), - datetime.datetime(1997, 9, 30, 9, 0), - datetime.datetime(1997, 10, 7, 9, 0), - datetime.datetime(1997, 10, 14, 9, 0), - datetime.datetime(1997, 10, 21, 9, 0), - datetime.datetime(1997, 10, 28, 9, 0), - datetime.datetime(1997, 11, 4, 9, 0)] -}}} - -Every other week, 6 occurrences. -{{{ ->>> list(rrule(WEEKLY, interval=2, count=6, - dtstart=parse("19970902T090000"))) -[datetime.datetime(1997, 9, 2, 9, 0), - datetime.datetime(1997, 9, 16, 9, 0), - datetime.datetime(1997, 9, 30, 9, 0), - datetime.datetime(1997, 10, 14, 9, 0), - datetime.datetime(1997, 10, 28, 9, 0), - datetime.datetime(1997, 11, 11, 9, 0)] -}}} - -Weekly on Tuesday and Thursday for 5 weeks. -{{{ ->>> list(rrule(WEEKLY, count=10, wkst=SU, byweekday=(TU,TH), - dtstart=parse("19970902T090000"))) -[datetime.datetime(1997, 9, 2, 9, 0), - datetime.datetime(1997, 9, 4, 9, 0), - datetime.datetime(1997, 9, 9, 9, 0), - datetime.datetime(1997, 9, 11, 9, 0), - datetime.datetime(1997, 9, 16, 9, 0), - datetime.datetime(1997, 9, 18, 9, 0), - datetime.datetime(1997, 9, 23, 9, 0), - datetime.datetime(1997, 9, 25, 9, 0), - datetime.datetime(1997, 9, 30, 9, 0), - datetime.datetime(1997, 10, 2, 9, 0)] -}}} - -Every other week on Tuesday and Thursday, for 8 occurrences. -{{{ ->>> list(rrule(WEEKLY, interval=2, count=8, - wkst=SU, byweekday=(TU,TH), - dtstart=parse("19970902T090000"))) -[datetime.datetime(1997, 9, 2, 9, 0), - datetime.datetime(1997, 9, 4, 9, 0), - datetime.datetime(1997, 9, 16, 9, 0), - datetime.datetime(1997, 9, 18, 9, 0), - datetime.datetime(1997, 9, 30, 9, 0), - datetime.datetime(1997, 10, 2, 9, 0), - datetime.datetime(1997, 10, 14, 9, 0), - datetime.datetime(1997, 10, 16, 9, 0)] -}}} - -Monthly on the 1st Friday for ten occurrences. -{{{ ->>> list(rrule(MONTHLY, count=10, byweekday=FR(1), - dtstart=parse("19970905T090000"))) -[datetime.datetime(1997, 9, 5, 9, 0), - datetime.datetime(1997, 10, 3, 9, 0), - datetime.datetime(1997, 11, 7, 9, 0), - datetime.datetime(1997, 12, 5, 9, 0), - datetime.datetime(1998, 1, 2, 9, 0), - datetime.datetime(1998, 2, 6, 9, 0), - datetime.datetime(1998, 3, 6, 9, 0), - datetime.datetime(1998, 4, 3, 9, 0), - datetime.datetime(1998, 5, 1, 9, 0), - datetime.datetime(1998, 6, 5, 9, 0)] -}}} - -Every other month on the 1st and last Sunday of the month for 10 occurrences. -{{{ ->>> list(rrule(MONTHLY, interval=2, count=10, - byweekday=(SU(1), SU(-1)), - dtstart=parse("19970907T090000"))) -[datetime.datetime(1997, 9, 7, 9, 0), - datetime.datetime(1997, 9, 28, 9, 0), - datetime.datetime(1997, 11, 2, 9, 0), - datetime.datetime(1997, 11, 30, 9, 0), - datetime.datetime(1998, 1, 4, 9, 0), - datetime.datetime(1998, 1, 25, 9, 0), - datetime.datetime(1998, 3, 1, 9, 0), - datetime.datetime(1998, 3, 29, 9, 0), - datetime.datetime(1998, 5, 3, 9, 0), - datetime.datetime(1998, 5, 31, 9, 0)] -}}} - -Monthly on the second to last Monday of the month for 6 months. -{{{ ->>> list(rrule(MONTHLY, count=6, byweekday=MO(-2), - dtstart=parse("19970922T090000"))) -[datetime.datetime(1997, 9, 22, 9, 0), - datetime.datetime(1997, 10, 20, 9, 0), - datetime.datetime(1997, 11, 17, 9, 0), - datetime.datetime(1997, 12, 22, 9, 0), - datetime.datetime(1998, 1, 19, 9, 0), - datetime.datetime(1998, 2, 16, 9, 0)] -}}} - -Monthly on the third to the last day of the month, for 6 months. -{{{ ->>> list(rrule(MONTHLY, count=6, bymonthday=-3, - dtstart=parse("19970928T090000"))) -[datetime.datetime(1997, 9, 28, 9, 0), - datetime.datetime(1997, 10, 29, 9, 0), - datetime.datetime(1997, 11, 28, 9, 0), - datetime.datetime(1997, 12, 29, 9, 0), - datetime.datetime(1998, 1, 29, 9, 0), - datetime.datetime(1998, 2, 26, 9, 0)] -}}} - -Monthly on the 2nd and 15th of the month for 5 occurrences. -{{{ ->>> list(rrule(MONTHLY, count=5, bymonthday=(2,15), - dtstart=parse("19970902T090000"))) -[datetime.datetime(1997, 9, 2, 9, 0), - datetime.datetime(1997, 9, 15, 9, 0), - datetime.datetime(1997, 10, 2, 9, 0), - datetime.datetime(1997, 10, 15, 9, 0), - datetime.datetime(1997, 11, 2, 9, 0)] -}}} - -Monthly on the first and last day of the month for 3 occurrences. -{{{ ->>> list(rrule(MONTHLY, count=5, bymonthday=(-1,1,), - dtstart=parse("1997090 -2T090000"))) -[datetime.datetime(1997, 9, 30, 9, 0), - datetime.datetime(1997, 10, 1, 9, 0), - datetime.datetime(1997, 10, 31, 9, 0), - datetime.datetime(1997, 11, 1, 9, 0), - datetime.datetime(1997, 11, 30, 9, 0)] -}}} - -Every 18 months on the 10th thru 15th of the month for 10 occurrences. -{{{ ->>> list(rrule(MONTHLY, interval=18, count=10, - bymonthday=range(10,16), - dtstart=parse("19970910T090000"))) -[datetime.datetime(1997, 9, 10, 9, 0), - datetime.datetime(1997, 9, 11, 9, 0), - datetime.datetime(1997, 9, 12, 9, 0), - datetime.datetime(1997, 9, 13, 9, 0), - datetime.datetime(1997, 9, 14, 9, 0), - datetime.datetime(1997, 9, 15, 9, 0), - datetime.datetime(1999, 3, 10, 9, 0), - datetime.datetime(1999, 3, 11, 9, 0), - datetime.datetime(1999, 3, 12, 9, 0), - datetime.datetime(1999, 3, 13, 9, 0)] -}}} - -Every Tuesday, every other month, 6 occurences. -{{{ ->>> list(rrule(MONTHLY, interval=2, count=6, byweekday=TU, - dtstart=parse("19970902T090000"))) -[datetime.datetime(1997, 9, 2, 9, 0), - datetime.datetime(1997, 9, 9, 9, 0), - datetime.datetime(1997, 9, 16, 9, 0), - datetime.datetime(1997, 9, 23, 9, 0), - datetime.datetime(1997, 9, 30, 9, 0), - datetime.datetime(1997, 11, 4, 9, 0)] -}}} - -Yearly in June and July for 10 occurrences. -{{{ ->>> list(rrule(YEARLY, count=4, bymonth=(6,7), - dtstart=parse("19970610T0900 -00"))) -[datetime.datetime(1997, 6, 10, 9, 0), - datetime.datetime(1997, 7, 10, 9, 0), - datetime.datetime(1998, 6, 10, 9, 0), - datetime.datetime(1998, 7, 10, 9, 0)] -}}} - -Every 3rd year on the 1st, 100th and 200th day for 4 occurrences. -{{{ ->>> list(rrule(YEARLY, count=4, interval=3, byyearday=(1,100,200), - dtstart=parse("19970101T090000"))) -[datetime.datetime(1997, 1, 1, 9, 0), - datetime.datetime(1997, 4, 10, 9, 0), - datetime.datetime(1997, 7, 19, 9, 0), - datetime.datetime(2000, 1, 1, 9, 0)] -}}} - -Every 20th Monday of the year, 3 occurrences. -{{{ ->>> list(rrule(YEARLY, count=3, byweekday=MO(20), - dtstart=parse("19970519T090000"))) -[datetime.datetime(1997, 5, 19, 9, 0), - datetime.datetime(1998, 5, 18, 9, 0), - datetime.datetime(1999, 5, 17, 9, 0)] -}}} - -Monday of week number 20 (where the default start of the week is Monday), -3 occurrences. -{{{ ->>> list(rrule(YEARLY, count=3, byweekno=20, byweekday=MO, - dtstart=parse("19970512T090000"))) -[datetime.datetime(1997, 5, 12, 9, 0), - datetime.datetime(1998, 5, 11, 9, 0), - datetime.datetime(1999, 5, 17, 9, 0)] -}}} - -The week number 1 may be in the last year. -{{{ ->>> list(rrule(WEEKLY, count=3, byweekno=1, byweekday=MO, - dtstart=parse("19970902T090000"))) -[datetime.datetime(1997, 12, 29, 9, 0), - datetime.datetime(1999, 1, 4, 9, 0), - datetime.datetime(2000, 1, 3, 9, 0)] -}}} - -And the week numbers greater than 51 may be in the next year. -{{{ ->>> list(rrule(WEEKLY, count=3, byweekno=52, byweekday=SU, - dtstart=parse("19970902T090000"))) -[datetime.datetime(1997, 12, 28, 9, 0), - datetime.datetime(1998, 12, 27, 9, 0), - datetime.datetime(2000, 1, 2, 9, 0)] -}}} - -Only some years have week number 53: -{{{ ->>> list(rrule(WEEKLY, count=3, byweekno=53, byweekday=MO, - dtstart=parse("19970902T090000"))) -[datetime.datetime(1998, 12, 28, 9, 0), - datetime.datetime(2004, 12, 27, 9, 0), - datetime.datetime(2009, 12, 28, 9, 0)] -}}} - -Every Friday the 13th, 4 occurrences. -{{{ ->>> list(rrule(YEARLY, count=4, byweekday=FR, bymonthday=13, - dtstart=parse("19970902T090000"))) -[datetime.datetime(1998, 2, 13, 9, 0), - datetime.datetime(1998, 3, 13, 9, 0), - datetime.datetime(1998, 11, 13, 9, 0), - datetime.datetime(1999, 8, 13, 9, 0)] -}}} - -Every four years, the first Tuesday after a Monday in November, -3 occurrences (U.S. Presidential Election day): -{{{ ->>> list(rrule(YEARLY, interval=4, count=3, bymonth=11, - byweekday=TU, bymonthday=(2,3,4,5,6,7,8), - dtstart=parse("19961105T090000"))) -[datetime.datetime(1996, 11, 5, 9, 0), - datetime.datetime(2000, 11, 7, 9, 0), - datetime.datetime(2004, 11, 2, 9, 0)] -}}} - -The 3rd instance into the month of one of Tuesday, Wednesday or -Thursday, for the next 3 months: -{{{ ->>> list(rrule(MONTHLY, count=3, byweekday=(TU,WE,TH), - bysetpos=3, dtstart=parse("19970904T090000"))) -[datetime.datetime(1997, 9, 4, 9, 0), - datetime.datetime(1997, 10, 7, 9, 0), - datetime.datetime(1997, 11, 6, 9, 0)] -}}} - -The 2nd to last weekday of the month, 3 occurrences. -{{{ ->>> list(rrule(MONTHLY, count=3, byweekday=(MO,TU,WE,TH,FR), - bysetpos=-2, dtstart=parse("19970929T090000"))) -[datetime.datetime(1997, 9, 29, 9, 0), - datetime.datetime(1997, 10, 30, 9, 0), - datetime.datetime(1997, 11, 27, 9, 0)] -}}} - -Every 3 hours from 9:00 AM to 5:00 PM on a specific day. -{{{ ->>> list(rrule(HOURLY, interval=3, - dtstart=parse("19970902T090000"), - until=parse("19970902T170000"))) -[datetime.datetime(1997, 9, 2, 9, 0), - datetime.datetime(1997, 9, 2, 12, 0), - datetime.datetime(1997, 9, 2, 15, 0)] -}}} - -Every 15 minutes for 6 occurrences. -{{{ ->>> list(rrule(MINUTELY, interval=15, count=6, - dtstart=parse("19970902T090000"))) -[datetime.datetime(1997, 9, 2, 9, 0), - datetime.datetime(1997, 9, 2, 9, 15), - datetime.datetime(1997, 9, 2, 9, 30), - datetime.datetime(1997, 9, 2, 9, 45), - datetime.datetime(1997, 9, 2, 10, 0), - datetime.datetime(1997, 9, 2, 10, 15)] -}}} - -Every hour and a half for 4 occurrences. -{{{ ->>> list(rrule(MINUTELY, interval=90, count=4, - dtstart=parse("19970902T090000"))) -[datetime.datetime(1997, 9, 2, 9, 0), - datetime.datetime(1997, 9, 2, 10, 30), - datetime.datetime(1997, 9, 2, 12, 0), - datetime.datetime(1997, 9, 2, 13, 30)] -}}} - -Every 20 minutes from 9:00 AM to 4:40 PM for two days. -{{{ ->>> list(rrule(MINUTELY, interval=20, count=48, - byhour=range(9,17), byminute=(0,20,40), - dtstart=parse("19970902T090000"))) -[datetime.datetime(1997, 9, 2, 9, 0), - datetime.datetime(1997, 9, 2, 9, 20), - (...) - datetime.datetime(1997, 9, 2, 16, 20), - datetime.datetime(1997, 9, 2, 16, 40), - datetime.datetime(1997, 9, 3, 9, 0), - datetime.datetime(1997, 9, 3, 9, 20), - (...) - datetime.datetime(1997, 9, 3, 16, 20), - datetime.datetime(1997, 9, 3, 16, 40)] -}}} - -An example where the days generated makes a difference because of {{{wkst}}}. -{{{ ->>> list(rrule(WEEKLY, interval=2, count=4, - byweekday=(TU,SU), wkst=MO, - dtstart=parse("19970805T090000"))) -[datetime.datetime(1997, 8, 5, 9, 0), - datetime.datetime(1997, 8, 10, 9, 0), - datetime.datetime(1997, 8, 19, 9, 0), - datetime.datetime(1997, 8, 24, 9, 0)] - ->>> list(rrule(WEEKLY, interval=2, count=4, - byweekday=(TU,SU), wkst=SU, - dtstart=parse("19970805T090000"))) -[datetime.datetime(1997, 8, 5, 9, 0), - datetime.datetime(1997, 8, 17, 9, 0), - datetime.datetime(1997, 8, 19, 9, 0), - datetime.datetime(1997, 8, 31, 9, 0)] -}}} - -==== rruleset type ==== -The {{{rruleset}}} type allows more complex recurrence setups, mixing -multiple rules, dates, exclusion rules, and exclusion dates. -The type constructor takes the following keyword arguments: - - cache:: - If True, caching of results will be enabled, improving performance - of multiple queries considerably. - -==== rruleset methods ==== -The following methods are available: - - rruleset.rrule(rrule):: - Include the given {{{rrule}}} instance in the recurrence set - generation. - - rruleset.rdate(dt):: - Include the given {{{datetime}}} instance in the recurrence - set generation. - - rruleset.exrule(rrule):: - Include the given {{{rrule}}} instance in the recurrence set - exclusion list. Dates which are part of the given recurrence - rules will not be generated, even if some inclusive {{{rrule}}} - or {{{rdate}}} matches them. - - rruleset.exdate(dt):: - Include the given {{{datetime}}} instance in the recurrence set - exclusion list. Dates included that way will not be generated, - even if some inclusive {{{rrule}}} or {{{rdate}}} matches them. - - rruleset.before(dt, inc=False):: - Returns the last recurrence before the given {{{datetime}}} - instance. The {{{inc}}} keyword defines what happens if - {{{dt}}} '''is''' an occurrence. With {{{inc == True}}}, - if {{{dt}}} itself is an occurrence, it will be returned. - - rruleset.after(dt, inc=False):: - Returns the first recurrence after the given {{{datetime}}} - instance. The {{{inc}}} keyword defines what happens if - {{{dt}}} '''is''' an occurrence. With {{{inc == True}}}, - if {{{dt}}} itself is an occurrence, it will be returned. - - rruleset.between(after, before, inc=False):: - Returns all the occurrences of the rrule between {{{after}}} - and {{{before}}}. The {{{inc}}} keyword defines what happens - if {{{after}}} and/or {{{before}}} are themselves occurrences. - With {{{inc == True}}}, they will be included in the list, - if they are found in the recurrence set. - - rruleset.count():: - Returns the number of recurrences in this set. It will have - go trough the whole recurrence, if this hasn't been done - before. - -Besides these methods, {{{rruleset}}} instances also support -the {{{__getitem__()}}} and {{{__contains__()}}} special methods, -meaning that these are valid expressions: -{{{ -set = rruleset(...) -if datetime(...) in set: - ... -print set[0] -print set[-1] -print set[1:2] -print set[::-2] -}}} - -The getitem/slicing mechanism is smart enough to avoid getting the whole -recurrence set, if possible. - -==== rruleset examples ==== -Daily, for 7 days, jumping Saturday and Sunday occurrences. -{{{ ->>> set = rruleset() ->>> set.rrule(rrule(DAILY, count=7, - dtstart=parse("19970902T090000"))) ->>> set.exrule(rrule(YEARLY, byweekday=(SA,SU), - dtstart=parse("19970902T090000"))) ->>> list(set) -[datetime.datetime(1997, 9, 2, 9, 0), - datetime.datetime(1997, 9, 3, 9, 0), - datetime.datetime(1997, 9, 4, 9, 0), - datetime.datetime(1997, 9, 5, 9, 0), - datetime.datetime(1997, 9, 8, 9, 0)] -}}} - -Weekly, for 4 weeks, plus one time on day 7, and not on day 16. -{{{ ->>> set = rruleset() ->>> set.rrule(rrule(WEEKLY, count=4, - dtstart=parse("19970902T090000"))) ->>> set.rdate(datetime.datetime(1997, 9, 7, 9, 0)) ->>> set.exdate(datetime.datetime(1997, 9, 16, 9, 0)) ->>> list(set) -[datetime.datetime(1997, 9, 2, 9, 0), - datetime.datetime(1997, 9, 7, 9, 0), - datetime.datetime(1997, 9, 9, 9, 0), - datetime.datetime(1997, 9, 23, 9, 0)] -}}} - -==== rrulestr() function ==== -The {{{rrulestr()}}} function is a parser for ''RFC-like'' syntaxes. -The function prototype is: -{{{ -rrulestr(str) -}}} - -The string passed as parameter may be a multiple line string, a -single line string, or just the {{{RRULE}}} property value. - -Additionally, it accepts the following keyword arguments: - - cache:: - If {{{True}}}, the {{{rruleset}}} or {{{rrule}}} created instance - will cache its results. Default is not to cache. - - dtstart:: - If given, it must be a {{{datetime}}} instance that will be used - when no {{{DTSTART}}} property is found in the parsed string. If - it is not given, and the property is not found, {{{datetime.now()}}} - will be used instead. - - unfold:: - If set to {{{True}}}, lines will be unfolded following the RFC - specification. It defaults to {{{False}}}, meaning that spaces - before every line will be stripped. - - forceset:: - If set to {{{True}}} a {{{rruleset}}} instance will be returned, - even if only a single rule is found. The default is to return an - {{{rrule}}} if possible, and an {{{rruleset}}} if necessary. - - compatible:: - If set to {{{True}}}, the parser will operate in RFC-compatible - mode. Right now it means that {{{unfold}}} will be turned on, - and if a {{{DTSTART}}} is found, it will be considered the first - recurrence instance, as documented in the RFC. - - ignoretz:: - If set to {{{True}}}, the date parser will ignore timezone - information available in the {{{DTSTART}}} property, or the - {{{UNTIL}}} attribute. - - tzinfos:: - If set, it will be passed to the datetime string parser to - resolve unknown timezone settings. For more information about - what could be used here, check the parser documentation. - -==== rrulestr() examples ==== - -Every 10 days, 5 occurrences. -{{{ ->>> list(rrulestr(""" -... DTSTART:19970902T090000 -... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5 -... """)) -[datetime.datetime(1997, 9, 2, 9, 0), - datetime.datetime(1997, 9, 12, 9, 0), - datetime.datetime(1997, 9, 22, 9, 0), - datetime.datetime(1997, 10, 2, 9, 0), - datetime.datetime(1997, 10, 12, 9, 0)] -}}} - -Same thing, but passing only the {{{RRULE}}} value. -{{{ ->>> list(rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5", - dtstart=parse("19970902T090000"))) -[datetime.datetime(1997, 9, 2, 9, 0), - datetime.datetime(1997, 9, 12, 9, 0), - datetime.datetime(1997, 9, 22, 9, 0), - datetime.datetime(1997, 10, 2, 9, 0), - datetime.datetime(1997, 10, 12, 9, 0)] -}}} - -Notice that when using a single rule, it returns an -{{{rrule}}} instance, unless {{{forceset}}} was used. -{{{ ->>> rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5") - - ->>> rrulestr(""" -... DTSTART:19970902T090000 -... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5 -... """) - - ->>> rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5", forceset=True) - -}}} - -But when an {{{rruleset}}} is needed, it is automatically used. -{{{ ->>> rrulestr(""" -... DTSTART:19970902T090000 -... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5 -... RRULE:FREQ=DAILY;INTERVAL=5;COUNT=3 -... """) - -}}} - -=== parser === -This module offers a generic date/time string parser which is -able to parse most known formats to represent a date and/or -time. - -==== parse() function ==== -That's probably the only function you'll need from this module. -It offers you an interface to access the parser functionality and -extract a {{{datetime}}} type out of a string. - -The prototype of this function is: -{{{ -parse(timestr) -}}} - -Additionally, the following keyword arguments are available: - - default:: - If given, this must be a {{{datetime}}} instance. Any fields - missing in the parsed date will be copied from this instance. - The default value is the current date, at 00:00:00am. - - ignoretz:: - If this is true, even if a timezone is found in the string, - the parser will not use it. - - tzinfos:: - Using this keyword argument you may provide custom timezones - to the parser. If given, it must be either a dictionary with - the timezone abbreviation as key, or a function accepting a - timezone abbreviation and offset as argument. The dictionary - values and the function return must be a timezone offset - in seconds, a tzinfo subclass, or a string defining the - timezone (in the TZ environment variable format). - - dayfirst:: - This option allow one to change the precedence in which - days are parsed in date strings. The default is given in the - parserinfo instance (the default parserinfo has it set to - False). If {{{dayfirst}}} is False, the {{{MM-DD-YYYY}}} - format will have precedence over {{{DD-MM-YYYY}}} in an - ambiguous date. - - yearfirst:: - This option allow one to change the precedence in which - years are parsed in date strings. The default is given in - the parserinfo instance (the default parserinfo has it set - to False). If {{{yearfirst}}} is false, the {{{MM-DD-YY}}} - format will have precedence over {{{YY-MM-DD}}} in an - ambiguous date. - - fuzzy:: - If {{{fuzzy}}} is set to True, unknown tokens in the string - will be ignored. - - parserinfo:: - This parameter allows one to change how the string is parsed, - by using a different parserinfo class instance. Using it you - may, for example, intenationalize the parser strings, or make - it ignore additional words. - -==== Format precedence ==== -Whenever an ambiguous date is found, the {{{dayfirst}}} and -{{{yearfirst}}} parameters will control how the information -is processed. Here is the precedence in each case: - -If {{{dayfirst}}} is {{{False}}} and {{{yearfirst}}} is {{{False}}}, -(default, if no parameter is given): - - * {{{MM-DD-YY}}} - * {{{DD-MM-YY}}} - * {{{YY-MM-DD}}} - -If {{{dayfirst}}} is {{{True}}} and {{{yearfirst}}} is {{{False}}}: - - * {{{DD-MM-YY}}} - * {{{MM-DD-YY}}} - * {{{YY-MM-DD}}} - -If {{{dayfirst}}} is {{{False}}} and {{{yearfirst}}} is {{{True}}}: - - * {{{YY-MM-DD}}} - * {{{MM-DD-YY}}} - * {{{DD-MM-YY}}} - -If {{{dayfirst}}} is {{{True}}} and {{{yearfirst}}} is {{{True}}}: - - * {{{YY-MM-DD}}} - * {{{DD-MM-YY}}} - * {{{MM-DD-YY}}} - -==== Converting two digit years ==== -When a two digit year is found, it is processed considering -the current year, so that the computed year is never more -than 49 years after the current year, nor 50 years before the -current year. In other words, if we are in year 2003, and the -year 30 is found, it will be considered as 2030, but if the -year 60 is found, it will be considered 1960. - -==== Examples ==== -The following code will prepare the environment: -{{{ ->>> from dateutil.parser import * ->>> from dateutil.tz import * ->>> from datetime import * ->>> TZOFFSETS = {"BRST": -10800} ->>> BRSTTZ = tzoffset(-10800, "BRST") ->>> DEFAULT = datetime(2003, 9, 25) -}}} - -Some simple examples based on the {{{date}}} command, using the -{{{TZOFFSET}}} dictionary to provide the BRST timezone offset. -{{{ ->>> parse("Thu Sep 25 10:36:28 BRST 2003", tzinfos=TZOFFSETS) -datetime.datetime(2003, 9, 25, 10, 36, 28, - tzinfo=tzoffset('BRST', -10800)) - ->>> parse("2003 10:36:28 BRST 25 Sep Thu", tzinfos=TZOFFSETS) -datetime.datetime(2003, 9, 25, 10, 36, 28, - tzinfo=tzoffset('BRST', -10800)) -}}} - -Notice that since BRST is my local timezone, parsing it without -further timezone settings will yield a {{{tzlocal}}} timezone. -{{{ ->>> parse("Thu Sep 25 10:36:28 BRST 2003") -datetime.datetime(2003, 9, 25, 10, 36, 28, tzinfo=tzlocal()) -}}} - -We can also ask to ignore the timezone explicitly: -{{{ ->>> parse("Thu Sep 25 10:36:28 BRST 2003", ignoretz=True) -datetime.datetime(2003, 9, 25, 10, 36, 28) -}}} - -That's the same as processing a string without timezone: -{{{ ->>> parse("Thu Sep 25 10:36:28 2003") -datetime.datetime(2003, 9, 25, 10, 36, 28) -}}} - -Without the year, but passing our {{{DEFAULT}}} datetime to return -the same year, no mattering what year we currently are in: -{{{ ->>> parse("Thu Sep 25 10:36:28", default=DEFAULT) -datetime.datetime(2003, 9, 25, 10, 36, 28) -}}} - -Strip it further: -{{{ ->>> parse("Thu Sep 10:36:28", default=DEFAULT) -datetime.datetime(2003, 9, 25, 10, 36, 28) - ->>> parse("Thu 10:36:28", default=DEFAULT) -datetime.datetime(2003, 9, 25, 10, 36, 28) - ->>> parse("Thu 10:36", default=DEFAULT) -datetime.datetime(2003, 9, 25, 10, 36) - ->>> parse("10:36", default=DEFAULT) -datetime.datetime(2003, 9, 25, 10, 36) ->>> -}}} - -Strip in a different way: -{{{ ->>> parse("Thu Sep 25 2003") -datetime.datetime(2003, 9, 25, 0, 0) - ->>> parse("Sep 25 2003") -datetime.datetime(2003, 9, 25, 0, 0) - ->>> parse("Sep 2003", default=DEFAULT) -datetime.datetime(2003, 9, 25, 0, 0) - ->>> parse("Sep", default=DEFAULT) -datetime.datetime(2003, 9, 25, 0, 0) - ->>> parse("2003", default=DEFAULT) -datetime.datetime(2003, 9, 25, 0, 0) -}}} - -Another format, based on {{{date -R}}} (RFC822): -{{{ ->>> parse("Thu, 25 Sep 2003 10:49:41 -0300") -datetime.datetime(2003, 9, 25, 10, 49, 41, - tzinfo=tzoffset(None, -10800)) -}}} - -ISO format: -{{{ ->>> parse("2003-09-25T10:49:41.5-03:00") -datetime.datetime(2003, 9, 25, 10, 49, 41, 500000, - tzinfo=tzoffset(None, -10800)) -}}} - -Some variations: -{{{ ->>> parse("2003-09-25T10:49:41") -datetime.datetime(2003, 9, 25, 10, 49, 41) - ->>> parse("2003-09-25T10:49") -datetime.datetime(2003, 9, 25, 10, 49) - ->>> parse("2003-09-25T10") -datetime.datetime(2003, 9, 25, 10, 0) - ->>> parse("2003-09-25") -datetime.datetime(2003, 9, 25, 0, 0) -}}} - -ISO format, without separators: -{{{ ->>> parse("20030925T104941.5-0300") -datetime.datetime(2003, 9, 25, 10, 49, 41, 500000, - tzinfo=tzinfo=tzoffset(None, -10800)) - ->>> parse("20030925T104941-0300") -datetime.datetime(2003, 9, 25, 10, 49, 41, - tzinfo=tzoffset(None, -10800)) - ->>> parse("20030925T104941") -datetime.datetime(2003, 9, 25, 10, 49, 41) - ->>> parse("20030925T1049") -datetime.datetime(2003, 9, 25, 10, 49) - ->>> parse("20030925T10") -datetime.datetime(2003, 9, 25, 10, 0) - ->>> parse("20030925") -datetime.datetime(2003, 9, 25, 0, 0) -}}} - -Everything together. -{{{ ->>> parse("199709020900") -datetime.datetime(1997, 9, 2, 9, 0) ->>> parse("19970902090059") -datetime.datetime(1997, 9, 2, 9, 0, 59) -}}} - -Different date orderings: -{{{ ->>> parse("2003-09-25") -datetime.datetime(2003, 9, 25, 0, 0) - ->>> parse("2003-Sep-25") -datetime.datetime(2003, 9, 25, 0, 0) - ->>> parse("25-Sep-2003") -datetime.datetime(2003, 9, 25, 0, 0) - ->>> parse("Sep-25-2003") -datetime.datetime(2003, 9, 25, 0, 0) - ->>> parse("09-25-2003") -datetime.datetime(2003, 9, 25, 0, 0) - ->>> parse("25-09-2003") -datetime.datetime(2003, 9, 25, 0, 0) -}}} - -Check some ambiguous dates: -{{{ ->>> parse("10-09-2003") -datetime.datetime(2003, 10, 9, 0, 0) - ->>> parse("10-09-2003", dayfirst=True) -datetime.datetime(2003, 9, 10, 0, 0) - ->>> parse("10-09-03") -datetime.datetime(2003, 10, 9, 0, 0) - ->>> parse("10-09-03", yearfirst=True) -datetime.datetime(2010, 9, 3, 0, 0) -}}} - -Other date separators are allowed: -{{{ ->>> parse("2003.Sep.25") -datetime.datetime(2003, 9, 25, 0, 0) - ->>> parse("2003/09/25") -datetime.datetime(2003, 9, 25, 0, 0) -}}} - -Even with spaces: -{{{ ->>> parse("2003 Sep 25") -datetime.datetime(2003, 9, 25, 0, 0) - ->>> parse("2003 09 25") -datetime.datetime(2003, 9, 25, 0, 0) -}}} - -Hours with letters work: -{{{ ->>> parse("10h36m28.5s", default=DEFAULT) -datetime.datetime(2003, 9, 25, 10, 36, 28, 500000) - ->>> parse("01s02h03m", default=DEFAULT) -datetime.datetime(2003, 9, 25, 2, 3, 1) - ->>> parse("01h02m03", default=DEFAULT) -datetime.datetime(2003, 9, 3, 1, 2) - ->>> parse("01h02", default=DEFAULT) -datetime.datetime(2003, 9, 2, 1, 0) - ->>> parse("01h02s", default=DEFAULT) -datetime.datetime(2003, 9, 25, 1, 0, 2) -}}} - -With AM/PM: -{{{ ->>> parse("10h am", default=DEFAULT) -datetime.datetime(2003, 9, 25, 10, 0) - ->>> parse("10pm", default=DEFAULT) -datetime.datetime(2003, 9, 25, 22, 0) - ->>> parse("12:00am", default=DEFAULT) -datetime.datetime(2003, 9, 25, 0, 0) - ->>> parse("12pm", default=DEFAULT) -datetime.datetime(2003, 9, 25, 12, 0) -}}} - -Some special treating for ''pertain'' relations: -{{{ ->>> parse("Sep 03", default=DEFAULT) -datetime.datetime(2003, 9, 3, 0, 0) - ->>> parse("Sep of 03", default=DEFAULT) -datetime.datetime(2003, 9, 25, 0, 0) -}}} - -Fuzzy parsing: -{{{ ->>> s = "Today is 25 of September of 2003, exactly " \ -... "at 10:49:41 with timezone -03:00." ->>> parse(s, fuzzy=True) -datetime.datetime(2003, 9, 25, 10, 49, 41, - tzinfo=tzoffset(None, -10800)) -}}} - -Other random formats: -{{{ ->>> parse("Wed, July 10, '96") -datetime.datetime(1996, 7, 10, 0, 0) - ->>> parse("1996.07.10 AD at 15:08:56 PDT", ignoretz=True) -datetime.datetime(1996, 7, 10, 15, 8, 56) - ->>> parse("Tuesday, April 12, 1952 AD 3:30:42pm PST", ignoretz=True) -datetime.datetime(1952, 4, 12, 15, 30, 42) - ->>> parse("November 5, 1994, 8:15:30 am EST", ignoretz=True) -datetime.datetime(1994, 11, 5, 8, 15, 30) - ->>> parse("3rd of May 2001") -datetime.datetime(2001, 5, 3, 0, 0) - ->>> parse("5:50 A.M. on June 13, 1990") -datetime.datetime(1990, 6, 13, 5, 50) -}}} - -=== easter === -This module offers a generic easter computing method for -any given year, using Western, Orthodox or Julian algorithms. - -==== easter() function ==== -This method was ported from the work done by -[http://users.chariot.net.au/~gmarts/eastalg.htm GM Arts], -on top of the algorithm by -[http://www.tondering.dk/claus/calendar.html Claus Tondering], -which was based in part on the algorithm of Ouding (1940), -as quoted in "Explanatory Supplement to the Astronomical -Almanac", P. Kenneth Seidelmann, editor. - -This algorithm implements three different easter -calculation methods: - - 1. Original calculation in Julian calendar, valid in - dates after 326 AD - 1. Original method, with date converted to Gregorian - calendar, valid in years 1583 to 4099 - 1. Revised method, in Gregorian calendar, valid in - years 1583 to 4099 as well - -These methods are represented by the constants: -{{{ -EASTER_JULIAN = 1 -EASTER_ORTHODOX = 2 -EASTER_WESTERN = 3 -}}} - -The default method is method 3. - -=== tz === -This module offers timezone implementations subclassing -the abstract {{{datetime.tzinfo}}} type. There are -classes to handle [http://www.twinsun.com/tz/tz-link.htm tzfile] -format files (usually are in /etc/localtime, -/usr/share/zoneinfo, etc), TZ environment string (in all -known formats), given ranges (with help from relative -deltas), local machine timezone, fixed offset timezone, -and UTC timezone. - -==== tzutc type ==== -This type implements a basic UTC timezone. The constructor of this -type accepts no parameters. - -==== tzutc examples ==== -{{{ ->>> from datetime import * ->>> from dateutil.tz import * - ->>> datetime.now() -datetime.datetime(2003, 9, 27, 9, 40, 1, 521290) - ->>> datetime.now(tzutc()) -datetime.datetime(2003, 9, 27, 12, 40, 12, 156379, tzinfo=tzutc()) - ->>> datetime.now(tzutc()).tzname() -'UTC' -}}} - -==== tzoffset type ==== -This type implements a fixed offset timezone, with no -support to daylight saving times. Here is the prototype of the -type constructor: -{{{ -tzoffset(name, offset) -}}} - -The {{{name}}} parameter may be optionally set to {{{None}}}, and -{{{offset}}} must be given in seconds. - -==== tzoffset examples ==== -{{{ ->>> from datetime import * ->>> from dateutil.tz import * - ->>> datetime.now(tzoffset("BRST", -10800)) -datetime.datetime(2003, 9, 27, 9, 52, 43, 624904, - tzinfo=tzinfo=tzoffset('BRST', -10800)) - ->>> datetime.now(tzoffset("BRST", -10800)).tzname() -'BRST' - ->>> datetime.now(tzoffset("BRST", -10800)).astimezone(tzutc()) -datetime.datetime(2003, 9, 27, 12, 53, 11, 446419, - tzinfo=tzutc()) -}}} - -==== tzlocal type ==== -This type implements timezone settings as known by the -operating system. The constructor of this type accepts no -parameters. - -==== tzlocal examples ==== -{{{ ->>> from datetime import * ->>> from dateutil.tz import * - ->>> datetime.now(tzlocal()) -datetime.datetime(2003, 9, 27, 10, 1, 43, 673605, - tzinfo=tzlocal()) - ->>> datetime.now(tzlocal()).tzname() -'BRST' - ->>> datetime.now(tzlocal()).astimezone(tzoffset(None, 0)) -datetime.datetime(2003, 9, 27, 13, 3, 0, 11493, - tzinfo=tzoffset(None, 0)) -}}} - -==== tzstr type ==== -This type implements timezone settings extracted from a -string in known TZ environment variable formats. Here is the prototype -of the constructor: -{{{ -tzstr(str) -}}} - -==== tzstr examples ==== -Here are examples of the recognized formats: - - * {{{EST5EDT}}} - * {{{EST5EDT,4,0,6,7200,10,0,26,7200,3600}}} - * {{{EST5EDT,4,1,0,7200,10,-1,0,7200,3600}}} - * {{{EST5EDT4,M4.1.0/02:00:00,M10-5-0/02:00}}} - * {{{EST5EDT4,95/02:00:00,298/02:00}}} - * {{{EST5EDT4,J96/02:00:00,J299/02:00}}} - -Notice that if daylight information is not present, but a -daylight abbreviation was provided, {{{tzstr}}} will follow the -convention of using the first sunday of April to start daylight -saving, and the last sunday of October to end it. If start or -end time is not present, 2AM will be used, and if the daylight -offset is not present, the standard offset plus one hour will -be used. This convention is the same as used in the GNU libc. - -This also means that some of the above examples are exactly -equivalent, and all of these examples are equivalent -in the year of 2003. - -Here is the example mentioned in the -[http://www.python.org/doc/current/lib/module-time.html time module documentation]. -{{{ ->>> os.environ['TZ'] = 'EST+05EDT,M4.1.0,M10.5.0' ->>> time.tzset() ->>> time.strftime('%X %x %Z') -'02:07:36 05/08/03 EDT' ->>> os.environ['TZ'] = 'AEST-10AEDT-11,M10.5.0,M3.5.0' ->>> time.tzset() ->>> time.strftime('%X %x %Z') -'16:08:12 05/08/03 AEST' -}}} - -And here is an example showing the same information using {{{tzstr}}}, -without touching system settings. -{{{ ->>> tz1 = tzstr('EST+05EDT,M4.1.0,M10.5.0') ->>> tz2 = tzstr('AEST-10AEDT-11,M10.5.0,M3.5.0') ->>> dt = datetime(2003, 5, 8, 2, 7, 36, tzinfo=tz1) ->>> dt.strftime('%X %x %Z') -'02:07:36 05/08/03 EDT' ->>> dt.astimezone(tz2).strftime('%X %x %Z') -'16:07:36 05/08/03 AEST' -}}} - -Are these really equivalent? -{{{ ->>> tzstr('EST5EDT') == tzstr('EST5EDT,4,1,0,7200,10,-1,0,7200,3600') -True -}}} - -Check the daylight limit. -{{{ ->>> datetime(2003, 4, 6, 1, 59, tzinfo=tz).tzname() -'EST' ->>> datetime(2003, 4, 6, 2, 00, tzinfo=tz).tzname() -'EDT' ->>> datetime(2003, 10, 26, 0, 59, tzinfo=tz).tzname() -'EDT' ->>> datetime(2003, 10, 26, 1, 00, tzinfo=tz).tzname() -'EST' -}}} - -==== tzrange type ==== -This type offers the same functionality as the {{{tzstr}}} type, but -instead of timezone strings, information is passed using -{{{relativedelta}}}s which are applied to a datetime set to the first -day of the year. Here is the prototype of this type's constructor: -{{{ -tzrange(stdabbr, stdoffset=None, dstabbr=None, dstoffset=None, - start=None, end=None): -}}} - -Offsets must be given in seconds. Information not provided will be -set to the defaults, as explained in the {{{tzstr}}} section above. - -==== tzrange examples ==== -{{{ ->>> tzstr('EST5EDT') == tzrange("EST", -18000, "EDT") -True - ->>> from dateutil.relativedelta import * ->>> range1 = tzrange("EST", -18000, "EDT") ->>> range2 = tzrange("EST", -18000, "EDT", -14400, -... relativedelta(hours=+2, month=4, day=1, - weekday=SU(+1)), -... relativedelta(hours=+1, month=10, day=31, - weekday=SU(-1))) ->>> tzstr('EST5EDT') == range1 == range2 -True -}}} - -Notice a minor detail in the last example: while the DST should end -at 2AM, the delta will catch 1AM. That's because the daylight saving -time should end at 2AM standard time (the difference between STD and -DST is 1h in the given example) instead of the DST time. That's how -the {{{tzinfo}}} subtypes should deal with the extra hour that happens -when going back to the standard time. Check -[http://www.python.org/doc/current/lib/datetime-tzinfo.html tzinfo documentation] -for more information. - -==== tzfile type ==== -This type allows one to use tzfile(5) format timezone files to extract -current and historical zone information. Here is the type constructor -prototype: -{{{ -tzfile(fileobj) -}}} - -Where {{{fileobj}}} is either a filename or a file-like object with -a {{{read()}}} method. - -==== tzfile examples ==== -{{{ ->>> tz = tzfile("/etc/localtime") ->>> datetime.now(tz) -datetime.datetime(2003, 9, 27, 12, 3, 48, 392138, - tzinfo=tzfile('/etc/localtime')) - ->>> datetime.now(tz).astimezone(tzutc()) -datetime.datetime(2003, 9, 27, 15, 3, 53, 70863, - tzinfo=tzutc()) - ->>> datetime.now(tz).tzname() -'BRST' ->>> datetime(2003, 1, 1, tzinfo=tz).tzname() -'BRDT' -}}} - -Check the daylight limit. -{{{ ->>> tz = tzfile('/usr/share/zoneinfo/EST5EDT') ->>> datetime(2003, 4, 6, 1, 59, tzinfo=tz).tzname() -'EST' ->>> datetime(2003, 4, 6, 2, 00, tzinfo=tz).tzname() -'EDT' ->>> datetime(2003, 10, 26, 0, 59, tzinfo=tz).tzname() -'EDT' ->>> datetime(2003, 10, 26, 1, 00, tzinfo=tz).tzname() -'EST' -}}} - -==== tzical type ==== -This type is able to parse -[ftp://ftp.rfc-editor.org/in-notes/rfc2445.txt iCalendar] -style {{{VTIMEZONE}}} sessions into a Python timezone object. -The constuctor prototype is: -{{{ -tzical(fileobj) -}}} - -Where {{{fileobj}}} is either a filename or a file-like object with -a {{{read()}}} method. - -==== tzical methods ==== - - tzical.get(tzid=None):: - Since a single iCalendar file may contain more than one timezone, - you must ask for the timezone you want with this method. If there's - more than one timezone in the parsed file, you'll need to pass the - {{{tzid}}} parameter. Otherwise, leaving it empty will yield the only - available timezone. - -==== tzical examples ==== -Here is a sample file extracted from the RFC. This file defines -the {{{EST5EDT}}} timezone, and will be used in the following example. -{{{ -BEGIN:VTIMEZONE -TZID:US-Eastern -LAST-MODIFIED:19870101T000000Z -TZURL:http://zones.stds_r_us.net/tz/US-Eastern -BEGIN:STANDARD -DTSTART:19671029T020000 -RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 -TZOFFSETFROM:-0400 -TZOFFSETTO:-0500 -TZNAME:EST -END:STANDARD -BEGIN:DAYLIGHT -DTSTART:19870405T020000 -RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4 -TZOFFSETFROM:-0500 -TZOFFSETTO:-0400 -TZNAME:EDT -END:DAYLIGHT -END:VTIMEZONE -}}} - -And here is an example exploring a {{{tzical}}} type: -{{{ ->>> from dateutil.tz import *; from datetime import * - ->>> tz = tzical('EST5EDT.ics') ->>> tz.keys() -['US-Eastern'] - ->>> est = tz.get('US-Eastern') ->>> est - - ->>> datetime.now(est) -datetime.datetime(2003, 10, 6, 19, 44, 18, 667987, - tzinfo=) - ->>> est == tz.get() -True -}}} - -Let's check the daylight ranges, as usual: -{{{ ->>> datetime(2003, 4, 6, 1, 59, tzinfo=est).tzname() -'EST' ->>> datetime(2003, 4, 6, 2, 00, tzinfo=est).tzname() -'EDT' - ->>> datetime(2003, 10, 26, 0, 59, tzinfo=est).tzname() -'EDT' ->>> datetime(2003, 10, 26, 1, 00, tzinfo=est).tzname() -'EST' -}}} - -==== tzwin type ==== -This type offers access to internal registry-based Windows timezones. -The constuctor prototype is: -{{{ -tzwin(name) -}}} - -Where {{{name}}} is the timezone name. There's a static {{{tzwin.list()}}} -method to check the available names, - -==== tzwin methods ==== - - tzwin.display():: - This method returns the timezone extended name. - - tzwin.list():: - This static method lists all available timezone names. - -==== tzwin examples ==== -{{{ ->>> tz = tzwin("E. South America Standard Time") -}}} - -==== tzwinlocal type ==== -This type offers access to internal registry-based Windows timezones. -The constructor accepts no parameters, so the prototype is: -{{{ -tzwinlocal() -}}} - -==== tzwinlocal methods ==== - - tzwinlocal.display():: - This method returns the timezone extended name, and returns - {{{None}}} if one is not available. - -==== tzwinlocal examples ==== -{{{ ->>> tz = tzwinlocal() -}}} - -==== gettz() function ==== -This function is a helper that will try its best to get the right -timezone for your environment, or for the given string. The prototype -is as follows: -{{{ -gettz(name=None) -}}} - -If given, the parameter may be a filename, a path relative to the base -of the timezone information path (the base could be -{{{/usr/share/zoneinfo}}}, for example), a string timezone -specification, or a timezone abbreviation. If {{{name}}} is not given, -and the {{{TZ}}} environment variable is set, it's used instead. If the -parameter is not given, and {{{TZ}}} is not set, the default tzfile -paths will be tried. Then, if no timezone information is found, -an internal compiled database of timezones is used. When running -on Windows, the internal registry-based Windows timezones are also -considered. - -Example: -{{{ ->>> from dateutil.tz import * ->>> gettz() -tzfile('/etc/localtime') - ->>> gettz("America/Sao Paulo") -tzfile('/usr/share/zoneinfo/America/Sao_Paulo') - ->>> gettz("EST5EDT") -tzfile('/usr/share/zoneinfo/EST5EDT') - ->>> gettz("EST5") -tzstr('EST5') - ->>> gettz('BRST') -tzlocal() - ->>> os.environ["TZ"] = "America/Sao Paulo" ->>> gettz() -tzfile('/usr/share/zoneinfo/America/Sao_Paulo') - ->>> os.environ["TZ"] = "BRST" ->>> gettz() -tzlocal() - ->>> gettz("Unavailable") ->>> -}}} - -=== zoneinfo === -This module provides direct access to the internal compiled -database of timezones. The timezone data and the compiling tools -are obtained from the following project: - - http://www.twinsun.com/tz/tz-link.htm - -==== gettz() function ==== -This function will try to retrieve the given timezone information -from the internal compiled database, and will cache its results. - -Example: -{{{ ->>> from dateutil import zoneinfo ->>> zoneinfo.gettz("Brazil/East") -tzfile('Brazil/East') -}}} - -## vim:ft=moin diff -Nru matplotlib-1.1.1/lib/dateutil/__init__.py matplotlib-1.2.0/lib/dateutil/__init__.py --- matplotlib-1.1.1/lib/dateutil/__init__.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil/__init__.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -""" -Copyright (c) 2003-2010 Gustavo Niemeyer - -This module offers extensions to the standard python 2.3+ -datetime module. -""" -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" -__version__ = "1.5" diff -Nru matplotlib-1.1.1/lib/dateutil/easter.py matplotlib-1.2.0/lib/dateutil/easter.py --- matplotlib-1.1.1/lib/dateutil/easter.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil/easter.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -""" -Copyright (c) 2003-2007 Gustavo Niemeyer - -This module offers extensions to the standard python 2.3+ -datetime module. -""" -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" - -import datetime - -__all__ = ["easter", "EASTER_JULIAN", "EASTER_ORTHODOX", "EASTER_WESTERN"] - -EASTER_JULIAN = 1 -EASTER_ORTHODOX = 2 -EASTER_WESTERN = 3 - -def easter(year, method=EASTER_WESTERN): - """ - This method was ported from the work done by GM Arts, - on top of the algorithm by Claus Tondering, which was - based in part on the algorithm of Ouding (1940), as - quoted in "Explanatory Supplement to the Astronomical - Almanac", P. Kenneth Seidelmann, editor. - - This algorithm implements three different easter - calculation methods: - - 1 - Original calculation in Julian calendar, valid in - dates after 326 AD - 2 - Original method, with date converted to Gregorian - calendar, valid in years 1583 to 4099 - 3 - Revised method, in Gregorian calendar, valid in - years 1583 to 4099 as well - - These methods are represented by the constants: - - EASTER_JULIAN = 1 - EASTER_ORTHODOX = 2 - EASTER_WESTERN = 3 - - The default method is method 3. - - More about the algorithm may be found at: - - http://users.chariot.net.au/~gmarts/eastalg.htm - - and - - http://www.tondering.dk/claus/calendar.html - - """ - - if not (1 <= method <= 3): - raise ValueError, "invalid method" - - # g - Golden year - 1 - # c - Century - # h - (23 - Epact) mod 30 - # i - Number of days from March 21 to Paschal Full Moon - # j - Weekday for PFM (0=Sunday, etc) - # p - Number of days from March 21 to Sunday on or before PFM - # (-6 to 28 methods 1 & 3, to 56 for method 2) - # e - Extra days to add for method 2 (converting Julian - # date to Gregorian date) - - y = year - g = y % 19 - e = 0 - if method < 3: - # Old method - i = (19*g+15)%30 - j = (y+y//4+i)%7 - if method == 2: - # Extra dates to convert Julian to Gregorian date - e = 10 - if y > 1600: - e = e+y//100-16-(y//100-16)//4 - else: - # New method - c = y//100 - h = (c-c//4-(8*c+13)//25+19*g+15)%30 - i = h-(h//28)*(1-(h//28)*(29//(h+1))*((21-g)//11)) - j = (y+y//4+i+2-c+c//4)%7 - - # p can be from -6 to 56 corresponding to dates 22 March to 23 May - # (later dates apply to method 2, although 23 May never actually occurs) - p = i-j+e - d = 1+(p+27+(p+6)//40)%31 - m = 3+(p+26)//30 - return datetime.date(int(y),int(m),int(d)) - diff -Nru matplotlib-1.1.1/lib/dateutil/parser.py matplotlib-1.2.0/lib/dateutil/parser.py --- matplotlib-1.1.1/lib/dateutil/parser.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil/parser.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,886 +0,0 @@ -# -*- coding:iso-8859-1 -*- -""" -Copyright (c) 2003-2007 Gustavo Niemeyer - -This module offers extensions to the standard python 2.3+ -datetime module. -""" -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" - -import datetime -import string -import time -import sys -import os - -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO - -import relativedelta -import tz - - -__all__ = ["parse", "parserinfo"] - - -# Some pointers: -# -# http://www.cl.cam.ac.uk/~mgk25/iso-time.html -# http://www.iso.ch/iso/en/prods-services/popstds/datesandtime.html -# http://www.w3.org/TR/NOTE-datetime -# http://ringmaster.arc.nasa.gov/tools/time_formats.html -# http://search.cpan.org/author/MUIR/Time-modules-2003.0211/lib/Time/ParseDate.pm -# http://stein.cshl.org/jade/distrib/docs/java.text.SimpleDateFormat.html - - -class _timelex(object): - - def __init__(self, instream): - if isinstance(instream, basestring): - instream = StringIO(instream) - self.instream = instream - self.wordchars = ('abcdfeghijklmnopqrstuvwxyz' - 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_' - '' - '') - self.numchars = '0123456789' - self.whitespace = ' \t\r\n' - self.charstack = [] - self.tokenstack = [] - self.eof = False - - def get_token(self): - if self.tokenstack: - return self.tokenstack.pop(0) - seenletters = False - token = None - state = None - wordchars = self.wordchars - numchars = self.numchars - whitespace = self.whitespace - while not self.eof: - if self.charstack: - nextchar = self.charstack.pop(0) - else: - nextchar = self.instream.read(1) - while nextchar == '\x00': - nextchar = self.instream.read(1) - if not nextchar: - self.eof = True - break - elif not state: - token = nextchar - if nextchar in wordchars: - state = 'a' - elif nextchar in numchars: - state = '0' - elif nextchar in whitespace: - token = ' ' - break # emit token - else: - break # emit token - elif state == 'a': - seenletters = True - if nextchar in wordchars: - token += nextchar - elif nextchar == '.': - token += nextchar - state = 'a.' - else: - self.charstack.append(nextchar) - break # emit token - elif state == '0': - if nextchar in numchars: - token += nextchar - elif nextchar == '.': - token += nextchar - state = '0.' - else: - self.charstack.append(nextchar) - break # emit token - elif state == 'a.': - seenletters = True - if nextchar == '.' or nextchar in wordchars: - token += nextchar - elif nextchar in numchars and token[-1] == '.': - token += nextchar - state = '0.' - else: - self.charstack.append(nextchar) - break # emit token - elif state == '0.': - if nextchar == '.' or nextchar in numchars: - token += nextchar - elif nextchar in wordchars and token[-1] == '.': - token += nextchar - state = 'a.' - else: - self.charstack.append(nextchar) - break # emit token - if (state in ('a.', '0.') and - (seenletters or token.count('.') > 1 or token[-1] == '.')): - l = token.split('.') - token = l[0] - for tok in l[1:]: - self.tokenstack.append('.') - if tok: - self.tokenstack.append(tok) - return token - - def __iter__(self): - return self - - def next(self): - token = self.get_token() - if token is None: - raise StopIteration - return token - - def split(cls, s): - return list(cls(s)) - split = classmethod(split) - - -class _resultbase(object): - - def __init__(self): - for attr in self.__slots__: - setattr(self, attr, None) - - def _repr(self, classname): - l = [] - for attr in self.__slots__: - value = getattr(self, attr) - if value is not None: - l.append("%s=%s" % (attr, `value`)) - return "%s(%s)" % (classname, ", ".join(l)) - - def __repr__(self): - return self._repr(self.__class__.__name__) - - -class parserinfo(object): - - # m from a.m/p.m, t from ISO T separator - JUMP = [" ", ".", ",", ";", "-", "/", "'", - "at", "on", "and", "ad", "m", "t", "of", - "st", "nd", "rd", "th"] - - WEEKDAYS = [("Mon", "Monday"), - ("Tue", "Tuesday"), - ("Wed", "Wednesday"), - ("Thu", "Thursday"), - ("Fri", "Friday"), - ("Sat", "Saturday"), - ("Sun", "Sunday")] - MONTHS = [("Jan", "January"), - ("Feb", "February"), - ("Mar", "March"), - ("Apr", "April"), - ("May", "May"), - ("Jun", "June"), - ("Jul", "July"), - ("Aug", "August"), - ("Sep", "September"), - ("Oct", "October"), - ("Nov", "November"), - ("Dec", "December")] - HMS = [("h", "hour", "hours"), - ("m", "minute", "minutes"), - ("s", "second", "seconds")] - AMPM = [("am", "a"), - ("pm", "p")] - UTCZONE = ["UTC", "GMT", "Z"] - PERTAIN = ["of"] - TZOFFSET = {} - - def __init__(self, dayfirst=False, yearfirst=False): - self._jump = self._convert(self.JUMP) - self._weekdays = self._convert(self.WEEKDAYS) - self._months = self._convert(self.MONTHS) - self._hms = self._convert(self.HMS) - self._ampm = self._convert(self.AMPM) - self._utczone = self._convert(self.UTCZONE) - self._pertain = self._convert(self.PERTAIN) - - self.dayfirst = dayfirst - self.yearfirst = yearfirst - - self._year = time.localtime().tm_year - self._century = self._year//100*100 - - def _convert(self, lst): - dct = {} - for i in range(len(lst)): - v = lst[i] - if isinstance(v, tuple): - for v in v: - dct[v.lower()] = i - else: - dct[v.lower()] = i - return dct - - def jump(self, name): - return name.lower() in self._jump - - def weekday(self, name): - if len(name) >= 3: - try: - return self._weekdays[name.lower()] - except KeyError: - pass - return None - - def month(self, name): - if len(name) >= 3: - try: - return self._months[name.lower()]+1 - except KeyError: - pass - return None - - def hms(self, name): - try: - return self._hms[name.lower()] - except KeyError: - return None - - def ampm(self, name): - try: - return self._ampm[name.lower()] - except KeyError: - return None - - def pertain(self, name): - return name.lower() in self._pertain - - def utczone(self, name): - return name.lower() in self._utczone - - def tzoffset(self, name): - if name in self._utczone: - return 0 - return self.TZOFFSET.get(name) - - def convertyear(self, year): - if year < 100: - year += self._century - if abs(year-self._year) >= 50: - if year < self._year: - year += 100 - else: - year -= 100 - return year - - def validate(self, res): - # move to info - if res.year is not None: - res.year = self.convertyear(res.year) - if res.tzoffset == 0 and not res.tzname or res.tzname == 'Z': - res.tzname = "UTC" - res.tzoffset = 0 - elif res.tzoffset != 0 and res.tzname and self.utczone(res.tzname): - res.tzoffset = 0 - return True - - -class parser(object): - - def __init__(self, info=None): - self.info = info or parserinfo() - - def parse(self, timestr, default=None, - ignoretz=False, tzinfos=None, - **kwargs): - if not default: - default = datetime.datetime.now().replace(hour=0, minute=0, - second=0, microsecond=0) - res = self._parse(timestr, **kwargs) - if res is None: - raise ValueError, "unknown string format" - repl = {} - for attr in ["year", "month", "day", "hour", - "minute", "second", "microsecond"]: - value = getattr(res, attr) - if value is not None: - repl[attr] = value - ret = default.replace(**repl) - if res.weekday is not None and not res.day: - ret = ret+relativedelta.relativedelta(weekday=res.weekday) - if not ignoretz: - if callable(tzinfos) or tzinfos and res.tzname in tzinfos: - if callable(tzinfos): - tzdata = tzinfos(res.tzname, res.tzoffset) - else: - tzdata = tzinfos.get(res.tzname) - if isinstance(tzdata, datetime.tzinfo): - tzinfo = tzdata - elif isinstance(tzdata, basestring): - tzinfo = tz.tzstr(tzdata) - elif isinstance(tzdata, int): - tzinfo = tz.tzoffset(res.tzname, tzdata) - else: - raise ValueError, "offset must be tzinfo subclass, " \ - "tz string, or int offset" - ret = ret.replace(tzinfo=tzinfo) - elif res.tzname and res.tzname in time.tzname: - ret = ret.replace(tzinfo=tz.tzlocal()) - elif res.tzoffset == 0: - ret = ret.replace(tzinfo=tz.tzutc()) - elif res.tzoffset: - ret = ret.replace(tzinfo=tz.tzoffset(res.tzname, res.tzoffset)) - return ret - - class _result(_resultbase): - __slots__ = ["year", "month", "day", "weekday", - "hour", "minute", "second", "microsecond", - "tzname", "tzoffset"] - - def _parse(self, timestr, dayfirst=None, yearfirst=None, fuzzy=False): - info = self.info - if dayfirst is None: - dayfirst = info.dayfirst - if yearfirst is None: - yearfirst = info.yearfirst - res = self._result() - l = _timelex.split(timestr) - try: - - # year/month/day list - ymd = [] - - # Index of the month string in ymd - mstridx = -1 - - len_l = len(l) - i = 0 - while i < len_l: - - # Check if it's a number - try: - value_repr = l[i] - value = float(value_repr) - except ValueError: - value = None - - if value is not None: - # Token is a number - len_li = len(l[i]) - i += 1 - if (len(ymd) == 3 and len_li in (2, 4) - and (i >= len_l or (l[i] != ':' and - info.hms(l[i]) is None))): - # 19990101T23[59] - s = l[i-1] - res.hour = int(s[:2]) - if len_li == 4: - res.minute = int(s[2:]) - elif len_li == 6 or (len_li > 6 and l[i-1].find('.') == 6): - # YYMMDD or HHMMSS[.ss] - s = l[i-1] - if not ymd and l[i-1].find('.') == -1: - ymd.append(info.convertyear(int(s[:2]))) - ymd.append(int(s[2:4])) - ymd.append(int(s[4:])) - else: - # 19990101T235959[.59] - res.hour = int(s[:2]) - res.minute = int(s[2:4]) - res.second, res.microsecond = _parsems(s[4:]) - elif len_li == 8: - # YYYYMMDD - s = l[i-1] - ymd.append(int(s[:4])) - ymd.append(int(s[4:6])) - ymd.append(int(s[6:])) - elif len_li in (12, 14): - # YYYYMMDDhhmm[ss] - s = l[i-1] - ymd.append(int(s[:4])) - ymd.append(int(s[4:6])) - ymd.append(int(s[6:8])) - res.hour = int(s[8:10]) - res.minute = int(s[10:12]) - if len_li == 14: - res.second = int(s[12:]) - elif ((i < len_l and info.hms(l[i]) is not None) or - (i+1 < len_l and l[i] == ' ' and - info.hms(l[i+1]) is not None)): - # HH[ ]h or MM[ ]m or SS[.ss][ ]s - if l[i] == ' ': - i += 1 - idx = info.hms(l[i]) - while True: - if idx == 0: - res.hour = int(value) - if value%1: - res.minute = int(60*(value%1)) - elif idx == 1: - res.minute = int(value) - if value%1: - res.second = int(60*(value%1)) - elif idx == 2: - res.second, res.microsecond = \ - _parsems(value_repr) - i += 1 - if i >= len_l or idx == 2: - break - # 12h00 - try: - value_repr = l[i] - value = float(value_repr) - except ValueError: - break - else: - i += 1 - idx += 1 - if i < len_l: - newidx = info.hms(l[i]) - if newidx is not None: - idx = newidx - elif i+1 < len_l and l[i] == ':': - # HH:MM[:SS[.ss]] - res.hour = int(value) - i += 1 - value = float(l[i]) - res.minute = int(value) - if value%1: - res.second = int(60*(value%1)) - i += 1 - if i < len_l and l[i] == ':': - res.second, res.microsecond = _parsems(l[i+1]) - i += 2 - elif i < len_l and l[i] in ('-', '/', '.'): - sep = l[i] - ymd.append(int(value)) - i += 1 - if i < len_l and not info.jump(l[i]): - try: - # 01-01[-01] - ymd.append(int(l[i])) - except ValueError: - # 01-Jan[-01] - value = info.month(l[i]) - if value is not None: - ymd.append(value) - assert mstridx == -1 - mstridx = len(ymd)-1 - else: - return None - i += 1 - if i < len_l and l[i] == sep: - # We have three members - i += 1 - value = info.month(l[i]) - if value is not None: - ymd.append(value) - mstridx = len(ymd)-1 - assert mstridx == -1 - else: - ymd.append(int(l[i])) - i += 1 - elif i >= len_l or info.jump(l[i]): - if i+1 < len_l and info.ampm(l[i+1]) is not None: - # 12 am - res.hour = int(value) - if res.hour < 12 and info.ampm(l[i+1]) == 1: - res.hour += 12 - elif res.hour == 12 and info.ampm(l[i+1]) == 0: - res.hour = 0 - i += 1 - else: - # Year, month or day - ymd.append(int(value)) - i += 1 - elif info.ampm(l[i]) is not None: - # 12am - res.hour = int(value) - if res.hour < 12 and info.ampm(l[i]) == 1: - res.hour += 12 - elif res.hour == 12 and info.ampm(l[i]) == 0: - res.hour = 0 - i += 1 - elif not fuzzy: - return None - else: - i += 1 - continue - - # Check weekday - value = info.weekday(l[i]) - if value is not None: - res.weekday = value - i += 1 - continue - - # Check month name - value = info.month(l[i]) - if value is not None: - ymd.append(value) - assert mstridx == -1 - mstridx = len(ymd)-1 - i += 1 - if i < len_l: - if l[i] in ('-', '/'): - # Jan-01[-99] - sep = l[i] - i += 1 - ymd.append(int(l[i])) - i += 1 - if i < len_l and l[i] == sep: - # Jan-01-99 - i += 1 - ymd.append(int(l[i])) - i += 1 - elif (i+3 < len_l and l[i] == l[i+2] == ' ' - and info.pertain(l[i+1])): - # Jan of 01 - # In this case, 01 is clearly year - try: - value = int(l[i+3]) - except ValueError: - # Wrong guess - pass - else: - # Convert it here to become unambiguous - ymd.append(info.convertyear(value)) - i += 4 - continue - - # Check am/pm - value = info.ampm(l[i]) - if value is not None: - if value == 1 and res.hour < 12: - res.hour += 12 - elif value == 0 and res.hour == 12: - res.hour = 0 - i += 1 - continue - - # Check for a timezone name - if (res.hour is not None and len(l[i]) <= 5 and - res.tzname is None and res.tzoffset is None and - not [x for x in l[i] if x not in string.ascii_uppercase]): - res.tzname = l[i] - res.tzoffset = info.tzoffset(res.tzname) - i += 1 - - # Check for something like GMT+3, or BRST+3. Notice - # that it doesn't mean "I am 3 hours after GMT", but - # "my time +3 is GMT". If found, we reverse the - # logic so that timezone parsing code will get it - # right. - if i < len_l and l[i] in ('+', '-'): - l[i] = ('+', '-')[l[i] == '+'] - res.tzoffset = None - if info.utczone(res.tzname): - # With something like GMT+3, the timezone - # is *not* GMT. - res.tzname = None - - continue - - # Check for a numbered timezone - if res.hour is not None and l[i] in ('+', '-'): - signal = (-1,1)[l[i] == '+'] - i += 1 - len_li = len(l[i]) - if len_li == 4: - # -0300 - res.tzoffset = int(l[i][:2])*3600+int(l[i][2:])*60 - elif i+1 < len_l and l[i+1] == ':': - # -03:00 - res.tzoffset = int(l[i])*3600+int(l[i+2])*60 - i += 2 - elif len_li <= 2: - # -[0]3 - res.tzoffset = int(l[i][:2])*3600 - else: - return None - i += 1 - res.tzoffset *= signal - - # Look for a timezone name between parenthesis - if (i+3 < len_l and - info.jump(l[i]) and l[i+1] == '(' and l[i+3] == ')' and - 3 <= len(l[i+2]) <= 5 and - not [x for x in l[i+2] - if x not in string.ascii_uppercase]): - # -0300 (BRST) - res.tzname = l[i+2] - i += 4 - continue - - # Check jumps - if not (info.jump(l[i]) or fuzzy): - return None - - i += 1 - - # Process year/month/day - len_ymd = len(ymd) - if len_ymd > 3: - # More than three members!? - return None - elif len_ymd == 1 or (mstridx != -1 and len_ymd == 2): - # One member, or two members with a month string - if mstridx != -1: - res.month = ymd[mstridx] - del ymd[mstridx] - if len_ymd > 1 or mstridx == -1: - if ymd[0] > 31: - res.year = ymd[0] - else: - res.day = ymd[0] - elif len_ymd == 2: - # Two members with numbers - if ymd[0] > 31: - # 99-01 - res.year, res.month = ymd - elif ymd[1] > 31: - # 01-99 - res.month, res.year = ymd - elif dayfirst and ymd[1] <= 12: - # 13-01 - res.day, res.month = ymd - else: - # 01-13 - res.month, res.day = ymd - if len_ymd == 3: - # Three members - if mstridx == 0: - res.month, res.day, res.year = ymd - elif mstridx == 1: - if ymd[0] > 31 or (yearfirst and ymd[2] <= 31): - # 99-Jan-01 - res.year, res.month, res.day = ymd - else: - # 01-Jan-01 - # Give precendence to day-first, since - # two-digit years is usually hand-written. - res.day, res.month, res.year = ymd - elif mstridx == 2: - # WTF!? - if ymd[1] > 31: - # 01-99-Jan - res.day, res.year, res.month = ymd - else: - # 99-01-Jan - res.year, res.day, res.month = ymd - else: - if ymd[0] > 31 or \ - (yearfirst and ymd[1] <= 12 and ymd[2] <= 31): - # 99-01-01 - res.year, res.month, res.day = ymd - elif ymd[0] > 12 or (dayfirst and ymd[1] <= 12): - # 13-01-01 - res.day, res.month, res.year = ymd - else: - # 01-13-01 - res.month, res.day, res.year = ymd - - except (IndexError, ValueError, AssertionError): - return None - - if not info.validate(res): - return None - return res - -DEFAULTPARSER = parser() -def parse(timestr, parserinfo=None, **kwargs): - if parserinfo: - return parser(parserinfo).parse(timestr, **kwargs) - else: - return DEFAULTPARSER.parse(timestr, **kwargs) - - -class _tzparser(object): - - class _result(_resultbase): - - __slots__ = ["stdabbr", "stdoffset", "dstabbr", "dstoffset", - "start", "end"] - - class _attr(_resultbase): - __slots__ = ["month", "week", "weekday", - "yday", "jyday", "day", "time"] - - def __repr__(self): - return self._repr("") - - def __init__(self): - _resultbase.__init__(self) - self.start = self._attr() - self.end = self._attr() - - def parse(self, tzstr): - res = self._result() - l = _timelex.split(tzstr) - try: - - len_l = len(l) - - i = 0 - while i < len_l: - # BRST+3[BRDT[+2]] - j = i - while j < len_l and not [x for x in l[j] - if x in "0123456789:,-+"]: - j += 1 - if j != i: - if not res.stdabbr: - offattr = "stdoffset" - res.stdabbr = "".join(l[i:j]) - else: - offattr = "dstoffset" - res.dstabbr = "".join(l[i:j]) - i = j - if (i < len_l and - (l[i] in ('+', '-') or l[i][0] in "0123456789")): - if l[i] in ('+', '-'): - # Yes, that's right. See the TZ variable - # documentation. - signal = (1,-1)[l[i] == '+'] - i += 1 - else: - signal = -1 - len_li = len(l[i]) - if len_li == 4: - # -0300 - setattr(res, offattr, - (int(l[i][:2])*3600+int(l[i][2:])*60)*signal) - elif i+1 < len_l and l[i+1] == ':': - # -03:00 - setattr(res, offattr, - (int(l[i])*3600+int(l[i+2])*60)*signal) - i += 2 - elif len_li <= 2: - # -[0]3 - setattr(res, offattr, - int(l[i][:2])*3600*signal) - else: - return None - i += 1 - if res.dstabbr: - break - else: - break - - if i < len_l: - for j in range(i, len_l): - if l[j] == ';': l[j] = ',' - - assert l[i] == ',' - - i += 1 - - if i >= len_l: - pass - elif (8 <= l.count(',') <= 9 and - not [y for x in l[i:] if x != ',' - for y in x if y not in "0123456789"]): - # GMT0BST,3,0,30,3600,10,0,26,7200[,3600] - for x in (res.start, res.end): - x.month = int(l[i]) - i += 2 - if l[i] == '-': - value = int(l[i+1])*-1 - i += 1 - else: - value = int(l[i]) - i += 2 - if value: - x.week = value - x.weekday = (int(l[i])-1)%7 - else: - x.day = int(l[i]) - i += 2 - x.time = int(l[i]) - i += 2 - if i < len_l: - if l[i] in ('-','+'): - signal = (-1,1)[l[i] == "+"] - i += 1 - else: - signal = 1 - res.dstoffset = (res.stdoffset+int(l[i]))*signal - elif (l.count(',') == 2 and l[i:].count('/') <= 2 and - not [y for x in l[i:] if x not in (',','/','J','M', - '.','-',':') - for y in x if y not in "0123456789"]): - for x in (res.start, res.end): - if l[i] == 'J': - # non-leap year day (1 based) - i += 1 - x.jyday = int(l[i]) - elif l[i] == 'M': - # month[-.]week[-.]weekday - i += 1 - x.month = int(l[i]) - i += 1 - assert l[i] in ('-', '.') - i += 1 - x.week = int(l[i]) - if x.week == 5: - x.week = -1 - i += 1 - assert l[i] in ('-', '.') - i += 1 - x.weekday = (int(l[i])-1)%7 - else: - # year day (zero based) - x.yday = int(l[i])+1 - - i += 1 - - if i < len_l and l[i] == '/': - i += 1 - # start time - len_li = len(l[i]) - if len_li == 4: - # -0300 - x.time = (int(l[i][:2])*3600+int(l[i][2:])*60) - elif i+1 < len_l and l[i+1] == ':': - # -03:00 - x.time = int(l[i])*3600+int(l[i+2])*60 - i += 2 - if i+1 < len_l and l[i+1] == ':': - i += 2 - x.time += int(l[i]) - elif len_li <= 2: - # -[0]3 - x.time = (int(l[i][:2])*3600) - else: - return None - i += 1 - - assert i == len_l or l[i] == ',' - - i += 1 - - assert i >= len_l - - except (IndexError, ValueError, AssertionError): - return None - - return res - - -DEFAULTTZPARSER = _tzparser() -def _parsetz(tzstr): - return DEFAULTTZPARSER.parse(tzstr) - - -def _parsems(value): - """Parse a I[.F] seconds value into (seconds, microseconds).""" - if "." not in value: - return int(value), 0 - else: - i, f = value.split(".") - return int(i), int(f.ljust(6, "0")[:6]) - - -# vim:ts=4:sw=4:et diff -Nru matplotlib-1.1.1/lib/dateutil/relativedelta.py matplotlib-1.2.0/lib/dateutil/relativedelta.py --- matplotlib-1.1.1/lib/dateutil/relativedelta.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil/relativedelta.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,432 +0,0 @@ -""" -Copyright (c) 2003-2010 Gustavo Niemeyer - -This module offers extensions to the standard python 2.3+ -datetime module. -""" -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" - -import datetime -import calendar - -__all__ = ["relativedelta", "MO", "TU", "WE", "TH", "FR", "SA", "SU"] - -class weekday(object): - __slots__ = ["weekday", "n"] - - def __init__(self, weekday, n=None): - self.weekday = weekday - self.n = n - - def __call__(self, n): - if n == self.n: - return self - else: - return self.__class__(self.weekday, n) - - def __eq__(self, other): - try: - if self.weekday != other.weekday or self.n != other.n: - return False - except AttributeError: - return False - return True - - def __repr__(self): - s = ("MO", "TU", "WE", "TH", "FR", "SA", "SU")[self.weekday] - if not self.n: - return s - else: - return "%s(%+d)" % (s, self.n) - -MO, TU, WE, TH, FR, SA, SU = weekdays = tuple([weekday(x) for x in range(7)]) - -class relativedelta: - """ -The relativedelta type is based on the specification of the excelent -work done by M.-A. Lemburg in his mx.DateTime extension. However, -notice that this type does *NOT* implement the same algorithm as -his work. Do *NOT* expect it to behave like mx.DateTime's counterpart. - -There's two different ways to build a relativedelta instance. The -first one is passing it two date/datetime classes: - - relativedelta(datetime1, datetime2) - -And the other way is to use the following keyword arguments: - - year, month, day, hour, minute, second, microsecond: - Absolute information. - - years, months, weeks, days, hours, minutes, seconds, microseconds: - Relative information, may be negative. - - weekday: - One of the weekday instances (MO, TU, etc). These instances may - receive a parameter N, specifying the Nth weekday, which could - be positive or negative (like MO(+1) or MO(-2). Not specifying - it is the same as specifying +1. You can also use an integer, - where 0=MO. - - leapdays: - Will add given days to the date found, if year is a leap - year, and the date found is post 28 of february. - - yearday, nlyearday: - Set the yearday or the non-leap year day (jump leap days). - These are converted to day/month/leapdays information. - -Here is the behavior of operations with relativedelta: - -1) Calculate the absolute year, using the 'year' argument, or the - original datetime year, if the argument is not present. - -2) Add the relative 'years' argument to the absolute year. - -3) Do steps 1 and 2 for month/months. - -4) Calculate the absolute day, using the 'day' argument, or the - original datetime day, if the argument is not present. Then, - subtract from the day until it fits in the year and month - found after their operations. - -5) Add the relative 'days' argument to the absolute day. Notice - that the 'weeks' argument is multiplied by 7 and added to - 'days'. - -6) Do steps 1 and 2 for hour/hours, minute/minutes, second/seconds, - microsecond/microseconds. - -7) If the 'weekday' argument is present, calculate the weekday, - with the given (wday, nth) tuple. wday is the index of the - weekday (0-6, 0=Mon), and nth is the number of weeks to add - forward or backward, depending on its signal. Notice that if - the calculated date is already Monday, for example, using - (0, 1) or (0, -1) won't change the day. - """ - - def __init__(self, dt1=None, dt2=None, - years=0, months=0, days=0, leapdays=0, weeks=0, - hours=0, minutes=0, seconds=0, microseconds=0, - year=None, month=None, day=None, weekday=None, - yearday=None, nlyearday=None, - hour=None, minute=None, second=None, microsecond=None): - if dt1 and dt2: - if not isinstance(dt1, datetime.date) or \ - not isinstance(dt2, datetime.date): - raise TypeError, "relativedelta only diffs datetime/date" - if type(dt1) is not type(dt2): - if not isinstance(dt1, datetime.datetime): - dt1 = datetime.datetime.fromordinal(dt1.toordinal()) - elif not isinstance(dt2, datetime.datetime): - dt2 = datetime.datetime.fromordinal(dt2.toordinal()) - self.years = 0 - self.months = 0 - self.days = 0 - self.leapdays = 0 - self.hours = 0 - self.minutes = 0 - self.seconds = 0 - self.microseconds = 0 - self.year = None - self.month = None - self.day = None - self.weekday = None - self.hour = None - self.minute = None - self.second = None - self.microsecond = None - self._has_time = 0 - - months = (dt1.year*12+dt1.month)-(dt2.year*12+dt2.month) - self._set_months(months) - dtm = self.__radd__(dt2) - if dt1 < dt2: - while dt1 > dtm: - months += 1 - self._set_months(months) - dtm = self.__radd__(dt2) - else: - while dt1 < dtm: - months -= 1 - self._set_months(months) - dtm = self.__radd__(dt2) - delta = dt1 - dtm - self.seconds = delta.seconds+delta.days*86400 - self.microseconds = delta.microseconds - else: - self.years = years - self.months = months - self.days = days+weeks*7 - self.leapdays = leapdays - self.hours = hours - self.minutes = minutes - self.seconds = seconds - self.microseconds = microseconds - self.year = year - self.month = month - self.day = day - self.hour = hour - self.minute = minute - self.second = second - self.microsecond = microsecond - - if type(weekday) is int: - self.weekday = weekdays[weekday] - else: - self.weekday = weekday - - yday = 0 - if nlyearday: - yday = nlyearday - elif yearday: - yday = yearday - if yearday > 59: - self.leapdays = -1 - if yday: - ydayidx = [31,59,90,120,151,181,212,243,273,304,334,366] - for idx, ydays in enumerate(ydayidx): - if yday <= ydays: - self.month = idx+1 - if idx == 0: - self.day = yday - else: - self.day = yday-ydayidx[idx-1] - break - else: - raise ValueError, "invalid year day (%d)" % yday - - self._fix() - - def _fix(self): - if abs(self.microseconds) > 999999: - s = self.microseconds//abs(self.microseconds) - div, mod = divmod(self.microseconds*s, 1000000) - self.microseconds = mod*s - self.seconds += div*s - if abs(self.seconds) > 59: - s = self.seconds//abs(self.seconds) - div, mod = divmod(self.seconds*s, 60) - self.seconds = mod*s - self.minutes += div*s - if abs(self.minutes) > 59: - s = self.minutes//abs(self.minutes) - div, mod = divmod(self.minutes*s, 60) - self.minutes = mod*s - self.hours += div*s - if abs(self.hours) > 23: - s = self.hours//abs(self.hours) - div, mod = divmod(self.hours*s, 24) - self.hours = mod*s - self.days += div*s - if abs(self.months) > 11: - s = self.months//abs(self.months) - div, mod = divmod(self.months*s, 12) - self.months = mod*s - self.years += div*s - if (self.hours or self.minutes or self.seconds or self.microseconds or - self.hour is not None or self.minute is not None or - self.second is not None or self.microsecond is not None): - self._has_time = 1 - else: - self._has_time = 0 - - def _set_months(self, months): - self.months = months - if abs(self.months) > 11: - s = self.months//abs(self.months) - div, mod = divmod(self.months*s, 12) - self.months = mod*s - self.years = div*s - else: - self.years = 0 - - def __radd__(self, other): - if not isinstance(other, datetime.date): - raise TypeError, "unsupported type for add operation" - elif self._has_time and not isinstance(other, datetime.datetime): - other = datetime.datetime.fromordinal(other.toordinal()) - year = (self.year or other.year)+self.years - month = self.month or other.month - if self.months: - assert 1 <= abs(self.months) <= 12 - month += self.months - if month > 12: - year += 1 - month -= 12 - elif month < 1: - year -= 1 - month += 12 - day = min(calendar.monthrange(year, month)[1], - self.day or other.day) - repl = {"year": year, "month": month, "day": day} - for attr in ["hour", "minute", "second", "microsecond"]: - value = getattr(self, attr) - if value is not None: - repl[attr] = value - days = self.days - if self.leapdays and month > 2 and calendar.isleap(year): - days += self.leapdays - ret = (other.replace(**repl) - + datetime.timedelta(days=days, - hours=self.hours, - minutes=self.minutes, - seconds=self.seconds, - microseconds=self.microseconds)) - if self.weekday: - weekday, nth = self.weekday.weekday, self.weekday.n or 1 - jumpdays = (abs(nth)-1)*7 - if nth > 0: - jumpdays += (7-ret.weekday()+weekday)%7 - else: - jumpdays += (ret.weekday()-weekday)%7 - jumpdays *= -1 - ret += datetime.timedelta(days=jumpdays) - return ret - - def __rsub__(self, other): - return self.__neg__().__radd__(other) - - def __add__(self, other): - if not isinstance(other, relativedelta): - raise TypeError, "unsupported type for add operation" - return relativedelta(years=other.years+self.years, - months=other.months+self.months, - days=other.days+self.days, - hours=other.hours+self.hours, - minutes=other.minutes+self.minutes, - seconds=other.seconds+self.seconds, - microseconds=other.microseconds+self.microseconds, - leapdays=other.leapdays or self.leapdays, - year=other.year or self.year, - month=other.month or self.month, - day=other.day or self.day, - weekday=other.weekday or self.weekday, - hour=other.hour or self.hour, - minute=other.minute or self.minute, - second=other.second or self.second, - microsecond=other.second or self.microsecond) - - def __sub__(self, other): - if not isinstance(other, relativedelta): - raise TypeError, "unsupported type for sub operation" - return relativedelta(years=other.years-self.years, - months=other.months-self.months, - days=other.days-self.days, - hours=other.hours-self.hours, - minutes=other.minutes-self.minutes, - seconds=other.seconds-self.seconds, - microseconds=other.microseconds-self.microseconds, - leapdays=other.leapdays or self.leapdays, - year=other.year or self.year, - month=other.month or self.month, - day=other.day or self.day, - weekday=other.weekday or self.weekday, - hour=other.hour or self.hour, - minute=other.minute or self.minute, - second=other.second or self.second, - microsecond=other.second or self.microsecond) - - def __neg__(self): - return relativedelta(years=-self.years, - months=-self.months, - days=-self.days, - hours=-self.hours, - minutes=-self.minutes, - seconds=-self.seconds, - microseconds=-self.microseconds, - leapdays=self.leapdays, - year=self.year, - month=self.month, - day=self.day, - weekday=self.weekday, - hour=self.hour, - minute=self.minute, - second=self.second, - microsecond=self.microsecond) - - def __nonzero__(self): - return not (not self.years and - not self.months and - not self.days and - not self.hours and - not self.minutes and - not self.seconds and - not self.microseconds and - not self.leapdays and - self.year is None and - self.month is None and - self.day is None and - self.weekday is None and - self.hour is None and - self.minute is None and - self.second is None and - self.microsecond is None) - - def __mul__(self, other): - f = float(other) - return relativedelta(years=self.years*f, - months=self.months*f, - days=self.days*f, - hours=self.hours*f, - minutes=self.minutes*f, - seconds=self.seconds*f, - microseconds=self.microseconds*f, - leapdays=self.leapdays, - year=self.year, - month=self.month, - day=self.day, - weekday=self.weekday, - hour=self.hour, - minute=self.minute, - second=self.second, - microsecond=self.microsecond) - - def __eq__(self, other): - if not isinstance(other, relativedelta): - return False - if self.weekday or other.weekday: - if not self.weekday or not other.weekday: - return False - if self.weekday.weekday != other.weekday.weekday: - return False - n1, n2 = self.weekday.n, other.weekday.n - if n1 != n2 and not ((not n1 or n1 == 1) and (not n2 or n2 == 1)): - return False - return (self.years == other.years and - self.months == other.months and - self.days == other.days and - self.hours == other.hours and - self.minutes == other.minutes and - self.seconds == other.seconds and - self.leapdays == other.leapdays and - self.year == other.year and - self.month == other.month and - self.day == other.day and - self.hour == other.hour and - self.minute == other.minute and - self.second == other.second and - self.microsecond == other.microsecond) - - def __ne__(self, other): - return not self.__eq__(other) - - def __div__(self, other): - return self.__mul__(1/float(other)) - - def __repr__(self): - l = [] - for attr in ["years", "months", "days", "leapdays", - "hours", "minutes", "seconds", "microseconds"]: - value = getattr(self, attr) - if value: - l.append("%s=%+d" % (attr, value)) - for attr in ["year", "month", "day", "weekday", - "hour", "minute", "second", "microsecond"]: - value = getattr(self, attr) - if value is not None: - l.append("%s=%s" % (attr, `value`)) - return "%s(%s)" % (self.__class__.__name__, ", ".join(l)) - -# vim:ts=4:sw=4:et diff -Nru matplotlib-1.1.1/lib/dateutil/rrule.py matplotlib-1.2.0/lib/dateutil/rrule.py --- matplotlib-1.1.1/lib/dateutil/rrule.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil/rrule.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,1097 +0,0 @@ -""" -Copyright (c) 2003-2010 Gustavo Niemeyer - -This module offers extensions to the standard python 2.3+ -datetime module. -""" -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" - -import itertools -import datetime -import calendar -import thread -import sys - -__all__ = ["rrule", "rruleset", "rrulestr", - "YEARLY", "MONTHLY", "WEEKLY", "DAILY", - "HOURLY", "MINUTELY", "SECONDLY", - "MO", "TU", "WE", "TH", "FR", "SA", "SU"] - -# Every mask is 7 days longer to handle cross-year weekly periods. -M366MASK = tuple([1]*31+[2]*29+[3]*31+[4]*30+[5]*31+[6]*30+ - [7]*31+[8]*31+[9]*30+[10]*31+[11]*30+[12]*31+[1]*7) -M365MASK = list(M366MASK) -M29, M30, M31 = range(1,30), range(1,31), range(1,32) -MDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7]) -MDAY365MASK = list(MDAY366MASK) -M29, M30, M31 = range(-29,0), range(-30,0), range(-31,0) -NMDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7]) -NMDAY365MASK = list(NMDAY366MASK) -M366RANGE = (0,31,60,91,121,152,182,213,244,274,305,335,366) -M365RANGE = (0,31,59,90,120,151,181,212,243,273,304,334,365) -WDAYMASK = [0,1,2,3,4,5,6]*55 -del M29, M30, M31, M365MASK[59], MDAY365MASK[59], NMDAY365MASK[31] -MDAY365MASK = tuple(MDAY365MASK) -M365MASK = tuple(M365MASK) - -(YEARLY, - MONTHLY, - WEEKLY, - DAILY, - HOURLY, - MINUTELY, - SECONDLY) = range(7) - -# Imported on demand. -easter = None -parser = None - -class weekday(object): - __slots__ = ["weekday", "n"] - - def __init__(self, weekday, n=None): - if n == 0: - raise ValueError, "Can't create weekday with n == 0" - self.weekday = weekday - self.n = n - - def __call__(self, n): - if n == self.n: - return self - else: - return self.__class__(self.weekday, n) - - def __eq__(self, other): - try: - if self.weekday != other.weekday or self.n != other.n: - return False - except AttributeError: - return False - return True - - def __repr__(self): - s = ("MO", "TU", "WE", "TH", "FR", "SA", "SU")[self.weekday] - if not self.n: - return s - else: - return "%s(%+d)" % (s, self.n) - -MO, TU, WE, TH, FR, SA, SU = weekdays = tuple([weekday(x) for x in range(7)]) - -class rrulebase: - def __init__(self, cache=False): - if cache: - self._cache = [] - self._cache_lock = thread.allocate_lock() - self._cache_gen = self._iter() - self._cache_complete = False - else: - self._cache = None - self._cache_complete = False - self._len = None - - def __iter__(self): - if self._cache_complete: - return iter(self._cache) - elif self._cache is None: - return self._iter() - else: - return self._iter_cached() - - def _iter_cached(self): - i = 0 - gen = self._cache_gen - cache = self._cache - acquire = self._cache_lock.acquire - release = self._cache_lock.release - while gen: - if i == len(cache): - acquire() - if self._cache_complete: - break - try: - for j in range(10): - cache.append(gen.next()) - except StopIteration: - self._cache_gen = gen = None - self._cache_complete = True - break - release() - yield cache[i] - i += 1 - while i < self._len: - yield cache[i] - i += 1 - - def __getitem__(self, item): - if self._cache_complete: - return self._cache[item] - elif isinstance(item, slice): - if item.step and item.step < 0: - return list(iter(self))[item] - else: - return list(itertools.islice(self, - item.start or 0, - item.stop or sys.maxint, - item.step or 1)) - elif item >= 0: - gen = iter(self) - try: - for i in range(item+1): - res = gen.next() - except StopIteration: - raise IndexError - return res - else: - return list(iter(self))[item] - - def __contains__(self, item): - if self._cache_complete: - return item in self._cache - else: - for i in self: - if i == item: - return True - elif i > item: - return False - return False - - # __len__() introduces a large performance penality. - def count(self): - if self._len is None: - for x in self: pass - return self._len - - def before(self, dt, inc=False): - if self._cache_complete: - gen = self._cache - else: - gen = self - last = None - if inc: - for i in gen: - if i > dt: - break - last = i - else: - for i in gen: - if i >= dt: - break - last = i - return last - - def after(self, dt, inc=False): - if self._cache_complete: - gen = self._cache - else: - gen = self - if inc: - for i in gen: - if i >= dt: - return i - else: - for i in gen: - if i > dt: - return i - return None - - def between(self, after, before, inc=False): - if self._cache_complete: - gen = self._cache - else: - gen = self - started = False - l = [] - if inc: - for i in gen: - if i > before: - break - elif not started: - if i >= after: - started = True - l.append(i) - else: - l.append(i) - else: - for i in gen: - if i >= before: - break - elif not started: - if i > after: - started = True - l.append(i) - else: - l.append(i) - return l - -class rrule(rrulebase): - def __init__(self, freq, dtstart=None, - interval=1, wkst=None, count=None, until=None, bysetpos=None, - bymonth=None, bymonthday=None, byyearday=None, byeaster=None, - byweekno=None, byweekday=None, - byhour=None, byminute=None, bysecond=None, - cache=False): - rrulebase.__init__(self, cache) - global easter - if not dtstart: - dtstart = datetime.datetime.now().replace(microsecond=0) - elif not isinstance(dtstart, datetime.datetime): - dtstart = datetime.datetime.fromordinal(dtstart.toordinal()) - else: - dtstart = dtstart.replace(microsecond=0) - self._dtstart = dtstart - self._tzinfo = dtstart.tzinfo - self._freq = freq - self._interval = interval - self._count = count - if until and not isinstance(until, datetime.datetime): - until = datetime.datetime.fromordinal(until.toordinal()) - self._until = until - if wkst is None: - self._wkst = calendar.firstweekday() - elif type(wkst) is int: - self._wkst = wkst - else: - self._wkst = wkst.weekday - if bysetpos is None: - self._bysetpos = None - elif type(bysetpos) is int: - if bysetpos == 0 or not (-366 <= bysetpos <= 366): - raise ValueError("bysetpos must be between 1 and 366, " - "or between -366 and -1") - self._bysetpos = (bysetpos,) - else: - self._bysetpos = tuple(bysetpos) - for pos in self._bysetpos: - if pos == 0 or not (-366 <= pos <= 366): - raise ValueError("bysetpos must be between 1 and 366, " - "or between -366 and -1") - if not (byweekno or byyearday or bymonthday or - byweekday is not None or byeaster is not None): - if freq == YEARLY: - if not bymonth: - bymonth = dtstart.month - bymonthday = dtstart.day - elif freq == MONTHLY: - bymonthday = dtstart.day - elif freq == WEEKLY: - byweekday = dtstart.weekday() - # bymonth - if not bymonth: - self._bymonth = None - elif type(bymonth) is int: - self._bymonth = (bymonth,) - else: - self._bymonth = tuple(bymonth) - # byyearday - if not byyearday: - self._byyearday = None - elif type(byyearday) is int: - self._byyearday = (byyearday,) - else: - self._byyearday = tuple(byyearday) - # byeaster - if byeaster is not None: - if not easter: - from dateutil import easter - if type(byeaster) is int: - self._byeaster = (byeaster,) - else: - self._byeaster = tuple(byeaster) - else: - self._byeaster = None - # bymonthay - if not bymonthday: - self._bymonthday = () - self._bynmonthday = () - elif type(bymonthday) is int: - if bymonthday < 0: - self._bynmonthday = (bymonthday,) - self._bymonthday = () - else: - self._bymonthday = (bymonthday,) - self._bynmonthday = () - else: - self._bymonthday = tuple([x for x in bymonthday if x > 0]) - self._bynmonthday = tuple([x for x in bymonthday if x < 0]) - # byweekno - if byweekno is None: - self._byweekno = None - elif type(byweekno) is int: - self._byweekno = (byweekno,) - else: - self._byweekno = tuple(byweekno) - # byweekday / bynweekday - if byweekday is None: - self._byweekday = None - self._bynweekday = None - elif type(byweekday) is int: - self._byweekday = (byweekday,) - self._bynweekday = None - elif hasattr(byweekday, "n"): - if not byweekday.n or freq > MONTHLY: - self._byweekday = (byweekday.weekday,) - self._bynweekday = None - else: - self._bynweekday = ((byweekday.weekday, byweekday.n),) - self._byweekday = None - else: - self._byweekday = [] - self._bynweekday = [] - for wday in byweekday: - if type(wday) is int: - self._byweekday.append(wday) - elif not wday.n or freq > MONTHLY: - self._byweekday.append(wday.weekday) - else: - self._bynweekday.append((wday.weekday, wday.n)) - self._byweekday = tuple(self._byweekday) - self._bynweekday = tuple(self._bynweekday) - if not self._byweekday: - self._byweekday = None - elif not self._bynweekday: - self._bynweekday = None - # byhour - if byhour is None: - if freq < HOURLY: - self._byhour = (dtstart.hour,) - else: - self._byhour = None - elif type(byhour) is int: - self._byhour = (byhour,) - else: - self._byhour = tuple(byhour) - # byminute - if byminute is None: - if freq < MINUTELY: - self._byminute = (dtstart.minute,) - else: - self._byminute = None - elif type(byminute) is int: - self._byminute = (byminute,) - else: - self._byminute = tuple(byminute) - # bysecond - if bysecond is None: - if freq < SECONDLY: - self._bysecond = (dtstart.second,) - else: - self._bysecond = None - elif type(bysecond) is int: - self._bysecond = (bysecond,) - else: - self._bysecond = tuple(bysecond) - - if self._freq >= HOURLY: - self._timeset = None - else: - self._timeset = [] - for hour in self._byhour: - for minute in self._byminute: - for second in self._bysecond: - self._timeset.append( - datetime.time(hour, minute, second, - tzinfo=self._tzinfo)) - self._timeset.sort() - self._timeset = tuple(self._timeset) - - def _iter(self): - year, month, day, hour, minute, second, weekday, yearday, _ = \ - self._dtstart.timetuple() - - # Some local variables to speed things up a bit - freq = self._freq - interval = self._interval - wkst = self._wkst - until = self._until - bymonth = self._bymonth - byweekno = self._byweekno - byyearday = self._byyearday - byweekday = self._byweekday - byeaster = self._byeaster - bymonthday = self._bymonthday - bynmonthday = self._bynmonthday - bysetpos = self._bysetpos - byhour = self._byhour - byminute = self._byminute - bysecond = self._bysecond - - ii = _iterinfo(self) - ii.rebuild(year, month) - - getdayset = {YEARLY:ii.ydayset, - MONTHLY:ii.mdayset, - WEEKLY:ii.wdayset, - DAILY:ii.ddayset, - HOURLY:ii.ddayset, - MINUTELY:ii.ddayset, - SECONDLY:ii.ddayset}[freq] - - if freq < HOURLY: - timeset = self._timeset - else: - gettimeset = {HOURLY:ii.htimeset, - MINUTELY:ii.mtimeset, - SECONDLY:ii.stimeset}[freq] - if ((freq >= HOURLY and - self._byhour and hour not in self._byhour) or - (freq >= MINUTELY and - self._byminute and minute not in self._byminute) or - (freq >= SECONDLY and - self._bysecond and second not in self._bysecond)): - timeset = () - else: - timeset = gettimeset(hour, minute, second) - - total = 0 - count = self._count - while True: - # Get dayset with the right frequency - dayset, start, end = getdayset(year, month, day) - - # Do the "hard" work ;-) - filtered = False - for i in dayset[start:end]: - if ((bymonth and ii.mmask[i] not in bymonth) or - (byweekno and not ii.wnomask[i]) or - (byweekday and ii.wdaymask[i] not in byweekday) or - (ii.nwdaymask and not ii.nwdaymask[i]) or - (byeaster and not ii.eastermask[i]) or - ((bymonthday or bynmonthday) and - ii.mdaymask[i] not in bymonthday and - ii.nmdaymask[i] not in bynmonthday) or - (byyearday and - ((i < ii.yearlen and i+1 not in byyearday - and -ii.yearlen+i not in byyearday) or - (i >= ii.yearlen and i+1-ii.yearlen not in byyearday - and -ii.nextyearlen+i-ii.yearlen - not in byyearday)))): - dayset[i] = None - filtered = True - - # Output results - if bysetpos and timeset: - poslist = [] - for pos in bysetpos: - if pos < 0: - daypos, timepos = divmod(pos, len(timeset)) - else: - daypos, timepos = divmod(pos-1, len(timeset)) - try: - i = [x for x in dayset[start:end] - if x is not None][daypos] - time = timeset[timepos] - except IndexError: - pass - else: - date = datetime.date.fromordinal(ii.yearordinal+i) - res = datetime.datetime.combine(date, time) - if res not in poslist: - poslist.append(res) - poslist.sort() - for res in poslist: - if until and res > until: - self._len = total - return - elif res >= self._dtstart: - total += 1 - yield res - if count: - count -= 1 - if not count: - self._len = total - return - else: - for i in dayset[start:end]: - if i is not None: - date = datetime.date.fromordinal(ii.yearordinal+i) - for time in timeset: - res = datetime.datetime.combine(date, time) - if until and res > until: - self._len = total - return - elif res >= self._dtstart: - total += 1 - yield res - if count: - count -= 1 - if not count: - self._len = total - return - - # Handle frequency and interval - fixday = False - if freq == YEARLY: - year += interval - if year > datetime.MAXYEAR: - self._len = total - return - ii.rebuild(year, month) - elif freq == MONTHLY: - month += interval - if month > 12: - div, mod = divmod(month, 12) - month = mod - year += div - if month == 0: - month = 12 - year -= 1 - if year > datetime.MAXYEAR: - self._len = total - return - ii.rebuild(year, month) - elif freq == WEEKLY: - if wkst > weekday: - day += -(weekday+1+(6-wkst))+self._interval*7 - else: - day += -(weekday-wkst)+self._interval*7 - weekday = wkst - fixday = True - elif freq == DAILY: - day += interval - fixday = True - elif freq == HOURLY: - if filtered: - # Jump to one iteration before next day - hour += ((23-hour)//interval)*interval - while True: - hour += interval - div, mod = divmod(hour, 24) - if div: - hour = mod - day += div - fixday = True - if not byhour or hour in byhour: - break - timeset = gettimeset(hour, minute, second) - elif freq == MINUTELY: - if filtered: - # Jump to one iteration before next day - minute += ((1439-(hour*60+minute))//interval)*interval - while True: - minute += interval - div, mod = divmod(minute, 60) - if div: - minute = mod - hour += div - div, mod = divmod(hour, 24) - if div: - hour = mod - day += div - fixday = True - filtered = False - if ((not byhour or hour in byhour) and - (not byminute or minute in byminute)): - break - timeset = gettimeset(hour, minute, second) - elif freq == SECONDLY: - if filtered: - # Jump to one iteration before next day - second += (((86399-(hour*3600+minute*60+second)) - //interval)*interval) - while True: - second += self._interval - div, mod = divmod(second, 60) - if div: - second = mod - minute += div - div, mod = divmod(minute, 60) - if div: - minute = mod - hour += div - div, mod = divmod(hour, 24) - if div: - hour = mod - day += div - fixday = True - if ((not byhour or hour in byhour) and - (not byminute or minute in byminute) and - (not bysecond or second in bysecond)): - break - timeset = gettimeset(hour, minute, second) - - if fixday and day > 28: - daysinmonth = calendar.monthrange(year, month)[1] - if day > daysinmonth: - while day > daysinmonth: - day -= daysinmonth - month += 1 - if month == 13: - month = 1 - year += 1 - if year > datetime.MAXYEAR: - self._len = total - return - daysinmonth = calendar.monthrange(year, month)[1] - ii.rebuild(year, month) - -class _iterinfo(object): - __slots__ = ["rrule", "lastyear", "lastmonth", - "yearlen", "nextyearlen", "yearordinal", "yearweekday", - "mmask", "mrange", "mdaymask", "nmdaymask", - "wdaymask", "wnomask", "nwdaymask", "eastermask"] - - def __init__(self, rrule): - for attr in self.__slots__: - setattr(self, attr, None) - self.rrule = rrule - - def rebuild(self, year, month): - # Every mask is 7 days longer to handle cross-year weekly periods. - rr = self.rrule - if year != self.lastyear: - self.yearlen = 365+calendar.isleap(year) - self.nextyearlen = 365+calendar.isleap(year+1) - firstyday = datetime.date(year, 1, 1) - self.yearordinal = firstyday.toordinal() - self.yearweekday = firstyday.weekday() - - wday = datetime.date(year, 1, 1).weekday() - if self.yearlen == 365: - self.mmask = M365MASK - self.mdaymask = MDAY365MASK - self.nmdaymask = NMDAY365MASK - self.wdaymask = WDAYMASK[wday:] - self.mrange = M365RANGE - else: - self.mmask = M366MASK - self.mdaymask = MDAY366MASK - self.nmdaymask = NMDAY366MASK - self.wdaymask = WDAYMASK[wday:] - self.mrange = M366RANGE - - if not rr._byweekno: - self.wnomask = None - else: - self.wnomask = [0]*(self.yearlen+7) - #no1wkst = firstwkst = self.wdaymask.index(rr._wkst) - no1wkst = firstwkst = (7-self.yearweekday+rr._wkst)%7 - if no1wkst >= 4: - no1wkst = 0 - # Number of days in the year, plus the days we got - # from last year. - wyearlen = self.yearlen+(self.yearweekday-rr._wkst)%7 - else: - # Number of days in the year, minus the days we - # left in last year. - wyearlen = self.yearlen-no1wkst - div, mod = divmod(wyearlen, 7) - numweeks = div+mod//4 - for n in rr._byweekno: - if n < 0: - n += numweeks+1 - if not (0 < n <= numweeks): - continue - if n > 1: - i = no1wkst+(n-1)*7 - if no1wkst != firstwkst: - i -= 7-firstwkst - else: - i = no1wkst - for j in range(7): - self.wnomask[i] = 1 - i += 1 - if self.wdaymask[i] == rr._wkst: - break - if 1 in rr._byweekno: - # Check week number 1 of next year as well - # TODO: Check -numweeks for next year. - i = no1wkst+numweeks*7 - if no1wkst != firstwkst: - i -= 7-firstwkst - if i < self.yearlen: - # If week starts in next year, we - # don't care about it. - for j in range(7): - self.wnomask[i] = 1 - i += 1 - if self.wdaymask[i] == rr._wkst: - break - if no1wkst: - # Check last week number of last year as - # well. If no1wkst is 0, either the year - # started on week start, or week number 1 - # got days from last year, so there are no - # days from last year's last week number in - # this year. - if -1 not in rr._byweekno: - lyearweekday = datetime.date(year-1,1,1).weekday() - lno1wkst = (7-lyearweekday+rr._wkst)%7 - lyearlen = 365+calendar.isleap(year-1) - if lno1wkst >= 4: - lno1wkst = 0 - lnumweeks = 52+(lyearlen+ - (lyearweekday-rr._wkst)%7)%7//4 - else: - lnumweeks = 52+(self.yearlen-no1wkst)%7//4 - else: - lnumweeks = -1 - if lnumweeks in rr._byweekno: - for i in range(no1wkst): - self.wnomask[i] = 1 - - if (rr._bynweekday and - (month != self.lastmonth or year != self.lastyear)): - ranges = [] - if rr._freq == YEARLY: - if rr._bymonth: - for month in rr._bymonth: - ranges.append(self.mrange[month-1:month+1]) - else: - ranges = [(0, self.yearlen)] - elif rr._freq == MONTHLY: - ranges = [self.mrange[month-1:month+1]] - if ranges: - # Weekly frequency won't get here, so we may not - # care about cross-year weekly periods. - self.nwdaymask = [0]*self.yearlen - for first, last in ranges: - last -= 1 - for wday, n in rr._bynweekday: - if n < 0: - i = last+(n+1)*7 - i -= (self.wdaymask[i]-wday)%7 - else: - i = first+(n-1)*7 - i += (7-self.wdaymask[i]+wday)%7 - if first <= i <= last: - self.nwdaymask[i] = 1 - - if rr._byeaster: - self.eastermask = [0]*(self.yearlen+7) - eyday = easter.easter(year).toordinal()-self.yearordinal - for offset in rr._byeaster: - self.eastermask[eyday+offset] = 1 - - self.lastyear = year - self.lastmonth = month - - def ydayset(self, year, month, day): - return range(self.yearlen), 0, self.yearlen - - def mdayset(self, year, month, day): - set = [None]*self.yearlen - start, end = self.mrange[month-1:month+1] - for i in range(start, end): - set[i] = i - return set, start, end - - def wdayset(self, year, month, day): - # We need to handle cross-year weeks here. - set = [None]*(self.yearlen+7) - i = datetime.date(year, month, day).toordinal()-self.yearordinal - start = i - for j in range(7): - set[i] = i - i += 1 - #if (not (0 <= i < self.yearlen) or - # self.wdaymask[i] == self.rrule._wkst): - # This will cross the year boundary, if necessary. - if self.wdaymask[i] == self.rrule._wkst: - break - return set, start, i - - def ddayset(self, year, month, day): - set = [None]*self.yearlen - i = datetime.date(year, month, day).toordinal()-self.yearordinal - set[i] = i - return set, i, i+1 - - def htimeset(self, hour, minute, second): - set = [] - rr = self.rrule - for minute in rr._byminute: - for second in rr._bysecond: - set.append(datetime.time(hour, minute, second, - tzinfo=rr._tzinfo)) - set.sort() - return set - - def mtimeset(self, hour, minute, second): - set = [] - rr = self.rrule - for second in rr._bysecond: - set.append(datetime.time(hour, minute, second, tzinfo=rr._tzinfo)) - set.sort() - return set - - def stimeset(self, hour, minute, second): - return (datetime.time(hour, minute, second, - tzinfo=self.rrule._tzinfo),) - - -class rruleset(rrulebase): - - class _genitem: - def __init__(self, genlist, gen): - try: - self.dt = gen() - genlist.append(self) - except StopIteration: - pass - self.genlist = genlist - self.gen = gen - - def next(self): - try: - self.dt = self.gen() - except StopIteration: - self.genlist.remove(self) - - def __cmp__(self, other): - return cmp(self.dt, other.dt) - - def __init__(self, cache=False): - rrulebase.__init__(self, cache) - self._rrule = [] - self._rdate = [] - self._exrule = [] - self._exdate = [] - - def rrule(self, rrule): - self._rrule.append(rrule) - - def rdate(self, rdate): - self._rdate.append(rdate) - - def exrule(self, exrule): - self._exrule.append(exrule) - - def exdate(self, exdate): - self._exdate.append(exdate) - - def _iter(self): - rlist = [] - self._rdate.sort() - self._genitem(rlist, iter(self._rdate).next) - for gen in [iter(x).next for x in self._rrule]: - self._genitem(rlist, gen) - rlist.sort() - exlist = [] - self._exdate.sort() - self._genitem(exlist, iter(self._exdate).next) - for gen in [iter(x).next for x in self._exrule]: - self._genitem(exlist, gen) - exlist.sort() - lastdt = None - total = 0 - while rlist: - ritem = rlist[0] - if not lastdt or lastdt != ritem.dt: - while exlist and exlist[0] < ritem: - exlist[0].next() - exlist.sort() - if not exlist or ritem != exlist[0]: - total += 1 - yield ritem.dt - lastdt = ritem.dt - ritem.next() - rlist.sort() - self._len = total - -class _rrulestr: - - _freq_map = {"YEARLY": YEARLY, - "MONTHLY": MONTHLY, - "WEEKLY": WEEKLY, - "DAILY": DAILY, - "HOURLY": HOURLY, - "MINUTELY": MINUTELY, - "SECONDLY": SECONDLY} - - _weekday_map = {"MO":0,"TU":1,"WE":2,"TH":3,"FR":4,"SA":5,"SU":6} - - def _handle_int(self, rrkwargs, name, value, **kwargs): - rrkwargs[name.lower()] = int(value) - - def _handle_int_list(self, rrkwargs, name, value, **kwargs): - rrkwargs[name.lower()] = [int(x) for x in value.split(',')] - - _handle_INTERVAL = _handle_int - _handle_COUNT = _handle_int - _handle_BYSETPOS = _handle_int_list - _handle_BYMONTH = _handle_int_list - _handle_BYMONTHDAY = _handle_int_list - _handle_BYYEARDAY = _handle_int_list - _handle_BYEASTER = _handle_int_list - _handle_BYWEEKNO = _handle_int_list - _handle_BYHOUR = _handle_int_list - _handle_BYMINUTE = _handle_int_list - _handle_BYSECOND = _handle_int_list - - def _handle_FREQ(self, rrkwargs, name, value, **kwargs): - rrkwargs["freq"] = self._freq_map[value] - - def _handle_UNTIL(self, rrkwargs, name, value, **kwargs): - global parser - if not parser: - from dateutil import parser - try: - rrkwargs["until"] = parser.parse(value, - ignoretz=kwargs.get("ignoretz"), - tzinfos=kwargs.get("tzinfos")) - except ValueError: - raise ValueError, "invalid until date" - - def _handle_WKST(self, rrkwargs, name, value, **kwargs): - rrkwargs["wkst"] = self._weekday_map[value] - - def _handle_BYWEEKDAY(self, rrkwargs, name, value, **kwarsg): - l = [] - for wday in value.split(','): - for i in range(len(wday)): - if wday[i] not in '+-0123456789': - break - n = wday[:i] or None - w = wday[i:] - if n: n = int(n) - l.append(weekdays[self._weekday_map[w]](n)) - rrkwargs["byweekday"] = l - - _handle_BYDAY = _handle_BYWEEKDAY - - def _parse_rfc_rrule(self, line, - dtstart=None, - cache=False, - ignoretz=False, - tzinfos=None): - if line.find(':') != -1: - name, value = line.split(':') - if name != "RRULE": - raise ValueError, "unknown parameter name" - else: - value = line - rrkwargs = {} - for pair in value.split(';'): - name, value = pair.split('=') - name = name.upper() - value = value.upper() - try: - getattr(self, "_handle_"+name)(rrkwargs, name, value, - ignoretz=ignoretz, - tzinfos=tzinfos) - except AttributeError: - raise ValueError, "unknown parameter '%s'" % name - except (KeyError, ValueError): - raise ValueError, "invalid '%s': %s" % (name, value) - return rrule(dtstart=dtstart, cache=cache, **rrkwargs) - - def _parse_rfc(self, s, - dtstart=None, - cache=False, - unfold=False, - forceset=False, - compatible=False, - ignoretz=False, - tzinfos=None): - global parser - if compatible: - forceset = True - unfold = True - s = s.upper() - if not s.strip(): - raise ValueError, "empty string" - if unfold: - lines = s.splitlines() - i = 0 - while i < len(lines): - line = lines[i].rstrip() - if not line: - del lines[i] - elif i > 0 and line[0] == " ": - lines[i-1] += line[1:] - del lines[i] - else: - i += 1 - else: - lines = s.split() - if (not forceset and len(lines) == 1 and - (s.find(':') == -1 or s.startswith('RRULE:'))): - return self._parse_rfc_rrule(lines[0], cache=cache, - dtstart=dtstart, ignoretz=ignoretz, - tzinfos=tzinfos) - else: - rrulevals = [] - rdatevals = [] - exrulevals = [] - exdatevals = [] - for line in lines: - if not line: - continue - if line.find(':') == -1: - name = "RRULE" - value = line - else: - name, value = line.split(':', 1) - parms = name.split(';') - if not parms: - raise ValueError, "empty property name" - name = parms[0] - parms = parms[1:] - if name == "RRULE": - for parm in parms: - raise ValueError, "unsupported RRULE parm: "+parm - rrulevals.append(value) - elif name == "RDATE": - for parm in parms: - if parm != "VALUE=DATE-TIME": - raise ValueError, "unsupported RDATE parm: "+parm - rdatevals.append(value) - elif name == "EXRULE": - for parm in parms: - raise ValueError, "unsupported EXRULE parm: "+parm - exrulevals.append(value) - elif name == "EXDATE": - for parm in parms: - if parm != "VALUE=DATE-TIME": - raise ValueError, "unsupported RDATE parm: "+parm - exdatevals.append(value) - elif name == "DTSTART": - for parm in parms: - raise ValueError, "unsupported DTSTART parm: "+parm - if not parser: - from dateutil import parser - dtstart = parser.parse(value, ignoretz=ignoretz, - tzinfos=tzinfos) - else: - raise ValueError, "unsupported property: "+name - if (forceset or len(rrulevals) > 1 or - rdatevals or exrulevals or exdatevals): - if not parser and (rdatevals or exdatevals): - from dateutil import parser - set = rruleset(cache=cache) - for value in rrulevals: - set.rrule(self._parse_rfc_rrule(value, dtstart=dtstart, - ignoretz=ignoretz, - tzinfos=tzinfos)) - for value in rdatevals: - for datestr in value.split(','): - set.rdate(parser.parse(datestr, - ignoretz=ignoretz, - tzinfos=tzinfos)) - for value in exrulevals: - set.exrule(self._parse_rfc_rrule(value, dtstart=dtstart, - ignoretz=ignoretz, - tzinfos=tzinfos)) - for value in exdatevals: - for datestr in value.split(','): - set.exdate(parser.parse(datestr, - ignoretz=ignoretz, - tzinfos=tzinfos)) - if compatible and dtstart: - set.rdate(dtstart) - return set - else: - return self._parse_rfc_rrule(rrulevals[0], - dtstart=dtstart, - cache=cache, - ignoretz=ignoretz, - tzinfos=tzinfos) - - def __call__(self, s, **kwargs): - return self._parse_rfc(s, **kwargs) - -rrulestr = _rrulestr() - -# vim:ts=4:sw=4:et diff -Nru matplotlib-1.1.1/lib/dateutil/tz.py matplotlib-1.2.0/lib/dateutil/tz.py --- matplotlib-1.1.1/lib/dateutil/tz.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil/tz.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,951 +0,0 @@ -""" -Copyright (c) 2003-2007 Gustavo Niemeyer - -This module offers extensions to the standard python 2.3+ -datetime module. -""" -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" - -import datetime -import struct -import time -import sys -import os - -relativedelta = None -parser = None -rrule = None - -__all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange", - "tzstr", "tzical", "tzwin", "tzwinlocal", "gettz"] - -try: - from dateutil.tzwin import tzwin, tzwinlocal -except (ImportError, OSError): - tzwin, tzwinlocal = None, None - -ZERO = datetime.timedelta(0) -EPOCHORDINAL = datetime.datetime.utcfromtimestamp(0).toordinal() - -class tzutc(datetime.tzinfo): - - def utcoffset(self, dt): - return ZERO - - def dst(self, dt): - return ZERO - - def tzname(self, dt): - return "UTC" - - def __eq__(self, other): - return (isinstance(other, tzutc) or - (isinstance(other, tzoffset) and other._offset == ZERO)) - - def __ne__(self, other): - return not self.__eq__(other) - - def __repr__(self): - return "%s()" % self.__class__.__name__ - - __reduce__ = object.__reduce__ - -class tzoffset(datetime.tzinfo): - - def __init__(self, name, offset): - self._name = name - self._offset = datetime.timedelta(seconds=offset) - - def utcoffset(self, dt): - return self._offset - - def dst(self, dt): - return ZERO - - def tzname(self, dt): - return self._name - - def __eq__(self, other): - return (isinstance(other, tzoffset) and - self._offset == other._offset) - - def __ne__(self, other): - return not self.__eq__(other) - - def __repr__(self): - return "%s(%s, %s)" % (self.__class__.__name__, - `self._name`, - self._offset.days*86400+self._offset.seconds) - - __reduce__ = object.__reduce__ - -class tzlocal(datetime.tzinfo): - - _std_offset = datetime.timedelta(seconds=-time.timezone) - if time.daylight: - _dst_offset = datetime.timedelta(seconds=-time.altzone) - else: - _dst_offset = _std_offset - - def utcoffset(self, dt): - if self._isdst(dt): - return self._dst_offset - else: - return self._std_offset - - def dst(self, dt): - if self._isdst(dt): - return self._dst_offset-self._std_offset - else: - return ZERO - - def tzname(self, dt): - return time.tzname[self._isdst(dt)] - - def _isdst(self, dt): - # We can't use mktime here. It is unstable when deciding if - # the hour near to a change is DST or not. - # - # timestamp = time.mktime((dt.year, dt.month, dt.day, dt.hour, - # dt.minute, dt.second, dt.weekday(), 0, -1)) - # return time.localtime(timestamp).tm_isdst - # - # The code above yields the following result: - # - #>>> import tz, datetime - #>>> t = tz.tzlocal() - #>>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname() - #'BRDT' - #>>> datetime.datetime(2003,2,16,0,tzinfo=t).tzname() - #'BRST' - #>>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname() - #'BRST' - #>>> datetime.datetime(2003,2,15,22,tzinfo=t).tzname() - #'BRDT' - #>>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname() - #'BRDT' - # - # Here is a more stable implementation: - # - timestamp = ((dt.toordinal() - EPOCHORDINAL) * 86400 - + dt.hour * 3600 - + dt.minute * 60 - + dt.second) - return time.localtime(timestamp+time.timezone).tm_isdst - - def __eq__(self, other): - if not isinstance(other, tzlocal): - return False - return (self._std_offset == other._std_offset and - self._dst_offset == other._dst_offset) - return True - - def __ne__(self, other): - return not self.__eq__(other) - - def __repr__(self): - return "%s()" % self.__class__.__name__ - - __reduce__ = object.__reduce__ - -class _ttinfo(object): - __slots__ = ["offset", "delta", "isdst", "abbr", "isstd", "isgmt"] - - def __init__(self): - for attr in self.__slots__: - setattr(self, attr, None) - - def __repr__(self): - l = [] - for attr in self.__slots__: - value = getattr(self, attr) - if value is not None: - l.append("%s=%s" % (attr, `value`)) - return "%s(%s)" % (self.__class__.__name__, ", ".join(l)) - - def __eq__(self, other): - if not isinstance(other, _ttinfo): - return False - return (self.offset == other.offset and - self.delta == other.delta and - self.isdst == other.isdst and - self.abbr == other.abbr and - self.isstd == other.isstd and - self.isgmt == other.isgmt) - - def __ne__(self, other): - return not self.__eq__(other) - - def __getstate__(self): - state = {} - for name in self.__slots__: - state[name] = getattr(self, name, None) - return state - - def __setstate__(self, state): - for name in self.__slots__: - if name in state: - setattr(self, name, state[name]) - -class tzfile(datetime.tzinfo): - - # http://www.twinsun.com/tz/tz-link.htm - # ftp://elsie.nci.nih.gov/pub/tz*.tar.gz - - def __init__(self, fileobj): - if isinstance(fileobj, basestring): - self._filename = fileobj - fileobj = open(fileobj) - elif hasattr(fileobj, "name"): - self._filename = fileobj.name - else: - self._filename = `fileobj` - - # From tzfile(5): - # - # The time zone information files used by tzset(3) - # begin with the magic characters "TZif" to identify - # them as time zone information files, followed by - # sixteen bytes reserved for future use, followed by - # six four-byte values of type long, written in a - # ``standard'' byte order (the high-order byte - # of the value is written first). - - if fileobj.read(4) != "TZif": - raise ValueError, "magic not found" - - fileobj.read(16) - - ( - # The number of UTC/local indicators stored in the file. - ttisgmtcnt, - - # The number of standard/wall indicators stored in the file. - ttisstdcnt, - - # The number of leap seconds for which data is - # stored in the file. - leapcnt, - - # The number of "transition times" for which data - # is stored in the file. - timecnt, - - # The number of "local time types" for which data - # is stored in the file (must not be zero). - typecnt, - - # The number of characters of "time zone - # abbreviation strings" stored in the file. - charcnt, - - ) = struct.unpack(">6l", fileobj.read(24)) - - # The above header is followed by tzh_timecnt four-byte - # values of type long, sorted in ascending order. - # These values are written in ``standard'' byte order. - # Each is used as a transition time (as returned by - # time(2)) at which the rules for computing local time - # change. - - if timecnt: - self._trans_list = struct.unpack(">%dl" % timecnt, - fileobj.read(timecnt*4)) - else: - self._trans_list = [] - - # Next come tzh_timecnt one-byte values of type unsigned - # char; each one tells which of the different types of - # ``local time'' types described in the file is associated - # with the same-indexed transition time. These values - # serve as indices into an array of ttinfo structures that - # appears next in the file. - - if timecnt: - self._trans_idx = struct.unpack(">%dB" % timecnt, - fileobj.read(timecnt)) - else: - self._trans_idx = [] - - # Each ttinfo structure is written as a four-byte value - # for tt_gmtoff of type long, in a standard byte - # order, followed by a one-byte value for tt_isdst - # and a one-byte value for tt_abbrind. In each - # structure, tt_gmtoff gives the number of - # seconds to be added to UTC, tt_isdst tells whether - # tm_isdst should be set by localtime(3), and - # tt_abbrind serves as an index into the array of - # time zone abbreviation characters that follow the - # ttinfo structure(s) in the file. - - ttinfo = [] - - for i in range(typecnt): - ttinfo.append(struct.unpack(">lbb", fileobj.read(6))) - - abbr = fileobj.read(charcnt) - - # Then there are tzh_leapcnt pairs of four-byte - # values, written in standard byte order; the - # first value of each pair gives the time (as - # returned by time(2)) at which a leap second - # occurs; the second gives the total number of - # leap seconds to be applied after the given time. - # The pairs of values are sorted in ascending order - # by time. - - # Not used, for now - if leapcnt: - leap = struct.unpack(">%dl" % (leapcnt*2), - fileobj.read(leapcnt*8)) - - # Then there are tzh_ttisstdcnt standard/wall - # indicators, each stored as a one-byte value; - # they tell whether the transition times associated - # with local time types were specified as standard - # time or wall clock time, and are used when - # a time zone file is used in handling POSIX-style - # time zone environment variables. - - if ttisstdcnt: - isstd = struct.unpack(">%db" % ttisstdcnt, - fileobj.read(ttisstdcnt)) - - # Finally, there are tzh_ttisgmtcnt UTC/local - # indicators, each stored as a one-byte value; - # they tell whether the transition times associated - # with local time types were specified as UTC or - # local time, and are used when a time zone file - # is used in handling POSIX-style time zone envi- - # ronment variables. - - if ttisgmtcnt: - isgmt = struct.unpack(">%db" % ttisgmtcnt, - fileobj.read(ttisgmtcnt)) - - # ** Everything has been read ** - - # Build ttinfo list - self._ttinfo_list = [] - for i in range(typecnt): - gmtoff, isdst, abbrind = ttinfo[i] - # Round to full-minutes if that's not the case. Python's - # datetime doesn't accept sub-minute timezones. Check - # http://python.org/sf/1447945 for some information. - gmtoff = (gmtoff+30)//60*60 - tti = _ttinfo() - tti.offset = gmtoff - tti.delta = datetime.timedelta(seconds=gmtoff) - tti.isdst = isdst - tti.abbr = abbr[abbrind:abbr.find('\x00', abbrind)] - tti.isstd = (ttisstdcnt > i and isstd[i] != 0) - tti.isgmt = (ttisgmtcnt > i and isgmt[i] != 0) - self._ttinfo_list.append(tti) - - # Replace ttinfo indexes for ttinfo objects. - trans_idx = [] - for idx in self._trans_idx: - trans_idx.append(self._ttinfo_list[idx]) - self._trans_idx = tuple(trans_idx) - - # Set standard, dst, and before ttinfos. before will be - # used when a given time is before any transitions, - # and will be set to the first non-dst ttinfo, or to - # the first dst, if all of them are dst. - self._ttinfo_std = None - self._ttinfo_dst = None - self._ttinfo_before = None - if self._ttinfo_list: - if not self._trans_list: - self._ttinfo_std = self._ttinfo_first = self._ttinfo_list[0] - else: - for i in range(timecnt-1,-1,-1): - tti = self._trans_idx[i] - if not self._ttinfo_std and not tti.isdst: - self._ttinfo_std = tti - elif not self._ttinfo_dst and tti.isdst: - self._ttinfo_dst = tti - if self._ttinfo_std and self._ttinfo_dst: - break - else: - if self._ttinfo_dst and not self._ttinfo_std: - self._ttinfo_std = self._ttinfo_dst - - for tti in self._ttinfo_list: - if not tti.isdst: - self._ttinfo_before = tti - break - else: - self._ttinfo_before = self._ttinfo_list[0] - - # Now fix transition times to become relative to wall time. - # - # I'm not sure about this. In my tests, the tz source file - # is setup to wall time, and in the binary file isstd and - # isgmt are off, so it should be in wall time. OTOH, it's - # always in gmt time. Let me know if you have comments - # about this. - laststdoffset = 0 - self._trans_list = list(self._trans_list) - for i in range(len(self._trans_list)): - tti = self._trans_idx[i] - if not tti.isdst: - # This is std time. - self._trans_list[i] += tti.offset - laststdoffset = tti.offset - else: - # This is dst time. Convert to std. - self._trans_list[i] += laststdoffset - self._trans_list = tuple(self._trans_list) - - def _find_ttinfo(self, dt, laststd=0): - timestamp = ((dt.toordinal() - EPOCHORDINAL) * 86400 - + dt.hour * 3600 - + dt.minute * 60 - + dt.second) - idx = 0 - for trans in self._trans_list: - if timestamp < trans: - break - idx += 1 - else: - return self._ttinfo_std - if idx == 0: - return self._ttinfo_before - if laststd: - while idx > 0: - tti = self._trans_idx[idx-1] - if not tti.isdst: - return tti - idx -= 1 - else: - return self._ttinfo_std - else: - return self._trans_idx[idx-1] - - def utcoffset(self, dt): - if not self._ttinfo_std: - return ZERO - return self._find_ttinfo(dt).delta - - def dst(self, dt): - if not self._ttinfo_dst: - return ZERO - tti = self._find_ttinfo(dt) - if not tti.isdst: - return ZERO - - # The documentation says that utcoffset()-dst() must - # be constant for every dt. - return tti.delta-self._find_ttinfo(dt, laststd=1).delta - - # An alternative for that would be: - # - # return self._ttinfo_dst.offset-self._ttinfo_std.offset - # - # However, this class stores historical changes in the - # dst offset, so I belive that this wouldn't be the right - # way to implement this. - - def tzname(self, dt): - if not self._ttinfo_std: - return None - return self._find_ttinfo(dt).abbr - - def __eq__(self, other): - if not isinstance(other, tzfile): - return False - return (self._trans_list == other._trans_list and - self._trans_idx == other._trans_idx and - self._ttinfo_list == other._ttinfo_list) - - def __ne__(self, other): - return not self.__eq__(other) - - - def __repr__(self): - return "%s(%s)" % (self.__class__.__name__, `self._filename`) - - def __reduce__(self): - if not os.path.isfile(self._filename): - raise ValueError, "Unpickable %s class" % self.__class__.__name__ - return (self.__class__, (self._filename,)) - -class tzrange(datetime.tzinfo): - - def __init__(self, stdabbr, stdoffset=None, - dstabbr=None, dstoffset=None, - start=None, end=None): - global relativedelta - if not relativedelta: - from dateutil import relativedelta - self._std_abbr = stdabbr - self._dst_abbr = dstabbr - if stdoffset is not None: - self._std_offset = datetime.timedelta(seconds=stdoffset) - else: - self._std_offset = ZERO - if dstoffset is not None: - self._dst_offset = datetime.timedelta(seconds=dstoffset) - elif dstabbr and stdoffset is not None: - self._dst_offset = self._std_offset+datetime.timedelta(hours=+1) - else: - self._dst_offset = ZERO - if dstabbr and start is None: - self._start_delta = relativedelta.relativedelta( - hours=+2, month=4, day=1, weekday=relativedelta.SU(+1)) - else: - self._start_delta = start - if dstabbr and end is None: - self._end_delta = relativedelta.relativedelta( - hours=+1, month=10, day=31, weekday=relativedelta.SU(-1)) - else: - self._end_delta = end - - def utcoffset(self, dt): - if self._isdst(dt): - return self._dst_offset - else: - return self._std_offset - - def dst(self, dt): - if self._isdst(dt): - return self._dst_offset-self._std_offset - else: - return ZERO - - def tzname(self, dt): - if self._isdst(dt): - return self._dst_abbr - else: - return self._std_abbr - - def _isdst(self, dt): - if not self._start_delta: - return False - year = datetime.datetime(dt.year,1,1) - start = year+self._start_delta - end = year+self._end_delta - dt = dt.replace(tzinfo=None) - if start < end: - return dt >= start and dt < end - else: - return dt >= start or dt < end - - def __eq__(self, other): - if not isinstance(other, tzrange): - return False - return (self._std_abbr == other._std_abbr and - self._dst_abbr == other._dst_abbr and - self._std_offset == other._std_offset and - self._dst_offset == other._dst_offset and - self._start_delta == other._start_delta and - self._end_delta == other._end_delta) - - def __ne__(self, other): - return not self.__eq__(other) - - def __repr__(self): - return "%s(...)" % self.__class__.__name__ - - __reduce__ = object.__reduce__ - -class tzstr(tzrange): - - def __init__(self, s): - global parser - if not parser: - from dateutil import parser - self._s = s - - res = parser._parsetz(s) - if res is None: - raise ValueError, "unknown string format" - - # Here we break the compatibility with the TZ variable handling. - # GMT-3 actually *means* the timezone -3. - if res.stdabbr in ("GMT", "UTC"): - res.stdoffset *= -1 - - # We must initialize it first, since _delta() needs - # _std_offset and _dst_offset set. Use False in start/end - # to avoid building it two times. - tzrange.__init__(self, res.stdabbr, res.stdoffset, - res.dstabbr, res.dstoffset, - start=False, end=False) - - if not res.dstabbr: - self._start_delta = None - self._end_delta = None - else: - self._start_delta = self._delta(res.start) - if self._start_delta: - self._end_delta = self._delta(res.end, isend=1) - - def _delta(self, x, isend=0): - kwargs = {} - if x.month is not None: - kwargs["month"] = x.month - if x.weekday is not None: - kwargs["weekday"] = relativedelta.weekday(x.weekday, x.week) - if x.week > 0: - kwargs["day"] = 1 - else: - kwargs["day"] = 31 - elif x.day: - kwargs["day"] = x.day - elif x.yday is not None: - kwargs["yearday"] = x.yday - elif x.jyday is not None: - kwargs["nlyearday"] = x.jyday - if not kwargs: - # Default is to start on first sunday of april, and end - # on last sunday of october. - if not isend: - kwargs["month"] = 4 - kwargs["day"] = 1 - kwargs["weekday"] = relativedelta.SU(+1) - else: - kwargs["month"] = 10 - kwargs["day"] = 31 - kwargs["weekday"] = relativedelta.SU(-1) - if x.time is not None: - kwargs["seconds"] = x.time - else: - # Default is 2AM. - kwargs["seconds"] = 7200 - if isend: - # Convert to standard time, to follow the documented way - # of working with the extra hour. See the documentation - # of the tzinfo class. - delta = self._dst_offset-self._std_offset - kwargs["seconds"] -= delta.seconds+delta.days*86400 - return relativedelta.relativedelta(**kwargs) - - def __repr__(self): - return "%s(%s)" % (self.__class__.__name__, `self._s`) - -class _tzicalvtzcomp: - def __init__(self, tzoffsetfrom, tzoffsetto, isdst, - tzname=None, rrule=None): - self.tzoffsetfrom = datetime.timedelta(seconds=tzoffsetfrom) - self.tzoffsetto = datetime.timedelta(seconds=tzoffsetto) - self.tzoffsetdiff = self.tzoffsetto-self.tzoffsetfrom - self.isdst = isdst - self.tzname = tzname - self.rrule = rrule - -class _tzicalvtz(datetime.tzinfo): - def __init__(self, tzid, comps=[]): - self._tzid = tzid - self._comps = comps - self._cachedate = [] - self._cachecomp = [] - - def _find_comp(self, dt): - if len(self._comps) == 1: - return self._comps[0] - dt = dt.replace(tzinfo=None) - try: - return self._cachecomp[self._cachedate.index(dt)] - except ValueError: - pass - lastcomp = None - lastcompdt = None - for comp in self._comps: - if not comp.isdst: - # Handle the extra hour in DST -> STD - compdt = comp.rrule.before(dt-comp.tzoffsetdiff, inc=True) - else: - compdt = comp.rrule.before(dt, inc=True) - if compdt and (not lastcompdt or lastcompdt < compdt): - lastcompdt = compdt - lastcomp = comp - if not lastcomp: - # RFC says nothing about what to do when a given - # time is before the first onset date. We'll look for the - # first standard component, or the first component, if - # none is found. - for comp in self._comps: - if not comp.isdst: - lastcomp = comp - break - else: - lastcomp = comp[0] - self._cachedate.insert(0, dt) - self._cachecomp.insert(0, lastcomp) - if len(self._cachedate) > 10: - self._cachedate.pop() - self._cachecomp.pop() - return lastcomp - - def utcoffset(self, dt): - return self._find_comp(dt).tzoffsetto - - def dst(self, dt): - comp = self._find_comp(dt) - if comp.isdst: - return comp.tzoffsetdiff - else: - return ZERO - - def tzname(self, dt): - return self._find_comp(dt).tzname - - def __repr__(self): - return "" % `self._tzid` - - __reduce__ = object.__reduce__ - -class tzical: - def __init__(self, fileobj): - global rrule - if not rrule: - from dateutil import rrule - - if isinstance(fileobj, basestring): - self._s = fileobj - fileobj = open(fileobj) - elif hasattr(fileobj, "name"): - self._s = fileobj.name - else: - self._s = `fileobj` - - self._vtz = {} - - self._parse_rfc(fileobj.read()) - - def keys(self): - return self._vtz.keys() - - def get(self, tzid=None): - if tzid is None: - keys = self._vtz.keys() - if len(keys) == 0: - raise ValueError, "no timezones defined" - elif len(keys) > 1: - raise ValueError, "more than one timezone available" - tzid = keys[0] - return self._vtz.get(tzid) - - def _parse_offset(self, s): - s = s.strip() - if not s: - raise ValueError, "empty offset" - if s[0] in ('+', '-'): - signal = (-1,+1)[s[0]=='+'] - s = s[1:] - else: - signal = +1 - if len(s) == 4: - return (int(s[:2])*3600+int(s[2:])*60)*signal - elif len(s) == 6: - return (int(s[:2])*3600+int(s[2:4])*60+int(s[4:]))*signal - else: - raise ValueError, "invalid offset: "+s - - def _parse_rfc(self, s): - lines = s.splitlines() - if not lines: - raise ValueError, "empty string" - - # Unfold - i = 0 - while i < len(lines): - line = lines[i].rstrip() - if not line: - del lines[i] - elif i > 0 and line[0] == " ": - lines[i-1] += line[1:] - del lines[i] - else: - i += 1 - - tzid = None - comps = [] - invtz = False - comptype = None - for line in lines: - if not line: - continue - name, value = line.split(':', 1) - parms = name.split(';') - if not parms: - raise ValueError, "empty property name" - name = parms[0].upper() - parms = parms[1:] - if invtz: - if name == "BEGIN": - if value in ("STANDARD", "DAYLIGHT"): - # Process component - pass - else: - raise ValueError, "unknown component: "+value - comptype = value - founddtstart = False - tzoffsetfrom = None - tzoffsetto = None - rrulelines = [] - tzname = None - elif name == "END": - if value == "VTIMEZONE": - if comptype: - raise ValueError, \ - "component not closed: "+comptype - if not tzid: - raise ValueError, \ - "mandatory TZID not found" - if not comps: - raise ValueError, \ - "at least one component is needed" - # Process vtimezone - self._vtz[tzid] = _tzicalvtz(tzid, comps) - invtz = False - elif value == comptype: - if not founddtstart: - raise ValueError, \ - "mandatory DTSTART not found" - if tzoffsetfrom is None: - raise ValueError, \ - "mandatory TZOFFSETFROM not found" - if tzoffsetto is None: - raise ValueError, \ - "mandatory TZOFFSETFROM not found" - # Process component - rr = None - if rrulelines: - rr = rrule.rrulestr("\n".join(rrulelines), - compatible=True, - ignoretz=True, - cache=True) - comp = _tzicalvtzcomp(tzoffsetfrom, tzoffsetto, - (comptype == "DAYLIGHT"), - tzname, rr) - comps.append(comp) - comptype = None - else: - raise ValueError, \ - "invalid component end: "+value - elif comptype: - if name == "DTSTART": - rrulelines.append(line) - founddtstart = True - elif name in ("RRULE", "RDATE", "EXRULE", "EXDATE"): - rrulelines.append(line) - elif name == "TZOFFSETFROM": - if parms: - raise ValueError, \ - "unsupported %s parm: %s "%(name, parms[0]) - tzoffsetfrom = self._parse_offset(value) - elif name == "TZOFFSETTO": - if parms: - raise ValueError, \ - "unsupported TZOFFSETTO parm: "+parms[0] - tzoffsetto = self._parse_offset(value) - elif name == "TZNAME": - if parms: - raise ValueError, \ - "unsupported TZNAME parm: "+parms[0] - tzname = value - elif name == "COMMENT": - pass - else: - raise ValueError, "unsupported property: "+name - else: - if name == "TZID": - if parms: - raise ValueError, \ - "unsupported TZID parm: "+parms[0] - tzid = value - elif name in ("TZURL", "LAST-MODIFIED", "COMMENT"): - pass - else: - raise ValueError, "unsupported property: "+name - elif name == "BEGIN" and value == "VTIMEZONE": - tzid = None - comps = [] - invtz = True - - def __repr__(self): - return "%s(%s)" % (self.__class__.__name__, `self._s`) - -if sys.platform != "win32": - TZFILES = ["/etc/localtime", "localtime"] - TZPATHS = ["/usr/share/zoneinfo", "/usr/lib/zoneinfo", "/etc/zoneinfo"] -else: - TZFILES = [] - TZPATHS = [] - -def gettz(name=None): - tz = None - if not name: - try: - name = os.environ["TZ"] - except KeyError: - pass - if name is None or name == ":": - for filepath in TZFILES: - if not os.path.isabs(filepath): - filename = filepath - for path in TZPATHS: - filepath = os.path.join(path, filename) - if os.path.isfile(filepath): - break - else: - continue - if os.path.isfile(filepath): - try: - tz = tzfile(filepath) - break - except (IOError, OSError, ValueError): - pass - else: - tz = tzlocal() - else: - if name.startswith(":"): - name = name[:-1] - if os.path.isabs(name): - if os.path.isfile(name): - tz = tzfile(name) - else: - tz = None - else: - for path in TZPATHS: - filepath = os.path.join(path, name) - if not os.path.isfile(filepath): - filepath = filepath.replace(' ','_') - if not os.path.isfile(filepath): - continue - try: - tz = tzfile(filepath) - break - except (IOError, OSError, ValueError): - pass - else: - tz = None - if tzwin: - try: - tz = tzwin(name) - except OSError: - pass - if not tz: - from dateutil.zoneinfo import gettz - tz = gettz(name) - if not tz: - for c in name: - # name must have at least one offset to be a tzstr - if c in "0123456789": - try: - tz = tzstr(name) - except ValueError: - pass - break - else: - if name in ("GMT", "UTC"): - tz = tzutc() - elif name in time.tzname: - tz = tzlocal() - return tz - -# vim:ts=4:sw=4:et diff -Nru matplotlib-1.1.1/lib/dateutil/tzwin.py matplotlib-1.2.0/lib/dateutil/tzwin.py --- matplotlib-1.1.1/lib/dateutil/tzwin.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil/tzwin.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,180 +0,0 @@ -# This code was originally contributed by Jeffrey Harris. -import datetime -import struct -import _winreg - -__author__ = "Jeffrey Harris & Gustavo Niemeyer " - -__all__ = ["tzwin", "tzwinlocal"] - -ONEWEEK = datetime.timedelta(7) - -TZKEYNAMENT = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones" -TZKEYNAME9X = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones" -TZLOCALKEYNAME = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation" - -def _settzkeyname(): - global TZKEYNAME - handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) - try: - _winreg.OpenKey(handle, TZKEYNAMENT).Close() - TZKEYNAME = TZKEYNAMENT - except WindowsError: - TZKEYNAME = TZKEYNAME9X - handle.Close() - -_settzkeyname() - -class tzwinbase(datetime.tzinfo): - """tzinfo class based on win32's timezones available in the registry.""" - - def utcoffset(self, dt): - if self._isdst(dt): - return datetime.timedelta(minutes=self._dstoffset) - else: - return datetime.timedelta(minutes=self._stdoffset) - - def dst(self, dt): - if self._isdst(dt): - minutes = self._dstoffset - self._stdoffset - return datetime.timedelta(minutes=minutes) - else: - return datetime.timedelta(0) - - def tzname(self, dt): - if self._isdst(dt): - return self._dstname - else: - return self._stdname - - def list(): - """Return a list of all time zones known to the system.""" - handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) - tzkey = _winreg.OpenKey(handle, TZKEYNAME) - result = [_winreg.EnumKey(tzkey, i) - for i in range(_winreg.QueryInfoKey(tzkey)[0])] - tzkey.Close() - handle.Close() - return result - list = staticmethod(list) - - def display(self): - return self._display - - def _isdst(self, dt): - dston = picknthweekday(dt.year, self._dstmonth, self._dstdayofweek, - self._dsthour, self._dstminute, - self._dstweeknumber) - dstoff = picknthweekday(dt.year, self._stdmonth, self._stddayofweek, - self._stdhour, self._stdminute, - self._stdweeknumber) - if dston < dstoff: - return dston <= dt.replace(tzinfo=None) < dstoff - else: - return not dstoff <= dt.replace(tzinfo=None) < dston - - -class tzwin(tzwinbase): - - def __init__(self, name): - self._name = name - - handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) - tzkey = _winreg.OpenKey(handle, "%s\%s" % (TZKEYNAME, name)) - keydict = valuestodict(tzkey) - tzkey.Close() - handle.Close() - - self._stdname = keydict["Std"].encode("iso-8859-1") - self._dstname = keydict["Dlt"].encode("iso-8859-1") - - self._display = keydict["Display"] - - # See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm - tup = struct.unpack("=3l16h", keydict["TZI"]) - self._stdoffset = -tup[0]-tup[1] # Bias + StandardBias * -1 - self._dstoffset = self._stdoffset-tup[2] # + DaylightBias * -1 - - (self._stdmonth, - self._stddayofweek, # Sunday = 0 - self._stdweeknumber, # Last = 5 - self._stdhour, - self._stdminute) = tup[4:9] - - (self._dstmonth, - self._dstdayofweek, # Sunday = 0 - self._dstweeknumber, # Last = 5 - self._dsthour, - self._dstminute) = tup[12:17] - - def __repr__(self): - return "tzwin(%s)" % repr(self._name) - - def __reduce__(self): - return (self.__class__, (self._name,)) - - -class tzwinlocal(tzwinbase): - - def __init__(self): - - handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) - - tzlocalkey = _winreg.OpenKey(handle, TZLOCALKEYNAME) - keydict = valuestodict(tzlocalkey) - tzlocalkey.Close() - - self._stdname = keydict["StandardName"].encode("iso-8859-1") - self._dstname = keydict["DaylightName"].encode("iso-8859-1") - - try: - tzkey = _winreg.OpenKey(handle, "%s\%s"%(TZKEYNAME, self._stdname)) - _keydict = valuestodict(tzkey) - self._display = _keydict["Display"] - tzkey.Close() - except OSError: - self._display = None - - handle.Close() - - self._stdoffset = -keydict["Bias"]-keydict["StandardBias"] - self._dstoffset = self._stdoffset-keydict["DaylightBias"] - - - # See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm - tup = struct.unpack("=8h", keydict["StandardStart"]) - - (self._stdmonth, - self._stddayofweek, # Sunday = 0 - self._stdweeknumber, # Last = 5 - self._stdhour, - self._stdminute) = tup[1:6] - - tup = struct.unpack("=8h", keydict["DaylightStart"]) - - (self._dstmonth, - self._dstdayofweek, # Sunday = 0 - self._dstweeknumber, # Last = 5 - self._dsthour, - self._dstminute) = tup[1:6] - - def __reduce__(self): - return (self.__class__, ()) - -def picknthweekday(year, month, dayofweek, hour, minute, whichweek): - """dayofweek == 0 means Sunday, whichweek 5 means last instance""" - first = datetime.datetime(year, month, 1, hour, minute) - weekdayone = first.replace(day=((dayofweek-first.isoweekday())%7+1)) - for n in xrange(whichweek): - dt = weekdayone+(whichweek-n)*ONEWEEK - if dt.month == month: - return dt - -def valuestodict(key): - """Convert a registry key's values to a dictionary.""" - dict = {} - size = _winreg.QueryInfoKey(key)[1] - for i in range(size): - data = _winreg.EnumValue(key, i) - dict[data[0]] = data[1] - return dict diff -Nru matplotlib-1.1.1/lib/dateutil/zoneinfo/__init__.py matplotlib-1.2.0/lib/dateutil/zoneinfo/__init__.py --- matplotlib-1.1.1/lib/dateutil/zoneinfo/__init__.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil/zoneinfo/__init__.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -""" -Copyright (c) 2003-2005 Gustavo Niemeyer - -This module offers extensions to the standard python 2.3+ -datetime module. -""" -from dateutil.tz import tzfile -from tarfile import TarFile -import os - -__author__ = "Gustavo Niemeyer " -__license__ = "PSF License" - -__all__ = ["setcachesize", "gettz", "rebuild"] - -CACHE = [] -CACHESIZE = 10 - -class tzfile(tzfile): - def __reduce__(self): - return (gettz, (self._filename,)) - -def getzoneinfofile(): - filenames = os.listdir(os.path.join(os.path.dirname(__file__))) - filenames.sort() - filenames.reverse() - for entry in filenames: - if entry.startswith("zoneinfo") and ".tar." in entry: - return os.path.join(os.path.dirname(__file__), entry) - return None - -ZONEINFOFILE = getzoneinfofile() - -del getzoneinfofile - -def setcachesize(size): - global CACHESIZE, CACHE - CACHESIZE = size - del CACHE[size:] - -def gettz(name): - tzinfo = None - if ZONEINFOFILE: - for cachedname, tzinfo in CACHE: - if cachedname == name: - break - else: - tf = TarFile.open(ZONEINFOFILE) - try: - zonefile = tf.extractfile(name) - except KeyError: - tzinfo = None - else: - tzinfo = tzfile(zonefile) - tf.close() - CACHE.insert(0, (name, tzinfo)) - del CACHE[CACHESIZE:] - return tzinfo - -def rebuild(filename, tag=None, format="gz"): - import tempfile, shutil - tmpdir = tempfile.mkdtemp() - zonedir = os.path.join(tmpdir, "zoneinfo") - moduledir = os.path.dirname(__file__) - if tag: tag = "-"+tag - targetname = "zoneinfo%s.tar.%s" % (tag, format) - try: - tf = TarFile.open(filename) - for name in tf.getnames(): - if not (name.endswith(".sh") or - name.endswith(".tab") or - name == "leapseconds"): - tf.extract(name, tmpdir) - filepath = os.path.join(tmpdir, name) - os.system("zic -d %s %s" % (zonedir, filepath)) - tf.close() - target = os.path.join(moduledir, targetname) - for entry in os.listdir(moduledir): - if entry.startswith("zoneinfo") and ".tar." in entry: - os.unlink(os.path.join(moduledir, entry)) - tf = TarFile.open(target, "w:%s" % format) - for entry in os.listdir(zonedir): - entrypath = os.path.join(zonedir, entry) - tf.add(entrypath, entry) - tf.close() - finally: - shutil.rmtree(tmpdir) Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/dateutil/zoneinfo/zoneinfo-2010g.tar.gz and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/dateutil/zoneinfo/zoneinfo-2010g.tar.gz differ diff -Nru matplotlib-1.1.1/lib/dateutil_py2/LICENSE matplotlib-1.2.0/lib/dateutil_py2/LICENSE --- matplotlib-1.1.1/lib/dateutil_py2/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py2/LICENSE 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,259 @@ +A. HISTORY OF THE SOFTWARE +========================== + +Python was created in the early 1990s by Guido van Rossum at Stichting +Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands +as a successor of a language called ABC. Guido remains Python's +principal author, although it includes many contributions from others. + +In 1995, Guido continued his work on Python at the Corporation for +National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) +in Reston, Virginia where he released several versions of the +software. + +In May 2000, Guido and the Python core development team moved to +BeOpen.com to form the BeOpen PythonLabs team. In October of the same +year, the PythonLabs team moved to Digital Creations (now Zope +Corporation, see http://www.zope.com). In 2001, the Python Software +Foundation (PSF, see http://www.python.org/psf/) was formed, a +non-profit organization created specifically to own Python-related +Intellectual Property. Zope Corporation is a sponsoring member of +the PSF. + +All Python releases are Open Source (see http://www.opensource.org for +the Open Source Definition). Historically, most, but not all, Python +releases have also been GPL-compatible; the table below summarizes +the various releases. + + Release Derived Year Owner GPL- + from compatible? (1) + + 0.9.0 thru 1.2 1991-1995 CWI yes + 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes + 1.6 1.5.2 2000 CNRI no + 2.0 1.6 2000 BeOpen.com no + 1.6.1 1.6 2001 CNRI yes (2) + 2.1 2.0+1.6.1 2001 PSF no + 2.0.1 2.0+1.6.1 2001 PSF yes + 2.1.1 2.1+2.0.1 2001 PSF yes + 2.2 2.1.1 2001 PSF yes + 2.1.2 2.1.1 2002 PSF yes + 2.1.3 2.1.2 2002 PSF yes + 2.2.1 2.2 2002 PSF yes + 2.2.2 2.2.1 2002 PSF yes + 2.2.3 2.2.2 2003 PSF yes + 2.3 2.2.2 2002-2003 PSF yes + +Footnotes: + +(1) GPL-compatible doesn't mean that we're distributing Python under + the GPL. All Python licenses, unlike the GPL, let you distribute + a modified version without making your changes open source. The + GPL-compatible licenses make it possible to combine Python with + other software that is released under the GPL; the others don't. + +(2) According to Richard Stallman, 1.6.1 is not GPL-compatible, + because its license has a choice of law clause. According to + CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 + is "not incompatible" with the GPL. + +Thanks to the many outside volunteers who have worked under Guido's +direction to make these releases possible. + + +B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON +=============================================================== + +PSF LICENSE AGREEMENT FOR PYTHON 2.3 +------------------------------------ + +1. This LICENSE AGREEMENT is between the Python Software Foundation +("PSF"), and the Individual or Organization ("Licensee") accessing and +otherwise using Python 2.3 software in source or binary form and its +associated documentation. + +2. Subject to the terms and conditions of this License Agreement, PSF +hereby grants Licensee a nonexclusive, royalty-free, world-wide +license to reproduce, analyze, test, perform and/or display publicly, +prepare derivative works, distribute, and otherwise use Python 2.3 +alone or in any derivative version, provided, however, that PSF's +License Agreement and PSF's notice of copyright, i.e., "Copyright (c) +2001, 2002, 2003 Python Software Foundation; All Rights Reserved" are +retained in Python 2.3 alone or in any derivative version prepared by +Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python 2.3 or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python 2.3. + +4. PSF is making Python 2.3 available to Licensee on an "AS IS" +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.3 WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +2.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.3, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF and +Licensee. This License Agreement does not grant permission to use PSF +trademarks or trade name in a trademark sense to endorse or promote +products or services of Licensee, or any third party. + +8. By copying, installing or otherwise using Python 2.3, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 +------------------------------------------- + +BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 + +1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an +office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the +Individual or Organization ("Licensee") accessing and otherwise using +this software in source or binary form and its associated +documentation ("the Software"). + +2. Subject to the terms and conditions of this BeOpen Python License +Agreement, BeOpen hereby grants Licensee a non-exclusive, +royalty-free, world-wide license to reproduce, analyze, test, perform +and/or display publicly, prepare derivative works, distribute, and +otherwise use the Software alone or in any derivative version, +provided, however, that the BeOpen Python License is retained in the +Software, alone or in any derivative version prepared by Licensee. + +3. BeOpen is making the Software available to Licensee on an "AS IS" +basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE +SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS +AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY +DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +5. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +6. This License Agreement shall be governed by and interpreted in all +respects by the law of the State of California, excluding conflict of +law provisions. Nothing in this License Agreement shall be deemed to +create any relationship of agency, partnership, or joint venture +between BeOpen and Licensee. This License Agreement does not grant +permission to use BeOpen trademarks or trade names in a trademark +sense to endorse or promote products or services of Licensee, or any +third party. As an exception, the "BeOpen Python" logos available at +http://www.pythonlabs.com/logos.html may be used according to the +permissions granted on that web page. + +7. By copying, installing or otherwise using the software, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 +--------------------------------------- + +1. This LICENSE AGREEMENT is between the Corporation for National +Research Initiatives, having an office at 1895 Preston White Drive, +Reston, VA 20191 ("CNRI"), and the Individual or Organization +("Licensee") accessing and otherwise using Python 1.6.1 software in +source or binary form and its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, CNRI +hereby grants Licensee a nonexclusive, royalty-free, world-wide +license to reproduce, analyze, test, perform and/or display publicly, +prepare derivative works, distribute, and otherwise use Python 1.6.1 +alone or in any derivative version, provided, however, that CNRI's +License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) +1995-2001 Corporation for National Research Initiatives; All Rights +Reserved" are retained in Python 1.6.1 alone or in any derivative +version prepared by Licensee. Alternately, in lieu of CNRI's License +Agreement, Licensee may substitute the following text (omitting the +quotes): "Python 1.6.1 is made available subject to the terms and +conditions in CNRI's License Agreement. This Agreement together with +Python 1.6.1 may be located on the Internet using the following +unique, persistent identifier (known as a handle): 1895.22/1013. This +Agreement may also be obtained from a proxy server on the Internet +using the following URL: http://hdl.handle.net/1895.22/1013". + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python 1.6.1 or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python 1.6.1. + +4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" +basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. This License Agreement shall be governed by the federal +intellectual property law of the United States, including without +limitation the federal copyright law, and, to the extent such +U.S. federal law does not apply, by the law of the Commonwealth of +Virginia, excluding Virginia's conflict of law provisions. +Notwithstanding the foregoing, with regard to derivative works based +on Python 1.6.1 that incorporate non-separable material that was +previously distributed under the GNU General Public License (GPL), the +law of the Commonwealth of Virginia shall govern this License +Agreement only as to issues arising under or with respect to +Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this +License Agreement shall be deemed to create any relationship of +agency, partnership, or joint venture between CNRI and Licensee. This +License Agreement does not grant permission to use CNRI trademarks or +trade name in a trademark sense to endorse or promote products or +services of Licensee, or any third party. + +8. By clicking on the "ACCEPT" button where indicated, or by copying, +installing or otherwise using Python 1.6.1, Licensee agrees to be +bound by the terms and conditions of this License Agreement. + + ACCEPT + + +CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 +-------------------------------------------------- + +Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, +The Netherlands. All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Stichting Mathematisch +Centrum or CWI not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff -Nru matplotlib-1.1.1/lib/dateutil_py2/NEWS matplotlib-1.2.0/lib/dateutil_py2/NEWS --- matplotlib-1.1.1/lib/dateutil_py2/NEWS 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py2/NEWS 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,143 @@ + +Version 1.5 +----------- + +- As reported by Mathieu Bridon, rrules were matching the bysecond rules + incorrectly against byminute in some circumstances when the SECONDLY + frequency was in use, due to a copy & paste bug. The problem has been + unittested and corrected. + +- Adam Ryan reported a problem in the relativedelta implementation which + affected the yearday parameter in the month of January specifically. + This has been unittested and fixed. + +- Updated timezone information. + + +Version 1.4.1 +------------- + +- Updated timezone information. + + +Version 1.4 +----------- + +- Fixed another parser precision problem on conversion of decimal seconds + to microseconds, as reported by Erik Brown. Now these issues are gone + for real since it's not using floating point arithmetic anymore. + +- Fixed case where tzrange.utcoffset and tzrange.dst() might fail due + to a date being used where a datetime was expected (reported and fixed + by Lennart Regebro). + +- Prevent tzstr from introducing daylight timings in strings that didn't + specify them (reported by Lennart Regebro). + +- Calls like gettz("GMT+3") and gettz("UTC-2") will now return the + expected values, instead of the TZ variable behavior. + +- Fixed DST signal handling in zoneinfo files. Reported by + Nicholas F. Fabry and John-Mark Gurney. + + +Version 1.3 +----------- + +- Fixed precision problem on conversion of decimal seconds to + microseconds, as reported by Skip Montanaro. + +- Fixed bug in constructor of parser, and converted parser classes to + new-style classes. Original report and patch by Michael Elsdrfer. + +- Initialize tzid and comps in tz.py, to prevent the code from ever + raising a NameError (even with broken files). Johan Dahlin suggested + the fix after a pyflakes run. + +- Version is now published in dateutil.__version__, as requested + by Darren Dale. + +- All code is compatible with new-style division. + + +Version 1.2 +----------- + +- Now tzfile will round timezones to full-minutes if necessary, + since Python's datetime doesn't support sub-minute offsets. + Thanks to Ilpo Nyyssnen for reporting the issue. + +- Removed bare string exceptions, as reported and fixed by + Wilfredo Snchez Vega. + +- Fix bug in leap count parsing (reported and fixed by Eugene Oden). + + +Version 1.1 +----------- + +- Fixed rrule byyearday handling. Abramo Bagnara pointed out that + RFC2445 allows negative numbers. + +- Fixed --prefix handling in setup.py (by Sidnei da Silva). + +- Now tz.gettz() returns a tzlocal instance when not given any + arguments and no other timezone information is found. + +- Updating timezone information to version 2005q. + + +Version 1.0 +----------- + +- Fixed parsing of XXhXXm formatted time after day/month/year + has been parsed. + +- Added patch by Jeffrey Harris optimizing rrule.__contains__. + + +Version 0.9 +----------- + +- Fixed pickling of timezone types, as reported by + Andreas Khler. + +- Implemented internal timezone information with binary + timezone files [1]. datautil.tz.gettz() function will now + try to use the system timezone files, and fallback to + the internal versions. It's also possible to ask for + the internal versions directly by using + dateutil.zoneinfo.gettz(). + +- New tzwin timezone type, allowing access to Windows + internal timezones (contributed by Jeffrey Harris). + +- Fixed parsing of unicode date strings. + +- Accept parserinfo instances as the parser constructor + parameter, besides parserinfo (sub)classes. + +- Changed weekday to spell the not-set n value as None + instead of 0. + +- Fixed other reported bugs. + +[1] http://www.twinsun.com/tz/tz-link.htm + + +Version 0.5 +----------- + +- Removed FREQ_ prefix from rrule frequency constants + WARNING: this breaks compatibility with previous versions. + +- Fixed rrule.between() for cases where "after" is achieved + before even starting, as reported by Andreas Khler. + +- Fixed two digit zero-year parsing (such as 31-Dec-00), as + reported by Jim Abramson, and included test case for this. + +- Sort exdate and rdate before iterating over them, so that + it's not necessary to sort them before adding to the rruleset, + as reported by Nicholas Piper. + diff -Nru matplotlib-1.1.1/lib/dateutil_py2/README matplotlib-1.2.0/lib/dateutil_py2/README --- matplotlib-1.1.1/lib/dateutil_py2/README 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py2/README 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,1970 @@ +## This file is in the moin format. The latest version is found +## at https://moin.conectiva.com.br/DateUtil + +== Contents == +[[TableOfContents]] + +== Description == +The '''dateutil''' module provides powerful extensions to +the standard '''datetime''' module, available in Python 2.3+. + +== Features == + + * Computing of relative deltas (next month, next year, + next monday, last week of month, etc); + + * Computing of relative deltas between two given + date and/or datetime objects; + + * Computing of dates based on very flexible recurrence rules, + using a superset of the + [ftp://ftp.rfc-editor.org/in-notes/rfc2445.txt iCalendar] + specification. Parsing of RFC strings is supported as well. + + * Generic parsing of dates in almost any string format; + + * Timezone (tzinfo) implementations for tzfile(5) format + files (/etc/localtime, /usr/share/zoneinfo, etc), TZ + environment string (in all known formats), iCalendar + format files, given ranges (with help from relative deltas), + local machine timezone, fixed offset timezone, UTC timezone, + and Windows registry-based time zones. + + * Internal up-to-date world timezone information based on + Olson's database. + + * Computing of Easter Sunday dates for any given year, + using Western, Orthodox or Julian algorithms; + + * More than 400 test cases. + +== Quick example == +Here's a snapshot, just to give an idea about the power of the +package. For more examples, look at the documentation below. + +Suppose you want to know how much time is left, in +years/months/days/etc, before the next easter happening on a +year with a Friday 13th in August, and you want to get today's +date out of the "date" unix system command. Here is the code: +{{{ +from dateutil.relativedelta import * +from dateutil.easter import * +from dateutil.rrule import * +from dateutil.parser import * +from datetime import * +import commands +import os +now = parse(commands.getoutput("date")) +today = now.date() +year = rrule(YEARLY,bymonth=8,bymonthday=13,byweekday=FR)[0].year +rdelta = relativedelta(easter(year), today) +print "Today is:", today +print "Year with next Aug 13th on a Friday is:", year +print "How far is the Easter of that year:", rdelta +print "And the Easter of that year is:", today+rdelta +}}} + +And here's the output: +{{{ +Today is: 2003-10-11 +Year with next Aug 13th on a Friday is: 2004 +How far is the Easter of that year: relativedelta(months=+6) +And the Easter of that year is: 2004-04-11 +}}} + +{i} Being exactly 6 months ahead was '''really''' a coincidence :) + +== Download == +The following files are available. + * attachment:python-dateutil-1.0.tar.bz2 + * attachment:python-dateutil-1.0-1.noarch.rpm + +== Author == +The dateutil module was written by GustavoNiemeyer . + +== Documentation == +The following modules are available. + +=== relativedelta === +This module offers the '''relativedelta''' type, which is based +on the specification of the excelent work done by M.-A. Lemburg in his +[http://www.egenix.com/files/python/mxDateTime.html mxDateTime] +extension. However, notice that this type '''does not''' implement the +same algorithm as his work. Do not expect it to behave like +{{{mxDateTime}}}'s counterpart. + +==== relativedelta type ==== + +There's two different ways to build a relativedelta instance. The +first one is passing it two {{{date}}}/{{{datetime}}} instances: +{{{ +relativedelta(datetime1, datetime2) +}}} + +This will build the relative difference between {{{datetime1}}} and +{{{datetime2}}}, so that the following constraint is always true: +{{{ +datetime2+relativedelta(datetime1, datetime2) == datetime1 +}}} + +Notice that instead of {{{datetime}}} instances, you may use +{{{date}}} instances, or a mix of both. + +And the other way is to use any of the following keyword arguments: + + year, month, day, hour, minute, second, microsecond:: + Absolute information. + + years, months, weeks, days, hours, minutes, seconds, microseconds:: + Relative information, may be negative. + + weekday:: + One of the weekday instances ({{{MO}}}, {{{TU}}}, etc). These + instances may receive a parameter {{{n}}}, specifying the {{{n}}}th + weekday, which could be positive or negative (like {{{MO(+2)}}} or + {{{MO(-3)}}}. Not specifying it is the same as specifying {{{+1}}}. + You can also use an integer, where {{{0=MO}}}. Notice that, + for example, if the calculated date is already Monday, using + {{{MO}}} or {{{MO(+1)}}} (which is the same thing in this context), + won't change the day. + + leapdays:: + Will add given days to the date found, but only if the computed + year is a leap year and the computed date is post 28 of february. + + yearday, nlyearday:: + Set the yearday or the non-leap year day (jump leap days). + These are converted to {{{day}}}/{{{month}}}/{{{leapdays}}} + information. + +==== Behavior of operations ==== +If you're curious about exactly how the relative delta will act +on operations, here is a description of its behavior. + + 1. Calculate the absolute year, using the {{{year}}} argument, or the + original datetime year, if the argument is not present. + 1. Add the relative {{{years}}} argument to the absolute year. + 1. Do steps 1 and 2 for {{{month}}}/{{{months}}}. + 1. Calculate the absolute day, using the {{{day}}} argument, or the + original datetime day, if the argument is not present. Then, subtract + from the day until it fits in the year and month found after their + operations. + 1. Add the relative {{{days}}} argument to the absolute day. Notice + that the {{{weeks}}} argument is multiplied by 7 and added to {{{days}}}. + 1. If {{{leapdays}}} is present, the computed year is a leap year, and + the computed month is after february, remove one day from the found date. + 1. Do steps 1 and 2 for {{{hour}}}/{{{hours}}}, {{{minute}}}/{{{minutes}}}, + {{{second}}}/{{{seconds}}}, {{{microsecond}}}/{{{microseconds}}}. + 1. If the {{{weekday}}} argument is present, calculate the {{{n}}}th + occurrence of the given weekday. + +==== Examples ==== + +Let's begin our trip. +{{{ +>>> from datetime import *; from dateutil.relativedelta import * +>>> import calendar +}}} + +Store some values. +{{{ +>>> NOW = datetime.now() +>>> TODAY = date.today() +>>> NOW +datetime.datetime(2003, 9, 17, 20, 54, 47, 282310) +>>> TODAY +datetime.date(2003, 9, 17) +}}} + +Next month. +{{{ +>>> NOW+relativedelta(months=+1) +datetime.datetime(2003, 10, 17, 20, 54, 47, 282310) +}}} + +Next month, plus one week. +{{{ +>>> NOW+relativedelta(months=+1, weeks=+1) +datetime.datetime(2003, 10, 24, 20, 54, 47, 282310) +}}} + +Next month, plus one week, at 10am. +{{{ +>>> TODAY+relativedelta(months=+1, weeks=+1, hour=10) +datetime.datetime(2003, 10, 24, 10, 0) +}}} + +Let's try the other way around. Notice that the +hour setting we get in the relativedelta is relative, +since it's a difference, and the weeks parameter +has gone. +{{{ +>>> relativedelta(datetime(2003, 10, 24, 10, 0), TODAY) +relativedelta(months=+1, days=+7, hours=+10) +}}} + +One month before one year. +{{{ +>>> NOW+relativedelta(years=+1, months=-1) +datetime.datetime(2004, 8, 17, 20, 54, 47, 282310) +}}} + +How does it handle months with different numbers of days? +Notice that adding one month will never cross the month +boundary. +{{{ +>>> date(2003,1,27)+relativedelta(months=+1) +datetime.date(2003, 2, 27) +>>> date(2003,1,31)+relativedelta(months=+1) +datetime.date(2003, 2, 28) +>>> date(2003,1,31)+relativedelta(months=+2) +datetime.date(2003, 3, 31) +}}} + +The logic for years is the same, even on leap years. +{{{ +>>> date(2000,2,28)+relativedelta(years=+1) +datetime.date(2001, 2, 28) +>>> date(2000,2,29)+relativedelta(years=+1) +datetime.date(2001, 2, 28) + +>>> date(1999,2,28)+relativedelta(years=+1) +datetime.date(2000, 2, 28) +>>> date(1999,3,1)+relativedelta(years=+1) +datetime.date(2000, 3, 1) + +>>> date(2001,2,28)+relativedelta(years=-1) +datetime.date(2000, 2, 28) +>>> date(2001,3,1)+relativedelta(years=-1) +datetime.date(2000, 3, 1) +}}} + +Next friday. +{{{ +>>> TODAY+relativedelta(weekday=FR) +datetime.date(2003, 9, 19) + +>>> TODAY+relativedelta(weekday=calendar.FRIDAY) +datetime.date(2003, 9, 19) +}}} + +Last friday in this month. +{{{ +>>> TODAY+relativedelta(day=31, weekday=FR(-1)) +datetime.date(2003, 9, 26) +}}} + +Next wednesday (it's today!). +{{{ +>>> TODAY+relativedelta(weekday=WE(+1)) +datetime.date(2003, 9, 17) +}}} + +Next wednesday, but not today. +{{{ +>>> TODAY+relativedelta(days=+1, weekday=WE(+1)) +datetime.date(2003, 9, 24) +}}} + +Following +[http://www.cl.cam.ac.uk/~mgk25/iso-time.html ISO year week number notation] +find the first day of the 15th week of 1997. +{{{ +>>> datetime(1997,1,1)+relativedelta(day=4, weekday=MO(-1), weeks=+14) +datetime.datetime(1997, 4, 7, 0, 0) +}}} + +How long ago has the millennium changed? +{{{ +>>> relativedelta(NOW, date(2001,1,1)) +relativedelta(years=+2, months=+8, days=+16, + hours=+20, minutes=+54, seconds=+47, microseconds=+282310) +}}} + +How old is John? +{{{ +>>> johnbirthday = datetime(1978, 4, 5, 12, 0) +>>> relativedelta(NOW, johnbirthday) +relativedelta(years=+25, months=+5, days=+12, + hours=+8, minutes=+54, seconds=+47, microseconds=+282310) +}}} + +It works with dates too. +{{{ +>>> relativedelta(TODAY, johnbirthday) +relativedelta(years=+25, months=+5, days=+11, hours=+12) +}}} + +Obtain today's date using the yearday: +{{{ +>>> date(2003, 1, 1)+relativedelta(yearday=260) +datetime.date(2003, 9, 17) +}}} + +We can use today's date, since yearday should be absolute +in the given year: +{{{ +>>> TODAY+relativedelta(yearday=260) +datetime.date(2003, 9, 17) +}}} + +Last year it should be in the same day: +{{{ +>>> date(2002, 1, 1)+relativedelta(yearday=260) +datetime.date(2002, 9, 17) +}}} + +But not in a leap year: +{{{ +>>> date(2000, 1, 1)+relativedelta(yearday=260) +datetime.date(2000, 9, 16) +}}} + +We can use the non-leap year day to ignore this: +{{{ +>>> date(2000, 1, 1)+relativedelta(nlyearday=260) +datetime.date(2000, 9, 17) +}}} + +=== rrule === +The rrule module offers a small, complete, and very fast, implementation +of the recurrence rules documented in the +[ftp://ftp.rfc-editor.org/in-notes/rfc2445.txt iCalendar RFC], including +support for caching of results. + +==== rrule type ==== +That's the base of the rrule operation. It accepts all the keywords +defined in the RFC as its constructor parameters (except {{{byday}}}, +which was renamed to {{{byweekday}}}) and more. The constructor +prototype is: +{{{ +rrule(freq) +}}} + +Where {{{freq}}} must be one of {{{YEARLY}}}, {{{MONTHLY}}}, +{{{WEEKLY}}}, {{{DAILY}}}, {{{HOURLY}}}, {{{MINUTELY}}}, +or {{{SECONDLY}}}. + +Additionally, it supports the following keyword arguments: + + cache:: + If given, it must be a boolean value specifying to enable + or disable caching of results. If you will use the same + {{{rrule}}} instance multiple times, enabling caching will + improve the performance considerably. + + dtstart:: + The recurrence start. Besides being the base for the + recurrence, missing parameters in the final recurrence + instances will also be extracted from this date. If not + given, {{{datetime.now()}}} will be used instead. + + interval:: + The interval between each {{{freq}}} iteration. For example, + when using {{{YEARLY}}}, an interval of {{{2}}} means + once every two years, but with {{{HOURLY}}}, it means + once every two hours. The default interval is {{{1}}}. + + wkst:: + The week start day. Must be one of the {{{MO}}}, {{{TU}}}, + {{{WE}}} constants, or an integer, specifying the first day + of the week. This will affect recurrences based on weekly + periods. The default week start is got from + {{{calendar.firstweekday()}}}, and may be modified by + {{{calendar.setfirstweekday()}}}. + + count:: + How many occurrences will be generated. + + until:: + If given, this must be a {{{datetime}}} instance, that will + specify the limit of the recurrence. If a recurrence instance + happens to be the same as the {{{datetime}}} instance given + in the {{{until}}} keyword, this will be the last occurrence. + + bysetpos:: + If given, it must be either an integer, or a sequence of + integers, positive or negative. Each given integer will + specify an occurrence number, corresponding to the nth + occurrence of the rule inside the frequency period. For + example, a {{{bysetpos}}} of {{{-1}}} if combined with a + {{{MONTHLY}}} frequency, and a {{{byweekday}}} of + {{{(MO, TU, WE, TH, FR)}}}, will result in the last work + day of every month. + + bymonth:: + If given, it must be either an integer, or a sequence of + integers, meaning the months to apply the recurrence to. + + bymonthday:: + If given, it must be either an integer, or a sequence of + integers, meaning the month days to apply the recurrence to. + + byyearday:: + If given, it must be either an integer, or a sequence of + integers, meaning the year days to apply the recurrence to. + + byweekno:: + If given, it must be either an integer, or a sequence of + integers, meaning the week numbers to apply the recurrence + to. Week numbers have the meaning described in ISO8601, + that is, the first week of the year is that containing at + least four days of the new year. + + byweekday:: + If given, it must be either an integer ({{{0 == MO}}}), a + sequence of integers, one of the weekday constants + ({{{MO}}}, {{{TU}}}, etc), or a sequence of these constants. + When given, these variables will define the weekdays where + the recurrence will be applied. It's also possible to use + an argument {{{n}}} for the weekday instances, which will + mean the {{{n}}}''th'' occurrence of this weekday in the + period. For example, with {{{MONTHLY}}}, or with + {{{YEARLY}}} and {{{BYMONTH}}}, using {{{FR(+1)}}} + in {{{byweekday}}} will specify the first friday of the + month where the recurrence happens. Notice that in the RFC + documentation, this is specified as {{{BYDAY}}}, but was + renamed to avoid the ambiguity of that keyword. + + byhour:: + If given, it must be either an integer, or a sequence of + integers, meaning the hours to apply the recurrence to. + + byminute:: + If given, it must be either an integer, or a sequence of + integers, meaning the minutes to apply the recurrence to. + + bysecond:: + If given, it must be either an integer, or a sequence of + integers, meaning the seconds to apply the recurrence to. + + byeaster:: + If given, it must be either an integer, or a sequence of + integers, positive or negative. Each integer will define + an offset from the Easter Sunday. Passing the offset + {{{0}}} to {{{byeaster}}} will yield the Easter Sunday + itself. This is an extension to the RFC specification. + +==== rrule methods ==== +The following methods are available in {{{rrule}}} instances: + + rrule.before(dt, inc=False):: + Returns the last recurrence before the given {{{datetime}}} + instance. The {{{inc}}} keyword defines what happens if + {{{dt}}} '''is''' an occurrence. With {{{inc == True}}}, + if {{{dt}}} itself is an occurrence, it will be returned. + + rrule.after(dt, inc=False):: + Returns the first recurrence after the given {{{datetime}}} + instance. The {{{inc}}} keyword defines what happens if + {{{dt}}} '''is''' an occurrence. With {{{inc == True}}}, + if {{{dt}}} itself is an occurrence, it will be returned. + + rrule.between(after, before, inc=False):: + Returns all the occurrences of the rrule between {{{after}}} + and {{{before}}}. The {{{inc}}} keyword defines what happens + if {{{after}}} and/or {{{before}}} are themselves occurrences. + With {{{inc == True}}}, they will be included in the list, + if they are found in the recurrence set. + + rrule.count():: + Returns the number of recurrences in this set. It will have + go trough the whole recurrence, if this hasn't been done + before. + +Besides these methods, {{{rrule}}} instances also support +the {{{__getitem__()}}} and {{{__contains__()}}} special methods, +meaning that these are valid expressions: +{{{ +rr = rrule(...) +if datetime(...) in rr: + ... +print rr[0] +print rr[-1] +print rr[1:2] +print rr[::-2] +}}} + +The getitem/slicing mechanism is smart enough to avoid getting the whole +recurrence set, if possible. + +==== Notes ==== + + * The rrule type has no {{{byday}}} keyword. The equivalent keyword + has been replaced by the {{{byweekday}}} keyword, to remove the + ambiguity present in the original keyword. + + * Unlike documented in the RFC, the starting datetime ({{{dtstart}}}) + is not the first recurrence instance, unless it does fit in the + specified rules. In a python module context, this behavior makes more + sense than otherwise. Notice that you can easily get the original + behavior by using a rruleset and adding the {{{dtstart}}} as an + {{{rdate}}} recurrence. + + * Unlike documented in the RFC, every keyword is valid on every + frequency (the RFC documents that {{{byweekno}}} is only valid + on yearly frequencies, for example). + + * In addition to the documented keywords, a {{{byeaster}}} keyword + was introduced, making it easy to compute recurrent events relative + to the Easter Sunday. + +==== rrule examples ==== +These examples were converted from the RFC. + +Prepare the environment. +{{{ +>>> from dateutil.rrule import * +>>> from dateutil.parser import * +>>> from datetime import * + +>>> import pprint +>>> import sys +>>> sys.displayhook = pprint.pprint +}}} + +Daily, for 10 occurrences. +{{{ +>>> list(rrule(DAILY, count=10, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 3, 9, 0), + datetime.datetime(1997, 9, 4, 9, 0), + datetime.datetime(1997, 9, 5, 9, 0), + datetime.datetime(1997, 9, 6, 9, 0), + datetime.datetime(1997, 9, 7, 9, 0), + datetime.datetime(1997, 9, 8, 9, 0), + datetime.datetime(1997, 9, 9, 9, 0), + datetime.datetime(1997, 9, 10, 9, 0), + datetime.datetime(1997, 9, 11, 9, 0)] +}}} + +Daily until December 24, 1997 +{{{ +>>> list(rrule(DAILY, + dtstart=parse("19970902T090000"), + until=parse("19971224T000000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 3, 9, 0), + datetime.datetime(1997, 9, 4, 9, 0), + (...) + datetime.datetime(1997, 12, 21, 9, 0), + datetime.datetime(1997, 12, 22, 9, 0), + datetime.datetime(1997, 12, 23, 9, 0)] +}}} + +Every other day, 5 occurrences. +{{{ +>>> list(rrule(DAILY, interval=2, count=5, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 4, 9, 0), + datetime.datetime(1997, 9, 6, 9, 0), + datetime.datetime(1997, 9, 8, 9, 0), + datetime.datetime(1997, 9, 10, 9, 0)] +}}} + +Every 10 days, 5 occurrences. +{{{ +>>> list(rrule(DAILY, interval=10, count=5, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 12, 9, 0), + datetime.datetime(1997, 9, 22, 9, 0), + datetime.datetime(1997, 10, 2, 9, 0), + datetime.datetime(1997, 10, 12, 9, 0)] +}}} + +Everyday in January, for 3 years. +{{{ +>>> list(rrule(YEARLY, bymonth=1, byweekday=range(7), + dtstart=parse("19980101T090000"), + until=parse("20000131T090000"))) +[datetime.datetime(1998, 1, 1, 9, 0), + datetime.datetime(1998, 1, 2, 9, 0), + (...) + datetime.datetime(1998, 1, 30, 9, 0), + datetime.datetime(1998, 1, 31, 9, 0), + datetime.datetime(1999, 1, 1, 9, 0), + datetime.datetime(1999, 1, 2, 9, 0), + (...) + datetime.datetime(1999, 1, 30, 9, 0), + datetime.datetime(1999, 1, 31, 9, 0), + datetime.datetime(2000, 1, 1, 9, 0), + datetime.datetime(2000, 1, 2, 9, 0), + (...) + datetime.datetime(2000, 1, 29, 9, 0), + datetime.datetime(2000, 1, 31, 9, 0)] +}}} + +Same thing, in another way. +{{{ +>>> list(rrule(DAILY, bymonth=1, + dtstart=parse("19980101T090000"), + until=parse("20000131T090000"))) +(...) +}}} + +Weekly for 10 occurrences. +{{{ +>>> list(rrule(WEEKLY, count=10, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 9, 9, 0), + datetime.datetime(1997, 9, 16, 9, 0), + datetime.datetime(1997, 9, 23, 9, 0), + datetime.datetime(1997, 9, 30, 9, 0), + datetime.datetime(1997, 10, 7, 9, 0), + datetime.datetime(1997, 10, 14, 9, 0), + datetime.datetime(1997, 10, 21, 9, 0), + datetime.datetime(1997, 10, 28, 9, 0), + datetime.datetime(1997, 11, 4, 9, 0)] +}}} + +Every other week, 6 occurrences. +{{{ +>>> list(rrule(WEEKLY, interval=2, count=6, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 16, 9, 0), + datetime.datetime(1997, 9, 30, 9, 0), + datetime.datetime(1997, 10, 14, 9, 0), + datetime.datetime(1997, 10, 28, 9, 0), + datetime.datetime(1997, 11, 11, 9, 0)] +}}} + +Weekly on Tuesday and Thursday for 5 weeks. +{{{ +>>> list(rrule(WEEKLY, count=10, wkst=SU, byweekday=(TU,TH), + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 4, 9, 0), + datetime.datetime(1997, 9, 9, 9, 0), + datetime.datetime(1997, 9, 11, 9, 0), + datetime.datetime(1997, 9, 16, 9, 0), + datetime.datetime(1997, 9, 18, 9, 0), + datetime.datetime(1997, 9, 23, 9, 0), + datetime.datetime(1997, 9, 25, 9, 0), + datetime.datetime(1997, 9, 30, 9, 0), + datetime.datetime(1997, 10, 2, 9, 0)] +}}} + +Every other week on Tuesday and Thursday, for 8 occurrences. +{{{ +>>> list(rrule(WEEKLY, interval=2, count=8, + wkst=SU, byweekday=(TU,TH), + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 4, 9, 0), + datetime.datetime(1997, 9, 16, 9, 0), + datetime.datetime(1997, 9, 18, 9, 0), + datetime.datetime(1997, 9, 30, 9, 0), + datetime.datetime(1997, 10, 2, 9, 0), + datetime.datetime(1997, 10, 14, 9, 0), + datetime.datetime(1997, 10, 16, 9, 0)] +}}} + +Monthly on the 1st Friday for ten occurrences. +{{{ +>>> list(rrule(MONTHLY, count=10, byweekday=FR(1), + dtstart=parse("19970905T090000"))) +[datetime.datetime(1997, 9, 5, 9, 0), + datetime.datetime(1997, 10, 3, 9, 0), + datetime.datetime(1997, 11, 7, 9, 0), + datetime.datetime(1997, 12, 5, 9, 0), + datetime.datetime(1998, 1, 2, 9, 0), + datetime.datetime(1998, 2, 6, 9, 0), + datetime.datetime(1998, 3, 6, 9, 0), + datetime.datetime(1998, 4, 3, 9, 0), + datetime.datetime(1998, 5, 1, 9, 0), + datetime.datetime(1998, 6, 5, 9, 0)] +}}} + +Every other month on the 1st and last Sunday of the month for 10 occurrences. +{{{ +>>> list(rrule(MONTHLY, interval=2, count=10, + byweekday=(SU(1), SU(-1)), + dtstart=parse("19970907T090000"))) +[datetime.datetime(1997, 9, 7, 9, 0), + datetime.datetime(1997, 9, 28, 9, 0), + datetime.datetime(1997, 11, 2, 9, 0), + datetime.datetime(1997, 11, 30, 9, 0), + datetime.datetime(1998, 1, 4, 9, 0), + datetime.datetime(1998, 1, 25, 9, 0), + datetime.datetime(1998, 3, 1, 9, 0), + datetime.datetime(1998, 3, 29, 9, 0), + datetime.datetime(1998, 5, 3, 9, 0), + datetime.datetime(1998, 5, 31, 9, 0)] +}}} + +Monthly on the second to last Monday of the month for 6 months. +{{{ +>>> list(rrule(MONTHLY, count=6, byweekday=MO(-2), + dtstart=parse("19970922T090000"))) +[datetime.datetime(1997, 9, 22, 9, 0), + datetime.datetime(1997, 10, 20, 9, 0), + datetime.datetime(1997, 11, 17, 9, 0), + datetime.datetime(1997, 12, 22, 9, 0), + datetime.datetime(1998, 1, 19, 9, 0), + datetime.datetime(1998, 2, 16, 9, 0)] +}}} + +Monthly on the third to the last day of the month, for 6 months. +{{{ +>>> list(rrule(MONTHLY, count=6, bymonthday=-3, + dtstart=parse("19970928T090000"))) +[datetime.datetime(1997, 9, 28, 9, 0), + datetime.datetime(1997, 10, 29, 9, 0), + datetime.datetime(1997, 11, 28, 9, 0), + datetime.datetime(1997, 12, 29, 9, 0), + datetime.datetime(1998, 1, 29, 9, 0), + datetime.datetime(1998, 2, 26, 9, 0)] +}}} + +Monthly on the 2nd and 15th of the month for 5 occurrences. +{{{ +>>> list(rrule(MONTHLY, count=5, bymonthday=(2,15), + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 15, 9, 0), + datetime.datetime(1997, 10, 2, 9, 0), + datetime.datetime(1997, 10, 15, 9, 0), + datetime.datetime(1997, 11, 2, 9, 0)] +}}} + +Monthly on the first and last day of the month for 3 occurrences. +{{{ +>>> list(rrule(MONTHLY, count=5, bymonthday=(-1,1,), + dtstart=parse("1997090 +2T090000"))) +[datetime.datetime(1997, 9, 30, 9, 0), + datetime.datetime(1997, 10, 1, 9, 0), + datetime.datetime(1997, 10, 31, 9, 0), + datetime.datetime(1997, 11, 1, 9, 0), + datetime.datetime(1997, 11, 30, 9, 0)] +}}} + +Every 18 months on the 10th thru 15th of the month for 10 occurrences. +{{{ +>>> list(rrule(MONTHLY, interval=18, count=10, + bymonthday=range(10,16), + dtstart=parse("19970910T090000"))) +[datetime.datetime(1997, 9, 10, 9, 0), + datetime.datetime(1997, 9, 11, 9, 0), + datetime.datetime(1997, 9, 12, 9, 0), + datetime.datetime(1997, 9, 13, 9, 0), + datetime.datetime(1997, 9, 14, 9, 0), + datetime.datetime(1997, 9, 15, 9, 0), + datetime.datetime(1999, 3, 10, 9, 0), + datetime.datetime(1999, 3, 11, 9, 0), + datetime.datetime(1999, 3, 12, 9, 0), + datetime.datetime(1999, 3, 13, 9, 0)] +}}} + +Every Tuesday, every other month, 6 occurences. +{{{ +>>> list(rrule(MONTHLY, interval=2, count=6, byweekday=TU, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 9, 9, 0), + datetime.datetime(1997, 9, 16, 9, 0), + datetime.datetime(1997, 9, 23, 9, 0), + datetime.datetime(1997, 9, 30, 9, 0), + datetime.datetime(1997, 11, 4, 9, 0)] +}}} + +Yearly in June and July for 10 occurrences. +{{{ +>>> list(rrule(YEARLY, count=4, bymonth=(6,7), + dtstart=parse("19970610T0900 +00"))) +[datetime.datetime(1997, 6, 10, 9, 0), + datetime.datetime(1997, 7, 10, 9, 0), + datetime.datetime(1998, 6, 10, 9, 0), + datetime.datetime(1998, 7, 10, 9, 0)] +}}} + +Every 3rd year on the 1st, 100th and 200th day for 4 occurrences. +{{{ +>>> list(rrule(YEARLY, count=4, interval=3, byyearday=(1,100,200), + dtstart=parse("19970101T090000"))) +[datetime.datetime(1997, 1, 1, 9, 0), + datetime.datetime(1997, 4, 10, 9, 0), + datetime.datetime(1997, 7, 19, 9, 0), + datetime.datetime(2000, 1, 1, 9, 0)] +}}} + +Every 20th Monday of the year, 3 occurrences. +{{{ +>>> list(rrule(YEARLY, count=3, byweekday=MO(20), + dtstart=parse("19970519T090000"))) +[datetime.datetime(1997, 5, 19, 9, 0), + datetime.datetime(1998, 5, 18, 9, 0), + datetime.datetime(1999, 5, 17, 9, 0)] +}}} + +Monday of week number 20 (where the default start of the week is Monday), +3 occurrences. +{{{ +>>> list(rrule(YEARLY, count=3, byweekno=20, byweekday=MO, + dtstart=parse("19970512T090000"))) +[datetime.datetime(1997, 5, 12, 9, 0), + datetime.datetime(1998, 5, 11, 9, 0), + datetime.datetime(1999, 5, 17, 9, 0)] +}}} + +The week number 1 may be in the last year. +{{{ +>>> list(rrule(WEEKLY, count=3, byweekno=1, byweekday=MO, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 12, 29, 9, 0), + datetime.datetime(1999, 1, 4, 9, 0), + datetime.datetime(2000, 1, 3, 9, 0)] +}}} + +And the week numbers greater than 51 may be in the next year. +{{{ +>>> list(rrule(WEEKLY, count=3, byweekno=52, byweekday=SU, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 12, 28, 9, 0), + datetime.datetime(1998, 12, 27, 9, 0), + datetime.datetime(2000, 1, 2, 9, 0)] +}}} + +Only some years have week number 53: +{{{ +>>> list(rrule(WEEKLY, count=3, byweekno=53, byweekday=MO, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1998, 12, 28, 9, 0), + datetime.datetime(2004, 12, 27, 9, 0), + datetime.datetime(2009, 12, 28, 9, 0)] +}}} + +Every Friday the 13th, 4 occurrences. +{{{ +>>> list(rrule(YEARLY, count=4, byweekday=FR, bymonthday=13, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1998, 2, 13, 9, 0), + datetime.datetime(1998, 3, 13, 9, 0), + datetime.datetime(1998, 11, 13, 9, 0), + datetime.datetime(1999, 8, 13, 9, 0)] +}}} + +Every four years, the first Tuesday after a Monday in November, +3 occurrences (U.S. Presidential Election day): +{{{ +>>> list(rrule(YEARLY, interval=4, count=3, bymonth=11, + byweekday=TU, bymonthday=(2,3,4,5,6,7,8), + dtstart=parse("19961105T090000"))) +[datetime.datetime(1996, 11, 5, 9, 0), + datetime.datetime(2000, 11, 7, 9, 0), + datetime.datetime(2004, 11, 2, 9, 0)] +}}} + +The 3rd instance into the month of one of Tuesday, Wednesday or +Thursday, for the next 3 months: +{{{ +>>> list(rrule(MONTHLY, count=3, byweekday=(TU,WE,TH), + bysetpos=3, dtstart=parse("19970904T090000"))) +[datetime.datetime(1997, 9, 4, 9, 0), + datetime.datetime(1997, 10, 7, 9, 0), + datetime.datetime(1997, 11, 6, 9, 0)] +}}} + +The 2nd to last weekday of the month, 3 occurrences. +{{{ +>>> list(rrule(MONTHLY, count=3, byweekday=(MO,TU,WE,TH,FR), + bysetpos=-2, dtstart=parse("19970929T090000"))) +[datetime.datetime(1997, 9, 29, 9, 0), + datetime.datetime(1997, 10, 30, 9, 0), + datetime.datetime(1997, 11, 27, 9, 0)] +}}} + +Every 3 hours from 9:00 AM to 5:00 PM on a specific day. +{{{ +>>> list(rrule(HOURLY, interval=3, + dtstart=parse("19970902T090000"), + until=parse("19970902T170000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 2, 12, 0), + datetime.datetime(1997, 9, 2, 15, 0)] +}}} + +Every 15 minutes for 6 occurrences. +{{{ +>>> list(rrule(MINUTELY, interval=15, count=6, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 2, 9, 15), + datetime.datetime(1997, 9, 2, 9, 30), + datetime.datetime(1997, 9, 2, 9, 45), + datetime.datetime(1997, 9, 2, 10, 0), + datetime.datetime(1997, 9, 2, 10, 15)] +}}} + +Every hour and a half for 4 occurrences. +{{{ +>>> list(rrule(MINUTELY, interval=90, count=4, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 2, 10, 30), + datetime.datetime(1997, 9, 2, 12, 0), + datetime.datetime(1997, 9, 2, 13, 30)] +}}} + +Every 20 minutes from 9:00 AM to 4:40 PM for two days. +{{{ +>>> list(rrule(MINUTELY, interval=20, count=48, + byhour=range(9,17), byminute=(0,20,40), + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 2, 9, 20), + (...) + datetime.datetime(1997, 9, 2, 16, 20), + datetime.datetime(1997, 9, 2, 16, 40), + datetime.datetime(1997, 9, 3, 9, 0), + datetime.datetime(1997, 9, 3, 9, 20), + (...) + datetime.datetime(1997, 9, 3, 16, 20), + datetime.datetime(1997, 9, 3, 16, 40)] +}}} + +An example where the days generated makes a difference because of {{{wkst}}}. +{{{ +>>> list(rrule(WEEKLY, interval=2, count=4, + byweekday=(TU,SU), wkst=MO, + dtstart=parse("19970805T090000"))) +[datetime.datetime(1997, 8, 5, 9, 0), + datetime.datetime(1997, 8, 10, 9, 0), + datetime.datetime(1997, 8, 19, 9, 0), + datetime.datetime(1997, 8, 24, 9, 0)] + +>>> list(rrule(WEEKLY, interval=2, count=4, + byweekday=(TU,SU), wkst=SU, + dtstart=parse("19970805T090000"))) +[datetime.datetime(1997, 8, 5, 9, 0), + datetime.datetime(1997, 8, 17, 9, 0), + datetime.datetime(1997, 8, 19, 9, 0), + datetime.datetime(1997, 8, 31, 9, 0)] +}}} + +==== rruleset type ==== +The {{{rruleset}}} type allows more complex recurrence setups, mixing +multiple rules, dates, exclusion rules, and exclusion dates. +The type constructor takes the following keyword arguments: + + cache:: + If True, caching of results will be enabled, improving performance + of multiple queries considerably. + +==== rruleset methods ==== +The following methods are available: + + rruleset.rrule(rrule):: + Include the given {{{rrule}}} instance in the recurrence set + generation. + + rruleset.rdate(dt):: + Include the given {{{datetime}}} instance in the recurrence + set generation. + + rruleset.exrule(rrule):: + Include the given {{{rrule}}} instance in the recurrence set + exclusion list. Dates which are part of the given recurrence + rules will not be generated, even if some inclusive {{{rrule}}} + or {{{rdate}}} matches them. + + rruleset.exdate(dt):: + Include the given {{{datetime}}} instance in the recurrence set + exclusion list. Dates included that way will not be generated, + even if some inclusive {{{rrule}}} or {{{rdate}}} matches them. + + rruleset.before(dt, inc=False):: + Returns the last recurrence before the given {{{datetime}}} + instance. The {{{inc}}} keyword defines what happens if + {{{dt}}} '''is''' an occurrence. With {{{inc == True}}}, + if {{{dt}}} itself is an occurrence, it will be returned. + + rruleset.after(dt, inc=False):: + Returns the first recurrence after the given {{{datetime}}} + instance. The {{{inc}}} keyword defines what happens if + {{{dt}}} '''is''' an occurrence. With {{{inc == True}}}, + if {{{dt}}} itself is an occurrence, it will be returned. + + rruleset.between(after, before, inc=False):: + Returns all the occurrences of the rrule between {{{after}}} + and {{{before}}}. The {{{inc}}} keyword defines what happens + if {{{after}}} and/or {{{before}}} are themselves occurrences. + With {{{inc == True}}}, they will be included in the list, + if they are found in the recurrence set. + + rruleset.count():: + Returns the number of recurrences in this set. It will have + go trough the whole recurrence, if this hasn't been done + before. + +Besides these methods, {{{rruleset}}} instances also support +the {{{__getitem__()}}} and {{{__contains__()}}} special methods, +meaning that these are valid expressions: +{{{ +set = rruleset(...) +if datetime(...) in set: + ... +print set[0] +print set[-1] +print set[1:2] +print set[::-2] +}}} + +The getitem/slicing mechanism is smart enough to avoid getting the whole +recurrence set, if possible. + +==== rruleset examples ==== +Daily, for 7 days, jumping Saturday and Sunday occurrences. +{{{ +>>> set = rruleset() +>>> set.rrule(rrule(DAILY, count=7, + dtstart=parse("19970902T090000"))) +>>> set.exrule(rrule(YEARLY, byweekday=(SA,SU), + dtstart=parse("19970902T090000"))) +>>> list(set) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 3, 9, 0), + datetime.datetime(1997, 9, 4, 9, 0), + datetime.datetime(1997, 9, 5, 9, 0), + datetime.datetime(1997, 9, 8, 9, 0)] +}}} + +Weekly, for 4 weeks, plus one time on day 7, and not on day 16. +{{{ +>>> set = rruleset() +>>> set.rrule(rrule(WEEKLY, count=4, + dtstart=parse("19970902T090000"))) +>>> set.rdate(datetime.datetime(1997, 9, 7, 9, 0)) +>>> set.exdate(datetime.datetime(1997, 9, 16, 9, 0)) +>>> list(set) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 7, 9, 0), + datetime.datetime(1997, 9, 9, 9, 0), + datetime.datetime(1997, 9, 23, 9, 0)] +}}} + +==== rrulestr() function ==== +The {{{rrulestr()}}} function is a parser for ''RFC-like'' syntaxes. +The function prototype is: +{{{ +rrulestr(str) +}}} + +The string passed as parameter may be a multiple line string, a +single line string, or just the {{{RRULE}}} property value. + +Additionally, it accepts the following keyword arguments: + + cache:: + If {{{True}}}, the {{{rruleset}}} or {{{rrule}}} created instance + will cache its results. Default is not to cache. + + dtstart:: + If given, it must be a {{{datetime}}} instance that will be used + when no {{{DTSTART}}} property is found in the parsed string. If + it is not given, and the property is not found, {{{datetime.now()}}} + will be used instead. + + unfold:: + If set to {{{True}}}, lines will be unfolded following the RFC + specification. It defaults to {{{False}}}, meaning that spaces + before every line will be stripped. + + forceset:: + If set to {{{True}}} a {{{rruleset}}} instance will be returned, + even if only a single rule is found. The default is to return an + {{{rrule}}} if possible, and an {{{rruleset}}} if necessary. + + compatible:: + If set to {{{True}}}, the parser will operate in RFC-compatible + mode. Right now it means that {{{unfold}}} will be turned on, + and if a {{{DTSTART}}} is found, it will be considered the first + recurrence instance, as documented in the RFC. + + ignoretz:: + If set to {{{True}}}, the date parser will ignore timezone + information available in the {{{DTSTART}}} property, or the + {{{UNTIL}}} attribute. + + tzinfos:: + If set, it will be passed to the datetime string parser to + resolve unknown timezone settings. For more information about + what could be used here, check the parser documentation. + +==== rrulestr() examples ==== + +Every 10 days, 5 occurrences. +{{{ +>>> list(rrulestr(""" +... DTSTART:19970902T090000 +... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5 +... """)) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 12, 9, 0), + datetime.datetime(1997, 9, 22, 9, 0), + datetime.datetime(1997, 10, 2, 9, 0), + datetime.datetime(1997, 10, 12, 9, 0)] +}}} + +Same thing, but passing only the {{{RRULE}}} value. +{{{ +>>> list(rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5", + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 12, 9, 0), + datetime.datetime(1997, 9, 22, 9, 0), + datetime.datetime(1997, 10, 2, 9, 0), + datetime.datetime(1997, 10, 12, 9, 0)] +}}} + +Notice that when using a single rule, it returns an +{{{rrule}}} instance, unless {{{forceset}}} was used. +{{{ +>>> rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5") + + +>>> rrulestr(""" +... DTSTART:19970902T090000 +... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5 +... """) + + +>>> rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5", forceset=True) + +}}} + +But when an {{{rruleset}}} is needed, it is automatically used. +{{{ +>>> rrulestr(""" +... DTSTART:19970902T090000 +... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5 +... RRULE:FREQ=DAILY;INTERVAL=5;COUNT=3 +... """) + +}}} + +=== parser === +This module offers a generic date/time string parser which is +able to parse most known formats to represent a date and/or +time. + +==== parse() function ==== +That's probably the only function you'll need from this module. +It offers you an interface to access the parser functionality and +extract a {{{datetime}}} type out of a string. + +The prototype of this function is: +{{{ +parse(timestr) +}}} + +Additionally, the following keyword arguments are available: + + default:: + If given, this must be a {{{datetime}}} instance. Any fields + missing in the parsed date will be copied from this instance. + The default value is the current date, at 00:00:00am. + + ignoretz:: + If this is true, even if a timezone is found in the string, + the parser will not use it. + + tzinfos:: + Using this keyword argument you may provide custom timezones + to the parser. If given, it must be either a dictionary with + the timezone abbreviation as key, or a function accepting a + timezone abbreviation and offset as argument. The dictionary + values and the function return must be a timezone offset + in seconds, a tzinfo subclass, or a string defining the + timezone (in the TZ environment variable format). + + dayfirst:: + This option allow one to change the precedence in which + days are parsed in date strings. The default is given in the + parserinfo instance (the default parserinfo has it set to + False). If {{{dayfirst}}} is False, the {{{MM-DD-YYYY}}} + format will have precedence over {{{DD-MM-YYYY}}} in an + ambiguous date. + + yearfirst:: + This option allow one to change the precedence in which + years are parsed in date strings. The default is given in + the parserinfo instance (the default parserinfo has it set + to False). If {{{yearfirst}}} is false, the {{{MM-DD-YY}}} + format will have precedence over {{{YY-MM-DD}}} in an + ambiguous date. + + fuzzy:: + If {{{fuzzy}}} is set to True, unknown tokens in the string + will be ignored. + + parserinfo:: + This parameter allows one to change how the string is parsed, + by using a different parserinfo class instance. Using it you + may, for example, intenationalize the parser strings, or make + it ignore additional words. + +==== Format precedence ==== +Whenever an ambiguous date is found, the {{{dayfirst}}} and +{{{yearfirst}}} parameters will control how the information +is processed. Here is the precedence in each case: + +If {{{dayfirst}}} is {{{False}}} and {{{yearfirst}}} is {{{False}}}, +(default, if no parameter is given): + + * {{{MM-DD-YY}}} + * {{{DD-MM-YY}}} + * {{{YY-MM-DD}}} + +If {{{dayfirst}}} is {{{True}}} and {{{yearfirst}}} is {{{False}}}: + + * {{{DD-MM-YY}}} + * {{{MM-DD-YY}}} + * {{{YY-MM-DD}}} + +If {{{dayfirst}}} is {{{False}}} and {{{yearfirst}}} is {{{True}}}: + + * {{{YY-MM-DD}}} + * {{{MM-DD-YY}}} + * {{{DD-MM-YY}}} + +If {{{dayfirst}}} is {{{True}}} and {{{yearfirst}}} is {{{True}}}: + + * {{{YY-MM-DD}}} + * {{{DD-MM-YY}}} + * {{{MM-DD-YY}}} + +==== Converting two digit years ==== +When a two digit year is found, it is processed considering +the current year, so that the computed year is never more +than 49 years after the current year, nor 50 years before the +current year. In other words, if we are in year 2003, and the +year 30 is found, it will be considered as 2030, but if the +year 60 is found, it will be considered 1960. + +==== Examples ==== +The following code will prepare the environment: +{{{ +>>> from dateutil.parser import * +>>> from dateutil.tz import * +>>> from datetime import * +>>> TZOFFSETS = {"BRST": -10800} +>>> BRSTTZ = tzoffset(-10800, "BRST") +>>> DEFAULT = datetime(2003, 9, 25) +}}} + +Some simple examples based on the {{{date}}} command, using the +{{{TZOFFSET}}} dictionary to provide the BRST timezone offset. +{{{ +>>> parse("Thu Sep 25 10:36:28 BRST 2003", tzinfos=TZOFFSETS) +datetime.datetime(2003, 9, 25, 10, 36, 28, + tzinfo=tzoffset('BRST', -10800)) + +>>> parse("2003 10:36:28 BRST 25 Sep Thu", tzinfos=TZOFFSETS) +datetime.datetime(2003, 9, 25, 10, 36, 28, + tzinfo=tzoffset('BRST', -10800)) +}}} + +Notice that since BRST is my local timezone, parsing it without +further timezone settings will yield a {{{tzlocal}}} timezone. +{{{ +>>> parse("Thu Sep 25 10:36:28 BRST 2003") +datetime.datetime(2003, 9, 25, 10, 36, 28, tzinfo=tzlocal()) +}}} + +We can also ask to ignore the timezone explicitly: +{{{ +>>> parse("Thu Sep 25 10:36:28 BRST 2003", ignoretz=True) +datetime.datetime(2003, 9, 25, 10, 36, 28) +}}} + +That's the same as processing a string without timezone: +{{{ +>>> parse("Thu Sep 25 10:36:28 2003") +datetime.datetime(2003, 9, 25, 10, 36, 28) +}}} + +Without the year, but passing our {{{DEFAULT}}} datetime to return +the same year, no mattering what year we currently are in: +{{{ +>>> parse("Thu Sep 25 10:36:28", default=DEFAULT) +datetime.datetime(2003, 9, 25, 10, 36, 28) +}}} + +Strip it further: +{{{ +>>> parse("Thu Sep 10:36:28", default=DEFAULT) +datetime.datetime(2003, 9, 25, 10, 36, 28) + +>>> parse("Thu 10:36:28", default=DEFAULT) +datetime.datetime(2003, 9, 25, 10, 36, 28) + +>>> parse("Thu 10:36", default=DEFAULT) +datetime.datetime(2003, 9, 25, 10, 36) + +>>> parse("10:36", default=DEFAULT) +datetime.datetime(2003, 9, 25, 10, 36) +>>> +}}} + +Strip in a different way: +{{{ +>>> parse("Thu Sep 25 2003") +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("Sep 25 2003") +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("Sep 2003", default=DEFAULT) +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("Sep", default=DEFAULT) +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("2003", default=DEFAULT) +datetime.datetime(2003, 9, 25, 0, 0) +}}} + +Another format, based on {{{date -R}}} (RFC822): +{{{ +>>> parse("Thu, 25 Sep 2003 10:49:41 -0300") +datetime.datetime(2003, 9, 25, 10, 49, 41, + tzinfo=tzoffset(None, -10800)) +}}} + +ISO format: +{{{ +>>> parse("2003-09-25T10:49:41.5-03:00") +datetime.datetime(2003, 9, 25, 10, 49, 41, 500000, + tzinfo=tzoffset(None, -10800)) +}}} + +Some variations: +{{{ +>>> parse("2003-09-25T10:49:41") +datetime.datetime(2003, 9, 25, 10, 49, 41) + +>>> parse("2003-09-25T10:49") +datetime.datetime(2003, 9, 25, 10, 49) + +>>> parse("2003-09-25T10") +datetime.datetime(2003, 9, 25, 10, 0) + +>>> parse("2003-09-25") +datetime.datetime(2003, 9, 25, 0, 0) +}}} + +ISO format, without separators: +{{{ +>>> parse("20030925T104941.5-0300") +datetime.datetime(2003, 9, 25, 10, 49, 41, 500000, + tzinfo=tzinfo=tzoffset(None, -10800)) + +>>> parse("20030925T104941-0300") +datetime.datetime(2003, 9, 25, 10, 49, 41, + tzinfo=tzoffset(None, -10800)) + +>>> parse("20030925T104941") +datetime.datetime(2003, 9, 25, 10, 49, 41) + +>>> parse("20030925T1049") +datetime.datetime(2003, 9, 25, 10, 49) + +>>> parse("20030925T10") +datetime.datetime(2003, 9, 25, 10, 0) + +>>> parse("20030925") +datetime.datetime(2003, 9, 25, 0, 0) +}}} + +Everything together. +{{{ +>>> parse("199709020900") +datetime.datetime(1997, 9, 2, 9, 0) +>>> parse("19970902090059") +datetime.datetime(1997, 9, 2, 9, 0, 59) +}}} + +Different date orderings: +{{{ +>>> parse("2003-09-25") +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("2003-Sep-25") +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("25-Sep-2003") +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("Sep-25-2003") +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("09-25-2003") +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("25-09-2003") +datetime.datetime(2003, 9, 25, 0, 0) +}}} + +Check some ambiguous dates: +{{{ +>>> parse("10-09-2003") +datetime.datetime(2003, 10, 9, 0, 0) + +>>> parse("10-09-2003", dayfirst=True) +datetime.datetime(2003, 9, 10, 0, 0) + +>>> parse("10-09-03") +datetime.datetime(2003, 10, 9, 0, 0) + +>>> parse("10-09-03", yearfirst=True) +datetime.datetime(2010, 9, 3, 0, 0) +}}} + +Other date separators are allowed: +{{{ +>>> parse("2003.Sep.25") +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("2003/09/25") +datetime.datetime(2003, 9, 25, 0, 0) +}}} + +Even with spaces: +{{{ +>>> parse("2003 Sep 25") +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("2003 09 25") +datetime.datetime(2003, 9, 25, 0, 0) +}}} + +Hours with letters work: +{{{ +>>> parse("10h36m28.5s", default=DEFAULT) +datetime.datetime(2003, 9, 25, 10, 36, 28, 500000) + +>>> parse("01s02h03m", default=DEFAULT) +datetime.datetime(2003, 9, 25, 2, 3, 1) + +>>> parse("01h02m03", default=DEFAULT) +datetime.datetime(2003, 9, 3, 1, 2) + +>>> parse("01h02", default=DEFAULT) +datetime.datetime(2003, 9, 2, 1, 0) + +>>> parse("01h02s", default=DEFAULT) +datetime.datetime(2003, 9, 25, 1, 0, 2) +}}} + +With AM/PM: +{{{ +>>> parse("10h am", default=DEFAULT) +datetime.datetime(2003, 9, 25, 10, 0) + +>>> parse("10pm", default=DEFAULT) +datetime.datetime(2003, 9, 25, 22, 0) + +>>> parse("12:00am", default=DEFAULT) +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("12pm", default=DEFAULT) +datetime.datetime(2003, 9, 25, 12, 0) +}}} + +Some special treating for ''pertain'' relations: +{{{ +>>> parse("Sep 03", default=DEFAULT) +datetime.datetime(2003, 9, 3, 0, 0) + +>>> parse("Sep of 03", default=DEFAULT) +datetime.datetime(2003, 9, 25, 0, 0) +}}} + +Fuzzy parsing: +{{{ +>>> s = "Today is 25 of September of 2003, exactly " \ +... "at 10:49:41 with timezone -03:00." +>>> parse(s, fuzzy=True) +datetime.datetime(2003, 9, 25, 10, 49, 41, + tzinfo=tzoffset(None, -10800)) +}}} + +Other random formats: +{{{ +>>> parse("Wed, July 10, '96") +datetime.datetime(1996, 7, 10, 0, 0) + +>>> parse("1996.07.10 AD at 15:08:56 PDT", ignoretz=True) +datetime.datetime(1996, 7, 10, 15, 8, 56) + +>>> parse("Tuesday, April 12, 1952 AD 3:30:42pm PST", ignoretz=True) +datetime.datetime(1952, 4, 12, 15, 30, 42) + +>>> parse("November 5, 1994, 8:15:30 am EST", ignoretz=True) +datetime.datetime(1994, 11, 5, 8, 15, 30) + +>>> parse("3rd of May 2001") +datetime.datetime(2001, 5, 3, 0, 0) + +>>> parse("5:50 A.M. on June 13, 1990") +datetime.datetime(1990, 6, 13, 5, 50) +}}} + +=== easter === +This module offers a generic easter computing method for +any given year, using Western, Orthodox or Julian algorithms. + +==== easter() function ==== +This method was ported from the work done by +[http://users.chariot.net.au/~gmarts/eastalg.htm GM Arts], +on top of the algorithm by +[http://www.tondering.dk/claus/calendar.html Claus Tondering], +which was based in part on the algorithm of Ouding (1940), +as quoted in "Explanatory Supplement to the Astronomical +Almanac", P. Kenneth Seidelmann, editor. + +This algorithm implements three different easter +calculation methods: + + 1. Original calculation in Julian calendar, valid in + dates after 326 AD + 1. Original method, with date converted to Gregorian + calendar, valid in years 1583 to 4099 + 1. Revised method, in Gregorian calendar, valid in + years 1583 to 4099 as well + +These methods are represented by the constants: +{{{ +EASTER_JULIAN = 1 +EASTER_ORTHODOX = 2 +EASTER_WESTERN = 3 +}}} + +The default method is method 3. + +=== tz === +This module offers timezone implementations subclassing +the abstract {{{datetime.tzinfo}}} type. There are +classes to handle [http://www.twinsun.com/tz/tz-link.htm tzfile] +format files (usually are in /etc/localtime, +/usr/share/zoneinfo, etc), TZ environment string (in all +known formats), given ranges (with help from relative +deltas), local machine timezone, fixed offset timezone, +and UTC timezone. + +==== tzutc type ==== +This type implements a basic UTC timezone. The constructor of this +type accepts no parameters. + +==== tzutc examples ==== +{{{ +>>> from datetime import * +>>> from dateutil.tz import * + +>>> datetime.now() +datetime.datetime(2003, 9, 27, 9, 40, 1, 521290) + +>>> datetime.now(tzutc()) +datetime.datetime(2003, 9, 27, 12, 40, 12, 156379, tzinfo=tzutc()) + +>>> datetime.now(tzutc()).tzname() +'UTC' +}}} + +==== tzoffset type ==== +This type implements a fixed offset timezone, with no +support to daylight saving times. Here is the prototype of the +type constructor: +{{{ +tzoffset(name, offset) +}}} + +The {{{name}}} parameter may be optionally set to {{{None}}}, and +{{{offset}}} must be given in seconds. + +==== tzoffset examples ==== +{{{ +>>> from datetime import * +>>> from dateutil.tz import * + +>>> datetime.now(tzoffset("BRST", -10800)) +datetime.datetime(2003, 9, 27, 9, 52, 43, 624904, + tzinfo=tzinfo=tzoffset('BRST', -10800)) + +>>> datetime.now(tzoffset("BRST", -10800)).tzname() +'BRST' + +>>> datetime.now(tzoffset("BRST", -10800)).astimezone(tzutc()) +datetime.datetime(2003, 9, 27, 12, 53, 11, 446419, + tzinfo=tzutc()) +}}} + +==== tzlocal type ==== +This type implements timezone settings as known by the +operating system. The constructor of this type accepts no +parameters. + +==== tzlocal examples ==== +{{{ +>>> from datetime import * +>>> from dateutil.tz import * + +>>> datetime.now(tzlocal()) +datetime.datetime(2003, 9, 27, 10, 1, 43, 673605, + tzinfo=tzlocal()) + +>>> datetime.now(tzlocal()).tzname() +'BRST' + +>>> datetime.now(tzlocal()).astimezone(tzoffset(None, 0)) +datetime.datetime(2003, 9, 27, 13, 3, 0, 11493, + tzinfo=tzoffset(None, 0)) +}}} + +==== tzstr type ==== +This type implements timezone settings extracted from a +string in known TZ environment variable formats. Here is the prototype +of the constructor: +{{{ +tzstr(str) +}}} + +==== tzstr examples ==== +Here are examples of the recognized formats: + + * {{{EST5EDT}}} + * {{{EST5EDT,4,0,6,7200,10,0,26,7200,3600}}} + * {{{EST5EDT,4,1,0,7200,10,-1,0,7200,3600}}} + * {{{EST5EDT4,M4.1.0/02:00:00,M10-5-0/02:00}}} + * {{{EST5EDT4,95/02:00:00,298/02:00}}} + * {{{EST5EDT4,J96/02:00:00,J299/02:00}}} + +Notice that if daylight information is not present, but a +daylight abbreviation was provided, {{{tzstr}}} will follow the +convention of using the first sunday of April to start daylight +saving, and the last sunday of October to end it. If start or +end time is not present, 2AM will be used, and if the daylight +offset is not present, the standard offset plus one hour will +be used. This convention is the same as used in the GNU libc. + +This also means that some of the above examples are exactly +equivalent, and all of these examples are equivalent +in the year of 2003. + +Here is the example mentioned in the +[http://www.python.org/doc/current/lib/module-time.html time module documentation]. +{{{ +>>> os.environ['TZ'] = 'EST+05EDT,M4.1.0,M10.5.0' +>>> time.tzset() +>>> time.strftime('%X %x %Z') +'02:07:36 05/08/03 EDT' +>>> os.environ['TZ'] = 'AEST-10AEDT-11,M10.5.0,M3.5.0' +>>> time.tzset() +>>> time.strftime('%X %x %Z') +'16:08:12 05/08/03 AEST' +}}} + +And here is an example showing the same information using {{{tzstr}}}, +without touching system settings. +{{{ +>>> tz1 = tzstr('EST+05EDT,M4.1.0,M10.5.0') +>>> tz2 = tzstr('AEST-10AEDT-11,M10.5.0,M3.5.0') +>>> dt = datetime(2003, 5, 8, 2, 7, 36, tzinfo=tz1) +>>> dt.strftime('%X %x %Z') +'02:07:36 05/08/03 EDT' +>>> dt.astimezone(tz2).strftime('%X %x %Z') +'16:07:36 05/08/03 AEST' +}}} + +Are these really equivalent? +{{{ +>>> tzstr('EST5EDT') == tzstr('EST5EDT,4,1,0,7200,10,-1,0,7200,3600') +True +}}} + +Check the daylight limit. +{{{ +>>> datetime(2003, 4, 6, 1, 59, tzinfo=tz).tzname() +'EST' +>>> datetime(2003, 4, 6, 2, 00, tzinfo=tz).tzname() +'EDT' +>>> datetime(2003, 10, 26, 0, 59, tzinfo=tz).tzname() +'EDT' +>>> datetime(2003, 10, 26, 1, 00, tzinfo=tz).tzname() +'EST' +}}} + +==== tzrange type ==== +This type offers the same functionality as the {{{tzstr}}} type, but +instead of timezone strings, information is passed using +{{{relativedelta}}}s which are applied to a datetime set to the first +day of the year. Here is the prototype of this type's constructor: +{{{ +tzrange(stdabbr, stdoffset=None, dstabbr=None, dstoffset=None, + start=None, end=None): +}}} + +Offsets must be given in seconds. Information not provided will be +set to the defaults, as explained in the {{{tzstr}}} section above. + +==== tzrange examples ==== +{{{ +>>> tzstr('EST5EDT') == tzrange("EST", -18000, "EDT") +True + +>>> from dateutil.relativedelta import * +>>> range1 = tzrange("EST", -18000, "EDT") +>>> range2 = tzrange("EST", -18000, "EDT", -14400, +... relativedelta(hours=+2, month=4, day=1, + weekday=SU(+1)), +... relativedelta(hours=+1, month=10, day=31, + weekday=SU(-1))) +>>> tzstr('EST5EDT') == range1 == range2 +True +}}} + +Notice a minor detail in the last example: while the DST should end +at 2AM, the delta will catch 1AM. That's because the daylight saving +time should end at 2AM standard time (the difference between STD and +DST is 1h in the given example) instead of the DST time. That's how +the {{{tzinfo}}} subtypes should deal with the extra hour that happens +when going back to the standard time. Check +[http://www.python.org/doc/current/lib/datetime-tzinfo.html tzinfo documentation] +for more information. + +==== tzfile type ==== +This type allows one to use tzfile(5) format timezone files to extract +current and historical zone information. Here is the type constructor +prototype: +{{{ +tzfile(fileobj) +}}} + +Where {{{fileobj}}} is either a filename or a file-like object with +a {{{read()}}} method. + +==== tzfile examples ==== +{{{ +>>> tz = tzfile("/etc/localtime") +>>> datetime.now(tz) +datetime.datetime(2003, 9, 27, 12, 3, 48, 392138, + tzinfo=tzfile('/etc/localtime')) + +>>> datetime.now(tz).astimezone(tzutc()) +datetime.datetime(2003, 9, 27, 15, 3, 53, 70863, + tzinfo=tzutc()) + +>>> datetime.now(tz).tzname() +'BRST' +>>> datetime(2003, 1, 1, tzinfo=tz).tzname() +'BRDT' +}}} + +Check the daylight limit. +{{{ +>>> tz = tzfile('/usr/share/zoneinfo/EST5EDT') +>>> datetime(2003, 4, 6, 1, 59, tzinfo=tz).tzname() +'EST' +>>> datetime(2003, 4, 6, 2, 00, tzinfo=tz).tzname() +'EDT' +>>> datetime(2003, 10, 26, 0, 59, tzinfo=tz).tzname() +'EDT' +>>> datetime(2003, 10, 26, 1, 00, tzinfo=tz).tzname() +'EST' +}}} + +==== tzical type ==== +This type is able to parse +[ftp://ftp.rfc-editor.org/in-notes/rfc2445.txt iCalendar] +style {{{VTIMEZONE}}} sessions into a Python timezone object. +The constuctor prototype is: +{{{ +tzical(fileobj) +}}} + +Where {{{fileobj}}} is either a filename or a file-like object with +a {{{read()}}} method. + +==== tzical methods ==== + + tzical.get(tzid=None):: + Since a single iCalendar file may contain more than one timezone, + you must ask for the timezone you want with this method. If there's + more than one timezone in the parsed file, you'll need to pass the + {{{tzid}}} parameter. Otherwise, leaving it empty will yield the only + available timezone. + +==== tzical examples ==== +Here is a sample file extracted from the RFC. This file defines +the {{{EST5EDT}}} timezone, and will be used in the following example. +{{{ +BEGIN:VTIMEZONE +TZID:US-Eastern +LAST-MODIFIED:19870101T000000Z +TZURL:http://zones.stds_r_us.net/tz/US-Eastern +BEGIN:STANDARD +DTSTART:19671029T020000 +RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 +TZOFFSETFROM:-0400 +TZOFFSETTO:-0500 +TZNAME:EST +END:STANDARD +BEGIN:DAYLIGHT +DTSTART:19870405T020000 +RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4 +TZOFFSETFROM:-0500 +TZOFFSETTO:-0400 +TZNAME:EDT +END:DAYLIGHT +END:VTIMEZONE +}}} + +And here is an example exploring a {{{tzical}}} type: +{{{ +>>> from dateutil.tz import *; from datetime import * + +>>> tz = tzical('EST5EDT.ics') +>>> tz.keys() +['US-Eastern'] + +>>> est = tz.get('US-Eastern') +>>> est + + +>>> datetime.now(est) +datetime.datetime(2003, 10, 6, 19, 44, 18, 667987, + tzinfo=) + +>>> est == tz.get() +True +}}} + +Let's check the daylight ranges, as usual: +{{{ +>>> datetime(2003, 4, 6, 1, 59, tzinfo=est).tzname() +'EST' +>>> datetime(2003, 4, 6, 2, 00, tzinfo=est).tzname() +'EDT' + +>>> datetime(2003, 10, 26, 0, 59, tzinfo=est).tzname() +'EDT' +>>> datetime(2003, 10, 26, 1, 00, tzinfo=est).tzname() +'EST' +}}} + +==== tzwin type ==== +This type offers access to internal registry-based Windows timezones. +The constuctor prototype is: +{{{ +tzwin(name) +}}} + +Where {{{name}}} is the timezone name. There's a static {{{tzwin.list()}}} +method to check the available names, + +==== tzwin methods ==== + + tzwin.display():: + This method returns the timezone extended name. + + tzwin.list():: + This static method lists all available timezone names. + +==== tzwin examples ==== +{{{ +>>> tz = tzwin("E. South America Standard Time") +}}} + +==== tzwinlocal type ==== +This type offers access to internal registry-based Windows timezones. +The constructor accepts no parameters, so the prototype is: +{{{ +tzwinlocal() +}}} + +==== tzwinlocal methods ==== + + tzwinlocal.display():: + This method returns the timezone extended name, and returns + {{{None}}} if one is not available. + +==== tzwinlocal examples ==== +{{{ +>>> tz = tzwinlocal() +}}} + +==== gettz() function ==== +This function is a helper that will try its best to get the right +timezone for your environment, or for the given string. The prototype +is as follows: +{{{ +gettz(name=None) +}}} + +If given, the parameter may be a filename, a path relative to the base +of the timezone information path (the base could be +{{{/usr/share/zoneinfo}}}, for example), a string timezone +specification, or a timezone abbreviation. If {{{name}}} is not given, +and the {{{TZ}}} environment variable is set, it's used instead. If the +parameter is not given, and {{{TZ}}} is not set, the default tzfile +paths will be tried. Then, if no timezone information is found, +an internal compiled database of timezones is used. When running +on Windows, the internal registry-based Windows timezones are also +considered. + +Example: +{{{ +>>> from dateutil.tz import * +>>> gettz() +tzfile('/etc/localtime') + +>>> gettz("America/Sao Paulo") +tzfile('/usr/share/zoneinfo/America/Sao_Paulo') + +>>> gettz("EST5EDT") +tzfile('/usr/share/zoneinfo/EST5EDT') + +>>> gettz("EST5") +tzstr('EST5') + +>>> gettz('BRST') +tzlocal() + +>>> os.environ["TZ"] = "America/Sao Paulo" +>>> gettz() +tzfile('/usr/share/zoneinfo/America/Sao_Paulo') + +>>> os.environ["TZ"] = "BRST" +>>> gettz() +tzlocal() + +>>> gettz("Unavailable") +>>> +}}} + +=== zoneinfo === +This module provides direct access to the internal compiled +database of timezones. The timezone data and the compiling tools +are obtained from the following project: + + http://www.twinsun.com/tz/tz-link.htm + +==== gettz() function ==== +This function will try to retrieve the given timezone information +from the internal compiled database, and will cache its results. + +Example: +{{{ +>>> from dateutil import zoneinfo +>>> zoneinfo.gettz("Brazil/East") +tzfile('Brazil/East') +}}} + +## vim:ft=moin diff -Nru matplotlib-1.1.1/lib/dateutil_py2/__init__.py matplotlib-1.2.0/lib/dateutil_py2/__init__.py --- matplotlib-1.1.1/lib/dateutil_py2/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py2/__init__.py 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,9 @@ +""" +Copyright (c) 2003-2010 Gustavo Niemeyer + +This module offers extensions to the standard python 2.3+ +datetime module. +""" +__author__ = "Gustavo Niemeyer " +__license__ = "PSF License" +__version__ = "1.5-mpl" diff -Nru matplotlib-1.1.1/lib/dateutil_py2/easter.py matplotlib-1.2.0/lib/dateutil_py2/easter.py --- matplotlib-1.1.1/lib/dateutil_py2/easter.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py2/easter.py 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,92 @@ +""" +Copyright (c) 2003-2007 Gustavo Niemeyer + +This module offers extensions to the standard python 2.3+ +datetime module. +""" +__author__ = "Gustavo Niemeyer " +__license__ = "PSF License" + +import datetime + +__all__ = ["easter", "EASTER_JULIAN", "EASTER_ORTHODOX", "EASTER_WESTERN"] + +EASTER_JULIAN = 1 +EASTER_ORTHODOX = 2 +EASTER_WESTERN = 3 + +def easter(year, method=EASTER_WESTERN): + """ + This method was ported from the work done by GM Arts, + on top of the algorithm by Claus Tondering, which was + based in part on the algorithm of Ouding (1940), as + quoted in "Explanatory Supplement to the Astronomical + Almanac", P. Kenneth Seidelmann, editor. + + This algorithm implements three different easter + calculation methods: + + 1 - Original calculation in Julian calendar, valid in + dates after 326 AD + 2 - Original method, with date converted to Gregorian + calendar, valid in years 1583 to 4099 + 3 - Revised method, in Gregorian calendar, valid in + years 1583 to 4099 as well + + These methods are represented by the constants: + + EASTER_JULIAN = 1 + EASTER_ORTHODOX = 2 + EASTER_WESTERN = 3 + + The default method is method 3. + + More about the algorithm may be found at: + + http://users.chariot.net.au/~gmarts/eastalg.htm + + and + + http://www.tondering.dk/claus/calendar.html + + """ + + if not (1 <= method <= 3): + raise ValueError, "invalid method" + + # g - Golden year - 1 + # c - Century + # h - (23 - Epact) mod 30 + # i - Number of days from March 21 to Paschal Full Moon + # j - Weekday for PFM (0=Sunday, etc) + # p - Number of days from March 21 to Sunday on or before PFM + # (-6 to 28 methods 1 & 3, to 56 for method 2) + # e - Extra days to add for method 2 (converting Julian + # date to Gregorian date) + + y = year + g = y % 19 + e = 0 + if method < 3: + # Old method + i = (19*g+15)%30 + j = (y+y//4+i)%7 + if method == 2: + # Extra dates to convert Julian to Gregorian date + e = 10 + if y > 1600: + e = e+y//100-16-(y//100-16)//4 + else: + # New method + c = y//100 + h = (c-c//4-(8*c+13)//25+19*g+15)%30 + i = h-(h//28)*(1-(h//28)*(29//(h+1))*((21-g)//11)) + j = (y+y//4+i+2-c+c//4)%7 + + # p can be from -6 to 56 corresponding to dates 22 March to 23 May + # (later dates apply to method 2, although 23 May never actually occurs) + p = i-j+e + d = 1+(p+27+(p+6)//40)%31 + m = 3+(p+26)//30 + return datetime.date(int(y),int(m),int(d)) + diff -Nru matplotlib-1.1.1/lib/dateutil_py2/parser.py matplotlib-1.2.0/lib/dateutil_py2/parser.py --- matplotlib-1.1.1/lib/dateutil_py2/parser.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py2/parser.py 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,886 @@ +# -*- coding:iso-8859-1 -*- +""" +Copyright (c) 2003-2007 Gustavo Niemeyer + +This module offers extensions to the standard python 2.3+ +datetime module. +""" +__author__ = "Gustavo Niemeyer " +__license__ = "PSF License" + +import datetime +import string +import time +import sys +import os + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +import relativedelta +import tz + + +__all__ = ["parse", "parserinfo"] + + +# Some pointers: +# +# http://www.cl.cam.ac.uk/~mgk25/iso-time.html +# http://www.iso.ch/iso/en/prods-services/popstds/datesandtime.html +# http://www.w3.org/TR/NOTE-datetime +# http://ringmaster.arc.nasa.gov/tools/time_formats.html +# http://search.cpan.org/author/MUIR/Time-modules-2003.0211/lib/Time/ParseDate.pm +# http://stein.cshl.org/jade/distrib/docs/java.text.SimpleDateFormat.html + + +class _timelex(object): + + def __init__(self, instream): + if isinstance(instream, basestring): + instream = StringIO(instream) + self.instream = instream + self.wordchars = ('abcdfeghijklmnopqrstuvwxyz' + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_' + '' + '') + self.numchars = '0123456789' + self.whitespace = ' \t\r\n' + self.charstack = [] + self.tokenstack = [] + self.eof = False + + def get_token(self): + if self.tokenstack: + return self.tokenstack.pop(0) + seenletters = False + token = None + state = None + wordchars = self.wordchars + numchars = self.numchars + whitespace = self.whitespace + while not self.eof: + if self.charstack: + nextchar = self.charstack.pop(0) + else: + nextchar = self.instream.read(1) + while nextchar == '\x00': + nextchar = self.instream.read(1) + if not nextchar: + self.eof = True + break + elif not state: + token = nextchar + if nextchar in wordchars: + state = 'a' + elif nextchar in numchars: + state = '0' + elif nextchar in whitespace: + token = ' ' + break # emit token + else: + break # emit token + elif state == 'a': + seenletters = True + if nextchar in wordchars: + token += nextchar + elif nextchar == '.': + token += nextchar + state = 'a.' + else: + self.charstack.append(nextchar) + break # emit token + elif state == '0': + if nextchar in numchars: + token += nextchar + elif nextchar == '.': + token += nextchar + state = '0.' + else: + self.charstack.append(nextchar) + break # emit token + elif state == 'a.': + seenletters = True + if nextchar == '.' or nextchar in wordchars: + token += nextchar + elif nextchar in numchars and token[-1] == '.': + token += nextchar + state = '0.' + else: + self.charstack.append(nextchar) + break # emit token + elif state == '0.': + if nextchar == '.' or nextchar in numchars: + token += nextchar + elif nextchar in wordchars and token[-1] == '.': + token += nextchar + state = 'a.' + else: + self.charstack.append(nextchar) + break # emit token + if (state in ('a.', '0.') and + (seenletters or token.count('.') > 1 or token[-1] == '.')): + l = token.split('.') + token = l[0] + for tok in l[1:]: + self.tokenstack.append('.') + if tok: + self.tokenstack.append(tok) + return token + + def __iter__(self): + return self + + def next(self): + token = self.get_token() + if token is None: + raise StopIteration + return token + + def split(cls, s): + return list(cls(s)) + split = classmethod(split) + + +class _resultbase(object): + + def __init__(self): + for attr in self.__slots__: + setattr(self, attr, None) + + def _repr(self, classname): + l = [] + for attr in self.__slots__: + value = getattr(self, attr) + if value is not None: + l.append("%s=%s" % (attr, `value`)) + return "%s(%s)" % (classname, ", ".join(l)) + + def __repr__(self): + return self._repr(self.__class__.__name__) + + +class parserinfo(object): + + # m from a.m/p.m, t from ISO T separator + JUMP = [" ", ".", ",", ";", "-", "/", "'", + "at", "on", "and", "ad", "m", "t", "of", + "st", "nd", "rd", "th"] + + WEEKDAYS = [("Mon", "Monday"), + ("Tue", "Tuesday"), + ("Wed", "Wednesday"), + ("Thu", "Thursday"), + ("Fri", "Friday"), + ("Sat", "Saturday"), + ("Sun", "Sunday")] + MONTHS = [("Jan", "January"), + ("Feb", "February"), + ("Mar", "March"), + ("Apr", "April"), + ("May", "May"), + ("Jun", "June"), + ("Jul", "July"), + ("Aug", "August"), + ("Sep", "September"), + ("Oct", "October"), + ("Nov", "November"), + ("Dec", "December")] + HMS = [("h", "hour", "hours"), + ("m", "minute", "minutes"), + ("s", "second", "seconds")] + AMPM = [("am", "a"), + ("pm", "p")] + UTCZONE = ["UTC", "GMT", "Z"] + PERTAIN = ["of"] + TZOFFSET = {} + + def __init__(self, dayfirst=False, yearfirst=False): + self._jump = self._convert(self.JUMP) + self._weekdays = self._convert(self.WEEKDAYS) + self._months = self._convert(self.MONTHS) + self._hms = self._convert(self.HMS) + self._ampm = self._convert(self.AMPM) + self._utczone = self._convert(self.UTCZONE) + self._pertain = self._convert(self.PERTAIN) + + self.dayfirst = dayfirst + self.yearfirst = yearfirst + + self._year = time.localtime().tm_year + self._century = self._year//100*100 + + def _convert(self, lst): + dct = {} + for i in range(len(lst)): + v = lst[i] + if isinstance(v, tuple): + for v in v: + dct[v.lower()] = i + else: + dct[v.lower()] = i + return dct + + def jump(self, name): + return name.lower() in self._jump + + def weekday(self, name): + if len(name) >= 3: + try: + return self._weekdays[name.lower()] + except KeyError: + pass + return None + + def month(self, name): + if len(name) >= 3: + try: + return self._months[name.lower()]+1 + except KeyError: + pass + return None + + def hms(self, name): + try: + return self._hms[name.lower()] + except KeyError: + return None + + def ampm(self, name): + try: + return self._ampm[name.lower()] + except KeyError: + return None + + def pertain(self, name): + return name.lower() in self._pertain + + def utczone(self, name): + return name.lower() in self._utczone + + def tzoffset(self, name): + if name in self._utczone: + return 0 + return self.TZOFFSET.get(name) + + def convertyear(self, year): + if year < 100: + year += self._century + if abs(year-self._year) >= 50: + if year < self._year: + year += 100 + else: + year -= 100 + return year + + def validate(self, res): + # move to info + if res.year is not None: + res.year = self.convertyear(res.year) + if res.tzoffset == 0 and not res.tzname or res.tzname == 'Z': + res.tzname = "UTC" + res.tzoffset = 0 + elif res.tzoffset != 0 and res.tzname and self.utczone(res.tzname): + res.tzoffset = 0 + return True + + +class parser(object): + + def __init__(self, info=None): + self.info = info or parserinfo() + + def parse(self, timestr, default=None, + ignoretz=False, tzinfos=None, + **kwargs): + if not default: + default = datetime.datetime.now().replace(hour=0, minute=0, + second=0, microsecond=0) + res = self._parse(timestr, **kwargs) + if res is None: + raise ValueError, "unknown string format" + repl = {} + for attr in ["year", "month", "day", "hour", + "minute", "second", "microsecond"]: + value = getattr(res, attr) + if value is not None: + repl[attr] = value + ret = default.replace(**repl) + if res.weekday is not None and not res.day: + ret = ret+relativedelta.relativedelta(weekday=res.weekday) + if not ignoretz: + if callable(tzinfos) or tzinfos and res.tzname in tzinfos: + if callable(tzinfos): + tzdata = tzinfos(res.tzname, res.tzoffset) + else: + tzdata = tzinfos.get(res.tzname) + if isinstance(tzdata, datetime.tzinfo): + tzinfo = tzdata + elif isinstance(tzdata, basestring): + tzinfo = tz.tzstr(tzdata) + elif isinstance(tzdata, int): + tzinfo = tz.tzoffset(res.tzname, tzdata) + else: + raise ValueError, "offset must be tzinfo subclass, " \ + "tz string, or int offset" + ret = ret.replace(tzinfo=tzinfo) + elif res.tzname and res.tzname in time.tzname: + ret = ret.replace(tzinfo=tz.tzlocal()) + elif res.tzoffset == 0: + ret = ret.replace(tzinfo=tz.tzutc()) + elif res.tzoffset: + ret = ret.replace(tzinfo=tz.tzoffset(res.tzname, res.tzoffset)) + return ret + + class _result(_resultbase): + __slots__ = ["year", "month", "day", "weekday", + "hour", "minute", "second", "microsecond", + "tzname", "tzoffset"] + + def _parse(self, timestr, dayfirst=None, yearfirst=None, fuzzy=False): + info = self.info + if dayfirst is None: + dayfirst = info.dayfirst + if yearfirst is None: + yearfirst = info.yearfirst + res = self._result() + l = _timelex.split(timestr) + try: + + # year/month/day list + ymd = [] + + # Index of the month string in ymd + mstridx = -1 + + len_l = len(l) + i = 0 + while i < len_l: + + # Check if it's a number + try: + value_repr = l[i] + value = float(value_repr) + except ValueError: + value = None + + if value is not None: + # Token is a number + len_li = len(l[i]) + i += 1 + if (len(ymd) == 3 and len_li in (2, 4) + and (i >= len_l or (l[i] != ':' and + info.hms(l[i]) is None))): + # 19990101T23[59] + s = l[i-1] + res.hour = int(s[:2]) + if len_li == 4: + res.minute = int(s[2:]) + elif len_li == 6 or (len_li > 6 and l[i-1].find('.') == 6): + # YYMMDD or HHMMSS[.ss] + s = l[i-1] + if not ymd and l[i-1].find('.') == -1: + ymd.append(info.convertyear(int(s[:2]))) + ymd.append(int(s[2:4])) + ymd.append(int(s[4:])) + else: + # 19990101T235959[.59] + res.hour = int(s[:2]) + res.minute = int(s[2:4]) + res.second, res.microsecond = _parsems(s[4:]) + elif len_li == 8: + # YYYYMMDD + s = l[i-1] + ymd.append(int(s[:4])) + ymd.append(int(s[4:6])) + ymd.append(int(s[6:])) + elif len_li in (12, 14): + # YYYYMMDDhhmm[ss] + s = l[i-1] + ymd.append(int(s[:4])) + ymd.append(int(s[4:6])) + ymd.append(int(s[6:8])) + res.hour = int(s[8:10]) + res.minute = int(s[10:12]) + if len_li == 14: + res.second = int(s[12:]) + elif ((i < len_l and info.hms(l[i]) is not None) or + (i+1 < len_l and l[i] == ' ' and + info.hms(l[i+1]) is not None)): + # HH[ ]h or MM[ ]m or SS[.ss][ ]s + if l[i] == ' ': + i += 1 + idx = info.hms(l[i]) + while True: + if idx == 0: + res.hour = int(value) + if value%1: + res.minute = int(60*(value%1)) + elif idx == 1: + res.minute = int(value) + if value%1: + res.second = int(60*(value%1)) + elif idx == 2: + res.second, res.microsecond = \ + _parsems(value_repr) + i += 1 + if i >= len_l or idx == 2: + break + # 12h00 + try: + value_repr = l[i] + value = float(value_repr) + except ValueError: + break + else: + i += 1 + idx += 1 + if i < len_l: + newidx = info.hms(l[i]) + if newidx is not None: + idx = newidx + elif i+1 < len_l and l[i] == ':': + # HH:MM[:SS[.ss]] + res.hour = int(value) + i += 1 + value = float(l[i]) + res.minute = int(value) + if value%1: + res.second = int(60*(value%1)) + i += 1 + if i < len_l and l[i] == ':': + res.second, res.microsecond = _parsems(l[i+1]) + i += 2 + elif i < len_l and l[i] in ('-', '/', '.'): + sep = l[i] + ymd.append(int(value)) + i += 1 + if i < len_l and not info.jump(l[i]): + try: + # 01-01[-01] + ymd.append(int(l[i])) + except ValueError: + # 01-Jan[-01] + value = info.month(l[i]) + if value is not None: + ymd.append(value) + assert mstridx == -1 + mstridx = len(ymd)-1 + else: + return None + i += 1 + if i < len_l and l[i] == sep: + # We have three members + i += 1 + value = info.month(l[i]) + if value is not None: + ymd.append(value) + mstridx = len(ymd)-1 + assert mstridx == -1 + else: + ymd.append(int(l[i])) + i += 1 + elif i >= len_l or info.jump(l[i]): + if i+1 < len_l and info.ampm(l[i+1]) is not None: + # 12 am + res.hour = int(value) + if res.hour < 12 and info.ampm(l[i+1]) == 1: + res.hour += 12 + elif res.hour == 12 and info.ampm(l[i+1]) == 0: + res.hour = 0 + i += 1 + else: + # Year, month or day + ymd.append(int(value)) + i += 1 + elif info.ampm(l[i]) is not None: + # 12am + res.hour = int(value) + if res.hour < 12 and info.ampm(l[i]) == 1: + res.hour += 12 + elif res.hour == 12 and info.ampm(l[i]) == 0: + res.hour = 0 + i += 1 + elif not fuzzy: + return None + else: + i += 1 + continue + + # Check weekday + value = info.weekday(l[i]) + if value is not None: + res.weekday = value + i += 1 + continue + + # Check month name + value = info.month(l[i]) + if value is not None: + ymd.append(value) + assert mstridx == -1 + mstridx = len(ymd)-1 + i += 1 + if i < len_l: + if l[i] in ('-', '/'): + # Jan-01[-99] + sep = l[i] + i += 1 + ymd.append(int(l[i])) + i += 1 + if i < len_l and l[i] == sep: + # Jan-01-99 + i += 1 + ymd.append(int(l[i])) + i += 1 + elif (i+3 < len_l and l[i] == l[i+2] == ' ' + and info.pertain(l[i+1])): + # Jan of 01 + # In this case, 01 is clearly year + try: + value = int(l[i+3]) + except ValueError: + # Wrong guess + pass + else: + # Convert it here to become unambiguous + ymd.append(info.convertyear(value)) + i += 4 + continue + + # Check am/pm + value = info.ampm(l[i]) + if value is not None: + if value == 1 and res.hour < 12: + res.hour += 12 + elif value == 0 and res.hour == 12: + res.hour = 0 + i += 1 + continue + + # Check for a timezone name + if (res.hour is not None and len(l[i]) <= 5 and + res.tzname is None and res.tzoffset is None and + not [x for x in l[i] if x not in string.ascii_uppercase]): + res.tzname = l[i] + res.tzoffset = info.tzoffset(res.tzname) + i += 1 + + # Check for something like GMT+3, or BRST+3. Notice + # that it doesn't mean "I am 3 hours after GMT", but + # "my time +3 is GMT". If found, we reverse the + # logic so that timezone parsing code will get it + # right. + if i < len_l and l[i] in ('+', '-'): + l[i] = ('+', '-')[l[i] == '+'] + res.tzoffset = None + if info.utczone(res.tzname): + # With something like GMT+3, the timezone + # is *not* GMT. + res.tzname = None + + continue + + # Check for a numbered timezone + if res.hour is not None and l[i] in ('+', '-'): + signal = (-1,1)[l[i] == '+'] + i += 1 + len_li = len(l[i]) + if len_li == 4: + # -0300 + res.tzoffset = int(l[i][:2])*3600+int(l[i][2:])*60 + elif i+1 < len_l and l[i+1] == ':': + # -03:00 + res.tzoffset = int(l[i])*3600+int(l[i+2])*60 + i += 2 + elif len_li <= 2: + # -[0]3 + res.tzoffset = int(l[i][:2])*3600 + else: + return None + i += 1 + res.tzoffset *= signal + + # Look for a timezone name between parenthesis + if (i+3 < len_l and + info.jump(l[i]) and l[i+1] == '(' and l[i+3] == ')' and + 3 <= len(l[i+2]) <= 5 and + not [x for x in l[i+2] + if x not in string.ascii_uppercase]): + # -0300 (BRST) + res.tzname = l[i+2] + i += 4 + continue + + # Check jumps + if not (info.jump(l[i]) or fuzzy): + return None + + i += 1 + + # Process year/month/day + len_ymd = len(ymd) + if len_ymd > 3: + # More than three members!? + return None + elif len_ymd == 1 or (mstridx != -1 and len_ymd == 2): + # One member, or two members with a month string + if mstridx != -1: + res.month = ymd[mstridx] + del ymd[mstridx] + if len_ymd > 1 or mstridx == -1: + if ymd[0] > 31: + res.year = ymd[0] + else: + res.day = ymd[0] + elif len_ymd == 2: + # Two members with numbers + if ymd[0] > 31: + # 99-01 + res.year, res.month = ymd + elif ymd[1] > 31: + # 01-99 + res.month, res.year = ymd + elif dayfirst and ymd[1] <= 12: + # 13-01 + res.day, res.month = ymd + else: + # 01-13 + res.month, res.day = ymd + if len_ymd == 3: + # Three members + if mstridx == 0: + res.month, res.day, res.year = ymd + elif mstridx == 1: + if ymd[0] > 31 or (yearfirst and ymd[2] <= 31): + # 99-Jan-01 + res.year, res.month, res.day = ymd + else: + # 01-Jan-01 + # Give precendence to day-first, since + # two-digit years is usually hand-written. + res.day, res.month, res.year = ymd + elif mstridx == 2: + # WTF!? + if ymd[1] > 31: + # 01-99-Jan + res.day, res.year, res.month = ymd + else: + # 99-01-Jan + res.year, res.day, res.month = ymd + else: + if ymd[0] > 31 or \ + (yearfirst and ymd[1] <= 12 and ymd[2] <= 31): + # 99-01-01 + res.year, res.month, res.day = ymd + elif ymd[0] > 12 or (dayfirst and ymd[1] <= 12): + # 13-01-01 + res.day, res.month, res.year = ymd + else: + # 01-13-01 + res.month, res.day, res.year = ymd + + except (IndexError, ValueError, AssertionError): + return None + + if not info.validate(res): + return None + return res + +DEFAULTPARSER = parser() +def parse(timestr, parserinfo=None, **kwargs): + if parserinfo: + return parser(parserinfo).parse(timestr, **kwargs) + else: + return DEFAULTPARSER.parse(timestr, **kwargs) + + +class _tzparser(object): + + class _result(_resultbase): + + __slots__ = ["stdabbr", "stdoffset", "dstabbr", "dstoffset", + "start", "end"] + + class _attr(_resultbase): + __slots__ = ["month", "week", "weekday", + "yday", "jyday", "day", "time"] + + def __repr__(self): + return self._repr("") + + def __init__(self): + _resultbase.__init__(self) + self.start = self._attr() + self.end = self._attr() + + def parse(self, tzstr): + res = self._result() + l = _timelex.split(tzstr) + try: + + len_l = len(l) + + i = 0 + while i < len_l: + # BRST+3[BRDT[+2]] + j = i + while j < len_l and not [x for x in l[j] + if x in "0123456789:,-+"]: + j += 1 + if j != i: + if not res.stdabbr: + offattr = "stdoffset" + res.stdabbr = "".join(l[i:j]) + else: + offattr = "dstoffset" + res.dstabbr = "".join(l[i:j]) + i = j + if (i < len_l and + (l[i] in ('+', '-') or l[i][0] in "0123456789")): + if l[i] in ('+', '-'): + # Yes, that's right. See the TZ variable + # documentation. + signal = (1,-1)[l[i] == '+'] + i += 1 + else: + signal = -1 + len_li = len(l[i]) + if len_li == 4: + # -0300 + setattr(res, offattr, + (int(l[i][:2])*3600+int(l[i][2:])*60)*signal) + elif i+1 < len_l and l[i+1] == ':': + # -03:00 + setattr(res, offattr, + (int(l[i])*3600+int(l[i+2])*60)*signal) + i += 2 + elif len_li <= 2: + # -[0]3 + setattr(res, offattr, + int(l[i][:2])*3600*signal) + else: + return None + i += 1 + if res.dstabbr: + break + else: + break + + if i < len_l: + for j in range(i, len_l): + if l[j] == ';': l[j] = ',' + + assert l[i] == ',' + + i += 1 + + if i >= len_l: + pass + elif (8 <= l.count(',') <= 9 and + not [y for x in l[i:] if x != ',' + for y in x if y not in "0123456789"]): + # GMT0BST,3,0,30,3600,10,0,26,7200[,3600] + for x in (res.start, res.end): + x.month = int(l[i]) + i += 2 + if l[i] == '-': + value = int(l[i+1])*-1 + i += 1 + else: + value = int(l[i]) + i += 2 + if value: + x.week = value + x.weekday = (int(l[i])-1)%7 + else: + x.day = int(l[i]) + i += 2 + x.time = int(l[i]) + i += 2 + if i < len_l: + if l[i] in ('-','+'): + signal = (-1,1)[l[i] == "+"] + i += 1 + else: + signal = 1 + res.dstoffset = (res.stdoffset+int(l[i]))*signal + elif (l.count(',') == 2 and l[i:].count('/') <= 2 and + not [y for x in l[i:] if x not in (',','/','J','M', + '.','-',':') + for y in x if y not in "0123456789"]): + for x in (res.start, res.end): + if l[i] == 'J': + # non-leap year day (1 based) + i += 1 + x.jyday = int(l[i]) + elif l[i] == 'M': + # month[-.]week[-.]weekday + i += 1 + x.month = int(l[i]) + i += 1 + assert l[i] in ('-', '.') + i += 1 + x.week = int(l[i]) + if x.week == 5: + x.week = -1 + i += 1 + assert l[i] in ('-', '.') + i += 1 + x.weekday = (int(l[i])-1)%7 + else: + # year day (zero based) + x.yday = int(l[i])+1 + + i += 1 + + if i < len_l and l[i] == '/': + i += 1 + # start time + len_li = len(l[i]) + if len_li == 4: + # -0300 + x.time = (int(l[i][:2])*3600+int(l[i][2:])*60) + elif i+1 < len_l and l[i+1] == ':': + # -03:00 + x.time = int(l[i])*3600+int(l[i+2])*60 + i += 2 + if i+1 < len_l and l[i+1] == ':': + i += 2 + x.time += int(l[i]) + elif len_li <= 2: + # -[0]3 + x.time = (int(l[i][:2])*3600) + else: + return None + i += 1 + + assert i == len_l or l[i] == ',' + + i += 1 + + assert i >= len_l + + except (IndexError, ValueError, AssertionError): + return None + + return res + + +DEFAULTTZPARSER = _tzparser() +def _parsetz(tzstr): + return DEFAULTTZPARSER.parse(tzstr) + + +def _parsems(value): + """Parse a I[.F] seconds value into (seconds, microseconds).""" + if "." not in value: + return int(value), 0 + else: + i, f = value.split(".") + return int(i), int(f.ljust(6, "0")[:6]) + + +# vim:ts=4:sw=4:et diff -Nru matplotlib-1.1.1/lib/dateutil_py2/relativedelta.py matplotlib-1.2.0/lib/dateutil_py2/relativedelta.py --- matplotlib-1.1.1/lib/dateutil_py2/relativedelta.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py2/relativedelta.py 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,432 @@ +""" +Copyright (c) 2003-2010 Gustavo Niemeyer + +This module offers extensions to the standard python 2.3+ +datetime module. +""" +__author__ = "Gustavo Niemeyer " +__license__ = "PSF License" + +import datetime +import calendar + +__all__ = ["relativedelta", "MO", "TU", "WE", "TH", "FR", "SA", "SU"] + +class weekday(object): + __slots__ = ["weekday", "n"] + + def __init__(self, weekday, n=None): + self.weekday = weekday + self.n = n + + def __call__(self, n): + if n == self.n: + return self + else: + return self.__class__(self.weekday, n) + + def __eq__(self, other): + try: + if self.weekday != other.weekday or self.n != other.n: + return False + except AttributeError: + return False + return True + + def __repr__(self): + s = ("MO", "TU", "WE", "TH", "FR", "SA", "SU")[self.weekday] + if not self.n: + return s + else: + return "%s(%+d)" % (s, self.n) + +MO, TU, WE, TH, FR, SA, SU = weekdays = tuple([weekday(x) for x in range(7)]) + +class relativedelta: + """ +The relativedelta type is based on the specification of the excelent +work done by M.-A. Lemburg in his mx.DateTime extension. However, +notice that this type does *NOT* implement the same algorithm as +his work. Do *NOT* expect it to behave like mx.DateTime's counterpart. + +There's two different ways to build a relativedelta instance. The +first one is passing it two date/datetime classes: + + relativedelta(datetime1, datetime2) + +And the other way is to use the following keyword arguments: + + year, month, day, hour, minute, second, microsecond: + Absolute information. + + years, months, weeks, days, hours, minutes, seconds, microseconds: + Relative information, may be negative. + + weekday: + One of the weekday instances (MO, TU, etc). These instances may + receive a parameter N, specifying the Nth weekday, which could + be positive or negative (like MO(+1) or MO(-2). Not specifying + it is the same as specifying +1. You can also use an integer, + where 0=MO. + + leapdays: + Will add given days to the date found, if year is a leap + year, and the date found is post 28 of february. + + yearday, nlyearday: + Set the yearday or the non-leap year day (jump leap days). + These are converted to day/month/leapdays information. + +Here is the behavior of operations with relativedelta: + +1) Calculate the absolute year, using the 'year' argument, or the + original datetime year, if the argument is not present. + +2) Add the relative 'years' argument to the absolute year. + +3) Do steps 1 and 2 for month/months. + +4) Calculate the absolute day, using the 'day' argument, or the + original datetime day, if the argument is not present. Then, + subtract from the day until it fits in the year and month + found after their operations. + +5) Add the relative 'days' argument to the absolute day. Notice + that the 'weeks' argument is multiplied by 7 and added to + 'days'. + +6) Do steps 1 and 2 for hour/hours, minute/minutes, second/seconds, + microsecond/microseconds. + +7) If the 'weekday' argument is present, calculate the weekday, + with the given (wday, nth) tuple. wday is the index of the + weekday (0-6, 0=Mon), and nth is the number of weeks to add + forward or backward, depending on its signal. Notice that if + the calculated date is already Monday, for example, using + (0, 1) or (0, -1) won't change the day. + """ + + def __init__(self, dt1=None, dt2=None, + years=0, months=0, days=0, leapdays=0, weeks=0, + hours=0, minutes=0, seconds=0, microseconds=0, + year=None, month=None, day=None, weekday=None, + yearday=None, nlyearday=None, + hour=None, minute=None, second=None, microsecond=None): + if dt1 and dt2: + if not isinstance(dt1, datetime.date) or \ + not isinstance(dt2, datetime.date): + raise TypeError, "relativedelta only diffs datetime/date" + if type(dt1) is not type(dt2): + if not isinstance(dt1, datetime.datetime): + dt1 = datetime.datetime.fromordinal(dt1.toordinal()) + elif not isinstance(dt2, datetime.datetime): + dt2 = datetime.datetime.fromordinal(dt2.toordinal()) + self.years = 0 + self.months = 0 + self.days = 0 + self.leapdays = 0 + self.hours = 0 + self.minutes = 0 + self.seconds = 0 + self.microseconds = 0 + self.year = None + self.month = None + self.day = None + self.weekday = None + self.hour = None + self.minute = None + self.second = None + self.microsecond = None + self._has_time = 0 + + months = (dt1.year*12+dt1.month)-(dt2.year*12+dt2.month) + self._set_months(months) + dtm = self.__radd__(dt2) + if dt1 < dt2: + while dt1 > dtm: + months += 1 + self._set_months(months) + dtm = self.__radd__(dt2) + else: + while dt1 < dtm: + months -= 1 + self._set_months(months) + dtm = self.__radd__(dt2) + delta = dt1 - dtm + self.seconds = delta.seconds+delta.days*86400 + self.microseconds = delta.microseconds + else: + self.years = years + self.months = months + self.days = days+weeks*7 + self.leapdays = leapdays + self.hours = hours + self.minutes = minutes + self.seconds = seconds + self.microseconds = microseconds + self.year = year + self.month = month + self.day = day + self.hour = hour + self.minute = minute + self.second = second + self.microsecond = microsecond + + if type(weekday) is int: + self.weekday = weekdays[weekday] + else: + self.weekday = weekday + + yday = 0 + if nlyearday: + yday = nlyearday + elif yearday: + yday = yearday + if yearday > 59: + self.leapdays = -1 + if yday: + ydayidx = [31,59,90,120,151,181,212,243,273,304,334,366] + for idx, ydays in enumerate(ydayidx): + if yday <= ydays: + self.month = idx+1 + if idx == 0: + self.day = yday + else: + self.day = yday-ydayidx[idx-1] + break + else: + raise ValueError, "invalid year day (%d)" % yday + + self._fix() + + def _fix(self): + if abs(self.microseconds) > 999999: + s = self.microseconds//abs(self.microseconds) + div, mod = divmod(self.microseconds*s, 1000000) + self.microseconds = mod*s + self.seconds += div*s + if abs(self.seconds) > 59: + s = self.seconds//abs(self.seconds) + div, mod = divmod(self.seconds*s, 60) + self.seconds = mod*s + self.minutes += div*s + if abs(self.minutes) > 59: + s = self.minutes//abs(self.minutes) + div, mod = divmod(self.minutes*s, 60) + self.minutes = mod*s + self.hours += div*s + if abs(self.hours) > 23: + s = self.hours//abs(self.hours) + div, mod = divmod(self.hours*s, 24) + self.hours = mod*s + self.days += div*s + if abs(self.months) > 11: + s = self.months//abs(self.months) + div, mod = divmod(self.months*s, 12) + self.months = mod*s + self.years += div*s + if (self.hours or self.minutes or self.seconds or self.microseconds or + self.hour is not None or self.minute is not None or + self.second is not None or self.microsecond is not None): + self._has_time = 1 + else: + self._has_time = 0 + + def _set_months(self, months): + self.months = months + if abs(self.months) > 11: + s = self.months//abs(self.months) + div, mod = divmod(self.months*s, 12) + self.months = mod*s + self.years = div*s + else: + self.years = 0 + + def __radd__(self, other): + if not isinstance(other, datetime.date): + raise TypeError, "unsupported type for add operation" + elif self._has_time and not isinstance(other, datetime.datetime): + other = datetime.datetime.fromordinal(other.toordinal()) + year = (self.year or other.year)+self.years + month = self.month or other.month + if self.months: + assert 1 <= abs(self.months) <= 12 + month += self.months + if month > 12: + year += 1 + month -= 12 + elif month < 1: + year -= 1 + month += 12 + day = min(calendar.monthrange(year, month)[1], + self.day or other.day) + repl = {"year": year, "month": month, "day": day} + for attr in ["hour", "minute", "second", "microsecond"]: + value = getattr(self, attr) + if value is not None: + repl[attr] = value + days = self.days + if self.leapdays and month > 2 and calendar.isleap(year): + days += self.leapdays + ret = (other.replace(**repl) + + datetime.timedelta(days=days, + hours=self.hours, + minutes=self.minutes, + seconds=self.seconds, + microseconds=self.microseconds)) + if self.weekday: + weekday, nth = self.weekday.weekday, self.weekday.n or 1 + jumpdays = (abs(nth)-1)*7 + if nth > 0: + jumpdays += (7-ret.weekday()+weekday)%7 + else: + jumpdays += (ret.weekday()-weekday)%7 + jumpdays *= -1 + ret += datetime.timedelta(days=jumpdays) + return ret + + def __rsub__(self, other): + return self.__neg__().__radd__(other) + + def __add__(self, other): + if not isinstance(other, relativedelta): + raise TypeError, "unsupported type for add operation" + return relativedelta(years=other.years+self.years, + months=other.months+self.months, + days=other.days+self.days, + hours=other.hours+self.hours, + minutes=other.minutes+self.minutes, + seconds=other.seconds+self.seconds, + microseconds=other.microseconds+self.microseconds, + leapdays=other.leapdays or self.leapdays, + year=other.year or self.year, + month=other.month or self.month, + day=other.day or self.day, + weekday=other.weekday or self.weekday, + hour=other.hour or self.hour, + minute=other.minute or self.minute, + second=other.second or self.second, + microsecond=other.second or self.microsecond) + + def __sub__(self, other): + if not isinstance(other, relativedelta): + raise TypeError, "unsupported type for sub operation" + return relativedelta(years=other.years-self.years, + months=other.months-self.months, + days=other.days-self.days, + hours=other.hours-self.hours, + minutes=other.minutes-self.minutes, + seconds=other.seconds-self.seconds, + microseconds=other.microseconds-self.microseconds, + leapdays=other.leapdays or self.leapdays, + year=other.year or self.year, + month=other.month or self.month, + day=other.day or self.day, + weekday=other.weekday or self.weekday, + hour=other.hour or self.hour, + minute=other.minute or self.minute, + second=other.second or self.second, + microsecond=other.second or self.microsecond) + + def __neg__(self): + return relativedelta(years=-self.years, + months=-self.months, + days=-self.days, + hours=-self.hours, + minutes=-self.minutes, + seconds=-self.seconds, + microseconds=-self.microseconds, + leapdays=self.leapdays, + year=self.year, + month=self.month, + day=self.day, + weekday=self.weekday, + hour=self.hour, + minute=self.minute, + second=self.second, + microsecond=self.microsecond) + + def __nonzero__(self): + return not (not self.years and + not self.months and + not self.days and + not self.hours and + not self.minutes and + not self.seconds and + not self.microseconds and + not self.leapdays and + self.year is None and + self.month is None and + self.day is None and + self.weekday is None and + self.hour is None and + self.minute is None and + self.second is None and + self.microsecond is None) + + def __mul__(self, other): + f = float(other) + return relativedelta(years=self.years*f, + months=self.months*f, + days=self.days*f, + hours=self.hours*f, + minutes=self.minutes*f, + seconds=self.seconds*f, + microseconds=self.microseconds*f, + leapdays=self.leapdays, + year=self.year, + month=self.month, + day=self.day, + weekday=self.weekday, + hour=self.hour, + minute=self.minute, + second=self.second, + microsecond=self.microsecond) + + def __eq__(self, other): + if not isinstance(other, relativedelta): + return False + if self.weekday or other.weekday: + if not self.weekday or not other.weekday: + return False + if self.weekday.weekday != other.weekday.weekday: + return False + n1, n2 = self.weekday.n, other.weekday.n + if n1 != n2 and not ((not n1 or n1 == 1) and (not n2 or n2 == 1)): + return False + return (self.years == other.years and + self.months == other.months and + self.days == other.days and + self.hours == other.hours and + self.minutes == other.minutes and + self.seconds == other.seconds and + self.leapdays == other.leapdays and + self.year == other.year and + self.month == other.month and + self.day == other.day and + self.hour == other.hour and + self.minute == other.minute and + self.second == other.second and + self.microsecond == other.microsecond) + + def __ne__(self, other): + return not self.__eq__(other) + + def __div__(self, other): + return self.__mul__(1/float(other)) + + def __repr__(self): + l = [] + for attr in ["years", "months", "days", "leapdays", + "hours", "minutes", "seconds", "microseconds"]: + value = getattr(self, attr) + if value: + l.append("%s=%+d" % (attr, value)) + for attr in ["year", "month", "day", "weekday", + "hour", "minute", "second", "microsecond"]: + value = getattr(self, attr) + if value is not None: + l.append("%s=%s" % (attr, `value`)) + return "%s(%s)" % (self.__class__.__name__, ", ".join(l)) + +# vim:ts=4:sw=4:et diff -Nru matplotlib-1.1.1/lib/dateutil_py2/rrule.py matplotlib-1.2.0/lib/dateutil_py2/rrule.py --- matplotlib-1.1.1/lib/dateutil_py2/rrule.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py2/rrule.py 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,1097 @@ +""" +Copyright (c) 2003-2010 Gustavo Niemeyer + +This module offers extensions to the standard python 2.3+ +datetime module. +""" +__author__ = "Gustavo Niemeyer " +__license__ = "PSF License" + +import itertools +import datetime +import calendar +import thread +import sys + +__all__ = ["rrule", "rruleset", "rrulestr", + "YEARLY", "MONTHLY", "WEEKLY", "DAILY", + "HOURLY", "MINUTELY", "SECONDLY", + "MO", "TU", "WE", "TH", "FR", "SA", "SU"] + +# Every mask is 7 days longer to handle cross-year weekly periods. +M366MASK = tuple([1]*31+[2]*29+[3]*31+[4]*30+[5]*31+[6]*30+ + [7]*31+[8]*31+[9]*30+[10]*31+[11]*30+[12]*31+[1]*7) +M365MASK = list(M366MASK) +M29, M30, M31 = range(1,30), range(1,31), range(1,32) +MDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7]) +MDAY365MASK = list(MDAY366MASK) +M29, M30, M31 = range(-29,0), range(-30,0), range(-31,0) +NMDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7]) +NMDAY365MASK = list(NMDAY366MASK) +M366RANGE = (0,31,60,91,121,152,182,213,244,274,305,335,366) +M365RANGE = (0,31,59,90,120,151,181,212,243,273,304,334,365) +WDAYMASK = [0,1,2,3,4,5,6]*55 +del M29, M30, M31, M365MASK[59], MDAY365MASK[59], NMDAY365MASK[31] +MDAY365MASK = tuple(MDAY365MASK) +M365MASK = tuple(M365MASK) + +(YEARLY, + MONTHLY, + WEEKLY, + DAILY, + HOURLY, + MINUTELY, + SECONDLY) = range(7) + +# Imported on demand. +easter = None +parser = None + +class weekday(object): + __slots__ = ["weekday", "n"] + + def __init__(self, weekday, n=None): + if n == 0: + raise ValueError, "Can't create weekday with n == 0" + self.weekday = weekday + self.n = n + + def __call__(self, n): + if n == self.n: + return self + else: + return self.__class__(self.weekday, n) + + def __eq__(self, other): + try: + if self.weekday != other.weekday or self.n != other.n: + return False + except AttributeError: + return False + return True + + def __repr__(self): + s = ("MO", "TU", "WE", "TH", "FR", "SA", "SU")[self.weekday] + if not self.n: + return s + else: + return "%s(%+d)" % (s, self.n) + +MO, TU, WE, TH, FR, SA, SU = weekdays = tuple([weekday(x) for x in range(7)]) + +class rrulebase: + def __init__(self, cache=False): + if cache: + self._cache = [] + self._cache_lock = thread.allocate_lock() + self._cache_gen = self._iter() + self._cache_complete = False + else: + self._cache = None + self._cache_complete = False + self._len = None + + def __iter__(self): + if self._cache_complete: + return iter(self._cache) + elif self._cache is None: + return self._iter() + else: + return self._iter_cached() + + def _iter_cached(self): + i = 0 + gen = self._cache_gen + cache = self._cache + acquire = self._cache_lock.acquire + release = self._cache_lock.release + while gen: + if i == len(cache): + acquire() + if self._cache_complete: + break + try: + for j in range(10): + cache.append(gen.next()) + except StopIteration: + self._cache_gen = gen = None + self._cache_complete = True + break + release() + yield cache[i] + i += 1 + while i < self._len: + yield cache[i] + i += 1 + + def __getitem__(self, item): + if self._cache_complete: + return self._cache[item] + elif isinstance(item, slice): + if item.step and item.step < 0: + return list(iter(self))[item] + else: + return list(itertools.islice(self, + item.start or 0, + item.stop or sys.maxint, + item.step or 1)) + elif item >= 0: + gen = iter(self) + try: + for i in range(item+1): + res = gen.next() + except StopIteration: + raise IndexError + return res + else: + return list(iter(self))[item] + + def __contains__(self, item): + if self._cache_complete: + return item in self._cache + else: + for i in self: + if i == item: + return True + elif i > item: + return False + return False + + # __len__() introduces a large performance penality. + def count(self): + if self._len is None: + for x in self: pass + return self._len + + def before(self, dt, inc=False): + if self._cache_complete: + gen = self._cache + else: + gen = self + last = None + if inc: + for i in gen: + if i > dt: + break + last = i + else: + for i in gen: + if i >= dt: + break + last = i + return last + + def after(self, dt, inc=False): + if self._cache_complete: + gen = self._cache + else: + gen = self + if inc: + for i in gen: + if i >= dt: + return i + else: + for i in gen: + if i > dt: + return i + return None + + def between(self, after, before, inc=False): + if self._cache_complete: + gen = self._cache + else: + gen = self + started = False + l = [] + if inc: + for i in gen: + if i > before: + break + elif not started: + if i >= after: + started = True + l.append(i) + else: + l.append(i) + else: + for i in gen: + if i >= before: + break + elif not started: + if i > after: + started = True + l.append(i) + else: + l.append(i) + return l + +class rrule(rrulebase): + def __init__(self, freq, dtstart=None, + interval=1, wkst=None, count=None, until=None, bysetpos=None, + bymonth=None, bymonthday=None, byyearday=None, byeaster=None, + byweekno=None, byweekday=None, + byhour=None, byminute=None, bysecond=None, + cache=False): + rrulebase.__init__(self, cache) + global easter + if not dtstart: + dtstart = datetime.datetime.now().replace(microsecond=0) + elif not isinstance(dtstart, datetime.datetime): + dtstart = datetime.datetime.fromordinal(dtstart.toordinal()) + else: + dtstart = dtstart.replace(microsecond=0) + self._dtstart = dtstart + self._tzinfo = dtstart.tzinfo + self._freq = freq + self._interval = interval + self._count = count + if until and not isinstance(until, datetime.datetime): + until = datetime.datetime.fromordinal(until.toordinal()) + self._until = until + if wkst is None: + self._wkst = calendar.firstweekday() + elif type(wkst) is int: + self._wkst = wkst + else: + self._wkst = wkst.weekday + if bysetpos is None: + self._bysetpos = None + elif type(bysetpos) is int: + if bysetpos == 0 or not (-366 <= bysetpos <= 366): + raise ValueError("bysetpos must be between 1 and 366, " + "or between -366 and -1") + self._bysetpos = (bysetpos,) + else: + self._bysetpos = tuple(bysetpos) + for pos in self._bysetpos: + if pos == 0 or not (-366 <= pos <= 366): + raise ValueError("bysetpos must be between 1 and 366, " + "or between -366 and -1") + if not (byweekno or byyearday or bymonthday or + byweekday is not None or byeaster is not None): + if freq == YEARLY: + if not bymonth: + bymonth = dtstart.month + bymonthday = dtstart.day + elif freq == MONTHLY: + bymonthday = dtstart.day + elif freq == WEEKLY: + byweekday = dtstart.weekday() + # bymonth + if not bymonth: + self._bymonth = None + elif type(bymonth) is int: + self._bymonth = (bymonth,) + else: + self._bymonth = tuple(bymonth) + # byyearday + if not byyearday: + self._byyearday = None + elif type(byyearday) is int: + self._byyearday = (byyearday,) + else: + self._byyearday = tuple(byyearday) + # byeaster + if byeaster is not None: + if not easter: + from dateutil import easter + if type(byeaster) is int: + self._byeaster = (byeaster,) + else: + self._byeaster = tuple(byeaster) + else: + self._byeaster = None + # bymonthay + if not bymonthday: + self._bymonthday = () + self._bynmonthday = () + elif type(bymonthday) is int: + if bymonthday < 0: + self._bynmonthday = (bymonthday,) + self._bymonthday = () + else: + self._bymonthday = (bymonthday,) + self._bynmonthday = () + else: + self._bymonthday = tuple([x for x in bymonthday if x > 0]) + self._bynmonthday = tuple([x for x in bymonthday if x < 0]) + # byweekno + if byweekno is None: + self._byweekno = None + elif type(byweekno) is int: + self._byweekno = (byweekno,) + else: + self._byweekno = tuple(byweekno) + # byweekday / bynweekday + if byweekday is None: + self._byweekday = None + self._bynweekday = None + elif type(byweekday) is int: + self._byweekday = (byweekday,) + self._bynweekday = None + elif hasattr(byweekday, "n"): + if not byweekday.n or freq > MONTHLY: + self._byweekday = (byweekday.weekday,) + self._bynweekday = None + else: + self._bynweekday = ((byweekday.weekday, byweekday.n),) + self._byweekday = None + else: + self._byweekday = [] + self._bynweekday = [] + for wday in byweekday: + if type(wday) is int: + self._byweekday.append(wday) + elif not wday.n or freq > MONTHLY: + self._byweekday.append(wday.weekday) + else: + self._bynweekday.append((wday.weekday, wday.n)) + self._byweekday = tuple(self._byweekday) + self._bynweekday = tuple(self._bynweekday) + if not self._byweekday: + self._byweekday = None + elif not self._bynweekday: + self._bynweekday = None + # byhour + if byhour is None: + if freq < HOURLY: + self._byhour = (dtstart.hour,) + else: + self._byhour = None + elif type(byhour) is int: + self._byhour = (byhour,) + else: + self._byhour = tuple(byhour) + # byminute + if byminute is None: + if freq < MINUTELY: + self._byminute = (dtstart.minute,) + else: + self._byminute = None + elif type(byminute) is int: + self._byminute = (byminute,) + else: + self._byminute = tuple(byminute) + # bysecond + if bysecond is None: + if freq < SECONDLY: + self._bysecond = (dtstart.second,) + else: + self._bysecond = None + elif type(bysecond) is int: + self._bysecond = (bysecond,) + else: + self._bysecond = tuple(bysecond) + + if self._freq >= HOURLY: + self._timeset = None + else: + self._timeset = [] + for hour in self._byhour: + for minute in self._byminute: + for second in self._bysecond: + self._timeset.append( + datetime.time(hour, minute, second, + tzinfo=self._tzinfo)) + self._timeset.sort() + self._timeset = tuple(self._timeset) + + def _iter(self): + year, month, day, hour, minute, second, weekday, yearday, _ = \ + self._dtstart.timetuple() + + # Some local variables to speed things up a bit + freq = self._freq + interval = self._interval + wkst = self._wkst + until = self._until + bymonth = self._bymonth + byweekno = self._byweekno + byyearday = self._byyearday + byweekday = self._byweekday + byeaster = self._byeaster + bymonthday = self._bymonthday + bynmonthday = self._bynmonthday + bysetpos = self._bysetpos + byhour = self._byhour + byminute = self._byminute + bysecond = self._bysecond + + ii = _iterinfo(self) + ii.rebuild(year, month) + + getdayset = {YEARLY:ii.ydayset, + MONTHLY:ii.mdayset, + WEEKLY:ii.wdayset, + DAILY:ii.ddayset, + HOURLY:ii.ddayset, + MINUTELY:ii.ddayset, + SECONDLY:ii.ddayset}[freq] + + if freq < HOURLY: + timeset = self._timeset + else: + gettimeset = {HOURLY:ii.htimeset, + MINUTELY:ii.mtimeset, + SECONDLY:ii.stimeset}[freq] + if ((freq >= HOURLY and + self._byhour and hour not in self._byhour) or + (freq >= MINUTELY and + self._byminute and minute not in self._byminute) or + (freq >= SECONDLY and + self._bysecond and second not in self._bysecond)): + timeset = () + else: + timeset = gettimeset(hour, minute, second) + + total = 0 + count = self._count + while True: + # Get dayset with the right frequency + dayset, start, end = getdayset(year, month, day) + + # Do the "hard" work ;-) + filtered = False + for i in dayset[start:end]: + if ((bymonth and ii.mmask[i] not in bymonth) or + (byweekno and not ii.wnomask[i]) or + (byweekday and ii.wdaymask[i] not in byweekday) or + (ii.nwdaymask and not ii.nwdaymask[i]) or + (byeaster and not ii.eastermask[i]) or + ((bymonthday or bynmonthday) and + ii.mdaymask[i] not in bymonthday and + ii.nmdaymask[i] not in bynmonthday) or + (byyearday and + ((i < ii.yearlen and i+1 not in byyearday + and -ii.yearlen+i not in byyearday) or + (i >= ii.yearlen and i+1-ii.yearlen not in byyearday + and -ii.nextyearlen+i-ii.yearlen + not in byyearday)))): + dayset[i] = None + filtered = True + + # Output results + if bysetpos and timeset: + poslist = [] + for pos in bysetpos: + if pos < 0: + daypos, timepos = divmod(pos, len(timeset)) + else: + daypos, timepos = divmod(pos-1, len(timeset)) + try: + i = [x for x in dayset[start:end] + if x is not None][daypos] + time = timeset[timepos] + except IndexError: + pass + else: + date = datetime.date.fromordinal(ii.yearordinal+i) + res = datetime.datetime.combine(date, time) + if res not in poslist: + poslist.append(res) + poslist.sort() + for res in poslist: + if until and res > until: + self._len = total + return + elif res >= self._dtstart: + total += 1 + yield res + if count: + count -= 1 + if not count: + self._len = total + return + else: + for i in dayset[start:end]: + if i is not None: + date = datetime.date.fromordinal(ii.yearordinal+i) + for time in timeset: + res = datetime.datetime.combine(date, time) + if until and res > until: + self._len = total + return + elif res >= self._dtstart: + total += 1 + yield res + if count: + count -= 1 + if not count: + self._len = total + return + + # Handle frequency and interval + fixday = False + if freq == YEARLY: + year += interval + if year > datetime.MAXYEAR: + self._len = total + return + ii.rebuild(year, month) + elif freq == MONTHLY: + month += interval + if month > 12: + div, mod = divmod(month, 12) + month = mod + year += div + if month == 0: + month = 12 + year -= 1 + if year > datetime.MAXYEAR: + self._len = total + return + ii.rebuild(year, month) + elif freq == WEEKLY: + if wkst > weekday: + day += -(weekday+1+(6-wkst))+self._interval*7 + else: + day += -(weekday-wkst)+self._interval*7 + weekday = wkst + fixday = True + elif freq == DAILY: + day += interval + fixday = True + elif freq == HOURLY: + if filtered: + # Jump to one iteration before next day + hour += ((23-hour)//interval)*interval + while True: + hour += interval + div, mod = divmod(hour, 24) + if div: + hour = mod + day += div + fixday = True + if not byhour or hour in byhour: + break + timeset = gettimeset(hour, minute, second) + elif freq == MINUTELY: + if filtered: + # Jump to one iteration before next day + minute += ((1439-(hour*60+minute))//interval)*interval + while True: + minute += interval + div, mod = divmod(minute, 60) + if div: + minute = mod + hour += div + div, mod = divmod(hour, 24) + if div: + hour = mod + day += div + fixday = True + filtered = False + if ((not byhour or hour in byhour) and + (not byminute or minute in byminute)): + break + timeset = gettimeset(hour, minute, second) + elif freq == SECONDLY: + if filtered: + # Jump to one iteration before next day + second += (((86399-(hour*3600+minute*60+second)) + //interval)*interval) + while True: + second += self._interval + div, mod = divmod(second, 60) + if div: + second = mod + minute += div + div, mod = divmod(minute, 60) + if div: + minute = mod + hour += div + div, mod = divmod(hour, 24) + if div: + hour = mod + day += div + fixday = True + if ((not byhour or hour in byhour) and + (not byminute or minute in byminute) and + (not bysecond or second in bysecond)): + break + timeset = gettimeset(hour, minute, second) + + if fixday and day > 28: + daysinmonth = calendar.monthrange(year, month)[1] + if day > daysinmonth: + while day > daysinmonth: + day -= daysinmonth + month += 1 + if month == 13: + month = 1 + year += 1 + if year > datetime.MAXYEAR: + self._len = total + return + daysinmonth = calendar.monthrange(year, month)[1] + ii.rebuild(year, month) + +class _iterinfo(object): + __slots__ = ["rrule", "lastyear", "lastmonth", + "yearlen", "nextyearlen", "yearordinal", "yearweekday", + "mmask", "mrange", "mdaymask", "nmdaymask", + "wdaymask", "wnomask", "nwdaymask", "eastermask"] + + def __init__(self, rrule): + for attr in self.__slots__: + setattr(self, attr, None) + self.rrule = rrule + + def rebuild(self, year, month): + # Every mask is 7 days longer to handle cross-year weekly periods. + rr = self.rrule + if year != self.lastyear: + self.yearlen = 365+calendar.isleap(year) + self.nextyearlen = 365+calendar.isleap(year+1) + firstyday = datetime.date(year, 1, 1) + self.yearordinal = firstyday.toordinal() + self.yearweekday = firstyday.weekday() + + wday = datetime.date(year, 1, 1).weekday() + if self.yearlen == 365: + self.mmask = M365MASK + self.mdaymask = MDAY365MASK + self.nmdaymask = NMDAY365MASK + self.wdaymask = WDAYMASK[wday:] + self.mrange = M365RANGE + else: + self.mmask = M366MASK + self.mdaymask = MDAY366MASK + self.nmdaymask = NMDAY366MASK + self.wdaymask = WDAYMASK[wday:] + self.mrange = M366RANGE + + if not rr._byweekno: + self.wnomask = None + else: + self.wnomask = [0]*(self.yearlen+7) + #no1wkst = firstwkst = self.wdaymask.index(rr._wkst) + no1wkst = firstwkst = (7-self.yearweekday+rr._wkst)%7 + if no1wkst >= 4: + no1wkst = 0 + # Number of days in the year, plus the days we got + # from last year. + wyearlen = self.yearlen+(self.yearweekday-rr._wkst)%7 + else: + # Number of days in the year, minus the days we + # left in last year. + wyearlen = self.yearlen-no1wkst + div, mod = divmod(wyearlen, 7) + numweeks = div+mod//4 + for n in rr._byweekno: + if n < 0: + n += numweeks+1 + if not (0 < n <= numweeks): + continue + if n > 1: + i = no1wkst+(n-1)*7 + if no1wkst != firstwkst: + i -= 7-firstwkst + else: + i = no1wkst + for j in range(7): + self.wnomask[i] = 1 + i += 1 + if self.wdaymask[i] == rr._wkst: + break + if 1 in rr._byweekno: + # Check week number 1 of next year as well + # TODO: Check -numweeks for next year. + i = no1wkst+numweeks*7 + if no1wkst != firstwkst: + i -= 7-firstwkst + if i < self.yearlen: + # If week starts in next year, we + # don't care about it. + for j in range(7): + self.wnomask[i] = 1 + i += 1 + if self.wdaymask[i] == rr._wkst: + break + if no1wkst: + # Check last week number of last year as + # well. If no1wkst is 0, either the year + # started on week start, or week number 1 + # got days from last year, so there are no + # days from last year's last week number in + # this year. + if -1 not in rr._byweekno: + lyearweekday = datetime.date(year-1,1,1).weekday() + lno1wkst = (7-lyearweekday+rr._wkst)%7 + lyearlen = 365+calendar.isleap(year-1) + if lno1wkst >= 4: + lno1wkst = 0 + lnumweeks = 52+(lyearlen+ + (lyearweekday-rr._wkst)%7)%7//4 + else: + lnumweeks = 52+(self.yearlen-no1wkst)%7//4 + else: + lnumweeks = -1 + if lnumweeks in rr._byweekno: + for i in range(no1wkst): + self.wnomask[i] = 1 + + if (rr._bynweekday and + (month != self.lastmonth or year != self.lastyear)): + ranges = [] + if rr._freq == YEARLY: + if rr._bymonth: + for month in rr._bymonth: + ranges.append(self.mrange[month-1:month+1]) + else: + ranges = [(0, self.yearlen)] + elif rr._freq == MONTHLY: + ranges = [self.mrange[month-1:month+1]] + if ranges: + # Weekly frequency won't get here, so we may not + # care about cross-year weekly periods. + self.nwdaymask = [0]*self.yearlen + for first, last in ranges: + last -= 1 + for wday, n in rr._bynweekday: + if n < 0: + i = last+(n+1)*7 + i -= (self.wdaymask[i]-wday)%7 + else: + i = first+(n-1)*7 + i += (7-self.wdaymask[i]+wday)%7 + if first <= i <= last: + self.nwdaymask[i] = 1 + + if rr._byeaster: + self.eastermask = [0]*(self.yearlen+7) + eyday = easter.easter(year).toordinal()-self.yearordinal + for offset in rr._byeaster: + self.eastermask[eyday+offset] = 1 + + self.lastyear = year + self.lastmonth = month + + def ydayset(self, year, month, day): + return range(self.yearlen), 0, self.yearlen + + def mdayset(self, year, month, day): + set = [None]*self.yearlen + start, end = self.mrange[month-1:month+1] + for i in range(start, end): + set[i] = i + return set, start, end + + def wdayset(self, year, month, day): + # We need to handle cross-year weeks here. + set = [None]*(self.yearlen+7) + i = datetime.date(year, month, day).toordinal()-self.yearordinal + start = i + for j in range(7): + set[i] = i + i += 1 + #if (not (0 <= i < self.yearlen) or + # self.wdaymask[i] == self.rrule._wkst): + # This will cross the year boundary, if necessary. + if self.wdaymask[i] == self.rrule._wkst: + break + return set, start, i + + def ddayset(self, year, month, day): + set = [None]*self.yearlen + i = datetime.date(year, month, day).toordinal()-self.yearordinal + set[i] = i + return set, i, i+1 + + def htimeset(self, hour, minute, second): + set = [] + rr = self.rrule + for minute in rr._byminute: + for second in rr._bysecond: + set.append(datetime.time(hour, minute, second, + tzinfo=rr._tzinfo)) + set.sort() + return set + + def mtimeset(self, hour, minute, second): + set = [] + rr = self.rrule + for second in rr._bysecond: + set.append(datetime.time(hour, minute, second, tzinfo=rr._tzinfo)) + set.sort() + return set + + def stimeset(self, hour, minute, second): + return (datetime.time(hour, minute, second, + tzinfo=self.rrule._tzinfo),) + + +class rruleset(rrulebase): + + class _genitem: + def __init__(self, genlist, gen): + try: + self.dt = gen() + genlist.append(self) + except StopIteration: + pass + self.genlist = genlist + self.gen = gen + + def next(self): + try: + self.dt = self.gen() + except StopIteration: + self.genlist.remove(self) + + def __cmp__(self, other): + return cmp(self.dt, other.dt) + + def __init__(self, cache=False): + rrulebase.__init__(self, cache) + self._rrule = [] + self._rdate = [] + self._exrule = [] + self._exdate = [] + + def rrule(self, rrule): + self._rrule.append(rrule) + + def rdate(self, rdate): + self._rdate.append(rdate) + + def exrule(self, exrule): + self._exrule.append(exrule) + + def exdate(self, exdate): + self._exdate.append(exdate) + + def _iter(self): + rlist = [] + self._rdate.sort() + self._genitem(rlist, iter(self._rdate).next) + for gen in [iter(x).next for x in self._rrule]: + self._genitem(rlist, gen) + rlist.sort() + exlist = [] + self._exdate.sort() + self._genitem(exlist, iter(self._exdate).next) + for gen in [iter(x).next for x in self._exrule]: + self._genitem(exlist, gen) + exlist.sort() + lastdt = None + total = 0 + while rlist: + ritem = rlist[0] + if not lastdt or lastdt != ritem.dt: + while exlist and exlist[0] < ritem: + exlist[0].next() + exlist.sort() + if not exlist or ritem != exlist[0]: + total += 1 + yield ritem.dt + lastdt = ritem.dt + ritem.next() + rlist.sort() + self._len = total + +class _rrulestr: + + _freq_map = {"YEARLY": YEARLY, + "MONTHLY": MONTHLY, + "WEEKLY": WEEKLY, + "DAILY": DAILY, + "HOURLY": HOURLY, + "MINUTELY": MINUTELY, + "SECONDLY": SECONDLY} + + _weekday_map = {"MO":0,"TU":1,"WE":2,"TH":3,"FR":4,"SA":5,"SU":6} + + def _handle_int(self, rrkwargs, name, value, **kwargs): + rrkwargs[name.lower()] = int(value) + + def _handle_int_list(self, rrkwargs, name, value, **kwargs): + rrkwargs[name.lower()] = [int(x) for x in value.split(',')] + + _handle_INTERVAL = _handle_int + _handle_COUNT = _handle_int + _handle_BYSETPOS = _handle_int_list + _handle_BYMONTH = _handle_int_list + _handle_BYMONTHDAY = _handle_int_list + _handle_BYYEARDAY = _handle_int_list + _handle_BYEASTER = _handle_int_list + _handle_BYWEEKNO = _handle_int_list + _handle_BYHOUR = _handle_int_list + _handle_BYMINUTE = _handle_int_list + _handle_BYSECOND = _handle_int_list + + def _handle_FREQ(self, rrkwargs, name, value, **kwargs): + rrkwargs["freq"] = self._freq_map[value] + + def _handle_UNTIL(self, rrkwargs, name, value, **kwargs): + global parser + if not parser: + from dateutil import parser + try: + rrkwargs["until"] = parser.parse(value, + ignoretz=kwargs.get("ignoretz"), + tzinfos=kwargs.get("tzinfos")) + except ValueError: + raise ValueError, "invalid until date" + + def _handle_WKST(self, rrkwargs, name, value, **kwargs): + rrkwargs["wkst"] = self._weekday_map[value] + + def _handle_BYWEEKDAY(self, rrkwargs, name, value, **kwarsg): + l = [] + for wday in value.split(','): + for i in range(len(wday)): + if wday[i] not in '+-0123456789': + break + n = wday[:i] or None + w = wday[i:] + if n: n = int(n) + l.append(weekdays[self._weekday_map[w]](n)) + rrkwargs["byweekday"] = l + + _handle_BYDAY = _handle_BYWEEKDAY + + def _parse_rfc_rrule(self, line, + dtstart=None, + cache=False, + ignoretz=False, + tzinfos=None): + if line.find(':') != -1: + name, value = line.split(':') + if name != "RRULE": + raise ValueError, "unknown parameter name" + else: + value = line + rrkwargs = {} + for pair in value.split(';'): + name, value = pair.split('=') + name = name.upper() + value = value.upper() + try: + getattr(self, "_handle_"+name)(rrkwargs, name, value, + ignoretz=ignoretz, + tzinfos=tzinfos) + except AttributeError: + raise ValueError, "unknown parameter '%s'" % name + except (KeyError, ValueError): + raise ValueError, "invalid '%s': %s" % (name, value) + return rrule(dtstart=dtstart, cache=cache, **rrkwargs) + + def _parse_rfc(self, s, + dtstart=None, + cache=False, + unfold=False, + forceset=False, + compatible=False, + ignoretz=False, + tzinfos=None): + global parser + if compatible: + forceset = True + unfold = True + s = s.upper() + if not s.strip(): + raise ValueError, "empty string" + if unfold: + lines = s.splitlines() + i = 0 + while i < len(lines): + line = lines[i].rstrip() + if not line: + del lines[i] + elif i > 0 and line[0] == " ": + lines[i-1] += line[1:] + del lines[i] + else: + i += 1 + else: + lines = s.split() + if (not forceset and len(lines) == 1 and + (s.find(':') == -1 or s.startswith('RRULE:'))): + return self._parse_rfc_rrule(lines[0], cache=cache, + dtstart=dtstart, ignoretz=ignoretz, + tzinfos=tzinfos) + else: + rrulevals = [] + rdatevals = [] + exrulevals = [] + exdatevals = [] + for line in lines: + if not line: + continue + if line.find(':') == -1: + name = "RRULE" + value = line + else: + name, value = line.split(':', 1) + parms = name.split(';') + if not parms: + raise ValueError, "empty property name" + name = parms[0] + parms = parms[1:] + if name == "RRULE": + for parm in parms: + raise ValueError, "unsupported RRULE parm: "+parm + rrulevals.append(value) + elif name == "RDATE": + for parm in parms: + if parm != "VALUE=DATE-TIME": + raise ValueError, "unsupported RDATE parm: "+parm + rdatevals.append(value) + elif name == "EXRULE": + for parm in parms: + raise ValueError, "unsupported EXRULE parm: "+parm + exrulevals.append(value) + elif name == "EXDATE": + for parm in parms: + if parm != "VALUE=DATE-TIME": + raise ValueError, "unsupported RDATE parm: "+parm + exdatevals.append(value) + elif name == "DTSTART": + for parm in parms: + raise ValueError, "unsupported DTSTART parm: "+parm + if not parser: + from dateutil import parser + dtstart = parser.parse(value, ignoretz=ignoretz, + tzinfos=tzinfos) + else: + raise ValueError, "unsupported property: "+name + if (forceset or len(rrulevals) > 1 or + rdatevals or exrulevals or exdatevals): + if not parser and (rdatevals or exdatevals): + from dateutil import parser + set = rruleset(cache=cache) + for value in rrulevals: + set.rrule(self._parse_rfc_rrule(value, dtstart=dtstart, + ignoretz=ignoretz, + tzinfos=tzinfos)) + for value in rdatevals: + for datestr in value.split(','): + set.rdate(parser.parse(datestr, + ignoretz=ignoretz, + tzinfos=tzinfos)) + for value in exrulevals: + set.exrule(self._parse_rfc_rrule(value, dtstart=dtstart, + ignoretz=ignoretz, + tzinfos=tzinfos)) + for value in exdatevals: + for datestr in value.split(','): + set.exdate(parser.parse(datestr, + ignoretz=ignoretz, + tzinfos=tzinfos)) + if compatible and dtstart: + set.rdate(dtstart) + return set + else: + return self._parse_rfc_rrule(rrulevals[0], + dtstart=dtstart, + cache=cache, + ignoretz=ignoretz, + tzinfos=tzinfos) + + def __call__(self, s, **kwargs): + return self._parse_rfc(s, **kwargs) + +rrulestr = _rrulestr() + +# vim:ts=4:sw=4:et diff -Nru matplotlib-1.1.1/lib/dateutil_py2/tz.py matplotlib-1.2.0/lib/dateutil_py2/tz.py --- matplotlib-1.1.1/lib/dateutil_py2/tz.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py2/tz.py 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,951 @@ +""" +Copyright (c) 2003-2007 Gustavo Niemeyer + +This module offers extensions to the standard python 2.3+ +datetime module. +""" +__author__ = "Gustavo Niemeyer " +__license__ = "PSF License" + +import datetime +import struct +import time +import sys +import os + +relativedelta = None +parser = None +rrule = None + +__all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange", + "tzstr", "tzical", "tzwin", "tzwinlocal", "gettz"] + +try: + from dateutil.tzwin import tzwin, tzwinlocal +except (ImportError, OSError): + tzwin, tzwinlocal = None, None + +ZERO = datetime.timedelta(0) +EPOCHORDINAL = datetime.datetime.utcfromtimestamp(0).toordinal() + +class tzutc(datetime.tzinfo): + + def utcoffset(self, dt): + return ZERO + + def dst(self, dt): + return ZERO + + def tzname(self, dt): + return "UTC" + + def __eq__(self, other): + return (isinstance(other, tzutc) or + (isinstance(other, tzoffset) and other._offset == ZERO)) + + def __ne__(self, other): + return not self.__eq__(other) + + def __repr__(self): + return "%s()" % self.__class__.__name__ + + __reduce__ = object.__reduce__ + +class tzoffset(datetime.tzinfo): + + def __init__(self, name, offset): + self._name = name + self._offset = datetime.timedelta(seconds=offset) + + def utcoffset(self, dt): + return self._offset + + def dst(self, dt): + return ZERO + + def tzname(self, dt): + return self._name + + def __eq__(self, other): + return (isinstance(other, tzoffset) and + self._offset == other._offset) + + def __ne__(self, other): + return not self.__eq__(other) + + def __repr__(self): + return "%s(%s, %s)" % (self.__class__.__name__, + `self._name`, + self._offset.days*86400+self._offset.seconds) + + __reduce__ = object.__reduce__ + +class tzlocal(datetime.tzinfo): + + _std_offset = datetime.timedelta(seconds=-time.timezone) + if time.daylight: + _dst_offset = datetime.timedelta(seconds=-time.altzone) + else: + _dst_offset = _std_offset + + def utcoffset(self, dt): + if self._isdst(dt): + return self._dst_offset + else: + return self._std_offset + + def dst(self, dt): + if self._isdst(dt): + return self._dst_offset-self._std_offset + else: + return ZERO + + def tzname(self, dt): + return time.tzname[self._isdst(dt)] + + def _isdst(self, dt): + # We can't use mktime here. It is unstable when deciding if + # the hour near to a change is DST or not. + # + # timestamp = time.mktime((dt.year, dt.month, dt.day, dt.hour, + # dt.minute, dt.second, dt.weekday(), 0, -1)) + # return time.localtime(timestamp).tm_isdst + # + # The code above yields the following result: + # + #>>> import tz, datetime + #>>> t = tz.tzlocal() + #>>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname() + #'BRDT' + #>>> datetime.datetime(2003,2,16,0,tzinfo=t).tzname() + #'BRST' + #>>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname() + #'BRST' + #>>> datetime.datetime(2003,2,15,22,tzinfo=t).tzname() + #'BRDT' + #>>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname() + #'BRDT' + # + # Here is a more stable implementation: + # + timestamp = ((dt.toordinal() - EPOCHORDINAL) * 86400 + + dt.hour * 3600 + + dt.minute * 60 + + dt.second) + return time.localtime(timestamp+time.timezone).tm_isdst + + def __eq__(self, other): + if not isinstance(other, tzlocal): + return False + return (self._std_offset == other._std_offset and + self._dst_offset == other._dst_offset) + return True + + def __ne__(self, other): + return not self.__eq__(other) + + def __repr__(self): + return "%s()" % self.__class__.__name__ + + __reduce__ = object.__reduce__ + +class _ttinfo(object): + __slots__ = ["offset", "delta", "isdst", "abbr", "isstd", "isgmt"] + + def __init__(self): + for attr in self.__slots__: + setattr(self, attr, None) + + def __repr__(self): + l = [] + for attr in self.__slots__: + value = getattr(self, attr) + if value is not None: + l.append("%s=%s" % (attr, `value`)) + return "%s(%s)" % (self.__class__.__name__, ", ".join(l)) + + def __eq__(self, other): + if not isinstance(other, _ttinfo): + return False + return (self.offset == other.offset and + self.delta == other.delta and + self.isdst == other.isdst and + self.abbr == other.abbr and + self.isstd == other.isstd and + self.isgmt == other.isgmt) + + def __ne__(self, other): + return not self.__eq__(other) + + def __getstate__(self): + state = {} + for name in self.__slots__: + state[name] = getattr(self, name, None) + return state + + def __setstate__(self, state): + for name in self.__slots__: + if name in state: + setattr(self, name, state[name]) + +class tzfile(datetime.tzinfo): + + # http://www.twinsun.com/tz/tz-link.htm + # ftp://elsie.nci.nih.gov/pub/tz*.tar.gz + + def __init__(self, fileobj): + if isinstance(fileobj, basestring): + self._filename = fileobj + fileobj = open(fileobj) + elif hasattr(fileobj, "name"): + self._filename = fileobj.name + else: + self._filename = `fileobj` + + # From tzfile(5): + # + # The time zone information files used by tzset(3) + # begin with the magic characters "TZif" to identify + # them as time zone information files, followed by + # sixteen bytes reserved for future use, followed by + # six four-byte values of type long, written in a + # ``standard'' byte order (the high-order byte + # of the value is written first). + + if fileobj.read(4) != "TZif": + raise ValueError, "magic not found" + + fileobj.read(16) + + ( + # The number of UTC/local indicators stored in the file. + ttisgmtcnt, + + # The number of standard/wall indicators stored in the file. + ttisstdcnt, + + # The number of leap seconds for which data is + # stored in the file. + leapcnt, + + # The number of "transition times" for which data + # is stored in the file. + timecnt, + + # The number of "local time types" for which data + # is stored in the file (must not be zero). + typecnt, + + # The number of characters of "time zone + # abbreviation strings" stored in the file. + charcnt, + + ) = struct.unpack(">6l", fileobj.read(24)) + + # The above header is followed by tzh_timecnt four-byte + # values of type long, sorted in ascending order. + # These values are written in ``standard'' byte order. + # Each is used as a transition time (as returned by + # time(2)) at which the rules for computing local time + # change. + + if timecnt: + self._trans_list = struct.unpack(">%dl" % timecnt, + fileobj.read(timecnt*4)) + else: + self._trans_list = [] + + # Next come tzh_timecnt one-byte values of type unsigned + # char; each one tells which of the different types of + # ``local time'' types described in the file is associated + # with the same-indexed transition time. These values + # serve as indices into an array of ttinfo structures that + # appears next in the file. + + if timecnt: + self._trans_idx = struct.unpack(">%dB" % timecnt, + fileobj.read(timecnt)) + else: + self._trans_idx = [] + + # Each ttinfo structure is written as a four-byte value + # for tt_gmtoff of type long, in a standard byte + # order, followed by a one-byte value for tt_isdst + # and a one-byte value for tt_abbrind. In each + # structure, tt_gmtoff gives the number of + # seconds to be added to UTC, tt_isdst tells whether + # tm_isdst should be set by localtime(3), and + # tt_abbrind serves as an index into the array of + # time zone abbreviation characters that follow the + # ttinfo structure(s) in the file. + + ttinfo = [] + + for i in range(typecnt): + ttinfo.append(struct.unpack(">lbb", fileobj.read(6))) + + abbr = fileobj.read(charcnt) + + # Then there are tzh_leapcnt pairs of four-byte + # values, written in standard byte order; the + # first value of each pair gives the time (as + # returned by time(2)) at which a leap second + # occurs; the second gives the total number of + # leap seconds to be applied after the given time. + # The pairs of values are sorted in ascending order + # by time. + + # Not used, for now + if leapcnt: + leap = struct.unpack(">%dl" % (leapcnt*2), + fileobj.read(leapcnt*8)) + + # Then there are tzh_ttisstdcnt standard/wall + # indicators, each stored as a one-byte value; + # they tell whether the transition times associated + # with local time types were specified as standard + # time or wall clock time, and are used when + # a time zone file is used in handling POSIX-style + # time zone environment variables. + + if ttisstdcnt: + isstd = struct.unpack(">%db" % ttisstdcnt, + fileobj.read(ttisstdcnt)) + + # Finally, there are tzh_ttisgmtcnt UTC/local + # indicators, each stored as a one-byte value; + # they tell whether the transition times associated + # with local time types were specified as UTC or + # local time, and are used when a time zone file + # is used in handling POSIX-style time zone envi- + # ronment variables. + + if ttisgmtcnt: + isgmt = struct.unpack(">%db" % ttisgmtcnt, + fileobj.read(ttisgmtcnt)) + + # ** Everything has been read ** + + # Build ttinfo list + self._ttinfo_list = [] + for i in range(typecnt): + gmtoff, isdst, abbrind = ttinfo[i] + # Round to full-minutes if that's not the case. Python's + # datetime doesn't accept sub-minute timezones. Check + # http://python.org/sf/1447945 for some information. + gmtoff = (gmtoff+30)//60*60 + tti = _ttinfo() + tti.offset = gmtoff + tti.delta = datetime.timedelta(seconds=gmtoff) + tti.isdst = isdst + tti.abbr = abbr[abbrind:abbr.find('\x00', abbrind)] + tti.isstd = (ttisstdcnt > i and isstd[i] != 0) + tti.isgmt = (ttisgmtcnt > i and isgmt[i] != 0) + self._ttinfo_list.append(tti) + + # Replace ttinfo indexes for ttinfo objects. + trans_idx = [] + for idx in self._trans_idx: + trans_idx.append(self._ttinfo_list[idx]) + self._trans_idx = tuple(trans_idx) + + # Set standard, dst, and before ttinfos. before will be + # used when a given time is before any transitions, + # and will be set to the first non-dst ttinfo, or to + # the first dst, if all of them are dst. + self._ttinfo_std = None + self._ttinfo_dst = None + self._ttinfo_before = None + if self._ttinfo_list: + if not self._trans_list: + self._ttinfo_std = self._ttinfo_first = self._ttinfo_list[0] + else: + for i in range(timecnt-1,-1,-1): + tti = self._trans_idx[i] + if not self._ttinfo_std and not tti.isdst: + self._ttinfo_std = tti + elif not self._ttinfo_dst and tti.isdst: + self._ttinfo_dst = tti + if self._ttinfo_std and self._ttinfo_dst: + break + else: + if self._ttinfo_dst and not self._ttinfo_std: + self._ttinfo_std = self._ttinfo_dst + + for tti in self._ttinfo_list: + if not tti.isdst: + self._ttinfo_before = tti + break + else: + self._ttinfo_before = self._ttinfo_list[0] + + # Now fix transition times to become relative to wall time. + # + # I'm not sure about this. In my tests, the tz source file + # is setup to wall time, and in the binary file isstd and + # isgmt are off, so it should be in wall time. OTOH, it's + # always in gmt time. Let me know if you have comments + # about this. + laststdoffset = 0 + self._trans_list = list(self._trans_list) + for i in range(len(self._trans_list)): + tti = self._trans_idx[i] + if not tti.isdst: + # This is std time. + self._trans_list[i] += tti.offset + laststdoffset = tti.offset + else: + # This is dst time. Convert to std. + self._trans_list[i] += laststdoffset + self._trans_list = tuple(self._trans_list) + + def _find_ttinfo(self, dt, laststd=0): + timestamp = ((dt.toordinal() - EPOCHORDINAL) * 86400 + + dt.hour * 3600 + + dt.minute * 60 + + dt.second) + idx = 0 + for trans in self._trans_list: + if timestamp < trans: + break + idx += 1 + else: + return self._ttinfo_std + if idx == 0: + return self._ttinfo_before + if laststd: + while idx > 0: + tti = self._trans_idx[idx-1] + if not tti.isdst: + return tti + idx -= 1 + else: + return self._ttinfo_std + else: + return self._trans_idx[idx-1] + + def utcoffset(self, dt): + if not self._ttinfo_std: + return ZERO + return self._find_ttinfo(dt).delta + + def dst(self, dt): + if not self._ttinfo_dst: + return ZERO + tti = self._find_ttinfo(dt) + if not tti.isdst: + return ZERO + + # The documentation says that utcoffset()-dst() must + # be constant for every dt. + return tti.delta-self._find_ttinfo(dt, laststd=1).delta + + # An alternative for that would be: + # + # return self._ttinfo_dst.offset-self._ttinfo_std.offset + # + # However, this class stores historical changes in the + # dst offset, so I belive that this wouldn't be the right + # way to implement this. + + def tzname(self, dt): + if not self._ttinfo_std: + return None + return self._find_ttinfo(dt).abbr + + def __eq__(self, other): + if not isinstance(other, tzfile): + return False + return (self._trans_list == other._trans_list and + self._trans_idx == other._trans_idx and + self._ttinfo_list == other._ttinfo_list) + + def __ne__(self, other): + return not self.__eq__(other) + + + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__, `self._filename`) + + def __reduce__(self): + if not os.path.isfile(self._filename): + raise ValueError, "Unpickable %s class" % self.__class__.__name__ + return (self.__class__, (self._filename,)) + +class tzrange(datetime.tzinfo): + + def __init__(self, stdabbr, stdoffset=None, + dstabbr=None, dstoffset=None, + start=None, end=None): + global relativedelta + if not relativedelta: + from dateutil import relativedelta + self._std_abbr = stdabbr + self._dst_abbr = dstabbr + if stdoffset is not None: + self._std_offset = datetime.timedelta(seconds=stdoffset) + else: + self._std_offset = ZERO + if dstoffset is not None: + self._dst_offset = datetime.timedelta(seconds=dstoffset) + elif dstabbr and stdoffset is not None: + self._dst_offset = self._std_offset+datetime.timedelta(hours=+1) + else: + self._dst_offset = ZERO + if dstabbr and start is None: + self._start_delta = relativedelta.relativedelta( + hours=+2, month=4, day=1, weekday=relativedelta.SU(+1)) + else: + self._start_delta = start + if dstabbr and end is None: + self._end_delta = relativedelta.relativedelta( + hours=+1, month=10, day=31, weekday=relativedelta.SU(-1)) + else: + self._end_delta = end + + def utcoffset(self, dt): + if self._isdst(dt): + return self._dst_offset + else: + return self._std_offset + + def dst(self, dt): + if self._isdst(dt): + return self._dst_offset-self._std_offset + else: + return ZERO + + def tzname(self, dt): + if self._isdst(dt): + return self._dst_abbr + else: + return self._std_abbr + + def _isdst(self, dt): + if not self._start_delta: + return False + year = datetime.datetime(dt.year,1,1) + start = year+self._start_delta + end = year+self._end_delta + dt = dt.replace(tzinfo=None) + if start < end: + return dt >= start and dt < end + else: + return dt >= start or dt < end + + def __eq__(self, other): + if not isinstance(other, tzrange): + return False + return (self._std_abbr == other._std_abbr and + self._dst_abbr == other._dst_abbr and + self._std_offset == other._std_offset and + self._dst_offset == other._dst_offset and + self._start_delta == other._start_delta and + self._end_delta == other._end_delta) + + def __ne__(self, other): + return not self.__eq__(other) + + def __repr__(self): + return "%s(...)" % self.__class__.__name__ + + __reduce__ = object.__reduce__ + +class tzstr(tzrange): + + def __init__(self, s): + global parser + if not parser: + from dateutil import parser + self._s = s + + res = parser._parsetz(s) + if res is None: + raise ValueError, "unknown string format" + + # Here we break the compatibility with the TZ variable handling. + # GMT-3 actually *means* the timezone -3. + if res.stdabbr in ("GMT", "UTC"): + res.stdoffset *= -1 + + # We must initialize it first, since _delta() needs + # _std_offset and _dst_offset set. Use False in start/end + # to avoid building it two times. + tzrange.__init__(self, res.stdabbr, res.stdoffset, + res.dstabbr, res.dstoffset, + start=False, end=False) + + if not res.dstabbr: + self._start_delta = None + self._end_delta = None + else: + self._start_delta = self._delta(res.start) + if self._start_delta: + self._end_delta = self._delta(res.end, isend=1) + + def _delta(self, x, isend=0): + kwargs = {} + if x.month is not None: + kwargs["month"] = x.month + if x.weekday is not None: + kwargs["weekday"] = relativedelta.weekday(x.weekday, x.week) + if x.week > 0: + kwargs["day"] = 1 + else: + kwargs["day"] = 31 + elif x.day: + kwargs["day"] = x.day + elif x.yday is not None: + kwargs["yearday"] = x.yday + elif x.jyday is not None: + kwargs["nlyearday"] = x.jyday + if not kwargs: + # Default is to start on first sunday of april, and end + # on last sunday of october. + if not isend: + kwargs["month"] = 4 + kwargs["day"] = 1 + kwargs["weekday"] = relativedelta.SU(+1) + else: + kwargs["month"] = 10 + kwargs["day"] = 31 + kwargs["weekday"] = relativedelta.SU(-1) + if x.time is not None: + kwargs["seconds"] = x.time + else: + # Default is 2AM. + kwargs["seconds"] = 7200 + if isend: + # Convert to standard time, to follow the documented way + # of working with the extra hour. See the documentation + # of the tzinfo class. + delta = self._dst_offset-self._std_offset + kwargs["seconds"] -= delta.seconds+delta.days*86400 + return relativedelta.relativedelta(**kwargs) + + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__, `self._s`) + +class _tzicalvtzcomp: + def __init__(self, tzoffsetfrom, tzoffsetto, isdst, + tzname=None, rrule=None): + self.tzoffsetfrom = datetime.timedelta(seconds=tzoffsetfrom) + self.tzoffsetto = datetime.timedelta(seconds=tzoffsetto) + self.tzoffsetdiff = self.tzoffsetto-self.tzoffsetfrom + self.isdst = isdst + self.tzname = tzname + self.rrule = rrule + +class _tzicalvtz(datetime.tzinfo): + def __init__(self, tzid, comps=[]): + self._tzid = tzid + self._comps = comps + self._cachedate = [] + self._cachecomp = [] + + def _find_comp(self, dt): + if len(self._comps) == 1: + return self._comps[0] + dt = dt.replace(tzinfo=None) + try: + return self._cachecomp[self._cachedate.index(dt)] + except ValueError: + pass + lastcomp = None + lastcompdt = None + for comp in self._comps: + if not comp.isdst: + # Handle the extra hour in DST -> STD + compdt = comp.rrule.before(dt-comp.tzoffsetdiff, inc=True) + else: + compdt = comp.rrule.before(dt, inc=True) + if compdt and (not lastcompdt or lastcompdt < compdt): + lastcompdt = compdt + lastcomp = comp + if not lastcomp: + # RFC says nothing about what to do when a given + # time is before the first onset date. We'll look for the + # first standard component, or the first component, if + # none is found. + for comp in self._comps: + if not comp.isdst: + lastcomp = comp + break + else: + lastcomp = comp[0] + self._cachedate.insert(0, dt) + self._cachecomp.insert(0, lastcomp) + if len(self._cachedate) > 10: + self._cachedate.pop() + self._cachecomp.pop() + return lastcomp + + def utcoffset(self, dt): + return self._find_comp(dt).tzoffsetto + + def dst(self, dt): + comp = self._find_comp(dt) + if comp.isdst: + return comp.tzoffsetdiff + else: + return ZERO + + def tzname(self, dt): + return self._find_comp(dt).tzname + + def __repr__(self): + return "" % `self._tzid` + + __reduce__ = object.__reduce__ + +class tzical: + def __init__(self, fileobj): + global rrule + if not rrule: + from dateutil import rrule + + if isinstance(fileobj, basestring): + self._s = fileobj + fileobj = open(fileobj) + elif hasattr(fileobj, "name"): + self._s = fileobj.name + else: + self._s = `fileobj` + + self._vtz = {} + + self._parse_rfc(fileobj.read()) + + def keys(self): + return self._vtz.keys() + + def get(self, tzid=None): + if tzid is None: + keys = self._vtz.keys() + if len(keys) == 0: + raise ValueError, "no timezones defined" + elif len(keys) > 1: + raise ValueError, "more than one timezone available" + tzid = keys[0] + return self._vtz.get(tzid) + + def _parse_offset(self, s): + s = s.strip() + if not s: + raise ValueError, "empty offset" + if s[0] in ('+', '-'): + signal = (-1,+1)[s[0]=='+'] + s = s[1:] + else: + signal = +1 + if len(s) == 4: + return (int(s[:2])*3600+int(s[2:])*60)*signal + elif len(s) == 6: + return (int(s[:2])*3600+int(s[2:4])*60+int(s[4:]))*signal + else: + raise ValueError, "invalid offset: "+s + + def _parse_rfc(self, s): + lines = s.splitlines() + if not lines: + raise ValueError, "empty string" + + # Unfold + i = 0 + while i < len(lines): + line = lines[i].rstrip() + if not line: + del lines[i] + elif i > 0 and line[0] == " ": + lines[i-1] += line[1:] + del lines[i] + else: + i += 1 + + tzid = None + comps = [] + invtz = False + comptype = None + for line in lines: + if not line: + continue + name, value = line.split(':', 1) + parms = name.split(';') + if not parms: + raise ValueError, "empty property name" + name = parms[0].upper() + parms = parms[1:] + if invtz: + if name == "BEGIN": + if value in ("STANDARD", "DAYLIGHT"): + # Process component + pass + else: + raise ValueError, "unknown component: "+value + comptype = value + founddtstart = False + tzoffsetfrom = None + tzoffsetto = None + rrulelines = [] + tzname = None + elif name == "END": + if value == "VTIMEZONE": + if comptype: + raise ValueError, \ + "component not closed: "+comptype + if not tzid: + raise ValueError, \ + "mandatory TZID not found" + if not comps: + raise ValueError, \ + "at least one component is needed" + # Process vtimezone + self._vtz[tzid] = _tzicalvtz(tzid, comps) + invtz = False + elif value == comptype: + if not founddtstart: + raise ValueError, \ + "mandatory DTSTART not found" + if tzoffsetfrom is None: + raise ValueError, \ + "mandatory TZOFFSETFROM not found" + if tzoffsetto is None: + raise ValueError, \ + "mandatory TZOFFSETFROM not found" + # Process component + rr = None + if rrulelines: + rr = rrule.rrulestr("\n".join(rrulelines), + compatible=True, + ignoretz=True, + cache=True) + comp = _tzicalvtzcomp(tzoffsetfrom, tzoffsetto, + (comptype == "DAYLIGHT"), + tzname, rr) + comps.append(comp) + comptype = None + else: + raise ValueError, \ + "invalid component end: "+value + elif comptype: + if name == "DTSTART": + rrulelines.append(line) + founddtstart = True + elif name in ("RRULE", "RDATE", "EXRULE", "EXDATE"): + rrulelines.append(line) + elif name == "TZOFFSETFROM": + if parms: + raise ValueError, \ + "unsupported %s parm: %s "%(name, parms[0]) + tzoffsetfrom = self._parse_offset(value) + elif name == "TZOFFSETTO": + if parms: + raise ValueError, \ + "unsupported TZOFFSETTO parm: "+parms[0] + tzoffsetto = self._parse_offset(value) + elif name == "TZNAME": + if parms: + raise ValueError, \ + "unsupported TZNAME parm: "+parms[0] + tzname = value + elif name == "COMMENT": + pass + else: + raise ValueError, "unsupported property: "+name + else: + if name == "TZID": + if parms: + raise ValueError, \ + "unsupported TZID parm: "+parms[0] + tzid = value + elif name in ("TZURL", "LAST-MODIFIED", "COMMENT"): + pass + else: + raise ValueError, "unsupported property: "+name + elif name == "BEGIN" and value == "VTIMEZONE": + tzid = None + comps = [] + invtz = True + + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__, `self._s`) + +if sys.platform != "win32": + TZFILES = ["/etc/localtime", "localtime"] + TZPATHS = ["/usr/share/zoneinfo", "/usr/lib/zoneinfo", "/etc/zoneinfo"] +else: + TZFILES = [] + TZPATHS = [] + +def gettz(name=None): + tz = None + if not name: + try: + name = os.environ["TZ"] + except KeyError: + pass + if name is None or name == ":": + for filepath in TZFILES: + if not os.path.isabs(filepath): + filename = filepath + for path in TZPATHS: + filepath = os.path.join(path, filename) + if os.path.isfile(filepath): + break + else: + continue + if os.path.isfile(filepath): + try: + tz = tzfile(filepath) + break + except (IOError, OSError, ValueError): + pass + else: + tz = tzlocal() + else: + if name.startswith(":"): + name = name[:-1] + if os.path.isabs(name): + if os.path.isfile(name): + tz = tzfile(name) + else: + tz = None + else: + for path in TZPATHS: + filepath = os.path.join(path, name) + if not os.path.isfile(filepath): + filepath = filepath.replace(' ','_') + if not os.path.isfile(filepath): + continue + try: + tz = tzfile(filepath) + break + except (IOError, OSError, ValueError): + pass + else: + tz = None + if tzwin: + try: + tz = tzwin(name) + except OSError: + pass + if not tz: + from dateutil.zoneinfo import gettz + tz = gettz(name) + if not tz: + for c in name: + # name must have at least one offset to be a tzstr + if c in "0123456789": + try: + tz = tzstr(name) + except ValueError: + pass + break + else: + if name in ("GMT", "UTC"): + tz = tzutc() + elif name in time.tzname: + tz = tzlocal() + return tz + +# vim:ts=4:sw=4:et diff -Nru matplotlib-1.1.1/lib/dateutil_py2/tzwin.py matplotlib-1.2.0/lib/dateutil_py2/tzwin.py --- matplotlib-1.1.1/lib/dateutil_py2/tzwin.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py2/tzwin.py 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,180 @@ +# This code was originally contributed by Jeffrey Harris. +import datetime +import struct +import _winreg + +__author__ = "Jeffrey Harris & Gustavo Niemeyer " + +__all__ = ["tzwin", "tzwinlocal"] + +ONEWEEK = datetime.timedelta(7) + +TZKEYNAMENT = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones" +TZKEYNAME9X = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones" +TZLOCALKEYNAME = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation" + +def _settzkeyname(): + global TZKEYNAME + handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) + try: + _winreg.OpenKey(handle, TZKEYNAMENT).Close() + TZKEYNAME = TZKEYNAMENT + except WindowsError: + TZKEYNAME = TZKEYNAME9X + handle.Close() + +_settzkeyname() + +class tzwinbase(datetime.tzinfo): + """tzinfo class based on win32's timezones available in the registry.""" + + def utcoffset(self, dt): + if self._isdst(dt): + return datetime.timedelta(minutes=self._dstoffset) + else: + return datetime.timedelta(minutes=self._stdoffset) + + def dst(self, dt): + if self._isdst(dt): + minutes = self._dstoffset - self._stdoffset + return datetime.timedelta(minutes=minutes) + else: + return datetime.timedelta(0) + + def tzname(self, dt): + if self._isdst(dt): + return self._dstname + else: + return self._stdname + + def list(): + """Return a list of all time zones known to the system.""" + handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) + tzkey = _winreg.OpenKey(handle, TZKEYNAME) + result = [_winreg.EnumKey(tzkey, i) + for i in range(_winreg.QueryInfoKey(tzkey)[0])] + tzkey.Close() + handle.Close() + return result + list = staticmethod(list) + + def display(self): + return self._display + + def _isdst(self, dt): + dston = picknthweekday(dt.year, self._dstmonth, self._dstdayofweek, + self._dsthour, self._dstminute, + self._dstweeknumber) + dstoff = picknthweekday(dt.year, self._stdmonth, self._stddayofweek, + self._stdhour, self._stdminute, + self._stdweeknumber) + if dston < dstoff: + return dston <= dt.replace(tzinfo=None) < dstoff + else: + return not dstoff <= dt.replace(tzinfo=None) < dston + + +class tzwin(tzwinbase): + + def __init__(self, name): + self._name = name + + handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) + tzkey = _winreg.OpenKey(handle, "%s\%s" % (TZKEYNAME, name)) + keydict = valuestodict(tzkey) + tzkey.Close() + handle.Close() + + self._stdname = keydict["Std"].encode("iso-8859-1") + self._dstname = keydict["Dlt"].encode("iso-8859-1") + + self._display = keydict["Display"] + + # See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm + tup = struct.unpack("=3l16h", keydict["TZI"]) + self._stdoffset = -tup[0]-tup[1] # Bias + StandardBias * -1 + self._dstoffset = self._stdoffset-tup[2] # + DaylightBias * -1 + + (self._stdmonth, + self._stddayofweek, # Sunday = 0 + self._stdweeknumber, # Last = 5 + self._stdhour, + self._stdminute) = tup[4:9] + + (self._dstmonth, + self._dstdayofweek, # Sunday = 0 + self._dstweeknumber, # Last = 5 + self._dsthour, + self._dstminute) = tup[12:17] + + def __repr__(self): + return "tzwin(%s)" % repr(self._name) + + def __reduce__(self): + return (self.__class__, (self._name,)) + + +class tzwinlocal(tzwinbase): + + def __init__(self): + + handle = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) + + tzlocalkey = _winreg.OpenKey(handle, TZLOCALKEYNAME) + keydict = valuestodict(tzlocalkey) + tzlocalkey.Close() + + self._stdname = keydict["StandardName"].encode("iso-8859-1") + self._dstname = keydict["DaylightName"].encode("iso-8859-1") + + try: + tzkey = _winreg.OpenKey(handle, "%s\%s"%(TZKEYNAME, self._stdname)) + _keydict = valuestodict(tzkey) + self._display = _keydict["Display"] + tzkey.Close() + except OSError: + self._display = None + + handle.Close() + + self._stdoffset = -keydict["Bias"]-keydict["StandardBias"] + self._dstoffset = self._stdoffset-keydict["DaylightBias"] + + + # See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm + tup = struct.unpack("=8h", keydict["StandardStart"]) + + (self._stdmonth, + self._stddayofweek, # Sunday = 0 + self._stdweeknumber, # Last = 5 + self._stdhour, + self._stdminute) = tup[1:6] + + tup = struct.unpack("=8h", keydict["DaylightStart"]) + + (self._dstmonth, + self._dstdayofweek, # Sunday = 0 + self._dstweeknumber, # Last = 5 + self._dsthour, + self._dstminute) = tup[1:6] + + def __reduce__(self): + return (self.__class__, ()) + +def picknthweekday(year, month, dayofweek, hour, minute, whichweek): + """dayofweek == 0 means Sunday, whichweek 5 means last instance""" + first = datetime.datetime(year, month, 1, hour, minute) + weekdayone = first.replace(day=((dayofweek-first.isoweekday())%7+1)) + for n in xrange(whichweek): + dt = weekdayone+(whichweek-n)*ONEWEEK + if dt.month == month: + return dt + +def valuestodict(key): + """Convert a registry key's values to a dictionary.""" + dict = {} + size = _winreg.QueryInfoKey(key)[1] + for i in range(size): + data = _winreg.EnumValue(key, i) + dict[data[0]] = data[1] + return dict diff -Nru matplotlib-1.1.1/lib/dateutil_py2/zoneinfo/__init__.py matplotlib-1.2.0/lib/dateutil_py2/zoneinfo/__init__.py --- matplotlib-1.1.1/lib/dateutil_py2/zoneinfo/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py2/zoneinfo/__init__.py 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,87 @@ +""" +Copyright (c) 2003-2005 Gustavo Niemeyer + +This module offers extensions to the standard python 2.3+ +datetime module. +""" +from dateutil.tz import tzfile +from tarfile import TarFile +import os + +__author__ = "Gustavo Niemeyer " +__license__ = "PSF License" + +__all__ = ["setcachesize", "gettz", "rebuild"] + +CACHE = [] +CACHESIZE = 10 + +class tzfile(tzfile): + def __reduce__(self): + return (gettz, (self._filename,)) + +def getzoneinfofile(): + filenames = os.listdir(os.path.join(os.path.dirname(__file__))) + filenames.sort() + filenames.reverse() + for entry in filenames: + if entry.startswith("zoneinfo") and ".tar." in entry: + return os.path.join(os.path.dirname(__file__), entry) + return None + +ZONEINFOFILE = getzoneinfofile() + +del getzoneinfofile + +def setcachesize(size): + global CACHESIZE, CACHE + CACHESIZE = size + del CACHE[size:] + +def gettz(name): + tzinfo = None + if ZONEINFOFILE: + for cachedname, tzinfo in CACHE: + if cachedname == name: + break + else: + tf = TarFile.open(ZONEINFOFILE) + try: + zonefile = tf.extractfile(name) + except KeyError: + tzinfo = None + else: + tzinfo = tzfile(zonefile) + tf.close() + CACHE.insert(0, (name, tzinfo)) + del CACHE[CACHESIZE:] + return tzinfo + +def rebuild(filename, tag=None, format="gz"): + import tempfile, shutil + tmpdir = tempfile.mkdtemp() + zonedir = os.path.join(tmpdir, "zoneinfo") + moduledir = os.path.dirname(__file__) + if tag: tag = "-"+tag + targetname = "zoneinfo%s.tar.%s" % (tag, format) + try: + tf = TarFile.open(filename) + for name in tf.getnames(): + if not (name.endswith(".sh") or + name.endswith(".tab") or + name == "leapseconds"): + tf.extract(name, tmpdir) + filepath = os.path.join(tmpdir, name) + os.system("zic -d %s %s" % (zonedir, filepath)) + tf.close() + target = os.path.join(moduledir, targetname) + for entry in os.listdir(moduledir): + if entry.startswith("zoneinfo") and ".tar." in entry: + os.unlink(os.path.join(moduledir, entry)) + tf = TarFile.open(target, "w:%s" % format) + for entry in os.listdir(zonedir): + entrypath = os.path.join(zonedir, entry) + tf.add(entrypath, entry) + tf.close() + finally: + shutil.rmtree(tmpdir) Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/dateutil_py2/zoneinfo/zoneinfo-2010g.tar.gz and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/dateutil_py2/zoneinfo/zoneinfo-2010g.tar.gz differ diff -Nru matplotlib-1.1.1/lib/dateutil_py3/LICENSE matplotlib-1.2.0/lib/dateutil_py3/LICENSE --- matplotlib-1.1.1/lib/dateutil_py3/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py3/LICENSE 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,30 @@ +dateutil - Extensions to the standard Python datetime module. + +Copyright (c) 2003-2011 - Gustavo Niemeyer +Copyright (c) 2012 - Tomi Pieviläinen + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff -Nru matplotlib-1.1.1/lib/dateutil_py3/NEWS matplotlib-1.2.0/lib/dateutil_py3/NEWS --- matplotlib-1.1.1/lib/dateutil_py3/NEWS 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py3/NEWS 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,164 @@ +Version 2.1 +----------- + +- New maintainer + +- Dateutil now works on Python 2.6, 2.7 and 3.2 from same codebase (with six) + +- #704047: Ismael Carnales' patch for a new time format + +- Small bug fixes, thanks for reporters! + + +Version 2.0 +----------- + +- Ported to Python 3, by Brian Jones. If you need dateutil for Python 2.X, + please continue using the 1.X series. + +- There's no such thing as a "PSF License". This source code is now + made available under the Simplified BSD license. See LICENSE for + details. + +Version 1.5 +----------- + +- As reported by Mathieu Bridon, rrules were matching the bysecond rules + incorrectly against byminute in some circumstances when the SECONDLY + frequency was in use, due to a copy & paste bug. The problem has been + unittested and corrected. + +- Adam Ryan reported a problem in the relativedelta implementation which + affected the yearday parameter in the month of January specifically. + This has been unittested and fixed. + +- Updated timezone information. + + +Version 1.4.1 +------------- + +- Updated timezone information. + + +Version 1.4 +----------- + +- Fixed another parser precision problem on conversion of decimal seconds + to microseconds, as reported by Erik Brown. Now these issues are gone + for real since it's not using floating point arithmetic anymore. + +- Fixed case where tzrange.utcoffset and tzrange.dst() might fail due + to a date being used where a datetime was expected (reported and fixed + by Lennart Regebro). + +- Prevent tzstr from introducing daylight timings in strings that didn't + specify them (reported by Lennart Regebro). + +- Calls like gettz("GMT+3") and gettz("UTC-2") will now return the + expected values, instead of the TZ variable behavior. + +- Fixed DST signal handling in zoneinfo files. Reported by + Nicholas F. Fabry and John-Mark Gurney. + + +Version 1.3 +----------- + +- Fixed precision problem on conversion of decimal seconds to + microseconds, as reported by Skip Montanaro. + +- Fixed bug in constructor of parser, and converted parser classes to + new-style classes. Original report and patch by Michael Elsdrfer. + +- Initialize tzid and comps in tz.py, to prevent the code from ever + raising a NameError (even with broken files). Johan Dahlin suggested + the fix after a pyflakes run. + +- Version is now published in dateutil.__version__, as requested + by Darren Dale. + +- All code is compatible with new-style division. + + +Version 1.2 +----------- + +- Now tzfile will round timezones to full-minutes if necessary, + since Python's datetime doesn't support sub-minute offsets. + Thanks to Ilpo Nyyssnen for reporting the issue. + +- Removed bare string exceptions, as reported and fixed by + Wilfredo Snchez Vega. + +- Fix bug in leap count parsing (reported and fixed by Eugene Oden). + + +Version 1.1 +----------- + +- Fixed rrule byyearday handling. Abramo Bagnara pointed out that + RFC2445 allows negative numbers. + +- Fixed --prefix handling in setup.py (by Sidnei da Silva). + +- Now tz.gettz() returns a tzlocal instance when not given any + arguments and no other timezone information is found. + +- Updating timezone information to version 2005q. + + +Version 1.0 +----------- + +- Fixed parsing of XXhXXm formatted time after day/month/year + has been parsed. + +- Added patch by Jeffrey Harris optimizing rrule.__contains__. + + +Version 0.9 +----------- + +- Fixed pickling of timezone types, as reported by + Andreas Khler. + +- Implemented internal timezone information with binary + timezone files [1]. datautil.tz.gettz() function will now + try to use the system timezone files, and fallback to + the internal versions. It's also possible to ask for + the internal versions directly by using + dateutil.zoneinfo.gettz(). + +- New tzwin timezone type, allowing access to Windows + internal timezones (contributed by Jeffrey Harris). + +- Fixed parsing of unicode date strings. + +- Accept parserinfo instances as the parser constructor + parameter, besides parserinfo (sub)classes. + +- Changed weekday to spell the not-set n value as None + instead of 0. + +- Fixed other reported bugs. + +[1] http://www.twinsun.com/tz/tz-link.htm + + +Version 0.5 +----------- + +- Removed FREQ_ prefix from rrule frequency constants + WARNING: this breaks compatibility with previous versions. + +- Fixed rrule.between() for cases where "after" is achieved + before even starting, as reported by Andreas Khler. + +- Fixed two digit zero-year parsing (such as 31-Dec-00), as + reported by Jim Abramson, and included test case for this. + +- Sort exdate and rdate before iterating over them, so that + it's not necessary to sort them before adding to the rruleset, + as reported by Nicholas Piper. + diff -Nru matplotlib-1.1.1/lib/dateutil_py3/README matplotlib-1.2.0/lib/dateutil_py3/README --- matplotlib-1.1.1/lib/dateutil_py3/README 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py3/README 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,1970 @@ +## This file is in the moin format. The latest version is found +## at https://moin.conectiva.com.br/DateUtil + +== Contents == +[[TableOfContents]] + +== Description == +The '''dateutil''' module provides powerful extensions to +the standard '''datetime''' module, available in Python. + +== Features == + + * Computing of relative deltas (next month, next year, + next monday, last week of month, etc); + + * Computing of relative deltas between two given + date and/or datetime objects; + + * Computing of dates based on very flexible recurrence rules, + using a superset of the + [ftp://ftp.rfc-editor.org/in-notes/rfc2445.txt iCalendar] + specification. Parsing of RFC strings is supported as well. + + * Generic parsing of dates in almost any string format; + + * Timezone (tzinfo) implementations for tzfile(5) format + files (/etc/localtime, /usr/share/zoneinfo, etc), TZ + environment string (in all known formats), iCalendar + format files, given ranges (with help from relative deltas), + local machine timezone, fixed offset timezone, UTC timezone, + and Windows registry-based time zones. + + * Internal up-to-date world timezone information based on + Olson's database. + + * Computing of Easter Sunday dates for any given year, + using Western, Orthodox or Julian algorithms; + + * More than 400 test cases. + +== Quick example == +Here's a snapshot, just to give an idea about the power of the +package. For more examples, look at the documentation below. + +Suppose you want to know how much time is left, in +years/months/days/etc, before the next easter happening on a +year with a Friday 13th in August, and you want to get today's +date out of the "date" unix system command. Here is the code: +{{{ +from dateutil.relativedelta import * +from dateutil.easter import * +from dateutil.rrule import * +from dateutil.parser import * +from datetime import * +import commands +import os +now = parse(commands.getoutput("date")) +today = now.date() +year = rrule(YEARLY,bymonth=8,bymonthday=13,byweekday=FR)[0].year +rdelta = relativedelta(easter(year), today) +print "Today is:", today +print "Year with next Aug 13th on a Friday is:", year +print "How far is the Easter of that year:", rdelta +print "And the Easter of that year is:", today+rdelta +}}} + +And here's the output: +{{{ +Today is: 2003-10-11 +Year with next Aug 13th on a Friday is: 2004 +How far is the Easter of that year: relativedelta(months=+6) +And the Easter of that year is: 2004-04-11 +}}} + +{i} Being exactly 6 months ahead was '''really''' a coincidence :) + +== Download == +The following files are available. + * attachment:python-dateutil-1.0.tar.bz2 + * attachment:python-dateutil-1.0-1.noarch.rpm + +== Author == +The dateutil module was written by GustavoNiemeyer . + +== Documentation == +The following modules are available. + +=== relativedelta === +This module offers the '''relativedelta''' type, which is based +on the specification of the excelent work done by M.-A. Lemburg in his +[http://www.egenix.com/files/python/mxDateTime.html mxDateTime] +extension. However, notice that this type '''does not''' implement the +same algorithm as his work. Do not expect it to behave like +{{{mxDateTime}}}'s counterpart. + +==== relativedelta type ==== + +There's two different ways to build a relativedelta instance. The +first one is passing it two {{{date}}}/{{{datetime}}} instances: +{{{ +relativedelta(datetime1, datetime2) +}}} + +This will build the relative difference between {{{datetime1}}} and +{{{datetime2}}}, so that the following constraint is always true: +{{{ +datetime2+relativedelta(datetime1, datetime2) == datetime1 +}}} + +Notice that instead of {{{datetime}}} instances, you may use +{{{date}}} instances, or a mix of both. + +And the other way is to use any of the following keyword arguments: + + year, month, day, hour, minute, second, microsecond:: + Absolute information. + + years, months, weeks, days, hours, minutes, seconds, microseconds:: + Relative information, may be negative. + + weekday:: + One of the weekday instances ({{{MO}}}, {{{TU}}}, etc). These + instances may receive a parameter {{{n}}}, specifying the {{{n}}}th + weekday, which could be positive or negative (like {{{MO(+2)}}} or + {{{MO(-3)}}}. Not specifying it is the same as specifying {{{+1}}}. + You can also use an integer, where {{{0=MO}}}. Notice that, + for example, if the calculated date is already Monday, using + {{{MO}}} or {{{MO(+1)}}} (which is the same thing in this context), + won't change the day. + + leapdays:: + Will add given days to the date found, but only if the computed + year is a leap year and the computed date is post 28 of february. + + yearday, nlyearday:: + Set the yearday or the non-leap year day (jump leap days). + These are converted to {{{day}}}/{{{month}}}/{{{leapdays}}} + information. + +==== Behavior of operations ==== +If you're curious about exactly how the relative delta will act +on operations, here is a description of its behavior. + + 1. Calculate the absolute year, using the {{{year}}} argument, or the + original datetime year, if the argument is not present. + 1. Add the relative {{{years}}} argument to the absolute year. + 1. Do steps 1 and 2 for {{{month}}}/{{{months}}}. + 1. Calculate the absolute day, using the {{{day}}} argument, or the + original datetime day, if the argument is not present. Then, subtract + from the day until it fits in the year and month found after their + operations. + 1. Add the relative {{{days}}} argument to the absolute day. Notice + that the {{{weeks}}} argument is multiplied by 7 and added to {{{days}}}. + 1. If {{{leapdays}}} is present, the computed year is a leap year, and + the computed month is after february, remove one day from the found date. + 1. Do steps 1 and 2 for {{{hour}}}/{{{hours}}}, {{{minute}}}/{{{minutes}}}, + {{{second}}}/{{{seconds}}}, {{{microsecond}}}/{{{microseconds}}}. + 1. If the {{{weekday}}} argument is present, calculate the {{{n}}}th + occurrence of the given weekday. + +==== Examples ==== + +Let's begin our trip. +{{{ +>>> from datetime import *; from dateutil.relativedelta import * +>>> import calendar +}}} + +Store some values. +{{{ +>>> NOW = datetime.now() +>>> TODAY = date.today() +>>> NOW +datetime.datetime(2003, 9, 17, 20, 54, 47, 282310) +>>> TODAY +datetime.date(2003, 9, 17) +}}} + +Next month. +{{{ +>>> NOW+relativedelta(months=+1) +datetime.datetime(2003, 10, 17, 20, 54, 47, 282310) +}}} + +Next month, plus one week. +{{{ +>>> NOW+relativedelta(months=+1, weeks=+1) +datetime.datetime(2003, 10, 24, 20, 54, 47, 282310) +}}} + +Next month, plus one week, at 10am. +{{{ +>>> TODAY+relativedelta(months=+1, weeks=+1, hour=10) +datetime.datetime(2003, 10, 24, 10, 0) +}}} + +Let's try the other way around. Notice that the +hour setting we get in the relativedelta is relative, +since it's a difference, and the weeks parameter +has gone. +{{{ +>>> relativedelta(datetime(2003, 10, 24, 10, 0), TODAY) +relativedelta(months=+1, days=+7, hours=+10) +}}} + +One month before one year. +{{{ +>>> NOW+relativedelta(years=+1, months=-1) +datetime.datetime(2004, 8, 17, 20, 54, 47, 282310) +}}} + +How does it handle months with different numbers of days? +Notice that adding one month will never cross the month +boundary. +{{{ +>>> date(2003,1,27)+relativedelta(months=+1) +datetime.date(2003, 2, 27) +>>> date(2003,1,31)+relativedelta(months=+1) +datetime.date(2003, 2, 28) +>>> date(2003,1,31)+relativedelta(months=+2) +datetime.date(2003, 3, 31) +}}} + +The logic for years is the same, even on leap years. +{{{ +>>> date(2000,2,28)+relativedelta(years=+1) +datetime.date(2001, 2, 28) +>>> date(2000,2,29)+relativedelta(years=+1) +datetime.date(2001, 2, 28) + +>>> date(1999,2,28)+relativedelta(years=+1) +datetime.date(2000, 2, 28) +>>> date(1999,3,1)+relativedelta(years=+1) +datetime.date(2000, 3, 1) + +>>> date(2001,2,28)+relativedelta(years=-1) +datetime.date(2000, 2, 28) +>>> date(2001,3,1)+relativedelta(years=-1) +datetime.date(2000, 3, 1) +}}} + +Next friday. +{{{ +>>> TODAY+relativedelta(weekday=FR) +datetime.date(2003, 9, 19) + +>>> TODAY+relativedelta(weekday=calendar.FRIDAY) +datetime.date(2003, 9, 19) +}}} + +Last friday in this month. +{{{ +>>> TODAY+relativedelta(day=31, weekday=FR(-1)) +datetime.date(2003, 9, 26) +}}} + +Next wednesday (it's today!). +{{{ +>>> TODAY+relativedelta(weekday=WE(+1)) +datetime.date(2003, 9, 17) +}}} + +Next wednesday, but not today. +{{{ +>>> TODAY+relativedelta(days=+1, weekday=WE(+1)) +datetime.date(2003, 9, 24) +}}} + +Following +[http://www.cl.cam.ac.uk/~mgk25/iso-time.html ISO year week number notation] +find the first day of the 15th week of 1997. +{{{ +>>> datetime(1997,1,1)+relativedelta(day=4, weekday=MO(-1), weeks=+14) +datetime.datetime(1997, 4, 7, 0, 0) +}}} + +How long ago has the millennium changed? +{{{ +>>> relativedelta(NOW, date(2001,1,1)) +relativedelta(years=+2, months=+8, days=+16, + hours=+20, minutes=+54, seconds=+47, microseconds=+282310) +}}} + +How old is John? +{{{ +>>> johnbirthday = datetime(1978, 4, 5, 12, 0) +>>> relativedelta(NOW, johnbirthday) +relativedelta(years=+25, months=+5, days=+12, + hours=+8, minutes=+54, seconds=+47, microseconds=+282310) +}}} + +It works with dates too. +{{{ +>>> relativedelta(TODAY, johnbirthday) +relativedelta(years=+25, months=+5, days=+11, hours=+12) +}}} + +Obtain today's date using the yearday: +{{{ +>>> date(2003, 1, 1)+relativedelta(yearday=260) +datetime.date(2003, 9, 17) +}}} + +We can use today's date, since yearday should be absolute +in the given year: +{{{ +>>> TODAY+relativedelta(yearday=260) +datetime.date(2003, 9, 17) +}}} + +Last year it should be in the same day: +{{{ +>>> date(2002, 1, 1)+relativedelta(yearday=260) +datetime.date(2002, 9, 17) +}}} + +But not in a leap year: +{{{ +>>> date(2000, 1, 1)+relativedelta(yearday=260) +datetime.date(2000, 9, 16) +}}} + +We can use the non-leap year day to ignore this: +{{{ +>>> date(2000, 1, 1)+relativedelta(nlyearday=260) +datetime.date(2000, 9, 17) +}}} + +=== rrule === +The rrule module offers a small, complete, and very fast, implementation +of the recurrence rules documented in the +[ftp://ftp.rfc-editor.org/in-notes/rfc2445.txt iCalendar RFC], including +support for caching of results. + +==== rrule type ==== +That's the base of the rrule operation. It accepts all the keywords +defined in the RFC as its constructor parameters (except {{{byday}}}, +which was renamed to {{{byweekday}}}) and more. The constructor +prototype is: +{{{ +rrule(freq) +}}} + +Where {{{freq}}} must be one of {{{YEARLY}}}, {{{MONTHLY}}}, +{{{WEEKLY}}}, {{{DAILY}}}, {{{HOURLY}}}, {{{MINUTELY}}}, +or {{{SECONDLY}}}. + +Additionally, it supports the following keyword arguments: + + cache:: + If given, it must be a boolean value specifying to enable + or disable caching of results. If you will use the same + {{{rrule}}} instance multiple times, enabling caching will + improve the performance considerably. + + dtstart:: + The recurrence start. Besides being the base for the + recurrence, missing parameters in the final recurrence + instances will also be extracted from this date. If not + given, {{{datetime.now()}}} will be used instead. + + interval:: + The interval between each {{{freq}}} iteration. For example, + when using {{{YEARLY}}}, an interval of {{{2}}} means + once every two years, but with {{{HOURLY}}}, it means + once every two hours. The default interval is {{{1}}}. + + wkst:: + The week start day. Must be one of the {{{MO}}}, {{{TU}}}, + {{{WE}}} constants, or an integer, specifying the first day + of the week. This will affect recurrences based on weekly + periods. The default week start is got from + {{{calendar.firstweekday()}}}, and may be modified by + {{{calendar.setfirstweekday()}}}. + + count:: + How many occurrences will be generated. + + until:: + If given, this must be a {{{datetime}}} instance, that will + specify the limit of the recurrence. If a recurrence instance + happens to be the same as the {{{datetime}}} instance given + in the {{{until}}} keyword, this will be the last occurrence. + + bysetpos:: + If given, it must be either an integer, or a sequence of + integers, positive or negative. Each given integer will + specify an occurrence number, corresponding to the nth + occurrence of the rule inside the frequency period. For + example, a {{{bysetpos}}} of {{{-1}}} if combined with a + {{{MONTHLY}}} frequency, and a {{{byweekday}}} of + {{{(MO, TU, WE, TH, FR)}}}, will result in the last work + day of every month. + + bymonth:: + If given, it must be either an integer, or a sequence of + integers, meaning the months to apply the recurrence to. + + bymonthday:: + If given, it must be either an integer, or a sequence of + integers, meaning the month days to apply the recurrence to. + + byyearday:: + If given, it must be either an integer, or a sequence of + integers, meaning the year days to apply the recurrence to. + + byweekno:: + If given, it must be either an integer, or a sequence of + integers, meaning the week numbers to apply the recurrence + to. Week numbers have the meaning described in ISO8601, + that is, the first week of the year is that containing at + least four days of the new year. + + byweekday:: + If given, it must be either an integer ({{{0 == MO}}}), a + sequence of integers, one of the weekday constants + ({{{MO}}}, {{{TU}}}, etc), or a sequence of these constants. + When given, these variables will define the weekdays where + the recurrence will be applied. It's also possible to use + an argument {{{n}}} for the weekday instances, which will + mean the {{{n}}}''th'' occurrence of this weekday in the + period. For example, with {{{MONTHLY}}}, or with + {{{YEARLY}}} and {{{BYMONTH}}}, using {{{FR(+1)}}} + in {{{byweekday}}} will specify the first friday of the + month where the recurrence happens. Notice that in the RFC + documentation, this is specified as {{{BYDAY}}}, but was + renamed to avoid the ambiguity of that keyword. + + byhour:: + If given, it must be either an integer, or a sequence of + integers, meaning the hours to apply the recurrence to. + + byminute:: + If given, it must be either an integer, or a sequence of + integers, meaning the minutes to apply the recurrence to. + + bysecond:: + If given, it must be either an integer, or a sequence of + integers, meaning the seconds to apply the recurrence to. + + byeaster:: + If given, it must be either an integer, or a sequence of + integers, positive or negative. Each integer will define + an offset from the Easter Sunday. Passing the offset + {{{0}}} to {{{byeaster}}} will yield the Easter Sunday + itself. This is an extension to the RFC specification. + +==== rrule methods ==== +The following methods are available in {{{rrule}}} instances: + + rrule.before(dt, inc=False):: + Returns the last recurrence before the given {{{datetime}}} + instance. The {{{inc}}} keyword defines what happens if + {{{dt}}} '''is''' an occurrence. With {{{inc == True}}}, + if {{{dt}}} itself is an occurrence, it will be returned. + + rrule.after(dt, inc=False):: + Returns the first recurrence after the given {{{datetime}}} + instance. The {{{inc}}} keyword defines what happens if + {{{dt}}} '''is''' an occurrence. With {{{inc == True}}}, + if {{{dt}}} itself is an occurrence, it will be returned. + + rrule.between(after, before, inc=False):: + Returns all the occurrences of the rrule between {{{after}}} + and {{{before}}}. The {{{inc}}} keyword defines what happens + if {{{after}}} and/or {{{before}}} are themselves occurrences. + With {{{inc == True}}}, they will be included in the list, + if they are found in the recurrence set. + + rrule.count():: + Returns the number of recurrences in this set. It will have + go trough the whole recurrence, if this hasn't been done + before. + +Besides these methods, {{{rrule}}} instances also support +the {{{__getitem__()}}} and {{{__contains__()}}} special methods, +meaning that these are valid expressions: +{{{ +rr = rrule(...) +if datetime(...) in rr: + ... +print rr[0] +print rr[-1] +print rr[1:2] +print rr[::-2] +}}} + +The getitem/slicing mechanism is smart enough to avoid getting the whole +recurrence set, if possible. + +==== Notes ==== + + * The rrule type has no {{{byday}}} keyword. The equivalent keyword + has been replaced by the {{{byweekday}}} keyword, to remove the + ambiguity present in the original keyword. + + * Unlike documented in the RFC, the starting datetime ({{{dtstart}}}) + is not the first recurrence instance, unless it does fit in the + specified rules. In a python module context, this behavior makes more + sense than otherwise. Notice that you can easily get the original + behavior by using a rruleset and adding the {{{dtstart}}} as an + {{{rdate}}} recurrence. + + * Unlike documented in the RFC, every keyword is valid on every + frequency (the RFC documents that {{{byweekno}}} is only valid + on yearly frequencies, for example). + + * In addition to the documented keywords, a {{{byeaster}}} keyword + was introduced, making it easy to compute recurrent events relative + to the Easter Sunday. + +==== rrule examples ==== +These examples were converted from the RFC. + +Prepare the environment. +{{{ +>>> from dateutil.rrule import * +>>> from dateutil.parser import * +>>> from datetime import * + +>>> import pprint +>>> import sys +>>> sys.displayhook = pprint.pprint +}}} + +Daily, for 10 occurrences. +{{{ +>>> list(rrule(DAILY, count=10, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 3, 9, 0), + datetime.datetime(1997, 9, 4, 9, 0), + datetime.datetime(1997, 9, 5, 9, 0), + datetime.datetime(1997, 9, 6, 9, 0), + datetime.datetime(1997, 9, 7, 9, 0), + datetime.datetime(1997, 9, 8, 9, 0), + datetime.datetime(1997, 9, 9, 9, 0), + datetime.datetime(1997, 9, 10, 9, 0), + datetime.datetime(1997, 9, 11, 9, 0)] +}}} + +Daily until December 24, 1997 +{{{ +>>> list(rrule(DAILY, + dtstart=parse("19970902T090000"), + until=parse("19971224T000000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 3, 9, 0), + datetime.datetime(1997, 9, 4, 9, 0), + (...) + datetime.datetime(1997, 12, 21, 9, 0), + datetime.datetime(1997, 12, 22, 9, 0), + datetime.datetime(1997, 12, 23, 9, 0)] +}}} + +Every other day, 5 occurrences. +{{{ +>>> list(rrule(DAILY, interval=2, count=5, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 4, 9, 0), + datetime.datetime(1997, 9, 6, 9, 0), + datetime.datetime(1997, 9, 8, 9, 0), + datetime.datetime(1997, 9, 10, 9, 0)] +}}} + +Every 10 days, 5 occurrences. +{{{ +>>> list(rrule(DAILY, interval=10, count=5, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 12, 9, 0), + datetime.datetime(1997, 9, 22, 9, 0), + datetime.datetime(1997, 10, 2, 9, 0), + datetime.datetime(1997, 10, 12, 9, 0)] +}}} + +Everyday in January, for 3 years. +{{{ +>>> list(rrule(YEARLY, bymonth=1, byweekday=range(7), + dtstart=parse("19980101T090000"), + until=parse("20000131T090000"))) +[datetime.datetime(1998, 1, 1, 9, 0), + datetime.datetime(1998, 1, 2, 9, 0), + (...) + datetime.datetime(1998, 1, 30, 9, 0), + datetime.datetime(1998, 1, 31, 9, 0), + datetime.datetime(1999, 1, 1, 9, 0), + datetime.datetime(1999, 1, 2, 9, 0), + (...) + datetime.datetime(1999, 1, 30, 9, 0), + datetime.datetime(1999, 1, 31, 9, 0), + datetime.datetime(2000, 1, 1, 9, 0), + datetime.datetime(2000, 1, 2, 9, 0), + (...) + datetime.datetime(2000, 1, 29, 9, 0), + datetime.datetime(2000, 1, 31, 9, 0)] +}}} + +Same thing, in another way. +{{{ +>>> list(rrule(DAILY, bymonth=1, + dtstart=parse("19980101T090000"), + until=parse("20000131T090000"))) +(...) +}}} + +Weekly for 10 occurrences. +{{{ +>>> list(rrule(WEEKLY, count=10, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 9, 9, 0), + datetime.datetime(1997, 9, 16, 9, 0), + datetime.datetime(1997, 9, 23, 9, 0), + datetime.datetime(1997, 9, 30, 9, 0), + datetime.datetime(1997, 10, 7, 9, 0), + datetime.datetime(1997, 10, 14, 9, 0), + datetime.datetime(1997, 10, 21, 9, 0), + datetime.datetime(1997, 10, 28, 9, 0), + datetime.datetime(1997, 11, 4, 9, 0)] +}}} + +Every other week, 6 occurrences. +{{{ +>>> list(rrule(WEEKLY, interval=2, count=6, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 16, 9, 0), + datetime.datetime(1997, 9, 30, 9, 0), + datetime.datetime(1997, 10, 14, 9, 0), + datetime.datetime(1997, 10, 28, 9, 0), + datetime.datetime(1997, 11, 11, 9, 0)] +}}} + +Weekly on Tuesday and Thursday for 5 weeks. +{{{ +>>> list(rrule(WEEKLY, count=10, wkst=SU, byweekday=(TU,TH), + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 4, 9, 0), + datetime.datetime(1997, 9, 9, 9, 0), + datetime.datetime(1997, 9, 11, 9, 0), + datetime.datetime(1997, 9, 16, 9, 0), + datetime.datetime(1997, 9, 18, 9, 0), + datetime.datetime(1997, 9, 23, 9, 0), + datetime.datetime(1997, 9, 25, 9, 0), + datetime.datetime(1997, 9, 30, 9, 0), + datetime.datetime(1997, 10, 2, 9, 0)] +}}} + +Every other week on Tuesday and Thursday, for 8 occurrences. +{{{ +>>> list(rrule(WEEKLY, interval=2, count=8, + wkst=SU, byweekday=(TU,TH), + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 4, 9, 0), + datetime.datetime(1997, 9, 16, 9, 0), + datetime.datetime(1997, 9, 18, 9, 0), + datetime.datetime(1997, 9, 30, 9, 0), + datetime.datetime(1997, 10, 2, 9, 0), + datetime.datetime(1997, 10, 14, 9, 0), + datetime.datetime(1997, 10, 16, 9, 0)] +}}} + +Monthly on the 1st Friday for ten occurrences. +{{{ +>>> list(rrule(MONTHLY, count=10, byweekday=FR(1), + dtstart=parse("19970905T090000"))) +[datetime.datetime(1997, 9, 5, 9, 0), + datetime.datetime(1997, 10, 3, 9, 0), + datetime.datetime(1997, 11, 7, 9, 0), + datetime.datetime(1997, 12, 5, 9, 0), + datetime.datetime(1998, 1, 2, 9, 0), + datetime.datetime(1998, 2, 6, 9, 0), + datetime.datetime(1998, 3, 6, 9, 0), + datetime.datetime(1998, 4, 3, 9, 0), + datetime.datetime(1998, 5, 1, 9, 0), + datetime.datetime(1998, 6, 5, 9, 0)] +}}} + +Every other month on the 1st and last Sunday of the month for 10 occurrences. +{{{ +>>> list(rrule(MONTHLY, interval=2, count=10, + byweekday=(SU(1), SU(-1)), + dtstart=parse("19970907T090000"))) +[datetime.datetime(1997, 9, 7, 9, 0), + datetime.datetime(1997, 9, 28, 9, 0), + datetime.datetime(1997, 11, 2, 9, 0), + datetime.datetime(1997, 11, 30, 9, 0), + datetime.datetime(1998, 1, 4, 9, 0), + datetime.datetime(1998, 1, 25, 9, 0), + datetime.datetime(1998, 3, 1, 9, 0), + datetime.datetime(1998, 3, 29, 9, 0), + datetime.datetime(1998, 5, 3, 9, 0), + datetime.datetime(1998, 5, 31, 9, 0)] +}}} + +Monthly on the second to last Monday of the month for 6 months. +{{{ +>>> list(rrule(MONTHLY, count=6, byweekday=MO(-2), + dtstart=parse("19970922T090000"))) +[datetime.datetime(1997, 9, 22, 9, 0), + datetime.datetime(1997, 10, 20, 9, 0), + datetime.datetime(1997, 11, 17, 9, 0), + datetime.datetime(1997, 12, 22, 9, 0), + datetime.datetime(1998, 1, 19, 9, 0), + datetime.datetime(1998, 2, 16, 9, 0)] +}}} + +Monthly on the third to the last day of the month, for 6 months. +{{{ +>>> list(rrule(MONTHLY, count=6, bymonthday=-3, + dtstart=parse("19970928T090000"))) +[datetime.datetime(1997, 9, 28, 9, 0), + datetime.datetime(1997, 10, 29, 9, 0), + datetime.datetime(1997, 11, 28, 9, 0), + datetime.datetime(1997, 12, 29, 9, 0), + datetime.datetime(1998, 1, 29, 9, 0), + datetime.datetime(1998, 2, 26, 9, 0)] +}}} + +Monthly on the 2nd and 15th of the month for 5 occurrences. +{{{ +>>> list(rrule(MONTHLY, count=5, bymonthday=(2,15), + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 15, 9, 0), + datetime.datetime(1997, 10, 2, 9, 0), + datetime.datetime(1997, 10, 15, 9, 0), + datetime.datetime(1997, 11, 2, 9, 0)] +}}} + +Monthly on the first and last day of the month for 3 occurrences. +{{{ +>>> list(rrule(MONTHLY, count=5, bymonthday=(-1,1,), + dtstart=parse("1997090 +2T090000"))) +[datetime.datetime(1997, 9, 30, 9, 0), + datetime.datetime(1997, 10, 1, 9, 0), + datetime.datetime(1997, 10, 31, 9, 0), + datetime.datetime(1997, 11, 1, 9, 0), + datetime.datetime(1997, 11, 30, 9, 0)] +}}} + +Every 18 months on the 10th thru 15th of the month for 10 occurrences. +{{{ +>>> list(rrule(MONTHLY, interval=18, count=10, + bymonthday=range(10,16), + dtstart=parse("19970910T090000"))) +[datetime.datetime(1997, 9, 10, 9, 0), + datetime.datetime(1997, 9, 11, 9, 0), + datetime.datetime(1997, 9, 12, 9, 0), + datetime.datetime(1997, 9, 13, 9, 0), + datetime.datetime(1997, 9, 14, 9, 0), + datetime.datetime(1997, 9, 15, 9, 0), + datetime.datetime(1999, 3, 10, 9, 0), + datetime.datetime(1999, 3, 11, 9, 0), + datetime.datetime(1999, 3, 12, 9, 0), + datetime.datetime(1999, 3, 13, 9, 0)] +}}} + +Every Tuesday, every other month, 6 occurences. +{{{ +>>> list(rrule(MONTHLY, interval=2, count=6, byweekday=TU, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 9, 9, 0), + datetime.datetime(1997, 9, 16, 9, 0), + datetime.datetime(1997, 9, 23, 9, 0), + datetime.datetime(1997, 9, 30, 9, 0), + datetime.datetime(1997, 11, 4, 9, 0)] +}}} + +Yearly in June and July for 10 occurrences. +{{{ +>>> list(rrule(YEARLY, count=4, bymonth=(6,7), + dtstart=parse("19970610T0900 +00"))) +[datetime.datetime(1997, 6, 10, 9, 0), + datetime.datetime(1997, 7, 10, 9, 0), + datetime.datetime(1998, 6, 10, 9, 0), + datetime.datetime(1998, 7, 10, 9, 0)] +}}} + +Every 3rd year on the 1st, 100th and 200th day for 4 occurrences. +{{{ +>>> list(rrule(YEARLY, count=4, interval=3, byyearday=(1,100,200), + dtstart=parse("19970101T090000"))) +[datetime.datetime(1997, 1, 1, 9, 0), + datetime.datetime(1997, 4, 10, 9, 0), + datetime.datetime(1997, 7, 19, 9, 0), + datetime.datetime(2000, 1, 1, 9, 0)] +}}} + +Every 20th Monday of the year, 3 occurrences. +{{{ +>>> list(rrule(YEARLY, count=3, byweekday=MO(20), + dtstart=parse("19970519T090000"))) +[datetime.datetime(1997, 5, 19, 9, 0), + datetime.datetime(1998, 5, 18, 9, 0), + datetime.datetime(1999, 5, 17, 9, 0)] +}}} + +Monday of week number 20 (where the default start of the week is Monday), +3 occurrences. +{{{ +>>> list(rrule(YEARLY, count=3, byweekno=20, byweekday=MO, + dtstart=parse("19970512T090000"))) +[datetime.datetime(1997, 5, 12, 9, 0), + datetime.datetime(1998, 5, 11, 9, 0), + datetime.datetime(1999, 5, 17, 9, 0)] +}}} + +The week number 1 may be in the last year. +{{{ +>>> list(rrule(WEEKLY, count=3, byweekno=1, byweekday=MO, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 12, 29, 9, 0), + datetime.datetime(1999, 1, 4, 9, 0), + datetime.datetime(2000, 1, 3, 9, 0)] +}}} + +And the week numbers greater than 51 may be in the next year. +{{{ +>>> list(rrule(WEEKLY, count=3, byweekno=52, byweekday=SU, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 12, 28, 9, 0), + datetime.datetime(1998, 12, 27, 9, 0), + datetime.datetime(2000, 1, 2, 9, 0)] +}}} + +Only some years have week number 53: +{{{ +>>> list(rrule(WEEKLY, count=3, byweekno=53, byweekday=MO, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1998, 12, 28, 9, 0), + datetime.datetime(2004, 12, 27, 9, 0), + datetime.datetime(2009, 12, 28, 9, 0)] +}}} + +Every Friday the 13th, 4 occurrences. +{{{ +>>> list(rrule(YEARLY, count=4, byweekday=FR, bymonthday=13, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1998, 2, 13, 9, 0), + datetime.datetime(1998, 3, 13, 9, 0), + datetime.datetime(1998, 11, 13, 9, 0), + datetime.datetime(1999, 8, 13, 9, 0)] +}}} + +Every four years, the first Tuesday after a Monday in November, +3 occurrences (U.S. Presidential Election day): +{{{ +>>> list(rrule(YEARLY, interval=4, count=3, bymonth=11, + byweekday=TU, bymonthday=(2,3,4,5,6,7,8), + dtstart=parse("19961105T090000"))) +[datetime.datetime(1996, 11, 5, 9, 0), + datetime.datetime(2000, 11, 7, 9, 0), + datetime.datetime(2004, 11, 2, 9, 0)] +}}} + +The 3rd instance into the month of one of Tuesday, Wednesday or +Thursday, for the next 3 months: +{{{ +>>> list(rrule(MONTHLY, count=3, byweekday=(TU,WE,TH), + bysetpos=3, dtstart=parse("19970904T090000"))) +[datetime.datetime(1997, 9, 4, 9, 0), + datetime.datetime(1997, 10, 7, 9, 0), + datetime.datetime(1997, 11, 6, 9, 0)] +}}} + +The 2nd to last weekday of the month, 3 occurrences. +{{{ +>>> list(rrule(MONTHLY, count=3, byweekday=(MO,TU,WE,TH,FR), + bysetpos=-2, dtstart=parse("19970929T090000"))) +[datetime.datetime(1997, 9, 29, 9, 0), + datetime.datetime(1997, 10, 30, 9, 0), + datetime.datetime(1997, 11, 27, 9, 0)] +}}} + +Every 3 hours from 9:00 AM to 5:00 PM on a specific day. +{{{ +>>> list(rrule(HOURLY, interval=3, + dtstart=parse("19970902T090000"), + until=parse("19970902T170000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 2, 12, 0), + datetime.datetime(1997, 9, 2, 15, 0)] +}}} + +Every 15 minutes for 6 occurrences. +{{{ +>>> list(rrule(MINUTELY, interval=15, count=6, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 2, 9, 15), + datetime.datetime(1997, 9, 2, 9, 30), + datetime.datetime(1997, 9, 2, 9, 45), + datetime.datetime(1997, 9, 2, 10, 0), + datetime.datetime(1997, 9, 2, 10, 15)] +}}} + +Every hour and a half for 4 occurrences. +{{{ +>>> list(rrule(MINUTELY, interval=90, count=4, + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 2, 10, 30), + datetime.datetime(1997, 9, 2, 12, 0), + datetime.datetime(1997, 9, 2, 13, 30)] +}}} + +Every 20 minutes from 9:00 AM to 4:40 PM for two days. +{{{ +>>> list(rrule(MINUTELY, interval=20, count=48, + byhour=range(9,17), byminute=(0,20,40), + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 2, 9, 20), + (...) + datetime.datetime(1997, 9, 2, 16, 20), + datetime.datetime(1997, 9, 2, 16, 40), + datetime.datetime(1997, 9, 3, 9, 0), + datetime.datetime(1997, 9, 3, 9, 20), + (...) + datetime.datetime(1997, 9, 3, 16, 20), + datetime.datetime(1997, 9, 3, 16, 40)] +}}} + +An example where the days generated makes a difference because of {{{wkst}}}. +{{{ +>>> list(rrule(WEEKLY, interval=2, count=4, + byweekday=(TU,SU), wkst=MO, + dtstart=parse("19970805T090000"))) +[datetime.datetime(1997, 8, 5, 9, 0), + datetime.datetime(1997, 8, 10, 9, 0), + datetime.datetime(1997, 8, 19, 9, 0), + datetime.datetime(1997, 8, 24, 9, 0)] + +>>> list(rrule(WEEKLY, interval=2, count=4, + byweekday=(TU,SU), wkst=SU, + dtstart=parse("19970805T090000"))) +[datetime.datetime(1997, 8, 5, 9, 0), + datetime.datetime(1997, 8, 17, 9, 0), + datetime.datetime(1997, 8, 19, 9, 0), + datetime.datetime(1997, 8, 31, 9, 0)] +}}} + +==== rruleset type ==== +The {{{rruleset}}} type allows more complex recurrence setups, mixing +multiple rules, dates, exclusion rules, and exclusion dates. +The type constructor takes the following keyword arguments: + + cache:: + If True, caching of results will be enabled, improving performance + of multiple queries considerably. + +==== rruleset methods ==== +The following methods are available: + + rruleset.rrule(rrule):: + Include the given {{{rrule}}} instance in the recurrence set + generation. + + rruleset.rdate(dt):: + Include the given {{{datetime}}} instance in the recurrence + set generation. + + rruleset.exrule(rrule):: + Include the given {{{rrule}}} instance in the recurrence set + exclusion list. Dates which are part of the given recurrence + rules will not be generated, even if some inclusive {{{rrule}}} + or {{{rdate}}} matches them. + + rruleset.exdate(dt):: + Include the given {{{datetime}}} instance in the recurrence set + exclusion list. Dates included that way will not be generated, + even if some inclusive {{{rrule}}} or {{{rdate}}} matches them. + + rruleset.before(dt, inc=False):: + Returns the last recurrence before the given {{{datetime}}} + instance. The {{{inc}}} keyword defines what happens if + {{{dt}}} '''is''' an occurrence. With {{{inc == True}}}, + if {{{dt}}} itself is an occurrence, it will be returned. + + rruleset.after(dt, inc=False):: + Returns the first recurrence after the given {{{datetime}}} + instance. The {{{inc}}} keyword defines what happens if + {{{dt}}} '''is''' an occurrence. With {{{inc == True}}}, + if {{{dt}}} itself is an occurrence, it will be returned. + + rruleset.between(after, before, inc=False):: + Returns all the occurrences of the rrule between {{{after}}} + and {{{before}}}. The {{{inc}}} keyword defines what happens + if {{{after}}} and/or {{{before}}} are themselves occurrences. + With {{{inc == True}}}, they will be included in the list, + if they are found in the recurrence set. + + rruleset.count():: + Returns the number of recurrences in this set. It will have + go trough the whole recurrence, if this hasn't been done + before. + +Besides these methods, {{{rruleset}}} instances also support +the {{{__getitem__()}}} and {{{__contains__()}}} special methods, +meaning that these are valid expressions: +{{{ +set = rruleset(...) +if datetime(...) in set: + ... +print set[0] +print set[-1] +print set[1:2] +print set[::-2] +}}} + +The getitem/slicing mechanism is smart enough to avoid getting the whole +recurrence set, if possible. + +==== rruleset examples ==== +Daily, for 7 days, jumping Saturday and Sunday occurrences. +{{{ +>>> set = rruleset() +>>> set.rrule(rrule(DAILY, count=7, + dtstart=parse("19970902T090000"))) +>>> set.exrule(rrule(YEARLY, byweekday=(SA,SU), + dtstart=parse("19970902T090000"))) +>>> list(set) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 3, 9, 0), + datetime.datetime(1997, 9, 4, 9, 0), + datetime.datetime(1997, 9, 5, 9, 0), + datetime.datetime(1997, 9, 8, 9, 0)] +}}} + +Weekly, for 4 weeks, plus one time on day 7, and not on day 16. +{{{ +>>> set = rruleset() +>>> set.rrule(rrule(WEEKLY, count=4, + dtstart=parse("19970902T090000"))) +>>> set.rdate(datetime.datetime(1997, 9, 7, 9, 0)) +>>> set.exdate(datetime.datetime(1997, 9, 16, 9, 0)) +>>> list(set) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 7, 9, 0), + datetime.datetime(1997, 9, 9, 9, 0), + datetime.datetime(1997, 9, 23, 9, 0)] +}}} + +==== rrulestr() function ==== +The {{{rrulestr()}}} function is a parser for ''RFC-like'' syntaxes. +The function prototype is: +{{{ +rrulestr(str) +}}} + +The string passed as parameter may be a multiple line string, a +single line string, or just the {{{RRULE}}} property value. + +Additionally, it accepts the following keyword arguments: + + cache:: + If {{{True}}}, the {{{rruleset}}} or {{{rrule}}} created instance + will cache its results. Default is not to cache. + + dtstart:: + If given, it must be a {{{datetime}}} instance that will be used + when no {{{DTSTART}}} property is found in the parsed string. If + it is not given, and the property is not found, {{{datetime.now()}}} + will be used instead. + + unfold:: + If set to {{{True}}}, lines will be unfolded following the RFC + specification. It defaults to {{{False}}}, meaning that spaces + before every line will be stripped. + + forceset:: + If set to {{{True}}} a {{{rruleset}}} instance will be returned, + even if only a single rule is found. The default is to return an + {{{rrule}}} if possible, and an {{{rruleset}}} if necessary. + + compatible:: + If set to {{{True}}}, the parser will operate in RFC-compatible + mode. Right now it means that {{{unfold}}} will be turned on, + and if a {{{DTSTART}}} is found, it will be considered the first + recurrence instance, as documented in the RFC. + + ignoretz:: + If set to {{{True}}}, the date parser will ignore timezone + information available in the {{{DTSTART}}} property, or the + {{{UNTIL}}} attribute. + + tzinfos:: + If set, it will be passed to the datetime string parser to + resolve unknown timezone settings. For more information about + what could be used here, check the parser documentation. + +==== rrulestr() examples ==== + +Every 10 days, 5 occurrences. +{{{ +>>> list(rrulestr(""" +... DTSTART:19970902T090000 +... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5 +... """)) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 12, 9, 0), + datetime.datetime(1997, 9, 22, 9, 0), + datetime.datetime(1997, 10, 2, 9, 0), + datetime.datetime(1997, 10, 12, 9, 0)] +}}} + +Same thing, but passing only the {{{RRULE}}} value. +{{{ +>>> list(rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5", + dtstart=parse("19970902T090000"))) +[datetime.datetime(1997, 9, 2, 9, 0), + datetime.datetime(1997, 9, 12, 9, 0), + datetime.datetime(1997, 9, 22, 9, 0), + datetime.datetime(1997, 10, 2, 9, 0), + datetime.datetime(1997, 10, 12, 9, 0)] +}}} + +Notice that when using a single rule, it returns an +{{{rrule}}} instance, unless {{{forceset}}} was used. +{{{ +>>> rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5") + + +>>> rrulestr(""" +... DTSTART:19970902T090000 +... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5 +... """) + + +>>> rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5", forceset=True) + +}}} + +But when an {{{rruleset}}} is needed, it is automatically used. +{{{ +>>> rrulestr(""" +... DTSTART:19970902T090000 +... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5 +... RRULE:FREQ=DAILY;INTERVAL=5;COUNT=3 +... """) + +}}} + +=== parser === +This module offers a generic date/time string parser which is +able to parse most known formats to represent a date and/or +time. + +==== parse() function ==== +That's probably the only function you'll need from this module. +It offers you an interface to access the parser functionality and +extract a {{{datetime}}} type out of a string. + +The prototype of this function is: +{{{ +parse(timestr) +}}} + +Additionally, the following keyword arguments are available: + + default:: + If given, this must be a {{{datetime}}} instance. Any fields + missing in the parsed date will be copied from this instance. + The default value is the current date, at 00:00:00am. + + ignoretz:: + If this is true, even if a timezone is found in the string, + the parser will not use it. + + tzinfos:: + Using this keyword argument you may provide custom timezones + to the parser. If given, it must be either a dictionary with + the timezone abbreviation as key, or a function accepting a + timezone abbreviation and offset as argument. The dictionary + values and the function return must be a timezone offset + in seconds, a tzinfo subclass, or a string defining the + timezone (in the TZ environment variable format). + + dayfirst:: + This option allow one to change the precedence in which + days are parsed in date strings. The default is given in the + parserinfo instance (the default parserinfo has it set to + False). If {{{dayfirst}}} is False, the {{{MM-DD-YYYY}}} + format will have precedence over {{{DD-MM-YYYY}}} in an + ambiguous date. + + yearfirst:: + This option allow one to change the precedence in which + years are parsed in date strings. The default is given in + the parserinfo instance (the default parserinfo has it set + to False). If {{{yearfirst}}} is false, the {{{MM-DD-YY}}} + format will have precedence over {{{YY-MM-DD}}} in an + ambiguous date. + + fuzzy:: + If {{{fuzzy}}} is set to True, unknown tokens in the string + will be ignored. + + parserinfo:: + This parameter allows one to change how the string is parsed, + by using a different parserinfo class instance. Using it you + may, for example, intenationalize the parser strings, or make + it ignore additional words. + +==== Format precedence ==== +Whenever an ambiguous date is found, the {{{dayfirst}}} and +{{{yearfirst}}} parameters will control how the information +is processed. Here is the precedence in each case: + +If {{{dayfirst}}} is {{{False}}} and {{{yearfirst}}} is {{{False}}}, +(default, if no parameter is given): + + * {{{MM-DD-YY}}} + * {{{DD-MM-YY}}} + * {{{YY-MM-DD}}} + +If {{{dayfirst}}} is {{{True}}} and {{{yearfirst}}} is {{{False}}}: + + * {{{DD-MM-YY}}} + * {{{MM-DD-YY}}} + * {{{YY-MM-DD}}} + +If {{{dayfirst}}} is {{{False}}} and {{{yearfirst}}} is {{{True}}}: + + * {{{YY-MM-DD}}} + * {{{MM-DD-YY}}} + * {{{DD-MM-YY}}} + +If {{{dayfirst}}} is {{{True}}} and {{{yearfirst}}} is {{{True}}}: + + * {{{YY-MM-DD}}} + * {{{DD-MM-YY}}} + * {{{MM-DD-YY}}} + +==== Converting two digit years ==== +When a two digit year is found, it is processed considering +the current year, so that the computed year is never more +than 49 years after the current year, nor 50 years before the +current year. In other words, if we are in year 2003, and the +year 30 is found, it will be considered as 2030, but if the +year 60 is found, it will be considered 1960. + +==== Examples ==== +The following code will prepare the environment: +{{{ +>>> from dateutil.parser import * +>>> from dateutil.tz import * +>>> from datetime import * +>>> TZOFFSETS = {"BRST": -10800} +>>> BRSTTZ = tzoffset(-10800, "BRST") +>>> DEFAULT = datetime(2003, 9, 25) +}}} + +Some simple examples based on the {{{date}}} command, using the +{{{TZOFFSET}}} dictionary to provide the BRST timezone offset. +{{{ +>>> parse("Thu Sep 25 10:36:28 BRST 2003", tzinfos=TZOFFSETS) +datetime.datetime(2003, 9, 25, 10, 36, 28, + tzinfo=tzoffset('BRST', -10800)) + +>>> parse("2003 10:36:28 BRST 25 Sep Thu", tzinfos=TZOFFSETS) +datetime.datetime(2003, 9, 25, 10, 36, 28, + tzinfo=tzoffset('BRST', -10800)) +}}} + +Notice that since BRST is my local timezone, parsing it without +further timezone settings will yield a {{{tzlocal}}} timezone. +{{{ +>>> parse("Thu Sep 25 10:36:28 BRST 2003") +datetime.datetime(2003, 9, 25, 10, 36, 28, tzinfo=tzlocal()) +}}} + +We can also ask to ignore the timezone explicitly: +{{{ +>>> parse("Thu Sep 25 10:36:28 BRST 2003", ignoretz=True) +datetime.datetime(2003, 9, 25, 10, 36, 28) +}}} + +That's the same as processing a string without timezone: +{{{ +>>> parse("Thu Sep 25 10:36:28 2003") +datetime.datetime(2003, 9, 25, 10, 36, 28) +}}} + +Without the year, but passing our {{{DEFAULT}}} datetime to return +the same year, no mattering what year we currently are in: +{{{ +>>> parse("Thu Sep 25 10:36:28", default=DEFAULT) +datetime.datetime(2003, 9, 25, 10, 36, 28) +}}} + +Strip it further: +{{{ +>>> parse("Thu Sep 10:36:28", default=DEFAULT) +datetime.datetime(2003, 9, 25, 10, 36, 28) + +>>> parse("Thu 10:36:28", default=DEFAULT) +datetime.datetime(2003, 9, 25, 10, 36, 28) + +>>> parse("Thu 10:36", default=DEFAULT) +datetime.datetime(2003, 9, 25, 10, 36) + +>>> parse("10:36", default=DEFAULT) +datetime.datetime(2003, 9, 25, 10, 36) +>>> +}}} + +Strip in a different way: +{{{ +>>> parse("Thu Sep 25 2003") +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("Sep 25 2003") +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("Sep 2003", default=DEFAULT) +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("Sep", default=DEFAULT) +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("2003", default=DEFAULT) +datetime.datetime(2003, 9, 25, 0, 0) +}}} + +Another format, based on {{{date -R}}} (RFC822): +{{{ +>>> parse("Thu, 25 Sep 2003 10:49:41 -0300") +datetime.datetime(2003, 9, 25, 10, 49, 41, + tzinfo=tzoffset(None, -10800)) +}}} + +ISO format: +{{{ +>>> parse("2003-09-25T10:49:41.5-03:00") +datetime.datetime(2003, 9, 25, 10, 49, 41, 500000, + tzinfo=tzoffset(None, -10800)) +}}} + +Some variations: +{{{ +>>> parse("2003-09-25T10:49:41") +datetime.datetime(2003, 9, 25, 10, 49, 41) + +>>> parse("2003-09-25T10:49") +datetime.datetime(2003, 9, 25, 10, 49) + +>>> parse("2003-09-25T10") +datetime.datetime(2003, 9, 25, 10, 0) + +>>> parse("2003-09-25") +datetime.datetime(2003, 9, 25, 0, 0) +}}} + +ISO format, without separators: +{{{ +>>> parse("20030925T104941.5-0300") +datetime.datetime(2003, 9, 25, 10, 49, 41, 500000, + tzinfo=tzinfo=tzoffset(None, -10800)) + +>>> parse("20030925T104941-0300") +datetime.datetime(2003, 9, 25, 10, 49, 41, + tzinfo=tzoffset(None, -10800)) + +>>> parse("20030925T104941") +datetime.datetime(2003, 9, 25, 10, 49, 41) + +>>> parse("20030925T1049") +datetime.datetime(2003, 9, 25, 10, 49) + +>>> parse("20030925T10") +datetime.datetime(2003, 9, 25, 10, 0) + +>>> parse("20030925") +datetime.datetime(2003, 9, 25, 0, 0) +}}} + +Everything together. +{{{ +>>> parse("199709020900") +datetime.datetime(1997, 9, 2, 9, 0) +>>> parse("19970902090059") +datetime.datetime(1997, 9, 2, 9, 0, 59) +}}} + +Different date orderings: +{{{ +>>> parse("2003-09-25") +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("2003-Sep-25") +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("25-Sep-2003") +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("Sep-25-2003") +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("09-25-2003") +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("25-09-2003") +datetime.datetime(2003, 9, 25, 0, 0) +}}} + +Check some ambiguous dates: +{{{ +>>> parse("10-09-2003") +datetime.datetime(2003, 10, 9, 0, 0) + +>>> parse("10-09-2003", dayfirst=True) +datetime.datetime(2003, 9, 10, 0, 0) + +>>> parse("10-09-03") +datetime.datetime(2003, 10, 9, 0, 0) + +>>> parse("10-09-03", yearfirst=True) +datetime.datetime(2010, 9, 3, 0, 0) +}}} + +Other date separators are allowed: +{{{ +>>> parse("2003.Sep.25") +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("2003/09/25") +datetime.datetime(2003, 9, 25, 0, 0) +}}} + +Even with spaces: +{{{ +>>> parse("2003 Sep 25") +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("2003 09 25") +datetime.datetime(2003, 9, 25, 0, 0) +}}} + +Hours with letters work: +{{{ +>>> parse("10h36m28.5s", default=DEFAULT) +datetime.datetime(2003, 9, 25, 10, 36, 28, 500000) + +>>> parse("01s02h03m", default=DEFAULT) +datetime.datetime(2003, 9, 25, 2, 3, 1) + +>>> parse("01h02m03", default=DEFAULT) +datetime.datetime(2003, 9, 3, 1, 2) + +>>> parse("01h02", default=DEFAULT) +datetime.datetime(2003, 9, 2, 1, 0) + +>>> parse("01h02s", default=DEFAULT) +datetime.datetime(2003, 9, 25, 1, 0, 2) +}}} + +With AM/PM: +{{{ +>>> parse("10h am", default=DEFAULT) +datetime.datetime(2003, 9, 25, 10, 0) + +>>> parse("10pm", default=DEFAULT) +datetime.datetime(2003, 9, 25, 22, 0) + +>>> parse("12:00am", default=DEFAULT) +datetime.datetime(2003, 9, 25, 0, 0) + +>>> parse("12pm", default=DEFAULT) +datetime.datetime(2003, 9, 25, 12, 0) +}}} + +Some special treating for ''pertain'' relations: +{{{ +>>> parse("Sep 03", default=DEFAULT) +datetime.datetime(2003, 9, 3, 0, 0) + +>>> parse("Sep of 03", default=DEFAULT) +datetime.datetime(2003, 9, 25, 0, 0) +}}} + +Fuzzy parsing: +{{{ +>>> s = "Today is 25 of September of 2003, exactly " \ +... "at 10:49:41 with timezone -03:00." +>>> parse(s, fuzzy=True) +datetime.datetime(2003, 9, 25, 10, 49, 41, + tzinfo=tzoffset(None, -10800)) +}}} + +Other random formats: +{{{ +>>> parse("Wed, July 10, '96") +datetime.datetime(1996, 7, 10, 0, 0) + +>>> parse("1996.07.10 AD at 15:08:56 PDT", ignoretz=True) +datetime.datetime(1996, 7, 10, 15, 8, 56) + +>>> parse("Tuesday, April 12, 1952 AD 3:30:42pm PST", ignoretz=True) +datetime.datetime(1952, 4, 12, 15, 30, 42) + +>>> parse("November 5, 1994, 8:15:30 am EST", ignoretz=True) +datetime.datetime(1994, 11, 5, 8, 15, 30) + +>>> parse("3rd of May 2001") +datetime.datetime(2001, 5, 3, 0, 0) + +>>> parse("5:50 A.M. on June 13, 1990") +datetime.datetime(1990, 6, 13, 5, 50) +}}} + +=== easter === +This module offers a generic easter computing method for +any given year, using Western, Orthodox or Julian algorithms. + +==== easter() function ==== +This method was ported from the work done by +[http://users.chariot.net.au/~gmarts/eastalg.htm GM Arts], +on top of the algorithm by +[http://www.tondering.dk/claus/calendar.html Claus Tondering], +which was based in part on the algorithm of Ouding (1940), +as quoted in "Explanatory Supplement to the Astronomical +Almanac", P. Kenneth Seidelmann, editor. + +This algorithm implements three different easter +calculation methods: + + 1. Original calculation in Julian calendar, valid in + dates after 326 AD + 1. Original method, with date converted to Gregorian + calendar, valid in years 1583 to 4099 + 1. Revised method, in Gregorian calendar, valid in + years 1583 to 4099 as well + +These methods are represented by the constants: +{{{ +EASTER_JULIAN = 1 +EASTER_ORTHODOX = 2 +EASTER_WESTERN = 3 +}}} + +The default method is method 3. + +=== tz === +This module offers timezone implementations subclassing +the abstract {{{datetime.tzinfo}}} type. There are +classes to handle [http://www.twinsun.com/tz/tz-link.htm tzfile] +format files (usually are in /etc/localtime, +/usr/share/zoneinfo, etc), TZ environment string (in all +known formats), given ranges (with help from relative +deltas), local machine timezone, fixed offset timezone, +and UTC timezone. + +==== tzutc type ==== +This type implements a basic UTC timezone. The constructor of this +type accepts no parameters. + +==== tzutc examples ==== +{{{ +>>> from datetime import * +>>> from dateutil.tz import * + +>>> datetime.now() +datetime.datetime(2003, 9, 27, 9, 40, 1, 521290) + +>>> datetime.now(tzutc()) +datetime.datetime(2003, 9, 27, 12, 40, 12, 156379, tzinfo=tzutc()) + +>>> datetime.now(tzutc()).tzname() +'UTC' +}}} + +==== tzoffset type ==== +This type implements a fixed offset timezone, with no +support to daylight saving times. Here is the prototype of the +type constructor: +{{{ +tzoffset(name, offset) +}}} + +The {{{name}}} parameter may be optionally set to {{{None}}}, and +{{{offset}}} must be given in seconds. + +==== tzoffset examples ==== +{{{ +>>> from datetime import * +>>> from dateutil.tz import * + +>>> datetime.now(tzoffset("BRST", -10800)) +datetime.datetime(2003, 9, 27, 9, 52, 43, 624904, + tzinfo=tzinfo=tzoffset('BRST', -10800)) + +>>> datetime.now(tzoffset("BRST", -10800)).tzname() +'BRST' + +>>> datetime.now(tzoffset("BRST", -10800)).astimezone(tzutc()) +datetime.datetime(2003, 9, 27, 12, 53, 11, 446419, + tzinfo=tzutc()) +}}} + +==== tzlocal type ==== +This type implements timezone settings as known by the +operating system. The constructor of this type accepts no +parameters. + +==== tzlocal examples ==== +{{{ +>>> from datetime import * +>>> from dateutil.tz import * + +>>> datetime.now(tzlocal()) +datetime.datetime(2003, 9, 27, 10, 1, 43, 673605, + tzinfo=tzlocal()) + +>>> datetime.now(tzlocal()).tzname() +'BRST' + +>>> datetime.now(tzlocal()).astimezone(tzoffset(None, 0)) +datetime.datetime(2003, 9, 27, 13, 3, 0, 11493, + tzinfo=tzoffset(None, 0)) +}}} + +==== tzstr type ==== +This type implements timezone settings extracted from a +string in known TZ environment variable formats. Here is the prototype +of the constructor: +{{{ +tzstr(str) +}}} + +==== tzstr examples ==== +Here are examples of the recognized formats: + + * {{{EST5EDT}}} + * {{{EST5EDT,4,0,6,7200,10,0,26,7200,3600}}} + * {{{EST5EDT,4,1,0,7200,10,-1,0,7200,3600}}} + * {{{EST5EDT4,M4.1.0/02:00:00,M10-5-0/02:00}}} + * {{{EST5EDT4,95/02:00:00,298/02:00}}} + * {{{EST5EDT4,J96/02:00:00,J299/02:00}}} + +Notice that if daylight information is not present, but a +daylight abbreviation was provided, {{{tzstr}}} will follow the +convention of using the first sunday of April to start daylight +saving, and the last sunday of October to end it. If start or +end time is not present, 2AM will be used, and if the daylight +offset is not present, the standard offset plus one hour will +be used. This convention is the same as used in the GNU libc. + +This also means that some of the above examples are exactly +equivalent, and all of these examples are equivalent +in the year of 2003. + +Here is the example mentioned in the +[http://www.python.org/doc/current/lib/module-time.html time module documentation]. +{{{ +>>> os.environ['TZ'] = 'EST+05EDT,M4.1.0,M10.5.0' +>>> time.tzset() +>>> time.strftime('%X %x %Z') +'02:07:36 05/08/03 EDT' +>>> os.environ['TZ'] = 'AEST-10AEDT-11,M10.5.0,M3.5.0' +>>> time.tzset() +>>> time.strftime('%X %x %Z') +'16:08:12 05/08/03 AEST' +}}} + +And here is an example showing the same information using {{{tzstr}}}, +without touching system settings. +{{{ +>>> tz1 = tzstr('EST+05EDT,M4.1.0,M10.5.0') +>>> tz2 = tzstr('AEST-10AEDT-11,M10.5.0,M3.5.0') +>>> dt = datetime(2003, 5, 8, 2, 7, 36, tzinfo=tz1) +>>> dt.strftime('%X %x %Z') +'02:07:36 05/08/03 EDT' +>>> dt.astimezone(tz2).strftime('%X %x %Z') +'16:07:36 05/08/03 AEST' +}}} + +Are these really equivalent? +{{{ +>>> tzstr('EST5EDT') == tzstr('EST5EDT,4,1,0,7200,10,-1,0,7200,3600') +True +}}} + +Check the daylight limit. +{{{ +>>> datetime(2003, 4, 6, 1, 59, tzinfo=tz).tzname() +'EST' +>>> datetime(2003, 4, 6, 2, 00, tzinfo=tz).tzname() +'EDT' +>>> datetime(2003, 10, 26, 0, 59, tzinfo=tz).tzname() +'EDT' +>>> datetime(2003, 10, 26, 1, 00, tzinfo=tz).tzname() +'EST' +}}} + +==== tzrange type ==== +This type offers the same functionality as the {{{tzstr}}} type, but +instead of timezone strings, information is passed using +{{{relativedelta}}}s which are applied to a datetime set to the first +day of the year. Here is the prototype of this type's constructor: +{{{ +tzrange(stdabbr, stdoffset=None, dstabbr=None, dstoffset=None, + start=None, end=None): +}}} + +Offsets must be given in seconds. Information not provided will be +set to the defaults, as explained in the {{{tzstr}}} section above. + +==== tzrange examples ==== +{{{ +>>> tzstr('EST5EDT') == tzrange("EST", -18000, "EDT") +True + +>>> from dateutil.relativedelta import * +>>> range1 = tzrange("EST", -18000, "EDT") +>>> range2 = tzrange("EST", -18000, "EDT", -14400, +... relativedelta(hours=+2, month=4, day=1, + weekday=SU(+1)), +... relativedelta(hours=+1, month=10, day=31, + weekday=SU(-1))) +>>> tzstr('EST5EDT') == range1 == range2 +True +}}} + +Notice a minor detail in the last example: while the DST should end +at 2AM, the delta will catch 1AM. That's because the daylight saving +time should end at 2AM standard time (the difference between STD and +DST is 1h in the given example) instead of the DST time. That's how +the {{{tzinfo}}} subtypes should deal with the extra hour that happens +when going back to the standard time. Check +[http://www.python.org/doc/current/lib/datetime-tzinfo.html tzinfo documentation] +for more information. + +==== tzfile type ==== +This type allows one to use tzfile(5) format timezone files to extract +current and historical zone information. Here is the type constructor +prototype: +{{{ +tzfile(fileobj) +}}} + +Where {{{fileobj}}} is either a filename or a file-like object with +a {{{read()}}} method. + +==== tzfile examples ==== +{{{ +>>> tz = tzfile("/etc/localtime") +>>> datetime.now(tz) +datetime.datetime(2003, 9, 27, 12, 3, 48, 392138, + tzinfo=tzfile('/etc/localtime')) + +>>> datetime.now(tz).astimezone(tzutc()) +datetime.datetime(2003, 9, 27, 15, 3, 53, 70863, + tzinfo=tzutc()) + +>>> datetime.now(tz).tzname() +'BRST' +>>> datetime(2003, 1, 1, tzinfo=tz).tzname() +'BRDT' +}}} + +Check the daylight limit. +{{{ +>>> tz = tzfile('/usr/share/zoneinfo/EST5EDT') +>>> datetime(2003, 4, 6, 1, 59, tzinfo=tz).tzname() +'EST' +>>> datetime(2003, 4, 6, 2, 00, tzinfo=tz).tzname() +'EDT' +>>> datetime(2003, 10, 26, 0, 59, tzinfo=tz).tzname() +'EDT' +>>> datetime(2003, 10, 26, 1, 00, tzinfo=tz).tzname() +'EST' +}}} + +==== tzical type ==== +This type is able to parse +[ftp://ftp.rfc-editor.org/in-notes/rfc2445.txt iCalendar] +style {{{VTIMEZONE}}} sessions into a Python timezone object. +The constuctor prototype is: +{{{ +tzical(fileobj) +}}} + +Where {{{fileobj}}} is either a filename or a file-like object with +a {{{read()}}} method. + +==== tzical methods ==== + + tzical.get(tzid=None):: + Since a single iCalendar file may contain more than one timezone, + you must ask for the timezone you want with this method. If there's + more than one timezone in the parsed file, you'll need to pass the + {{{tzid}}} parameter. Otherwise, leaving it empty will yield the only + available timezone. + +==== tzical examples ==== +Here is a sample file extracted from the RFC. This file defines +the {{{EST5EDT}}} timezone, and will be used in the following example. +{{{ +BEGIN:VTIMEZONE +TZID:US-Eastern +LAST-MODIFIED:19870101T000000Z +TZURL:http://zones.stds_r_us.net/tz/US-Eastern +BEGIN:STANDARD +DTSTART:19671029T020000 +RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 +TZOFFSETFROM:-0400 +TZOFFSETTO:-0500 +TZNAME:EST +END:STANDARD +BEGIN:DAYLIGHT +DTSTART:19870405T020000 +RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4 +TZOFFSETFROM:-0500 +TZOFFSETTO:-0400 +TZNAME:EDT +END:DAYLIGHT +END:VTIMEZONE +}}} + +And here is an example exploring a {{{tzical}}} type: +{{{ +>>> from dateutil.tz import *; from datetime import * + +>>> tz = tzical('EST5EDT.ics') +>>> tz.keys() +['US-Eastern'] + +>>> est = tz.get('US-Eastern') +>>> est + + +>>> datetime.now(est) +datetime.datetime(2003, 10, 6, 19, 44, 18, 667987, + tzinfo=) + +>>> est == tz.get() +True +}}} + +Let's check the daylight ranges, as usual: +{{{ +>>> datetime(2003, 4, 6, 1, 59, tzinfo=est).tzname() +'EST' +>>> datetime(2003, 4, 6, 2, 00, tzinfo=est).tzname() +'EDT' + +>>> datetime(2003, 10, 26, 0, 59, tzinfo=est).tzname() +'EDT' +>>> datetime(2003, 10, 26, 1, 00, tzinfo=est).tzname() +'EST' +}}} + +==== tzwin type ==== +This type offers access to internal registry-based Windows timezones. +The constuctor prototype is: +{{{ +tzwin(name) +}}} + +Where {{{name}}} is the timezone name. There's a static {{{tzwin.list()}}} +method to check the available names, + +==== tzwin methods ==== + + tzwin.display():: + This method returns the timezone extended name. + + tzwin.list():: + This static method lists all available timezone names. + +==== tzwin examples ==== +{{{ +>>> tz = tzwin("E. South America Standard Time") +}}} + +==== tzwinlocal type ==== +This type offers access to internal registry-based Windows timezones. +The constructor accepts no parameters, so the prototype is: +{{{ +tzwinlocal() +}}} + +==== tzwinlocal methods ==== + + tzwinlocal.display():: + This method returns the timezone extended name, and returns + {{{None}}} if one is not available. + +==== tzwinlocal examples ==== +{{{ +>>> tz = tzwinlocal() +}}} + +==== gettz() function ==== +This function is a helper that will try its best to get the right +timezone for your environment, or for the given string. The prototype +is as follows: +{{{ +gettz(name=None) +}}} + +If given, the parameter may be a filename, a path relative to the base +of the timezone information path (the base could be +{{{/usr/share/zoneinfo}}}, for example), a string timezone +specification, or a timezone abbreviation. If {{{name}}} is not given, +and the {{{TZ}}} environment variable is set, it's used instead. If the +parameter is not given, and {{{TZ}}} is not set, the default tzfile +paths will be tried. Then, if no timezone information is found, +an internal compiled database of timezones is used. When running +on Windows, the internal registry-based Windows timezones are also +considered. + +Example: +{{{ +>>> from dateutil.tz import * +>>> gettz() +tzfile('/etc/localtime') + +>>> gettz("America/Sao Paulo") +tzfile('/usr/share/zoneinfo/America/Sao_Paulo') + +>>> gettz("EST5EDT") +tzfile('/usr/share/zoneinfo/EST5EDT') + +>>> gettz("EST5") +tzstr('EST5') + +>>> gettz('BRST') +tzlocal() + +>>> os.environ["TZ"] = "America/Sao Paulo" +>>> gettz() +tzfile('/usr/share/zoneinfo/America/Sao_Paulo') + +>>> os.environ["TZ"] = "BRST" +>>> gettz() +tzlocal() + +>>> gettz("Unavailable") +>>> +}}} + +=== zoneinfo === +This module provides direct access to the internal compiled +database of timezones. The timezone data and the compiling tools +are obtained from the following project: + + http://www.twinsun.com/tz/tz-link.htm + +==== gettz() function ==== +This function will try to retrieve the given timezone information +from the internal compiled database, and will cache its results. + +Example: +{{{ +>>> from dateutil import zoneinfo +>>> zoneinfo.gettz("Brazil/East") +tzfile('Brazil/East') +}}} + +## vim:ft=moin diff -Nru matplotlib-1.1.1/lib/dateutil_py3/__init__.py matplotlib-1.2.0/lib/dateutil_py3/__init__.py --- matplotlib-1.1.1/lib/dateutil_py3/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py3/__init__.py 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +""" +Copyright (c) 2003-2010 Gustavo Niemeyer + +This module offers extensions to the standard Python +datetime module. +""" +__author__ = "Tomi Pieviläinen " +__license__ = "Simplified BSD" +__version__ = "2.1-mpl" diff -Nru matplotlib-1.1.1/lib/dateutil_py3/easter.py matplotlib-1.2.0/lib/dateutil_py3/easter.py --- matplotlib-1.1.1/lib/dateutil_py3/easter.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py3/easter.py 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,91 @@ +""" +Copyright (c) 2003-2007 Gustavo Niemeyer + +This module offers extensions to the standard Python +datetime module. +""" +__license__ = "Simplified BSD" + +import datetime + +__all__ = ["easter", "EASTER_JULIAN", "EASTER_ORTHODOX", "EASTER_WESTERN"] + +EASTER_JULIAN = 1 +EASTER_ORTHODOX = 2 +EASTER_WESTERN = 3 + +def easter(year, method=EASTER_WESTERN): + """ + This method was ported from the work done by GM Arts, + on top of the algorithm by Claus Tondering, which was + based in part on the algorithm of Ouding (1940), as + quoted in "Explanatory Supplement to the Astronomical + Almanac", P. Kenneth Seidelmann, editor. + + This algorithm implements three different easter + calculation methods: + + 1 - Original calculation in Julian calendar, valid in + dates after 326 AD + 2 - Original method, with date converted to Gregorian + calendar, valid in years 1583 to 4099 + 3 - Revised method, in Gregorian calendar, valid in + years 1583 to 4099 as well + + These methods are represented by the constants: + + EASTER_JULIAN = 1 + EASTER_ORTHODOX = 2 + EASTER_WESTERN = 3 + + The default method is method 3. + + More about the algorithm may be found at: + + http://users.chariot.net.au/~gmarts/eastalg.htm + + and + + http://www.tondering.dk/claus/calendar.html + + """ + + if not (1 <= method <= 3): + raise ValueError("invalid method") + + # g - Golden year - 1 + # c - Century + # h - (23 - Epact) mod 30 + # i - Number of days from March 21 to Paschal Full Moon + # j - Weekday for PFM (0=Sunday, etc) + # p - Number of days from March 21 to Sunday on or before PFM + # (-6 to 28 methods 1 & 3, to 56 for method 2) + # e - Extra days to add for method 2 (converting Julian + # date to Gregorian date) + + y = year + g = y % 19 + e = 0 + if method < 3: + # Old method + i = (19*g+15)%30 + j = (y+y//4+i)%7 + if method == 2: + # Extra dates to convert Julian to Gregorian date + e = 10 + if y > 1600: + e = e+y//100-16-(y//100-16)//4 + else: + # New method + c = y//100 + h = (c-c//4-(8*c+13)//25+19*g+15)%30 + i = h-(h//28)*(1-(h//28)*(29//(h+1))*((21-g)//11)) + j = (y+y//4+i+2-c+c//4)%7 + + # p can be from -6 to 56 corresponding to dates 22 March to 23 May + # (later dates apply to method 2, although 23 May never actually occurs) + p = i-j+e + d = 1+(p+27+(p+6)//40)%31 + m = 3+(p+26)//30 + return datetime.date(int(y), int(m), int(d)) + diff -Nru matplotlib-1.1.1/lib/dateutil_py3/parser.py matplotlib-1.2.0/lib/dateutil_py3/parser.py --- matplotlib-1.1.1/lib/dateutil_py3/parser.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py3/parser.py 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,909 @@ +# -*- coding:iso-8859-1 -*- +""" +Copyright (c) 2003-2007 Gustavo Niemeyer + +This module offers extensions to the standard Python +datetime module. +""" +from __future__ import unicode_literals +__license__ = "Simplified BSD" + + +import datetime +import string +import time +import sys +import os +import collections + +try: + from io import StringIO +except ImportError: + from io import StringIO + +from six import text_type, binary_type, integer_types + +from . import relativedelta +from . import tz + + +__all__ = ["parse", "parserinfo"] + + +# Some pointers: +# +# http://www.cl.cam.ac.uk/~mgk25/iso-time.html +# http://www.iso.ch/iso/en/prods-services/popstds/datesandtime.html +# http://www.w3.org/TR/NOTE-datetime +# http://ringmaster.arc.nasa.gov/tools/time_formats.html +# http://search.cpan.org/author/MUIR/Time-modules-2003.0211/lib/Time/ParseDate.pm +# http://stein.cshl.org/jade/distrib/docs/java.text.SimpleDateFormat.html + + +class _timelex(object): + + def __init__(self, instream): + if isinstance(instream, text_type): + instream = StringIO(instream) + self.instream = instream + self.wordchars = ('abcdfeghijklmnopqrstuvwxyz' + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_' + '' + '') + self.numchars = '0123456789' + self.whitespace = ' \t\r\n' + self.charstack = [] + self.tokenstack = [] + self.eof = False + + def get_token(self): + if self.tokenstack: + return self.tokenstack.pop(0) + seenletters = False + token = None + state = None + wordchars = self.wordchars + numchars = self.numchars + whitespace = self.whitespace + while not self.eof: + if self.charstack: + nextchar = self.charstack.pop(0) + else: + nextchar = self.instream.read(1) + while nextchar == '\x00': + nextchar = self.instream.read(1) + if not nextchar: + self.eof = True + break + elif not state: + token = nextchar + if nextchar in wordchars: + state = 'a' + elif nextchar in numchars: + state = '0' + elif nextchar in whitespace: + token = ' ' + break # emit token + else: + break # emit token + elif state == 'a': + seenletters = True + if nextchar in wordchars: + token += nextchar + elif nextchar == '.': + token += nextchar + state = 'a.' + else: + self.charstack.append(nextchar) + break # emit token + elif state == '0': + if nextchar in numchars: + token += nextchar + elif nextchar == '.': + token += nextchar + state = '0.' + else: + self.charstack.append(nextchar) + break # emit token + elif state == 'a.': + seenletters = True + if nextchar == '.' or nextchar in wordchars: + token += nextchar + elif nextchar in numchars and token[-1] == '.': + token += nextchar + state = '0.' + else: + self.charstack.append(nextchar) + break # emit token + elif state == '0.': + if nextchar == '.' or nextchar in numchars: + token += nextchar + elif nextchar in wordchars and token[-1] == '.': + token += nextchar + state = 'a.' + else: + self.charstack.append(nextchar) + break # emit token + if (state in ('a.', '0.') and + (seenletters or token.count('.') > 1 or token[-1] == '.')): + l = token.split('.') + token = l[0] + for tok in l[1:]: + self.tokenstack.append('.') + if tok: + self.tokenstack.append(tok) + return token + + def __iter__(self): + return self + + def __next__(self): + token = self.get_token() + if token is None: + raise StopIteration + return token + + def next(self): + return self.__next__() # Python 2.x support + + def split(cls, s): + return list(cls(s)) + split = classmethod(split) + + +class _resultbase(object): + + def __init__(self): + for attr in self.__slots__: + setattr(self, attr, None) + + def _repr(self, classname): + l = [] + for attr in self.__slots__: + value = getattr(self, attr) + if value is not None: + l.append("%s=%s" % (attr, repr(value))) + return "%s(%s)" % (classname, ", ".join(l)) + + def __repr__(self): + return self._repr(self.__class__.__name__) + + +class parserinfo(object): + + # m from a.m/p.m, t from ISO T separator + JUMP = [" ", ".", ",", ";", "-", "/", "'", + "at", "on", "and", "ad", "m", "t", "of", + "st", "nd", "rd", "th"] + + WEEKDAYS = [("Mon", "Monday"), + ("Tue", "Tuesday"), + ("Wed", "Wednesday"), + ("Thu", "Thursday"), + ("Fri", "Friday"), + ("Sat", "Saturday"), + ("Sun", "Sunday")] + MONTHS = [("Jan", "January"), + ("Feb", "February"), + ("Mar", "March"), + ("Apr", "April"), + ("May", "May"), + ("Jun", "June"), + ("Jul", "July"), + ("Aug", "August"), + ("Sep", "Sept", "September"), + ("Oct", "October"), + ("Nov", "November"), + ("Dec", "December")] + HMS = [("h", "hour", "hours"), + ("m", "minute", "minutes"), + ("s", "second", "seconds")] + AMPM = [("am", "a"), + ("pm", "p")] + UTCZONE = ["UTC", "GMT", "Z"] + PERTAIN = ["of"] + TZOFFSET = {} + + def __init__(self, dayfirst=False, yearfirst=False): + self._jump = self._convert(self.JUMP) + self._weekdays = self._convert(self.WEEKDAYS) + self._months = self._convert(self.MONTHS) + self._hms = self._convert(self.HMS) + self._ampm = self._convert(self.AMPM) + self._utczone = self._convert(self.UTCZONE) + self._pertain = self._convert(self.PERTAIN) + + self.dayfirst = dayfirst + self.yearfirst = yearfirst + + self._year = time.localtime().tm_year + self._century = self._year//100*100 + + def _convert(self, lst): + dct = {} + for i in range(len(lst)): + v = lst[i] + if isinstance(v, tuple): + for v in v: + dct[v.lower()] = i + else: + dct[v.lower()] = i + return dct + + def jump(self, name): + return name.lower() in self._jump + + def weekday(self, name): + if len(name) >= 3: + try: + return self._weekdays[name.lower()] + except KeyError: + pass + return None + + def month(self, name): + if len(name) >= 3: + try: + return self._months[name.lower()]+1 + except KeyError: + pass + return None + + def hms(self, name): + try: + return self._hms[name.lower()] + except KeyError: + return None + + def ampm(self, name): + try: + return self._ampm[name.lower()] + except KeyError: + return None + + def pertain(self, name): + return name.lower() in self._pertain + + def utczone(self, name): + return name.lower() in self._utczone + + def tzoffset(self, name): + if name in self._utczone: + return 0 + return self.TZOFFSET.get(name) + + def convertyear(self, year): + if year < 100: + year += self._century + if abs(year-self._year) >= 50: + if year < self._year: + year += 100 + else: + year -= 100 + return year + + def validate(self, res): + # move to info + if res.year is not None: + res.year = self.convertyear(res.year) + if res.tzoffset == 0 and not res.tzname or res.tzname == 'Z': + res.tzname = "UTC" + res.tzoffset = 0 + elif res.tzoffset != 0 and res.tzname and self.utczone(res.tzname): + res.tzoffset = 0 + return True + + +class parser(object): + + def __init__(self, info=None): + self.info = info or parserinfo() + + def parse(self, timestr, default=None, + ignoretz=False, tzinfos=None, + **kwargs): + if not default: + default = datetime.datetime.now().replace(hour=0, minute=0, + second=0, microsecond=0) + res = self._parse(timestr, **kwargs) + if res is None: + raise ValueError("unknown string format") + repl = {} + for attr in ["year", "month", "day", "hour", + "minute", "second", "microsecond"]: + value = getattr(res, attr) + if value is not None: + repl[attr] = value + ret = default.replace(**repl) + if res.weekday is not None and not res.day: + ret = ret+relativedelta.relativedelta(weekday=res.weekday) + if not ignoretz: + if isinstance(tzinfos, collections.Callable) or tzinfos and res.tzname in tzinfos: + if isinstance(tzinfos, collections.Callable): + tzdata = tzinfos(res.tzname, res.tzoffset) + else: + tzdata = tzinfos.get(res.tzname) + if isinstance(tzdata, datetime.tzinfo): + tzinfo = tzdata + elif isinstance(tzdata, text_type): + tzinfo = tz.tzstr(tzdata) + elif isinstance(tzdata, integer_types): + tzinfo = tz.tzoffset(res.tzname, tzdata) + else: + raise ValueError("offset must be tzinfo subclass, " \ + "tz string, or int offset") + ret = ret.replace(tzinfo=tzinfo) + elif res.tzname and res.tzname in time.tzname: + ret = ret.replace(tzinfo=tz.tzlocal()) + elif res.tzoffset == 0: + ret = ret.replace(tzinfo=tz.tzutc()) + elif res.tzoffset: + ret = ret.replace(tzinfo=tz.tzoffset(res.tzname, res.tzoffset)) + return ret + + class _result(_resultbase): + __slots__ = ["year", "month", "day", "weekday", + "hour", "minute", "second", "microsecond", + "tzname", "tzoffset"] + + def _parse(self, timestr, dayfirst=None, yearfirst=None, fuzzy=False): + info = self.info + if dayfirst is None: + dayfirst = info.dayfirst + if yearfirst is None: + yearfirst = info.yearfirst + res = self._result() + l = _timelex.split(timestr) + try: + + # year/month/day list + ymd = [] + + # Index of the month string in ymd + mstridx = -1 + + len_l = len(l) + i = 0 + while i < len_l: + + # Check if it's a number + try: + value_repr = l[i] + value = float(value_repr) + except ValueError: + value = None + + if value is not None: + # Token is a number + len_li = len(l[i]) + i += 1 + if (len(ymd) == 3 and len_li in (2, 4) + and (i >= len_l or (l[i] != ':' and + info.hms(l[i]) is None))): + # 19990101T23[59] + s = l[i-1] + res.hour = int(s[:2]) + if len_li == 4: + res.minute = int(s[2:]) + elif len_li == 6 or (len_li > 6 and l[i-1].find('.') == 6): + # YYMMDD or HHMMSS[.ss] + s = l[i-1] + if not ymd and l[i-1].find('.') == -1: + ymd.append(info.convertyear(int(s[:2]))) + ymd.append(int(s[2:4])) + ymd.append(int(s[4:])) + else: + # 19990101T235959[.59] + res.hour = int(s[:2]) + res.minute = int(s[2:4]) + res.second, res.microsecond = _parsems(s[4:]) + elif len_li == 8: + # YYYYMMDD + s = l[i-1] + ymd.append(int(s[:4])) + ymd.append(int(s[4:6])) + ymd.append(int(s[6:])) + elif len_li in (12, 14): + # YYYYMMDDhhmm[ss] + s = l[i-1] + ymd.append(int(s[:4])) + ymd.append(int(s[4:6])) + ymd.append(int(s[6:8])) + res.hour = int(s[8:10]) + res.minute = int(s[10:12]) + if len_li == 14: + res.second = int(s[12:]) + elif ((i < len_l and info.hms(l[i]) is not None) or + (i+1 < len_l and l[i] == ' ' and + info.hms(l[i+1]) is not None)): + # HH[ ]h or MM[ ]m or SS[.ss][ ]s + if l[i] == ' ': + i += 1 + idx = info.hms(l[i]) + while True: + if idx == 0: + res.hour = int(value) + if value%1: + res.minute = int(60*(value%1)) + elif idx == 1: + res.minute = int(value) + if value%1: + res.second = int(60*(value%1)) + elif idx == 2: + res.second, res.microsecond = \ + _parsems(value_repr) + i += 1 + if i >= len_l or idx == 2: + break + # 12h00 + try: + value_repr = l[i] + value = float(value_repr) + except ValueError: + break + else: + i += 1 + idx += 1 + if i < len_l: + newidx = info.hms(l[i]) + if newidx is not None: + idx = newidx + elif i == len_l and l[i-2] == ' ' and info.hms(l[i-3]) is not None: + # X h MM or X m SS + idx = info.hms(l[i-3]) + 1 + if idx == 1: + res.minute = int(value) + if value%1: + res.second = int(60*(value%1)) + elif idx == 2: + res.second, res.microsecond = \ + _parsems(value_repr) + i += 1 + elif i+1 < len_l and l[i] == ':': + # HH:MM[:SS[.ss]] + res.hour = int(value) + i += 1 + value = float(l[i]) + res.minute = int(value) + if value%1: + res.second = int(60*(value%1)) + i += 1 + if i < len_l and l[i] == ':': + res.second, res.microsecond = _parsems(l[i+1]) + i += 2 + elif i < len_l and l[i] in ('-', '/', '.'): + sep = l[i] + ymd.append(int(value)) + i += 1 + if i < len_l and not info.jump(l[i]): + try: + # 01-01[-01] + ymd.append(int(l[i])) + except ValueError: + # 01-Jan[-01] + value = info.month(l[i]) + if value is not None: + ymd.append(value) + assert mstridx == -1 + mstridx = len(ymd)-1 + else: + return None + i += 1 + if i < len_l and l[i] == sep: + # We have three members + i += 1 + value = info.month(l[i]) + if value is not None: + ymd.append(value) + mstridx = len(ymd)-1 + assert mstridx == -1 + else: + ymd.append(int(l[i])) + i += 1 + elif i >= len_l or info.jump(l[i]): + if i+1 < len_l and info.ampm(l[i+1]) is not None: + # 12 am + res.hour = int(value) + if res.hour < 12 and info.ampm(l[i+1]) == 1: + res.hour += 12 + elif res.hour == 12 and info.ampm(l[i+1]) == 0: + res.hour = 0 + i += 1 + else: + # Year, month or day + ymd.append(int(value)) + i += 1 + elif info.ampm(l[i]) is not None: + # 12am + res.hour = int(value) + if res.hour < 12 and info.ampm(l[i]) == 1: + res.hour += 12 + elif res.hour == 12 and info.ampm(l[i]) == 0: + res.hour = 0 + i += 1 + elif not fuzzy: + return None + else: + i += 1 + continue + + # Check weekday + value = info.weekday(l[i]) + if value is not None: + res.weekday = value + i += 1 + continue + + # Check month name + value = info.month(l[i]) + if value is not None: + ymd.append(value) + assert mstridx == -1 + mstridx = len(ymd)-1 + i += 1 + if i < len_l: + if l[i] in ('-', '/'): + # Jan-01[-99] + sep = l[i] + i += 1 + ymd.append(int(l[i])) + i += 1 + if i < len_l and l[i] == sep: + # Jan-01-99 + i += 1 + ymd.append(int(l[i])) + i += 1 + elif (i+3 < len_l and l[i] == l[i+2] == ' ' + and info.pertain(l[i+1])): + # Jan of 01 + # In this case, 01 is clearly year + try: + value = int(l[i+3]) + except ValueError: + # Wrong guess + pass + else: + # Convert it here to become unambiguous + ymd.append(info.convertyear(value)) + i += 4 + continue + + # Check am/pm + value = info.ampm(l[i]) + if value is not None: + if value == 1 and res.hour < 12: + res.hour += 12 + elif value == 0 and res.hour == 12: + res.hour = 0 + i += 1 + continue + + # Check for a timezone name + if (res.hour is not None and len(l[i]) <= 5 and + res.tzname is None and res.tzoffset is None and + not [x for x in l[i] if x not in string.ascii_uppercase]): + res.tzname = l[i] + res.tzoffset = info.tzoffset(res.tzname) + i += 1 + + # Check for something like GMT+3, or BRST+3. Notice + # that it doesn't mean "I am 3 hours after GMT", but + # "my time +3 is GMT". If found, we reverse the + # logic so that timezone parsing code will get it + # right. + if i < len_l and l[i] in ('+', '-'): + l[i] = ('+', '-')[l[i] == '+'] + res.tzoffset = None + if info.utczone(res.tzname): + # With something like GMT+3, the timezone + # is *not* GMT. + res.tzname = None + + continue + + # Check for a numbered timezone + if res.hour is not None and l[i] in ('+', '-'): + signal = (-1, 1)[l[i] == '+'] + i += 1 + len_li = len(l[i]) + if len_li == 4: + # -0300 + res.tzoffset = int(l[i][:2])*3600+int(l[i][2:])*60 + elif i+1 < len_l and l[i+1] == ':': + # -03:00 + res.tzoffset = int(l[i])*3600+int(l[i+2])*60 + i += 2 + elif len_li <= 2: + # -[0]3 + res.tzoffset = int(l[i][:2])*3600 + else: + return None + i += 1 + res.tzoffset *= signal + + # Look for a timezone name between parenthesis + if (i+3 < len_l and + info.jump(l[i]) and l[i+1] == '(' and l[i+3] == ')' and + 3 <= len(l[i+2]) <= 5 and + not [x for x in l[i+2] + if x not in string.ascii_uppercase]): + # -0300 (BRST) + res.tzname = l[i+2] + i += 4 + continue + + # Check jumps + if not (info.jump(l[i]) or fuzzy): + return None + + i += 1 + + # Process year/month/day + len_ymd = len(ymd) + if len_ymd > 3: + # More than three members!? + return None + elif len_ymd == 1 or (mstridx != -1 and len_ymd == 2): + # One member, or two members with a month string + if mstridx != -1: + res.month = ymd[mstridx] + del ymd[mstridx] + if len_ymd > 1 or mstridx == -1: + if ymd[0] > 31: + res.year = ymd[0] + else: + res.day = ymd[0] + elif len_ymd == 2: + # Two members with numbers + if ymd[0] > 31: + # 99-01 + res.year, res.month = ymd + elif ymd[1] > 31: + # 01-99 + res.month, res.year = ymd + elif dayfirst and ymd[1] <= 12: + # 13-01 + res.day, res.month = ymd + else: + # 01-13 + res.month, res.day = ymd + if len_ymd == 3: + # Three members + if mstridx == 0: + res.month, res.day, res.year = ymd + elif mstridx == 1: + if ymd[0] > 31 or (yearfirst and ymd[2] <= 31): + # 99-Jan-01 + res.year, res.month, res.day = ymd + else: + # 01-Jan-01 + # Give precendence to day-first, since + # two-digit years is usually hand-written. + res.day, res.month, res.year = ymd + elif mstridx == 2: + # WTF!? + if ymd[1] > 31: + # 01-99-Jan + res.day, res.year, res.month = ymd + else: + # 99-01-Jan + res.year, res.day, res.month = ymd + else: + if ymd[0] > 31 or \ + (yearfirst and ymd[1] <= 12 and ymd[2] <= 31): + # 99-01-01 + res.year, res.month, res.day = ymd + elif ymd[0] > 12 or (dayfirst and ymd[1] <= 12): + # 13-01-01 + res.day, res.month, res.year = ymd + else: + # 01-13-01 + res.month, res.day, res.year = ymd + + except (IndexError, ValueError, AssertionError): + return None + + if not info.validate(res): + return None + return res + +DEFAULTPARSER = parser() +def parse(timestr, parserinfo=None, **kwargs): + # Python 2.x support: datetimes return their string presentation as + # bytes in 2.x and unicode in 3.x, so it's reasonable to expect that + # the parser will get both kinds. Internally we use unicode only. + if isinstance(timestr, binary_type): + timestr = timestr.decode() + if parserinfo: + return parser(parserinfo).parse(timestr, **kwargs) + else: + return DEFAULTPARSER.parse(timestr, **kwargs) + + +class _tzparser(object): + + class _result(_resultbase): + + __slots__ = ["stdabbr", "stdoffset", "dstabbr", "dstoffset", + "start", "end"] + + class _attr(_resultbase): + __slots__ = ["month", "week", "weekday", + "yday", "jyday", "day", "time"] + + def __repr__(self): + return self._repr("") + + def __init__(self): + _resultbase.__init__(self) + self.start = self._attr() + self.end = self._attr() + + def parse(self, tzstr): + res = self._result() + l = _timelex.split(tzstr) + try: + + len_l = len(l) + + i = 0 + while i < len_l: + # BRST+3[BRDT[+2]] + j = i + while j < len_l and not [x for x in l[j] + if x in "0123456789:,-+"]: + j += 1 + if j != i: + if not res.stdabbr: + offattr = "stdoffset" + res.stdabbr = "".join(l[i:j]) + else: + offattr = "dstoffset" + res.dstabbr = "".join(l[i:j]) + i = j + if (i < len_l and + (l[i] in ('+', '-') or l[i][0] in "0123456789")): + if l[i] in ('+', '-'): + # Yes, that's right. See the TZ variable + # documentation. + signal = (1, -1)[l[i] == '+'] + i += 1 + else: + signal = -1 + len_li = len(l[i]) + if len_li == 4: + # -0300 + setattr(res, offattr, + (int(l[i][:2])*3600+int(l[i][2:])*60)*signal) + elif i+1 < len_l and l[i+1] == ':': + # -03:00 + setattr(res, offattr, + (int(l[i])*3600+int(l[i+2])*60)*signal) + i += 2 + elif len_li <= 2: + # -[0]3 + setattr(res, offattr, + int(l[i][:2])*3600*signal) + else: + return None + i += 1 + if res.dstabbr: + break + else: + break + + if i < len_l: + for j in range(i, len_l): + if l[j] == ';': l[j] = ',' + + assert l[i] == ',' + + i += 1 + + if i >= len_l: + pass + elif (8 <= l.count(',') <= 9 and + not [y for x in l[i:] if x != ',' + for y in x if y not in "0123456789"]): + # GMT0BST,3,0,30,3600,10,0,26,7200[,3600] + for x in (res.start, res.end): + x.month = int(l[i]) + i += 2 + if l[i] == '-': + value = int(l[i+1])*-1 + i += 1 + else: + value = int(l[i]) + i += 2 + if value: + x.week = value + x.weekday = (int(l[i])-1)%7 + else: + x.day = int(l[i]) + i += 2 + x.time = int(l[i]) + i += 2 + if i < len_l: + if l[i] in ('-', '+'): + signal = (-1, 1)[l[i] == "+"] + i += 1 + else: + signal = 1 + res.dstoffset = (res.stdoffset+int(l[i]))*signal + elif (l.count(',') == 2 and l[i:].count('/') <= 2 and + not [y for x in l[i:] if x not in (',', '/', 'J', 'M', + '.', '-', ':') + for y in x if y not in "0123456789"]): + for x in (res.start, res.end): + if l[i] == 'J': + # non-leap year day (1 based) + i += 1 + x.jyday = int(l[i]) + elif l[i] == 'M': + # month[-.]week[-.]weekday + i += 1 + x.month = int(l[i]) + i += 1 + assert l[i] in ('-', '.') + i += 1 + x.week = int(l[i]) + if x.week == 5: + x.week = -1 + i += 1 + assert l[i] in ('-', '.') + i += 1 + x.weekday = (int(l[i])-1)%7 + else: + # year day (zero based) + x.yday = int(l[i])+1 + + i += 1 + + if i < len_l and l[i] == '/': + i += 1 + # start time + len_li = len(l[i]) + if len_li == 4: + # -0300 + x.time = (int(l[i][:2])*3600+int(l[i][2:])*60) + elif i+1 < len_l and l[i+1] == ':': + # -03:00 + x.time = int(l[i])*3600+int(l[i+2])*60 + i += 2 + if i+1 < len_l and l[i+1] == ':': + i += 2 + x.time += int(l[i]) + elif len_li <= 2: + # -[0]3 + x.time = (int(l[i][:2])*3600) + else: + return None + i += 1 + + assert i == len_l or l[i] == ',' + + i += 1 + + assert i >= len_l + + except (IndexError, ValueError, AssertionError): + return None + + return res + + +DEFAULTTZPARSER = _tzparser() +def _parsetz(tzstr): + return DEFAULTTZPARSER.parse(tzstr) + + +def _parsems(value): + """Parse a I[.F] seconds value into (seconds, microseconds).""" + if "." not in value: + return int(value), 0 + else: + i, f = value.split(".") + return int(i), int(f.ljust(6, "0")[:6]) + + +# vim:ts=4:sw=4:et diff -Nru matplotlib-1.1.1/lib/dateutil_py3/relativedelta.py matplotlib-1.2.0/lib/dateutil_py3/relativedelta.py --- matplotlib-1.1.1/lib/dateutil_py3/relativedelta.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py3/relativedelta.py 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,436 @@ +""" +Copyright (c) 2003-2010 Gustavo Niemeyer + +This module offers extensions to the standard Python +datetime module. +""" +__license__ = "Simplified BSD" + +import datetime +import calendar + +from six import integer_types + +__all__ = ["relativedelta", "MO", "TU", "WE", "TH", "FR", "SA", "SU"] + +class weekday(object): + __slots__ = ["weekday", "n"] + + def __init__(self, weekday, n=None): + self.weekday = weekday + self.n = n + + def __call__(self, n): + if n == self.n: + return self + else: + return self.__class__(self.weekday, n) + + def __eq__(self, other): + try: + if self.weekday != other.weekday or self.n != other.n: + return False + except AttributeError: + return False + return True + + def __repr__(self): + s = ("MO", "TU", "WE", "TH", "FR", "SA", "SU")[self.weekday] + if not self.n: + return s + else: + return "%s(%+d)" % (s, self.n) + +MO, TU, WE, TH, FR, SA, SU = weekdays = tuple([weekday(x) for x in range(7)]) + +class relativedelta(object): + """ +The relativedelta type is based on the specification of the excelent +work done by M.-A. Lemburg in his mx.DateTime extension. However, +notice that this type does *NOT* implement the same algorithm as +his work. Do *NOT* expect it to behave like mx.DateTime's counterpart. + +There's two different ways to build a relativedelta instance. The +first one is passing it two date/datetime classes: + + relativedelta(datetime1, datetime2) + +And the other way is to use the following keyword arguments: + + year, month, day, hour, minute, second, microsecond: + Absolute information. + + years, months, weeks, days, hours, minutes, seconds, microseconds: + Relative information, may be negative. + + weekday: + One of the weekday instances (MO, TU, etc). These instances may + receive a parameter N, specifying the Nth weekday, which could + be positive or negative (like MO(+1) or MO(-2). Not specifying + it is the same as specifying +1. You can also use an integer, + where 0=MO. + + leapdays: + Will add given days to the date found, if year is a leap + year, and the date found is post 28 of february. + + yearday, nlyearday: + Set the yearday or the non-leap year day (jump leap days). + These are converted to day/month/leapdays information. + +Here is the behavior of operations with relativedelta: + +1) Calculate the absolute year, using the 'year' argument, or the + original datetime year, if the argument is not present. + +2) Add the relative 'years' argument to the absolute year. + +3) Do steps 1 and 2 for month/months. + +4) Calculate the absolute day, using the 'day' argument, or the + original datetime day, if the argument is not present. Then, + subtract from the day until it fits in the year and month + found after their operations. + +5) Add the relative 'days' argument to the absolute day. Notice + that the 'weeks' argument is multiplied by 7 and added to + 'days'. + +6) Do steps 1 and 2 for hour/hours, minute/minutes, second/seconds, + microsecond/microseconds. + +7) If the 'weekday' argument is present, calculate the weekday, + with the given (wday, nth) tuple. wday is the index of the + weekday (0-6, 0=Mon), and nth is the number of weeks to add + forward or backward, depending on its signal. Notice that if + the calculated date is already Monday, for example, using + (0, 1) or (0, -1) won't change the day. + """ + + def __init__(self, dt1=None, dt2=None, + years=0, months=0, days=0, leapdays=0, weeks=0, + hours=0, minutes=0, seconds=0, microseconds=0, + year=None, month=None, day=None, weekday=None, + yearday=None, nlyearday=None, + hour=None, minute=None, second=None, microsecond=None): + if dt1 and dt2: + if (not isinstance(dt1, datetime.date)) or (not isinstance(dt2, datetime.date)): + raise TypeError("relativedelta only diffs datetime/date") + if not type(dt1) == type(dt2): #isinstance(dt1, type(dt2)): + if not isinstance(dt1, datetime.datetime): + dt1 = datetime.datetime.fromordinal(dt1.toordinal()) + elif not isinstance(dt2, datetime.datetime): + dt2 = datetime.datetime.fromordinal(dt2.toordinal()) + self.years = 0 + self.months = 0 + self.days = 0 + self.leapdays = 0 + self.hours = 0 + self.minutes = 0 + self.seconds = 0 + self.microseconds = 0 + self.year = None + self.month = None + self.day = None + self.weekday = None + self.hour = None + self.minute = None + self.second = None + self.microsecond = None + self._has_time = 0 + + months = (dt1.year*12+dt1.month)-(dt2.year*12+dt2.month) + self._set_months(months) + dtm = self.__radd__(dt2) + if dt1 < dt2: + while dt1 > dtm: + months += 1 + self._set_months(months) + dtm = self.__radd__(dt2) + else: + while dt1 < dtm: + months -= 1 + self._set_months(months) + dtm = self.__radd__(dt2) + delta = dt1 - dtm + self.seconds = delta.seconds+delta.days*86400 + self.microseconds = delta.microseconds + else: + self.years = years + self.months = months + self.days = days+weeks*7 + self.leapdays = leapdays + self.hours = hours + self.minutes = minutes + self.seconds = seconds + self.microseconds = microseconds + self.year = year + self.month = month + self.day = day + self.hour = hour + self.minute = minute + self.second = second + self.microsecond = microsecond + + if isinstance(weekday, integer_types): + self.weekday = weekdays[weekday] + else: + self.weekday = weekday + + yday = 0 + if nlyearday: + yday = nlyearday + elif yearday: + yday = yearday + if yearday > 59: + self.leapdays = -1 + if yday: + ydayidx = [31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 366] + for idx, ydays in enumerate(ydayidx): + if yday <= ydays: + self.month = idx+1 + if idx == 0: + self.day = yday + else: + self.day = yday-ydayidx[idx-1] + break + else: + raise ValueError("invalid year day (%d)" % yday) + + self._fix() + + def _fix(self): + if abs(self.microseconds) > 999999: + s = self.microseconds//abs(self.microseconds) + div, mod = divmod(self.microseconds*s, 1000000) + self.microseconds = mod*s + self.seconds += div*s + if abs(self.seconds) > 59: + s = self.seconds//abs(self.seconds) + div, mod = divmod(self.seconds*s, 60) + self.seconds = mod*s + self.minutes += div*s + if abs(self.minutes) > 59: + s = self.minutes//abs(self.minutes) + div, mod = divmod(self.minutes*s, 60) + self.minutes = mod*s + self.hours += div*s + if abs(self.hours) > 23: + s = self.hours//abs(self.hours) + div, mod = divmod(self.hours*s, 24) + self.hours = mod*s + self.days += div*s + if abs(self.months) > 11: + s = self.months//abs(self.months) + div, mod = divmod(self.months*s, 12) + self.months = mod*s + self.years += div*s + if (self.hours or self.minutes or self.seconds or self.microseconds or + self.hour is not None or self.minute is not None or + self.second is not None or self.microsecond is not None): + self._has_time = 1 + else: + self._has_time = 0 + + def _set_months(self, months): + self.months = months + if abs(self.months) > 11: + s = self.months//abs(self.months) + div, mod = divmod(self.months*s, 12) + self.months = mod*s + self.years = div*s + else: + self.years = 0 + + def __add__(self, other): + if isinstance(other, relativedelta): + return relativedelta(years=other.years+self.years, + months=other.months+self.months, + days=other.days+self.days, + hours=other.hours+self.hours, + minutes=other.minutes+self.minutes, + seconds=other.seconds+self.seconds, + microseconds=other.microseconds+self.microseconds, + leapdays=other.leapdays or self.leapdays, + year=other.year or self.year, + month=other.month or self.month, + day=other.day or self.day, + weekday=other.weekday or self.weekday, + hour=other.hour or self.hour, + minute=other.minute or self.minute, + second=other.second or self.second, + microsecond=other.microsecond or self.microsecond) + if not isinstance(other, datetime.date): + raise TypeError("unsupported type for add operation") + elif self._has_time and not isinstance(other, datetime.datetime): + other = datetime.datetime.fromordinal(other.toordinal()) + year = (self.year or other.year)+self.years + month = self.month or other.month + if self.months: + assert 1 <= abs(self.months) <= 12 + month += self.months + if month > 12: + year += 1 + month -= 12 + elif month < 1: + year -= 1 + month += 12 + day = min(calendar.monthrange(year, month)[1], + self.day or other.day) + repl = {"year": year, "month": month, "day": day} + for attr in ["hour", "minute", "second", "microsecond"]: + value = getattr(self, attr) + if value is not None: + repl[attr] = value + days = self.days + if self.leapdays and month > 2 and calendar.isleap(year): + days += self.leapdays + ret = (other.replace(**repl) + + datetime.timedelta(days=days, + hours=self.hours, + minutes=self.minutes, + seconds=self.seconds, + microseconds=self.microseconds)) + if self.weekday: + weekday, nth = self.weekday.weekday, self.weekday.n or 1 + jumpdays = (abs(nth)-1)*7 + if nth > 0: + jumpdays += (7-ret.weekday()+weekday)%7 + else: + jumpdays += (ret.weekday()-weekday)%7 + jumpdays *= -1 + ret += datetime.timedelta(days=jumpdays) + return ret + + def __radd__(self, other): + return self.__add__(other) + + def __rsub__(self, other): + return self.__neg__().__radd__(other) + + def __sub__(self, other): + if not isinstance(other, relativedelta): + raise TypeError("unsupported type for sub operation") + return relativedelta(years=self.years-other.years, + months=self.months-other.months, + days=self.days-other.days, + hours=self.hours-other.hours, + minutes=self.minutes-other.minutes, + seconds=self.seconds-other.seconds, + microseconds=self.microseconds-other.microseconds, + leapdays=self.leapdays or other.leapdays, + year=self.year or other.year, + month=self.month or other.month, + day=self.day or other.day, + weekday=self.weekday or other.weekday, + hour=self.hour or other.hour, + minute=self.minute or other.minute, + second=self.second or other.second, + microsecond=self.microsecond or other.microsecond) + + def __neg__(self): + return relativedelta(years=-self.years, + months=-self.months, + days=-self.days, + hours=-self.hours, + minutes=-self.minutes, + seconds=-self.seconds, + microseconds=-self.microseconds, + leapdays=self.leapdays, + year=self.year, + month=self.month, + day=self.day, + weekday=self.weekday, + hour=self.hour, + minute=self.minute, + second=self.second, + microsecond=self.microsecond) + + def __bool__(self): + return not (not self.years and + not self.months and + not self.days and + not self.hours and + not self.minutes and + not self.seconds and + not self.microseconds and + not self.leapdays and + self.year is None and + self.month is None and + self.day is None and + self.weekday is None and + self.hour is None and + self.minute is None and + self.second is None and + self.microsecond is None) + + def __mul__(self, other): + f = float(other) + return relativedelta(years=int(self.years*f), + months=int(self.months*f), + days=int(self.days*f), + hours=int(self.hours*f), + minutes=int(self.minutes*f), + seconds=int(self.seconds*f), + microseconds=int(self.microseconds*f), + leapdays=self.leapdays, + year=self.year, + month=self.month, + day=self.day, + weekday=self.weekday, + hour=self.hour, + minute=self.minute, + second=self.second, + microsecond=self.microsecond) + + __rmul__ = __mul__ + + def __eq__(self, other): + if not isinstance(other, relativedelta): + return False + if self.weekday or other.weekday: + if not self.weekday or not other.weekday: + return False + if self.weekday.weekday != other.weekday.weekday: + return False + n1, n2 = self.weekday.n, other.weekday.n + if n1 != n2 and not ((not n1 or n1 == 1) and (not n2 or n2 == 1)): + return False + return (self.years == other.years and + self.months == other.months and + self.days == other.days and + self.hours == other.hours and + self.minutes == other.minutes and + self.seconds == other.seconds and + self.leapdays == other.leapdays and + self.year == other.year and + self.month == other.month and + self.day == other.day and + self.hour == other.hour and + self.minute == other.minute and + self.second == other.second and + self.microsecond == other.microsecond) + + def __ne__(self, other): + return not self.__eq__(other) + + def __div__(self, other): + return self.__mul__(1/float(other)) + + __truediv__ = __div__ + + def __repr__(self): + l = [] + for attr in ["years", "months", "days", "leapdays", + "hours", "minutes", "seconds", "microseconds"]: + value = getattr(self, attr) + if value: + l.append("%s=%+d" % (attr, value)) + for attr in ["year", "month", "day", "weekday", + "hour", "minute", "second", "microsecond"]: + value = getattr(self, attr) + if value is not None: + l.append("%s=%s" % (attr, repr(value))) + return "%s(%s)" % (self.__class__.__name__, ", ".join(l)) + +# vim:ts=4:sw=4:et diff -Nru matplotlib-1.1.1/lib/dateutil_py3/rrule.py matplotlib-1.2.0/lib/dateutil_py3/rrule.py --- matplotlib-1.1.1/lib/dateutil_py3/rrule.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py3/rrule.py 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,1112 @@ +""" +Copyright (c) 2003-2010 Gustavo Niemeyer + +This module offers extensions to the standard Python +datetime module. +""" +__license__ = "Simplified BSD" + +import itertools +import datetime +import calendar +try: + import _thread +except ImportError: + import thread as _thread +import sys + +from six import advance_iterator, integer_types + +__all__ = ["rrule", "rruleset", "rrulestr", + "YEARLY", "MONTHLY", "WEEKLY", "DAILY", + "HOURLY", "MINUTELY", "SECONDLY", + "MO", "TU", "WE", "TH", "FR", "SA", "SU"] + +# Every mask is 7 days longer to handle cross-year weekly periods. +M366MASK = tuple([1]*31+[2]*29+[3]*31+[4]*30+[5]*31+[6]*30+ + [7]*31+[8]*31+[9]*30+[10]*31+[11]*30+[12]*31+[1]*7) +M365MASK = list(M366MASK) +M29, M30, M31 = list(range(1, 30)), list(range(1, 31)), list(range(1, 32)) +MDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7]) +MDAY365MASK = list(MDAY366MASK) +M29, M30, M31 = list(range(-29, 0)), list(range(-30, 0)), list(range(-31, 0)) +NMDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7]) +NMDAY365MASK = list(NMDAY366MASK) +M366RANGE = (0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366) +M365RANGE = (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365) +WDAYMASK = [0, 1, 2, 3, 4, 5, 6]*55 +del M29, M30, M31, M365MASK[59], MDAY365MASK[59], NMDAY365MASK[31] +MDAY365MASK = tuple(MDAY365MASK) +M365MASK = tuple(M365MASK) + +(YEARLY, + MONTHLY, + WEEKLY, + DAILY, + HOURLY, + MINUTELY, + SECONDLY) = list(range(7)) + +# Imported on demand. +easter = None +parser = None + +class weekday(object): + __slots__ = ["weekday", "n"] + + def __init__(self, weekday, n=None): + if n == 0: + raise ValueError("Can't create weekday with n == 0") + self.weekday = weekday + self.n = n + + def __call__(self, n): + if n == self.n: + return self + else: + return self.__class__(self.weekday, n) + + def __eq__(self, other): + try: + if self.weekday != other.weekday or self.n != other.n: + return False + except AttributeError: + return False + return True + + def __repr__(self): + s = ("MO", "TU", "WE", "TH", "FR", "SA", "SU")[self.weekday] + if not self.n: + return s + else: + return "%s(%+d)" % (s, self.n) + +MO, TU, WE, TH, FR, SA, SU = weekdays = tuple([weekday(x) for x in range(7)]) + +class rrulebase(object): + def __init__(self, cache=False): + if cache: + self._cache = [] + self._cache_lock = _thread.allocate_lock() + self._cache_gen = self._iter() + self._cache_complete = False + else: + self._cache = None + self._cache_complete = False + self._len = None + + def __iter__(self): + if self._cache_complete: + return iter(self._cache) + elif self._cache is None: + return self._iter() + else: + return self._iter_cached() + + def _iter_cached(self): + i = 0 + gen = self._cache_gen + cache = self._cache + acquire = self._cache_lock.acquire + release = self._cache_lock.release + while gen: + if i == len(cache): + acquire() + if self._cache_complete: + break + try: + for j in range(10): + cache.append(advance_iterator(gen)) + except StopIteration: + self._cache_gen = gen = None + self._cache_complete = True + break + release() + yield cache[i] + i += 1 + while i < self._len: + yield cache[i] + i += 1 + + def __getitem__(self, item): + if self._cache_complete: + return self._cache[item] + elif isinstance(item, slice): + if item.step and item.step < 0: + return list(iter(self))[item] + else: + return list(itertools.islice(self, + item.start or 0, + item.stop or sys.maxsize, + item.step or 1)) + elif item >= 0: + gen = iter(self) + try: + for i in range(item+1): + res = advance_iterator(gen) + except StopIteration: + raise IndexError + return res + else: + return list(iter(self))[item] + + def __contains__(self, item): + if self._cache_complete: + return item in self._cache + else: + for i in self: + if i == item: + return True + elif i > item: + return False + return False + + # __len__() introduces a large performance penality. + def count(self): + if self._len is None: + for x in self: pass + return self._len + + def before(self, dt, inc=False): + if self._cache_complete: + gen = self._cache + else: + gen = self + last = None + if inc: + for i in gen: + if i > dt: + break + last = i + else: + for i in gen: + if i >= dt: + break + last = i + return last + + def after(self, dt, inc=False): + if self._cache_complete: + gen = self._cache + else: + gen = self + if inc: + for i in gen: + if i >= dt: + return i + else: + for i in gen: + if i > dt: + return i + return None + + def between(self, after, before, inc=False): + if self._cache_complete: + gen = self._cache + else: + gen = self + started = False + l = [] + if inc: + for i in gen: + if i > before: + break + elif not started: + if i >= after: + started = True + l.append(i) + else: + l.append(i) + else: + for i in gen: + if i >= before: + break + elif not started: + if i > after: + started = True + l.append(i) + else: + l.append(i) + return l + +class rrule(rrulebase): + def __init__(self, freq, dtstart=None, + interval=1, wkst=None, count=None, until=None, bysetpos=None, + bymonth=None, bymonthday=None, byyearday=None, byeaster=None, + byweekno=None, byweekday=None, + byhour=None, byminute=None, bysecond=None, + cache=False): + super(rrule, self).__init__(cache) + global easter + if not dtstart: + dtstart = datetime.datetime.now().replace(microsecond=0) + elif not isinstance(dtstart, datetime.datetime): + dtstart = datetime.datetime.fromordinal(dtstart.toordinal()) + else: + dtstart = dtstart.replace(microsecond=0) + self._dtstart = dtstart + self._tzinfo = dtstart.tzinfo + self._freq = freq + self._interval = interval + self._count = count + if until and not isinstance(until, datetime.datetime): + until = datetime.datetime.fromordinal(until.toordinal()) + self._until = until + if wkst is None: + self._wkst = calendar.firstweekday() + elif isinstance(wkst, integer_types): + self._wkst = wkst + else: + self._wkst = wkst.weekday + if bysetpos is None: + self._bysetpos = None + elif isinstance(bysetpos, integer_types): + if bysetpos == 0 or not (-366 <= bysetpos <= 366): + raise ValueError("bysetpos must be between 1 and 366, " + "or between -366 and -1") + self._bysetpos = (bysetpos,) + else: + self._bysetpos = tuple(bysetpos) + for pos in self._bysetpos: + if pos == 0 or not (-366 <= pos <= 366): + raise ValueError("bysetpos must be between 1 and 366, " + "or between -366 and -1") + if not (byweekno or byyearday or bymonthday or + byweekday is not None or byeaster is not None): + if freq == YEARLY: + if not bymonth: + bymonth = dtstart.month + bymonthday = dtstart.day + elif freq == MONTHLY: + bymonthday = dtstart.day + elif freq == WEEKLY: + byweekday = dtstart.weekday() + # bymonth + if not bymonth: + self._bymonth = None + elif isinstance(bymonth, integer_types): + self._bymonth = (bymonth,) + else: + self._bymonth = tuple(bymonth) + # byyearday + if not byyearday: + self._byyearday = None + elif isinstance(byyearday, integer_types): + self._byyearday = (byyearday,) + else: + self._byyearday = tuple(byyearday) + # byeaster + if byeaster is not None: + if not easter: + from dateutil import easter + if isinstance(byeaster, integer_types): + self._byeaster = (byeaster,) + else: + self._byeaster = tuple(byeaster) + else: + self._byeaster = None + # bymonthay + if not bymonthday: + self._bymonthday = () + self._bynmonthday = () + elif isinstance(bymonthday, integer_types): + if bymonthday < 0: + self._bynmonthday = (bymonthday,) + self._bymonthday = () + else: + self._bymonthday = (bymonthday,) + self._bynmonthday = () + else: + self._bymonthday = tuple([x for x in bymonthday if x > 0]) + self._bynmonthday = tuple([x for x in bymonthday if x < 0]) + # byweekno + if byweekno is None: + self._byweekno = None + elif isinstance(byweekno, integer_types): + self._byweekno = (byweekno,) + else: + self._byweekno = tuple(byweekno) + # byweekday / bynweekday + if byweekday is None: + self._byweekday = None + self._bynweekday = None + elif isinstance(byweekday, integer_types): + self._byweekday = (byweekday,) + self._bynweekday = None + elif hasattr(byweekday, "n"): + if not byweekday.n or freq > MONTHLY: + self._byweekday = (byweekday.weekday,) + self._bynweekday = None + else: + self._bynweekday = ((byweekday.weekday, byweekday.n),) + self._byweekday = None + else: + self._byweekday = [] + self._bynweekday = [] + for wday in byweekday: + if isinstance(wday, integer_types): + self._byweekday.append(wday) + elif not wday.n or freq > MONTHLY: + self._byweekday.append(wday.weekday) + else: + self._bynweekday.append((wday.weekday, wday.n)) + self._byweekday = tuple(self._byweekday) + self._bynweekday = tuple(self._bynweekday) + if not self._byweekday: + self._byweekday = None + elif not self._bynweekday: + self._bynweekday = None + # byhour + if byhour is None: + if freq < HOURLY: + self._byhour = (dtstart.hour,) + else: + self._byhour = None + elif isinstance(byhour, integer_types): + self._byhour = (byhour,) + else: + self._byhour = tuple(byhour) + # byminute + if byminute is None: + if freq < MINUTELY: + self._byminute = (dtstart.minute,) + else: + self._byminute = None + elif isinstance(byminute, integer_types): + self._byminute = (byminute,) + else: + self._byminute = tuple(byminute) + # bysecond + if bysecond is None: + if freq < SECONDLY: + self._bysecond = (dtstart.second,) + else: + self._bysecond = None + elif isinstance(bysecond, integer_types): + self._bysecond = (bysecond,) + else: + self._bysecond = tuple(bysecond) + + if self._freq >= HOURLY: + self._timeset = None + else: + self._timeset = [] + for hour in self._byhour: + for minute in self._byminute: + for second in self._bysecond: + self._timeset.append( + datetime.time(hour, minute, second, + tzinfo=self._tzinfo)) + self._timeset.sort() + self._timeset = tuple(self._timeset) + + def _iter(self): + year, month, day, hour, minute, second, weekday, yearday, _ = \ + self._dtstart.timetuple() + + # Some local variables to speed things up a bit + freq = self._freq + interval = self._interval + wkst = self._wkst + until = self._until + bymonth = self._bymonth + byweekno = self._byweekno + byyearday = self._byyearday + byweekday = self._byweekday + byeaster = self._byeaster + bymonthday = self._bymonthday + bynmonthday = self._bynmonthday + bysetpos = self._bysetpos + byhour = self._byhour + byminute = self._byminute + bysecond = self._bysecond + + ii = _iterinfo(self) + ii.rebuild(year, month) + + getdayset = {YEARLY:ii.ydayset, + MONTHLY:ii.mdayset, + WEEKLY:ii.wdayset, + DAILY:ii.ddayset, + HOURLY:ii.ddayset, + MINUTELY:ii.ddayset, + SECONDLY:ii.ddayset}[freq] + + if freq < HOURLY: + timeset = self._timeset + else: + gettimeset = {HOURLY:ii.htimeset, + MINUTELY:ii.mtimeset, + SECONDLY:ii.stimeset}[freq] + if ((freq >= HOURLY and + self._byhour and hour not in self._byhour) or + (freq >= MINUTELY and + self._byminute and minute not in self._byminute) or + (freq >= SECONDLY and + self._bysecond and second not in self._bysecond)): + timeset = () + else: + timeset = gettimeset(hour, minute, second) + + total = 0 + count = self._count + while True: + # Get dayset with the right frequency + dayset, start, end = getdayset(year, month, day) + + # Do the "hard" work ;-) + filtered = False + for i in dayset[start:end]: + if ((bymonth and ii.mmask[i] not in bymonth) or + (byweekno and not ii.wnomask[i]) or + (byweekday and ii.wdaymask[i] not in byweekday) or + (ii.nwdaymask and not ii.nwdaymask[i]) or + (byeaster and not ii.eastermask[i]) or + ((bymonthday or bynmonthday) and + ii.mdaymask[i] not in bymonthday and + ii.nmdaymask[i] not in bynmonthday) or + (byyearday and + ((i < ii.yearlen and i+1 not in byyearday + and -ii.yearlen+i not in byyearday) or + (i >= ii.yearlen and i+1-ii.yearlen not in byyearday + and -ii.nextyearlen+i-ii.yearlen + not in byyearday)))): + dayset[i] = None + filtered = True + + # Output results + if bysetpos and timeset: + poslist = [] + for pos in bysetpos: + if pos < 0: + daypos, timepos = divmod(pos, len(timeset)) + else: + daypos, timepos = divmod(pos-1, len(timeset)) + try: + i = [x for x in dayset[start:end] + if x is not None][daypos] + time = timeset[timepos] + except IndexError: + pass + else: + date = datetime.date.fromordinal(ii.yearordinal+i) + res = datetime.datetime.combine(date, time) + if res not in poslist: + poslist.append(res) + poslist.sort() + for res in poslist: + if until and res > until: + self._len = total + return + elif res >= self._dtstart: + total += 1 + yield res + if count: + count -= 1 + if not count: + self._len = total + return + else: + for i in dayset[start:end]: + if i is not None: + date = datetime.date.fromordinal(ii.yearordinal+i) + for time in timeset: + res = datetime.datetime.combine(date, time) + if until and res > until: + self._len = total + return + elif res >= self._dtstart: + total += 1 + yield res + if count: + count -= 1 + if not count: + self._len = total + return + + # Handle frequency and interval + fixday = False + if freq == YEARLY: + year += interval + if year > datetime.MAXYEAR: + self._len = total + return + ii.rebuild(year, month) + elif freq == MONTHLY: + month += interval + if month > 12: + div, mod = divmod(month, 12) + month = mod + year += div + if month == 0: + month = 12 + year -= 1 + if year > datetime.MAXYEAR: + self._len = total + return + ii.rebuild(year, month) + elif freq == WEEKLY: + if wkst > weekday: + day += -(weekday+1+(6-wkst))+self._interval*7 + else: + day += -(weekday-wkst)+self._interval*7 + weekday = wkst + fixday = True + elif freq == DAILY: + day += interval + fixday = True + elif freq == HOURLY: + if filtered: + # Jump to one iteration before next day + hour += ((23-hour)//interval)*interval + while True: + hour += interval + div, mod = divmod(hour, 24) + if div: + hour = mod + day += div + fixday = True + if not byhour or hour in byhour: + break + timeset = gettimeset(hour, minute, second) + elif freq == MINUTELY: + if filtered: + # Jump to one iteration before next day + minute += ((1439-(hour*60+minute))//interval)*interval + while True: + minute += interval + div, mod = divmod(minute, 60) + if div: + minute = mod + hour += div + div, mod = divmod(hour, 24) + if div: + hour = mod + day += div + fixday = True + filtered = False + if ((not byhour or hour in byhour) and + (not byminute or minute in byminute)): + break + timeset = gettimeset(hour, minute, second) + elif freq == SECONDLY: + if filtered: + # Jump to one iteration before next day + second += (((86399-(hour*3600+minute*60+second)) + //interval)*interval) + while True: + second += self._interval + div, mod = divmod(second, 60) + if div: + second = mod + minute += div + div, mod = divmod(minute, 60) + if div: + minute = mod + hour += div + div, mod = divmod(hour, 24) + if div: + hour = mod + day += div + fixday = True + if ((not byhour or hour in byhour) and + (not byminute or minute in byminute) and + (not bysecond or second in bysecond)): + break + timeset = gettimeset(hour, minute, second) + + if fixday and day > 28: + daysinmonth = calendar.monthrange(year, month)[1] + if day > daysinmonth: + while day > daysinmonth: + day -= daysinmonth + month += 1 + if month == 13: + month = 1 + year += 1 + if year > datetime.MAXYEAR: + self._len = total + return + daysinmonth = calendar.monthrange(year, month)[1] + ii.rebuild(year, month) + +class _iterinfo(object): + __slots__ = ["rrule", "lastyear", "lastmonth", + "yearlen", "nextyearlen", "yearordinal", "yearweekday", + "mmask", "mrange", "mdaymask", "nmdaymask", + "wdaymask", "wnomask", "nwdaymask", "eastermask"] + + def __init__(self, rrule): + for attr in self.__slots__: + setattr(self, attr, None) + self.rrule = rrule + + def rebuild(self, year, month): + # Every mask is 7 days longer to handle cross-year weekly periods. + rr = self.rrule + if year != self.lastyear: + self.yearlen = 365+calendar.isleap(year) + self.nextyearlen = 365+calendar.isleap(year+1) + firstyday = datetime.date(year, 1, 1) + self.yearordinal = firstyday.toordinal() + self.yearweekday = firstyday.weekday() + + wday = datetime.date(year, 1, 1).weekday() + if self.yearlen == 365: + self.mmask = M365MASK + self.mdaymask = MDAY365MASK + self.nmdaymask = NMDAY365MASK + self.wdaymask = WDAYMASK[wday:] + self.mrange = M365RANGE + else: + self.mmask = M366MASK + self.mdaymask = MDAY366MASK + self.nmdaymask = NMDAY366MASK + self.wdaymask = WDAYMASK[wday:] + self.mrange = M366RANGE + + if not rr._byweekno: + self.wnomask = None + else: + self.wnomask = [0]*(self.yearlen+7) + #no1wkst = firstwkst = self.wdaymask.index(rr._wkst) + no1wkst = firstwkst = (7-self.yearweekday+rr._wkst)%7 + if no1wkst >= 4: + no1wkst = 0 + # Number of days in the year, plus the days we got + # from last year. + wyearlen = self.yearlen+(self.yearweekday-rr._wkst)%7 + else: + # Number of days in the year, minus the days we + # left in last year. + wyearlen = self.yearlen-no1wkst + div, mod = divmod(wyearlen, 7) + numweeks = div+mod//4 + for n in rr._byweekno: + if n < 0: + n += numweeks+1 + if not (0 < n <= numweeks): + continue + if n > 1: + i = no1wkst+(n-1)*7 + if no1wkst != firstwkst: + i -= 7-firstwkst + else: + i = no1wkst + for j in range(7): + self.wnomask[i] = 1 + i += 1 + if self.wdaymask[i] == rr._wkst: + break + if 1 in rr._byweekno: + # Check week number 1 of next year as well + # TODO: Check -numweeks for next year. + i = no1wkst+numweeks*7 + if no1wkst != firstwkst: + i -= 7-firstwkst + if i < self.yearlen: + # If week starts in next year, we + # don't care about it. + for j in range(7): + self.wnomask[i] = 1 + i += 1 + if self.wdaymask[i] == rr._wkst: + break + if no1wkst: + # Check last week number of last year as + # well. If no1wkst is 0, either the year + # started on week start, or week number 1 + # got days from last year, so there are no + # days from last year's last week number in + # this year. + if -1 not in rr._byweekno: + lyearweekday = datetime.date(year-1, 1, 1).weekday() + lno1wkst = (7-lyearweekday+rr._wkst)%7 + lyearlen = 365+calendar.isleap(year-1) + if lno1wkst >= 4: + lno1wkst = 0 + lnumweeks = 52+(lyearlen+ + (lyearweekday-rr._wkst)%7)%7//4 + else: + lnumweeks = 52+(self.yearlen-no1wkst)%7//4 + else: + lnumweeks = -1 + if lnumweeks in rr._byweekno: + for i in range(no1wkst): + self.wnomask[i] = 1 + + if (rr._bynweekday and + (month != self.lastmonth or year != self.lastyear)): + ranges = [] + if rr._freq == YEARLY: + if rr._bymonth: + for month in rr._bymonth: + ranges.append(self.mrange[month-1:month+1]) + else: + ranges = [(0, self.yearlen)] + elif rr._freq == MONTHLY: + ranges = [self.mrange[month-1:month+1]] + if ranges: + # Weekly frequency won't get here, so we may not + # care about cross-year weekly periods. + self.nwdaymask = [0]*self.yearlen + for first, last in ranges: + last -= 1 + for wday, n in rr._bynweekday: + if n < 0: + i = last+(n+1)*7 + i -= (self.wdaymask[i]-wday)%7 + else: + i = first+(n-1)*7 + i += (7-self.wdaymask[i]+wday)%7 + if first <= i <= last: + self.nwdaymask[i] = 1 + + if rr._byeaster: + self.eastermask = [0]*(self.yearlen+7) + eyday = easter.easter(year).toordinal()-self.yearordinal + for offset in rr._byeaster: + self.eastermask[eyday+offset] = 1 + + self.lastyear = year + self.lastmonth = month + + def ydayset(self, year, month, day): + return list(range(self.yearlen)), 0, self.yearlen + + def mdayset(self, year, month, day): + set = [None]*self.yearlen + start, end = self.mrange[month-1:month+1] + for i in range(start, end): + set[i] = i + return set, start, end + + def wdayset(self, year, month, day): + # We need to handle cross-year weeks here. + set = [None]*(self.yearlen+7) + i = datetime.date(year, month, day).toordinal()-self.yearordinal + start = i + for j in range(7): + set[i] = i + i += 1 + #if (not (0 <= i < self.yearlen) or + # self.wdaymask[i] == self.rrule._wkst): + # This will cross the year boundary, if necessary. + if self.wdaymask[i] == self.rrule._wkst: + break + return set, start, i + + def ddayset(self, year, month, day): + set = [None]*self.yearlen + i = datetime.date(year, month, day).toordinal()-self.yearordinal + set[i] = i + return set, i, i+1 + + def htimeset(self, hour, minute, second): + set = [] + rr = self.rrule + for minute in rr._byminute: + for second in rr._bysecond: + set.append(datetime.time(hour, minute, second, + tzinfo=rr._tzinfo)) + set.sort() + return set + + def mtimeset(self, hour, minute, second): + set = [] + rr = self.rrule + for second in rr._bysecond: + set.append(datetime.time(hour, minute, second, tzinfo=rr._tzinfo)) + set.sort() + return set + + def stimeset(self, hour, minute, second): + return (datetime.time(hour, minute, second, + tzinfo=self.rrule._tzinfo),) + + +class rruleset(rrulebase): + + class _genitem(object): + def __init__(self, genlist, gen): + try: + self.dt = advance_iterator(gen) + genlist.append(self) + except StopIteration: + pass + self.genlist = genlist + self.gen = gen + + def __next__(self): + try: + self.dt = advance_iterator(self.gen) + except StopIteration: + self.genlist.remove(self) + + next = __next__ + + def __lt__(self, other): + return self.dt < other.dt + + def __gt__(self, other): + return self.dt > other.dt + + def __eq__(self, other): + return self.dt == other.dt + + def __ne__(self, other): + return self.dt != other.dt + + def __init__(self, cache=False): + super(rruleset, self).__init__(cache) + self._rrule = [] + self._rdate = [] + self._exrule = [] + self._exdate = [] + + def rrule(self, rrule): + self._rrule.append(rrule) + + def rdate(self, rdate): + self._rdate.append(rdate) + + def exrule(self, exrule): + self._exrule.append(exrule) + + def exdate(self, exdate): + self._exdate.append(exdate) + + def _iter(self): + rlist = [] + self._rdate.sort() + self._genitem(rlist, iter(self._rdate)) + for gen in [iter(x) for x in self._rrule]: + self._genitem(rlist, gen) + rlist.sort() + exlist = [] + self._exdate.sort() + self._genitem(exlist, iter(self._exdate)) + for gen in [iter(x) for x in self._exrule]: + self._genitem(exlist, gen) + exlist.sort() + lastdt = None + total = 0 + while rlist: + ritem = rlist[0] + if not lastdt or lastdt != ritem.dt: + while exlist and exlist[0] < ritem: + advance_iterator(exlist[0]) + exlist.sort() + if not exlist or ritem != exlist[0]: + total += 1 + yield ritem.dt + lastdt = ritem.dt + advance_iterator(ritem) + rlist.sort() + self._len = total + +class _rrulestr(object): + + _freq_map = {"YEARLY": YEARLY, + "MONTHLY": MONTHLY, + "WEEKLY": WEEKLY, + "DAILY": DAILY, + "HOURLY": HOURLY, + "MINUTELY": MINUTELY, + "SECONDLY": SECONDLY} + + _weekday_map = {"MO":0,"TU":1,"WE":2,"TH":3,"FR":4,"SA":5,"SU":6} + + def _handle_int(self, rrkwargs, name, value, **kwargs): + rrkwargs[name.lower()] = int(value) + + def _handle_int_list(self, rrkwargs, name, value, **kwargs): + rrkwargs[name.lower()] = [int(x) for x in value.split(',')] + + _handle_INTERVAL = _handle_int + _handle_COUNT = _handle_int + _handle_BYSETPOS = _handle_int_list + _handle_BYMONTH = _handle_int_list + _handle_BYMONTHDAY = _handle_int_list + _handle_BYYEARDAY = _handle_int_list + _handle_BYEASTER = _handle_int_list + _handle_BYWEEKNO = _handle_int_list + _handle_BYHOUR = _handle_int_list + _handle_BYMINUTE = _handle_int_list + _handle_BYSECOND = _handle_int_list + + def _handle_FREQ(self, rrkwargs, name, value, **kwargs): + rrkwargs["freq"] = self._freq_map[value] + + def _handle_UNTIL(self, rrkwargs, name, value, **kwargs): + global parser + if not parser: + from dateutil import parser + try: + rrkwargs["until"] = parser.parse(value, + ignoretz=kwargs.get("ignoretz"), + tzinfos=kwargs.get("tzinfos")) + except ValueError: + raise ValueError("invalid until date") + + def _handle_WKST(self, rrkwargs, name, value, **kwargs): + rrkwargs["wkst"] = self._weekday_map[value] + + def _handle_BYWEEKDAY(self, rrkwargs, name, value, **kwarsg): + l = [] + for wday in value.split(','): + for i in range(len(wday)): + if wday[i] not in '+-0123456789': + break + n = wday[:i] or None + w = wday[i:] + if n: n = int(n) + l.append(weekdays[self._weekday_map[w]](n)) + rrkwargs["byweekday"] = l + + _handle_BYDAY = _handle_BYWEEKDAY + + def _parse_rfc_rrule(self, line, + dtstart=None, + cache=False, + ignoretz=False, + tzinfos=None): + if line.find(':') != -1: + name, value = line.split(':') + if name != "RRULE": + raise ValueError("unknown parameter name") + else: + value = line + rrkwargs = {} + for pair in value.split(';'): + name, value = pair.split('=') + name = name.upper() + value = value.upper() + try: + getattr(self, "_handle_"+name)(rrkwargs, name, value, + ignoretz=ignoretz, + tzinfos=tzinfos) + except AttributeError: + raise ValueError("unknown parameter '%s'" % name) + except (KeyError, ValueError): + raise ValueError("invalid '%s': %s" % (name, value)) + return rrule(dtstart=dtstart, cache=cache, **rrkwargs) + + def _parse_rfc(self, s, + dtstart=None, + cache=False, + unfold=False, + forceset=False, + compatible=False, + ignoretz=False, + tzinfos=None): + global parser + if compatible: + forceset = True + unfold = True + s = s.upper() + if not s.strip(): + raise ValueError("empty string") + if unfold: + lines = s.splitlines() + i = 0 + while i < len(lines): + line = lines[i].rstrip() + if not line: + del lines[i] + elif i > 0 and line[0] == " ": + lines[i-1] += line[1:] + del lines[i] + else: + i += 1 + else: + lines = s.split() + if (not forceset and len(lines) == 1 and + (s.find(':') == -1 or s.startswith('RRULE:'))): + return self._parse_rfc_rrule(lines[0], cache=cache, + dtstart=dtstart, ignoretz=ignoretz, + tzinfos=tzinfos) + else: + rrulevals = [] + rdatevals = [] + exrulevals = [] + exdatevals = [] + for line in lines: + if not line: + continue + if line.find(':') == -1: + name = "RRULE" + value = line + else: + name, value = line.split(':', 1) + parms = name.split(';') + if not parms: + raise ValueError("empty property name") + name = parms[0] + parms = parms[1:] + if name == "RRULE": + for parm in parms: + raise ValueError("unsupported RRULE parm: "+parm) + rrulevals.append(value) + elif name == "RDATE": + for parm in parms: + if parm != "VALUE=DATE-TIME": + raise ValueError("unsupported RDATE parm: "+parm) + rdatevals.append(value) + elif name == "EXRULE": + for parm in parms: + raise ValueError("unsupported EXRULE parm: "+parm) + exrulevals.append(value) + elif name == "EXDATE": + for parm in parms: + if parm != "VALUE=DATE-TIME": + raise ValueError("unsupported RDATE parm: "+parm) + exdatevals.append(value) + elif name == "DTSTART": + for parm in parms: + raise ValueError("unsupported DTSTART parm: "+parm) + if not parser: + from dateutil import parser + dtstart = parser.parse(value, ignoretz=ignoretz, + tzinfos=tzinfos) + else: + raise ValueError("unsupported property: "+name) + if (forceset or len(rrulevals) > 1 or + rdatevals or exrulevals or exdatevals): + if not parser and (rdatevals or exdatevals): + from dateutil import parser + set = rruleset(cache=cache) + for value in rrulevals: + set.rrule(self._parse_rfc_rrule(value, dtstart=dtstart, + ignoretz=ignoretz, + tzinfos=tzinfos)) + for value in rdatevals: + for datestr in value.split(','): + set.rdate(parser.parse(datestr, + ignoretz=ignoretz, + tzinfos=tzinfos)) + for value in exrulevals: + set.exrule(self._parse_rfc_rrule(value, dtstart=dtstart, + ignoretz=ignoretz, + tzinfos=tzinfos)) + for value in exdatevals: + for datestr in value.split(','): + set.exdate(parser.parse(datestr, + ignoretz=ignoretz, + tzinfos=tzinfos)) + if compatible and dtstart: + set.rdate(dtstart) + return set + else: + return self._parse_rfc_rrule(rrulevals[0], + dtstart=dtstart, + cache=cache, + ignoretz=ignoretz, + tzinfos=tzinfos) + + def __call__(self, s, **kwargs): + return self._parse_rfc(s, **kwargs) + +rrulestr = _rrulestr() + +# vim:ts=4:sw=4:et diff -Nru matplotlib-1.1.1/lib/dateutil_py3/tz.py matplotlib-1.2.0/lib/dateutil_py3/tz.py --- matplotlib-1.1.1/lib/dateutil_py3/tz.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py3/tz.py 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,960 @@ +""" +Copyright (c) 2003-2007 Gustavo Niemeyer + +This module offers extensions to the standard Python +datetime module. +""" +__license__ = "Simplified BSD" + +from six import string_types, PY3 + +import datetime +import struct +import time +import sys +import os + +relativedelta = None +parser = None +rrule = None + +__all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange", + "tzstr", "tzical", "tzwin", "tzwinlocal", "gettz"] + +try: + from dateutil.tzwin import tzwin, tzwinlocal +except (ImportError, OSError): + tzwin, tzwinlocal = None, None + +def tzname_in_python2(myfunc): + """Change unicode output into bytestrings in Python 2 + + tzname() API changed in Python 3. It used to return bytes, but was changed + to unicode strings + """ + def inner_func(*args, **kwargs): + if PY3: + return myfunc(*args, **kwargs) + else: + return myfunc(*args, **kwargs).encode() + return inner_func + +ZERO = datetime.timedelta(0) +EPOCHORDINAL = datetime.datetime.utcfromtimestamp(0).toordinal() + +class tzutc(datetime.tzinfo): + + def utcoffset(self, dt): + return ZERO + + def dst(self, dt): + return ZERO + + @tzname_in_python2 + def tzname(self, dt): + return "UTC" + + def __eq__(self, other): + return (isinstance(other, tzutc) or + (isinstance(other, tzoffset) and other._offset == ZERO)) + + def __ne__(self, other): + return not self.__eq__(other) + + def __repr__(self): + return "%s()" % self.__class__.__name__ + + __reduce__ = object.__reduce__ + +class tzoffset(datetime.tzinfo): + + def __init__(self, name, offset): + self._name = name + self._offset = datetime.timedelta(seconds=offset) + + def utcoffset(self, dt): + return self._offset + + def dst(self, dt): + return ZERO + + @tzname_in_python2 + def tzname(self, dt): + return self._name + + def __eq__(self, other): + return (isinstance(other, tzoffset) and + self._offset == other._offset) + + def __ne__(self, other): + return not self.__eq__(other) + + def __repr__(self): + return "%s(%s, %s)" % (self.__class__.__name__, + repr(self._name), + self._offset.days*86400+self._offset.seconds) + + __reduce__ = object.__reduce__ + +class tzlocal(datetime.tzinfo): + + _std_offset = datetime.timedelta(seconds=-time.timezone) + if time.daylight: + _dst_offset = datetime.timedelta(seconds=-time.altzone) + else: + _dst_offset = _std_offset + + def utcoffset(self, dt): + if self._isdst(dt): + return self._dst_offset + else: + return self._std_offset + + def dst(self, dt): + if self._isdst(dt): + return self._dst_offset-self._std_offset + else: + return ZERO + + @tzname_in_python2 + def tzname(self, dt): + return time.tzname[self._isdst(dt)] + + def _isdst(self, dt): + # We can't use mktime here. It is unstable when deciding if + # the hour near to a change is DST or not. + # + # timestamp = time.mktime((dt.year, dt.month, dt.day, dt.hour, + # dt.minute, dt.second, dt.weekday(), 0, -1)) + # return time.localtime(timestamp).tm_isdst + # + # The code above yields the following result: + # + #>>> import tz, datetime + #>>> t = tz.tzlocal() + #>>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname() + #'BRDT' + #>>> datetime.datetime(2003,2,16,0,tzinfo=t).tzname() + #'BRST' + #>>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname() + #'BRST' + #>>> datetime.datetime(2003,2,15,22,tzinfo=t).tzname() + #'BRDT' + #>>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname() + #'BRDT' + # + # Here is a more stable implementation: + # + timestamp = ((dt.toordinal() - EPOCHORDINAL) * 86400 + + dt.hour * 3600 + + dt.minute * 60 + + dt.second) + return time.localtime(timestamp+time.timezone).tm_isdst + + def __eq__(self, other): + if not isinstance(other, tzlocal): + return False + return (self._std_offset == other._std_offset and + self._dst_offset == other._dst_offset) + return True + + def __ne__(self, other): + return not self.__eq__(other) + + def __repr__(self): + return "%s()" % self.__class__.__name__ + + __reduce__ = object.__reduce__ + +class _ttinfo(object): + __slots__ = ["offset", "delta", "isdst", "abbr", "isstd", "isgmt"] + + def __init__(self): + for attr in self.__slots__: + setattr(self, attr, None) + + def __repr__(self): + l = [] + for attr in self.__slots__: + value = getattr(self, attr) + if value is not None: + l.append("%s=%s" % (attr, repr(value))) + return "%s(%s)" % (self.__class__.__name__, ", ".join(l)) + + def __eq__(self, other): + if not isinstance(other, _ttinfo): + return False + return (self.offset == other.offset and + self.delta == other.delta and + self.isdst == other.isdst and + self.abbr == other.abbr and + self.isstd == other.isstd and + self.isgmt == other.isgmt) + + def __ne__(self, other): + return not self.__eq__(other) + + def __getstate__(self): + state = {} + for name in self.__slots__: + state[name] = getattr(self, name, None) + return state + + def __setstate__(self, state): + for name in self.__slots__: + if name in state: + setattr(self, name, state[name]) + +class tzfile(datetime.tzinfo): + + # http://www.twinsun.com/tz/tz-link.htm + # ftp://ftp.iana.org/tz/tz*.tar.gz + + def __init__(self, fileobj): + if isinstance(fileobj, string_types): + self._filename = fileobj + fileobj = open(fileobj, 'rb') + elif hasattr(fileobj, "name"): + self._filename = fileobj.name + else: + self._filename = repr(fileobj) + + # From tzfile(5): + # + # The time zone information files used by tzset(3) + # begin with the magic characters "TZif" to identify + # them as time zone information files, followed by + # sixteen bytes reserved for future use, followed by + # six four-byte values of type long, written in a + # ``standard'' byte order (the high-order byte + # of the value is written first). + + if fileobj.read(4).decode() != "TZif": + raise ValueError("magic not found") + + fileobj.read(16) + + ( + # The number of UTC/local indicators stored in the file. + ttisgmtcnt, + + # The number of standard/wall indicators stored in the file. + ttisstdcnt, + + # The number of leap seconds for which data is + # stored in the file. + leapcnt, + + # The number of "transition times" for which data + # is stored in the file. + timecnt, + + # The number of "local time types" for which data + # is stored in the file (must not be zero). + typecnt, + + # The number of characters of "time zone + # abbreviation strings" stored in the file. + charcnt, + + ) = struct.unpack(">6l", fileobj.read(24)) + + # The above header is followed by tzh_timecnt four-byte + # values of type long, sorted in ascending order. + # These values are written in ``standard'' byte order. + # Each is used as a transition time (as returned by + # time(2)) at which the rules for computing local time + # change. + + if timecnt: + self._trans_list = struct.unpack(">%dl" % timecnt, + fileobj.read(timecnt*4)) + else: + self._trans_list = [] + + # Next come tzh_timecnt one-byte values of type unsigned + # char; each one tells which of the different types of + # ``local time'' types described in the file is associated + # with the same-indexed transition time. These values + # serve as indices into an array of ttinfo structures that + # appears next in the file. + + if timecnt: + self._trans_idx = struct.unpack(">%dB" % timecnt, + fileobj.read(timecnt)) + else: + self._trans_idx = [] + + # Each ttinfo structure is written as a four-byte value + # for tt_gmtoff of type long, in a standard byte + # order, followed by a one-byte value for tt_isdst + # and a one-byte value for tt_abbrind. In each + # structure, tt_gmtoff gives the number of + # seconds to be added to UTC, tt_isdst tells whether + # tm_isdst should be set by localtime(3), and + # tt_abbrind serves as an index into the array of + # time zone abbreviation characters that follow the + # ttinfo structure(s) in the file. + + ttinfo = [] + + for i in range(typecnt): + ttinfo.append(struct.unpack(">lbb", fileobj.read(6))) + + abbr = fileobj.read(charcnt).decode() + + # Then there are tzh_leapcnt pairs of four-byte + # values, written in standard byte order; the + # first value of each pair gives the time (as + # returned by time(2)) at which a leap second + # occurs; the second gives the total number of + # leap seconds to be applied after the given time. + # The pairs of values are sorted in ascending order + # by time. + + # Not used, for now + if leapcnt: + leap = struct.unpack(">%dl" % (leapcnt*2), + fileobj.read(leapcnt*8)) + + # Then there are tzh_ttisstdcnt standard/wall + # indicators, each stored as a one-byte value; + # they tell whether the transition times associated + # with local time types were specified as standard + # time or wall clock time, and are used when + # a time zone file is used in handling POSIX-style + # time zone environment variables. + + if ttisstdcnt: + isstd = struct.unpack(">%db" % ttisstdcnt, + fileobj.read(ttisstdcnt)) + + # Finally, there are tzh_ttisgmtcnt UTC/local + # indicators, each stored as a one-byte value; + # they tell whether the transition times associated + # with local time types were specified as UTC or + # local time, and are used when a time zone file + # is used in handling POSIX-style time zone envi- + # ronment variables. + + if ttisgmtcnt: + isgmt = struct.unpack(">%db" % ttisgmtcnt, + fileobj.read(ttisgmtcnt)) + + # ** Everything has been read ** + + # Build ttinfo list + self._ttinfo_list = [] + for i in range(typecnt): + gmtoff, isdst, abbrind = ttinfo[i] + # Round to full-minutes if that's not the case. Python's + # datetime doesn't accept sub-minute timezones. Check + # http://python.org/sf/1447945 for some information. + gmtoff = (gmtoff+30)//60*60 + tti = _ttinfo() + tti.offset = gmtoff + tti.delta = datetime.timedelta(seconds=gmtoff) + tti.isdst = isdst + tti.abbr = abbr[abbrind:abbr.find('\x00', abbrind)] + tti.isstd = (ttisstdcnt > i and isstd[i] != 0) + tti.isgmt = (ttisgmtcnt > i and isgmt[i] != 0) + self._ttinfo_list.append(tti) + + # Replace ttinfo indexes for ttinfo objects. + trans_idx = [] + for idx in self._trans_idx: + trans_idx.append(self._ttinfo_list[idx]) + self._trans_idx = tuple(trans_idx) + + # Set standard, dst, and before ttinfos. before will be + # used when a given time is before any transitions, + # and will be set to the first non-dst ttinfo, or to + # the first dst, if all of them are dst. + self._ttinfo_std = None + self._ttinfo_dst = None + self._ttinfo_before = None + if self._ttinfo_list: + if not self._trans_list: + self._ttinfo_std = self._ttinfo_first = self._ttinfo_list[0] + else: + for i in range(timecnt-1, -1, -1): + tti = self._trans_idx[i] + if not self._ttinfo_std and not tti.isdst: + self._ttinfo_std = tti + elif not self._ttinfo_dst and tti.isdst: + self._ttinfo_dst = tti + if self._ttinfo_std and self._ttinfo_dst: + break + else: + if self._ttinfo_dst and not self._ttinfo_std: + self._ttinfo_std = self._ttinfo_dst + + for tti in self._ttinfo_list: + if not tti.isdst: + self._ttinfo_before = tti + break + else: + self._ttinfo_before = self._ttinfo_list[0] + + # Now fix transition times to become relative to wall time. + # + # I'm not sure about this. In my tests, the tz source file + # is setup to wall time, and in the binary file isstd and + # isgmt are off, so it should be in wall time. OTOH, it's + # always in gmt time. Let me know if you have comments + # about this. + laststdoffset = 0 + self._trans_list = list(self._trans_list) + for i in range(len(self._trans_list)): + tti = self._trans_idx[i] + if not tti.isdst: + # This is std time. + self._trans_list[i] += tti.offset + laststdoffset = tti.offset + else: + # This is dst time. Convert to std. + self._trans_list[i] += laststdoffset + self._trans_list = tuple(self._trans_list) + + def _find_ttinfo(self, dt, laststd=0): + timestamp = ((dt.toordinal() - EPOCHORDINAL) * 86400 + + dt.hour * 3600 + + dt.minute * 60 + + dt.second) + idx = 0 + for trans in self._trans_list: + if timestamp < trans: + break + idx += 1 + else: + return self._ttinfo_std + if idx == 0: + return self._ttinfo_before + if laststd: + while idx > 0: + tti = self._trans_idx[idx-1] + if not tti.isdst: + return tti + idx -= 1 + else: + return self._ttinfo_std + else: + return self._trans_idx[idx-1] + + def utcoffset(self, dt): + if not self._ttinfo_std: + return ZERO + return self._find_ttinfo(dt).delta + + def dst(self, dt): + if not self._ttinfo_dst: + return ZERO + tti = self._find_ttinfo(dt) + if not tti.isdst: + return ZERO + + # The documentation says that utcoffset()-dst() must + # be constant for every dt. + return tti.delta-self._find_ttinfo(dt, laststd=1).delta + + # An alternative for that would be: + # + # return self._ttinfo_dst.offset-self._ttinfo_std.offset + # + # However, this class stores historical changes in the + # dst offset, so I belive that this wouldn't be the right + # way to implement this. + + @tzname_in_python2 + def tzname(self, dt): + if not self._ttinfo_std: + return None + return self._find_ttinfo(dt).abbr + + def __eq__(self, other): + if not isinstance(other, tzfile): + return False + return (self._trans_list == other._trans_list and + self._trans_idx == other._trans_idx and + self._ttinfo_list == other._ttinfo_list) + + def __ne__(self, other): + return not self.__eq__(other) + + + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__, repr(self._filename)) + + def __reduce__(self): + if not os.path.isfile(self._filename): + raise ValueError("Unpickable %s class" % self.__class__.__name__) + return (self.__class__, (self._filename,)) + +class tzrange(datetime.tzinfo): + + def __init__(self, stdabbr, stdoffset=None, + dstabbr=None, dstoffset=None, + start=None, end=None): + global relativedelta + if not relativedelta: + from dateutil import relativedelta + self._std_abbr = stdabbr + self._dst_abbr = dstabbr + if stdoffset is not None: + self._std_offset = datetime.timedelta(seconds=stdoffset) + else: + self._std_offset = ZERO + if dstoffset is not None: + self._dst_offset = datetime.timedelta(seconds=dstoffset) + elif dstabbr and stdoffset is not None: + self._dst_offset = self._std_offset+datetime.timedelta(hours=+1) + else: + self._dst_offset = ZERO + if dstabbr and start is None: + self._start_delta = relativedelta.relativedelta( + hours=+2, month=4, day=1, weekday=relativedelta.SU(+1)) + else: + self._start_delta = start + if dstabbr and end is None: + self._end_delta = relativedelta.relativedelta( + hours=+1, month=10, day=31, weekday=relativedelta.SU(-1)) + else: + self._end_delta = end + + def utcoffset(self, dt): + if self._isdst(dt): + return self._dst_offset + else: + return self._std_offset + + def dst(self, dt): + if self._isdst(dt): + return self._dst_offset-self._std_offset + else: + return ZERO + + @tzname_in_python2 + def tzname(self, dt): + if self._isdst(dt): + return self._dst_abbr + else: + return self._std_abbr + + def _isdst(self, dt): + if not self._start_delta: + return False + year = datetime.datetime(dt.year, 1, 1) + start = year+self._start_delta + end = year+self._end_delta + dt = dt.replace(tzinfo=None) + if start < end: + return dt >= start and dt < end + else: + return dt >= start or dt < end + + def __eq__(self, other): + if not isinstance(other, tzrange): + return False + return (self._std_abbr == other._std_abbr and + self._dst_abbr == other._dst_abbr and + self._std_offset == other._std_offset and + self._dst_offset == other._dst_offset and + self._start_delta == other._start_delta and + self._end_delta == other._end_delta) + + def __ne__(self, other): + return not self.__eq__(other) + + def __repr__(self): + return "%s(...)" % self.__class__.__name__ + + __reduce__ = object.__reduce__ + +class tzstr(tzrange): + + def __init__(self, s): + global parser + if not parser: + from dateutil import parser + self._s = s + + res = parser._parsetz(s) + if res is None: + raise ValueError("unknown string format") + + # Here we break the compatibility with the TZ variable handling. + # GMT-3 actually *means* the timezone -3. + if res.stdabbr in ("GMT", "UTC"): + res.stdoffset *= -1 + + # We must initialize it first, since _delta() needs + # _std_offset and _dst_offset set. Use False in start/end + # to avoid building it two times. + tzrange.__init__(self, res.stdabbr, res.stdoffset, + res.dstabbr, res.dstoffset, + start=False, end=False) + + if not res.dstabbr: + self._start_delta = None + self._end_delta = None + else: + self._start_delta = self._delta(res.start) + if self._start_delta: + self._end_delta = self._delta(res.end, isend=1) + + def _delta(self, x, isend=0): + kwargs = {} + if x.month is not None: + kwargs["month"] = x.month + if x.weekday is not None: + kwargs["weekday"] = relativedelta.weekday(x.weekday, x.week) + if x.week > 0: + kwargs["day"] = 1 + else: + kwargs["day"] = 31 + elif x.day: + kwargs["day"] = x.day + elif x.yday is not None: + kwargs["yearday"] = x.yday + elif x.jyday is not None: + kwargs["nlyearday"] = x.jyday + if not kwargs: + # Default is to start on first sunday of april, and end + # on last sunday of october. + if not isend: + kwargs["month"] = 4 + kwargs["day"] = 1 + kwargs["weekday"] = relativedelta.SU(+1) + else: + kwargs["month"] = 10 + kwargs["day"] = 31 + kwargs["weekday"] = relativedelta.SU(-1) + if x.time is not None: + kwargs["seconds"] = x.time + else: + # Default is 2AM. + kwargs["seconds"] = 7200 + if isend: + # Convert to standard time, to follow the documented way + # of working with the extra hour. See the documentation + # of the tzinfo class. + delta = self._dst_offset-self._std_offset + kwargs["seconds"] -= delta.seconds+delta.days*86400 + return relativedelta.relativedelta(**kwargs) + + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__, repr(self._s)) + +class _tzicalvtzcomp(object): + def __init__(self, tzoffsetfrom, tzoffsetto, isdst, + tzname=None, rrule=None): + self.tzoffsetfrom = datetime.timedelta(seconds=tzoffsetfrom) + self.tzoffsetto = datetime.timedelta(seconds=tzoffsetto) + self.tzoffsetdiff = self.tzoffsetto-self.tzoffsetfrom + self.isdst = isdst + self.tzname = tzname + self.rrule = rrule + +class _tzicalvtz(datetime.tzinfo): + def __init__(self, tzid, comps=[]): + self._tzid = tzid + self._comps = comps + self._cachedate = [] + self._cachecomp = [] + + def _find_comp(self, dt): + if len(self._comps) == 1: + return self._comps[0] + dt = dt.replace(tzinfo=None) + try: + return self._cachecomp[self._cachedate.index(dt)] + except ValueError: + pass + lastcomp = None + lastcompdt = None + for comp in self._comps: + if not comp.isdst: + # Handle the extra hour in DST -> STD + compdt = comp.rrule.before(dt-comp.tzoffsetdiff, inc=True) + else: + compdt = comp.rrule.before(dt, inc=True) + if compdt and (not lastcompdt or lastcompdt < compdt): + lastcompdt = compdt + lastcomp = comp + if not lastcomp: + # RFC says nothing about what to do when a given + # time is before the first onset date. We'll look for the + # first standard component, or the first component, if + # none is found. + for comp in self._comps: + if not comp.isdst: + lastcomp = comp + break + else: + lastcomp = comp[0] + self._cachedate.insert(0, dt) + self._cachecomp.insert(0, lastcomp) + if len(self._cachedate) > 10: + self._cachedate.pop() + self._cachecomp.pop() + return lastcomp + + def utcoffset(self, dt): + return self._find_comp(dt).tzoffsetto + + def dst(self, dt): + comp = self._find_comp(dt) + if comp.isdst: + return comp.tzoffsetdiff + else: + return ZERO + + @tzname_in_python2 + def tzname(self, dt): + return self._find_comp(dt).tzname + + def __repr__(self): + return "" % repr(self._tzid) + + __reduce__ = object.__reduce__ + +class tzical(object): + def __init__(self, fileobj): + global rrule + if not rrule: + from dateutil import rrule + + if isinstance(fileobj, string_types): + self._s = fileobj + fileobj = open(fileobj, 'r') # ical should be encoded in UTF-8 with CRLF + elif hasattr(fileobj, "name"): + self._s = fileobj.name + else: + self._s = repr(fileobj) + + self._vtz = {} + + self._parse_rfc(fileobj.read()) + + def keys(self): + return list(self._vtz.keys()) + + def get(self, tzid=None): + if tzid is None: + keys = list(self._vtz.keys()) + if len(keys) == 0: + raise ValueError("no timezones defined") + elif len(keys) > 1: + raise ValueError("more than one timezone available") + tzid = keys[0] + return self._vtz.get(tzid) + + def _parse_offset(self, s): + s = s.strip() + if not s: + raise ValueError("empty offset") + if s[0] in ('+', '-'): + signal = (-1, +1)[s[0]=='+'] + s = s[1:] + else: + signal = +1 + if len(s) == 4: + return (int(s[:2])*3600+int(s[2:])*60)*signal + elif len(s) == 6: + return (int(s[:2])*3600+int(s[2:4])*60+int(s[4:]))*signal + else: + raise ValueError("invalid offset: "+s) + + def _parse_rfc(self, s): + lines = s.splitlines() + if not lines: + raise ValueError("empty string") + + # Unfold + i = 0 + while i < len(lines): + line = lines[i].rstrip() + if not line: + del lines[i] + elif i > 0 and line[0] == " ": + lines[i-1] += line[1:] + del lines[i] + else: + i += 1 + + tzid = None + comps = [] + invtz = False + comptype = None + for line in lines: + if not line: + continue + name, value = line.split(':', 1) + parms = name.split(';') + if not parms: + raise ValueError("empty property name") + name = parms[0].upper() + parms = parms[1:] + if invtz: + if name == "BEGIN": + if value in ("STANDARD", "DAYLIGHT"): + # Process component + pass + else: + raise ValueError("unknown component: "+value) + comptype = value + founddtstart = False + tzoffsetfrom = None + tzoffsetto = None + rrulelines = [] + tzname = None + elif name == "END": + if value == "VTIMEZONE": + if comptype: + raise ValueError("component not closed: "+comptype) + if not tzid: + raise ValueError("mandatory TZID not found") + if not comps: + raise ValueError("at least one component is needed") + # Process vtimezone + self._vtz[tzid] = _tzicalvtz(tzid, comps) + invtz = False + elif value == comptype: + if not founddtstart: + raise ValueError("mandatory DTSTART not found") + if tzoffsetfrom is None: + raise ValueError("mandatory TZOFFSETFROM not found") + if tzoffsetto is None: + raise ValueError("mandatory TZOFFSETFROM not found") + # Process component + rr = None + if rrulelines: + rr = rrule.rrulestr("\n".join(rrulelines), + compatible=True, + ignoretz=True, + cache=True) + comp = _tzicalvtzcomp(tzoffsetfrom, tzoffsetto, + (comptype == "DAYLIGHT"), + tzname, rr) + comps.append(comp) + comptype = None + else: + raise ValueError("invalid component end: "+value) + elif comptype: + if name == "DTSTART": + rrulelines.append(line) + founddtstart = True + elif name in ("RRULE", "RDATE", "EXRULE", "EXDATE"): + rrulelines.append(line) + elif name == "TZOFFSETFROM": + if parms: + raise ValueError("unsupported %s parm: %s "%(name, parms[0])) + tzoffsetfrom = self._parse_offset(value) + elif name == "TZOFFSETTO": + if parms: + raise ValueError("unsupported TZOFFSETTO parm: "+parms[0]) + tzoffsetto = self._parse_offset(value) + elif name == "TZNAME": + if parms: + raise ValueError("unsupported TZNAME parm: "+parms[0]) + tzname = value + elif name == "COMMENT": + pass + else: + raise ValueError("unsupported property: "+name) + else: + if name == "TZID": + if parms: + raise ValueError("unsupported TZID parm: "+parms[0]) + tzid = value + elif name in ("TZURL", "LAST-MODIFIED", "COMMENT"): + pass + else: + raise ValueError("unsupported property: "+name) + elif name == "BEGIN" and value == "VTIMEZONE": + tzid = None + comps = [] + invtz = True + + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__, repr(self._s)) + +if sys.platform != "win32": + TZFILES = ["/etc/localtime", "localtime"] + TZPATHS = ["/usr/share/zoneinfo", "/usr/lib/zoneinfo", "/etc/zoneinfo"] +else: + TZFILES = [] + TZPATHS = [] + +def gettz(name=None): + tz = None + if not name: + try: + name = os.environ["TZ"] + except KeyError: + pass + if name is None or name == ":": + for filepath in TZFILES: + if not os.path.isabs(filepath): + filename = filepath + for path in TZPATHS: + filepath = os.path.join(path, filename) + if os.path.isfile(filepath): + break + else: + continue + if os.path.isfile(filepath): + try: + tz = tzfile(filepath) + break + except (IOError, OSError, ValueError): + pass + else: + tz = tzlocal() + else: + if name.startswith(":"): + name = name[:-1] + if os.path.isabs(name): + if os.path.isfile(name): + tz = tzfile(name) + else: + tz = None + else: + for path in TZPATHS: + filepath = os.path.join(path, name) + if not os.path.isfile(filepath): + filepath = filepath.replace(' ', '_') + if not os.path.isfile(filepath): + continue + try: + tz = tzfile(filepath) + break + except (IOError, OSError, ValueError): + pass + else: + tz = None + if tzwin: + try: + tz = tzwin(name) + except OSError: + pass + if not tz: + from dateutil.zoneinfo import gettz + tz = gettz(name) + if not tz: + for c in name: + # name must have at least one offset to be a tzstr + if c in "0123456789": + try: + tz = tzstr(name) + except ValueError: + pass + break + else: + if name in ("GMT", "UTC"): + tz = tzutc() + elif name in time.tzname: + tz = tzlocal() + return tz + +# vim:ts=4:sw=4:et diff -Nru matplotlib-1.1.1/lib/dateutil_py3/tzwin.py matplotlib-1.2.0/lib/dateutil_py3/tzwin.py --- matplotlib-1.1.1/lib/dateutil_py3/tzwin.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py3/tzwin.py 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,179 @@ +# This code was originally contributed by Jeffrey Harris. +import datetime +import struct +import winreg + + +__all__ = ["tzwin", "tzwinlocal"] + +ONEWEEK = datetime.timedelta(7) + +TZKEYNAMENT = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones" +TZKEYNAME9X = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones" +TZLOCALKEYNAME = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation" + +def _settzkeyname(): + global TZKEYNAME + handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) + try: + winreg.OpenKey(handle, TZKEYNAMENT).Close() + TZKEYNAME = TZKEYNAMENT + except WindowsError: + TZKEYNAME = TZKEYNAME9X + handle.Close() + +_settzkeyname() + +class tzwinbase(datetime.tzinfo): + """tzinfo class based on win32's timezones available in the registry.""" + + def utcoffset(self, dt): + if self._isdst(dt): + return datetime.timedelta(minutes=self._dstoffset) + else: + return datetime.timedelta(minutes=self._stdoffset) + + def dst(self, dt): + if self._isdst(dt): + minutes = self._dstoffset - self._stdoffset + return datetime.timedelta(minutes=minutes) + else: + return datetime.timedelta(0) + + def tzname(self, dt): + if self._isdst(dt): + return self._dstname + else: + return self._stdname + + def list(): + """Return a list of all time zones known to the system.""" + handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) + tzkey = winreg.OpenKey(handle, TZKEYNAME) + result = [winreg.EnumKey(tzkey, i) + for i in range(winreg.QueryInfoKey(tzkey)[0])] + tzkey.Close() + handle.Close() + return result + list = staticmethod(list) + + def display(self): + return self._display + + def _isdst(self, dt): + dston = picknthweekday(dt.year, self._dstmonth, self._dstdayofweek, + self._dsthour, self._dstminute, + self._dstweeknumber) + dstoff = picknthweekday(dt.year, self._stdmonth, self._stddayofweek, + self._stdhour, self._stdminute, + self._stdweeknumber) + if dston < dstoff: + return dston <= dt.replace(tzinfo=None) < dstoff + else: + return not dstoff <= dt.replace(tzinfo=None) < dston + + +class tzwin(tzwinbase): + + def __init__(self, name): + self._name = name + + handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) + tzkey = winreg.OpenKey(handle, "%s\%s" % (TZKEYNAME, name)) + keydict = valuestodict(tzkey) + tzkey.Close() + handle.Close() + + self._stdname = keydict["Std"].encode("iso-8859-1") + self._dstname = keydict["Dlt"].encode("iso-8859-1") + + self._display = keydict["Display"] + + # See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm + tup = struct.unpack("=3l16h", keydict["TZI"]) + self._stdoffset = -tup[0]-tup[1] # Bias + StandardBias * -1 + self._dstoffset = self._stdoffset-tup[2] # + DaylightBias * -1 + + (self._stdmonth, + self._stddayofweek, # Sunday = 0 + self._stdweeknumber, # Last = 5 + self._stdhour, + self._stdminute) = tup[4:9] + + (self._dstmonth, + self._dstdayofweek, # Sunday = 0 + self._dstweeknumber, # Last = 5 + self._dsthour, + self._dstminute) = tup[12:17] + + def __repr__(self): + return "tzwin(%s)" % repr(self._name) + + def __reduce__(self): + return (self.__class__, (self._name,)) + + +class tzwinlocal(tzwinbase): + + def __init__(self): + + handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) + + tzlocalkey = winreg.OpenKey(handle, TZLOCALKEYNAME) + keydict = valuestodict(tzlocalkey) + tzlocalkey.Close() + + self._stdname = keydict["StandardName"].encode("iso-8859-1") + self._dstname = keydict["DaylightName"].encode("iso-8859-1") + + try: + tzkey = winreg.OpenKey(handle, "%s\%s"%(TZKEYNAME, self._stdname)) + _keydict = valuestodict(tzkey) + self._display = _keydict["Display"] + tzkey.Close() + except OSError: + self._display = None + + handle.Close() + + self._stdoffset = -keydict["Bias"]-keydict["StandardBias"] + self._dstoffset = self._stdoffset-keydict["DaylightBias"] + + + # See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm + tup = struct.unpack("=8h", keydict["StandardStart"]) + + (self._stdmonth, + self._stddayofweek, # Sunday = 0 + self._stdweeknumber, # Last = 5 + self._stdhour, + self._stdminute) = tup[1:6] + + tup = struct.unpack("=8h", keydict["DaylightStart"]) + + (self._dstmonth, + self._dstdayofweek, # Sunday = 0 + self._dstweeknumber, # Last = 5 + self._dsthour, + self._dstminute) = tup[1:6] + + def __reduce__(self): + return (self.__class__, ()) + +def picknthweekday(year, month, dayofweek, hour, minute, whichweek): + """dayofweek == 0 means Sunday, whichweek 5 means last instance""" + first = datetime.datetime(year, month, 1, hour, minute) + weekdayone = first.replace(day=((dayofweek-first.isoweekday())%7+1)) + for n in range(whichweek): + dt = weekdayone+(whichweek-n)*ONEWEEK + if dt.month == month: + return dt + +def valuestodict(key): + """Convert a registry key's values to a dictionary.""" + dict = {} + size = winreg.QueryInfoKey(key)[1] + for i in range(size): + data = winreg.EnumValue(key, i) + dict[data[0]] = data[1] + return dict diff -Nru matplotlib-1.1.1/lib/dateutil_py3/zoneinfo/__init__.py matplotlib-1.2.0/lib/dateutil_py3/zoneinfo/__init__.py --- matplotlib-1.1.1/lib/dateutil_py3/zoneinfo/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/dateutil_py3/zoneinfo/__init__.py 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +""" +Copyright (c) 2003-2005 Gustavo Niemeyer + +This module offers extensions to the standard Python +datetime module. +""" +from dateutil.tz import tzfile +from tarfile import TarFile +import os + +__author__ = "Tomi Pieviläinen " +__license__ = "Simplified BSD" + +__all__ = ["setcachesize", "gettz", "rebuild"] + +CACHE = [] +CACHESIZE = 10 + +class tzfile(tzfile): + def __reduce__(self): + return (gettz, (self._filename,)) + +def getzoneinfofile(): + filenames = sorted(os.listdir(os.path.join(os.path.dirname(__file__)))) + filenames.reverse() + for entry in filenames: + if entry.startswith("zoneinfo") and ".tar." in entry: + return os.path.join(os.path.dirname(__file__), entry) + return None + +ZONEINFOFILE = getzoneinfofile() + +del getzoneinfofile + +def setcachesize(size): + global CACHESIZE, CACHE + CACHESIZE = size + del CACHE[size:] + +def gettz(name): + tzinfo = None + if ZONEINFOFILE: + for cachedname, tzinfo in CACHE: + if cachedname == name: + break + else: + tf = TarFile.open(ZONEINFOFILE) + try: + zonefile = tf.extractfile(name) + except KeyError: + tzinfo = None + else: + tzinfo = tzfile(zonefile) + tf.close() + CACHE.insert(0, (name, tzinfo)) + del CACHE[CACHESIZE:] + return tzinfo + +def rebuild(filename, tag=None, format="gz"): + import tempfile, shutil + tmpdir = tempfile.mkdtemp() + zonedir = os.path.join(tmpdir, "zoneinfo") + moduledir = os.path.dirname(__file__) + if tag: tag = "-"+tag + targetname = "zoneinfo%s.tar.%s" % (tag, format) + try: + tf = TarFile.open(filename) + # The "backwards" zone file contains links to other files, so must be + # processed as last + for name in sorted(tf.getnames(), + key=lambda k: k != "backward" and k or "z"): + if not (name.endswith(".sh") or + name.endswith(".tab") or + name == "leapseconds"): + tf.extract(name, tmpdir) + filepath = os.path.join(tmpdir, name) + os.system("zic -d %s %s" % (zonedir, filepath)) + tf.close() + target = os.path.join(moduledir, targetname) + for entry in os.listdir(moduledir): + if entry.startswith("zoneinfo") and ".tar." in entry: + os.unlink(os.path.join(moduledir, entry)) + tf = TarFile.open(target, "w:%s" % format) + for entry in os.listdir(zonedir): + entrypath = os.path.join(zonedir, entry) + tf.add(entrypath, entry) + tf.close() + finally: + shutil.rmtree(tmpdir) Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/dateutil_py3/zoneinfo/zoneinfo--latest.tar.gz and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/dateutil_py3/zoneinfo/zoneinfo--latest.tar.gz differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/dateutil_py3/zoneinfo/zoneinfo-2011d.tar.gz and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/dateutil_py3/zoneinfo/zoneinfo-2011d.tar.gz differ diff -Nru matplotlib-1.1.1/lib/matplotlib/__init__.py matplotlib-1.2.0/lib/matplotlib/__init__.py --- matplotlib-1.1.1/lib/matplotlib/__init__.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/__init__.py 2012-11-08 16:38:17.000000000 +0000 @@ -1,5 +1,5 @@ """ -This is an object-orient plotting library. +This is an object-oriented plotting library. A procedural interface is provided by the companion pyplot module, which may be imported directly, e.g:: @@ -90,22 +90,28 @@ for the first time. In particular, it must be called **before** importing pylab (if pylab is imported). -matplotlib was initially written by John D. Hunter (jdh2358 at -gmail.com) and is now developed and maintained by a host of others. +matplotlib was initially written by John D. Hunter (1968-2012) and is now +developed and maintained by a host of others. Occasionally the internal documentation (python docstrings) will refer to MATLAB®, a registered trademark of The MathWorks, Inc. """ -from __future__ import generators +from __future__ import print_function -__version__ = '1.1.1' +__version__ = '1.2.0' __version__numpy__ = '1.4' # minimum required numpy version import os, re, shutil, subprocess, sys, warnings import distutils.sysconfig import distutils.version +try: + reload +except NameError: + # Python 3 + from imp import reload + # Needed for toolkit setuptools support if 0: try: @@ -131,13 +137,23 @@ import sys, os, tempfile +if sys.version_info[0] >= 3: + def ascii(s): return bytes(s, 'ascii') + + def byte2str(b): return b.decode('ascii') + +else: + ascii = str + + def byte2str(b): return b + + from matplotlib.rcsetup import (defaultParams, validate_backend, - validate_toolbar, - validate_cairo_format) + validate_toolbar) major, minor1, minor2, s, tmp = sys.version_info -_python24 = major>=2 and minor1>=4 +_python24 = (major == 2 and minor1 >= 4) or major >= 3 # the havedate check was a legacy from old matplotlib which preceeded # datetime support @@ -162,7 +178,6 @@ __version__numpy__, numpy.__version__)) del version - def is_string_like(obj): if hasattr(obj, 'shape'): return 0 try: obj + '' @@ -179,8 +194,10 @@ except TypeError: return False try: t = tempfile.TemporaryFile(dir=p) - t.write('1') - t.close() + try: + t.write(ascii('1')) + finally: + t.close() except OSError: return False else: return True @@ -197,8 +214,14 @@ _commandLineVerbose = None for arg in sys.argv[1:]: - if not arg.startswith('--verbose-'): continue - _commandLineVerbose = arg[10:] + if not arg.startswith('--verbose-'): + continue + level_str = arg[10:] + # If it doesn't match one of ours, then don't even + # bother noting it, we are just a 3rd-party library + # to somebody else's script. + if level_str in levels: + _commandLineVerbose = level_str def __init__(self): self.set_level('silent') @@ -210,8 +233,10 @@ if self._commandLineVerbose is not None: level = self._commandLineVerbose if level not in self.levels: - raise ValueError('Illegal verbose string "%s". Legal values are %s'%(level, self.levels)) - self.level = level + warnings.warn('matplotlib: unrecognized --verbose-* string "%s".' + ' Legal values are %s' % (level, self.levels)) + else: + self.level = level def set_fileo(self, fname): std = { @@ -222,7 +247,7 @@ self.fileo = std[fname] else: try: - fileo = file(fname, 'w') + fileo = open(fname, 'w') except IOError: raise ValueError('Verbose object could not open log file "%s" for writing.\nCheck your matplotlibrc verbose.fileo setting'%fname) else: @@ -235,7 +260,7 @@ """ if self.ge(level): - print >>self.fileo, s + print(s, file=self.fileo) return True return False @@ -268,12 +293,13 @@ verbose=Verbose() + def checkdep_dvipng(): try: s = subprocess.Popen(['dvipng','-version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) line = s.stdout.readlines()[1] - v = line.split()[-1] + v = byte2str(line.split()[-1]) return v except (IndexError, ValueError, OSError): return None @@ -286,7 +312,7 @@ command_args = ['gs', '--version'] s = subprocess.Popen(command_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - v = s.stdout.read()[:-1] + v = byte2str(s.stdout.read()[:-1]) return v except (IndexError, ValueError, OSError): return None @@ -295,7 +321,7 @@ try: s = subprocess.Popen(['tex','-version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - line = s.stdout.readlines()[0] + line = byte2str(s.stdout.readlines()[0]) pattern = '3\.1\d+' match = re.search(pattern, line) v = match.group(0) @@ -308,8 +334,8 @@ s = subprocess.Popen(['pdftops','-v'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) for line in s.stderr: - if 'version' in line: - v = line.split()[-1] + if b'version' in line: + v = byte2str(line.split()[-1]) return v except (IndexError, ValueError, UnboundLocalError, OSError): return None @@ -319,8 +345,8 @@ s = subprocess.Popen(['inkscape','-V'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) for line in s.stdout: - if 'Inkscape' in line: - v = line.split()[1] + if b'Inkscape' in line: + v = byte2str(line.split()[1]) break return v except (IndexError, ValueError, UnboundLocalError, OSError): @@ -331,8 +357,8 @@ s = subprocess.Popen(['xmllint','--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) for line in s.stderr: - if 'version' in line: - v = line.split()[-1] + if b'version' in line: + v = byte2str(line.split()[-1]) break return v except (IndexError, ValueError, UnboundLocalError, OSError): @@ -448,15 +474,33 @@ raise RuntimeError('please define environment variable $HOME') +def _create_tmp_config_dir(): + """ + If the config directory can not be created, create a temporary + directory. + """ + import getpass + import tempfile + + tempdir = os.path.join( + tempfile.gettempdir(), 'matplotlib-%s' % getpass.getuser()) + os.environ['MPLCONFIGDIR'] = tempdir + + return tempdir + get_home = verbose.wrap('$HOME=%s', _get_home, always=False) def _get_configdir(): """ - Return the string representing the configuration dir. + Return the string representing the configuration directory. - default is HOME/.matplotlib. you can override this with the - MPLCONFIGDIR environment variable + Default is HOME/.matplotlib. You can override this with the + MPLCONFIGDIR environment variable. If the default is not + writable, and MPLCONFIGDIR is not set, then + tempfile.gettempdir() is used to provide a directory in + which a matplotlib subdirectory is created as the configuration + directory. """ configdir = os.environ.get('MPLCONFIGDIR') @@ -464,7 +508,7 @@ if not os.path.exists(configdir): os.makedirs(configdir) if not _is_writable_dir(configdir): - raise RuntimeError('Could not write to MPLCONFIGDIR="%s"'%configdir) + return _create_tmp_config_dir() return configdir h = get_home() @@ -472,12 +516,12 @@ if os.path.exists(p): if not _is_writable_dir(p): - raise RuntimeError("'%s' is not a writable dir; you must set %s/.matplotlib to be a writable dir. You can also set environment variable MPLCONFIGDIR to any writable directory where you want matplotlib data stored "% (h, h)) + return _create_tmp_config_dir() else: if not _is_writable_dir(h): - raise RuntimeError("Failed to create %s/.matplotlib; consider setting MPLCONFIGDIR to a writable directory for matplotlib configuration data"%h) - - os.mkdir(p) + return _create_tmp_config_dir() + from matplotlib.cbook import mkdirs + mkdirs(p) return p get_configdir = verbose.wrap('CONFIGDIR=%s', _get_configdir, always=False) @@ -552,7 +596,7 @@ root = root.replace(tail, 'mpl-data') root = root[root.index('mpl-data'):] d[root] = files - return d.items() + return list(d.items()) def matplotlib_fname(): @@ -571,10 +615,10 @@ oldname = os.path.join( os.getcwd(), '.matplotlibrc') if os.path.exists(oldname): - print >> sys.stderr, """\ + print("""\ WARNING: Old rc filename ".matplotlibrc" found in working dir and and renamed to new default rc file name "matplotlibrc" - (no leading"dot"). """ + (no leading"dot"). """, file=sys.stderr) shutil.move('.matplotlibrc', 'matplotlibrc') home = get_home() @@ -582,9 +626,9 @@ if os.path.exists(oldname): configdir = get_configdir() newname = os.path.join(configdir, 'matplotlibrc') - print >> sys.stderr, """\ + print("""\ WARNING: Old rc filename "%s" found and renamed to - new default rc file name "%s"."""%(oldname, newname) + new default rc file name "%s"."""%(oldname, newname), file=sys.stderr) shutil.move(oldname, newname) @@ -617,7 +661,8 @@ 'text.fontweight': 'font.weight', 'text.fontsize': 'font.size', 'tick.size' : 'tick.major.size', - 'svg.embed_char_paths' : 'svg.fonttype' + 'svg.embed_char_paths' : 'svg.fonttype', + 'savefig.extension' : 'savefig.format' } _deprecated_ignore_map = { @@ -682,7 +727,7 @@ """ Return values in order of sorted keys. """ - return [self[k] for k in self.keys()] + return [self[k] for k in self.iterkeys()] def rc_params(fail_on_error=False): 'Return the default params updated from the values in the rc file' @@ -696,23 +741,30 @@ warnings.warn(message) return ret + return rc_params_from_file(fname, fail_on_error) + + +def rc_params_from_file(fname, fail_on_error=False): + """Load and return params from fname.""" + cnt = 0 rc_temp = {} - for line in file(fname): - cnt += 1 - strippedline = line.split('#',1)[0].strip() - if not strippedline: continue - tup = strippedline.split(':',1) - if len(tup) !=2: - warnings.warn('Illegal line #%d\n\t%s\n\tin file "%s"'%\ - (cnt, line, fname)) - continue - key, val = tup - key = key.strip() - val = val.strip() - if key in rc_temp: - warnings.warn('Duplicate key in file "%s", line #%d'%(fname,cnt)) - rc_temp[key] = (val, line, cnt) + with open(fname) as fd: + for line in fd: + cnt += 1 + strippedline = line.split('#',1)[0].strip() + if not strippedline: continue + tup = strippedline.split(':',1) + if len(tup) !=2: + warnings.warn('Illegal line #%d\n\t%s\n\tin file "%s"'%\ + (cnt, line, fname)) + continue + key, val = tup + key = key.strip() + val = val.strip() + if key in rc_temp: + warnings.warn('Duplicate key in file "%s", line #%d'%(fname,cnt)) + rc_temp[key] = (val, line, cnt) ret = RcParams([ (key, default) for key, (default, converter) in \ defaultParams.iteritems() ]) @@ -724,7 +776,7 @@ ret[key] = val # try to convert to proper type or raise else: try: ret[key] = val # try to convert to proper type or skip - except Exception, msg: + except Exception as msg: warnings.warn('Bad val "%s" on line #%d\n\t"%s"\n\tin file \ "%s"\n\t%s' % (val, cnt, line, fname, msg)) @@ -737,19 +789,19 @@ ret[key] = val # try to convert to proper type or raise else: try: ret[key] = val # try to convert to proper type or skip - except Exception, msg: + except Exception as msg: warnings.warn('Bad val "%s" on line #%d\n\t"%s"\n\tin file \ "%s"\n\t%s' % (val, cnt, line, fname, msg)) elif key in _deprecated_ignore_map: warnings.warn('%s is deprecated. Update your matplotlibrc to use %s instead.'% (key, _deprecated_ignore_map[key])) else: - print >> sys.stderr, """ + print(""" Bad key "%s" on line %d in %s. You probably need to get an updated matplotlibrc file from http://matplotlib.sf.net/_static/matplotlibrc or from the matplotlib source -distribution""" % (key, cnt, fname) +distribution""" % (key, cnt, fname), file=sys.stderr) if ret['datapath'] is None: ret['datapath'] = get_data_path() @@ -771,20 +823,6 @@ # this is the instance used by the matplotlib classes rcParams = rc_params() -if rcParams['examples.directory']: - # paths that are intended to be relative to matplotlib_fname() - # are allowed for the examples.directory parameter. - # However, we will need to fully qualify the path because - # Sphinx requires absolute paths. - if not os.path.isabs(rcParams['examples.directory']): - _basedir, _fname = os.path.split(matplotlib_fname()) - # Sometimes matplotlib_fname() can return relative paths, - # Also, using realpath() guarentees that Sphinx will use - # the same path that matplotlib sees (in case of weird symlinks). - _basedir = os.path.realpath(_basedir) - _fullpath = os.path.join(_basedir, rcParams['examples.directory']) - rcParams['examples.directory'] = _fullpath - rcParamsOrig = rcParams.copy() rcParamsDefault = RcParams([ (key, default) for key, (default, converter) in \ @@ -860,7 +898,7 @@ if is_string_like(group): group = (group,) for g in group: - for k,v in kwargs.items(): + for k,v in kwargs.iteritems(): name = aliases.get(k) or k key = '%s.%s' % (g, name) try: @@ -871,12 +909,58 @@ def rcdefaults(): """ - Restore the default rc params - these are not the params loaded by + Restore the default rc params. These are not the params loaded by the rc file, but mpl's internal params. See rc_file_defaults for reloading the default params from the rc file """ rcParams.update(rcParamsDefault) + +def rc_file(fname): + """ + Update rc params from file. + """ + rcParams.update(rc_params_from_file(fname)) + + +class rc_context(object): + """ + Return a context manager for managing rc settings. + + This allows one to do:: + + >>> with mpl.rc_context(fname='screen.rc'): + >>> plt.plot(x, a) + >>> with mpl.rc_context(fname='print.rc'): + >>> plt.plot(x, b) + >>> plt.plot(x, c) + + The 'a' vs 'x' and 'c' vs 'x' plots would have settings from + 'screen.rc', while the 'b' vs 'x' plot would have settings from + 'print.rc'. + + A dictionary can also be passed to the context manager:: + + >>> with mpl.rc_context(rc={'text.usetex': True}, fname='screen.rc'): + >>> plt.plot(x, a) + + The 'rc' dictionary takes precedence over the settings loaded from + 'fname'. Passing a dictionary only is also valid. + """ + + def __init__(self, rc=None, fname=None): + self.rcdict = rc + self.fname = fname + def __enter__(self): + self._rcparams = rcParams.copy() + if self.fname: + rc_file(self.fname) + if self.rcdict: + rcParams.update(self.rcdict) + def __exit__(self, type, value, tb): + rcParams.update(self._rcparams) + + def rc_file_defaults(): """ Restore the default rc params from the original matplotlib rc that @@ -890,17 +974,15 @@ or matplotlib.backends is imported for the first time. """ -def use(arg, warn=True): +def use(arg, warn=True, force=False): """ Set the matplotlib backend to one of the known backends. - The argument is case-insensitive. For the Cairo backend, - the argument can have an extension to indicate the type of - output. Example: - - use('cairo.pdf') - - will specify a default of pdf output generated by Cairo. + The argument is case-insensitive. *warn* specifies whether a + warning should be issued if a backend has already been set up. + *force* is an **experimental** flag that tells matplotlib to + attempt to initialize a new backend by reloading the backend + module. .. note:: @@ -909,31 +991,41 @@ before importing matplotlib.backends. If warn is True, a warning is issued if you try and call this after pylab or pyplot have been loaded. In certain black magic use cases, e.g. - :func:`pyplot.switch_backends`, we are doing the reloading necessary to + :func:`pyplot.switch_backend`, we are doing the reloading necessary to make the backend switch work (in some cases, e.g. pure image - backends) so one can set warn=False to supporess the warnings. + backends) so one can set warn=False to suppress the warnings. To find out which backend is currently set, see :func:`matplotlib.get_backend`. """ + # Check if we've already set up a backend if 'matplotlib.backends' in sys.modules: - if warn: warnings.warn(_use_error_msg) - return + if warn: + warnings.warn(_use_error_msg) + + # Unless we've been told to force it, just return + if not force: + return + need_reload = True + else: + need_reload = False + + # Set-up the proper backend name if arg.startswith('module://'): name = arg else: # Lowercase only non-module backend names (modules are case-sensitive) arg = arg.lower() - be_parts = arg.split('.') - name = validate_backend(be_parts[0]) - if len(be_parts) > 1: - if name == 'cairo': - rcParams['cairo.format'] = validate_cairo_format(be_parts[1]) - else: - raise ValueError('Only cairo backend has a format option') + name = validate_backend(arg) + rcParams['backend'] = name + # If needed we reload here because a lot of setup code is triggered on + # module import. See backends/__init__.py for more detail. + if need_reload: + reload(sys.modules['matplotlib.backends']) + def get_backend(): "Returns the current backend." return rcParams['backend'] @@ -974,24 +1066,37 @@ default_test_modules = [ 'matplotlib.tests.test_agg', + 'matplotlib.tests.test_artist', + 'matplotlib.tests.test_axes', 'matplotlib.tests.test_backend_svg', + 'matplotlib.tests.test_backend_pgf', 'matplotlib.tests.test_basic', 'matplotlib.tests.test_cbook', - 'matplotlib.tests.test_mlab', - 'matplotlib.tests.test_transforms', - 'matplotlib.tests.test_axes', - 'matplotlib.tests.test_figure', + 'matplotlib.tests.test_colorbar', + 'matplotlib.tests.test_colors', 'matplotlib.tests.test_dates', - 'matplotlib.tests.test_spines', + 'matplotlib.tests.test_delaunay', + 'matplotlib.tests.test_figure', 'matplotlib.tests.test_image', - 'matplotlib.tests.test_simplification', + 'matplotlib.tests.test_legend', 'matplotlib.tests.test_mathtext', + 'matplotlib.tests.test_mlab', + 'matplotlib.tests.test_patches', + 'matplotlib.tests.test_pickle', + 'matplotlib.tests.test_rcparams', + 'matplotlib.tests.test_scale', + 'matplotlib.tests.test_simplification', + 'matplotlib.tests.test_spines', + 'matplotlib.tests.test_subplots', 'matplotlib.tests.test_text', + 'matplotlib.tests.test_ticker', 'matplotlib.tests.test_tightlayout', - 'matplotlib.tests.test_delaunay', - 'matplotlib.tests.test_legend' + 'matplotlib.tests.test_triangulation', + 'matplotlib.tests.test_transforms', + 'matplotlib.tests.test_arrow_patches', ] + def test(verbosity=1): """run the matplotlib test suite""" old_backend = rcParams['backend'] @@ -999,7 +1104,7 @@ use('agg') import nose import nose.plugins.builtin - from testing.noseclasses import KnownFailure + from .testing.noseclasses import KnownFailure from nose.plugins.manager import PluginManager # store the old values before overriding @@ -1025,4 +1130,4 @@ verbose.report('verbose.level %s'%verbose.level) verbose.report('interactive is %s'%rcParams['interactive']) verbose.report('platform is %s'%sys.platform) -verbose.report('loaded modules: %s'%sys.modules.keys(), 'debug') +verbose.report('loaded modules: %s'%sys.modules.iterkeys(), 'debug') diff -Nru matplotlib-1.1.1/lib/matplotlib/_cm.py matplotlib-1.2.0/lib/matplotlib/_cm.py --- matplotlib-1.1.1/lib/matplotlib/_cm.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/_cm.py 2012-11-08 13:38:03.000000000 +0000 @@ -4,6 +4,7 @@ """ +from __future__ import print_function, division import numpy as np _binary_data = { @@ -1624,7 +1625,7 @@ } # This bipolar color map was generated from CoolWarmFloat33.csv of -# "Diverging Color Maps for Scientific Visualization" by Kenneth Moreland. +# "Diverging Color Maps for Scientific Visualization" by Kenneth Moreland. # _coolwarm_data = { 'red': [ @@ -1731,6 +1732,36 @@ (1.0, 0.150232812, 0.150232812)] } +# Implementation of Carey Rappaport's CMRmap. +# See `A Color Map for Effective Black-and-White Rendering of Color-Scale Images' by Carey Rappaport +# http://www.mathworks.com/matlabcentral/fileexchange/2662-cmrmap-m +_CMRmap_data = {'red' : ( (0.000, 0.00, 0.00), + (0.125, 0.15, 0.15), + (0.250, 0.30, 0.30), + (0.375, 0.60, 0.60), + (0.500, 1.00, 1.00), + (0.625, 0.90, 0.90), + (0.750, 0.90, 0.90), + (0.875, 0.90, 0.90), + (1.000, 1.00, 1.00) ), + 'green' : ( (0.000, 0.00, 0.00), + (0.125, 0.15, 0.15), + (0.250, 0.15, 0.15), + (0.375, 0.20, 0.20), + (0.500, 0.25, 0.25), + (0.625, 0.50, 0.50), + (0.750, 0.75, 0.75), + (0.875, 0.90, 0.90), + (1.000, 1.00, 1.00) ), + 'blue': ( (0.000, 0.00, 0.00), + (0.125, 0.50, 0.50), + (0.250, 0.75, 0.75), + (0.375, 0.50, 0.50), + (0.500, 0.15, 0.15), + (0.625, 0.00, 0.00), + (0.750, 0.10, 0.10), + (0.875, 0.50, 0.50), + (1.000, 1.00, 1.00) )} datad = { 'afmhot': _afmhot_data, @@ -1739,6 +1770,7 @@ 'binary': _binary_data, 'bwr': _bwr_data, 'brg': _brg_data, + 'CMRmap': _CMRmap_data, 'cool': _cool_data, 'copper': _copper_data, 'cubehelix': _cubehelix_data, diff -Nru matplotlib-1.1.1/lib/matplotlib/_mathtext_data.py matplotlib-1.2.0/lib/matplotlib/_mathtext_data.py --- matplotlib-1.1.1/lib/matplotlib/_mathtext_data.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/_mathtext_data.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,10 @@ """ font data tables for truetype and afm computer modern fonts """ - # this dict maps symbol names to fontnames, glyphindex. To get the # glyph index from the character code, you have to use get_charmap +from __future__ import print_function + """ from matplotlib.ft2font import FT2Font font = FT2Font('/usr/local/share/matplotlib/cmr10.ttf') @@ -366,39 +367,39 @@ r'\lceil' : ('psyr', 233), r'\lbrace' : ('psyr', 123), r'\Psi' : ('psyr', 89), - r'\bot' : ('psyr', 0136), - r'\Omega' : ('psyr', 0127), - r'\leftbracket' : ('psyr', 0133), - r'\rightbracket' : ('psyr', 0135), + r'\bot' : ('psyr', 0o136), + r'\Omega' : ('psyr', 0o127), + r'\leftbracket' : ('psyr', 0o133), + r'\rightbracket' : ('psyr', 0o135), r'\leftbrace' : ('psyr', 123), - r'\leftparen' : ('psyr', 050), - r'\prime' : ('psyr', 0242), - r'\sharp' : ('psyr', 043), - r'\slash' : ('psyr', 057), - r'\Lamda' : ('psyr', 0114), - r'\neg' : ('psyr', 0330), - r'\Upsilon' : ('psyr', 0241), - r'\rightbrace' : ('psyr', 0175), - r'\rfloor' : ('psyr', 0373), - r'\lambda' : ('psyr', 0154), - r'\to' : ('psyr', 0256), - r'\Xi' : ('psyr', 0130), - r'\emptyset' : ('psyr', 0306), - r'\lfloor' : ('psyr', 0353), - r'\rightparen' : ('psyr', 051), - r'\rceil' : ('psyr', 0371), - r'\ni' : ('psyr', 047), - r'\epsilon' : ('psyr', 0145), - r'\Theta' : ('psyr', 0121), - r'\langle' : ('psyr', 0341), - r'\leftangle' : ('psyr', 0341), - r'\rangle' : ('psyr', 0361), - r'\rightangle' : ('psyr', 0361), - r'\rbrace' : ('psyr', 0175), - r'\circ' : ('psyr', 0260), - r'\diamond' : ('psyr', 0340), - r'\mu' : ('psyr', 0155), - r'\mid' : ('psyr', 0352), + r'\leftparen' : ('psyr', 0o50), + r'\prime' : ('psyr', 0o242), + r'\sharp' : ('psyr', 0o43), + r'\slash' : ('psyr', 0o57), + r'\Lamda' : ('psyr', 0o114), + r'\neg' : ('psyr', 0o330), + r'\Upsilon' : ('psyr', 0o241), + r'\rightbrace' : ('psyr', 0o175), + r'\rfloor' : ('psyr', 0o373), + r'\lambda' : ('psyr', 0o154), + r'\to' : ('psyr', 0o256), + r'\Xi' : ('psyr', 0o130), + r'\emptyset' : ('psyr', 0o306), + r'\lfloor' : ('psyr', 0o353), + r'\rightparen' : ('psyr', 0o51), + r'\rceil' : ('psyr', 0o371), + r'\ni' : ('psyr', 0o47), + r'\epsilon' : ('psyr', 0o145), + r'\Theta' : ('psyr', 0o121), + r'\langle' : ('psyr', 0o341), + r'\leftangle' : ('psyr', 0o341), + r'\rangle' : ('psyr', 0o361), + r'\rightangle' : ('psyr', 0o361), + r'\rbrace' : ('psyr', 0o175), + r'\circ' : ('psyr', 0o260), + r'\diamond' : ('psyr', 0o340), + r'\mu' : ('psyr', 0o155), + r'\mid' : ('psyr', 0o352), r'\imath' : ('pncri8a', 105), r'\%' : ('pncr8a', 37), r'\$' : ('pncr8a', 36), @@ -1763,7 +1764,7 @@ 'uni044B' : 1099 } -uni2type1 = dict([(v,k) for k,v in type12uni.items()]) +uni2type1 = dict(((v,k) for k,v in type12uni.iteritems())) tex2uni = { 'widehat' : 0x0302, diff -Nru matplotlib-1.1.1/lib/matplotlib/_pylab_helpers.py matplotlib-1.2.0/lib/matplotlib/_pylab_helpers.py --- matplotlib-1.1.1/lib/matplotlib/_pylab_helpers.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/_pylab_helpers.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,7 @@ """ Manage figures for pyplot interface. """ +from __future__ import print_function import sys, gc @@ -9,11 +10,11 @@ def error_msg(msg): - print >>sys.stderr, msg + print(msg, file=sys.stderr) class Gcf(object): """ - Manage a set of integer-numbered figures. + Singleton to manage a set of integer-numbered figures. This class is never instantiated; it consists of two class attributes (a list and a dictionary), and a set of static @@ -71,9 +72,13 @@ @staticmethod def destroy_fig(fig): "*fig* is a Figure instance" - for manager in Gcf.figs.values(): + num = None + for manager in Gcf.figs.itervalues(): if manager.canvas.figure == fig: - Gcf.destroy(manager.num) + num = manager.num + break + if num is not None: + Gcf.destroy(num) @staticmethod def destroy_all(): @@ -127,6 +132,7 @@ Gcf._activeQue.append(manager) Gcf.figs[manager.num] = manager + atexit.register(Gcf.destroy_all) diff -Nru matplotlib-1.1.1/lib/matplotlib/afm.py matplotlib-1.2.0/lib/matplotlib/afm.py --- matplotlib-1.1.1/lib/matplotlib/afm.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/afm.py 2012-10-31 00:11:13.000000000 +0000 @@ -14,7 +14,7 @@ It is pretty easy to use, and requires only built-in python libs:: >>> from afm import AFM - >>> fh = file('ptmr8a.afm') + >>> fh = open('ptmr8a.afm') >>> afm = AFM(fh) >>> afm.string_width_height('What the heck?') (6220.0, 683) @@ -34,7 +34,11 @@ John D. Hunter """ -import sys, os, re +from __future__ import print_function + +import sys +import os +import re from _mathtext_data import uni2type1 #Convert string the a python type @@ -45,21 +49,32 @@ # this change to _to_int should at least prevent mpl from crashing on # these JDH (2009-11-06) + def _to_int(x): return int(float(x)) _to_float = float -_to_str = str +if sys.version_info[0] >= 3: + def _to_str(x): + return x.decode('utf8') +else: + _to_str = str + def _to_list_of_ints(s): - s = s.replace(',', ' ') + s = s.replace(b',', b' ') return [_to_int(val) for val in s.split()] + def _to_list_of_floats(s): return [_to_float(val) for val in s.split()] + + def _to_bool(s): - if s.lower().strip() in ('false', '0', 'no'): return False - else: return True + if s.lower().strip() in (b'false', b'0', b'no'): + return False + else: + return True def _sanity_check(fh): @@ -80,9 +95,10 @@ # version number] must be the first line in the file, and the # EndFontMetrics keyword must be the last non-empty line in the # file. We just check the first line. - if not line.startswith('StartFontMetrics'): + if not line.startswith(b'StartFontMetrics'): raise RuntimeError('Not an AFM file') + def _parse_header(fh): """ Reads the font metrics header (up to the char metrics) and returns @@ -102,55 +118,62 @@ """ headerConverters = { - 'StartFontMetrics': _to_float, - 'FontName': _to_str, - 'FullName': _to_str, - 'FamilyName': _to_str, - 'Weight': _to_str, - 'ItalicAngle': _to_float, - 'IsFixedPitch': _to_bool, - 'FontBBox': _to_list_of_ints, - 'UnderlinePosition': _to_int, - 'UnderlineThickness': _to_int, - 'Version': _to_str, - 'Notice': _to_str, - 'EncodingScheme': _to_str, - 'CapHeight': _to_float, # Is the second version a mistake, or - 'Capheight': _to_float, # do some AFM files contain 'Capheight'? -JKS - 'XHeight': _to_float, - 'Ascender': _to_float, - 'Descender': _to_float, - 'StdHW': _to_float, - 'StdVW': _to_float, - 'StartCharMetrics': _to_int, - 'CharacterSet': _to_str, - 'Characters': _to_int, + b'StartFontMetrics': _to_float, + b'FontName': _to_str, + b'FullName': _to_str, + b'FamilyName': _to_str, + b'Weight': _to_str, + b'ItalicAngle': _to_float, + b'IsFixedPitch': _to_bool, + b'FontBBox': _to_list_of_ints, + b'UnderlinePosition': _to_int, + b'UnderlineThickness': _to_int, + b'Version': _to_str, + b'Notice': _to_str, + b'EncodingScheme': _to_str, + b'CapHeight': _to_float, # Is the second version a mistake, or + b'Capheight': _to_float, # do some AFM files contain 'Capheight'? -JKS + b'XHeight': _to_float, + b'Ascender': _to_float, + b'Descender': _to_float, + b'StdHW': _to_float, + b'StdVW': _to_float, + b'StartCharMetrics': _to_int, + b'CharacterSet': _to_str, + b'Characters': _to_int, } d = {} while 1: line = fh.readline() - if not line: break + if not line: + break line = line.rstrip() - if line.startswith('Comment'): continue - lst = line.split( ' ', 1 ) + if line.startswith(b'Comment'): + continue + lst = line.split(b' ', 1) #print '%-s\t%-d line :: %-s' % ( fh.name, len(lst), line ) key = lst[0] - if len( lst ) == 2: + if len(lst) == 2: val = lst[1] else: - val = '' + val = b'' #key, val = line.split(' ', 1) - try: d[key] = headerConverters[key](val) + try: + d[key] = headerConverters[key](val) except ValueError: - print >>sys.stderr, 'Value error parsing header in AFM:', key, val + print('Value error parsing header in AFM:', + key, val, file=sys.stderr) continue except KeyError: - print >>sys.stderr, 'Found an unknown keyword in AFM header (was %s)' % key + print('Found an unknown keyword in AFM header (was %s)' % key, + file=sys.stderr) continue - if key=='StartCharMetrics': return d + if key == b'StartCharMetrics': + return d raise RuntimeError('Bad parse') + def _parse_char_metrics(fh): """ Return a character metric dictionary. Keys are the ASCII num of @@ -163,21 +186,26 @@ """ ascii_d = {} - name_d = {} + name_d = {} while 1: line = fh.readline() - if not line: break + if not line: + break line = line.rstrip() - if line.startswith('EndCharMetrics'): return ascii_d, name_d - vals = line.split(';')[:4] - if len(vals) !=4 : raise RuntimeError('Bad char metrics line: %s' % line) + if line.startswith(b'EndCharMetrics'): + return ascii_d, name_d + vals = line.split(b';')[:4] + if len(vals) != 4: + raise RuntimeError('Bad char metrics line: %s' % line) num = _to_int(vals[0].split()[1]) wx = _to_float(vals[1].split()[1]) name = vals[2].split()[1] + name = name.decode('ascii') bbox = _to_list_of_floats(vals[3][2:]) bbox = map(int, bbox) - # Workaround: If the character name is 'Euro', give it the corresponding - # character code, according to WinAnsiEncoding (see PDF Reference). + # Workaround: If the character name is 'Euro', give it the + # corresponding character code, according to WinAnsiEncoding (see PDF + # Reference). if name == 'Euro': num = 128 if num != -1: @@ -185,6 +213,7 @@ name_d[name] = (wx, bbox) raise RuntimeError('Bad parse') + def _parse_kern_pairs(fh): """ Return a kern pairs dictionary; keys are (*char1*, *char2*) tuples and @@ -198,25 +227,28 @@ """ line = fh.readline() - if not line.startswith('StartKernPairs'): - raise RuntimeError('Bad start of kern pairs data: %s'%line) + if not line.startswith(b'StartKernPairs'): + raise RuntimeError('Bad start of kern pairs data: %s' % line) d = {} while 1: line = fh.readline() - if not line: break + if not line: + break line = line.rstrip() - if len(line)==0: continue - if line.startswith('EndKernPairs'): + if len(line) == 0: + continue + if line.startswith(b'EndKernPairs'): fh.readline() # EndKernData return d vals = line.split() - if len(vals)!=4 or vals[0]!='KPX': - raise RuntimeError('Bad kern pairs line: %s'%line) - c1, c2, val = vals[1], vals[2], _to_float(vals[3]) - d[(c1,c2)] = val + if len(vals) != 4 or vals[0] != b'KPX': + raise RuntimeError('Bad kern pairs line: %s' % line) + c1, c2, val = _to_str(vals[1]), _to_str(vals[2]), _to_float(vals[3]) + d[(c1, c2)] = val raise RuntimeError('Bad kern pairs parse') + def _parse_composites(fh): """ Return a composites dictionary. Keys are the names of the @@ -234,23 +266,26 @@ d = {} while 1: line = fh.readline() - if not line: break + if not line: + break line = line.rstrip() - if len(line)==0: continue - if line.startswith('EndComposites'): + if len(line) == 0: + continue + if line.startswith(b'EndComposites'): return d - vals = line.split(';') + vals = line.split(b';') cc = vals[0].split() name, numParts = cc[1], _to_int(cc[2]) pccParts = [] for s in vals[1:-1]: pcc = s.split() name, dx, dy = pcc[1], _to_float(pcc[2]), _to_float(pcc[3]) - pccParts.append( (name, dx, dy) ) + pccParts.append((name, dx, dy)) d[name] = pccParts raise RuntimeError('Bad composites parse') + def _parse_optional(fh): """ Parse the optional fields for kern pair data and composites @@ -261,23 +296,27 @@ otherwise """ optional = { - 'StartKernData' : _parse_kern_pairs, - 'StartComposites' : _parse_composites, + b'StartKernData': _parse_kern_pairs, + b'StartComposites': _parse_composites, } - d = {'StartKernData':{}, 'StartComposites':{}} + d = {b'StartKernData': {}, b'StartComposites': {}} while 1: line = fh.readline() - if not line: break + if not line: + break line = line.rstrip() - if len(line)==0: continue + if len(line) == 0: + continue key = line.split()[0] - if key in optional: d[key] = optional[key](fh) + if key in optional: + d[key] = optional[key](fh) - l = ( d['StartKernData'], d['StartComposites'] ) + l = (d[b'StartKernData'], d[b'StartComposites']) return l + def parse_afm(fh): """ Parse the Adobe Font Metics file in file handle *fh*. Return value @@ -288,13 +327,13 @@ :func:`_parse_composites` dict (possibly {}) """ _sanity_check(fh) - dhead = _parse_header(fh) + dhead = _parse_header(fh) dcmetrics_ascii, dcmetrics_name = _parse_char_metrics(fh) doptional = _parse_optional(fh) return dhead, dcmetrics_ascii, dcmetrics_name, doptional[0], doptional[1] -class AFM: +class AFM(object): def __init__(self, fh): """ @@ -308,9 +347,9 @@ self._metrics_by_name = dcmetrics_name self._composite = dcomposite - def get_bbox_char(self, c, isord=False): - if not isord: c=ord(c) + if not isord: + c = ord(c) wx, name, bbox = self._metrics[c] return bbox @@ -319,68 +358,82 @@ Return the string width (including kerning) and string height as a (*w*, *h*) tuple. """ - if not len(s): return 0,0 + if not len(s): + return 0, 0 totalw = 0 namelast = None miny = 1e9 maxy = 0 for c in s: - if c == '\n': continue + if c == '\n': + continue wx, name, bbox = self._metrics[ord(c)] - l,b,w,h = bbox + l, b, w, h = bbox # find the width with kerning - try: kp = self._kern[ (namelast, name) ] - except KeyError: kp = 0 + try: + kp = self._kern[(namelast, name)] + except KeyError: + kp = 0 totalw += wx + kp # find the max y - thismax = b+h - if thismax>maxy: maxy = thismax + thismax = b + h + if thismax > maxy: + maxy = thismax # find the min y thismin = b - if thisminmaxy: maxy = thismax + thismax = b + h + if thismax > maxy: + maxy = thismax # find the min y thismin = b - if thismin 0: + args.extend(['-b', '%dk' % self.bitrate]) + if self.extra_args: + args.extend(self.extra_args) + for k, v in self.metadata.items(): + args.extend(['-metadata', '%s=%s' % (k, v)]) + + return args + ['-y', self.outfile] + + +# Combine FFMpeg options with pipe-based writing +@writers.register('ffmpeg') +class FFMpegWriter(MovieWriter, FFMpegBase): + def _args(self): + # Returns the command line parameters for subprocess to use + # ffmpeg to create a movie using a pipe. + args = [self.bin_path(), '-f', 'rawvideo', '-vcodec', 'rawvideo', + '-s', '%dx%d' % self.frame_size, '-pix_fmt', self.frame_format, + '-r', str(self.fps)] + # Logging is quieted because subprocess.PIPE has limited buffer size. + if not verbose.ge('debug'): + args += ['-loglevel', 'quiet'] + args += ['-i', 'pipe:'] + self.output_args + return args + + +#Combine FFMpeg options with temp file-based writing +@writers.register('ffmpeg_file') +class FFMpegFileWriter(FileMovieWriter, FFMpegBase): + supported_formats = ['png', 'jpeg', 'ppm', 'tiff', 'sgi', 'bmp', + 'pbm', 'raw', 'rgba'] + + def _args(self): + # Returns the command line parameters for subprocess to use + # ffmpeg to create a movie using a collection of temp images + return [self.bin_path(), '-vframes', str(self._frame_counter), + '-r', str(self.fps), '-i', + self._base_temp_name()] + self.output_args + + +# Base class of mencoder information. Contains configuration key information +# as well as arguments for controlling *output* +class MencoderBase: + exec_key = 'animation.mencoder_path' + args_key = 'animation.mencoder_args' + + # Mencoder only allows certain keys, other ones cause the program + # to fail. + allowed_metadata = ['name', 'artist', 'genre', 'subject', 'copyright', + 'srcform', 'comment'] + + # Mencoder mandates using name, but 'title' works better with ffmpeg. + # If we find it, just put it's value into name + def _remap_metadata(self): + if 'title' in self.metadata: + self.metadata['name'] = self.metadata['title'] + + @property + def output_args(self): + self._remap_metadata() + args = ['-o', self.outfile, '-ovc', 'lavc', '-lavcopts', + 'vcodec=%s' % self.codec] + if self.bitrate > 0: + args.append('vbitrate=%d' % self.bitrate) + if self.extra_args: + args.extend(self.extra_args) + if self.metadata: + args.extend(['-info', ':'.join('%s=%s' % (k, v) + for k, v in self.metadata.items() + if k in self.allowed_metadata)]) + return args + + +# Combine Mencoder options with pipe-based writing +@writers.register('mencoder') +class MencoderWriter(MovieWriter, MencoderBase): + def _args(self): + # Returns the command line parameters for subprocess to use + # mencoder to create a movie + return [self.bin_path(), '-', '-demuxer', 'rawvideo', '-rawvideo', + ('w=%i:h=%i:' % self.frame_size + + 'fps=%i:format=%s' % (self.fps, + self.frame_format))] + self.output_args + + +# Combine Mencoder options with temp file-based writing +@writers.register('mencoder_file') +class MencoderFileWriter(FileMovieWriter, MencoderBase): + supported_formats = ['png', 'jpeg', 'tga', 'sgi'] + + def _args(self): + # Returns the command line parameters for subprocess to use + # mencoder to create a movie + return [self.bin_path(), + 'mf://%s*.%s' % (self.temp_prefix, self.frame_format), + '-frames', str(self._frame_counter), '-mf', + 'type=%s:fps=%d' % (self.frame_format, + self.fps)] + self.output_args + class Animation(object): ''' @@ -58,7 +485,8 @@ # Connect to the figure's close_event so that we don't continue to # fire events and try to draw to a deleted figure. - self._close_id = self._fig.canvas.mpl_connect('close_event', self._stop) + self._close_id = self._fig.canvas.mpl_connect('close_event', + self._stop) if blit: self._setup_blit() @@ -73,7 +501,7 @@ self.event_source.add_callback(self._step) self.event_source.start() self._fig.canvas.mpl_disconnect(self._first_draw_id) - self._first_draw_id = None # So we can check on save + self._first_draw_id = None # So we can check on save def _stop(self, *args): # On stop we disconnect all of our events. @@ -83,23 +511,48 @@ self.event_source.remove_callback(self._step) self.event_source = None - def save(self, filename, fps=5, codec='mpeg4', clear_temp=True, - frame_prefix='_tmp'): + def save(self, filename, writer=None, fps=None, dpi=None, codec=None, + bitrate=None, extra_args=None, metadata=None, extra_anim=None): ''' Saves a movie file by drawing every frame. *filename* is the output filename, eg :file:`mymovie.mp4` - *fps* is the frames per second in the movie - - *codec* is the codec to be used,if it is supported by the output method. - - *clear_temp* specifies whether the temporary image files should be - deleted. - - *frame_prefix* gives the prefix that should be used for individual - image files. This prefix will have a frame number (i.e. 0001) appended - when saving individual frames. + *writer* is either an instance of :class:`MovieWriter` or a string + key that identifies a class to use, such as 'ffmpeg' or 'mencoder'. + If nothing is passed, the value of the rcparam `animation.writer` is + used. + + *fps* is the frames per second in the movie. Defaults to None, + which will use the animation's specified interval to set the frames + per second. + + *dpi* controls the dots per inch for the movie frames. This combined + with the figure's size in inches controls the size of the movie. + + *codec* is the video codec to be used. Not all codecs are supported + by a given :class:`MovieWriter`. If none is given, this defaults to the + value specified by the rcparam `animation.codec`. + + *bitrate* specifies the amount of bits used per second in the + compressed movie, in kilobits per second. A higher number means a + higher quality movie, but at the cost of increased file size. If no + value is given, this defaults to the value given by the rcparam + `animation.bitrate`. + + *extra_args* is a list of extra string arguments to be passed to the + underlying movie utiltiy. The default is None, which passes the + additional argurments in the 'animation.extra_args' rcParam. + + *metadata* is a dictionary of keys and values for metadata to include + in the output file. Some keys that may be of use include: + title, artist, genre, subject, copyright, srcform, comment. + + *extra_anim* is a list of additional `Animation` objects that should + be included in the saved movie file. These need to be from the same + `matplotlib.Figure` instance. Also, animation frames will just be + simply combined, so there should be a 1:1 correspondence between + the frames from the different animations. ''' # Need to disconnect the first draw callback, since we'll be doing # draws. Otherwise, we'll end up starting the animation. @@ -109,61 +562,63 @@ else: reconnect_first_draw = False - fnames = [] + if fps is None and hasattr(self, '_interval'): + # Convert interval in ms to frames per second + fps = 1000. / self._interval + + # If the writer is None, use the rc param to find the name of the one + # to use + if writer is None: + writer = rcParams['animation.writer'] + + # Re-use the savefig DPI for ours if none is given + if dpi is None: + dpi = rcParams['savefig.dpi'] + + if codec is None: + codec = rcParams['animation.codec'] + + if bitrate is None: + bitrate = rcParams['animation.bitrate'] + + all_anim = [self] + if not extra_anim is None: + all_anim.extend(anim + for anim + in extra_anim if anim._fig is self._fig) + + # If we have the name of a writer, instantiate an instance of the + # registered class. + if is_string_like(writer): + if writer in writers.avail: + writer = writers[writer](fps, codec, bitrate, + extra_args=extra_args, metadata=metadata) + else: + import warnings + warnings.warn("MovieWriter %s unavailable" % writer) + writer = writers.list()[0] + + verbose.report('Animation.save using %s' % type(writer), + level='helpful') # Create a new sequence of frames for saved data. This is different # from new_frame_seq() to give the ability to save 'live' generated # frame information to be saved later. - # TODO: Right now, after closing the figure, saving a movie won't - # work since GUI widgets are gone. Either need to remove extra code - # to allow for this non-existant use case or find a way to make it work. - for idx,data in enumerate(self.new_saved_frame_seq()): - #TODO: Need to see if turning off blit is really necessary - self._draw_next_frame(data, blit=False) - fname = '%s%04d.png' % (frame_prefix, idx) - fnames.append(fname) - verbose.report('Animation.save: saved frame %d to fname=%s'%(idx, fname), level='debug') - self._fig.savefig(fname) - - self._make_movie(filename, fps, codec, frame_prefix) - - #Delete temporary files - if clear_temp: - import os - verbose.report('Animation.save: clearing temporary fnames=%s'%str(fnames), level='debug') - for fname in fnames: - os.remove(fname) + # TODO: Right now, after closing the figure, saving a movie won't work + # since GUI widgets are gone. Either need to remove extra code to + # allow for this non-existant use case or find a way to make it work. + with writer.saving(self._fig, filename, dpi): + for data in itertools.izip(*[a.new_saved_frame_seq() + for a in all_anim]): + for anim, d in zip(all_anim, data): + #TODO: Need to see if turning off blit is really necessary + anim._draw_next_frame(d, blit=False) + writer.grab_frame() # Reconnect signal for first draw if necessary if reconnect_first_draw: self._first_draw_id = self._fig.canvas.mpl_connect('draw_event', self._start) - def ffmpeg_cmd(self, fname, fps, codec, frame_prefix): - # Returns the command line parameters for subprocess to use - # ffmpeg to create a movie - return ['ffmpeg', '-y', '-r', str(fps), '-b', '1800k', '-i', - '%s%%04d.png' % frame_prefix, fname] - - def mencoder_cmd(self, fname, fps, codec, frame_prefix): - # Returns the command line parameters for subprocess to use - # mencoder to create a movie - return ['mencoder', 'mf://%s*.png' % frame_prefix, '-mf', - 'type=png:fps=%d' % fps, '-ovc', 'lavc', '-lavcopts', - 'vcodec=%s' % codec, '-oac', 'copy', '-o', fname] - - def _make_movie(self, fname, fps, codec, frame_prefix, cmd_gen=None): - # Uses subprocess to call the program for assembling frames into a - # movie file. *cmd_gen* is a callable that generates the sequence - # of command line arguments from a few configuration options. - from subprocess import Popen, PIPE - if cmd_gen is None: - cmd_gen = self.ffmpeg_cmd - command = cmd_gen(fname, fps, codec, frame_prefix) - verbose.report('Animation._make_movie running command: %s'%' '.join(command)) - proc = Popen(command, shell=False, - stdout=PIPE, stderr=PIPE) - proc.wait() - def _step(self, *args): ''' Handler for getting events. By default, gets the next frame in the @@ -173,7 +628,7 @@ # call _step, until the frame sequence reaches the end of iteration, # at which point False will be returned. try: - framedata = self.frame_seq.next() + framedata = next(self.frame_seq) self._draw_next_frame(framedata, self._blit) return True except StopIteration: @@ -265,7 +720,8 @@ self.event_source.stop() self._blit_cache.clear() self._init_draw() - self._resize_id = self._fig.canvas.mpl_connect('draw_event', self._end_redraw) + self._resize_id = self._fig.canvas.mpl_connect('draw_event', + self._end_redraw) def _end_redraw(self, evt): # Now that the redraw has happened, do the post draw flushing and @@ -301,25 +757,29 @@ event_source = fig.canvas.new_timer() event_source.interval = self._interval - Animation.__init__(self, fig, event_source=event_source, *args, **kwargs) + Animation.__init__(self, fig, event_source=event_source, + *args, **kwargs) def _step(self, *args): ''' Handler for getting events. ''' # Extends the _step() method for the Animation class. If - # Animation._step signals that it reached the end and we want to repeat, - # we refresh the frame sequence and return True. If _repeat_delay is - # set, change the event_source's interval to our loop delay and set the - # callback to one which will then set the interval back. + # Animation._step signals that it reached the end and we want to + # repeat, we refresh the frame sequence and return True. If + # _repeat_delay is set, change the event_source's interval to our loop + # delay and set the callback to one which will then set the interval + # back. still_going = Animation._step(self, *args) if not still_going and self.repeat: + self.frame_seq = self.new_frame_seq() if self._repeat_delay: self.event_source.remove_callback(self._step) self.event_source.add_callback(self._loop_delay) self.event_source.interval = self._repeat_delay - self.frame_seq = self.new_frame_seq() - return True + return True + else: + return Animation._step(self, *args) else: return still_going @@ -335,6 +795,7 @@ self.event_source.remove_callback(self._loop_delay) self.event_source.interval = self._interval self.event_source.add_callback(self._step) + Animation._step(self) class ArtistAnimation(TimedAnimation): @@ -390,6 +851,7 @@ for artist in artists: artist.set_visible(True) + class FuncAnimation(TimedAnimation): ''' Makes an animation by repeatedly calling a function *func*, passing in @@ -401,7 +863,7 @@ results of drawing from the first item in the frames sequence will be used. ''' - def __init__(self, fig, func, frames=None ,init_func=None, fargs=None, + def __init__(self, fig, func, frames=None, init_func=None, fargs=None, save_count=None, **kwargs): if fargs: self._args = fargs @@ -464,7 +926,7 @@ # For blitting, the init_func should return a sequence of modified # artists. if self._init_func is None: - self._draw_frame(self.new_frame_seq().next()) + self._draw_frame(next(self.new_frame_seq())) else: self._drawn_artists = self._init_func() @@ -472,7 +934,8 @@ # Save the data for potential saving of movies. self._save_seq.append(framedata) - # Make sure to respect save_count (keep only the last save_count around) + # Make sure to respect save_count (keep only the last save_count + # around) self._save_seq = self._save_seq[-self.save_count:] # Call the func with framedata and args. If blitting is desired, diff -Nru matplotlib-1.1.1/lib/matplotlib/artist.py matplotlib-1.2.0/lib/matplotlib/artist.py --- matplotlib-1.1.1/lib/matplotlib/artist.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/artist.py 2012-11-06 22:31:09.000000000 +0000 @@ -1,9 +1,11 @@ -from __future__ import division -import re, warnings +from __future__ import division, print_function +import re +import warnings import matplotlib import matplotlib.cbook as cbook from matplotlib import docstring, rcParams -from transforms import Bbox, IdentityTransform, TransformedBbox, TransformedPath +from transforms import Bbox, IdentityTransform, TransformedBbox, \ + TransformedPath, Transform from path import Path ## Note, matplotlib artists use the doc strings for set and get @@ -23,8 +25,6 @@ # http://groups.google.com/groups?hl=en&lr=&threadm=mailman.5090.1098044946.5135.python-list%40python.org&rnum=1&prev=/groups%3Fq%3D__doc__%2Bauthor%253Ajdhunter%2540ace.bsd.uchicago.edu%26hl%3Den%26btnG%3DGoogle%2BSearch - - def allow_rasterization(draw): """ Decorator for Artist.draw method. Provides routines @@ -40,7 +40,6 @@ if artist.get_agg_filter() is not None: renderer.start_filter() - def after(artist, renderer): if artist.get_agg_filter() is not None: @@ -58,7 +57,7 @@ # "safe wrapping" to exactly replicate anything we haven't overridden above draw_wrapper.__name__ = draw.__name__ draw_wrapper.__dict__ = draw.__dict__ - draw_wrapper.__doc__ = draw.__doc__ + draw_wrapper.__doc__ = draw.__doc__ draw_wrapper._supports_rasterization = True return draw_wrapper @@ -71,6 +70,7 @@ aname = 'Artist' zorder = 0 + def __init__(self): self.figure = None @@ -91,7 +91,7 @@ self.eventson = False # fire events only if eventson self._oid = 0 # an observer id - self._propobservers = {} # a dict from oids to funcs + self._propobservers = {} # a dict from oids to funcs try: self.axes = None except AttributeError: @@ -100,10 +100,15 @@ self._remove_method = None self._url = None self._gid = None - self.x_isdata = True # False to avoid updating Axes.dataLim with x - self.y_isdata = True # with y self._snap = None + def __getstate__(self): + d = self.__dict__.copy() + # remove the unpicklable remove method, this will get re-added on load + # (by the axes) if the artist lives on an axes. + d['_remove_method'] = None + return d + def remove(self): """ Remove the artist from the figure if possible. The effect @@ -119,18 +124,18 @@ Note: there is no support for removing the artist's legend entry. """ - # There is no method to set the callback. Instead the parent should set - # the _remove_method attribute directly. This would be a protected - # attribute if Python supported that sort of thing. The callback - # has one parameter, which is the child to be removed. - if self._remove_method != None: + # There is no method to set the callback. Instead the parent should + # set the _remove_method attribute directly. This would be a + # protected attribute if Python supported that sort of thing. The + # callback has one parameter, which is the child to be removed. + if self._remove_method is not None: self._remove_method(self) else: raise NotImplementedError('cannot remove artist') # TODO: the fix for the collections relim problem is to move the - # limits calculation into the artist itself, including the property - # of whether or not the artist should affect the limits. Then there - # will be no distinction between axes.add_line, axes.add_patch, etc. + # limits calculation into the artist itself, including the property of + # whether or not the artist should affect the limits. Then there will + # be no distinction between axes.add_line, axes.add_patch, etc. # TODO: add legend support def have_units(self): @@ -155,7 +160,8 @@ convert *y* using yaxis unit type """ ax = getattr(self, 'axes', None) - if ax is None or ax.yaxis is None: return y + if ax is None or ax.yaxis is None: + return y return ax.yaxis.convert_units(y) def set_axes(self, axes): @@ -197,15 +203,17 @@ For adding callbacks """ - try: del self._propobservers[oid] - except KeyError: pass + try: + del self._propobservers[oid] + except KeyError: + pass def pchanged(self): """ Fire an event when property changed, calling all of the registered callbacks. """ - for oid, func in self._propobservers.items(): + for oid, func in self._propobservers.iteritems(): func(self) def is_transform_set(self): @@ -232,7 +240,10 @@ instance used by this artist. """ if self._transform is None: - self._transform = IdentityTransform() + self.set_transform(IdentityTransform()) + elif (not isinstance(self._transform, Transform) + and hasattr(self._transform, '_as_mpl_transform')): + self._transform = self._transform._as_mpl_transform(self.axes) return self._transform def hitlist(self, event): @@ -241,14 +252,13 @@ """ L = [] try: - hascursor,info = self.contains(event) + hascursor, info = self.contains(event) if hascursor: L.append(self) except: import traceback traceback.print_exc() - print "while checking",self.__class__ - + print("while checking", self.__class__) for a in self.get_children(): L.extend(a.hitlist(event)) @@ -268,12 +278,12 @@ selection, such as which points are contained in the pick radius. See individual artists for details. """ - if callable(self._contains): return self._contains(self,mouseevent) - #raise NotImplementedError,str(self.__class__)+" needs 'contains' method" + if callable(self._contains): + return self._contains(self, mouseevent) warnings.warn("'%s' needs 'contains' method" % self.__class__.__name__) - return False,{} + return False, {} - def set_contains(self,picker): + def set_contains(self, picker): """ Replace the contains test used by this artist. The new picker should be a callable function which determines whether the @@ -314,9 +324,9 @@ if self.pickable(): picker = self.get_picker() if callable(picker): - inside,prop = picker(self,mouseevent) + inside, prop = picker(self, mouseevent) else: - inside,prop = self.contains(mouseevent) + inside, prop = self.contains(mouseevent) if inside: self.figure.canvas.pick_event(mouseevent, self, **prop) @@ -324,7 +334,7 @@ for a in self.get_children(): # make sure the event happened in the same axes ax = getattr(a, 'axes', None) - if mouseevent.inaxes is None or mouseevent.inaxes==ax: + if mouseevent.inaxes is None or mouseevent.inaxes == ax: # we need to check if mouseevent.inaxes is None # because some objects associated with an axes (eg a # tick label) can be outside the bounding box of the @@ -390,7 +400,6 @@ """ self._url = url - def get_gid(self): """ Returns the group id @@ -485,12 +494,13 @@ :class:`~matplotlib.transforms.Transform`) | :class:`~matplotlib.patches.Patch` | None ] """ - from patches import Patch, Rectangle + from matplotlib.patches import Patch, Rectangle success = False if transform is None: if isinstance(path, Rectangle): - self.clipbox = TransformedBbox(Bbox.unit(), path.get_transform()) + self.clipbox = TransformedBbox(Bbox.unit(), + path.get_transform()) self._clippath = None success = True elif isinstance(path, Patch): @@ -512,7 +522,7 @@ success = True if not success: - print type(path), type(transform) + print(type(path), type(transform)) raise TypeError("Invalid arguments to set_clip_path") self.pchanged() @@ -603,7 +613,8 @@ def draw(self, renderer, *args, **kwargs): 'Derived classes drawing method' - if not self.get_visible(): return + if not self.get_visible(): + return def set_alpha(self, alpha): """ @@ -635,7 +646,6 @@ self._visible = b self.pchanged() - def set_animated(self, b): """ Set the artist's animation state. @@ -653,15 +663,16 @@ store = self.eventson self.eventson = False changed = False - for k,v in props.items(): - func = getattr(self, 'set_'+k, None) + + for k, v in props.iteritems(): + func = getattr(self, 'set_' + k, None) if func is None or not callable(func): - raise AttributeError('Unknown property %s'%k) + raise AttributeError('Unknown property %s' % k) func(v) changed = True self.eventson = store - if changed: self.pchanged() - + if changed: + self.pchanged() def get_label(self): """ @@ -673,13 +684,11 @@ """ Set the label to *s* for auto legend. - ACCEPTS: any string + ACCEPTS: string or anything printable with '%s' conversion. """ - self._label = s + self._label = '%s' % (s, ) self.pchanged() - - def get_zorder(self): """ Return the :class:`Artist`'s zorder. @@ -709,7 +718,6 @@ self._label = other._label self.pchanged() - def properties(self): """ return a dictionary mapping property name -> value for all Artist props @@ -721,15 +729,17 @@ A tkstyle set command, pass *kwargs* to set properties """ ret = [] - for k,v in kwargs.items(): + for k, v in kwargs.iteritems(): k = k.lower() - funcName = "set_%s"%k - func = getattr(self,funcName) - ret.extend( [func(v)] ) + funcName = "set_%s" % k + func = getattr(self, funcName) + ret.extend([func(v)]) return ret def findobj(self, match=None, include_self=True): """ + Find artist objects. + pyplot signature: findobj(o=gcf(), match=None, include_self=True) @@ -751,15 +761,17 @@ .. plot:: mpl_examples/pylab_examples/findobj_demo.py """ - if match is None: # always return True - def matchfunc(x): return True + if match is None: # always return True + def matchfunc(x): + return True elif cbook.issubclass_safe(match, Artist): def matchfunc(x): return isinstance(x, match) elif callable(match): matchfunc = match else: - raise ValueError('match must be None, a matplotlib.artist.Artist subclass, or a callable') + raise ValueError('match must be None, a matplotlib.artist.Artist ' + 'subclass, or a callable') artists = [] @@ -775,10 +787,6 @@ return artists - - - - class ArtistInspector: """ A helper class to inspect an :class:`~matplotlib.artist.Artist` @@ -788,12 +796,13 @@ def __init__(self, o): """ Initialize the artist inspector with an - :class:`~matplotlib.artist.Artist` or sequence of - :class:`Artists`. If a sequence is used, we assume it is a - homogeneous sequence (all :class:`Artists` are of the same - type) and it is your responsibility to make sure this is so. + :class:`~matplotlib.artist.Artist` or sequence of :class:`Artists`. + If a sequence is used, we assume it is a homogeneous sequence (all + :class:`Artists` are of the same type) and it is your responsibility + to make sure this is so. """ - if cbook.iterable(o) and len(o): o = o[0] + if cbook.iterable(o) and len(o): + o = o[0] self.oorig = o if not isinstance(o, type): @@ -816,17 +825,20 @@ """ names = [name for name in dir(self.o) if (name.startswith('set_') or name.startswith('get_')) - and callable(getattr(self.o,name))] + and callable(getattr(self.o, name))] aliases = {} for name in names: func = getattr(self.o, name) - if not self.is_alias(func): continue + if not self.is_alias(func): + continue docstring = func.__doc__ fullname = docstring[10:] aliases.setdefault(fullname[4:], {})[name[4:]] = None return aliases - _get_valid_values_regex = re.compile(r"\n\s*ACCEPTS:\s*((?:.|\n)*?)(?:$|(?:\n\n))") + _get_valid_values_regex = re.compile( + r"\n\s*ACCEPTS:\s*((?:.|\n)*?)(?:$|(?:\n\n))") + def get_valid_values(self, attr): """ Get the legal arguments for the setter associated with *attr*. @@ -838,13 +850,14 @@ "[ ``'-'`` | ``'--'`` | ``'-.'`` | ``':'`` | ``'steps'`` | ``'None'`` ]" """ - name = 'set_%s'%attr + name = 'set_%s' % attr if not hasattr(self.o, name): - raise AttributeError('%s has no function %s'%(self.o,name)) + raise AttributeError('%s has no function %s' % (self.o, name)) func = getattr(self.o, name) docstring = func.__doc__ - if docstring is None: return 'unknown' + if docstring is None: + return 'unknown' if docstring.startswith('alias for '): return None @@ -862,11 +875,14 @@ setters = [] for name in dir(self.o): - if not name.startswith('set_'): continue + if not name.startswith('set_'): + continue o = getattr(self.o, name) - if not callable(o): continue + if not callable(o): + continue func = o - if self.is_alias(func): continue + if self.is_alias(func): + continue source_class = self.o.__module__ + "." + self.o.__name__ for cls in self.o.mro(): if name in cls.__dict__: @@ -889,7 +905,8 @@ function. """ ds = o.__doc__ - if ds is None: return False + if ds is None: + return False return ds.startswith('alias for ') def aliased_name(self, s): @@ -903,11 +920,12 @@ """ if s in self.aliasd: - return s + ''.join([' or %s' % x for x in self.aliasd[s].keys()]) + return s + ''.join([' or %s' % x + for x + in self.aliasd[s].iterkeys()]) else: return s - def aliased_name_rest(self, s, target): """ return 'PROPNAME or alias' if *s* has an alias, else return @@ -919,13 +937,13 @@ """ if s in self.aliasd: - aliases = ''.join([' or %s' % x for x in self.aliasd[s].keys()]) + aliases = ''.join([' or %s' % x + for x + in self.aliasd[s].iterkeys()]) else: aliases = '' return ':meth:`%s <%s>`%s' % (s, target, aliases) - - def pprint_setters(self, prop=None, leadingspace=2): """ If *prop* is *None*, return a list of strings of all settable properies @@ -936,12 +954,12 @@ values. """ if leadingspace: - pad = ' '*leadingspace + pad = ' ' * leadingspace else: - pad = '' + pad = '' if prop is not None: accepts = self.get_valid_values(prop) - return '%s%s: %s' %(pad, prop, accepts) + return '%s%s: %s' % (pad, prop, accepts) attrs = self._get_setters_and_targets() attrs.sort() @@ -951,7 +969,7 @@ accepts = self.get_valid_values(prop) name = self.aliased_name(prop) - lines.append('%s%s: %s' %(pad, name, accepts)) + lines.append('%s%s: %s' % (pad, name, accepts)) return lines def pprint_setters_rest(self, prop=None, leadingspace=2): @@ -964,32 +982,34 @@ values. """ if leadingspace: - pad = ' '*leadingspace + pad = ' ' * leadingspace else: - pad = '' + pad = '' if prop is not None: accepts = self.get_valid_values(prop) - return '%s%s: %s' %(pad, prop, accepts) + return '%s%s: %s' % (pad, prop, accepts) attrs = self._get_setters_and_targets() attrs.sort() lines = [] ######## - names = [self.aliased_name_rest(prop, target) for prop, target in attrs] + names = [self.aliased_name_rest(prop, target) + for prop, target + in attrs] accepts = [self.get_valid_values(prop) for prop, target in attrs] col0_len = max([len(n) for n in names]) col1_len = max([len(a) for a in accepts]) - table_formatstr = pad + '='*col0_len + ' ' + '='*col1_len + table_formatstr = pad + '=' * col0_len + ' ' + '=' * col1_len lines.append('') lines.append(table_formatstr) - lines.append(pad + 'Property'.ljust(col0_len+3) + \ + lines.append(pad + 'Property'.ljust(col0_len + 3) + \ 'Description'.ljust(col1_len)) lines.append(table_formatstr) - lines.extend([pad + n.ljust(col0_len+3) + a.ljust(col1_len) + lines.extend([pad + n.ljust(col0_len + 3) + a.ljust(col1_len) for n, a in zip(names, accepts)]) lines.append(table_formatstr) @@ -1001,10 +1021,9 @@ accepts = self.get_valid_values(prop) name = self.aliased_name_rest(prop, path) - lines.append('%s%s: %s' %(pad, name, accepts)) + lines.append('%s%s: %s' % (pad, name, accepts)) return lines - def properties(self): """ return a dictionary mapping property name -> value @@ -1018,11 +1037,15 @@ d = dict() for name in getters: func = getattr(o, name) - if self.is_alias(func): continue + if self.is_alias(func): + continue - try: val = func() - except: continue - else: d[name[4:]] = val + try: + val = func() + except: + continue + else: + d[name[4:]] = val return d @@ -1037,19 +1060,17 @@ lines = [] for name in names: val = d[name] - if getattr(val, 'shape', ()) != () and len(val)>6: + if getattr(val, 'shape', ()) != () and len(val) > 6: s = str(val[:6]) + '...' else: s = str(val) s = s.replace('\n', ' ') - if len(s)>50: + if len(s) > 50: s = s[:50] + '...' name = self.aliased_name(name) - lines.append(' %s = %s' %(name, s)) + lines.append(' %s = %s' % (name, s)) return lines - - def findobj(self, match=None): """ Recursively find all :class:`matplotlib.artist.Artist` @@ -1063,34 +1084,34 @@ used to filter matches. """ - - if match is None: # always return True - def matchfunc(x): return True + if match is None: # always return True + def matchfunc(x): + return True elif issubclass(match, Artist): def matchfunc(x): return isinstance(x, match) elif callable(match): matchfunc = func else: - raise ValueError('match must be None, an matplotlib.artist.Artist subclass, or a callable') - + raise ValueError('match must be None, an ' + 'matplotlib.artist.Artist ' + 'subclass, or a callable') artists = [] for c in self.get_children(): if matchfunc(c): artists.append(c) - artists.extend([thisc for thisc in c.findobj(matchfunc) if matchfunc(thisc)]) + artists.extend([thisc + for thisc + in c.findobj(matchfunc) + if matchfunc(thisc)]) if matchfunc(self): artists.append(self) return artists - - - - def getp(obj, property=None): """ Return the value of object's property. *property* is an optional string @@ -1119,12 +1140,10 @@ linewidth or lw = 2 """ - - if property is None: insp = ArtistInspector(obj) ret = insp.pprint_getters() - print '\n'.join(ret) + print('\n'.join(ret)) return func = getattr(obj, 'get_' + property) @@ -1133,8 +1152,11 @@ # alias get = getp + def setp(obj, *args, **kwargs): """ + Set a property on an artist object. + matplotlib supports the use of :func:`setp` ("set property") and :func:`getp` to set and get object properties, as well as to do introspection on the object. For example, to set the linestyle of a @@ -1178,12 +1200,12 @@ insp = ArtistInspector(obj) - if len(kwargs)==0 and len(args)==0: - print '\n'.join(insp.pprint_setters()) + if len(kwargs) == 0 and len(args) == 0: + print('\n'.join(insp.pprint_setters())) return - if len(kwargs)==0 and len(args)==1: - print insp.pprint_setters(prop=args[0]) + if len(kwargs) == 0 and len(args) == 1: + print(insp.pprint_setters(prop=args[0])) return if not cbook.iterable(obj): @@ -1191,28 +1213,29 @@ else: objs = cbook.flatten(obj) - - if len(args)%2: + if len(args) % 2: raise ValueError('The set args must be string, value pairs') funcvals = [] - for i in range(0, len(args)-1, 2): - funcvals.append((args[i], args[i+1])) - funcvals.extend(kwargs.items()) + for i in range(0, len(args) - 1, 2): + funcvals.append((args[i], args[i + 1])) + funcvals.extend(kwargs.iteritems()) ret = [] for o in objs: for s, val in funcvals: s = s.lower() - funcName = "set_%s"%s + funcName = "set_%s" % s func = getattr(o, funcName) - ret.extend( [func(val)] ) + ret.extend([func(val)]) return [x for x in cbook.flatten(ret)] + def kwdoc(a): hardcopy = matplotlib.rcParams['docstring.hardcopy'] if hardcopy: - return '\n'.join(ArtistInspector(a).pprint_setters_rest(leadingspace=2)) + return '\n'.join(ArtistInspector(a).pprint_setters_rest( + leadingspace=2)) else: return '\n'.join(ArtistInspector(a).pprint_setters(leadingspace=2)) diff -Nru matplotlib-1.1.1/lib/matplotlib/axes.py matplotlib-1.2.0/lib/matplotlib/axes.py --- matplotlib-1.1.1/lib/matplotlib/axes.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/axes.py 2012-11-08 13:38:03.000000000 +0000 @@ -1,5 +1,5 @@ -from __future__ import division, generators -import math, sys, warnings, datetime, new +from __future__ import division, print_function +import math, sys, warnings, datetime from operator import itemgetter import itertools @@ -16,7 +16,7 @@ import matplotlib.collections as mcoll import matplotlib.colors as mcolors import matplotlib.contour as mcontour -import matplotlib.dates as mdates +import matplotlib.dates as _ # <-registers a date unit converter from matplotlib import docstring import matplotlib.font_manager as font_manager import matplotlib.image as mimage @@ -29,12 +29,13 @@ import matplotlib.spines as mspines import matplotlib.quiver as mquiver import matplotlib.scale as mscale +import matplotlib.stackplot as mstack +import matplotlib.streamplot as mstream import matplotlib.table as mtable import matplotlib.text as mtext import matplotlib.ticker as mticker import matplotlib.transforms as mtransforms import matplotlib.tri as mtri - from matplotlib.container import BarContainer, ErrorbarContainer, StemContainer iterable = cbook.iterable @@ -153,9 +154,8 @@ DeprecationWarning) -class _process_plot_var_args: +class _process_plot_var_args(object): """ - Process variable length arguments to the plot command, so that plot commands like the following are supported:: @@ -171,6 +171,14 @@ self.command = command self.set_color_cycle() + def __getstate__(self): + # note: it is not possible to pickle a itertools.cycle instance + return {'axes': self.axes, 'command': self.command} + + def __setstate__(self, state): + self.__dict__ = state.copy() + self.set_color_cycle() + def set_color_cycle(self, clist=None): if clist is None: clist = rcParams['axes.color_cycle'] @@ -198,7 +206,7 @@ for key, val in kwargs.items(): funcName = "set_%s"%key if not hasattr(line,funcName): - raise TypeError, 'There is no line property "%s"'%key + raise TypeError('There is no line property "%s"'%key) func = getattr(line,funcName) func(val) @@ -207,7 +215,7 @@ for key, val in kwargs.items(): funcName = "set_%s"%key if not hasattr(fill_poly,funcName): - raise TypeError, 'There is no patch property "%s"'%key + raise TypeError('There is no patch property "%s"'%key) func = getattr(fill_poly,funcName) func(val) @@ -281,7 +289,7 @@ linestyle, marker, color = _process_plot_format(tup[-1]) tup = tup[:-1] elif len(tup) == 3: - raise ValueError, 'third arg must be a format string' + raise ValueError('third arg must be a format string') else: linestyle, marker, color = None, None, None kw = {} @@ -354,6 +362,7 @@ def __str__(self): return "Axes(%g,%g;%gx%g)" % tuple(self._position.bounds) + def __init__(self, fig, rect, axisbg = None, # defaults to rc axes.facecolor frameon = True, @@ -456,7 +465,7 @@ self._frameon = frameon self._axisbelow = rcParams['axes.axisbelow'] - self._rasterization_zorder = -30000 + self._rasterization_zorder = None self._hold = rcParams['axes.hold'] self._connected = {} # a dict from events to (id, func) @@ -488,6 +497,15 @@ self._ycid = self.yaxis.callbacks.connect('units finalize', self.relim) + def __setstate__(self, state): + self.__dict__ = state + # put the _remove_method back on all artists contained within the axes + for container_name in ['lines', 'collections', 'tables', 'patches', + 'texts', 'images']: + container = getattr(self, container_name) + for artist in container: + artist._remove_method = container.remove + def get_window_extent(self, *args, **kwargs): """ get the axes bounding box in display space; *args* and @@ -834,7 +852,7 @@ } def cla(self): - """Clear the current axes""" + """Clear the current axes.""" # Note: this is called by Axes.__init__() self.xaxis.cla() self.yaxis.cla() @@ -851,7 +869,21 @@ self.xaxis.minor = self._sharex.xaxis.minor x0, x1 = self._sharex.get_xlim() self.set_xlim(x0, x1, emit=False, auto=None) + + # Save the current formatter/locator so we don't lose it + majf = self._sharex.xaxis.get_major_formatter() + minf = self._sharex.xaxis.get_minor_formatter() + majl = self._sharex.xaxis.get_major_locator() + minl = self._sharex.xaxis.get_minor_locator() + + # This overwrites the current formatter/locator self.xaxis.set_scale(self._sharex.xaxis.get_scale()) + + # Reset the formatter/locator + self.xaxis.set_major_formatter(majf) + self.xaxis.set_minor_formatter(minf) + self.xaxis.set_major_locator(majl) + self.xaxis.set_minor_locator(minl) else: self.xaxis.set_scale('linear') @@ -860,7 +892,21 @@ self.yaxis.minor = self._sharey.yaxis.minor y0, y1 = self._sharey.get_ylim() self.set_ylim(y0, y1, emit=False, auto=None) + + # Save the current formatter/locator so we don't lose it + majf = self._sharey.yaxis.get_major_formatter() + minf = self._sharey.yaxis.get_minor_formatter() + majl = self._sharey.yaxis.get_major_locator() + minl = self._sharey.yaxis.get_minor_locator() + + # This overwrites the current formatter/locator self.yaxis.set_scale(self._sharey.yaxis.get_scale()) + + # Reset the formatter/locator + self.yaxis.set_major_formatter(majf) + self.yaxis.set_minor_formatter(minf) + self.yaxis.set_major_locator(majl) + self.yaxis.set_minor_locator(minl) else: self.yaxis.set_scale('linear') @@ -1074,7 +1120,7 @@ self._anchor = anchor else: raise ValueError('argument must be among %s' % - ', '.join(mtransforms.BBox.coefs.keys())) + ', '.join(mtransforms.Bbox.coefs.keys())) def get_data_ratio(self): """ @@ -1460,17 +1506,52 @@ self._update_line_limits(line) if not line.get_label(): - line.set_label('_line%d'%len(self.lines)) + line.set_label('_line%d' % len(self.lines)) self.lines.append(line) line._remove_method = lambda h: self.lines.remove(h) return line def _update_line_limits(self, line): - p = line.get_path() - if p.vertices.size > 0: - self.dataLim.update_from_path(p, self.ignore_existing_data_limits, - updatex=line.x_isdata, - updatey=line.y_isdata) + """Figures out the data limit of the given line, updating self.dataLim.""" + path = line.get_path() + if path.vertices.size == 0: + return + + line_trans = line.get_transform() + + if line_trans == self.transData: + data_path = path + + elif any(line_trans.contains_branch_seperately(self.transData)): + # identify the transform to go from line's coordinates + # to data coordinates + trans_to_data = line_trans - self.transData + + # if transData is affine we can use the cached non-affine component + # of line's path. (since the non-affine part of line_trans is + # entirely encapsulated in trans_to_data). + if self.transData.is_affine: + line_trans_path = line._get_transformed_path() + na_path, _ = line_trans_path.get_transformed_path_and_affine() + data_path = trans_to_data.transform_path_affine(na_path) + else: + data_path = trans_to_data.transform_path(path) + else: + # for backwards compatibility we update the dataLim with the + # coordinate range of the given path, even though the coordinate + # systems are completely different. This may occur in situations + # such as when ax.transAxes is passed through for absolute + # positioning. + data_path = path + + if data_path.vertices.size > 0: + updatex, updatey = line_trans.contains_branch_seperately( + self.transData + ) + self.dataLim.update_from_path(data_path, + self.ignore_existing_data_limits, + updatex=updatex, + updatey=updatey) self.ignore_existing_data_limits = False def add_patch(self, p): @@ -1506,11 +1587,14 @@ if vertices.size > 0: xys = patch.get_patch_transform().transform(vertices) if patch.get_data_transform() != self.transData: - transform = (patch.get_data_transform() + - self.transData.inverted()) - xys = transform.transform(xys) - self.update_datalim(xys, updatex=patch.x_isdata, - updatey=patch.y_isdata) + patch_to_data = (patch.get_data_transform() - + self.transData) + xys = patch_to_data.transform(xys) + + updatex, updatey = patch.get_transform().\ + contains_branch_seperately(self.transData) + self.update_datalim(xys, updatex=updatex, + updatey=updatey) def add_table(self, tab): @@ -1537,7 +1621,7 @@ if not label: container.set_label('_container%d'%len(self.containers)) self.containers.append(container) - container.set_remove_method(lambda h: self.containers.remove(container)) + container.set_remove_method(lambda h: self.containers.remove(h)) return container @@ -1598,13 +1682,13 @@ if xdata is not None: # we only need to update if there is nothing set yet. if not self.xaxis.have_units(): - self.xaxis.update_units(xdata) + self.xaxis.update_units(xdata) #print '\tset from xdata', self.xaxis.units if ydata is not None: # we only need to update if there is nothing set yet. if not self.yaxis.have_units(): - self.yaxis.update_units(ydata) + self.yaxis.update_units(ydata) #print '\tset from ydata', self.yaxis.units # process kwargs 2nd since these will override default units @@ -1710,7 +1794,7 @@ def margins(self, *args, **kw): """ - Convenience method to set or retrieve autoscaling margins. + Set or retrieve autoscaling margins. signatures:: @@ -1768,7 +1852,9 @@ def set_rasterization_zorder(self, z): """ - Set zorder value below which artists will be rasterized + Set zorder value below which artists will be rasterized. Set + to `None` to disable rasterizing of artists below a particular + zorder. """ self._rasterization_zorder = z @@ -1780,6 +1866,8 @@ def autoscale(self, enable=True, axis='both', tight=None): """ + Autoscale the axis view to the data (toggle). + Convenience method for simple axis view autoscaling. It turns autoscaling on or off, and then, if autoscaling for either axis is on, it performs @@ -1943,7 +2031,8 @@ # rasterize artists with negative zorder # if the minimum zorder is negative, start rasterization rasterization_zorder = self._rasterization_zorder - if len(dsu) > 0 and dsu[0][0] < rasterization_zorder: + if (rasterization_zorder is not None and + len(dsu) > 0 and dsu[0][0] < rasterization_zorder): renderer.start_rasterizing() dsu_rasterized = [l for l in dsu if l[0] < rasterization_zorder] dsu = [l for l in dsu if l[0] >= rasterization_zorder] @@ -2064,6 +2153,8 @@ @docstring.dedent_interpd def grid(self, b=None, which='major', axis='both', **kwargs): """ + Turn the axes grids on or off. + Call signature:: grid(self, b=None, which='major', axis='both', **kwargs) @@ -2101,8 +2192,8 @@ def ticklabel_format(self, **kwargs): """ - Convenience method for manipulating the ScalarFormatter - used by default for linear axes. + Change the `~matplotlib.ticker.ScalarFormatter` used by + default for linear axes. Optional keyword arguments: @@ -2114,7 +2205,7 @@ *scilimits* (m, n), pair of integers; if *style* is 'sci', scientific notation will be used for numbers outside the range - 10`-m`:sup: to 10`n`:sup:. + 10`m`:sup: to 10`n`:sup:. Use (0,0) to include all numbers. *useOffset* [True | False | offset]; if True, the offset will be calculated as needed; @@ -2157,11 +2248,11 @@ cb = False else: cb = True - raise NotImplementedError, "comma style remains to be added" + raise NotImplementedError("comma style remains to be added") elif style == '': sb = None else: - raise ValueError, "%s is not a valid style value" + raise ValueError("%s is not a valid style value") try: if sb is not None: if axis == 'both' or axis == 'x': @@ -2189,7 +2280,7 @@ def locator_params(self, axis='both', tight=None, **kwargs): """ - Convenience method for controlling tick locators. + Control behavior of tick locators. Keyword arguments: @@ -2228,8 +2319,7 @@ def tick_params(self, axis='both', **kwargs): """ - Convenience method for changing the appearance of ticks and - tick labels. + Change the appearance of ticks and tick labels. Keyword arguments: @@ -3254,6 +3344,8 @@ def text(self, x, y, s, fontdict=None, withdash=False, **kwargs): """ + Add text to the axes. + Call signature:: text(x, y, s, fontdict=None, **kwargs) @@ -3334,6 +3426,9 @@ @docstring.dedent_interpd def annotate(self, *args, **kwargs): """ + Create an annotation: a piece of text referring to a data + point. + Call signature:: annotate(s, xy, xytext=None, xycoords='data', @@ -3358,12 +3453,12 @@ @docstring.dedent_interpd def axhline(self, y=0, xmin=0, xmax=1, **kwargs): """ + Add a horizontal line across the axis. + Call signature:: axhline(y=0, xmin=0, xmax=1, **kwargs) - Axis Horizontal Line - Draw a horizontal line at *y* from *xmin* to *xmax*. With the default values of *xmin* = 0 and *xmax* = 1, this line will always span the horizontal extent of the axes, regardless of @@ -3415,7 +3510,6 @@ trans = mtransforms.blended_transform_factory( self.transAxes, self.transData) l = mlines.Line2D([xmin,xmax], [y,y], transform=trans, **kwargs) - l.x_isdata = False self.add_line(l) self.autoscale_view(scalex=False, scaley=scaley) return l @@ -3423,12 +3517,12 @@ @docstring.dedent_interpd def axvline(self, x=0, ymin=0, ymax=1, **kwargs): """ + Add a vertical line across the axes. + Call signature:: axvline(x=0, ymin=0, ymax=1, **kwargs) - Axis Vertical Line - Draw a vertical line at *x* from *ymin* to *ymax*. With the default values of *ymin* = 0 and *ymax* = 1, this line will always span the vertical extent of the axes, regardless of the @@ -3480,7 +3574,6 @@ trans = mtransforms.blended_transform_factory( self.transData, self.transAxes) l = mlines.Line2D([x,x], [ymin,ymax] , transform=trans, **kwargs) - l.y_isdata = False self.add_line(l) self.autoscale_view(scalex=scalex, scaley=False) return l @@ -3488,12 +3581,12 @@ @docstring.dedent_interpd def axhspan(self, ymin, ymax, xmin=0, xmax=1, **kwargs): """ + Add a horizontal span (rectangle) across the axis. + Call signature:: axhspan(ymin, ymax, xmin=0, xmax=1, **kwargs) - Axis Horizontal Span. - *y* coords are in data units and *x* coords are in axes (relative 0-1) units. @@ -3537,7 +3630,6 @@ verts = (xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin) p = mpatches.Polygon(verts, **kwargs) p.set_transform(trans) - p.x_isdata = False self.add_patch(p) self.autoscale_view(scalex=False) return p @@ -3545,12 +3637,12 @@ @docstring.dedent_interpd def axvspan(self, xmin, xmax, ymin=0, ymax=1, **kwargs): """ + Add a vertical span (rectangle) across the axes. + Call signature:: axvspan(xmin, xmax, ymin=0, ymax=1, **kwargs) - Axis Vertical Span. - *x* coords are in data units and *y* coords are in axes (relative 0-1) units. @@ -3594,7 +3686,6 @@ verts = [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)] p = mpatches.Polygon(verts, **kwargs) p.set_transform(trans) - p.y_isdata = False self.add_patch(p) self.autoscale_view(scaley=False) return p @@ -3604,6 +3695,8 @@ def hlines(self, y, xmin, xmax, colors='k', linestyles='solid', label='', **kwargs): """ + Plot horizontal lines. + call signature:: hlines(y, xmin, xmax, colors='k', linestyles='solid', **kwargs) @@ -3662,9 +3755,9 @@ xmax = np.resize( xmax, y.shape ) if len(xmin)!=len(y): - raise ValueError, 'xmin and y are unequal sized sequences' + raise ValueError('xmin and y are unequal sized sequences') if len(xmax)!=len(y): - raise ValueError, 'xmax and y are unequal sized sequences' + raise ValueError('xmax and y are unequal sized sequences') verts = [ ((thisxmin, thisy), (thisxmax, thisy)) for thisxmin, thisxmax, thisy in zip(xmin, xmax, y)] @@ -3673,15 +3766,16 @@ self.add_collection(coll) coll.update(kwargs) - minx = min(xmin.min(), xmax.min()) - maxx = max(xmin.max(), xmax.max()) - miny = y.min() - maxy = y.max() + if len(y) > 0: + minx = min(xmin.min(), xmax.min()) + maxx = max(xmin.max(), xmax.max()) + miny = y.min() + maxy = y.max() - corners = (minx, miny), (maxx, maxy) + corners = (minx, miny), (maxx, maxy) - self.update_datalim(corners) - self.autoscale_view() + self.update_datalim(corners) + self.autoscale_view() return coll @@ -3690,6 +3784,8 @@ def vlines(self, x, ymin, ymax, colors='k', linestyles='solid', label='', **kwargs): """ + Plot vertical lines. + Call signature:: vlines(x, ymin, ymax, color='k', linestyles='solid') @@ -3738,9 +3834,9 @@ ymax = np.resize( ymax, x.shape ) if len(ymin)!=len(x): - raise ValueError, 'ymin and x are unequal sized sequences' + raise ValueError('ymin and x are unequal sized sequences') if len(ymax)!=len(x): - raise ValueError, 'ymax and x are unequal sized sequences' + raise ValueError('ymax and x are unequal sized sequences') Y = np.array([ymin, ymax]).T @@ -3752,15 +3848,16 @@ self.add_collection(coll) coll.update(kwargs) - minx = min( x ) - maxx = max( x ) - - miny = min( min(ymin), min(ymax) ) - maxy = max( max(ymin), max(ymax) ) - - corners = (minx, miny), (maxx, maxy) - self.update_datalim(corners) - self.autoscale_view() + if len(x) > 0: + minx = min( x ) + maxx = max( x ) + + miny = min( min(ymin), min(ymax) ) + maxy = max( max(ymin), max(ymax) ) + + corners = (minx, miny), (maxx, maxy) + self.update_datalim(corners) + self.autoscale_view() return coll @@ -3789,6 +3886,11 @@ Return value is a list of lines that were added. + By default, each line is assigned a different color specified by a + 'color cycle'. To change this behavior, you can edit the + axes.color_cycle rcParam. Alternatively, you can use + :meth:`~matplotlib.axes.Axes.set_default_color_cycle`. + The following format string characters are accepted to control the line style or marker: @@ -3872,8 +3974,9 @@ marker, linestyle, and markercolor with:: plot(x, y, color='green', linestyle='dashed', marker='o', - markerfacecolor='blue', markersize=12). See - :class:`~matplotlib.lines.Line2D` for details. + markerfacecolor='blue', markersize=12). + + See :class:`~matplotlib.lines.Line2D` for details. The kwargs are :class:`~matplotlib.lines.Line2D` properties: @@ -3894,7 +3997,6 @@ self.add_line(line) lines.append(line) - self.autoscale_view(scalex=scalex, scaley=scaley) return lines @@ -3902,6 +4004,8 @@ def plot_date(self, x, y, fmt='bo', tz=None, xdate=True, ydate=False, **kwargs): """ + Plot with data with dates. + Call signature:: plot_date(x, y, fmt='bo', tz=None, xdate=True, ydate=False, **kwargs) @@ -3971,12 +4075,12 @@ @docstring.dedent_interpd def loglog(self, *args, **kwargs): """ + Make a plot with log scaling on both the *x* and *y* axis. + Call signature:: loglog(*args, **kwargs) - Make a plot with log scaling on the *x* and *y* axis. - :func:`~matplotlib.pyplot.loglog` supports all the keyword arguments of :func:`~matplotlib.pyplot.plot` and :meth:`matplotlib.axes.Axes.set_xscale` / @@ -4031,12 +4135,12 @@ @docstring.dedent_interpd def semilogx(self, *args, **kwargs): """ + Make a plot with log scaling on the *x* axis. + Call signature:: semilogx(*args, **kwargs) - Make a plot with log scaling on the *x* axis. - :func:`semilogx` supports all the keyword arguments of :func:`~matplotlib.pyplot.plot` and :meth:`matplotlib.axes.Axes.set_xscale`. @@ -4082,12 +4186,12 @@ @docstring.dedent_interpd def semilogy(self, *args, **kwargs): """ + Make a plot with log scaling on the *y* axis. + call signature:: semilogy(*args, **kwargs) - Make a plot with log scaling on the *y* axis. - :func:`semilogy` supports all the keyword arguments of :func:`~matplotlib.pylab.plot` and :meth:`matplotlib.axes.Axes.set_yscale`. @@ -4133,14 +4237,16 @@ @docstring.dedent_interpd def acorr(self, x, **kwargs): """ + Plot the autocorrelation of *x*. + Call signature:: acorr(x, normed=True, detrend=mlab.detrend_none, usevlines=True, maxlags=10, **kwargs) - Plot the autocorrelation of *x*. If *normed* = *True*, - normalize the data by the autocorrelation at 0-th lag. *x* is - detrended by the *detrend* callable (default no normalization). + If *normed* = *True*, normalize the data by the autocorrelation at + 0-th lag. *x* is detrended by the *detrend* callable (default no + normalization). Data are plotted as ``plot(lags, c, **kwargs)`` @@ -4195,15 +4301,17 @@ def xcorr(self, x, y, normed=True, detrend=mlab.detrend_none, usevlines=True, maxlags=10, **kwargs): """ + Plot the cross correlation between *x* and *y*. + Call signature:: xcorr(self, x, y, normed=True, detrend=mlab.detrend_none, usevlines=True, maxlags=10, **kwargs) - Plot the cross correlation between *x* and *y*. If *normed* = - *True*, normalize the data by the cross correlation at 0-th - lag. *x* and y are detrended by the *detrend* callable - (default no normalization). *x* and *y* must be equal length. + If *normed* = *True*, normalize the data by the cross + correlation at 0-th lag. *x* and y are detrended by the + *detrend* callable (default no normalization). *x* and *y* + must be equal length. Data are plotted as ``plot(lags, c, **kwargs)`` @@ -4325,46 +4433,48 @@ def legend(self, *args, **kwargs): """ + Place a legend on the current axes. + Call signature:: - legend(*args, **kwargs) + legend(*args, **kwargs) - Place a legend on the current axes at location *loc*. Labels are a - sequence of strings and *loc* can be a string or an integer specifying - the legend location. + Places legend at location *loc*. Labels are a sequence of + strings and *loc* can be a string or an integer specifying the + legend location. To make a legend with existing lines:: - legend() + legend() :meth:`legend` by itself will try and build a legend using the label property of the lines/patches/collections. You can set the label of a line by doing:: - plot(x, y, label='my data') + plot(x, y, label='my data') or:: - line.set_label('my data'). + line.set_label('my data'). If label is set to '_nolegend_', the item will not be shown in legend. To automatically generate the legend from labels:: - legend( ('label1', 'label2', 'label3') ) + legend( ('label1', 'label2', 'label3') ) To make a legend for a list of lines and labels:: - legend( (line1, line2, line3), ('label1', 'label2', 'label3') ) + legend( (line1, line2, line3), ('label1', 'label2', 'label3') ) To make a legend at a given location, using a location argument:: - legend( ('label1', 'label2', 'label3'), loc='upper left') + legend( ('label1', 'label2', 'label3'), loc='upper left') or:: - legend( (line1, line2, line3), ('label1', 'label2', 'label3'), loc=2) + legend( (line1, line2, line3), ('label1', 'label2', 'label3'), loc=2) The location codes are @@ -4390,7 +4500,7 @@ of BboxBase(or its derivatives) or a tuple of 2 or 4 floats. For example, - loc = 'upper right', bbox_to_anchor = (0.5, 0.5) + loc = 'upper right', bbox_to_anchor = (0.5, 0.5) will place the legend so that the upper right corner of the legend at the center of the axes. @@ -4409,6 +4519,12 @@ instance. If *prop* is a dictionary, a new instance will be created with *prop*. If *None*, use rc settings. + *fontsize*: [ size in points | 'xx-small' | 'x-small' | + 'small' | 'medium' | 'large' | 'x-large' | 'xx-large' ] + Set the font size. May be either a size string, relative to + the default font size, or an absolute font size in points. This + argument is only used if prop is not specified. + *numpoints*: integer The number of points in the legend for line @@ -4523,12 +4639,14 @@ def step(self, x, y, *args, **kwargs): """ + Make a step plot. + Call signature:: step(x, y, *args, **kwargs) - Make a step plot. Additional keyword args to :func:`step` are the same - as those for :func:`~matplotlib.pyplot.plot`. + Additional keyword args to :func:`step` are the same as those + for :func:`~matplotlib.pyplot.plot`. *x* and *y* must be 1-D sequences, and it is assumed, but not checked, that *x* is uniformly increasing. @@ -4556,6 +4674,8 @@ @docstring.dedent_interpd def bar(self, left, height, width=0.8, bottom=None, **kwargs): """ + Make a bar plot. + Call signature:: bar(left, height, width=0.8, bottom=0, **kwargs) @@ -4703,7 +4823,7 @@ if len(height) == 1: height *= nbars else: - raise ValueError, 'invalid orientation: %s' % orientation + raise ValueError('invalid orientation: %s' % orientation) if len(linewidth) < nbars: linewidth *= nbars @@ -4761,7 +4881,7 @@ bottom = [bottom[i] - height[i]/2. for i in xrange(len(bottom))] else: - raise ValueError, 'invalid alignment: %s' % align + raise ValueError('invalid alignment: %s' % align) args = zip(left, bottom, width, height, color, edgecolor, linewidth) for l, b, w, h, c, e, lw in args: @@ -4834,6 +4954,8 @@ @docstring.dedent_interpd def barh(self, bottom, width, height=0.8, left=None, **kwargs): """ + Make a horizontal bar plot. + Call signature:: barh(bottom, width, height=0.8, left=0, **kwargs) @@ -4905,6 +5027,8 @@ @docstring.dedent_interpd def broken_barh(self, xranges, yrange, **kwargs): """ + Plot horizontal bars. + Call signature:: broken_barh(self, xranges, yrange, **kwargs) @@ -4948,6 +5072,8 @@ def stem(self, x, y, linefmt='b-', markerfmt='bo', basefmt='r-', bottom=None, label=None): """ + Create a stem plot. + Call signature:: stem(x, y, linefmt='b-', markerfmt='bo', basefmt='r-') @@ -4998,18 +5124,22 @@ def pie(self, x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, - labeldistance=1.1): + labeldistance=1.1, startangle=None, radius=None): r""" + Plot a pie chart. + Call signature:: pie(x, explode=None, labels=None, colors=('b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'), - autopct=None, pctdistance=0.6, labeldistance=1.1, shadow=False) + autopct=None, pctdistance=0.6, shadow=False, + labeldistance=1.1, startangle=None, radius=None) Make a pie chart of array *x*. The fractional area of each wedge is given by x/sum(x). If sum(x) <= 1, then the values of x give the fractional area directly and the array will not - be normalized. + be normalized. The wedges are plotted counterclockwise, + by default starting from the x-axis. Keyword arguments: @@ -5041,6 +5171,13 @@ *shadow*: [ *False* | *True* ] Draw a shadow beneath the pie. + *startangle*: [ *None* | Offset angle ] + If not *None*, rotates the start of the pie chart by *angle* + degrees counterclockwise from the x-axis. + + *radius*: [ *None* | scalar ] + The radius of the pie, if *radius* is *None* it will be set to 1. + The pie chart will probably look best if the figure and axes are square. Eg.:: @@ -5077,12 +5214,20 @@ center = 0,0 - radius = 1 - theta1 = 0 - i = 0 + if radius is None: + radius = 1 + + # Starting theta1 is the start fraction of the circle + if startangle is None: + theta1 = 0 + else: + theta1 = startangle / 360.0 + texts = [] slices = [] autotexts = [] + + i = 0 for frac, label, expl in cbook.safezip(x,labels, explode): x, y = center theta2 = theta1 + frac @@ -5144,21 +5289,27 @@ self.set_xticks([]) self.set_yticks([]) - if autopct is None: return slices, texts - else: return slices, texts, autotexts + if autopct is None: + return slices, texts + else: + return slices, texts, autotexts @docstring.dedent_interpd def errorbar(self, x, y, yerr=None, xerr=None, fmt='-', ecolor=None, elinewidth=None, capsize=3, barsabove=False, lolims=False, uplims=False, - xlolims=False, xuplims=False, **kwargs): + xlolims=False, xuplims=False, errorevery=1, capthick=None, + **kwargs): """ + Plot an errorbar graph. + Call signature:: errorbar(x, y, yerr=None, xerr=None, fmt='-', ecolor=None, elinewidth=None, capsize=3, barsabove=False, lolims=False, uplims=False, - xlolims=False, xuplims=False) + xlolims=False, xuplims=False, errorevery=1, + capthick=None) Plot *x* versus *y* with error deltas in *yerr* and *xerr*. Vertical errorbars are plotted if *yerr* is not *None*. @@ -5182,14 +5333,22 @@ errorbars to a bar plot, for example. *ecolor*: [ *None* | mpl color ] - a matplotlib color arg which gives the color the errorbar lines; + A matplotlib color arg which gives the color the errorbar lines; if *None*, use the marker color. *elinewidth*: scalar - the linewidth of the errorbar lines. If *None*, use the linewidth. + The linewidth of the errorbar lines. If *None*, use the linewidth. *capsize*: scalar - the size of the error bar caps in points + The length of the error bar caps in points + + *capthick*: scalar + An alias kwarg to *markeredgewidth* (a.k.a. - *mew*). This + setting is a more sensible name for the property that + controls the thickness of the error bar cap in points. For + backwards compatibility, if *mew* or *markeredgewidth* are given, + then they will over-ride *capthick*. This may change in future + releases. *barsabove*: [ *True* | *False* ] if *True*, will plot the errorbars above the plot @@ -5201,6 +5360,11 @@ used to indicate this. lims-arguments may be of the same type as *xerr* and *yerr*. + *errorevery*: positive integer + subsamples the errorbars. Eg if everyerror=5, errorbars for every + 5-th datapoint will be plotted. The data plot itself still shows + all data points. + All other keyword arguments are passed on to the plot command for the markers. For example, this code makes big red squares with thick green edges:: @@ -5234,6 +5398,9 @@ """ + if errorevery < 1: + raise ValueError('errorevery has to be a strictly positive integer') + self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs) if not self._hold: self.cla() holdstate = self._hold @@ -5290,6 +5457,8 @@ if not iterable(xuplims): xuplims = np.array([xuplims]*len(x), bool) else: xuplims = np.asarray(xuplims, bool) + everymask = np.arange(len(x)) % errorevery == 0 + def xywhere(xs, ys, mask): """ return xs[mask], ys[mask] where mask is True but xs and @@ -5306,6 +5475,15 @@ plot_kw = { 'ms':2*capsize, 'label':'_nolegend_'} + if capthick is not None: + # 'mew' has higher priority, I believe, + # if both 'mew' and 'markeredgewidth' exists. + # So, save capthick to markeredgewidth so that + # explicitly setting mew or markeredgewidth will + # over-write capthick. + plot_kw['markeredgewidth'] = capthick + # For backwards-compat, allow explicit setting of + # 'mew' or 'markeredgewidth' to over-ride capthick. if 'markeredgewidth' in kwargs: plot_kw['markeredgewidth']=kwargs['markeredgewidth'] if 'mew' in kwargs: @@ -5328,33 +5506,38 @@ right = [thisx+thiserr for (thisx, thiserr) in cbook.safezip(x,xerr)] - barcols.append( self.hlines(y, left, right, **lines_kw ) ) + yo, _ = xywhere(y, right, everymask) + lo, ro= xywhere(left, right, everymask) + barcols.append( self.hlines(yo, lo, ro, **lines_kw ) ) if capsize > 0: if xlolims.any(): # can't use numpy logical indexing since left and # y are lists - leftlo, ylo = xywhere(left, y, xlolims) + leftlo, ylo = xywhere(left, y, xlolims & everymask) caplines.extend( self.plot(leftlo, ylo, ls='None', marker=mlines.CARETLEFT, **plot_kw) ) xlolims = ~xlolims - leftlo, ylo = xywhere(left, y, xlolims) + leftlo, ylo = xywhere(left, y, xlolims & everymask) caplines.extend( self.plot(leftlo, ylo, 'k|', **plot_kw) ) else: - caplines.extend( self.plot(left, y, 'k|', **plot_kw) ) + + leftlo, ylo = xywhere(left, y, everymask) + caplines.extend( self.plot(leftlo, ylo, 'k|', **plot_kw) ) if xuplims.any(): - rightup, yup = xywhere(right, y, xuplims) + rightup, yup = xywhere(right, y, xuplims & everymask) caplines.extend( self.plot(rightup, yup, ls='None', marker=mlines.CARETRIGHT, **plot_kw) ) xuplims = ~xuplims - rightup, yup = xywhere(right, y, xuplims) + rightup, yup = xywhere(right, y, xuplims & everymask) caplines.extend( self.plot(rightup, yup, 'k|', **plot_kw) ) else: - caplines.extend( self.plot(right, y, 'k|', **plot_kw) ) + rightup, yup = xywhere(right, y, everymask) + caplines.extend( self.plot(rightup, yup, 'k|', **plot_kw) ) if yerr is not None: if (iterable(yerr) and len(yerr)==2 and @@ -5371,31 +5554,35 @@ upper = [thisy+thiserr for (thisy, thiserr) in cbook.safezip(y,yerr)] - barcols.append( self.vlines(x, lower, upper, **lines_kw) ) + xo, _ = xywhere(x, lower, everymask) + lo, uo= xywhere(lower, upper, everymask) + barcols.append( self.vlines(xo, lo, uo, **lines_kw) ) if capsize > 0: if lolims.any(): - xlo, lowerlo = xywhere(x, lower, lolims) + xlo, lowerlo = xywhere(x, lower, lolims & everymask) caplines.extend( self.plot(xlo, lowerlo, ls='None', marker=mlines.CARETDOWN, **plot_kw) ) lolims = ~lolims - xlo, lowerlo = xywhere(x, lower, lolims) + xlo, lowerlo = xywhere(x, lower, lolims & everymask) caplines.extend( self.plot(xlo, lowerlo, 'k_', **plot_kw) ) else: - caplines.extend( self.plot(x, lower, 'k_', **plot_kw) ) + xlo, lowerlo = xywhere(x, lower, everymask) + caplines.extend( self.plot(xlo, lowerlo, 'k_', **plot_kw) ) if uplims.any(): - xup, upperup = xywhere(x, upper, uplims) + xup, upperup = xywhere(x, upper, uplims & everymask) caplines.extend( self.plot(xup, upperup, ls='None', marker=mlines.CARETUP, **plot_kw) ) uplims = ~uplims - xup, upperup = xywhere(x, upper, uplims) + xup, upperup = xywhere(x, upper, uplims & everymask) caplines.extend( self.plot(xup, upperup, 'k_', **plot_kw) ) else: - caplines.extend( self.plot(x, upper, 'k_', **plot_kw) ) + xup, upperup = xywhere(x, upper, everymask) + caplines.extend( self.plot(xup, upperup, 'k_', **plot_kw) ) if not barsabove and fmt is not None: l0, = self.plot(x,y,fmt,**kwargs) @@ -5422,14 +5609,17 @@ return errorbar_container # (l0, caplines, barcols) - def boxplot(self, x, notch=0, sym='b+', vert=1, whis=1.5, + def boxplot(self, x, notch=False, sym='b+', vert=True, whis=1.5, positions=None, widths=None, patch_artist=False, - bootstrap=None): + bootstrap=None, usermedians=None, conf_intervals=None): """ + Make a box and whisker plot. + Call signature:: - boxplot(x, notch=0, sym='+', vert=1, whis=1.5, - positions=None, widths=None, patch_artist=False) + boxplot(x, notch=False, sym='+', vert=True, whis=1.5, + positions=None, widths=None, patch_artist=False, + bootstrap=None, usermedians=None, conf_intervals=None) Make a box and whisker plot for each column of *x* or each vector in sequence *x*. The box extends from the lower to @@ -5442,59 +5632,110 @@ *x* : Array or a sequence of vectors. - *notch* : [ 0 (default) | 1] - If 0, produce a rectangular box plot. - If 1, produce a notched box plot + *notch* : [ False (default) | True ] + If False (default), produces a rectangular box plot. + If True, will produce a notched box plot - *sym* : - (default 'b+') is the default symbol for flier points. + *sym* : [ default 'b+' ] + The default symbol for flier points. Enter an empty string ('') if you don't want to show fliers. - *vert* : [1 (default) | 0] - If 1, make the boxes vertical. - If 0, make horizontal boxes. (Odd, but kept for compatibility - with MATLAB boxplots) - - *whis* : (default 1.5) - Defines the length of the whiskers as - a function of the inner quartile range. They extend to the - most extreme data point within ( ``whis*(75%-25%)`` ) data range. + *vert* : [ False | True (default) ] + If True (default), makes the boxes vertical. + If False, makes horizontal boxes. + + *whis* : [ default 1.5 ] + Defines the length of the whiskers as a function of the inner + quartile range. They extend to the most extreme data point + within ( ``whis*(75%-25%)`` ) data range. *bootstrap* : [ *None* (default) | integer ] Specifies whether to bootstrap the confidence intervals - around the median for notched boxplots. If *None*, no - bootstrapping is performed, and notches are calculated - using a Gaussian-based asymptotic approximation - (see McGill, R., Tukey, J.W., and Larsen, W.A., - 1978, and Kendall and Stuart, 1967). Otherwise, bootstrap - specifies the number of times to bootstrap the median to - determine its 95% confidence intervals. Values between 1000 - and 10000 are recommended. - - *positions* : (default 1,2,...,n) - Sets the horizontal positions of - the boxes. The ticks and limits are automatically set to match - the positions. - - *widths* : [ scalar | array ] - Either a scalar or a vector to set the width of each box. - The default is 0.5, or ``0.15*(distance between extreme - positions)`` if that is smaller. - - *patch_artist* : boolean - If *False* (default), produce boxes with the - :class:`~matplotlib.lines.Line2D` artist. - If *True*, produce boxes with the - :class:`~matplotlib.patches.Patch` artist. + around the median for notched boxplots. If bootstrap==None, + no bootstrapping is performed, and notches are calculated + using a Gaussian-based asymptotic approximation (see McGill, R., + Tukey, J.W., and Larsen, W.A., 1978, and Kendall and Stuart, + 1967). Otherwise, bootstrap specifies the number of times to + bootstrap the median to determine it's 95% confidence intervals. + Values between 1000 and 10000 are recommended. + + *usermedians* : [ default None ] + An array or sequence whose first dimension (or length) is + compatible with *x*. This overrides the medians computed by + matplotlib for each element of *usermedians* that is not None. + When an element of *usermedians* == None, the median will be + computed directly as normal. + + *conf_intervals* : [ default None ] + Array or sequence whose first dimension (or length) is compatible + with *x* and whose second dimension is 2. When the current element + of *conf_intervals* is not None, the notch locations computed by + matplotlib are overridden (assuming notch is True). When an element of + *conf_intervals* is None, boxplot compute notches the method + specified by the other kwargs (e.g. *bootstrap*). + + *positions* : [ default 1,2,...,n ] + Sets the horizontal positions of the boxes. The ticks and limits + are automatically set to match the positions. + + *widths* : [ default 0.5 ] + Either a scalar or a vector and sets the width of each box. The + default is 0.5, or ``0.15*(distance between extreme positions)`` + if that is smaller. + + *patch_artist* : [ False (default) | True ] + If False produces boxes with the Line2D artist + If True produces boxes with the Patch artist Returns a dictionary mapping each component of the boxplot - to a list of the :class:`~matplotlib.lines.Line2D` - instances created (unless *patch_artist* was *True*. See above.). + to a list of the :class:`matplotlib.lines.Line2D` + instances created. That dictionary has the following keys + (assuming vertical boxplots): + + - boxes: the main body of the boxplot showing the quartiles + and the median's confidence intervals if enabled. + - medians: horizonal lines at the median of each box. + - whiskers: the vertical lines extending to the most extreme, + n-outlier data points. + - caps: the horizontal lines at the ends of the whiskers. + - fliers: points representing data that extend beyone the + whiskers (outliers). **Example:** .. plot:: pyplots/boxplot_demo.py """ + def bootstrapMedian(data, N=5000): + # determine 95% confidence intervals of the median + M = len(data) + percentile = [2.5,97.5] + estimate = np.zeros(N) + for n in range(N): + bsIndex = np.random.random_integers(0,M-1,M) + bsData = data[bsIndex] + estimate[n] = mlab.prctile(bsData, 50) + CI = mlab.prctile(estimate, percentile) + return CI + + def computeConfInterval(data, med, iq, bootstrap): + if bootstrap is not None: + # Do a bootstrap estimate of notch locations. + # get conf. intervals around median + CI = bootstrapMedian(data, N=bootstrap) + notch_min = CI[0] + notch_max = CI[1] + else: + # Estimate notch locations using Gaussian-based + # asymptotic approximation. + # + # For discussion: McGill, R., Tukey, J.W., + # and Larsen, W.A. (1978) "Variations of + # Boxplots", The American Statistician, 32:12-16. + N = len(data) + notch_min = med - 1.57*iq/np.sqrt(N) + notch_max = med + 1.57*iq/np.sqrt(N) + return notch_min, notch_max + if not self._hold: self.cla() holdStatus = self._hold whiskers, caps, boxes, medians, fliers = [], [], [], [], [] @@ -5515,11 +5756,43 @@ else: x = [x[:,i] for i in xrange(nc)] else: - raise ValueError, "input x can have no more than 2 dimensions" + raise ValueError("input x can have no more than 2 dimensions") if not hasattr(x[0], '__len__'): x = [x] col = len(x) + # sanitize user-input medians + msg1 = "usermedians must either be a list/tuple or a 1d array" + msg2 = "usermedians' length must be compatible with x" + if usermedians is not None: + if hasattr(usermedians, 'shape'): + if len(usermedians.shape) != 1: + raise ValueError(msg1) + elif usermedians.shape[0] != col: + raise ValueError(msg2) + elif len(usermedians) != col: + raise ValueError(msg2) + + #sanitize user-input confidence intervals + msg1 = "conf_intervals must either be a list of tuples or a 2d array" + msg2 = "conf_intervals' length must be compatible with x" + msg3 = "each conf_interval, if specificied, must have two values" + if conf_intervals is not None: + if hasattr(conf_intervals, 'shape'): + if len(conf_intervals.shape) != 2: + raise ValueError(msg1) + elif conf_intervals.shape[0] != col: + raise ValueError(msg2) + elif conf_intervals.shape[1] == 2: + raise ValueError(msg3) + else: + if len(conf_intervals) != col: + raise ValueError(msg2) + for ci in conf_intervals: + if ci is not None and len(ci) != 2: + raise ValueError(msg3) + + # get some plot info if positions is None: positions = range(1, col + 1) @@ -5531,14 +5804,21 @@ # loop through columns, adding each to plot self.hold(True) - for i,pos in enumerate(positions): + for i, pos in enumerate(positions): d = np.ravel(x[i]) row = len(d) if row==0: # no data, skip this position continue + # get median and quartiles q1, med, q3 = mlab.prctile(d,[25,50,75]) + + # replace with input medians if available + if usermedians is not None: + if usermedians[i] is not None: + med = usermedians[i] + # get high extreme iq = q3 - q1 hi_val = q3 + whis*iq @@ -5578,42 +5858,16 @@ # get y location for median med_y = [med, med] - # calculate 'regular' plot - if notch == 0: - # make our box vectors - box_x = [box_x_min, box_x_max, box_x_max, box_x_min, box_x_min ] - box_y = [q1, q1, q3, q3, q1 ] - # make our median line vectors - med_x = [box_x_min, box_x_max] # calculate 'notch' plot - else: - if bootstrap is not None: - # Do a bootstrap estimate of notch locations. - def bootstrapMedian(data, N=5000): - # determine 95% confidence intervals of the median - M = len(data) - percentile = [2.5,97.5] - estimate = np.zeros(N) - for n in range(N): - bsIndex = np.random.random_integers(0,M-1,M) - bsData = data[bsIndex] - estimate[n] = mlab.prctile(bsData, 50) - CI = mlab.prctile(estimate, percentile) - return CI - - # get conf. intervals around median - CI = bootstrapMedian(d, N=bootstrap) - notch_max = CI[1] - notch_min = CI[0] + if notch: + # conf. intervals from user, if available + if conf_intervals is not None and conf_intervals[i] is not None: + notch_max = np.max(conf_intervals[i]) + notch_min = np.min(conf_intervals[i]) else: - # Estimate notch locations using Gaussian-based - # asymptotic approximation. - # - # For discussion: McGill, R., Tukey, J.W., - # and Larsen, W.A. (1978) "Variations of - # Boxplots", The American Statistician, 32:12-16. - notch_max = med + 1.57*iq/np.sqrt(row) - notch_min = med - 1.57*iq/np.sqrt(row) + notch_min, notch_max = computeConfInterval(d, med, iq, + bootstrap) + # make our notched box vectors box_x = [box_x_min, box_x_max, box_x_max, cap_x_max, box_x_max, box_x_max, box_x_min, box_x_min, cap_x_min, box_x_min, @@ -5623,6 +5877,13 @@ # make our median line vectors med_x = [cap_x_min, cap_x_max] med_y = [med, med] + # calculate 'regular' plot + else: + # make our box vectors + box_x = [box_x_min, box_x_max, box_x_max, box_x_min, box_x_min ] + box_y = [q1, q1, q3, q3, q1 ] + # make our median line vectors + med_x = [box_x_min, box_x_max] def to_vc(xs,ys): # convert arguments to verts and codes @@ -5672,12 +5933,13 @@ boxes.extend(dopatch(box_x, box_y)) else: boxes.extend(doplot(box_x, box_y, 'b-')) + medians.extend(doplot(med_x, med_y, median_color+'-')) fliers.extend(doplot(flier_hi_x, flier_hi, sym, flier_lo_x, flier_lo, sym)) # fix our axes/ticks up a little - if 1 == vert: + if vert: setticks, setlim = self.set_xticks, self.set_xlim else: setticks, setlim = self.set_yticks, self.set_ylim @@ -5698,6 +5960,8 @@ faceted=True, verts=None, **kwargs): """ + Make a scatter plot. + Call signatures:: scatter(x, y, s=20, c='b', marker='o', cmap=None, norm=None, @@ -5845,7 +6109,7 @@ edgecolors = edgecolors, linewidths = linewidths, offsets = zip(x,y), - transOffset = self.transData, + transOffset = kwargs.pop('transform', self.transData), ) collection.set_transform(mtransforms.IdentityTransform()) collection.set_alpha(alpha) @@ -5886,6 +6150,8 @@ reduce_C_function = np.mean, mincnt=None, marginals=False, **kwargs): """ + Make a hexagonal binning plot. + Call signature:: hexbin(x, y, C = None, gridsize = 100, bins = None, @@ -6149,43 +6415,44 @@ lattice1.astype(float).ravel(), lattice2.astype(float).ravel())) good_idxs = ~np.isnan(accum) - px = xmin + sx * np.array([ 0.5, 0.5, 0.0, -0.5, -0.5, 0.0]) - py = ymin + sy * np.array([-0.5, 0.5, 1.0, 0.5, -0.5, -1.0]) / 3.0 - - polygons = np.zeros((6, n, 2), float) - polygons[:,:nx1*ny1,0] = np.repeat(np.arange(nx1), ny1) - polygons[:,:nx1*ny1,1] = np.tile(np.arange(ny1), nx1) - polygons[:,nx1*ny1:,0] = np.repeat(np.arange(nx2) + 0.5, ny2) - polygons[:,nx1*ny1:,1] = np.tile(np.arange(ny2), nx2) + 0.5 - + offsets = np.zeros((n, 2), float) + offsets[:nx1*ny1,0] = np.repeat(np.arange(nx1), ny1) + offsets[:nx1*ny1,1] = np.tile(np.arange(ny1), nx1) + offsets[nx1*ny1:,0] = np.repeat(np.arange(nx2) + 0.5, ny2) + offsets[nx1*ny1:,1] = np.tile(np.arange(ny2), nx2) + 0.5 + offsets[:,0] *= sx + offsets[:,1] *= sy + offsets[:,0] += xmin + offsets[:,1] += ymin # remove accumulation bins with no data - polygons = polygons[:,good_idxs,:] + offsets = offsets[good_idxs,:] accum = accum[good_idxs] - polygons = np.transpose(polygons, axes=[1,0,2]) - polygons[:,:,0] *= sx - polygons[:,:,1] *= sy - polygons[:,:,0] += px - polygons[:,:,1] += py - if xscale=='log': - polygons[:,:,0] = 10**(polygons[:,:,0]) + offsets[:,0] = 10**(offsets[:,0]) xmin = 10**xmin xmax = 10**xmax self.set_xscale('log') if yscale=='log': - polygons[:,:,1] = 10**(polygons[:,:,1]) + offsets[:,1] = 10**(offsets[:,1]) ymin = 10**ymin ymax = 10**ymax self.set_yscale('log') + polygon = np.zeros((6, 2), float) + polygon[:,0] = sx * np.array([ 0.5, 0.5, 0.0, -0.5, -0.5, 0.0]) + polygon[:,1] = sy * np.array([-0.5, 0.5, 1.0, 0.5, -0.5, -1.0]) / 3.0 + if edgecolors=='none': edgecolors = 'face' + collection = mcoll.PolyCollection( - polygons, + [polygon], edgecolors = edgecolors, linewidths = linewidths, - transOffset = self.transData, + offsets = offsets, + transOffset = mtransforms.IdentityTransform(), + offset_position = "data" ) if isinstance(norm, mcolors.LogNorm): @@ -6321,14 +6588,16 @@ @docstring.dedent_interpd def arrow(self, x, y, dx, dy, **kwargs): """ + Add an arrow to the axes. + Call signature:: arrow(x, y, dx, dy, **kwargs) Draws arrow on specified axis from (*x*, *y*) to (*x* + *dx*, - *y* + *dy*). + *y* + *dy*). Uses FancyArrow patch to construct the arrow. - Optional kwargs control the arrow properties: + Optional kwargs control the arrow construction and properties: %(FancyArrow)s @@ -6362,6 +6631,27 @@ return q quiver.__doc__ = mquiver.Quiver.quiver_doc + def stackplot(self, x, *args, **kwargs): + return mstack.stackplot(self, x, *args, **kwargs) + stackplot.__doc__ = mstack.stackplot.__doc__ + + def streamplot(self, x, y, u, v, density=1, linewidth=None, color=None, + cmap=None, norm=None, arrowsize=1, arrowstyle='-|>', + minlength=0.1, transform=None): + if not self._hold: self.cla() + stream_container = mstream.streamplot(self, x, y, u, v, + density=density, + linewidth=linewidth, + color=color, + cmap=cmap, + norm=norm, + arrowsize=arrowsize, + arrowstyle=arrowstyle, + minlength=minlength, + transform=transform) + return stream_container + streamplot.__doc__ = mstream.streamplot.__doc__ + @docstring.dedent_interpd def barbs(self, *args, **kw): """ @@ -6381,15 +6671,17 @@ @docstring.dedent_interpd def fill(self, *args, **kwargs): """ + Plot filled polygons. + Call signature:: fill(*args, **kwargs) - Plot filled polygons. *args* is a variable length argument, - allowing for multiple *x*, *y* pairs with an optional color - format string; see :func:`~matplotlib.pyplot.plot` for details - on the argument parsing. For example, to plot a polygon with - vertices at *x*, *y* in blue.:: + *args* is a variable length argument, allowing for multiple + *x*, *y* pairs with an optional color format string; see + :func:`~matplotlib.pyplot.plot` for details on the argument + parsing. For example, to plot a polygon with vertices at *x*, + *y* in blue.:: ax.fill(x,y, 'b' ) @@ -6430,6 +6722,8 @@ def fill_between(self, x, y1, y2=0, where=None, interpolate=False, **kwargs): """ + Make filled polygons between two curves. + Call signature:: fill_between(x, y1, y2=0, where=None, **kwargs) @@ -6479,9 +6773,9 @@ self._process_unit_info(ydata=y2) # Convert the arrays so we can work with them - x = np.asanyarray(self.convert_xunits(x)) - y1 = np.asanyarray(self.convert_yunits(y1)) - y2 = np.asanyarray(self.convert_yunits(y2)) + x = ma.masked_invalid(self.convert_xunits(x)) + y1 = ma.masked_invalid(self.convert_yunits(y1)) + y2 = ma.masked_invalid(self.convert_yunits(y2)) if y1.ndim == 0: y1 = np.ones_like(x)*y1 @@ -6496,14 +6790,12 @@ if not (x.shape == y1.shape == y2.shape == where.shape): raise ValueError("Argument dimensions are incompatible") - mask = reduce(ma.mask_or, - [ma.getmask(x), ma.getmask(y1), ma.getmask(y2)]) + mask = reduce(ma.mask_or, [ma.getmask(a) for a in (x, y1, y2)]) if mask is not ma.nomask: where &= ~mask polys = [] for ind0, ind1 in mlab.contiguous_regions(where): - theseverts = [] xslice = x[ind0:ind1] y1slice = y1[ind0:ind1] y2slice = y2[ind0:ind1] @@ -6568,6 +6860,8 @@ @docstring.dedent_interpd def fill_betweenx(self, y, x1, x2=0, where=None, **kwargs): """ + Make filled polygons between two horizontal curves. + Call signature:: fill_between(y, x1, x2=0, where=None, **kwargs) @@ -6611,9 +6905,9 @@ self._process_unit_info(xdata=x2) # Convert the arrays so we can work with them - y = np.asanyarray(self.convert_yunits(y)) - x1 = np.asanyarray(self.convert_xunits(x1)) - x2 = np.asanyarray(self.convert_xunits(x2)) + y = ma.masked_invalid(self.convert_yunits(y)) + x1 = ma.masked_invalid(self.convert_xunits(x1)) + x2 = ma.masked_invalid(self.convert_xunits(x2)) if x1.ndim == 0: x1 = np.ones_like(y)*x1 @@ -6628,14 +6922,12 @@ if not (y.shape == x1.shape == x2.shape == where.shape): raise ValueError("Argument dimensions are incompatible") - mask = reduce(ma.mask_or, - [ma.getmask(y), ma.getmask(x1), ma.getmask(x2)]) + mask = reduce(ma.mask_or, [ma.getmask(a) for a in (y, x1, x2)]) if mask is not ma.nomask: where &= ~mask polys = [] for ind0, ind1 in mlab.contiguous_regions(where): - theseverts = [] yslice = y[ind0:ind1] x1slice = x1[ind0:ind1] x2slice = x2[ind0:ind1] @@ -6681,6 +6973,8 @@ origin=None, extent=None, shape=None, filternorm=1, filterrad=4.0, imlim=None, resample=None, url=None, **kwargs): """ + Display an image on the axes. + Call signature:: imshow(X, cmap=None, norm=None, aspect=None, interpolation=None, @@ -6782,6 +7076,7 @@ **Example:** .. plot:: mpl_examples/pylab_examples/image_demo.py + """ if not self._hold: self.cla() @@ -6830,10 +7125,10 @@ Nx = X.shape[-1] Ny = Y.shape[0] - if len(X.shape) <> 2 or X.shape[0] == 1: + if len(X.shape) != 2 or X.shape[0] == 1: x = X.reshape(1,Nx) X = x.repeat(Ny, axis=0) - if len(Y.shape) <> 2 or Y.shape[1] == 1: + if len(Y.shape) != 2 or Y.shape[1] == 1: y = Y.reshape(Ny, 1) Y = y.repeat(Nx, axis=1) if X.shape != Y.shape: @@ -6845,13 +7140,17 @@ @docstring.dedent_interpd def pcolor(self, *args, **kwargs): """ + Create a pseudocolor plot of a 2-D array. + + Note: pcolor can be very slow for large arrays; consider + using the similar but much faster + :func:`~matplotlib.pyplot.pcolormesh` instead. + Call signatures:: pcolor(C, **kwargs) pcolor(X, Y, C, **kwargs) - Create a pseudocolor plot of a 2-D array. - *C* is the array of color values. *X* and *Y*, if given, specify the (*x*, *y*) coordinates of @@ -6886,16 +7185,18 @@ A :class:`matplotlib.colors.Colormap` instance. If *None*, use rc settings. - norm: [ *None* | Normalize ] + *norm*: [ *None* | Normalize ] An :class:`matplotlib.colors.Normalize` instance is used to scale luminance data to 0,1. If *None*, defaults to :func:`normalize`. *vmin*/*vmax*: [ *None* | scalar ] *vmin* and *vmax* are used in conjunction with *norm* to - normalize luminance data. If either are *None*, the min - and max of the color array *C* is used. If you pass a - *norm* instance, *vmin* and *vmax* will be ignored. + normalize luminance data. If either is *None*, it + is autoscaled to the respective min or max + of the color array *C*. If not *None*, *vmin* or + *vmax* passed in here override any pre-existing values + supplied in the *norm* instance. *shading*: [ 'flat' | 'faceted' ] If 'faceted', a black grid is drawn around each rectangle; if @@ -6975,6 +7276,11 @@ Stroking the edges may be preferred if *alpha* is 1, but will cause artifacts otherwise. + .. seealso:: + + :func:`~matplotlib.pyplot.pcolormesh` + For an explanation of the differences between + pcolor and pcolormesh. """ if not self._hold: self.cla() @@ -7041,8 +7347,9 @@ # makes artifacts that are often disturbing. if 'antialiased' in kwargs: kwargs['antialiaseds'] = kwargs.pop('antialiased') - if 'antialiaseds' not in kwargs and ec.lower() == "none": - kwargs['antialiaseds'] = False + if 'antialiaseds' not in kwargs and (is_string_like(ec) and + ec.lower() == "none"): + kwargs['antialiaseds'] = False collection = mcoll.PolyCollection(verts, **kwargs) @@ -7052,14 +7359,26 @@ if norm is not None: assert(isinstance(norm, mcolors.Normalize)) collection.set_cmap(cmap) collection.set_norm(norm) - if vmin is not None or vmax is not None: - collection.set_clim(vmin, vmax) - else: - collection.autoscale_None() + collection.set_clim(vmin, vmax) + collection.autoscale_None() self.grid(False) x = X.compressed() y = Y.compressed() + + # Transform from native to data coordinates? + t = collection._transform + if (not isinstance(t, mtransforms.Transform) + and hasattr(t, '_as_mpl_transform')): + t = t._as_mpl_transform(self.axes) + + if t and any(t.contains_branch_seperately(self.transData)): + trans_to_data = t - self.transData + pts = np.vstack([x, y]).T.astype(np.float) + transformed_pts = trans_to_data.transform(pts) + x = transformed_pts[..., 0] + y = transformed_pts[..., 1] + minx = np.amin(x) maxx = np.amax(x) miny = np.amin(y) @@ -7074,12 +7393,24 @@ @docstring.dedent_interpd def pcolormesh(self, *args, **kwargs): """ + Plot a quadrilateral mesh. + Call signatures:: pcolormesh(C) pcolormesh(X, Y, C) pcolormesh(C, **kwargs) + Create a pseudocolor plot of a 2-D array. + + pcolormesh is similar to :func:`~matplotlib.pyplot.pcolor`, + but uses a different mechanism and returns a different + object; pcolor returns a + :class:`~matplotlib.collections.PolyCollection` but pcolormesh + returns a + :class:`~matplotlib.collections.QuadMesh`. It is much faster, + so it is almost always preferred for large arrays. + *C* may be a masked array, but *X* and *Y* may not. Masked array support is implemented via *cmap* and *norm*; in contrast, :func:`~matplotlib.pyplot.pcolor` simply does not @@ -7098,24 +7429,24 @@ *vmin*/*vmax*: [ *None* | scalar ] *vmin* and *vmax* are used in conjunction with *norm* to - normalize luminance data. If either are *None*, the min - and max of the color array *C* is used. If you pass a - *norm* instance, *vmin* and *vmax* will be ignored. - - *shading*: [ 'flat' | 'faceted' | 'gouraud' ] - If 'faceted', a black grid is drawn around each rectangle; if - 'flat', edges are not drawn. Default is 'flat', contrary to - MATLAB. - - This kwarg is deprecated; please use 'edgecolors' instead: - * shading='flat' -- edgecolors='None' - * shading='faceted -- edgecolors='k' + normalize luminance data. If either is *None*, it + is autoscaled to the respective min or max + of the color array *C*. If not *None*, *vmin* or + *vmax* passed in here override any pre-existing values + supplied in the *norm* instance. + + *shading*: [ 'flat' | 'gouraud' ] + 'flat' indicates a solid color for each quad. When + 'gouraud', each quad will be Gouraud shaded. When gouraud + shading, edgecolors is ignored. - *edgecolors*: [ *None* | ``'None'`` | color | color sequence] + *edgecolors*: [ *None* | ``'None'`` | ``'face'`` | color | color sequence] If *None*, the rc setting is used by default. If ``'None'``, edges will not be visible. + If ``'face'``, edges will have the same color as the faces. + An mpl color or sequence of colors will set the edge color *alpha*: ``0 <= scalar <= 1`` or *None* @@ -7143,8 +7474,8 @@ vmin = kwargs.pop('vmin', None) vmax = kwargs.pop('vmax', None) shading = kwargs.pop('shading', 'flat').lower() - edgecolors = kwargs.pop('edgecolors', 'None') antialiased = kwargs.pop('antialiased', False) + kwargs.setdefault('edgecolors', 'None') X, Y, C = self._pcolorargs('pcolormesh', *args) Ny, Nx = X.shape @@ -7162,25 +7493,31 @@ coords[:, 0] = X coords[:, 1] = Y - if shading == 'faceted' or edgecolors != 'None': - showedges = 1 - else: - showedges = 0 - collection = mcoll.QuadMesh( - Nx - 1, Ny - 1, coords, showedges, + Nx - 1, Ny - 1, coords, antialiased=antialiased, shading=shading, **kwargs) collection.set_alpha(alpha) collection.set_array(C) if norm is not None: assert(isinstance(norm, mcolors.Normalize)) collection.set_cmap(cmap) collection.set_norm(norm) - if vmin is not None or vmax is not None: - collection.set_clim(vmin, vmax) - else: - collection.autoscale_None() + collection.set_clim(vmin, vmax) + collection.autoscale_None() self.grid(False) + + # Transform from native to data coordinates? + t = collection._transform + if (not isinstance(t, mtransforms.Transform) + and hasattr(t, '_as_mpl_transform')): + t = t._as_mpl_transform(self.axes) + + if t and any(t.contains_branch_seperately(self.transData)): + trans_to_data = t - self.transData + pts = np.vstack([X, Y]).T.astype(np.float) + transformed_pts = trans_to_data.transform(pts) + X = transformed_pts[..., 0] + Y = transformed_pts[..., 1] minx = np.amin(X) maxx = np.amax(X) @@ -7198,23 +7535,25 @@ """ pseudocolor plot of a 2-D array - Experimental; this is a version of pcolor that - does not draw lines, that provides the fastest - possible rendering with the Agg backend, and that - can handle any quadrilateral grid. + Experimental; this is a pcolor-type method that + provides the fastest possible rendering with the Agg + backend, and that can handle any quadrilateral grid. + It supports only flat shading (no outlines), it lacks + support for log scaling of the axes, and it does not + have a pyplot wrapper. Call signatures:: - pcolor(C, **kwargs) - pcolor(xr, yr, C, **kwargs) - pcolor(x, y, C, **kwargs) - pcolor(X, Y, C, **kwargs) + ax.pcolorfast(C, **kwargs) + ax.pcolorfast(xr, yr, C, **kwargs) + ax.pcolorfast(x, y, C, **kwargs) + ax.pcolorfast(X, Y, C, **kwargs) C is the 2D array of color values corresponding to quadrilateral cells. Let (nr, nc) be its shape. C may be a masked array. - ``pcolor(C, **kwargs)`` is equivalent to - ``pcolor([0,nc], [0,nr], C, **kwargs)`` + ``ax.pcolorfast(C, **kwargs)`` is equivalent to + ``ax.pcolorfast([0,nc], [0,nr], C, **kwargs)`` *xr*, *yr* specify the ranges of *x* and *y* corresponding to the rectangular region bounding *C*. If:: @@ -7333,7 +7672,7 @@ # The QuadMesh class can also be changed to # handle relevant superclass kwargs; the initializer # should do much more than it does now. - collection = mcoll.QuadMesh(nc, nr, coords, 0) + collection = mcoll.QuadMesh(nc, nr, coords, 0, edgecolors="None") collection.set_alpha(alpha) collection.set_array(C) collection.set_cmap(cmap) @@ -7394,6 +7733,8 @@ @docstring.dedent_interpd def table(self, **kwargs): """ + Add a table to the current axes. + Call signature:: table(cellText=None, cellColours=None, @@ -7402,11 +7743,10 @@ colLabels=None, colColours=None, colLoc='center', loc='bottom', bbox=None): - Add a table to the current axes. Returns a - :class:`matplotlib.table.Table` instance. For finer grained - control over tables, use the :class:`~matplotlib.table.Table` - class and add it to the axes with - :meth:`~matplotlib.axes.Axes.add_table`. + Returns a :class:`matplotlib.table.Table` instance. For finer + grained control over tables, use the + :class:`~matplotlib.table.Table` class and add it to the axes + with :meth:`~matplotlib.axes.Axes.add_table`. Thanks to John Gill for providing the class and table. @@ -7417,6 +7757,14 @@ """ return mtable.table(self, **kwargs) + def _make_twin_axes(self, *kl, **kwargs): + """ + make a twinx axes of self. This is used for twinx and twiny. + """ + ax2 = self.figure.add_axes(self.get_position(True), *kl, **kwargs) + return ax2 + + def twinx(self): """ Call signature:: @@ -7433,8 +7781,7 @@ events are only called for the artists in the top-most axes. """ - ax2 = self.figure.add_axes(self.get_position(True), sharex=self, - frameon=False) + ax2 = self._make_twin_axes(sharex=self, frameon=False) ax2.yaxis.tick_right() ax2.yaxis.set_label_position('right') ax2.yaxis.set_offset_position('right') @@ -7458,8 +7805,7 @@ events are only called for the artists in the top-most axes. """ - ax2 = self.figure.add_axes(self.get_position(True), sharey=self, - frameon=False) + ax2 = self._make_twin_axes(sharey=self, frameon=False) ax2.xaxis.tick_top() ax2.xaxis.set_label_position('top') self.xaxis.tick_bottom() @@ -7480,15 +7826,17 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, - color=None, label=None, + color=None, label=None, stacked=False, **kwargs): """ + Plot a histogram. + Call signature:: hist(x, bins=10, range=None, normed=False, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, - color=None, label=None, + color=None, label=None, stacked=False, **kwargs) Compute and draw the histogram of *x*. The return value is a @@ -7612,6 +7960,13 @@ ax.hist(12+3*np.random.randn(1000), label='women', alpha=0.5) ax.legend() + *stacked*: + If *True*, multiple data are stacked on top of each other + If *False* multiple data are aranged side by side if + histtype is 'bar' or on top of each other if histtype is 'step' + + . + kwargs are used to update the properties of the :class:`~matplotlib.patches.Patch` instances returned by *hist*: @@ -7624,6 +7979,10 @@ """ if not self._hold: self.cla() + # xrange becomes range after 2to3 + bin_range = range + range = __builtins__["range"] + # NOTE: the range keyword overwrites the built-in func range !!! # needs to be fixed in numpy !!! @@ -7645,6 +8004,9 @@ 'hist now uses the rwidth to give relative width ' 'and not absolute width') + if histtype == 'barstacked' and not stacked: + stacked=True + # Massage 'x' for processing. # NOTE: Be sure any changes here is also done below to 'weights' if isinstance(x, np.ndarray) or not iterable(x[0]): @@ -7709,7 +8071,7 @@ # Check whether bins or range are given explicitly. In that # case use those values for autoscaling. - binsgiven = (cbook.iterable(bins) or range != None) + binsgiven = (cbook.iterable(bins) or bin_range != None) # If bins are not specified either explicitly or via range, # we need to figure out the range required for all datasets, @@ -7720,23 +8082,31 @@ for xi in x: xmin = min(xmin, xi.min()) xmax = max(xmax, xi.max()) - range = (xmin, xmax) + bin_range = (xmin, xmax) #hist_kwargs = dict(range=range, normed=bool(normed)) # We will handle the normed kwarg within mpl until we # get to the point of requiring numpy >= 1.5. - hist_kwargs = dict(range=range) + hist_kwargs = dict(range=bin_range) if np.__version__ < "1.3": # version 1.1 and 1.2 hist_kwargs['new'] = True n = [] - for i in xrange(nx): + mlast = bottom + # reversed order is necessary so when stacking histogram, first dataset is on top + # if histogram isn't stacked, this doesn't make any difference + for i in reversed(xrange(nx)): # this will automatically overwrite bins, # so that each histogram uses the same bins m, bins = np.histogram(x[i], bins, weights=w[i], **hist_kwargs) + if mlast is None: + mlast = np.zeros(len(bins)-1, m.dtype) if normed: db = np.diff(bins) m = (m.astype(float) / db) / m.sum() + if stacked: + m += mlast + mlast[:] = m n.append(m) if cumulative: @@ -7749,6 +8119,8 @@ else: n = [m[slc].cumsum()[slc] for m in n] + n.reverse() # put them back in the right order + patches = [] if histtype.startswith('bar'): @@ -7761,7 +8133,7 @@ else: dr = 1.0 - if histtype=='bar': + if histtype=='bar' and not stacked: width = dr*totwidth/nx dw = width @@ -7770,10 +8142,9 @@ else: boffset = 0.0 stacked = False - elif histtype=='barstacked': + elif histtype=='barstacked' or stacked: width = dr*totwidth boffset, dw = 0.0, 0.0 - stacked = True if align == 'mid' or align == 'edge': boffset += 0.5*totwidth @@ -7786,14 +8157,10 @@ _barfunc = self.bar for m, c in zip(n, color): - patch = _barfunc(bins[:-1]+boffset, m, width, bottom, + patch = _barfunc(bins[:-1]+boffset, m, width, align='center', log=log, color=c) patches.append(patch) - if stacked: - if bottom is None: - bottom = 0.0 - bottom += m boffset += dw elif histtype.startswith('step'): @@ -7802,7 +8169,7 @@ x[0::2], x[1::2] = bins, bins - minimum = min(bins) + minimum = np.min(n) if align == 'left' or align == 'center': x -= 0.5*(bins[1]-bins[0]) @@ -7816,6 +8183,8 @@ else: # orientation == 'vertical' self.set_yscale('log') + # If fill kwarg is set, it will be passed to the patch collection, + # overriding this fill = (histtype == 'stepfilled') for m, c in zip(n, color): @@ -7889,11 +8258,99 @@ else: return n, bins, cbook.silent_list('Lists of Patches', patches) + + @docstring.dedent_interpd + def hist2d(self, x, y, bins = 10, range=None, normed=False, weights=None, + cmin=None, cmax=None, **kwargs): + """ + Make a 2D histogram plot. + + Call signature:: + + hist2d(x, y, bins = None, range=None, weights=None, cmin=None, cmax=None **kwargs) + + Make a 2d histogram plot of *x* versus *y*, where *x*, + *y* are 1-D sequences of the same length. + + The return value is ``(counts, xedges, yedges, Image)``. + + Optional keyword arguments: + *bins*: [None | int | [int, int] | array_like | [array, array]] + + The bin specification: + + - If int, the number of bins for the two dimensions + (nx=ny=bins). + + - If [int, int], the number of bins in each dimension + (nx, ny = bins). + + - If array_like, the bin edges for the two dimensions + (x_edges=y_edges=bins). + + - If [array, array], the bin edges in each dimension + (x_edges, y_edges = bins). + + The default value is 10. + + *range*: [*None* | array_like shape(2,2)] + The leftmost and rightmost edges of the bins along each + dimension (if not specified explicitly in the bins + parameters): [[xmin, xmax], [ymin, ymax]]. All values + outside of this range will be considered outliers and not + tallied in the histogram. + + *normed*:[True|False] + Normalize histogram. + The default value is False + + *weights*: [*None* | array] + An array of values w_i weighing each sample (x_i, y_i). + + *cmin* : [None| scalar] + All bins that has count less than cmin will not be + displayed and these count values in the return value + count histogram will also be set to nan upon return + + *cmax* : [None| scalar] + All bins that has count more than cmax will not be + displayed (set to none before passing to imshow) and + these count values in the return value count histogram + will also be set to nan upon return + + Remaining keyword arguments are passed directly to :meth:`pcolorfast`. + + Rendering the histogram with a logarithmic color scale is + accomplished by passing a :class:`colors.LogNorm` instance to + the *norm* keyword argument. + + **Example:** + + .. plot:: mpl_examples/pylab_examples/hist2d_demo.py + """ + + # xrange becomes range after 2to3 + bin_range = range + range = __builtins__["range"] + h,xedges,yedges = np.histogram2d(x, y, bins=bins, range=bin_range, + normed=normed, weights=weights) + + if cmin is not None: h[hcmax]=None + + pc = self.pcolorfast(xedges,yedges,h.T,**kwargs) + self.set_xlim(xedges[0],xedges[-1]) + self.set_ylim(yedges[0],yedges[-1]) + + return h,xedges,yedges,pc + @docstring.dedent_interpd def psd(self, x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, window=mlab.window_hanning, noverlap=0, pad_to=None, sides='default', scale_by_freq=None, **kwargs): """ + Plot the power spectral density. + Call signature:: psd(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, @@ -7911,6 +8368,10 @@ %(PSD)s + *noverlap*: integer + The number of points of overlap between blocks. The default value + is 0 (no overlap). + *Fc*: integer The center frequency of *x* (defaults to 0), which offsets the x extents of the plot to reflect the frequency range used @@ -7966,6 +8427,8 @@ window=mlab.window_hanning, noverlap=0, pad_to=None, sides='default', scale_by_freq=None, **kwargs): """ + Plot cross-spectral density. + Call signature:: csd(x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, @@ -7986,6 +8449,10 @@ %(PSD)s + *noverlap*: integer + The number of points of overlap between blocks. The + default value is 0 (no overlap). + *Fc*: integer The center frequency of *x* (defaults to 0), which offsets the x extents of the plot to reflect the frequency range used @@ -8035,14 +8502,16 @@ window=mlab.window_hanning, noverlap=0, pad_to=None, sides='default', scale_by_freq=None, **kwargs): """ + Plot the coherence between *x* and *y*. + Call signature:: cohere(x, y, NFFT=256, Fs=2, Fc=0, detrend = mlab.detrend_none, window = mlab.window_hanning, noverlap=0, pad_to=None, sides='default', scale_by_freq=None, **kwargs) - :meth:`cohere` the coherence between *x* and *y*. Coherence - is the normalized cross spectral density: + Plot the coherence between *x* and *y*. Coherence is the + normalized cross spectral density: .. math:: @@ -8050,6 +8519,10 @@ %(PSD)s + *noverlap*: integer + The number of points of overlap between blocks. The + default value is 0 (no overlap). + *Fc*: integer The center frequency of *x* (defaults to 0), which offsets the x extents of the plot to reflect the frequency range used @@ -8093,6 +8566,8 @@ cmap=None, xextent=None, pad_to=None, sides='default', scale_by_freq=None, **kwargs): """ + Plot a spectrogram. + Call signature:: specgram(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, @@ -8108,6 +8583,10 @@ %(PSD)s + *noverlap*: integer + The number of points of overlap between blocks. The + default value is 128. + *Fc*: integer The center frequency of *x* (defaults to 0), which offsets the y extents of the plot to reflect the frequency range used @@ -8132,7 +8611,7 @@ - *bins* are the time points the spectrogram is calculated over - *freqs* is an array of frequencies - - *Pxx* is a len(times) x len(freqs) array of power + - *Pxx* is an array of shape `(len(times), len(freqs))` of power - *im* is a :class:`~matplotlib.image.AxesImage` instance Note: If *x* is real (i.e. non-complex), only the positive @@ -8164,6 +8643,8 @@ def spy(self, Z, precision=0, marker=None, markersize=None, aspect='equal', **kwargs): """ + Plot the sparsity pattern on a 2-D array. + Call signature:: spy(Z, precision=0, marker=None, markersize=None, @@ -8456,7 +8937,15 @@ # _axes_class is set in the subplot_class_factory self._axes_class.__init__(self, fig, self.figbox, **kwargs) - + def __reduce__(self): + # get the first axes class which does not inherit from a subplotbase + not_subplotbase = lambda c: issubclass(c, Axes) and \ + not issubclass(c, SubplotBase) + axes_class = [c for c in self.__class__.mro() if not_subplotbase(c)][0] + r = [_PicklableSubplotClassConstructor(), + (axes_class,), + self.__getstate__()] + return tuple(r) def get_geometry(self): """get the subplot geometry, eg 2,2,3""" @@ -8515,6 +9004,13 @@ label.set_visible(firstcol) + def _make_twin_axes(self, *kl, **kwargs): + """ + make a twinx axes of self. This is used for twinx and twiny. + """ + ax2 = self.figure.add_subplot(self.get_subplotspec(), *kl, **kwargs) + return ax2 + _subplot_classes = {} def subplot_class_factory(axes_class=None): @@ -8528,9 +9024,9 @@ new_class = _subplot_classes.get(axes_class) if new_class is None: - new_class = new.classobj("%sSubplot" % (axes_class.__name__), - (SubplotBase, axes_class), - {'_axes_class': axes_class}) + new_class = type("%sSubplot" % (axes_class.__name__), + (SubplotBase, axes_class), + {'_axes_class': axes_class}) _subplot_classes[axes_class] = new_class return new_class @@ -8538,6 +9034,22 @@ # This is provided for backward compatibility Subplot = subplot_class_factory() + +class _PicklableSubplotClassConstructor(object): + """ + This stub class exists to return the appropriate subplot + class when __call__-ed with an axes class. This is purely to + allow Pickling of Axes and Subplots. + """ + def __call__(self, axes_class): + # create a dummy object instance + subplot_instance = _PicklableSubplotClassConstructor() + subplot_class = subplot_class_factory(axes_class) + # update the class to the desired subplot class + subplot_instance.__class__ = subplot_class + return subplot_instance + + docstring.interpd.update(Axes=martist.kwdoc(Axes)) docstring.interpd.update(Subplot=martist.kwdoc(Axes)) diff -Nru matplotlib-1.1.1/lib/matplotlib/axis.py matplotlib-1.2.0/lib/matplotlib/axis.py --- matplotlib-1.1.1/lib/matplotlib/axis.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/axis.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,7 @@ """ Classes for the ticks and x and y axis """ -from __future__ import division +from __future__ import division, print_function from matplotlib import rcParams import matplotlib.artist as artist @@ -19,6 +19,7 @@ GRIDLINE_INTERPOLATION_STEPS = 180 + class Tick(artist.Artist): """ Abstract base class for the axis ticks, grid lines and labels @@ -60,22 +61,20 @@ """ def __init__(self, axes, loc, label, - - size = None, # points - width = None, - color = None, - tickdir = None, - pad = None, - labelsize = None, - labelcolor = None, - zorder = None, - - gridOn = None, # defaults to axes.grid - tick1On = True, - tick2On = True, - label1On = True, - label2On = False, - major = True, + size=None, # points + width=None, + color=None, + tickdir=None, + pad=None, + labelsize=None, + labelcolor=None, + zorder=None, + gridOn=None, # defaults to axes.grid + tick1On=True, + tick2On=True, + label1On=True, + label2On=False, + major=True, ): """ bbox is the Bound2D bounding box in display coords of the Axes @@ -97,16 +96,16 @@ if size is None: if major: - size = rcParams['%s.major.size'%name] + size = rcParams['%s.major.size' % name] else: - size = rcParams['%s.minor.size'%name] + size = rcParams['%s.minor.size' % name] self._size = size if width is None: if major: - width = rcParams['%s.major.width'%name] + width = rcParams['%s.major.width' % name] else: - width = rcParams['%s.minor.width'%name] + width = rcParams['%s.minor.width' % name] self._width = width if color is None: @@ -115,9 +114,9 @@ if pad is None: if major: - pad = rcParams['%s.major.pad'%name] + pad = rcParams['%s.major.pad' % name] else: - pad = rcParams['%s.minor.pad'%name] + pad = rcParams['%s.minor.pad' % name] self._base_pad = pad if labelcolor is None: @@ -159,9 +158,9 @@ """ pass - def get_children(self): - children = [self.tick1line, self.tick2line, self.gridline, self.label1, self.label2] + children = [self.tick1line, self.tick2line, + self.gridline, self.label1, self.label2] return children def set_clip_path(self, clippath, transform=None): @@ -181,8 +180,9 @@ This function always returns false. It is more useful to test if the axis as a whole contains the mouse rather than the set of tick marks. """ - if callable(self._contains): return self._contains(self,mouseevent) - return False,{} + if callable(self._contains): + return self._contains(self, mouseevent) + return False, {} def set_pad(self, val): """ @@ -216,16 +216,17 @@ 'Get the default grid Line2d instance for this tick' pass - def get_loc(self): 'Return the tick location (data coords) as a scalar' return self._loc @allow_rasterization def draw(self, renderer): - if not self.get_visible(): return + if not self.get_visible(): + return renderer.open_group(self.__name__) - midPoint = mtransforms.interval_contains(self.get_view_interval(), self.get_loc()) + midPoint = mtransforms.interval_contains(self.get_view_interval(), + self.get_loc()) if midPoint: if self.gridOn: @@ -282,31 +283,31 @@ self.label2.set_transform(trans) self.tick1line.set_marker(self._tickmarkers[0]) self.tick2line.set_marker(self._tickmarkers[1]) - tick_kw = dict([kv for kv in kw.items() - if kv[0] in ['color', 'zorder']]) + tick_kw = dict([kv for kv in kw.iteritems() + if kv[0] in ['color', 'zorder']]) if tick_kw: self.tick1line.set(**tick_kw) self.tick2line.set(**tick_kw) - for k, v in tick_kw.items(): - setattr(self, '_'+k, v) - tick_list = [kv for kv in kw.items() if kv[0] in ['size', 'width']] + for k, v in tick_kw.iteritems(): + setattr(self, '_' + k, v) + tick_list = [kv for kv + in kw.iteritems() if kv[0] in ['size', 'width']] for k, v in tick_list: - setattr(self, '_'+k, v) + setattr(self, '_' + k, v) if k == 'size': self.tick1line.set_markersize(v) self.tick2line.set_markersize(v) else: self.tick1line.set_markeredgewidth(v) self.tick2line.set_markeredgewidth(v) - label_list = [k for k in kw.items() - if k[0] in ['labelsize', 'labelcolor']] + label_list = [k for k in kw.iteritems() + if k[0] in ['labelsize', 'labelcolor']] if label_list: label_kw = dict([(k[5:], v) for (k, v) in label_list]) self.label1.set(**label_kw) self.label2.set(**label_kw) - for k, v in label_kw.items(): - setattr(self, '_'+k, v) - + for k, v in label_kw.iteritems(): + setattr(self, '_' + k, v) class XTick(Tick): @@ -330,11 +331,13 @@ if self._tickdir == 'in': self._tickmarkers = (mlines.TICKUP, mlines.TICKDOWN) self._pad = self._base_pad + elif self._tickdir == 'inout': + self._tickmarkers = ('|', '|') + self._pad = self._base_pad + self._size / 2. else: self._tickmarkers = (mlines.TICKDOWN, mlines.TICKUP) self._pad = self._base_pad + self._size - def _get_text1(self): 'Get the default Text instance' # the y loc is 3 points below the min of y axis @@ -353,7 +356,6 @@ self._set_artist_props(t) return t - def _get_text2(self): 'Get the default Text 2 instance' @@ -376,8 +378,8 @@ # x in data coords, y in axes coords l = mlines.Line2D(xdata=(0,), ydata=(0,), color=self._color, - linestyle = 'None', - marker = self._tickmarkers[0], + linestyle='None', + marker=self._tickmarkers[0], markersize=self._size, markeredgewidth=self._width, zorder=self._zorder, @@ -389,10 +391,10 @@ def _get_tick2line(self): 'Get the default line2D instance' # x in data coords, y in axes coords - l = mlines.Line2D( xdata=(0,), ydata=(1,), + l = mlines.Line2D(xdata=(0,), ydata=(1,), color=self._color, - linestyle = 'None', - marker = self._tickmarkers[1], + linestyle='None', + marker=self._tickmarkers[1], markersize=self._size, markeredgewidth=self._width, zorder=self._zorder, @@ -409,6 +411,7 @@ color=rcParams['grid.color'], linestyle=rcParams['grid.linestyle'], linewidth=rcParams['grid.linewidth'], + alpha=rcParams['grid.alpha'], ) l.set_transform(self.axes.get_xaxis_transform(which='grid')) l.get_path()._interpolation_steps = GRIDLINE_INTERPOLATION_STEPS @@ -469,11 +472,13 @@ if self._tickdir == 'in': self._tickmarkers = (mlines.TICKRIGHT, mlines.TICKLEFT) self._pad = self._base_pad + elif self._tickdir == 'inout': + self._tickmarkers = ('_', '_') + self._pad = self._base_pad + self._size / 2. else: self._tickmarkers = (mlines.TICKLEFT, mlines.TICKRIGHT) self._pad = self._base_pad + self._size - # how far from the y axis line the right of the ticklabel are def _get_text1(self): 'Get the default Text instance' @@ -510,10 +515,10 @@ 'Get the default line2D instance' # x in axes coords, y in data coords - l = mlines.Line2D( (0,), (0,), + l = mlines.Line2D((0,), (0,), color=self._color, - marker = self._tickmarkers[0], - linestyle = 'None', + marker=self._tickmarkers[0], + linestyle='None', markersize=self._size, markeredgewidth=self._width, zorder=self._zorder, @@ -525,10 +530,10 @@ def _get_tick2line(self): 'Get the default line2D instance' # x in axes coords, y in data coords - l = mlines.Line2D( (1,), (0,), + l = mlines.Line2D((1,), (0,), color=self._color, - marker = self._tickmarkers[1], - linestyle = 'None', + marker=self._tickmarkers[1], + linestyle='None', markersize=self._size, markeredgewidth=self._width, zorder=self._zorder, @@ -540,10 +545,11 @@ def _get_gridline(self): 'Get the default line2D instance' # x in axes coords, y in data coords - l = mlines.Line2D( xdata=(0,1), ydata=(0, 0), + l = mlines.Line2D(xdata=(0, 1), ydata=(0, 0), color=rcParams['grid.color'], linestyle=rcParams['grid.linestyle'], linewidth=rcParams['grid.linewidth'], + alpha=rcParams['grid.alpha'], ) l.set_transform(self.axes.get_yaxis_transform(which='grid')) @@ -551,7 +557,6 @@ self._set_artist_props(l) return l - def update_position(self, loc): 'Set the location of tick in data coords with scalar loc' y = loc @@ -568,9 +573,9 @@ if self.gridOn: self.gridline.set_ydata((y, )) if self.label1On: - self.label1.set_y( y ) + self.label1.set_y(y) if self.label2On: - self.label2.set_y( y ) + self.label2.set_y(y) if nonlinear: self.tick1line._invalid = True self.tick2line._invalid = True @@ -578,7 +583,6 @@ self._loc = loc - def get_view_interval(self): 'return the Interval instance for this axis view limits' return self.axes.viewLim.intervaly @@ -589,9 +593,7 @@ formatter = None - class Axis(artist.Artist): - """ Public attributes @@ -603,7 +605,7 @@ def __str__(self): return self.__class__.__name__ \ - + "(%f,%f)"%tuple(self.axes.transAxes.transform_point((0,0))) + + "(%f,%f)" % tuple(self.axes.transAxes.transform_point((0, 0))) def __init__(self, axes, pickradius=15): """ @@ -649,7 +651,6 @@ self.cla() self.set_scale('linear') - def set_label_coords(self, x, y, transform=None): """ Set the coordinates of the label. By default, the x @@ -767,10 +768,10 @@ self.reset_ticks() else: if which == 'major' or which == 'both': - for tick in self.majorTicks: + for tick in self.majorTicks: tick._apply_params(**self._major_tick_kw) if which == 'minor' or which == 'both': - for tick in self.minorTicks: + for tick in self.minorTicks: tick._apply_params(**self._minor_tick_kw) @staticmethod @@ -834,8 +835,6 @@ def set_clip_path(self, clippath, transform=None): artist.Artist.set_clip_path(self, clippath, transform) - majorticks = self.get_major_ticks() - minorticks = self.get_minor_ticks() for child in self.majorTicks + self.minorTicks: child.set_clip_path(clippath, transform) @@ -851,11 +850,12 @@ raise NotImplementedError('Derived must override') def set_data_interval(self): - 'set the axis data limits' + '''set the axis data limits''' raise NotImplementedError('Derived must override') def set_default_intervals(self): - 'set the default limits for the axis data and view interval if they are not mutated' + '''set the default limits for the axis data and view interval if they + are not mutated''' # this is mainly in support of custom object plotting. For # example, if someone passes in a datetime object, we do not @@ -868,7 +868,8 @@ pass def _set_artist_props(self, a): - if a is None: return + if a is None: + return a.set_figure(self.figure) def iter_ticks(self): @@ -878,12 +879,14 @@ majorLocs = self.major.locator() majorTicks = self.get_major_ticks(len(majorLocs)) self.major.formatter.set_locs(majorLocs) - majorLabels = [self.major.formatter(val, i) for i, val in enumerate(majorLocs)] + majorLabels = [self.major.formatter(val, i) + for i, val in enumerate(majorLocs)] minorLocs = self.minor.locator() minorTicks = self.get_minor_ticks(len(minorLocs)) self.minor.formatter.set_locs(minorLocs) - minorLabels = [self.minor.formatter(val, i) for i, val in enumerate(minorLocs)] + minorLabels = [self.minor.formatter(val, i) + for i, val in enumerate(minorLocs)] major_minor = [ (majorTicks, majorLocs, majorLabels), @@ -900,7 +903,8 @@ """ ticks_to_draw = self._update_ticks(renderer) - ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(ticks_to_draw, renderer) + ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(ticks_to_draw, + renderer) if len(ticklabelBoxes): bbox = mtransforms.Bbox.union(ticklabelBoxes) @@ -912,7 +916,7 @@ bbox2 = mtransforms.Bbox.from_extents(0, 0, 0, 0) return bbox, bbox2 - def set_smart_bounds(self,value): + def set_smart_bounds(self, value): """set the axis to have smart bounds""" self._smart_bounds = value @@ -928,7 +932,7 @@ """ interval = self.get_view_interval() - tick_tups = [ t for t in self.iter_ticks()] + tick_tups = [t for t in self.iter_ticks()] if self._smart_bounds: # handle inverted limits view_low, view_high = min(*interval), max(*interval) @@ -965,13 +969,15 @@ else: # No ticks (why not?), take last tick ihigh = locs[-1] - tick_tups = [ ti for ti in tick_tups - if (ti[1] >= ilow) and (ti[1] <= ihigh)] + tick_tups = [ti for ti in tick_tups + if (ti[1] >= ilow) and (ti[1] <= ihigh)] ticks_to_draw = [] for tick, loc, label in tick_tups: - if tick is None: continue - if not mtransforms.interval_contains(interval, loc): continue + if tick is None: + continue + if not mtransforms.interval_contains(interval, loc): + continue tick.update_position(loc) tick.set_label1(label) tick.set_label2(label) @@ -1002,16 +1008,17 @@ Return a bounding box that encloses the axis. It only accounts tick labels, axis label, and offsetText. """ - if not self.get_visible(): return + if not self.get_visible(): + return ticks_to_draw = self._update_ticks(renderer) - ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(ticks_to_draw, renderer) + ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(ticks_to_draw, + renderer) self._update_label_position(ticklabelBoxes, ticklabelBoxes2) self._update_offset_text_position(ticklabelBoxes, ticklabelBoxes2) - self.offsetText.set_text( self.major.formatter.get_offset() ) - + self.offsetText.set_text(self.major.formatter.get_offset()) bb = [] @@ -1023,23 +1030,24 @@ bb.extend(ticklabelBoxes2) #self.offsetText - bb = [b for b in bb if b.width!=0 or b.height!=0] + bb = [b for b in bb if b.width != 0 or b.height != 0] if bb: _bbox = mtransforms.Bbox.union(bb) return _bbox else: return None - @allow_rasterization def draw(self, renderer, *args, **kwargs): 'Draw the axis lines, grid lines, tick lines and labels' - if not self.get_visible(): return + if not self.get_visible(): + return renderer.open_group(__name__) ticks_to_draw = self._update_ticks(renderer) - ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(ticks_to_draw, renderer) + ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(ticks_to_draw, + renderer) for tick in ticks_to_draw: tick.draw(renderer) @@ -1054,11 +1062,11 @@ self.label.draw(renderer) self._update_offset_text_position(ticklabelBoxes, ticklabelBoxes2) - self.offsetText.set_text( self.major.formatter.get_offset() ) + self.offsetText.set_text(self.major.formatter.get_offset()) self.offsetText.draw(renderer) - if 0: # draw the bounding boxes around the text for debug - for tick in majorTicks: + if 0: # draw the bounding boxes around the text for debug + for tick in self.majorTicks: label = tick.label1 mpatches.bbox_artist(label, renderer) mpatches.bbox_artist(self.label, renderer) @@ -1074,7 +1082,8 @@ def get_gridlines(self): 'Return the grid lines as a list of Line2D instance' ticks = self.get_major_ticks() - return cbook.silent_list('Line2D gridline', [tick.gridline for tick in ticks]) + return cbook.silent_list('Line2D gridline', + [tick.gridline for tick in ticks]) def get_label(self): 'Return the axis label as a Text instance' @@ -1093,14 +1102,14 @@ ticks = self.get_major_ticks() labels1 = [tick.label1 for tick in ticks if tick.label1On] labels2 = [tick.label2 for tick in ticks if tick.label2On] - return cbook.silent_list('Text major ticklabel', labels1+labels2) + return cbook.silent_list('Text major ticklabel', labels1 + labels2) def get_minorticklabels(self): 'Return a list of Text instances for the minor ticklabels' ticks = self.get_minor_ticks() labels1 = [tick.label1 for tick in ticks if tick.label1On] labels2 = [tick.label2 for tick in ticks if tick.label2On] - return cbook.silent_list('Text minor ticklabel', labels1+labels2) + return cbook.silent_list('Text minor ticklabel', labels1 + labels2) def get_ticklabels(self, minor=False): 'Return a list of Text instances for ticklabels' @@ -1152,7 +1161,8 @@ def _copy_tick_props(self, src, dest): 'Copy the props from src tick to dest tick' - if src is None or dest is None: return + if src is None or dest is None: + return dest.label1.update_from(src.label1) dest.label2.update_from(src.label2) @@ -1199,7 +1209,8 @@ protoTick = self.majorTicks[0] for i in range(self._lastNumMajorTicks, len(self.majorTicks)): tick = self.majorTicks[i] - if self._gridOnMajor: tick.gridOn = True + if self._gridOnMajor: + tick.gridOn = True self._copy_tick_props(protoTick, tick) self._lastNumMajorTicks = numticks @@ -1207,7 +1218,6 @@ return ticks - def get_minor_ticks(self, numticks=None): 'get the minor tick instances; grow as necessary' if numticks is None: @@ -1223,7 +1233,8 @@ protoTick = self.minorTicks[0] for i in range(self._lastNumMinorTicks, len(self.minorTicks)): tick = self.minorTicks[i] - if self._gridOnMinor: tick.gridOn = True + if self._gridOnMinor: + tick.gridOn = True self._copy_tick_props(protoTick, tick) self._lastNumMinorTicks = numticks @@ -1231,7 +1242,6 @@ return ticks - def grid(self, b=None, which='major', **kwargs): """ Set the axis grid on or off; b is a boolean. Use *which* = @@ -1245,7 +1255,8 @@ xax.grid(color='r', linestyle='-', linewidth=2) """ - if len(kwargs): b = True + if len(kwargs): + b = True which = which.lower() if which in ['minor', 'both']: if b is None: @@ -1253,9 +1264,11 @@ else: self._gridOnMinor = b for tick in self.minorTicks: # don't use get_ticks here! - if tick is None: continue + if tick is None: + continue tick.gridOn = self._gridOnMinor - if len(kwargs): artist.setp(tick.gridline,**kwargs) + if len(kwargs): + artist.setp(tick.gridline, **kwargs) self._minor_tick_kw['gridOn'] = self._gridOnMinor if which in ['major', 'both']: if b is None: @@ -1263,9 +1276,11 @@ else: self._gridOnMajor = b for tick in self.majorTicks: # don't use get_ticks here! - if tick is None: continue + if tick is None: + continue tick.gridOn = self._gridOnMajor - if len(kwargs): artist.setp(tick.gridline,**kwargs) + if len(kwargs): + artist.setp(tick.gridline, **kwargs) self._major_tick_kw['gridOn'] = self._gridOnMajor def update_units(self, data): @@ -1279,7 +1294,7 @@ if converter is None: return False - neednew = self.converter!=converter + neednew = self.converter != converter self.converter = converter default = self.converter.default_units(data, self) #print 'update units: default=%s, units=%s'%(default, self.units) @@ -1302,16 +1317,20 @@ info = self.converter.axisinfo(self.units, self) if info is None: return - if info.majloc is not None and self.major.locator!=info.majloc and self.isDefault_majloc: + if info.majloc is not None and \ + self.major.locator != info.majloc and self.isDefault_majloc: self.set_major_locator(info.majloc) self.isDefault_majloc = True - if info.minloc is not None and self.minor.locator!=info.minloc and self.isDefault_minloc: + if info.minloc is not None and \ + self.minor.locator != info.minloc and self.isDefault_minloc: self.set_minor_locator(info.minloc) self.isDefault_minloc = True - if info.majfmt is not None and self.major.formatter!=info.majfmt and self.isDefault_majfmt: + if info.majfmt is not None and \ + self.major.formatter != info.majfmt and self.isDefault_majfmt: self.set_major_formatter(info.majfmt) self.isDefault_majfmt = True - if info.minfmt is not None and self.minor.formatter!=info.minfmt and self.isDefault_minfmt: + if info.minfmt is not None and \ + self.minor.formatter != info.minfmt and self.isDefault_minfmt: self.set_minor_formatter(info.minfmt) self.isDefault_minfmt = True if info.label is not None and self.isDefault_label: @@ -1328,11 +1347,9 @@ self.converter = munits.registry.get_converter(x) if self.converter is None: - #print 'convert_units returning identity: units=%s, converter=%s'%(self.units, self.converter) return x - ret = self.converter.convert(x, self.units, self) - #print 'convert_units converting: axis=%s, units=%s, converter=%s, in=%s, out=%s'%(self, self.units, self.converter, x, ret) + ret = self.converter.convert(x, self.units, self) return ret def set_units(self, u): @@ -1346,9 +1363,8 @@ self.units = None pchanged = True else: - if u!=self.units: + if u != self.units: self.units = u - #print 'setting units', self.converter, u, munits.registry.get_converter(u) pchanged = True if pchanged: self._update_axisinfo() @@ -1359,14 +1375,15 @@ 'return the units for axis' return self.units - def set_label_text(self, label, fontdict = None, **kwargs): + def set_label_text(self, label, fontdict=None, **kwargs): """ Sets the text value of the axis label ACCEPTS: A string value for the label """ self.isDefault_label = False self.label.set_text(label) - if fontdict is not None: self.label.update(fontdict) + if fontdict is not None: + self.label.update(fontdict) self.label.update(kwargs) return self.label @@ -1380,7 +1397,6 @@ self.major.formatter = formatter formatter.set_axis(self) - def set_minor_formatter(self, formatter): """ Set the formatter of the minor ticker @@ -1391,7 +1407,6 @@ self.minor.formatter = formatter formatter.set_axis(self) - def set_major_locator(self, locator): """ Set the locator of the major ticker @@ -1402,7 +1417,6 @@ self.major.locator = locator locator.set_axis(self) - def set_minor_locator(self, locator): """ Set the locator of the minor ticker @@ -1421,7 +1435,6 @@ """ self.pickradius = pickradius - def set_ticklabels(self, ticklabels, *args, **kwargs): """ Set the text values of the tick labels. Return a list of Text @@ -1451,7 +1464,7 @@ ret1 = [] ret2 = [] for i, tick in enumerate(ticks): - if i0 zoom in, else zoom out" self.major.locator.zoom(direction) - def axis_date(self, tz=None): """ Sets up x-axis ticks and labels that treat the x data as dates. @@ -1520,29 +1532,30 @@ if isinstance(tz, (str, unicode)): import pytz tz = pytz.timezone(tz) - self.update_units(datetime.datetime(2009,1,1,0,0,0,0,tz)) + self.update_units(datetime.datetime(2009, 1, 1, 0, 0, 0, 0, tz)) class XAxis(Axis): __name__ = 'xaxis' axis_name = 'x' - def contains(self,mouseevent): + def contains(self, mouseevent): """Test whether the mouse event occured in the x axis. """ - if callable(self._contains): return self._contains(self,mouseevent) + if callable(self._contains): + return self._contains(self, mouseevent) - x,y = mouseevent.x,mouseevent.y + x, y = mouseevent.x, mouseevent.y try: trans = self.axes.transAxes.inverted() - xaxes,yaxes = trans.transform_point((x,y)) + xaxes, yaxes = trans.transform_point((x, y)) except ValueError: return False, {} - l,b = self.axes.transAxes.transform_point((0,0)) - r,t = self.axes.transAxes.transform_point((1,1)) - inaxis = xaxes>=0 and xaxes<=1 and ( - (yb-self.pickradius) or - (y>t and y= 0 and xaxes <= 1 and ( + (y < b and y > b - self.pickradius) or + (y > t and y < t + self.pickradius)) return inaxis, {} def _get_tick(self, major): @@ -1556,34 +1569,34 @@ # x in axes coords, y in display coords (to be updated at draw # time by _update_label_positions) label = mtext.Text(x=0.5, y=0, - fontproperties = font_manager.FontProperties( + fontproperties=font_manager.FontProperties( size=rcParams['axes.labelsize'], weight=rcParams['axes.labelweight']), - color = rcParams['axes.labelcolor'], + color=rcParams['axes.labelcolor'], verticalalignment='top', horizontalalignment='center', ) - label.set_transform( mtransforms.blended_transform_factory( - self.axes.transAxes, mtransforms.IdentityTransform() )) + label.set_transform(mtransforms.blended_transform_factory( + self.axes.transAxes, mtransforms.IdentityTransform())) self._set_artist_props(label) - self.label_position='bottom' + self.label_position = 'bottom' return label def _get_offset_text(self): # x in axes coords, y in display coords (to be updated at draw time) offsetText = mtext.Text(x=1, y=0, - fontproperties = font_manager.FontProperties( + fontproperties=font_manager.FontProperties( size=rcParams['xtick.labelsize']), - color = rcParams['xtick.color'], + color=rcParams['xtick.color'], verticalalignment='top', horizontalalignment='right', ) - offsetText.set_transform( mtransforms.blended_transform_factory( - self.axes.transAxes, mtransforms.IdentityTransform() )) + offsetText.set_transform(mtransforms.blended_transform_factory( + self.axes.transAxes, mtransforms.IdentityTransform())) self._set_artist_props(offsetText) - self.offset_text_position='bottom' + self.offset_text_position = 'bottom' return offsetText def get_label_position(self): @@ -1603,22 +1616,25 @@ self.label.set_verticalalignment('baseline') else: self.label.set_verticalalignment('top') - self.label_position=position + self.label_position = position def _update_label_position(self, bboxes, bboxes2): """ Update the label position based on the sequence of bounding boxes of all the ticklabels """ - if not self._autolabelpos: return - x,y = self.label.get_position() + if not self._autolabelpos: + return + x, y = self.label.get_position() if self.label_position == 'bottom': if not len(bboxes): bottom = self.axes.bbox.ymin else: bbox = mtransforms.Bbox.union(bboxes) bottom = bbox.y0 - self.label.set_position( (x, bottom - self.labelpad*self.figure.dpi / 72.0)) + self.label.set_position((x, + bottom - \ + self.labelpad * self.figure.dpi / 72.0)) else: if not len(bboxes2): @@ -1626,20 +1642,22 @@ else: bbox = mtransforms.Bbox.union(bboxes2) top = bbox.y1 - self.label.set_position( (x, top+self.labelpad*self.figure.dpi / 72.0)) + self.label.set_position((x, + top + self.labelpad * self.figure.dpi / 72.0)) def _update_offset_text_position(self, bboxes, bboxes2): """ Update the offset_text position based on the sequence of bounding boxes of all the ticklabels """ - x,y = self.offsetText.get_position() + x, y = self.offsetText.get_position() if not len(bboxes): bottom = self.axes.bbox.ymin else: bbox = mtransforms.Bbox.union(bboxes) bottom = bbox.y0 - self.offsetText.set_position((x, bottom-self.OFFSETTEXTPAD*self.figure.dpi/72.0)) + self.offsetText.set_position((x, + bottom - self.OFFSETTEXTPAD * self.figure.dpi / 72.0)) def get_text_heights(self, renderer): """ @@ -1704,20 +1722,29 @@ """ Return the ticks position (top, bottom, default or unknown) """ - majt=self.majorTicks[0] - mT=self.minorTicks[0] + majt = self.majorTicks[0] + mT = self.minorTicks[0] - majorTop=(not majt.tick1On) and majt.tick2On and (not majt.label1On) and majt.label2On - minorTop=(not mT.tick1On) and mT.tick2On and (not mT.label1On) and mT.label2On - if majorTop and minorTop: return 'top' - - MajorBottom=majt.tick1On and (not majt.tick2On) and majt.label1On and (not majt.label2On) - MinorBottom=mT.tick1On and (not mT.tick2On) and mT.label1On and (not mT.label2On) - if MajorBottom and MinorBottom: return 'bottom' - - majorDefault=majt.tick1On and majt.tick2On and majt.label1On and (not majt.label2On) - minorDefault=mT.tick1On and mT.tick2On and mT.label1On and (not mT.label2On) - if majorDefault and minorDefault: return 'default' + majorTop = (not majt.tick1On) and \ + majt.tick2On and (not majt.label1On) and majt.label2On + minorTop = (not mT.tick1On) and \ + mT.tick2On and (not mT.label1On) and mT.label2On + if majorTop and minorTop: + return 'top' + + MajorBottom = majt.tick1On and (not majt.tick2On) and \ + majt.label1On and (not majt.label2On) + MinorBottom = mT.tick1On and (not mT.tick2On) and \ + mT.label1On and (not mT.label2On) + if MajorBottom and MinorBottom: + return 'bottom' + + majorDefault = majt.tick1On and majt.tick2On and \ + majt.label1On and (not majt.label2On) + minorDefault = mT.tick1On and mT.tick2On and \ + mT.label1On and (not mT.label2On) + if majorDefault and minorDefault: + return 'default' return 'unknown' @@ -1761,7 +1788,6 @@ Vmin, Vmax = self.get_data_interval() self.axes.dataLim.intervalx = min(vmin, Vmin), max(vmax, Vmax) - def set_default_intervals(self): 'set the default limits for the axis interval if they are not mutated' xmin, xmax = 0., 1. @@ -1780,29 +1806,29 @@ self.axes.viewLim.intervalx = xmin, xmax - class YAxis(Axis): __name__ = 'yaxis' axis_name = 'y' - def contains(self,mouseevent): + def contains(self, mouseevent): """Test whether the mouse event occurred in the y axis. Returns *True* | *False* """ - if callable(self._contains): return self._contains(self,mouseevent) + if callable(self._contains): + return self._contains(self, mouseevent) - x,y = mouseevent.x,mouseevent.y + x, y = mouseevent.x, mouseevent.y try: trans = self.axes.transAxes.inverted() - xaxes,yaxes = trans.transform_point((x,y)) + xaxes, yaxes = trans.transform_point((x, y)) except ValueError: return False, {} - l,b = self.axes.transAxes.transform_point((0,0)) - r,t = self.axes.transAxes.transform_point((1,1)) - inaxis = yaxes>=0 and yaxes<=1 and ( - (xl-self.pickradius) or - (x>r and x= 0 and yaxes <= 1 and ( + (x < l and x > l - self.pickradius) or + (x > r and x < r + self.pickradius)) return inaxis, {} def _get_tick(self, major): @@ -1812,7 +1838,6 @@ tick_kw = self._minor_tick_kw return YTick(self.axes, 0, '', major=major, **tick_kw) - def _get_label(self): # x in display coords (updated by _update_label_position) # y in axes coords @@ -1821,31 +1846,31 @@ fontproperties=font_manager.FontProperties( size=rcParams['axes.labelsize'], weight=rcParams['axes.labelweight']), - color = rcParams['axes.labelcolor'], + color=rcParams['axes.labelcolor'], verticalalignment='center', horizontalalignment='right', rotation='vertical', ) - label.set_transform( mtransforms.blended_transform_factory( - mtransforms.IdentityTransform(), self.axes.transAxes) ) + label.set_transform(mtransforms.blended_transform_factory( + mtransforms.IdentityTransform(), self.axes.transAxes)) self._set_artist_props(label) - self.label_position='left' + self.label_position = 'left' return label def _get_offset_text(self): # x in display coords, y in axes coords (to be updated at draw time) offsetText = mtext.Text(x=0, y=0.5, - fontproperties = font_manager.FontProperties( + fontproperties=font_manager.FontProperties( size=rcParams['ytick.labelsize']), - color = rcParams['ytick.color'], - verticalalignment = 'baseline', - horizontalalignment = 'left', + color=rcParams['ytick.color'], + verticalalignment='baseline', + horizontalalignment='left', ) offsetText.set_transform(mtransforms.blended_transform_factory( - self.axes.transAxes, mtransforms.IdentityTransform()) ) + self.axes.transAxes, mtransforms.IdentityTransform())) self._set_artist_props(offsetText) - self.offset_text_position='left' + self.offset_text_position = 'left' return offsetText def get_label_position(self): @@ -1865,15 +1890,16 @@ self.label.set_horizontalalignment('left') else: self.label.set_horizontalalignment('right') - self.label_position=position + self.label_position = position def _update_label_position(self, bboxes, bboxes2): """ Update the label position based on the sequence of bounding boxes of all the ticklabels """ - if not self._autolabelpos: return - x,y = self.label.get_position() + if not self._autolabelpos: + return + x, y = self.label.get_position() if self.label_position == 'left': if not len(bboxes): left = self.axes.bbox.xmin @@ -1881,7 +1907,8 @@ bbox = mtransforms.Bbox.union(bboxes) left = bbox.x0 - self.label.set_position( (left-self.labelpad*self.figure.dpi/72.0, y)) + self.label.set_position((left - \ + self.labelpad * self.figure.dpi / 72.0, y)) else: if not len(bboxes2): @@ -1890,26 +1917,30 @@ bbox = mtransforms.Bbox.union(bboxes2) right = bbox.x1 - self.label.set_position( (right+self.labelpad*self.figure.dpi/72.0, y)) + self.label.set_position((right + \ + self.labelpad * self.figure.dpi / 72.0, y)) def _update_offset_text_position(self, bboxes, bboxes2): """ Update the offset_text position based on the sequence of bounding boxes of all the ticklabels """ - x,y = self.offsetText.get_position() + x, y = self.offsetText.get_position() top = self.axes.bbox.ymax - self.offsetText.set_position((x, top+self.OFFSETTEXTPAD*self.figure.dpi/72.0)) + self.offsetText.set_position((x, + top + self.OFFSETTEXTPAD * self.figure.dpi / 72.0)) def set_offset_position(self, position): assert position == 'left' or position == 'right' - x,y = self.offsetText.get_position() - if position == 'left': x = 0 - else: x = 1 + x, y = self.offsetText.get_position() + if position == 'left': + x = 0 + else: + x = 1 self.offsetText.set_ha(position) - self.offsetText.set_position((x,y)) + self.offsetText.set_position((x, y)) def get_text_widths(self, renderer): bbox, bbox2 = self.get_ticklabel_extents(renderer) @@ -1970,20 +2001,29 @@ """ Return the ticks position (left, right, both or unknown) """ - majt=self.majorTicks[0] - mT=self.minorTicks[0] + majt = self.majorTicks[0] + mT = self.minorTicks[0] - majorRight=(not majt.tick1On) and majt.tick2On and (not majt.label1On) and majt.label2On - minorRight=(not mT.tick1On) and mT.tick2On and (not mT.label1On) and mT.label2On - if majorRight and minorRight: return 'right' - - majorLeft=majt.tick1On and (not majt.tick2On) and majt.label1On and (not majt.label2On) - minorLeft=mT.tick1On and (not mT.tick2On) and mT.label1On and (not mT.label2On) - if majorLeft and minorLeft: return 'left' - - majorDefault=majt.tick1On and majt.tick2On and majt.label1On and (not majt.label2On) - minorDefault=mT.tick1On and mT.tick2On and mT.label1On and (not mT.label2On) - if majorDefault and minorDefault: return 'default' + majorRight = (not majt.tick1On) and majt.tick2On \ + and (not majt.label1On) and majt.label2On + minorRight = (not mT.tick1On) and mT.tick2On and \ + (not mT.label1On) and mT.label2On + if majorRight and minorRight: + return 'right' + + majorLeft = majt.tick1On and (not majt.tick2On) and \ + majt.label1On and (not majt.label2On) + minorLeft = mT.tick1On and (not mT.tick2On) and \ + mT.label1On and (not mT.label2On) + if majorLeft and minorLeft: + return 'left' + + majorDefault = majt.tick1On and majt.tick2On and \ + majt.label1On and (not majt.label2On) + minorDefault = mT.tick1On and mT.tick2On and \ + mT.label1On and (not mT.label2On) + if majorDefault and minorDefault: + return 'default' return 'unknown' diff -Nru matplotlib-1.1.1/lib/matplotlib/backend_bases.py matplotlib-1.2.0/lib/matplotlib/backend_bases.py --- matplotlib-1.1.1/lib/matplotlib/backend_bases.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backend_bases.py 2012-11-08 13:38:03.000000000 +0000 @@ -1,4 +1,3 @@ - """ Abstract base classes define the primitives that renderers and graphics contexts must implement to serve as a matplotlib backend @@ -28,8 +27,8 @@ """ -from __future__ import division -import os, warnings, time +from __future__ import division, print_function +import os, warnings, time, io import numpy as np import matplotlib.cbook as cbook @@ -187,14 +186,16 @@ def draw_path_collection(self, gc, master_transform, paths, all_transforms, offsets, offsetTrans, facecolors, edgecolors, - linewidths, linestyles, antialiaseds, urls): + linewidths, linestyles, antialiaseds, urls, + offset_position): """ Draws a collection of paths selecting drawing properties from the lists *facecolors*, *edgecolors*, *linewidths*, *linestyles* and *antialiaseds*. *offsets* is a list of offsets to apply to each of the paths. The offsets in *offsets* are first transformed by *offsetTrans* before being - applied. + applied. *offset_position* may be either "screen" or "data" + depending on the space that the offsets are in. This provides a fallback implementation of :meth:`draw_path_collection` that makes multiple calls to @@ -214,34 +215,33 @@ path_ids.append((path, transform)) for xo, yo, path_id, gc0, rgbFace in self._iter_collection( - gc, path_ids, offsets, offsetTrans, facecolors, edgecolors, - linewidths, linestyles, antialiaseds, urls): + gc, master_transform, all_transforms, path_ids, offsets, + offsetTrans, facecolors, edgecolors, linewidths, linestyles, + antialiaseds, urls, offset_position): path, transform = path_id transform = transforms.Affine2D(transform.get_matrix()).translate(xo, yo) self.draw_path(gc0, path, transform, rgbFace) def draw_quad_mesh(self, gc, master_transform, meshWidth, meshHeight, coordinates, offsets, offsetTrans, facecolors, - antialiased, showedges): + antialiased, edgecolors): """ This provides a fallback implementation of :meth:`draw_quad_mesh` that generates paths and then calls :meth:`draw_path_collection`. """ + from matplotlib.collections import QuadMesh paths = QuadMesh.convert_mesh_to_paths( meshWidth, meshHeight, coordinates) - if showedges: - edgecolors = np.array([[0.0, 0.0, 0.0, 1.0]], np.float_) - linewidths = np.array([gc.get_linewidth()], np.float_) - else: + if edgecolors is None: edgecolors = facecolors - linewidths = np.array([gc.get_linewidth()], np.float_) + linewidths = np.array([gc.get_linewidth()], np.float_) return self.draw_path_collection( gc, master_transform, paths, [], offsets, offsetTrans, facecolors, - edgecolors, linewidths, [], [antialiased], [None]) + edgecolors, linewidths, [], [antialiased], [None], 'screen') def draw_gouraud_triangle(self, gc, points, colors, transform): """ @@ -303,9 +303,10 @@ transform = all_transforms[i % Ntransforms] yield path, transform + master_transform - def _iter_collection(self, gc, path_ids, offsets, offsetTrans, facecolors, - edgecolors, linewidths, linestyles, antialiaseds, - urls): + def _iter_collection(self, gc, master_transform, all_transforms, + path_ids, offsets, offsetTrans, facecolors, + edgecolors, linewidths, linestyles, + antialiaseds, urls, offset_position): """ This is a helper method (along with :meth:`_iter_collection_raw_paths`) to make it easier to write @@ -331,6 +332,7 @@ *path_ids*; *gc* is a graphics context and *rgbFace* is a color to use for filling the path. """ + Ntransforms = len(all_transforms) Npaths = len(path_ids) Noffsets = len(offsets) N = max(Npaths, Noffsets) @@ -360,6 +362,15 @@ path_id = path_ids[i % Npaths] if Noffsets: xo, yo = toffsets[i % Noffsets] + if offset_position == 'data': + if Ntransforms: + transform = all_transforms[i % Ntransforms] + master_transform + else: + transform = master_transform + xo, yo = transform.transform_point((xo, yo)) + xp, yp = transform.transform_point((0, 0)) + xo = -(xp - xo) + yo = -(yp - yo) if Nfacecolors: rgbFace = facecolors[i % Nfacecolors] if Nedgecolors: @@ -671,6 +682,7 @@ self._rgb = (0.0, 0.0, 0.0) self._hatch = None self._url = None + self._gid = None self._snap = None def copy_properties(self, gc): @@ -687,6 +699,7 @@ self._rgb = gc._rgb self._hatch = gc._hatch self._url = gc._url + self._gid = gc._gid self._snap = gc._snap def restore(self): @@ -775,6 +788,12 @@ """ return self._url + def get_gid(self): + """ + Return the object identifier if one is set, None otherwise. + """ + return self._gid + def get_snap(self): """ returns the snap setting which may be: @@ -912,6 +931,12 @@ """ self._url = url + def set_gid(self, id): + """ + Sets the id. + """ + self._gid = id + def set_snap(self, snap): """ Sets the snap setting which may be: @@ -1018,7 +1043,7 @@ to reset the timer interval first if provided. ''' if interval is not None: - self.set_interval(interval) + self._set_interval(interval) self._timer_start() def stop(self): @@ -1166,6 +1191,7 @@ def __init__(self, name, canvas, guiEvent=None): Event.__init__(self, name, canvas, guiEvent) + class LocationEvent(Event): """ An event that has a screen location @@ -1228,8 +1254,7 @@ self._update_enter_leave() return elif (len(axes_list) > 1): # Overlap, get the highest zorder - axCmp = lambda _x,_y: cmp(_x.zorder, _y.zorder) - axes_list.sort(axCmp) + axes_list.sort(key=lambda x: x.zorder) self.inaxes = axes_list[-1] # Use the highest zorder else: # Just found one hit self.inaxes = axes_list[0] @@ -1272,9 +1297,6 @@ LocationEvent.lastevent = self - - - class MouseEvent(LocationEvent): """ A mouse event ('button_press_event', 'button_release_event', 'scroll_event', @@ -1284,10 +1306,12 @@ attributes, the following attributes are defined: *button* - button pressed None, 1, 2, 3, 'up', 'down' (up and down are used for scroll events) + button pressed None, 1, 2, 3, 'up', 'down' (up and down are used + for scroll events) *key* - the key pressed: None, chr(range(255), 'shift', 'win', or 'control' + the key depressed when the mouse event triggered (see + :class:`KeyEvent`) *step* number of scroll steps (positive for 'up', negative for 'down') @@ -1296,7 +1320,7 @@ Example usage:: def on_press(event): - print 'you pressed', event.button, event.xdata, event.ydata + print('you pressed', event.button, event.xdata, event.ydata) cid = fig.canvas.mpl_connect('button_press_event', on_press) @@ -1304,13 +1328,14 @@ x = None # x position - pixels from left of canvas y = None # y position - pixels from right of canvas button = None # button pressed None, 1, 2, 3 + dblclick = None # whether or not the event is the result of a double click inaxes = None # the Axes instance if mouse us over axes xdata = None # x coord of mouse in data coords ydata = None # y coord of mouse in data coords step = None # scroll steps for scroll events def __init__(self, name, canvas, x, y, button=None, key=None, - step=0, guiEvent=None): + step=0, dblclick=False, guiEvent=None): """ x, y in figure coords, 0,0 = bottom, left button pressed None, 1, 2, 3, 'up', 'down' @@ -1319,6 +1344,13 @@ self.button = button self.key = key self.step = step + self.dblclick = dblclick + + def __str__(self): + return ("MPL MouseEvent: xy=(%d,%d) xydata=(%s,%s) button=%d " + + "dblclick=%s inaxes=%s") % (self.x, self.y, self.xdata, + self.ydata, self.button, self.dblclick, self.inaxes) + class PickEvent(Event): """ @@ -1348,7 +1380,7 @@ thisline = event.artist xdata, ydata = thisline.get_data() ind = event.ind - print 'on pick line:', zip(xdata[ind], ydata[ind]) + print('on pick line:', zip(xdata[ind], ydata[ind])) cid = fig.canvas.mpl_connect('pick_event', on_pick) @@ -1371,16 +1403,23 @@ attributes, the following attributes are defined: *key* - the key pressed: None, chr(range(255), shift, win, or control - - This interface may change slightly when better support for - modifier keys is included. + the key(s) pressed. Could be **None**, a single case sensitive ascii + character ("g", "G", "#", etc.), a special key + ("control", "shift", "f1", "up", etc.) or a + combination of the above (e.g. "ctrl+alt+g", "ctrl+alt+G"). + + .. note:: + + Modifier keys will be prefixed to the pressed key and will be in the + order "ctrl", "alt", "super". The exception to this rule is when the + pressed key is itself a modifier key, therefore "ctrl+alt" and + "alt+control" can both be valid key values. Example usage:: def on_key(event): - print 'you pressed', event.key, event.xdata, event.ydata + print('you pressed', event.key, event.xdata, event.ydata) cid = fig.canvas.mpl_connect('key_press_event', on_key) @@ -1390,7 +1429,6 @@ self.key = key - class FigureCanvasBase(object): """ The canvas the figure renders into. @@ -1419,7 +1457,6 @@ 'close_event' ] - def __init__(self, figure): figure.set_canvas(self) self.figure = figure @@ -1432,7 +1469,7 @@ self.button_pick_id = self.mpl_connect('button_press_event',self.pick) self.scroll_pick_id = self.mpl_connect('scroll_event',self.pick) self.mouse_grabber = None # the axes currently grabbing mouse - + self.toolbar = None # NavigationToolbar2 will set me if False: ## highlight the artists that are hit self.mpl_connect('motion_notify_event',self.onHilite) @@ -1463,7 +1500,7 @@ # Try deleting that artist, or its parent if you # can't delete the artist while h: - print "Removing",h + print("Removing",h) if h.remove(): self.draw_idle() break @@ -1562,11 +1599,13 @@ try: event = CloseEvent(s, self, guiEvent=guiEvent) self.callbacks.process(s, event) - except TypeError: + except (TypeError, AttributeError): pass # Suppress the TypeError when the python session is being killed. # It may be that a better solution would be a mechanism to # disconnect all callbacks upon shutdown. + # AttributeError occurs on OSX with qt4agg upon exiting + # with an open window; 'callbacks' attribute no longer exists. def key_press_event(self, key, guiEvent=None): """ @@ -1616,7 +1655,7 @@ self.callbacks.process(s, mouseevent) - def button_press_event(self, x, y, button, guiEvent=None): + def button_press_event(self, x, y, button, dblclick=False, guiEvent=None): """ Backend derived classes should call this function on any mouse button press. x,y are the canvas coords: 0,0 is lower, left. @@ -1628,7 +1667,8 @@ """ self._button = button s = 'button_press_event' - mouseevent = MouseEvent(s, self, x, y, button, self._key, guiEvent=guiEvent) + mouseevent = MouseEvent(s, self, x, y, button, self._key, + dblclick=dblclick, guiEvent=guiEvent) self.callbacks.process(s, mouseevent) def button_release_event(self, x, y, button, guiEvent=None): @@ -1689,23 +1729,32 @@ the native UI event that generated the mpl event """ + self.callbacks.process('figure_leave_event', LocationEvent.lastevent) LocationEvent.lastevent = None + self._lastx, self._lasty = None, None - def enter_notify_event(self, guiEvent=None): + def enter_notify_event(self, guiEvent=None, xy=None): """ Backend derived classes should call this function when entering canvas *guiEvent* the native UI event that generated the mpl event + *xy* + the coordinate location of the pointer when the canvas is + entered """ + if xy is not None: + x, y = xy + self._lastx, self._lasty = x, y + event = Event('figure_enter_event', self, guiEvent) self.callbacks.process('figure_enter_event', event) def idle_event(self, guiEvent=None): - 'call when GUI is idle' + """Called when GUI is idle.""" s = 'idle_event' event = IdleEvent(s, self, guiEvent=guiEvent) self.callbacks.process(s, event) @@ -1751,7 +1800,7 @@ def get_width_height(self): """ - return the figure width and height in points or pixels + Return the figure width and height in points or pixels (depending on the backend), truncated to integers """ return int(self.figure.bbox.width), int(self.figure.bbox.height) @@ -1760,6 +1809,7 @@ 'emf': 'Enhanced Metafile', 'eps': 'Encapsulated Postscript', 'pdf': 'Portable Document Format', + 'pgf': 'LaTeX PGF Figure', 'png': 'Portable Network Graphics', 'ps' : 'Postscript', 'raw': 'Raw RGBA bitmap', @@ -1773,6 +1823,12 @@ # classes inherit from FigureCanvasBase # b) so we don't import a bunch of stuff the user may never use + # TODO: these print_* throw ImportErrror when called from + # compare_images_decorator (decorators.py line 112) + # if the backend has not already been loaded earlier on. Simple trigger: + # >>> import matplotlib.tests.test_spines + # >>> list(matplotlib.tests.test_spines.test_spines_axes_positions())[0][0]() + def print_emf(self, *args, **kwargs): from backends.backend_emf import FigureCanvasEMF # lazy import emf = self.switch_backends(FigureCanvasEMF) @@ -1788,6 +1844,11 @@ pdf = self.switch_backends(FigureCanvasPdf) return pdf.print_pdf(*args, **kwargs) + def print_pgf(self, *args, **kwargs): + from backends.backend_pgf import FigureCanvasPgf # lazy import + pgf = self.switch_backends(FigureCanvasPgf) + return pgf.print_pgf(*args, **kwargs) + def print_png(self, *args, **kwargs): from backends.backend_agg import FigureCanvasAgg # lazy import agg = self.switch_backends(FigureCanvasAgg) @@ -1839,7 +1900,7 @@ image = Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1) options = cbook.restrict_dict(kwargs, ['quality', 'optimize', 'progressive']) - return image.save(filename_or_obj, **options) + return image.save(filename_or_obj, format='jpeg', **options) print_jpeg = print_jpg filetypes['tif'] = filetypes['tiff'] = 'Tagged Image File Format' @@ -1849,20 +1910,26 @@ buf, size = agg.print_to_buffer() if kwargs.pop("dryrun", False): return image = Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1) - return image.save(filename_or_obj) + dpi = (self.figure.dpi, self.figure.dpi) + return image.save(filename_or_obj, format='tiff', + dpi=dpi) print_tiff = print_tif def get_supported_filetypes(self): + """Return dict of savefig file formats supported by this backend""" return self.filetypes def get_supported_filetypes_grouped(self): + """Return a dict of savefig file formats supported by this backend, + where the keys are a file type name, such as 'Joint Photographic + Experts Group', and the values are a list of filename extensions used + for that filetype, such as ['jpg', 'jpeg'].""" groupings = {} - for ext, name in self.filetypes.items(): + for ext, name in self.filetypes.iteritems(): groupings.setdefault(name, []).append(ext) groupings[name].sort() return groupings - def _get_print_method(self, format): method_name = 'print_%s' % format @@ -1877,10 +1944,9 @@ return _print_method - if (format not in self.filetypes or - not hasattr(self, method_name)): - formats = self.filetypes.keys() - formats.sort() + formats = self.get_supported_filetypes() + if (format not in formats or not hasattr(self, method_name)): + formats = sorted(formats) raise ValueError( 'Format "%s" is not supported.\n' 'Supported formats: ' @@ -1888,7 +1954,6 @@ return getattr(self, method_name) - def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w', orientation='portrait', format=None, **kwargs): """ @@ -1920,15 +1985,14 @@ *format* when set, forcibly set the file format to save to - *bbox_inches* Bbox in inches. Only the given portion of the figure is saved. If 'tight', try to figure out the tight bbox of - the figure. + the figure. If None, use savefig.bbox *pad_inches* Amount of padding around the figure when bbox_inches is - 'tight'. + 'tight'. If None, use savefig.pad_inches *bbox_extra_artists* A list of extra artists that will be considered when the @@ -1936,6 +2000,7 @@ """ if format is None: + # get format from filename, or from backend's default filetype if cbook.is_string_like(filename): format = os.path.splitext(filename)[1][1:] if format is None or format == '': @@ -1949,6 +2014,7 @@ if dpi is None: dpi = rcParams['savefig.dpi'] + origDPI = self.figure.dpi origfacecolor = self.figure.get_facecolor() origedgecolor = self.figure.get_edgecolor() @@ -1958,6 +2024,9 @@ self.figure.set_edgecolor(edgecolor) bbox_inches = kwargs.pop("bbox_inches", None) + if bbox_inches is None: + bbox_inches = rcParams['savefig.bbox'] + if bbox_inches: # call adjust_bbox to save only the given area @@ -1972,9 +2041,9 @@ # the backend to support file-like object, i'm going # to leave it as it is. However, a better solution # than stringIO seems to be needed. -JJL - #result = getattr(self, method_name)( + #result = getattr(self, method_name) result = print_method( - cStringIO.StringIO(), + io.BytesIO(), dpi=dpi, facecolor=facecolor, edgecolor=edgecolor, @@ -1989,17 +2058,20 @@ bbox_extra_artists = self.figure.get_default_bbox_extra_artists() bb = [a.get_window_extent(renderer) for a in bbox_extra_artists] - - if bb: - _bbox = Bbox.union([b for b in bb if b.width!=0 or b.height!=0]) + + bbox_filtered = [b for b in bb if b.width!=0 or b.height!=0] + if bbox_filtered: + _bbox = Bbox.union(bbox_filtered) bbox_inches1 = TransformedBbox(_bbox, - Affine2D().scale(1./self.figure.dpi)) + Affine2D().scale(1./self.figure.dpi)) bbox_inches = Bbox.union([bbox_inches, bbox_inches1]) + pad = kwargs.pop("pad_inches", None) + if pad is None: + pad = rcParams['savefig.pad_inches'] - pad = kwargs.pop("pad_inches", 0.1) bbox_inches = bbox_inches.padded(pad) restore_bbox = tight_bbox.adjust_bbox(self.figure, format, @@ -2030,11 +2102,21 @@ #self.figure.canvas.draw() ## seems superfluous return result - - - def get_default_filetype(self): - raise NotImplementedError + """ + Get the default savefig file format as specified in rcParam + ``savefig.format``. Returned string excludes period. Overridden + in backends that only support a single file type. + """ + return rcParams['savefig.format'] + + def get_window_title(self): + """ + Get the title text of the window containing the figure. + Return None if there is no window (eg, a PS backend). + """ + if hasattr(self, "manager"): + return self.manager.get_window_title() def set_window_title(self, title): """ @@ -2044,9 +2126,18 @@ if hasattr(self, "manager"): self.manager.set_window_title(title) + def get_default_filename(self): + """ + Return a string, which includes extension, suitable for use as + a default filename. + """ + default_filename = self.get_window_title() or 'image' + default_filename = default_filename.lower().replace(' ', '_') + return default_filename + '.' + self.get_default_filetype() + def switch_backends(self, FigureCanvasClass): """ - instantiate an instance of FigureCanvasClass + Instantiate an instance of FigureCanvasClass This is used for backend switching, eg, to instantiate a FigureCanvasPS from a FigureCanvasGTK. Note, deep copying is @@ -2095,7 +2186,7 @@ Example usage:: def on_press(event): - print 'you pressed', event.button, event.xdata, event.ydata + print('you pressed', event.button, event.xdata, event.ydata) cid = canvas.mpl_connect('button_press_event', on_press) @@ -2105,7 +2196,7 @@ def mpl_disconnect(self, cid): """ - disconnect callback id cid + Disconnect callback id cid Example usage:: @@ -2207,6 +2298,115 @@ self._looping = False +def key_press_handler(event, canvas, toolbar=None): + """ + Implement the default mpl key bindings for the canvas and toolbar + described at :ref:`key-event-handling` + + *event* + a :class:`KeyEvent` instance + *canvas* + a :class:`FigureCanvasBase` instance + *toolbar* + a :class:`NavigationToolbar2` instance + + """ + # these bindings happen whether you are over an axes or not + + if event.key is None: + return + + # Load key-mappings from your matplotlibrc file. + fullscreen_keys = rcParams['keymap.fullscreen'] + home_keys = rcParams['keymap.home'] + back_keys = rcParams['keymap.back'] + forward_keys = rcParams['keymap.forward'] + pan_keys = rcParams['keymap.pan'] + zoom_keys = rcParams['keymap.zoom'] + save_keys = rcParams['keymap.save'] + quit_keys = rcParams['keymap.quit'] + grid_keys = rcParams['keymap.grid'] + toggle_yscale_keys = rcParams['keymap.yscale'] + toggle_xscale_keys = rcParams['keymap.xscale'] + all = rcParams['keymap.all_axes'] + + # toggle fullscreen mode (default key 'f') + if event.key in fullscreen_keys: + canvas.manager.full_screen_toggle() + + # quit the figure (defaut key 'ctrl+w') + if event.key in quit_keys: + Gcf.destroy_fig(canvas.figure) + + if toolbar is not None: + # home or reset mnemonic (default key 'h', 'home' and 'r') + if event.key in home_keys: + toolbar.home() + # forward / backward keys to enable left handed quick navigation + # (default key for backward: 'left', 'backspace' and 'c') + elif event.key in back_keys: + toolbar.back() + # (default key for forward: 'right' and 'v') + elif event.key in forward_keys: + toolbar.forward() + # pan mnemonic (default key 'p') + elif event.key in pan_keys: + toolbar.pan() + # zoom mnemonic (default key 'o') + elif event.key in zoom_keys: + toolbar.zoom() + # saving current figure (default key 's') + elif event.key in save_keys: + toolbar.save_figure() + + if event.inaxes is None: + return + + # these bindings require the mouse to be over an axes to trigger + + # switching on/off a grid in current axes (default key 'g') + if event.key in grid_keys: + event.inaxes.grid() + canvas.draw() + # toggle scaling of y-axes between 'log and 'linear' (default key 'l') + elif event.key in toggle_yscale_keys: + ax = event.inaxes + scale = ax.get_yscale() + if scale == 'log': + ax.set_yscale('linear') + ax.figure.canvas.draw() + elif scale == 'linear': + ax.set_yscale('log') + ax.figure.canvas.draw() + # toggle scaling of x-axes between 'log and 'linear' (default key 'k') + elif event.key in toggle_xscale_keys: + ax = event.inaxes + scalex = ax.get_xscale() + if scalex == 'log': + ax.set_xscale('linear') + ax.figure.canvas.draw() + elif scalex == 'linear': + ax.set_xscale('log') + ax.figure.canvas.draw() + + elif (event.key.isdigit() and event.key!='0') or event.key in all: + # keys in list 'all' enables all axes (default key 'a'), + # otherwise if key is a number only enable this particular axes + # if it was the axes, where the event was raised + if not (event.key in all): + n = int(event.key)-1 + for i, a in enumerate(canvas.figure.get_axes()): + # consider axes, in which the event was raised + # FIXME: Why only this axes? + if event.x is not None and event.y is not None \ + and a.in_axes(event): + if event.key in all: + a.set_navigate(True) + else: + a.set_navigate(i==n) + +class NonGuiException(Exception): + pass class FigureManagerBase: """ @@ -2218,117 +2418,50 @@ A :class:`FigureCanvasBase` instance *num* - The figure nuamber + The figure number """ def __init__(self, canvas, num): self.canvas = canvas canvas.manager = self # store a pointer to parent self.num = num - self.canvas.mpl_connect('key_press_event', self.key_press) + self.key_press_handler_id = self.canvas.mpl_connect('key_press_event', + self.key_press) + """ + The returned id from connecting the default key handler via :meth:`FigureCanvasBase.mpl_connnect`. + + To disable default key press handling:: + + manager, canvas = figure.canvas.manager, figure.canvas + canvas.mpl_disconnect(manager.key_press_handler_id) + + """ + + def show(self): + """ + For GUI backends, show the figure window and redraw. + For non-GUI backends, raise an exception to be caught + by :meth:`~matplotlib.figure.Figure.show`, for an + optional warning. + """ + raise NonGuiException() def destroy(self): pass - def full_screen_toggle (self): + def full_screen_toggle(self): pass def resize(self, w, h): - 'For gui backends: resize window in pixels' + """"For gui backends, resize the window (in pixels).""" pass def key_press(self, event): - - # these bindings happen whether you are over an axes or not - #if event.key == 'q': - # self.destroy() # how cruel to have to destroy oneself! - # return - - if event.key is None: - return - - # Load key-mappings from your matplotlibrc file. - fullscreen_keys = rcParams['keymap.fullscreen'] - home_keys = rcParams['keymap.home'] - back_keys = rcParams['keymap.back'] - forward_keys = rcParams['keymap.forward'] - pan_keys = rcParams['keymap.pan'] - zoom_keys = rcParams['keymap.zoom'] - save_keys = rcParams['keymap.save'] - grid_keys = rcParams['keymap.grid'] - toggle_yscale_keys = rcParams['keymap.yscale'] - toggle_xscale_keys = rcParams['keymap.xscale'] - all = rcParams['keymap.all_axes'] - - # toggle fullscreen mode (default key 'f') - if event.key in fullscreen_keys: - self.full_screen_toggle() - - # home or reset mnemonic (default key 'h', 'home' and 'r') - elif event.key in home_keys: - self.canvas.toolbar.home() - # forward / backward keys to enable left handed quick navigation - # (default key for backward: 'left', 'backspace' and 'c') - elif event.key in back_keys: - self.canvas.toolbar.back() - # (default key for forward: 'right' and 'v') - elif event.key in forward_keys: - self.canvas.toolbar.forward() - # pan mnemonic (default key 'p') - elif event.key in pan_keys: - self.canvas.toolbar.pan() - # zoom mnemonic (default key 'o') - elif event.key in zoom_keys: - self.canvas.toolbar.zoom() - # saving current figure (default key 's') - elif event.key in save_keys: - self.canvas.toolbar.save_figure() - - if event.inaxes is None: - return - - # the mouse has to be over an axes to trigger these - # switching on/off a grid in current axes (default key 'g') - if event.key in grid_keys: - event.inaxes.grid() - self.canvas.draw() - # toggle scaling of y-axes between 'log and 'linear' (default key 'l') - elif event.key in toggle_yscale_keys: - ax = event.inaxes - scale = ax.get_yscale() - if scale == 'log': - ax.set_yscale('linear') - ax.figure.canvas.draw() - elif scale == 'linear': - ax.set_yscale('log') - ax.figure.canvas.draw() - # toggle scaling of x-axes between 'log and 'linear' (default key 'k') - elif event.key in toggle_xscale_keys: - ax = event.inaxes - scalex = ax.get_xscale() - if scalex == 'log': - ax.set_xscale('linear') - ax.figure.canvas.draw() - elif scalex == 'linear': - ax.set_xscale('log') - ax.figure.canvas.draw() - - elif (event.key.isdigit() and event.key!='0') or event.key in all: - # keys in list 'all' enables all axes (default key 'a'), - # otherwise if key is a number only enable this particular axes - # if it was the axes, where the event was raised - if not (event.key in all): - n = int(event.key)-1 - for i, a in enumerate(self.canvas.figure.get_axes()): - # consider axes, in which the event was raised - # FIXME: Why only this axes? - if event.x is not None and event.y is not None \ - and a.in_axes(event): - if event.key in all: - a.set_navigate(True) - else: - a.set_navigate(i==n) - + """ + Implement the default mpl key bindings defined at + :ref:`key-event-handling` + """ + key_press_handler(event, self.canvas, self.canvas.toolbar) def show_popup(self, msg): """ @@ -2336,20 +2469,27 @@ """ pass + def get_window_title(self): + """ + Get the title text of the window containing the figure. + Return None for non-GUI backends (eg, a PS backend). + """ + return 'image' + def set_window_title(self, title): """ Set the title text of the window containing the figure. Note that - this has no effect if there is no window (eg, a PS backend). + this has no effect for non-GUI backends (eg, a PS backend). """ pass -# cursors -class Cursors: #namespace + +class Cursors: + # this class is only used as a simple namespace HAND, POINTER, SELECT_REGION, MOVE = range(4) cursors = Cursors() - class NavigationToolbar2(object): """ Base class for the navigation cursor, version 2 @@ -2394,6 +2534,25 @@ That's it, we'll do the rest! """ + # list of toolitems to add to the toolbar, format is: + # ( + # text, # the text of the button (often not visible to users) + # tooltip_text, # the tooltip shown on hover (where possible) + # image_file, # name of the image for the button (without the extension) + # name_of_method, # name of the method in NavigationToolbar2 to call + # ) + toolitems = ( + ('Home', 'Reset original view', 'home', 'home'), + ('Back', 'Back to previous view', 'back', 'back'), + ('Forward', 'Forward to next view', 'forward', 'forward'), + (None, None, None, None), + ('Pan', 'Pan axes with left mouse, zoom with right', 'move', 'pan'), + ('Zoom', 'Zoom to rectangle', 'zoom_to_rect', 'zoom'), + (None, None, None, None), + ('Subplots', 'Configure subplots', 'subplots', 'configure_subplots'), + ('Save', 'Save the figure', 'filesave', 'save_figure'), + ) + def __init__(self, canvas): self.canvas = canvas canvas.toolbar = self @@ -2417,11 +2576,11 @@ self.set_history_buttons() def set_message(self, s): - 'display a message on toolbar or in status bar' + """Display a message on toolbar or in status bar""" pass def back(self, *args): - 'move back up the view lim stack' + """move back up the view lim stack""" self._views.back() self._positions.back() self.set_history_buttons() @@ -2431,18 +2590,18 @@ pass def draw_rubberband(self, event, x0, y0, x1, y1): - 'draw a rectangle rubberband to indicate zoom limits' + """Draw a rectangle rubberband to indicate zoom limits""" pass def forward(self, *args): - 'move forward in the view lim stack' + """Move forward in the view lim stack""" self._views.forward() self._positions.forward() self.set_history_buttons() self._update_view() def home(self, *args): - 'restore the original view' + """Restore the original view""" self._views.home() self._positions.home() self.set_history_buttons() @@ -2471,8 +2630,6 @@ raise NotImplementedError def mouse_move(self, event): - #print 'mouse_move', event.button - if not event.inaxes or not self._active: if self._lastCursor != cursors.POINTER: self.set_cursor(cursors.POINTER) @@ -2490,9 +2647,10 @@ if event.inaxes and event.inaxes.get_navigate(): - try: s = event.inaxes.format_coord(event.xdata, event.ydata) - except ValueError: pass - except OverflowError: pass + try: + s = event.inaxes.format_coord(event.xdata, event.ydata) + except (ValueError, OverflowError): + pass else: if len(self.mode): self.set_message('%s, %s' % (self.mode, s)) @@ -2501,7 +2659,7 @@ else: self.set_message(self.mode) def pan(self,*args): - 'Activate the pan/zoom tool. pan with left button, zoom with right' + """Activate the pan/zoom tool. pan with left button, zoom with right""" # set the pointer icon and button press funcs to the # appropriate callbacks @@ -2533,11 +2691,11 @@ self.set_message(self.mode) def press(self, event): - 'this will be called whenver a mouse button is pressed' + """Called whenver a mouse button is pressed.""" pass def press_pan(self, event): - 'the press mouse button in pan/zoom mode callback' + """the press mouse button in pan/zoom mode callback""" if event.button == 1: self._button_pressed=1 @@ -2565,7 +2723,7 @@ self.press(event) def press_zoom(self, event): - 'the press mouse button in zoom to rect mode callback' + """the press mouse button in zoom to rect mode callback""" if event.button == 1: self._button_pressed=1 elif event.button == 3: @@ -2587,17 +2745,14 @@ a.transData.frozen() )) id1 = self.canvas.mpl_connect('motion_notify_event', self.drag_zoom) - id2 = self.canvas.mpl_connect('key_press_event', self._switch_on_zoom_mode) id3 = self.canvas.mpl_connect('key_release_event', self._switch_off_zoom_mode) self._ids_zoom = id1, id2, id3 - self._zoom_mode = event.key - self.press(event) def _switch_on_zoom_mode(self, event): @@ -2609,7 +2764,7 @@ self.mouse_move(event) def push_current(self): - 'push the current view limits and position onto the stack' + """push the current view limits and position onto the stack""" lims = []; pos = [] for a in self.canvas.figure.get_axes(): xmin, xmax = a.get_xlim() @@ -2624,11 +2779,11 @@ self.set_history_buttons() def release(self, event): - 'this will be called whenever mouse button is released' + """this will be called whenever mouse button is released""" pass def release_pan(self, event): - 'the release mouse button callback in pan/zoom mode' + """the release mouse button callback in pan/zoom mode""" if self._button_pressed is None: return @@ -2644,7 +2799,7 @@ self.draw() def drag_pan(self, event): - 'the drag callback in pan/zoom mode' + """the drag callback in pan/zoom mode""" for a, ind in self._xypress: #safer to use the recorded button at the press than current button: @@ -2653,7 +2808,7 @@ self.dynamic_update() def drag_zoom(self, event): - 'the drag callback in zoom mode' + """the drag callback in zoom mode""" if self._xypress: x, y = event.x, event.y @@ -2673,10 +2828,8 @@ self.draw_rubberband(event, x, y, lastx, lasty) - - def release_zoom(self, event): - 'the release mouse button callback in zoom to rect mode' + """the release mouse button callback in zoom to rect mode""" for zoom_id in self._ids_zoom: self.canvas.mpl_disconnect(zoom_id) self._ids_zoom = [] @@ -2784,7 +2937,7 @@ self.release(event) def draw(self): - 'redraw the canvases, update the locators' + """Redraw the canvases, update the locators""" for a in self.canvas.figure.get_axes(): xaxis = getattr(a, 'xaxis', None) yaxis = getattr(a, 'yaxis', None) @@ -2800,12 +2953,10 @@ loc.refresh() self.canvas.draw() - - def _update_view(self): - '''update the viewlim and position from the view and + """Update the viewlim and position from the view and position stack for each axes - ''' + """ lims = self._views() if lims is None: return @@ -2821,9 +2972,8 @@ self.draw() - def save_figure(self, *args): - 'save the current figure' + """Save the current figure""" raise NotImplementedError def set_cursor(self, cursor): @@ -2834,13 +2984,13 @@ pass def update(self): - 'reset the axes stack' + """Reset the axes stack""" self._views.clear() self._positions.clear() self.set_history_buttons() def zoom(self, *args): - 'activate zoom to rect mode' + """Activate zoom to rect mode""" if self._active == 'ZOOM': self._active = None else: @@ -2867,7 +3017,6 @@ self.set_message(self.mode) - def set_history_buttons(self): - 'enable or disable back/forward button' + """Enable or disable back/forward button""" pass diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/__init__.py matplotlib-1.2.0/lib/matplotlib/backends/__init__.py --- matplotlib-1.1.1/lib/matplotlib/backends/__init__.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/__init__.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,4 @@ - +from __future__ import print_function import matplotlib import inspect import warnings @@ -52,6 +52,6 @@ matplotlib.verbose.report('backend %s version %s' % (backend,backend_version)) - return new_figure_manager, draw_if_interactive, show + return backend_mod, new_figure_manager, draw_if_interactive, show diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_agg.py matplotlib-1.2.0/lib/matplotlib/backends/backend_agg.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_agg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_agg.py 2012-10-31 00:11:13.000000000 +0000 @@ -30,16 +30,29 @@ from matplotlib.cbook import is_string_like, maxdict from matplotlib.figure import Figure from matplotlib.font_manager import findfont -from matplotlib.ft2font import FT2Font, LOAD_FORCE_AUTOHINT, LOAD_NO_HINTING +from matplotlib.ft2font import FT2Font, LOAD_FORCE_AUTOHINT, LOAD_NO_HINTING, \ + LOAD_DEFAULT, LOAD_NO_AUTOHINT from matplotlib.mathtext import MathTextParser from matplotlib.path import Path from matplotlib.transforms import Bbox, BboxBase -from _backend_agg import RendererAgg as _RendererAgg +from matplotlib.backends._backend_agg import RendererAgg as _RendererAgg from matplotlib import _png backend_version = 'v2.2' +def get_hinting_flag(): + mapping = { + True: LOAD_FORCE_AUTOHINT, + False: LOAD_NO_HINTING, + 'either': LOAD_DEFAULT, + 'native': LOAD_NO_AUTOHINT, + 'auto': LOAD_FORCE_AUTOHINT, + 'none': LOAD_NO_HINTING + } + return mapping[rcParams['text.hinting']] + + class RendererAgg(RendererBase): """ The renderer handles all the drawing primitives using a graphics @@ -82,7 +95,6 @@ if __debug__: verbose.report('RendererAgg.__init__ done', 'debug-annoying') - def _get_hinting_flag(self): if rcParams['text.hinting']: return LOAD_FORCE_AUTOHINT @@ -155,7 +167,7 @@ if ismath: return self.draw_mathtext(gc, x, y, s, prop, angle) - flags = self._get_hinting_flag() + flags = get_hinting_flag() font = self._get_agg_font(prop) if font is None: return None if len(s) == 1 and ord(s) > 127: @@ -167,7 +179,6 @@ font.draw_glyphs_to_bitmap(antialiased=rcParams['text.antialiased']) #print x, y, int(x), int(y), s - self._renderer.draw_text_image(font.get_image(), int(x), int(y) + 1, angle, gc) def get_text_width_height_descent(self, s, prop, ismath): @@ -193,7 +204,7 @@ self.mathtext_parser.parse(s, self.dpi, prop) return width, height, descent - flags = self._get_hinting_flag() + flags = get_hinting_flag() font = self._get_agg_font(prop) font.set_text(s, 0.0, flags=flags) # the width and height of unrotated string w, h = font.get_width_height() @@ -235,9 +246,10 @@ fname = findfont(prop) font = RendererAgg._fontd.get(fname) if font is None: - font = FT2Font(str(fname)) + font = FT2Font( + str(fname), + hinting_factor=rcParams['text.hinting_factor']) RendererAgg._fontd[fname] = font - RendererAgg._fontd[key] = font font.clear() @@ -265,10 +277,10 @@ 'debug-annoying') return self._renderer.tostring_argb() - def buffer_rgba(self,x,y): + def buffer_rgba(self): if __debug__: verbose.report('RendererAgg.buffer_rgba', 'debug-annoying') - return self._renderer.buffer_rgba(x,y) + return self._renderer.buffer_rgba() def clear(self): self._renderer.clear() @@ -373,7 +385,6 @@ image) - def new_figure_manager(num, *args, **kwargs): """ Create a new figure manager instance @@ -384,7 +395,14 @@ FigureClass = kwargs.pop('FigureClass', Figure) thisFig = FigureClass(*args, **kwargs) - canvas = FigureCanvasAgg(thisFig) + return new_figure_manager_given_figure(num, thisFig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + canvas = FigureCanvasAgg(figure) manager = FigureManagerBase(canvas, num) return manager @@ -446,13 +464,10 @@ 'debug-annoying') return self.renderer.tostring_argb() - def buffer_rgba(self,x,y): + def buffer_rgba(self): if __debug__: verbose.report('FigureCanvasAgg.buffer_rgba', 'debug-annoying') - return self.renderer.buffer_rgba(x,y) - - def get_default_filetype(self): - return 'png' + return self.renderer.buffer_rgba() def print_raw(self, filename_or_obj, *args, **kwargs): FigureCanvasAgg.draw(self) @@ -460,8 +475,15 @@ original_dpi = renderer.dpi renderer.dpi = self.figure.dpi if is_string_like(filename_or_obj): - filename_or_obj = file(filename_or_obj, 'wb') - renderer._renderer.write_rgba(filename_or_obj) + filename_or_obj = open(filename_or_obj, 'wb') + close = True + else: + close = False + try: + renderer._renderer.write_rgba(filename_or_obj) + finally: + if close: + filename_or_obj.close() renderer.dpi = original_dpi print_rgba = print_raw @@ -471,10 +493,17 @@ original_dpi = renderer.dpi renderer.dpi = self.figure.dpi if is_string_like(filename_or_obj): - filename_or_obj = file(filename_or_obj, 'wb') - _png.write_png(renderer._renderer.buffer_rgba(0, 0), - renderer.width, renderer.height, - filename_or_obj, self.figure.dpi) + filename_or_obj = open(filename_or_obj, 'wb') + close = True + else: + close = False + try: + _png.write_png(renderer._renderer.buffer_rgba(), + renderer.width, renderer.height, + filename_or_obj, self.figure.dpi) + finally: + if close: + filename_or_obj.close() renderer.dpi = original_dpi def print_to_buffer(self): @@ -482,7 +511,7 @@ renderer = self.get_renderer() original_dpi = renderer.dpi renderer.dpi = self.figure.dpi - result = (renderer._renderer.buffer_rgba(0, 0), + result = (renderer._renderer.buffer_rgba(), (int(renderer.width), int(renderer.height))) renderer.dpi = original_dpi return result diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_cairo.py matplotlib-1.2.0/lib/matplotlib/backends/backend_cairo.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_cairo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_cairo.py 2012-10-31 00:11:13.000000000 +0000 @@ -18,7 +18,7 @@ * functions underscore_separated """ -from __future__ import division +from __future__ import division, print_function import os, sys, warnings, gzip import numpy as np @@ -26,15 +26,15 @@ def _fn_name(): return sys._getframe(1).f_code.co_name try: - import cairo + import cairo except ImportError: - raise ImportError("Cairo backend requires that pycairo is installed.") + raise ImportError("Cairo backend requires that pycairo is installed.") _version_required = (1,2,0) if cairo.version_info < _version_required: - raise ImportError ("Pycairo %d.%d.%d is installed\n" - "Pycairo %d.%d.%d or later is required" - % (cairo.version_info + _version_required)) + raise ImportError ("Pycairo %d.%d.%d is installed\n" + "Pycairo %d.%d.%d or later is required" + % (cairo.version_info + _version_required)) backend_version = cairo.version del _version_required @@ -46,7 +46,6 @@ from matplotlib.path import Path from matplotlib.transforms import Bbox, Affine2D from matplotlib.font_manager import ttfFontProperty -from matplotlib import rcParams _debug = False #_debug = True @@ -89,7 +88,7 @@ def __init__(self, dpi): """ """ - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) + if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name())) self.dpi = dpi self.gc = GraphicsContextCairo (renderer=self) self.text_ctx = cairo.Context ( @@ -155,7 +154,7 @@ def draw_image(self, gc, x, y, im): # bbox - not currently used - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) + if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name())) clippath, clippath_trans = gc.get_clip_path() @@ -181,30 +180,33 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False): # Note: x,y are device/display coords, not user-coords, unlike other # draw_* methods - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) + if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name())) if ismath: - self._draw_mathtext(gc, x, y, s, prop, angle) + self._draw_mathtext(gc, x, y, s, prop, angle) else: - ctx = gc.ctx - ctx.new_path() - ctx.move_to (x, y) - ctx.select_font_face (prop.get_name(), - self.fontangles [prop.get_style()], - self.fontweights[prop.get_weight()]) - - size = prop.get_size_in_points() * self.dpi / 72.0 - - ctx.save() - if angle: - ctx.rotate (-angle * np.pi / 180) - ctx.set_font_size (size) - ctx.show_text (s.encode("utf-8")) - ctx.restore() + ctx = gc.ctx + ctx.new_path() + ctx.move_to (x, y) + ctx.select_font_face (prop.get_name(), + self.fontangles [prop.get_style()], + self.fontweights[prop.get_weight()]) + + size = prop.get_size_in_points() * self.dpi / 72.0 + + ctx.save() + if angle: + ctx.rotate (-angle * np.pi / 180) + ctx.set_font_size (size) + if sys.version_info[0] < 3: + ctx.show_text (s.encode("utf-8")) + else: + ctx.show_text (s) + ctx.restore() def _draw_mathtext(self, gc, x, y, s, prop, angle): - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) + if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name())) ctx = gc.ctx width, height, descent, glyphs, rects = self.mathtext_parser.parse( @@ -213,46 +215,46 @@ ctx.save() ctx.translate(x, y) if angle: - ctx.rotate (-angle * np.pi / 180) + ctx.rotate (-angle * np.pi / 180) for font, fontsize, s, ox, oy in glyphs: - ctx.new_path() - ctx.move_to(ox, oy) - - fontProp = ttfFontProperty(font) - ctx.save() - ctx.select_font_face (fontProp.name, - self.fontangles [fontProp.style], - self.fontweights[fontProp.weight]) - - size = fontsize * self.dpi / 72.0 - ctx.set_font_size(size) - ctx.show_text(s.encode("utf-8")) - ctx.restore() + ctx.new_path() + ctx.move_to(ox, oy) + + fontProp = ttfFontProperty(font) + ctx.save() + ctx.select_font_face (fontProp.name, + self.fontangles [fontProp.style], + self.fontweights[fontProp.weight]) + + size = fontsize * self.dpi / 72.0 + ctx.set_font_size(size) + ctx.show_text(s.encode("utf-8")) + ctx.restore() for ox, oy, w, h in rects: - ctx.new_path() - ctx.rectangle (ox, oy, w, h) - ctx.set_source_rgb (0, 0, 0) - ctx.fill_preserve() + ctx.new_path() + ctx.rectangle (ox, oy, w, h) + ctx.set_source_rgb (0, 0, 0) + ctx.fill_preserve() ctx.restore() def flipy(self): - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) + if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name())) return True #return False # tried - all draw objects ok except text (and images?) # which comes out mirrored! def get_canvas_width_height(self): - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) + if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name())) return self.width, self.height def get_text_width_height_descent(self, s, prop, ismath): - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) + if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name())) if ismath: width, height, descent, fonts, used_characters = self.mathtext_parser.parse( s, self.dpi, prop) @@ -281,7 +283,7 @@ def new_gc(self): - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) + if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name())) self.gc.ctx.save() self.gc._alpha = 1.0 self.gc._forced_alpha = False # if True, _alpha overrides A from RGBA @@ -289,7 +291,7 @@ def points_to_pixels(self, points): - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) + if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name())) return points/72.0 * self.dpi @@ -395,10 +397,17 @@ """ Create a new figure manager instance """ - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) + if _debug: print('%s()' % (_fn_name())) FigureClass = kwargs.pop('FigureClass', Figure) thisFig = FigureClass(*args, **kwargs) - canvas = FigureCanvasCairo(thisFig) + return new_figure_manager_given_figure(num, thisFig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + canvas = FigureCanvasCairo(figure) manager = FigureManagerBase(canvas, num) return manager @@ -427,9 +436,6 @@ def print_svgz(self, fobj, *args, **kwargs): return self._save(fobj, 'svgz', *args, **kwargs) - def get_default_filetype(self): - return rcParams['cairo.format'] - def _save (self, fo, format, **kwargs): # save PDF/PS/SVG orientation = kwargs.get('orientation', 'portrait') @@ -461,7 +467,14 @@ filename = fo if is_string_like(fo): fo = open(fo, 'wb') - fo = gzip.GzipFile(None, 'wb', fileobj=fo) + close = True + else: + close = False + try: + fo = gzip.GzipFile(None, 'wb', fileobj=fo) + finally: + if close: + fo.close() surface = cairo.SVGSurface (fo, width_in_points, height_in_points) else: warnings.warn ("unknown format: %s" % format) diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_cocoaagg.py matplotlib-1.2.0/lib/matplotlib/backends/backend_cocoaagg.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_cocoaagg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_cocoaagg.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,4 @@ -from __future__ import division +from __future__ import division, print_function """ backend_cocoaagg.py @@ -35,12 +35,21 @@ mplBundle = NSBundle.bundleWithPath_(os.path.dirname(__file__)) + def new_figure_manager(num, *args, **kwargs): FigureClass = kwargs.pop('FigureClass', Figure) thisFig = FigureClass( *args, **kwargs ) - canvas = FigureCanvasCocoaAgg(thisFig) + return new_figure_manager_given_figure(num, thisFig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + canvas = FigureCanvasCocoaAgg(figure) return FigureManagerCocoaAgg(canvas, num) + ## Below is the original show() function: #def show(): # for manager in Gcf.get_all_fig_managers(): @@ -142,7 +151,7 @@ self.image_.setSize_((w,h)) brep = NSBitmapImageRep.alloc().initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bytesPerRow_bitsPerPixel_( - (self.canvas.buffer_rgba(0,0),'','','',''), # Image data + (self.canvas.buffer_rgba(),'','','',''), # Image data w, # width h, # height 8, # bits per pixel @@ -164,14 +173,15 @@ self.updatePlot() def mouseDown_(self, event): + dblclick = (event.clickCount() == 2) loc = self.convertPoint_fromView_(event.locationInWindow(), None) type = event.type() if (type == NSLeftMouseDown): button = 1 else: - print >>sys.stderr, 'Unknown mouse event type:', type + print('Unknown mouse event type:', type, file=sys.stderr) button = -1 - self.canvas.button_press_event(loc.x, loc.y, button) + self.canvas.button_press_event(loc.x, loc.y, button, dblclick=dblclick) self.updatePlot() def mouseDragged_(self, event): @@ -185,7 +195,7 @@ if (type == NSLeftMouseUp): button = 1 else: - print >>sys.stderr, 'Unknown mouse event type:', type + print('Unknown mouse event type:', type, file=sys.stderr) button = -1 self.canvas.button_release_event(loc.x, loc.y, button) self.updatePlot() @@ -203,7 +213,7 @@ def startWithBundle_(self, bundle): #NSApplicationLoad() if not bundle.loadNibFile_externalNameTable_withZone_('Matplotlib.nib', {}, None): - print >>sys.stderr, 'Unable to load Matplotlib Cocoa UI!' + print('Unable to load Matplotlib Cocoa UI!', file=sys.stderr) sys.exit() class FigureManagerCocoaAgg(FigureManagerBase): @@ -257,21 +267,21 @@ return True bndl = NSBundle.bundleWithPath_(objc.pathForFramework('/System/Library/Frameworks/ApplicationServices.framework')) if bndl is None: - print >>sys.stderr, 'ApplicationServices missing' + print('ApplicationServices missing', file=sys.stderr) return False d = {} objc.loadBundleFunctions(bndl, d, FUNCTIONS) for (fn, sig) in FUNCTIONS: if fn not in d: - print >>sys.stderr, 'Missing', fn + print('Missing', fn, file=sys.stderr) return False err, psn = d['GetCurrentProcess']() if err: - print >>sys.stderr, 'GetCurrentProcess', (err, psn) + print('GetCurrentProcess', (err, psn), file=sys.stderr) return False err = d['CPSSetProcessName'](psn, name) if err: - print >>sys.stderr, 'CPSSetProcessName', (err, psn) + print('CPSSetProcessName', (err, psn), file=sys.stderr) return False err = d['CPSEnableForegroundOperation'](psn) if err: @@ -279,7 +289,7 @@ return False err = d['SetFrontProcess'](psn) if err: - print >>sys.stderr, 'SetFrontProcess', (err, psn) + print('SetFrontProcess', (err, psn), file=sys.stderr) return False return True diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_emf.py matplotlib-1.2.0/lib/matplotlib/backends/backend_emf.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_emf.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_emf.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,7 +3,7 @@ driver library. """ -from __future__ import division +from __future__ import division, print_function try: import pyemf @@ -74,7 +74,7 @@ self.style=0 self.set_linestyle() - if debugHandle: print "EMFPen: style=%d width=%d rgb=(%d,%d,%d)" % (self.style,self.width,self.r,self.g,self.b) + if debugHandle: print("EMFPen: style=%d width=%d rgb=(%d,%d,%d)" % (self.style,self.width,self.r,self.g,self.b)) def __hash__(self): return hash((self.style,self.width,self.r,self.g,self.b)) @@ -88,7 +88,7 @@ 'dashdot':pyemf.PS_DASHDOT, 'dotted':pyemf.PS_DOT} #style=styles.get(self.gc.get_linestyle('solid')) style=self.gc.get_linestyle('solid') - if debugHandle: print "EMFPen: style=%s" % style + if debugHandle: print("EMFPen: style=%s" % style) if style in styles: self.style=styles[style] else: @@ -106,7 +106,7 @@ self.r=int(r*255) self.g=int(g*255) self.b=int(b*255) - if debugHandle: print "EMFBrush: rgb=(%d,%d,%d)" % (self.r,self.g,self.b) + if debugHandle: print("EMFBrush: rgb=(%d,%d,%d)" % (self.r,self.g,self.b)) def __hash__(self): return hash((self.r,self.g,self.b)) @@ -172,7 +172,7 @@ self._lastClipRect = None - if debugPrint: print "RendererEMF: (%f,%f) %s dpi=%f" % (self.width,self.height,outfile,dpi) + if debugPrint: print("RendererEMF: (%f,%f) %s dpi=%f" % (self.width,self.height,outfile,dpi)) @@ -188,7 +188,7 @@ If the color rgbFace is not None, fill the arc with it. """ - if debugPrint: print "draw_arc: (%f,%f) angles=(%f,%f) w,h=(%f,%f)" % (x,y,angle1,angle2,width,height) + if debugPrint: print("draw_arc: (%f,%f) angles=(%f,%f) w,h=(%f,%f)" % (x,y,angle1,angle2,width,height)) pen=self.select_pen(gcEdge) brush=self.select_brush(rgbFace) @@ -286,19 +286,19 @@ """ Draw a single line from x1,y1 to x2,y2 """ - if debugPrint: print "draw_line: (%f,%f) - (%f,%f)" % (x1,y1,x2,y2) + if debugPrint: print("draw_line: (%f,%f) - (%f,%f)" % (x1,y1,x2,y2)) if self.select_pen(gc): self.emf.Polyline([(long(x1),long(self.height-y1)),(long(x2),long(self.height-y2))]) else: - if debugPrint: print "draw_line: optimizing away (%f,%f) - (%f,%f)" % (x1,y1,x2,y2) + if debugPrint: print("draw_line: optimizing away (%f,%f) - (%f,%f)" % (x1,y1,x2,y2)) def draw_lines(self, gc, x, y): """ x and y are equal length arrays, draw lines connecting each point in x, y """ - if debugPrint: print "draw_lines: %d points" % len(str(x)) + if debugPrint: print("draw_lines: %d points" % len(str(x))) # optimize away anything that won't actually be drawn. Edge # style must not be PS_NULL for it to appear on screen. @@ -311,7 +311,7 @@ Draw a single point at x,y Where 'point' is a device-unit point (or pixel), not a matplotlib point """ - if debugPrint: print "draw_point: (%f,%f)" % (x,y) + if debugPrint: print("draw_point: (%f,%f)" % (x,y)) # don't cache this pen pen=EMFPen(self.emf,gc) @@ -326,7 +326,7 @@ If the color rgbFace is not None, fill the polygon with it """ - if debugPrint: print "draw_polygon: %d points" % len(points) + if debugPrint: print("draw_polygon: %d points" % len(points)) # optimize away anything that won't actually draw. Either a # face color or edge style must be defined @@ -337,7 +337,7 @@ self.emf.Polygon(points) else: points = [(long(x), long(self.height-y)) for x,y in points] - if debugPrint: print "draw_polygon: optimizing away polygon: %d points = %s" % (len(points),str(points)) + if debugPrint: print("draw_polygon: optimizing away polygon: %d points = %s" % (len(points),str(points))) def draw_rectangle(self, gcEdge, rgbFace, x, y, width, height): """ @@ -346,7 +346,7 @@ If rgbFace is not None, fill the rectangle with it. """ - if debugPrint: print "draw_rectangle: (%f,%f) w=%f,h=%f" % (x,y,width,height) + if debugPrint: print("draw_rectangle: (%f,%f) w=%f,h=%f" % (x,y,width,height)) # optimize away anything that won't actually draw. Either a # face color or edge style must be defined @@ -355,7 +355,7 @@ if pen or brush: self.emf.Rectangle(int(x),int(self.height-y),int(x)+int(width),int(self.height-y)-int(height)) else: - if debugPrint: print "draw_rectangle: optimizing away (%f,%f) w=%f,h=%f" % (x,y,width,height) + if debugPrint: print("draw_rectangle: optimizing away (%f,%f) w=%f,h=%f" % (x,y,width,height)) def draw_text(self, gc, x, y, s, prop, angle, ismath=False): @@ -391,8 +391,8 @@ """ Draw a text string verbatim; no conversion is done. """ - if debugText: print "draw_plain_text: (%f,%f) %d degrees: '%s'" % (x,y,angle,s) - if debugText: print " properties:\n"+str(prop) + if debugText: print("draw_plain_text: (%f,%f) %d degrees: '%s'" % (x,y,angle,s)) + if debugText: print(" properties:\n"+str(prop)) self.select_font(prop,angle) # haxor follows! The subtleties of text placement in EMF @@ -412,13 +412,13 @@ pyemf doesn't have any raster functionality yet, the texmanager.get_rgba won't help. """ - if debugText: print "draw_math_text: (%f,%f) %d degrees: '%s'" % (x,y,angle,s) + if debugText: print("draw_math_text: (%f,%f) %d degrees: '%s'" % (x,y,angle,s)) s = s[1:-1] # strip the $ from front and back match=re.match("10\^\{(.+)\}",s) if match: exp=match.group(1) - if debugText: print " exponent=%s" % exp + if debugText: print(" exponent=%s" % exp) font = self._get_font_ttf(prop) font.set_text("10", 0.0) w, h = font.get_width_height() @@ -438,12 +438,12 @@ with FontPropertry prop, ripped right out of backend_ps. This method must be kept in sync with draw_math_text. """ - if debugText: print "get_math_text_width_height:" + if debugText: print("get_math_text_width_height:") s = s[1:-1] # strip the $ from front and back match=re.match("10\^\{(.+)\}",s) if match: exp=match.group(1) - if debugText: print " exponent=%s" % exp + if debugText: print(" exponent=%s" % exp) font = self._get_font_ttf(prop) font.set_text("10", 0.0) w1, h1 = font.get_width_height() @@ -458,7 +458,7 @@ w /= 64.0 # convert from subpixels h /= 64.0 w+=self.points_to_pixels(self.hackPointsForMathExponent) - if debugText: print " math string=%s w,h=(%f,%f)" % (s, w, h) + if debugText: print(" math string=%s w,h=(%f,%f)" % (s, w, h)) else: w,h=self.get_text_width_height(s,prop,False) return w, h @@ -524,9 +524,9 @@ pyemf.ANSI_CHARSET, pyemf.OUT_DEFAULT_PRECIS, pyemf.CLIP_DEFAULT_PRECIS, pyemf.DEFAULT_QUALITY, pyemf.DEFAULT_PITCH | pyemf.FF_DONTCARE, face); - if debugHandle: print "get_font_handle: creating handle=%d for face=%s size=%d" % (handle,face,size) + if debugHandle: print("get_font_handle: creating handle=%d for face=%s size=%d" % (handle,face,size)) self._fontHandle[key]=handle - if debugHandle: print " found font handle %d for face=%s size=%d" % (handle,face,size) + if debugHandle: print(" found font handle %d for face=%s size=%d" % (handle,face,size)) self.set_handle("font",handle) return handle @@ -548,7 +548,7 @@ if handle is None: handle=pen.get_handle() self._fontHandle[key]=handle - if debugHandle: print " found pen handle %d" % handle + if debugHandle: print(" found pen handle %d" % handle) self.set_handle("pen",handle) if pen.style != pyemf.PS_NULL: return pen @@ -568,7 +568,7 @@ if handle is None: handle=brush.get_handle() self._fontHandle[key]=handle - if debugHandle: print " found brush handle %d" % handle + if debugHandle: print(" found brush handle %d" % handle) self.set_handle("brush",handle) return brush else: @@ -584,7 +584,7 @@ font = _fontd.get(key) if font is None: fname = findfont(prop) - if debugText: print "_get_font_ttf: name=%s" % fname + if debugText: print("_get_font_ttf: name=%s" % fname) font = FT2Font(str(fname)) _fontd[key] = font font.clear() @@ -599,9 +599,9 @@ get the width and height in display coords of the string s with FontPropertry prop, ripped right out of backend_ps """ - if debugText: print "get_text_width_height: ismath=%s properties: %s" % (str(ismath),str(prop)) + if debugText: print("get_text_width_height: ismath=%s properties: %s" % (str(ismath),str(prop))) if ismath: - if debugText: print " MATH TEXT! = %s" % str(ismath) + if debugText: print(" MATH TEXT! = %s" % str(ismath)) w,h = self.get_math_text_width_height(s, prop) return w,h @@ -610,7 +610,7 @@ w, h = font.get_width_height() w /= 64.0 # convert from subpixels h /= 64.0 - if debugText: print " text string=%s w,h=(%f,%f)" % (s, w, h) + if debugText: print(" text string=%s w,h=(%f,%f)" % (s, w, h)) return w, h @@ -688,7 +688,14 @@ # main-level app (egg backend_gtk, backend_gtkagg) for pylab FigureClass = kwargs.pop('FigureClass', Figure) thisFig = FigureClass(*args, **kwargs) - canvas = FigureCanvasEMF(thisFig) + return new_figure_manager_given_figure(num, thisFig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + canvas = FigureCanvasEMF(figure) manager = FigureManagerEMF(canvas, num) return manager diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_fltkagg.py matplotlib-1.2.0/lib/matplotlib/backends/backend_fltkagg.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_fltkagg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_fltkagg.py 2012-10-31 00:11:13.000000000 +0000 @@ -8,7 +8,7 @@ """ -from __future__ import division +from __future__ import division, print_function import os, sys, math @@ -78,6 +78,13 @@ """ FigureClass = kwargs.pop('FigureClass', Figure) figure = FigureClass(*args, **kwargs) + return new_figure_manager_given_figure(num, figure) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ window = Fltk.Fl_Double_Window(10,10,30,30) canvas = FigureCanvasFltkAgg(figure) window.end() @@ -108,7 +115,7 @@ self._source.resize(newsize) self._source.draw() t1,t2,w,h = self._source.figure.bbox.bounds - Fltk.fl_draw_image(self._source.buffer_rgba(0,0),0,0,int(w),int(h),4,0) + Fltk.fl_draw_image(self._source.buffer_rgba(),0,0,int(w),int(h),4,0) self.redraw() def blit(self,bbox=None): @@ -118,7 +125,7 @@ t1o,t2o,wo,ho = self._source.figure.bbox.bounds t1,t2,w,h = bbox.bounds x,y=int(t1),int(t2) - Fltk.fl_draw_image(self._source.buffer_rgba(x,y),x,y,int(w),int(h),4,int(wo)*4) + Fltk.fl_draw_image(self._source.buffer_rgba(),x,y,int(w),int(h),4,int(wo)*4) #self.redraw() def handle(self, event): @@ -136,6 +143,8 @@ self._key=special_key[ikey] except: self._key=None + + # TODO: Handle ctrl, alt, super modifiers. FigureCanvasBase.key_press_event(self._source, self._key) return 1 elif event == Fltk.FL_KEYUP: @@ -155,8 +164,8 @@ if self._draw_overlay: self._oldx=x self._oldy=y - if Fltk.Fl.event_clicks(): - FigureCanvasBase.button_press_event(self._source, x, yf, self._button) + if Fltk.Fl.event_clicks(): # according to docs, event_clicks() returns nonzero if this is a double click. + FigureCanvasBase.button_press_event(self._source, x, yf, self._button, dblclick=True) return 1 else: FigureCanvasBase.button_press_event(self._source, x, yf, self._button) @@ -502,7 +511,7 @@ try: base.canvas.print_figure(fname, format=format) - except IOError, msg: + except IOError as msg: err = '\n'.join(map(str, msg)) msg = 'Failed to save %s: Error msg was\n\n%s' % ( fname, err) diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_gdk.py matplotlib-1.2.0/lib/matplotlib/backends/backend_gdk.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_gdk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_gdk.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,4 @@ -from __future__ import division +from __future__ import division, print_function import math import os @@ -28,7 +28,6 @@ from matplotlib.transforms import Affine2D from matplotlib.backends._backend_gdk import pixbuf_get_pixels_array - backend_version = "%d.%d.%d" % gtk.pygtk_version _debug = False @@ -423,11 +422,15 @@ """ FigureClass = kwargs.pop('FigureClass', Figure) thisFig = FigureClass(*args, **kwargs) - canvas = FigureCanvasGDK(thisFig) + return new_figure_manager_given_figure(num, thisFig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + canvas = FigureCanvasGDK(figure) manager = FigureManagerBase(canvas, num) - # equals: - #manager = FigureManagerBase (FigureCanvasGDK (Figure(*args, **kwargs), - # num) return manager @@ -469,6 +472,3 @@ 0, 0, 0, 0, width, height) pixbuf.save(filename, format) - - def get_default_filetype(self): - return 'png' diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_gtk.py matplotlib-1.2.0/lib/matplotlib/backends/backend_gtk.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_gtk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_gtk.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,8 +1,13 @@ -from __future__ import division +from __future__ import division, print_function import os, sys, warnings def fn_name(): return sys._getframe(1).f_code.co_name +if sys.version_info[0] >= 3: + warnings.warn( + "The gtk* backends have not been tested with Python 3.x", + ImportWarning) + try: import gobject import gtk; gdk = gtk.gdk @@ -35,6 +40,7 @@ from matplotlib import markers from matplotlib import cbook from matplotlib import verbose +from matplotlib import rcParams backend_version = "%d.%d.%d" % gtk.pygtk_version @@ -84,10 +90,15 @@ """ FigureClass = kwargs.pop('FigureClass', Figure) thisFig = FigureClass(*args, **kwargs) - canvas = FigureCanvasGTK(thisFig) + return new_figure_manager_given_figure(num, thisFig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + canvas = FigureCanvasGTK(figure) manager = FigureManagerGTK(canvas, num) - # equals: - #manager = FigureManagerGTK(FigureCanvasGTK(Figure(*args, **kwargs), num) return manager @@ -183,6 +194,10 @@ 65455 : '/', 65439 : 'dec', 65421 : 'enter', + 65511 : 'super', + 65512 : 'super', + 65406 : 'alt', + 65289 : 'tab', } # Setting this as a static constant prevents @@ -198,7 +213,7 @@ gdk.POINTER_MOTION_HINT_MASK) def __init__(self, figure): - if _debug: print 'FigureCanvasGTK.%s' % fn_name() + if _debug: print('FigureCanvasGTK.%s' % fn_name()) FigureCanvasBase.__init__(self, figure) gtk.DrawingArea.__init__(self) @@ -227,6 +242,8 @@ self._idle_event_id = gobject.idle_add(self.idle_event) + self.last_downclick = {} + def destroy(self): #gtk.DrawingArea.destroy(self) self.close_event() @@ -235,7 +252,7 @@ gobject.source_remove(self._idle_draw_id) def scroll_event(self, widget, event): - if _debug: print 'FigureCanvasGTK.%s' % fn_name() + if _debug: print('FigureCanvasGTK.%s' % fn_name()) x = event.x # flipy so y=0 is bottom of canvas y = self.allocation.height - event.y @@ -247,15 +264,31 @@ return False # finish event propagation? def button_press_event(self, widget, event): - if _debug: print 'FigureCanvasGTK.%s' % fn_name() + if _debug: print('FigureCanvasGTK.%s' % fn_name()) x = event.x # flipy so y=0 is bottom of canvas y = self.allocation.height - event.y - FigureCanvasBase.button_press_event(self, x, y, event.button, guiEvent=event) + dblclick = (event.type == gdk._2BUTTON_PRESS) + if not dblclick: + # GTK is the only backend that generates a DOWN-UP-DOWN-DBLCLICK-UP event + # sequence for a double click. All other backends have a DOWN-UP-DBLCLICK-UP + # sequence. In order to provide consistency to matplotlib users, we will + # eat the extra DOWN event in the case that we detect it is part of a double + # click. + # first, get the double click time in milliseconds. + current_time = event.get_time() + last_time = self.last_downclick.get(event.button,0) + dblclick_time = gtk.settings_get_for_screen(gdk.screen_get_default()).get_property('gtk-double-click-time') + delta_time = current_time-last_time + if delta_time < dblclick_time: + del self.last_downclick[event.button] # we do not want to eat more than one event. + return False # eat. + self.last_downclick[event.button] = current_time + FigureCanvasBase.button_press_event(self, x, y, event.button, dblclick=dblclick, guiEvent=event) return False # finish event propagation? def button_release_event(self, widget, event): - if _debug: print 'FigureCanvasGTK.%s' % fn_name() + if _debug: print('FigureCanvasGTK.%s' % fn_name()) x = event.x # flipy so y=0 is bottom of canvas y = self.allocation.height - event.y @@ -263,21 +296,21 @@ return False # finish event propagation? def key_press_event(self, widget, event): - if _debug: print 'FigureCanvasGTK.%s' % fn_name() + if _debug: print('FigureCanvasGTK.%s' % fn_name()) key = self._get_key(event) - if _debug: print "hit", key + if _debug: print("hit", key) FigureCanvasBase.key_press_event(self, key, guiEvent=event) return False # finish event propagation? def key_release_event(self, widget, event): - if _debug: print 'FigureCanvasGTK.%s' % fn_name() + if _debug: print('FigureCanvasGTK.%s' % fn_name()) key = self._get_key(event) - if _debug: print "release", key + if _debug: print("release", key) FigureCanvasBase.key_release_event(self, key, guiEvent=event) return False # finish event propagation? def motion_notify_event(self, widget, event): - if _debug: print 'FigureCanvasGTK.%s' % fn_name() + if _debug: print('FigureCanvasGTK.%s' % fn_name()) if event.is_hint: x, y, state = event.window.get_pointer() else: @@ -292,23 +325,28 @@ FigureCanvasBase.leave_notify_event(self, event) def enter_notify_event(self, widget, event): - FigureCanvasBase.enter_notify_event(self, event) + x, y, state = event.window.get_pointer() + FigureCanvasBase.enter_notify_event(self, event, xy=(x,y)) def _get_key(self, event): if event.keyval in self.keyvald: key = self.keyvald[event.keyval] - elif event.keyval <256: + elif event.keyval < 256: key = chr(event.keyval) else: key = None - ctrl = event.state & gdk.CONTROL_MASK - shift = event.state & gdk.SHIFT_MASK - return key + for key_mask, prefix in ( + [gdk.MOD4_MASK, 'super'], + [gdk.MOD1_MASK, 'alt'], + [gdk.CONTROL_MASK, 'ctrl'],): + if event.state & key_mask: + key = '{}+{}'.format(prefix, key) + return key def configure_event(self, widget, event): - if _debug: print 'FigureCanvasGTK.%s' % fn_name() + if _debug: print('FigureCanvasGTK.%s' % fn_name()) if widget.window is None: return w, h = event.width, event.height @@ -359,7 +397,7 @@ Make sure _._pixmap is at least width, height, create new pixmap if necessary """ - if _debug: print 'FigureCanvasGTK.%s' % fn_name() + if _debug: print('FigureCanvasGTK.%s' % fn_name()) create_pixmap = False if width > self._pixmap_width: @@ -389,7 +427,7 @@ def expose_event(self, widget, event): """Expose_event for all GTK backends. Should not be overridden. """ - if _debug: print 'FigureCanvasGTK.%s' % fn_name() + if _debug: print('FigureCanvasGTK.%s' % fn_name()) if GTK_WIDGET_DRAWABLE(self): if self._need_redraw: @@ -435,7 +473,7 @@ if is_string_like(filename): try: pixbuf.save(filename, format) - except gobject.GError, exc: + except gobject.GError as exc: error_msg_gtk('Save figure failure:\n%s' % (exc,), parent=self) elif is_writable_file_like(filename): if hasattr(pixbuf, 'save_to_callback'): @@ -443,16 +481,13 @@ data.write(buf) try: pixbuf.save_to_callback(save_callback, format, user_data=filename) - except gobject.GError, exc: + except gobject.GError as exc: error_msg_gtk('Save figure failure:\n%s' % (exc,), parent=self) else: raise ValueError("Saving to a Python file-like object is only supported by PyGTK >= 2.8") else: raise ValueError("filename must be a path or a file-like object") - def get_default_filetype(self): - return 'png' - def new_timer(self, *args, **kwargs): """ Creates a new backend-specific subclass of :class:`backend_bases.Timer`. @@ -495,11 +530,11 @@ window : The gtk.Window (gtk only) """ def __init__(self, canvas, num): - if _debug: print 'FigureManagerGTK.%s' % fn_name() + if _debug: print('FigureManagerGTK.%s' % fn_name()) FigureManagerBase.__init__(self, canvas, num) self.window = gtk.Window() - self.window.set_title("Figure %d" % num) + self.set_window_title("Figure %d" % num) if (window_icon): try: self.window.set_icon_from_file(window_icon) @@ -516,9 +551,6 @@ self.canvas.show() - # attach a show method to the figure for pylab ease of use - self.canvas.figure.show = lambda *args: self.window.show() - self.vbox.pack_start(self.canvas, True, True) self.toolbar = self._get_toolbar(canvas) @@ -550,7 +582,7 @@ self.canvas.grab_focus() def destroy(self, *args): - if _debug: print 'FigureManagerGTK.%s' % fn_name() + if _debug: print('FigureManagerGTK.%s' % fn_name()) if hasattr(self, 'toolbar') and self.toolbar is not None: self.toolbar.destroy() if hasattr(self, 'vbox'): @@ -570,7 +602,7 @@ # show the figure window self.window.show() - def full_screen_toggle (self): + def full_screen_toggle(self): self._full_screen_flag = not self._full_screen_flag if self._full_screen_flag: self.window.fullscreen() @@ -582,14 +614,17 @@ def _get_toolbar(self, canvas): # must be inited after the window, drawingArea and figure # attrs are set - if matplotlib.rcParams['toolbar'] == 'classic': + if rcParams['toolbar'] == 'classic': toolbar = NavigationToolbar (canvas, self.window) - elif matplotlib.rcParams['toolbar'] == 'toolbar2': + elif rcParams['toolbar'] == 'toolbar2': toolbar = NavigationToolbar2GTK (canvas, self.window) else: toolbar = None return toolbar + def get_window_title(self): + return self.window.get_title() + def set_window_title(self, title): self.window.set_title(title) @@ -602,19 +637,6 @@ class NavigationToolbar2GTK(NavigationToolbar2, gtk.Toolbar): - # list of toolitems to add to the toolbar, format is: - # text, tooltip_text, image_file, callback(str) - toolitems = ( - ('Home', 'Reset original view', 'home.png', 'home'), - ('Back', 'Back to previous view','back.png', 'back'), - ('Forward', 'Forward to next view','forward.png', 'forward'), - ('Pan', 'Pan axes with left mouse, zoom with right', 'move.png','pan'), - ('Zoom', 'Zoom to rectangle','zoom_to_rect.png', 'zoom'), - (None, None, None, None), - ('Subplots', 'Configure subplots','subplots.png', 'configure_subplots'), - ('Save', 'Save the figure','filesave.png', 'save_figure'), - ) - def __init__(self, canvas, window): self.win = window gtk.Toolbar.__init__(self) @@ -649,7 +671,7 @@ w = abs(x1 - x0) h = abs(y1 - y0) - rect = [int(val)for val in min(x0,x1), min(y0, y1), w, h] + rect = [int(val)for val in (min(x0,x1), min(y0, y1), w, h)] try: lastrect, pixmapBack = self._pixmapBack except AttributeError: @@ -674,7 +696,7 @@ def _init_toolbar2_4(self): - basedir = os.path.join(matplotlib.rcParams['datapath'],'images') + basedir = os.path.join(rcParams['datapath'],'images') if not _new_tooltip_api: self.tooltips = gtk.Tooltips() @@ -682,7 +704,7 @@ if text is None: self.insert( gtk.SeparatorToolItem(), -1 ) continue - fname = os.path.join(basedir, image_file) + fname = os.path.join(basedir, image_file + '.png') image = gtk.Image() image.set_from_file(fname) tbutton = gtk.ToolButton(image, text) @@ -708,18 +730,20 @@ self.show_all() def get_filechooser(self): - return FileChooserDialog( + fc = FileChooserDialog( title='Save the figure', parent=self.win, filetypes=self.canvas.get_supported_filetypes(), default_filetype=self.canvas.get_default_filetype()) + fc.set_current_name(self.canvas.get_default_filename()) + return fc def save_figure(self, *args): fname, format = self.get_filechooser().get_filename_from_user() if fname: try: self.canvas.print_figure(fname, format=format) - except Exception, e: + except Exception as e: error_msg_gtk(str(e), parent=self) def configure_subplots(self, button): @@ -982,7 +1006,7 @@ if fname: try: self.canvas.print_figure(fname, format=format) - except Exception, e: + except Exception as e: error_msg_gtk(str(e), parent=self) @@ -1167,12 +1191,12 @@ button = self.wtree.get_widget('colorbutton_linestyle') color = button.get_color() - r, g, b = [val/65535. for val in color.red, color.green, color.blue] + r, g, b = [val/65535. for val in (color.red, color.green, color.blue)] line.set_color((r,g,b)) button = self.wtree.get_widget('colorbutton_markerface') color = button.get_color() - r, g, b = [val/65535. for val in color.red, color.green, color.blue] + r, g, b = [val/65535. for val in (color.red, color.green, color.blue)] line.set_markerfacecolor((r,g,b)) line.figure.canvas.draw() @@ -1194,12 +1218,12 @@ self.cbox_markers.set_active(self.markerd[marker]) r,g,b = colorConverter.to_rgb(line.get_color()) - color = gtk.gdk.Color(*[int(val*65535) for val in r,g,b]) + color = gtk.gdk.Color(*[int(val*65535) for val in (r,g,b)]) button = self.wtree.get_widget('colorbutton_linestyle') button.set_color(color) r,g,b = colorConverter.to_rgb(line.get_markerfacecolor()) - color = gtk.gdk.Color(*[int(val*65535) for val in r,g,b]) + color = gtk.gdk.Color(*[int(val*65535) for val in (r,g,b)]) button = self.wtree.get_widget('colorbutton_markerface') button.set_color(color) self._updateson = True @@ -1233,7 +1257,7 @@ icon_filename = 'matplotlib.png' else: icon_filename = 'matplotlib.svg' - window_icon = os.path.join(matplotlib.rcParams['datapath'], 'images', icon_filename) + window_icon = os.path.join(rcParams['datapath'], 'images', icon_filename) except: window_icon = None verbose.report('Could not load matplotlib icon: %s' % sys.exc_info()[1]) diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_gtk3.py matplotlib-1.2.0/lib/matplotlib/backends/backend_gtk3.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_gtk3.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_gtk3.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,1070 @@ +from __future__ import division + +import os, sys +def fn_name(): return sys._getframe(1).f_code.co_name + +try: + from gi.repository import Gtk, Gdk, GObject +except ImportError: + raise ImportError("GTK3 backend requires pygobject to be installed.") + +import matplotlib +from matplotlib._pylab_helpers import Gcf +from matplotlib.backend_bases import RendererBase, GraphicsContextBase, \ + FigureManagerBase, FigureCanvasBase, NavigationToolbar2, cursors, TimerBase +from matplotlib.backend_bases import ShowBase + +from matplotlib.cbook import is_string_like, is_writable_file_like +from matplotlib.colors import colorConverter +from matplotlib.figure import Figure +from matplotlib.widgets import SubplotTool + +from matplotlib import lines +from matplotlib import cbook +from matplotlib import verbose +from matplotlib import rcParams + +backend_version = "%s.%s.%s" % (Gtk.get_major_version(), Gtk.get_micro_version(), Gtk.get_minor_version()) + +_debug = False +#_debug = True + +# the true dots per inch on the screen; should be display dependent +# see http://groups.google.com/groups?q=screen+dpi+x11&hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=7077.26e81ad5%40swift.cs.tcd.ie&rnum=5 for some info about screen dpi +PIXELS_PER_INCH = 96 + +cursord = { + cursors.MOVE : Gdk.Cursor.new(Gdk.CursorType.FLEUR), + cursors.HAND : Gdk.Cursor.new(Gdk.CursorType.HAND2), + cursors.POINTER : Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR), + cursors.SELECT_REGION : Gdk.Cursor.new(Gdk.CursorType.TCROSS), + } + +def draw_if_interactive(): + """ + Is called after every pylab drawing command + """ + if matplotlib.is_interactive(): + figManager = Gcf.get_active() + if figManager is not None: + figManager.canvas.draw_idle() + +class Show(ShowBase): + def mainloop(self): + if Gtk.main_level() == 0: + Gtk.main() + +show = Show() + + +class TimerGTK3(TimerBase): + ''' + Subclass of :class:`backend_bases.TimerBase` that uses GTK3 for timer events. + + Attributes: + * interval: The time between timer events in milliseconds. Default + is 1000 ms. + * single_shot: Boolean flag indicating whether this timer should + operate as single shot (run once and then stop). Defaults to False. + * callbacks: Stores list of (func, args) tuples that will be called + upon timer events. This list can be manipulated directly, or the + functions add_callback and remove_callback can be used. + ''' + def _timer_start(self): + # Need to stop it, otherwise we potentially leak a timer id that will + # never be stopped. + self._timer_stop() + self._timer = GObject.timeout_add(self._interval, self._on_timer) + + def _timer_stop(self): + if self._timer is not None: + GObject.source_remove(self._timer) + self._timer = None + + def _timer_set_interval(self): + # Only stop and restart it if the timer has already been started + if self._timer is not None: + self._timer_stop() + self._timer_start() + + def _on_timer(self): + TimerBase._on_timer(self) + + # Gtk timeout_add() requires that the callback returns True if it + # is to be called again. + if len(self.callbacks) > 0 and not self._single: + return True + else: + self._timer = None + return False + +class FigureCanvasGTK3 (Gtk.DrawingArea, FigureCanvasBase): + keyvald = {65507 : 'control', + 65505 : 'shift', + 65513 : 'alt', + 65508 : 'control', + 65506 : 'shift', + 65514 : 'alt', + 65361 : 'left', + 65362 : 'up', + 65363 : 'right', + 65364 : 'down', + 65307 : 'escape', + 65470 : 'f1', + 65471 : 'f2', + 65472 : 'f3', + 65473 : 'f4', + 65474 : 'f5', + 65475 : 'f6', + 65476 : 'f7', + 65477 : 'f8', + 65478 : 'f9', + 65479 : 'f10', + 65480 : 'f11', + 65481 : 'f12', + 65300 : 'scroll_lock', + 65299 : 'break', + 65288 : 'backspace', + 65293 : 'enter', + 65379 : 'insert', + 65535 : 'delete', + 65360 : 'home', + 65367 : 'end', + 65365 : 'pageup', + 65366 : 'pagedown', + 65438 : '0', + 65436 : '1', + 65433 : '2', + 65435 : '3', + 65430 : '4', + 65437 : '5', + 65432 : '6', + 65429 : '7', + 65431 : '8', + 65434 : '9', + 65451 : '+', + 65453 : '-', + 65450 : '*', + 65455 : '/', + 65439 : 'dec', + 65421 : 'enter', + } + + # Setting this as a static constant prevents + # this resulting expression from leaking + event_mask = (Gdk.EventMask.BUTTON_PRESS_MASK | + Gdk.EventMask.BUTTON_RELEASE_MASK | + Gdk.EventMask.EXPOSURE_MASK | + Gdk.EventMask.KEY_PRESS_MASK | + Gdk.EventMask.KEY_RELEASE_MASK | + Gdk.EventMask.ENTER_NOTIFY_MASK | + Gdk.EventMask.LEAVE_NOTIFY_MASK | + Gdk.EventMask.POINTER_MOTION_MASK | + Gdk.EventMask.POINTER_MOTION_HINT_MASK) + + def __init__(self, figure): + if _debug: print 'FigureCanvasGTK3.%s' % fn_name() + FigureCanvasBase.__init__(self, figure) + GObject.GObject.__init__(self) + + self._idle_draw_id = 0 + self._need_redraw = True + self._lastCursor = None + + self.connect('scroll_event', self.scroll_event) + self.connect('button_press_event', self.button_press_event) + self.connect('button_release_event', self.button_release_event) + self.connect('configure_event', self.configure_event) + self.connect('draw', self.on_draw_event) + self.connect('key_press_event', self.key_press_event) + self.connect('key_release_event', self.key_release_event) + self.connect('motion_notify_event', self.motion_notify_event) + self.connect('leave_notify_event', self.leave_notify_event) + self.connect('enter_notify_event', self.enter_notify_event) + + self.set_events(self.__class__.event_mask) + + self.set_double_buffered(True) + self.set_can_focus(True) + self._renderer_init() + self._idle_event_id = GObject.idle_add(self.idle_event) + + def destroy(self): + #Gtk.DrawingArea.destroy(self) + self.close_event() + GObject.source_remove(self._idle_event_id) + if self._idle_draw_id != 0: + GObject.source_remove(self._idle_draw_id) + + def scroll_event(self, widget, event): + if _debug: print 'FigureCanvasGTK3.%s' % fn_name() + x = event.x + # flipy so y=0 is bottom of canvas + y = self.get_allocation().height - event.y + if event.direction==Gdk.ScrollDirection.UP: + step = 1 + else: + step = -1 + FigureCanvasBase.scroll_event(self, x, y, step, guiEvent=event) + return False # finish event propagation? + + def button_press_event(self, widget, event): + if _debug: print 'FigureCanvasGTK3.%s' % fn_name() + x = event.x + # flipy so y=0 is bottom of canvas + y = self.get_allocation().height - event.y + FigureCanvasBase.button_press_event(self, x, y, event.button, guiEvent=event) + return False # finish event propagation? + + def button_release_event(self, widget, event): + if _debug: print 'FigureCanvasGTK3.%s' % fn_name() + x = event.x + # flipy so y=0 is bottom of canvas + y = self.get_allocation().height - event.y + FigureCanvasBase.button_release_event(self, x, y, event.button, guiEvent=event) + return False # finish event propagation? + + def key_press_event(self, widget, event): + if _debug: print 'FigureCanvasGTK3.%s' % fn_name() + key = self._get_key(event) + if _debug: print "hit", key + FigureCanvasBase.key_press_event(self, key, guiEvent=event) + return False # finish event propagation? + + def key_release_event(self, widget, event): + if _debug: print 'FigureCanvasGTK3.%s' % fn_name() + key = self._get_key(event) + if _debug: print "release", key + FigureCanvasBase.key_release_event(self, key, guiEvent=event) + return False # finish event propagation? + + def motion_notify_event(self, widget, event): + if _debug: print 'FigureCanvasGTK3.%s' % fn_name() + if event.is_hint: + t, x, y, state = event.window.get_pointer() + else: + x, y, state = event.x, event.y, event.get_state() + + # flipy so y=0 is bottom of canvas + y = self.get_allocation().height - y + FigureCanvasBase.motion_notify_event(self, x, y, guiEvent=event) + return False # finish event propagation? + + def leave_notify_event(self, widget, event): + FigureCanvasBase.leave_notify_event(self, event) + + def enter_notify_event(self, widget, event): + FigureCanvasBase.enter_notify_event(self, event) + + def _get_key(self, event): + if event.keyval in self.keyvald: + key = self.keyvald[event.keyval] + elif event.keyval < 256: + key = chr(event.keyval) + else: + key = None + + modifiers = [ + (Gdk.ModifierType.MOD4_MASK, 'super'), + (Gdk.ModifierType.MOD1_MASK, 'alt'), + (Gdk.ModifierType.CONTROL_MASK, 'ctrl'), + ] + for key_mask, prefix in modifiers: + if event.state & key_mask: + key = '{}+{}'.format(prefix, key) + + return key + + def configure_event(self, widget, event): + if _debug: print 'FigureCanvasGTK3.%s' % fn_name() + if widget.get_property("window") is None: + return + w, h = event.width, event.height + if w < 3 or h < 3: + return # empty fig + + # resize the figure (in inches) + dpi = self.figure.dpi + self.figure.set_size_inches (w/dpi, h/dpi) + self._need_redraw = True + + return False # finish event propagation? + + def on_draw_event(self, widget, ctx): + # to be overwritten by GTK3Agg or GTK3Cairo + pass + + def draw(self): + self._need_redraw = True + if self.get_visible() and self.get_mapped(): + self.queue_draw() + # do a synchronous draw (its less efficient than an async draw, + # but is required if/when animation is used) + self.get_property("window").process_updates (False) + + def draw_idle(self): + def idle_draw(*args): + self.draw() + self._idle_draw_id = 0 + return False + if self._idle_draw_id == 0: + self._idle_draw_id = GObject.idle_add(idle_draw) + + def new_timer(self, *args, **kwargs): + """ + Creates a new backend-specific subclass of :class:`backend_bases.Timer`. + This is useful for getting periodic events through the backend's native + event loop. Implemented only for backends with GUIs. + + optional arguments: + + *interval* + Timer interval in milliseconds + *callbacks* + Sequence of (func, args, kwargs) where func(*args, **kwargs) will + be executed by the timer every *interval*. + """ + return TimerGTK3(*args, **kwargs) + + def flush_events(self): + Gdk.threads_enter() + while Gtk.events_pending(): + Gtk.main_iteration(True) + Gdk.flush() + Gdk.threads_leave() + + def start_event_loop(self,timeout): + FigureCanvasBase.start_event_loop_default(self,timeout) + start_event_loop.__doc__=FigureCanvasBase.start_event_loop_default.__doc__ + + def stop_event_loop(self): + FigureCanvasBase.stop_event_loop_default(self) + stop_event_loop.__doc__=FigureCanvasBase.stop_event_loop_default.__doc__ + +FigureCanvas = FigureCanvasGTK3 + +class FigureManagerGTK3(FigureManagerBase): + """ + Public attributes + + canvas : The FigureCanvas instance + num : The Figure number + toolbar : The Gtk.Toolbar (gtk only) + vbox : The Gtk.VBox containing the canvas and toolbar (gtk only) + window : The Gtk.Window (gtk only) + """ + def __init__(self, canvas, num): + if _debug: print 'FigureManagerGTK3.%s' % fn_name() + FigureManagerBase.__init__(self, canvas, num) + + self.window = Gtk.Window() + self.set_window_title("Figure %d" % num) + try: + self.window.set_icon_from_file(window_icon) + except (SystemExit, KeyboardInterrupt): + # re-raise exit type Exceptions + raise + except: + # some versions of gtk throw a glib.GError but not + # all, so I am not sure how to catch it. I am unhappy + # doing a blanket catch here, but am not sure what a + # better way is - JDH + verbose.report('Could not load matplotlib icon: %s' % sys.exc_info()[1]) + + self.vbox = Gtk.Box() + self.vbox.set_property("orientation", Gtk.Orientation.VERTICAL) + self.window.add(self.vbox) + self.vbox.show() + + self.canvas.show() + + self.vbox.pack_start(self.canvas, True, True, 0) + + self.toolbar = self._get_toolbar(canvas) + + # calculate size for window + w = int (self.canvas.figure.bbox.width) + h = int (self.canvas.figure.bbox.height) + + if self.toolbar is not None: + self.toolbar.show() + self.vbox.pack_end(self.toolbar, False, False, 0) + size_request = self.toolbar.size_request() + h += size_request.height + + self.window.set_default_size (w, h) + + def destroy(*args): + Gcf.destroy(num) + self.window.connect("destroy", destroy) + self.window.connect("delete_event", destroy) + if matplotlib.is_interactive(): + self.window.show() + + def notify_axes_change(fig): + 'this will be called whenever the current axes is changed' + if self.toolbar is not None: self.toolbar.update() + self.canvas.figure.add_axobserver(notify_axes_change) + + self.canvas.grab_focus() + + def destroy(self, *args): + if _debug: print 'FigureManagerGTK3.%s' % fn_name() + self.vbox.destroy() + self.window.destroy() + self.canvas.destroy() + if self.toolbar: + self.toolbar.destroy() + self.__dict__.clear() #Is this needed? Other backends don't have it. + + if Gcf.get_num_fig_managers()==0 and \ + not matplotlib.is_interactive() and \ + Gtk.main_level() >= 1: + Gtk.main_quit() + + def show(self): + # show the figure window + self.window.show() + + def full_screen_toggle (self): + self._full_screen_flag = not self._full_screen_flag + if self._full_screen_flag: + self.window.fullscreen() + else: + self.window.unfullscreen() + _full_screen_flag = False + + + def _get_toolbar(self, canvas): + # must be inited after the window, drawingArea and figure + # attrs are set + if rcParams['toolbar'] == 'classic': + toolbar = NavigationToolbar (canvas, self.window) + elif rcParams['toolbar'] == 'toolbar2': + toolbar = NavigationToolbar2GTK3 (canvas, self.window) + else: + toolbar = None + return toolbar + + def get_window_title(self): + return self.window.get_title() + + def set_window_title(self, title): + self.window.set_title(title) + + def resize(self, width, height): + 'set the canvas size in pixels' + #_, _, cw, ch = self.canvas.allocation + #_, _, ww, wh = self.window.allocation + #self.window.resize (width-cw+ww, height-ch+wh) + self.window.resize(width, height) + + +class NavigationToolbar2GTK3(NavigationToolbar2, Gtk.Toolbar): + def __init__(self, canvas, window): + self.win = window + GObject.GObject.__init__(self) + NavigationToolbar2.__init__(self, canvas) + self.ctx = None + + def set_message(self, s): + self.message.set_label(s) + + def set_cursor(self, cursor): + self.canvas.get_property("window").set_cursor(cursord[cursor]) + #self.canvas.set_cursor(cursord[cursor]) + + def release(self, event): + try: del self._pixmapBack + except AttributeError: pass + + def dynamic_update(self): + # legacy method; new method is canvas.draw_idle + self.canvas.draw_idle() + + def draw_rubberband(self, event, x0, y0, x1, y1): + 'adapted from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/189744' + self.ctx = self.canvas.get_property("window").cairo_create() + + # todo: instead of redrawing the entire figure, copy the part of + # the figure that was covered by the previous rubberband rectangle + self.canvas.draw() + + height = self.canvas.figure.bbox.height + y1 = height - y1 + y0 = height - y0 + w = abs(x1 - x0) + h = abs(y1 - y0) + rect = [int(val)for val in min(x0,x1), min(y0, y1), w, h] + + self.ctx.new_path() + self.ctx.set_line_width(0.5) + self.ctx.rectangle(rect[0], rect[1], rect[2], rect[3]) + self.ctx.set_source_rgb(0, 0, 0) + self.ctx.stroke() + + def _init_toolbar(self): + self.set_style(Gtk.ToolbarStyle.ICONS) + basedir = os.path.join(rcParams['datapath'],'images') + + for text, tooltip_text, image_file, callback in self.toolitems: + if text is None: + self.insert( Gtk.SeparatorToolItem(), -1 ) + continue + fname = os.path.join(basedir, image_file + '.png') + image = Gtk.Image() + image.set_from_file(fname) + tbutton = Gtk.ToolButton() + tbutton.set_label(text) + tbutton.set_icon_widget(image) + self.insert(tbutton, -1) + tbutton.connect('clicked', getattr(self, callback)) + tbutton.set_tooltip_text(tooltip_text) + + toolitem = Gtk.SeparatorToolItem() + self.insert(toolitem, -1) + toolitem.set_draw(False) + toolitem.set_expand(True) + + toolitem = Gtk.ToolItem() + self.insert(toolitem, -1) + self.message = Gtk.Label() + toolitem.add(self.message) + + self.show_all() + + def get_filechooser(self): + fc = FileChooserDialog( + title='Save the figure', + parent=self.win, + filetypes=self.canvas.get_supported_filetypes(), + default_filetype=self.canvas.get_default_filetype()) + fc.set_current_name(self.canvas.get_default_filename()) + return fc + + def save_figure(self, *args): + fname, format = self.get_filechooser().get_filename_from_user() + if fname: + try: + self.canvas.print_figure(fname, format=format) + except Exception, e: + error_msg_gtk(str(e), parent=self) + + def configure_subplots(self, button): + toolfig = Figure(figsize=(6,3)) + canvas = self._get_canvas(toolfig) + toolfig.subplots_adjust(top=0.9) + tool = SubplotTool(self.canvas.figure, toolfig) + + w = int (toolfig.bbox.width) + h = int (toolfig.bbox.height) + + + window = Gtk.Window() + try: + window.set_icon_from_file(window_icon) + except (SystemExit, KeyboardInterrupt): + # re-raise exit type Exceptions + raise + except: + # we presumably already logged a message on the + # failure of the main plot, don't keep reporting + pass + window.set_title("Subplot Configuration Tool") + window.set_default_size(w, h) + vbox = Gtk.Box() + vbox.set_property("orientation", Gtk.Orientation.VERTICAL) + window.add(vbox) + vbox.show() + + canvas.show() + vbox.pack_start(canvas, True, True, 0) + window.show() + + def _get_canvas(self, fig): + return self.canvas.__class__(fig) + + +class NavigationToolbar(Gtk.Toolbar): + """ + Public attributes + + canvas - the FigureCanvas (Gtk.DrawingArea) + win - the Gtk.Window + + """ + # list of toolitems to add to the toolbar, format is: + # text, tooltip_text, image, callback(str), callback_arg, scroll(bool) + toolitems = ( + ('Left', 'Pan left with click or wheel mouse (bidirectional)', + Gtk.STOCK_GO_BACK, 'panx', -1, True), + ('Right', 'Pan right with click or wheel mouse (bidirectional)', + Gtk.STOCK_GO_FORWARD, 'panx', 1, True), + ('Zoom In X', + 'Zoom In X (shrink the x axis limits) with click or wheel' + ' mouse (bidirectional)', + Gtk.STOCK_ZOOM_IN, 'zoomx', 1, True), + ('Zoom Out X', + 'Zoom Out X (expand the x axis limits) with click or wheel' + ' mouse (bidirectional)', + Gtk.STOCK_ZOOM_OUT, 'zoomx', -1, True), + (None, None, None, None, None, None,), + ('Up', 'Pan up with click or wheel mouse (bidirectional)', + Gtk.STOCK_GO_UP, 'pany', 1, True), + ('Down', 'Pan down with click or wheel mouse (bidirectional)', + Gtk.STOCK_GO_DOWN, 'pany', -1, True), + ('Zoom In Y', + 'Zoom in Y (shrink the y axis limits) with click or wheel' + ' mouse (bidirectional)', + Gtk.STOCK_ZOOM_IN, 'zoomy', 1, True), + ('Zoom Out Y', + 'Zoom Out Y (expand the y axis limits) with click or wheel' + ' mouse (bidirectional)', + Gtk.STOCK_ZOOM_OUT, 'zoomy', -1, True), + (None, None, None, None, None, None,), + ('Save', 'Save the figure', + Gtk.STOCK_SAVE, 'save_figure', None, False), + ) + + def __init__(self, canvas, window): + """ + figManager is the FigureManagerGTK3 instance that contains the + toolbar, with attributes figure, window and drawingArea + + """ + GObject.GObject.__init__(self) + + self.canvas = canvas + # Note: Gtk.Toolbar already has a 'window' attribute + self.win = window + + self.set_style(Gtk.ToolbarStyle.ICONS) + + self._create_toolitems() + self.update = self._update + self.fileselect = FileChooserDialog( + title='Save the figure', + parent=self.win, + filetypes=self.canvas.get_supported_filetypes(), + default_filetype=self.canvas.get_default_filetype()) + self.show_all() + self.update() + + def _create_toolitems(self): + iconSize = Gtk.IconSize.SMALL_TOOLBAR + + for text, tooltip_text, image_num, callback, callback_arg, scroll \ + in self.toolitems: + if text is None: + self.insert( Gtk.SeparatorToolItem(), -1 ) + continue + image = Gtk.Image() + image.set_from_stock(image_num, iconSize) + tbutton = Gtk.ToolButton() + tbutton.set_label(text) + tbutton.set_icon_widget(image) + self.insert(tbutton, -1) + if callback_arg: + tbutton.connect('clicked', getattr(self, callback), + callback_arg) + else: + tbutton.connect('clicked', getattr(self, callback)) + if scroll: + tbutton.connect('scroll_event', getattr(self, callback)) + tbutton.set_tooltip_text(tooltip_text) + + # Axes toolitem, is empty at start, update() adds a menu if >=2 axes + self.axes_toolitem = Gtk.ToolItem() + self.insert(self.axes_toolitem, 0) + self.axes_toolitem.set_tooltip_text( + 'Select axes that controls affect') + + align = Gtk.Alignment (xalign=0.5, yalign=0.5, xscale=0.0, yscale=0.0) + self.axes_toolitem.add(align) + + self.menubutton = Gtk.Button ("Axes") + align.add (self.menubutton) + + def position_menu (menu): + """Function for positioning a popup menu. + Place menu below the menu button, but ensure it does not go off + the bottom of the screen. + The default is to popup menu at current mouse position + """ + x0, y0 = self.window.get_origin() + x1, y1, m = self.window.get_pointer() + x2, y2 = self.menubutton.get_pointer() + sc_h = self.get_screen().get_height() + w, h = menu.size_request() + + x = x0 + x1 - x2 + y = y0 + y1 - y2 + self.menubutton.allocation.height + y = min(y, sc_h - h) + return x, y, True + + def button_clicked (button, data=None): + self.axismenu.popup (None, None, position_menu, 0, + Gtk.get_current_event_time()) + + self.menubutton.connect ("clicked", button_clicked) + + + def _update(self): + # called by __init__() and FigureManagerGTK3 + + self._axes = self.canvas.figure.axes + + if len(self._axes) >= 2: + self.axismenu = self._make_axis_menu() + self.menubutton.show_all() + else: + self.menubutton.hide() + + self.set_active(range(len(self._axes))) + + + def _make_axis_menu(self): + # called by self._update*() + + def toggled(item, data=None): + if item == self.itemAll: + for item in items: item.set_active(True) + elif item == self.itemInvert: + for item in items: + item.set_active(not item.get_active()) + + ind = [i for i,item in enumerate(items) if item.get_active()] + self.set_active(ind) + + menu = Gtk.Menu() + + self.itemAll = Gtk.MenuItem("All") + menu.append(self.itemAll) + self.itemAll.connect("activate", toggled) + + self.itemInvert = Gtk.MenuItem("Invert") + menu.append(self.itemInvert) + self.itemInvert.connect("activate", toggled) + + items = [] + for i in range(len(self._axes)): + item = Gtk.CheckMenuItem("Axis %d" % (i+1)) + menu.append(item) + item.connect("toggled", toggled) + item.set_active(True) + items.append(item) + + menu.show_all() + return menu + + + def set_active(self, ind): + self._ind = ind + self._active = [ self._axes[i] for i in self._ind ] + + def panx(self, button, direction): + 'panx in direction' + + for a in self._active: + a.xaxis.pan(direction) + self.canvas.draw() + self._need_redraw = True + return True + + def pany(self, button, direction): + 'pany in direction' + for a in self._active: + a.yaxis.pan(direction) + self.canvas.draw() + return True + + def zoomx(self, button, direction): + 'zoomx in direction' + for a in self._active: + a.xaxis.zoom(direction) + self.canvas.draw() + return True + + def zoomy(self, button, direction): + 'zoomy in direction' + for a in self._active: + a.yaxis.zoom(direction) + self.canvas.draw() + return True + + def get_filechooser(self): + return FileChooserDialog( + title='Save the figure', + parent=self.win, + filetypes=self.canvas.get_supported_filetypes(), + default_filetype=self.canvas.get_default_filetype()) + + def save_figure(self, *args): + fname, format = self.get_filechooser().get_filename_from_user() + if fname: + try: + self.canvas.print_figure(fname, format=format) + except Exception, e: + error_msg_gtk(str(e), parent=self) + + +class FileChooserDialog(Gtk.FileChooserDialog): + """GTK+ file selector which remembers the last file/directory + selected and presents the user with a menu of supported image formats + """ + def __init__ (self, + title = 'Save file', + parent = None, + action = Gtk.FileChooserAction.SAVE, + buttons = (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, + Gtk.STOCK_SAVE, Gtk.ResponseType.OK), + path = None, + filetypes = [], + default_filetype = None + ): + super (FileChooserDialog, self).__init__ (title, parent, action, + buttons) + self.set_default_response (Gtk.ResponseType.OK) + + if not path: path = os.getcwd() + os.sep + + # create an extra widget to list supported image formats + self.set_current_folder (path) + self.set_current_name ('image.' + default_filetype) + + hbox = Gtk.Box(spacing=10) + hbox.pack_start(Gtk.Label(label="File Format:"), False, False, 0) + + liststore = Gtk.ListStore(GObject.TYPE_STRING) + cbox = Gtk.ComboBox() #liststore) + cbox.set_model(liststore) + cell = Gtk.CellRendererText() + cbox.pack_start(cell, True) + cbox.add_attribute(cell, 'text', 0) + hbox.pack_start(cbox, False, False, 0) + + self.filetypes = filetypes + self.sorted_filetypes = filetypes.items() + self.sorted_filetypes.sort() + default = 0 + for i, (ext, name) in enumerate(self.sorted_filetypes): + liststore.append(["%s (*.%s)" % (name, ext)]) + if ext == default_filetype: + default = i + cbox.set_active(default) + self.ext = default_filetype + + def cb_cbox_changed (cbox, data=None): + """File extension changed""" + head, filename = os.path.split(self.get_filename()) + root, ext = os.path.splitext(filename) + ext = ext[1:] + new_ext = self.sorted_filetypes[cbox.get_active()][0] + self.ext = new_ext + + if ext in self.filetypes: + filename = root + '.' + new_ext + elif ext == '': + filename = filename.rstrip('.') + '.' + new_ext + + self.set_current_name (filename) + cbox.connect ("changed", cb_cbox_changed) + + hbox.show_all() + self.set_extra_widget(hbox) + + def get_filename_from_user (self): + while True: + filename = None + if self.run() != int(Gtk.ResponseType.OK): + break + filename = self.get_filename() + break + + self.hide() + return filename, self.ext + +class DialogLineprops: + """ + A GUI dialog for controlling lineprops + """ + signals = ( + 'on_combobox_lineprops_changed', + 'on_combobox_linestyle_changed', + 'on_combobox_marker_changed', + 'on_colorbutton_linestyle_color_set', + 'on_colorbutton_markerface_color_set', + 'on_dialog_lineprops_okbutton_clicked', + 'on_dialog_lineprops_cancelbutton_clicked', + ) + + linestyles = [ls for ls in lines.Line2D.lineStyles if ls.strip()] + linestyled = dict([ (s,i) for i,s in enumerate(linestyles)]) + + + markers = [m for m in lines.Line2D.markers if cbook.is_string_like(m)] + + markerd = dict([(s,i) for i,s in enumerate(markers)]) + + def __init__(self, lines): + import Gtk.glade + + datadir = matplotlib.get_data_path() + gladefile = os.path.join(datadir, 'lineprops.glade') + if not os.path.exists(gladefile): + raise IOError('Could not find gladefile lineprops.glade in %s'%datadir) + + self._inited = False + self._updateson = True # suppress updates when setting widgets manually + self.wtree = Gtk.glade.XML(gladefile, 'dialog_lineprops') + self.wtree.signal_autoconnect(dict([(s, getattr(self, s)) for s in self.signals])) + + self.dlg = self.wtree.get_widget('dialog_lineprops') + + self.lines = lines + + cbox = self.wtree.get_widget('combobox_lineprops') + cbox.set_active(0) + self.cbox_lineprops = cbox + + cbox = self.wtree.get_widget('combobox_linestyles') + for ls in self.linestyles: + cbox.append_text(ls) + cbox.set_active(0) + self.cbox_linestyles = cbox + + cbox = self.wtree.get_widget('combobox_markers') + for m in self.markers: + cbox.append_text(m) + cbox.set_active(0) + self.cbox_markers = cbox + self._lastcnt = 0 + self._inited = True + + + def show(self): + 'populate the combo box' + self._updateson = False + # flush the old + cbox = self.cbox_lineprops + for i in range(self._lastcnt-1,-1,-1): + cbox.remove_text(i) + + # add the new + for line in self.lines: + cbox.append_text(line.get_label()) + cbox.set_active(0) + + self._updateson = True + self._lastcnt = len(self.lines) + self.dlg.show() + + def get_active_line(self): + 'get the active line' + ind = self.cbox_lineprops.get_active() + line = self.lines[ind] + return line + + def get_active_linestyle(self): + 'get the active lineinestyle' + ind = self.cbox_linestyles.get_active() + ls = self.linestyles[ind] + return ls + + def get_active_marker(self): + 'get the active lineinestyle' + ind = self.cbox_markers.get_active() + m = self.markers[ind] + return m + + def _update(self): + 'update the active line props from the widgets' + if not self._inited or not self._updateson: return + line = self.get_active_line() + ls = self.get_active_linestyle() + marker = self.get_active_marker() + line.set_linestyle(ls) + line.set_marker(marker) + + button = self.wtree.get_widget('colorbutton_linestyle') + color = button.get_color() + r, g, b = [val/65535. for val in color.red, color.green, color.blue] + line.set_color((r,g,b)) + + button = self.wtree.get_widget('colorbutton_markerface') + color = button.get_color() + r, g, b = [val/65535. for val in color.red, color.green, color.blue] + line.set_markerfacecolor((r,g,b)) + + line.figure.canvas.draw() + + def on_combobox_lineprops_changed(self, item): + 'update the widgets from the active line' + if not self._inited: return + self._updateson = False + line = self.get_active_line() + + ls = line.get_linestyle() + if ls is None: ls = 'None' + self.cbox_linestyles.set_active(self.linestyled[ls]) + + marker = line.get_marker() + if marker is None: marker = 'None' + self.cbox_markers.set_active(self.markerd[marker]) + + r,g,b = colorConverter.to_rgb(line.get_color()) + color = Gdk.Color(*[int(val*65535) for val in r,g,b]) + button = self.wtree.get_widget('colorbutton_linestyle') + button.set_color(color) + + r,g,b = colorConverter.to_rgb(line.get_markerfacecolor()) + color = Gdk.Color(*[int(val*65535) for val in r,g,b]) + button = self.wtree.get_widget('colorbutton_markerface') + button.set_color(color) + self._updateson = True + + def on_combobox_linestyle_changed(self, item): + self._update() + + def on_combobox_marker_changed(self, item): + self._update() + + def on_colorbutton_linestyle_color_set(self, button): + self._update() + + def on_colorbutton_markerface_color_set(self, button): + 'called colorbutton marker clicked' + self._update() + + def on_dialog_lineprops_okbutton_clicked(self, button): + self._update() + self.dlg.hide() + + def on_dialog_lineprops_cancelbutton_clicked(self, button): + self.dlg.hide() + + +# Define the file to use as the GTk icon +if sys.platform == 'win32': + icon_filename = 'matplotlib.png' +else: + icon_filename = 'matplotlib.svg' +window_icon = os.path.join(matplotlib.rcParams['datapath'], 'images', icon_filename) + + +def error_msg_gtk(msg, parent=None): + if parent is not None: # find the toplevel Gtk.Window + parent = parent.get_toplevel() + if not parent.is_toplevel(): + parent = None + + if not is_string_like(msg): + msg = ','.join(map(str,msg)) + + dialog = Gtk.MessageDialog( + parent = parent, + type = Gtk.MessageType.ERROR, + buttons = Gtk.ButtonsType.OK, + message_format = msg) + dialog.run() + dialog.destroy() diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_gtk3agg.py matplotlib-1.2.0/lib/matplotlib/backends/backend_gtk3agg.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_gtk3agg.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_gtk3agg.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,94 @@ +import cairo +import numpy as np +import sys +import warnings + +import backend_agg +import backend_gtk3 +from matplotlib.figure import Figure +from matplotlib import transforms + +if sys.version_info[0] >= 3: + warnings.warn("The Gtk3Agg backend is not known to work on Python 3.x.") + + +class FigureCanvasGTK3Agg(backend_gtk3.FigureCanvasGTK3, + backend_agg.FigureCanvasAgg): + def __init__(self, figure): + backend_gtk3.FigureCanvasGTK3.__init__(self, figure) + self._bbox_queue = [] + + def _renderer_init(self): + pass + + def _render_figure(self, width, height): + backend_agg.FigureCanvasAgg.draw(self) + + def on_draw_event(self, widget, ctx): + """ GtkDrawable draw event, like expose_event in GTK 2.X + """ + allocation = self.get_allocation() + w, h = allocation.width, allocation.height + + if not len(self._bbox_queue): + if self._need_redraw: + self._render_figure(w, h) + bbox_queue = [transforms.Bbox([[0, 0], [w, h]])] + else: + return + else: + bbox_queue = self._bbox_queue + + for bbox in bbox_queue: + area = self.copy_from_bbox(bbox) + buf = np.fromstring(area.to_string_argb(), dtype='uint8') + + x = int(bbox.x0) + y = h - int(bbox.y1) + width = int(bbox.x1) - int(bbox.x0) + height = int(bbox.y1) - int(bbox.y0) + + image = cairo.ImageSurface.create_for_data( + buf, cairo.FORMAT_ARGB32, width, height) + ctx.set_source_surface(image, x, y) + ctx.paint() + + if len(self._bbox_queue): + self._bbox_queue = [] + + return False + + def blit(self, bbox=None): + self._bbox_queue.append(bbox) + self.queue_draw() + + def print_png(self, filename, *args, **kwargs): + # Do this so we can save the resolution of figure in the PNG file + agg = self.switch_backends(backend_agg.FigureCanvasAgg) + return agg.print_png(filename, *args, **kwargs) + + +class FigureManagerGTK3Agg(backend_gtk3.FigureManagerGTK3): + pass + + +def new_figure_manager(num, *args, **kwargs): + """ + Create a new figure manager instance + """ + FigureClass = kwargs.pop('FigureClass', Figure) + thisFig = FigureClass(*args, **kwargs) + return new_figure_manager_given_figure(num, thisFig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + canvas = FigureCanvasGTK3Agg(figure) + manager = FigureManagerGTK3Agg(canvas, num) + return manager + + +FigureManager = FigureManagerGTK3Agg +show = backend_gtk3.show diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_gtk3cairo.py matplotlib-1.2.0/lib/matplotlib/backends/backend_gtk3cairo.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_gtk3cairo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_gtk3cairo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,61 @@ +import backend_gtk3 +import backend_cairo +from matplotlib.figure import Figure + +class RendererGTK3Cairo(backend_cairo.RendererCairo): + def set_context(self, ctx): + self.gc.ctx = ctx + + +class FigureCanvasGTK3Cairo(backend_gtk3.FigureCanvasGTK3, + backend_cairo.FigureCanvasCairo): + def __init__(self, figure): + backend_gtk3.FigureCanvasGTK3.__init__(self, figure) + + def _renderer_init(self): + """use cairo renderer""" + self._renderer = RendererGTK3Cairo(self.figure.dpi) + + def _render_figure(self, width, height): + self._renderer.set_width_height (width, height) + self.figure.draw (self._renderer) + + def on_draw_event(self, widget, ctx): + """ GtkDrawable draw event, like expose_event in GTK 2.X + """ + # the _need_redraw flag doesnt work. it sometimes prevents + # the rendering and leaving the canvas blank + #if self._need_redraw: + self._renderer.set_context(ctx) + allocation = self.get_allocation() + x, y, w, h = allocation.x, allocation.y, allocation.width, allocation.height + self._render_figure(w, h) + #self._need_redraw = False + + return False # finish event propagation? + + +class FigureManagerGTK3Cairo(backend_gtk3.FigureManagerGTK3): + pass + + +def new_figure_manager(num, *args, **kwargs): + """ + Create a new figure manager instance + """ + FigureClass = kwargs.pop('FigureClass', Figure) + thisFig = FigureClass(*args, **kwargs) + return new_figure_manager_given_figure(num, thisFig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + canvas = FigureCanvasGTK3Cairo(figure) + manager = FigureManagerGTK3Cairo(canvas, num) + return manager + + +FigureManager = FigureManagerGTK3Cairo +show = backend_gtk3.show diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_gtkagg.py matplotlib-1.2.0/lib/matplotlib/backends/backend_gtkagg.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_gtkagg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_gtkagg.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,7 @@ """ Render to gtk from agg """ -from __future__ import division +from __future__ import division, print_function import os import matplotlib @@ -33,16 +33,25 @@ toolbar = None return toolbar + def new_figure_manager(num, *args, **kwargs): """ Create a new figure manager instance """ - if DEBUG: print 'backend_gtkagg.new_figure_manager' + if DEBUG: print('backend_gtkagg.new_figure_manager') FigureClass = kwargs.pop('FigureClass', Figure) thisFig = FigureClass(*args, **kwargs) - canvas = FigureCanvasGTKAgg(thisFig) + return new_figure_manager_given_figure(num, thisFig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + canvas = FigureCanvasGTKAgg(figure) return FigureManagerGTKAgg(canvas, num) - if DEBUG: print 'backend_gtkagg.new_figure_manager done' + if DEBUG: print('backend_gtkagg.new_figure_manager done') + class FigureCanvasGTKAgg(FigureCanvasGTK, FigureCanvasAgg): filetypes = FigureCanvasGTK.filetypes.copy() @@ -50,7 +59,7 @@ def configure_event(self, widget, event=None): - if DEBUG: print 'FigureCanvasGTKAgg.configure_event' + if DEBUG: print('FigureCanvasGTKAgg.configure_event') if widget.window is None: return try: @@ -67,16 +76,16 @@ self.figure.set_size_inches(winch, hinch) self._need_redraw = True self.resize_event() - if DEBUG: print 'FigureCanvasGTKAgg.configure_event end' + if DEBUG: print('FigureCanvasGTKAgg.configure_event end') return True def _render_figure(self, pixmap, width, height): - if DEBUG: print 'FigureCanvasGTKAgg.render_figure' + if DEBUG: print('FigureCanvasGTKAgg.render_figure') FigureCanvasAgg.draw(self) - if DEBUG: print 'FigureCanvasGTKAgg.render_figure pixmap', pixmap + if DEBUG: print('FigureCanvasGTKAgg.render_figure pixmap', pixmap) #agg_to_gtk_drawable(pixmap, self.renderer._renderer, None) - buf = self.buffer_rgba(0,0) + buf = self.buffer_rgba() ren = self.get_renderer() w = int(ren.width) h = int(ren.height) @@ -85,23 +94,24 @@ buf, gtk.gdk.COLORSPACE_RGB, True, 8, w, h, w*4) pixmap.draw_pixbuf(pixmap.new_gc(), pixbuf, 0, 0, 0, 0, w, h, gtk.gdk.RGB_DITHER_NONE, 0, 0) - if DEBUG: print 'FigureCanvasGTKAgg.render_figure done' + if DEBUG: print('FigureCanvasGTKAgg.render_figure done') def blit(self, bbox=None): - if DEBUG: print 'FigureCanvasGTKAgg.blit', self._pixmap + if DEBUG: print('FigureCanvasGTKAgg.blit', self._pixmap) agg_to_gtk_drawable(self._pixmap, self.renderer._renderer, bbox) x, y, w, h = self.allocation self.window.draw_drawable (self.style.fg_gc[self.state], self._pixmap, 0, 0, 0, 0, w, h) - if DEBUG: print 'FigureCanvasGTKAgg.done' + if DEBUG: print('FigureCanvasGTKAgg.done') def print_png(self, filename, *args, **kwargs): # Do this so we can save the resolution of figure in the PNG file agg = self.switch_backends(FigureCanvasAgg) return agg.print_png(filename, *args, **kwargs) + """\ Traceback (most recent call last): File "/home/titan/johnh/local/lib/python2.3/site-packages/matplotlib/backends/backend_gtk.py", line 304, in expose_event diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_gtkcairo.py matplotlib-1.2.0/lib/matplotlib/backends/backend_gtkcairo.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_gtkcairo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_gtkcairo.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,6 +2,8 @@ GTK+ Matplotlib interface using cairo (not GDK) drawing operations. Author: Steve Chaplin """ +from __future__ import print_function + import gtk if gtk.pygtk_version < (2,7,0): import cairo.gtk @@ -21,10 +23,17 @@ """ Create a new figure manager instance """ - if _debug: print 'backend_gtkcairo.%s()' % fn_name() + if _debug: print('backend_gtkcairo.%s()' % fn_name()) FigureClass = kwargs.pop('FigureClass', Figure) thisFig = FigureClass(*args, **kwargs) - canvas = FigureCanvasGTKCairo(thisFig) + return new_figure_manager_given_figure(num, thisFig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + canvas = FigureCanvasGTKCairo(figure) return FigureManagerGTK(canvas, num) @@ -43,7 +52,7 @@ def _renderer_init(self): """Override to use cairo (rather than GDK) renderer""" - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) + if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name())) self._renderer = RendererGTKCairo (self.figure.dpi) diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_macosx.py matplotlib-1.2.0/lib/matplotlib/backends/backend_macosx.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_macosx.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_macosx.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,4 @@ -from __future__ import division +from __future__ import division, print_function import os import numpy @@ -13,19 +13,20 @@ from matplotlib.path import Path from matplotlib.mathtext import MathTextParser from matplotlib.colors import colorConverter - +from matplotlib import rcParams from matplotlib.widgets import SubplotTool import matplotlib from matplotlib.backends import _macosx + class Show(ShowBase): def mainloop(self): _macosx.show() - show = Show() + class RendererMac(RendererBase): """ The renderer handles drawing/rendering operations. Most of the renderer's @@ -41,6 +42,7 @@ self.width = width self.height = height self.gc = GraphicsContextMac() + self.gc.set_dpi(self.dpi) self.mathtext_parser = MathTextParser('MacOSX') def set_width_height (self, width, height): @@ -60,43 +62,36 @@ def draw_path_collection(self, gc, master_transform, paths, all_transforms, offsets, offsetTrans, facecolors, edgecolors, - linewidths, linestyles, antialiaseds, urls): - cliprect = gc.get_clip_rectangle() - clippath, clippath_transform = gc.get_clip_path() - if all_transforms: - transforms = [numpy.dot(master_transform, t) for t in all_transforms] + linewidths, linestyles, antialiaseds, urls, + offset_position): + if offset_position=='data': + offset_position = True else: - transforms = [master_transform] - gc.draw_path_collection(cliprect, - clippath, - clippath_transform, - paths, - transforms, - offsets, - offsetTrans, - facecolors, - edgecolors, - linewidths, - linestyles, - antialiaseds) + offset_position = False + path_ids = [] + for path, transform in self._iter_collection_raw_paths( + master_transform, paths, all_transforms): + path_ids.append((path, transform)) + master_transform = master_transform.get_matrix() + all_transforms = [t.get_matrix() for t in all_transforms] + offsetTrans = offsetTrans.get_matrix() + gc.draw_path_collection(master_transform, path_ids, all_transforms, + offsets, offsetTrans, facecolors, edgecolors, + linewidths, linestyles, antialiaseds, + offset_position) def draw_quad_mesh(self, gc, master_transform, meshWidth, meshHeight, coordinates, offsets, offsetTrans, facecolors, - antialiased, showedges): - cliprect = gc.get_clip_rectangle() - clippath, clippath_transform = gc.get_clip_path() - gc.draw_quad_mesh(master_transform, - cliprect, - clippath, - clippath_transform, + antialiased, edgecolors): + gc.draw_quad_mesh(master_transform.get_matrix(), meshWidth, meshHeight, coordinates, offsets, - offsetTrans, + offsetTrans.get_matrix(), facecolors, antialiased, - showedges) + edgecolors) def new_gc(self): self.gc.save() @@ -135,7 +130,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False): if ismath: - self._draw_mathtext(gc, x, y, s, prop, angle) + self._draw_mathtext(gc, x, y, s, prop, angle) else: family = prop.get_family() weight = prop.get_weight() @@ -173,6 +168,7 @@ def option_image_nocomposite(self): return True + class GraphicsContextMac(_macosx.GraphicsContext, GraphicsContextBase): """ The GraphicsContext wraps a Quartz graphics context. All methods @@ -210,6 +206,7 @@ path = path.get_fully_transformed_path() _macosx.GraphicsContext.set_clip_path(self, path) + ######################################################################## # # The following functions and classes are for pylab and implement @@ -224,7 +221,7 @@ it will be redrawn as soon as the event loop resumes via PyOS_InputHook. This function should be called after each draw event, even if matplotlib is not running interactively. - """ + """ if matplotlib.is_interactive(): figManager = Gcf.get_active() if figManager is not None: @@ -237,13 +234,25 @@ """ if not _macosx.verify_main_display(): import warnings - warnings.warn("Python is not installed as a framework. The MacOSX backend may not work correctly if Python is not installed as a framework. Please see the Python documentation for more information on installing Python as a framework on Mac OS X") + warnings.warn("Python is not installed as a framework. The MacOSX " + "backend may not work correctly if Python is not " + "installed as a framework. Please see the Python " + "documentation for more information on installing " + "Python as a framework on Mac OS X") FigureClass = kwargs.pop('FigureClass', Figure) figure = FigureClass(*args, **kwargs) + return new_figure_manager_given_figure(num, figure) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ canvas = FigureCanvasMac(figure) manager = FigureManagerMac(canvas, num) return manager + class TimerMac(_macosx.Timer, TimerBase): ''' Subclass of :class:`backend_bases.TimerBase` that uses CoreFoundation @@ -261,7 +270,6 @@ # completely implemented at the C-level (in _macosx.Timer) - class FigureCanvasMac(_macosx.FigureCanvas, FigureCanvasBase): """ The canvas the figure renders into. Calls the draw and print fig @@ -308,7 +316,7 @@ width, height = self.figure.get_size_inches() width, height = width*dpi, height*dpi filename = unicode(filename) - self.write_bitmap(filename, width, height) + self.write_bitmap(filename, width, height, dpi) self.figure.dpi = old_dpi def print_bmp(self, filename, *args, **kwargs): @@ -329,9 +337,6 @@ def print_gif(self, filename, *args, **kwargs): self._print_bitmap(filename, *args, **kwargs) - def get_default_filetype(self): - return 'png' - def new_timer(self, *args, **kwargs): """ Creates a new backend-specific subclass of :class:`backend_bases.Timer`. @@ -348,6 +353,7 @@ """ return TimerMac(*args, **kwargs) + class FigureManagerMac(_macosx.FigureManager, FigureManagerBase): """ Wrap everything up into a window for the pylab interface @@ -356,9 +362,9 @@ FigureManagerBase.__init__(self, canvas, num) title = "Figure %d" % num _macosx.FigureManager.__init__(self, canvas, title) - if matplotlib.rcParams['toolbar']=='classic': + if rcParams['toolbar']=='classic': self.toolbar = NavigationToolbarMac(canvas) - elif matplotlib.rcParams['toolbar']=='toolbar2': + elif rcParams['toolbar']=='toolbar2': self.toolbar = NavigationToolbar2Mac(canvas) else: self.toolbar = None @@ -370,20 +376,18 @@ if self.toolbar != None: self.toolbar.update() self.canvas.figure.add_axobserver(notify_axes_change) - # This is ugly, but this is what tkagg and gtk are doing. - # It is needed to get ginput() working. - self.canvas.figure.show = lambda *args: self.show() if matplotlib.is_interactive(): self.show() def close(self): Gcf.destroy(self.num) + class NavigationToolbarMac(_macosx.NavigationToolbar): def __init__(self, canvas): self.canvas = canvas - basedir = os.path.join(matplotlib.rcParams['datapath'], "images") + basedir = os.path.join(rcParams['datapath'], "images") images = {} for imagename in ("stock_left", "stock_right", @@ -441,18 +445,20 @@ self.canvas.invalidate() def save_figure(self, *args): - filename = _macosx.choose_save_file('Save the figure') + filename = _macosx.choose_save_file('Save the figure', + self.canvas.get_default_filename()) if filename is None: # Cancel return self.canvas.print_figure(filename) + class NavigationToolbar2Mac(_macosx.NavigationToolbar2, NavigationToolbar2): def __init__(self, canvas): NavigationToolbar2.__init__(self, canvas) def _init_toolbar(self): - basedir = os.path.join(matplotlib.rcParams['datapath'], "images") + basedir = os.path.join(rcParams['datapath'], "images") _macosx.NavigationToolbar2.__init__(self, basedir) def draw_rubberband(self, event, x0, y0, x1, y1): @@ -465,7 +471,8 @@ _macosx.set_cursor(cursor) def save_figure(self, *args): - filename = _macosx.choose_save_file('Save the figure') + filename = _macosx.choose_save_file('Save the figure', + self.canvas.get_default_filename()) if filename is None: # Cancel return self.canvas.print_figure(filename) @@ -480,6 +487,9 @@ def set_message(self, message): _macosx.NavigationToolbar2.set_message(self, message.encode('utf-8')) + def dynamic_update(self): + self.canvas.draw_idle() + ######################################################################## # # Now just provide the standard names that backend.__init__ is expecting diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_mixed.py matplotlib-1.2.0/lib/matplotlib/backends/backend_mixed.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_mixed.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_mixed.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function from matplotlib._image import frombuffer from matplotlib.backends.backend_agg import RendererAgg from matplotlib.tight_bbox import process_figure_for_rasterizing diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_pdf.py matplotlib-1.2.0/lib/matplotlib/backends/backend_pdf.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_pdf.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_pdf.py 2012-11-08 02:24:13.000000000 +0000 @@ -1,9 +1,10 @@ # -*- coding: iso-8859-1 -*- + """ -A PDF matplotlib backend (not yet complete) +A PDF matplotlib backend Author: Jouni K Seppnen """ -from __future__ import division +from __future__ import division, print_function import codecs import os @@ -15,7 +16,10 @@ import numpy as np -from cStringIO import StringIO +if sys.version_info[0] >= 3: + from io import BytesIO +else: + from cStringIO import StringIO as BytesIO from datetime import datetime from math import ceil, cos, floor, pi, sin try: @@ -105,11 +109,11 @@ if currpos + length < linelen: currpos += length + 1 else: - result.append(' '.join(strings[lasti:i])) + result.append(b' '.join(strings[lasti:i])) lasti = i currpos = length - result.append(' '.join(strings[lasti:])) - return '\n'.join(result) + result.append(b' '.join(strings[lasti:])) + return b'\n'.join(result) # PDF strings are supposed to be able to include any eight-bit data, # except that unbalanced parens and backslashes must be escaped by a @@ -117,12 +121,12 @@ # character may get read as a newline; these characters correspond to # \gamma and \Omega in TeX's math font encoding. Escaping them fixes # the bug. -_string_escape_regex = re.compile(r'([\\()\r\n])') +_string_escape_regex = re.compile(br'([\\()\r\n])') def _string_escape(match): m = match.group(0) - if m in r'\()': return '\\' + m - elif m == '\n': return r'\n' - elif m == '\r': return r'\r' + if m in br'\()': return b'\\' + m + elif m == b'\n': return br'\n' + elif m == b'\r': return br'\r' assert False def pdfRepr(obj): @@ -135,20 +139,20 @@ # Floats. PDF does not have exponential notation (1.0e-10) so we # need to use %f with some precision. Perhaps the precision # should adapt to the magnitude of the number? - elif isinstance(obj, float): + elif isinstance(obj, (float, np.floating)): if not np.isfinite(obj): - raise ValueError, "Can only output finite numbers in PDF" - r = "%.10f" % obj - return r.rstrip('0').rstrip('.') + raise ValueError("Can only output finite numbers in PDF") + r = ("%.10f" % obj).encode('ascii') + return r.rstrip(b'0').rstrip(b'.') # Booleans. Needs to be tested before integers since # isinstance(True, int) is true. elif isinstance(obj, bool): - return ['false', 'true'][obj] + return [b'false', b'true'][obj] # Integers are written as such. - elif isinstance(obj, (int, long)): - return "%d" % obj + elif isinstance(obj, (int, long, np.integer)): + return ("%d" % obj).encode('ascii') # Unicode strings are encoded in UTF-16BE with byte-order mark. elif isinstance(obj, unicode): @@ -164,30 +168,30 @@ # escaped. Actually balanced parens are allowed, but it is # simpler to escape them all. TODO: cut long strings into lines; # I believe there is some maximum line length in PDF. - elif is_string_like(obj): - return '(' + _string_escape_regex.sub(_string_escape, obj) + ')' + elif isinstance(obj, bytes): + return b'(' + _string_escape_regex.sub(_string_escape, obj) + b')' # Dictionaries. The keys must be PDF names, so if we find strings # there, we make Name objects from them. The values may be # anything, so the caller must ensure that PDF names are # represented as Name objects. elif isinstance(obj, dict): - r = ["<<"] - r.extend(["%s %s" % (Name(key).pdfRepr(), pdfRepr(val)) - for key, val in obj.items()]) - r.append(">>") + r = [b"<<"] + r.extend([Name(key).pdfRepr() + b" " + pdfRepr(val) + for key, val in obj.iteritems()]) + r.append(b">>") return fill(r) # Lists. elif isinstance(obj, (list, tuple)): - r = ["["] + r = [b"["] r.extend([pdfRepr(val) for val in obj]) - r.append("]") + r.append(b"]") return fill(r) # The null keyword. elif obj is None: - return 'null' + return b'null' # A date. elif isinstance(obj, datetime): @@ -204,9 +208,8 @@ return fill([pdfRepr(val) for val in obj.bounds]) else: - raise TypeError, \ - "Don't know a PDF representation for %s objects." \ - % type(obj) + raise TypeError("Don't know a PDF representation for %s objects." \ + % type(obj)) class Reference(object): """PDF reference object. @@ -220,13 +223,13 @@ return "" % self.id def pdfRepr(self): - return "%d 0 R" % self.id + return ("%d 0 R" % self.id).encode('ascii') def write(self, contents, file): write = file.write - write("%d 0 obj\n" % self.id) + write(("%d 0 obj\n" % self.id).encode('ascii')) write(pdfRepr(contents)) - write("\nendobj\n") + write(b"\nendobj\n") class Name(object): """PDF name object.""" @@ -237,20 +240,22 @@ if isinstance(name, Name): self.name = name.name else: - self.name = self._regex.sub(Name.hexify, name) + if isinstance(name, bytes): + name = name.decode('ascii') + self.name = self._regex.sub(Name.hexify, name).encode('ascii') def __repr__(self): return "" % self.name def __str__(self): - return '/' + self.name + return '/' + unicode(self.name) @staticmethod def hexify(match): return '#%02x' % ord(match.group()) def pdfRepr(self): - return '/' + self.name + return b'/' + self.name class Operator(object): """PDF operator object.""" @@ -266,24 +271,47 @@ return self.op # PDF operators (not an exhaustive list) -_pdfops = dict(close_fill_stroke='b', fill_stroke='B', fill='f', - closepath='h', close_stroke='s', stroke='S', endpath='n', - begin_text='BT', end_text='ET', - curveto='c', rectangle='re', lineto='l', moveto='m', - concat_matrix='cm', - use_xobject='Do', - setgray_stroke='G', setgray_nonstroke='g', - setrgb_stroke='RG', setrgb_nonstroke='rg', - setcolorspace_stroke='CS', setcolorspace_nonstroke='cs', - setcolor_stroke='SCN', setcolor_nonstroke='scn', - setdash='d', setlinejoin='j', setlinecap='J', setgstate='gs', - gsave='q', grestore='Q', - textpos='Td', selectfont='Tf', textmatrix='Tm', - show='Tj', showkern='TJ', - setlinewidth='w', clip='W', shading='sh') +_pdfops = dict(close_fill_stroke=b'b', fill_stroke=b'B', fill=b'f', + closepath=b'h', close_stroke=b's', stroke=b'S', endpath=b'n', + begin_text=b'BT', end_text=b'ET', + curveto=b'c', rectangle=b're', lineto=b'l', moveto=b'm', + concat_matrix=b'cm', + use_xobject=b'Do', + setgray_stroke=b'G', setgray_nonstroke=b'g', + setrgb_stroke=b'RG', setrgb_nonstroke=b'rg', + setcolorspace_stroke=b'CS', setcolorspace_nonstroke=b'cs', + setcolor_stroke=b'SCN', setcolor_nonstroke=b'scn', + setdash=b'd', setlinejoin=b'j', setlinecap=b'J', setgstate=b'gs', + gsave=b'q', grestore=b'Q', + textpos=b'Td', selectfont=b'Tf', textmatrix=b'Tm', + show=b'Tj', showkern=b'TJ', + setlinewidth=b'w', clip=b'W', shading=b'sh') Op = Bunch(**dict([(name, Operator(value)) - for name, value in _pdfops.items()])) + for name, value in _pdfops.iteritems()])) + +def _paint_path(closep, fillp, strokep): + """Return the PDF operator to paint a path in the following way: + closep: close the path before painting + fillp: fill the path with the fill color + strokep: stroke the outline of the path with the line color""" + if strokep: + if closep: + if fillp: + return Op.close_fill_stroke + else: + return Op.close_stroke + else: + if fillp: + return Op.fill_stroke + else: + return Op.stroke + else: + if fillp: + return Op.fill + else: + return Op.endpath +Op.paint_path = _paint_path class Stream(object): """PDF stream object. @@ -310,21 +338,21 @@ if rcParams['pdf.compression']: self.compressobj = zlib.compressobj(rcParams['pdf.compression']) if self.len is None: - self.file = StringIO() + self.file = BytesIO() else: self._writeHeader() self.pos = self.file.tell() def _writeHeader(self): write = self.file.write - write("%d 0 obj\n" % self.id) + write(("%d 0 obj\n" % self.id).encode('ascii')) dict = self.extra dict['Length'] = self.len if rcParams['pdf.compression']: dict['Filter'] = Name('FlateDecode') write(pdfRepr(dict)) - write("\nstream\n") + write(b"\nstream\n") def end(self): """Finalize stream.""" @@ -336,10 +364,10 @@ self.file = self.pdfFile.fh self._writeHeader() self.file.write(contents) - self.file.write("\nendstream\nendobj\n") + self.file.write(b"\nendstream\nendobj\n") else: length = self.file.tell() - self.pos - self.file.write("\nendstream\nendobj\n") + self.file.write(b"\nendstream\nendobj\n") self.pdfFile.writeObject(self.len, length) def write(self, data): @@ -366,11 +394,19 @@ self.nextObject = 1 # next free object id self.xrefTable = [ [0, 65535, 'the zero object'] ] self.passed_in_file_object = False + self.original_file_like = None + self.tell_base = 0 if is_string_like(filename): - fh = file(filename, 'wb') + fh = open(filename, 'wb') elif is_writable_file_like(filename): - fh = filename - self.passed_in_file_object = True + try: + self.tell_base = filename.tell() + except IOError: + fh = BytesIO() + self.original_file_like = filename + else: + fh = filename + self.passed_in_file_object = True else: raise ValueError("filename must be a path or a file-like object") @@ -378,11 +414,11 @@ rcParams['datapath'], 'fonts', 'pdfcorefonts') self.fh = fh self.currentstream = None # stream object to write to, if any - fh.write("%PDF-1.4\n") # 1.4 is the first version to have alpha + fh.write(b"%PDF-1.4\n") # 1.4 is the first version to have alpha # Output some eight-bit chars as a comment so various utilities # recognize the file as binary by looking at the first few # lines (see note in section 3.4.1 of the PDF reference). - fh.write("%\254\334 \253\272\n") + fh.write(b"%\254\334 \253\272\n") self.rootObject = self.reserveObject('root') self.pagesObject = self.reserveObject('pages') @@ -424,6 +460,8 @@ self.markers = {} self.multi_byte_charprocs = {} + self.paths = [] + # The PDF spec recommends to include every procset procsets = [ Name(x) for x in "PDF Text ImageB ImageC ImageI".split() ] @@ -469,17 +507,20 @@ self.writeFonts() self.writeObject(self.alphaStateObject, dict([(val[0], val[1]) - for val in self.alphaStates.values()])) + for val in self.alphaStates.itervalues()])) self.writeHatches() self.writeGouraudTriangles() - xobjects = dict(self.images.values()) - for tup in self.markers.values(): + xobjects = dict(self.images.itervalues()) + for tup in self.markers.itervalues(): xobjects[tup[0]] = tup[1] - for name, value in self.multi_byte_charprocs.items(): + for name, value in self.multi_byte_charprocs.iteritems(): xobjects[name] = value + for name, path, trans, ob, join, cap, padding, filled, stroked in self.paths: + xobjects[name] = ob self.writeObject(self.XObjectObject, xobjects) self.writeImages() self.writeMarkers() + self.writePathCollectionTemplates() self.writeObject(self.pagesObject, { 'Type': Name('Pages'), 'Kids': self.pageList, @@ -491,6 +532,9 @@ self.writeTrailer() if self.passed_in_file_object: self.fh.flush() + elif self.original_file_like is not None: + self.original_file_like.write(self.fh.getvalue()) + self.fh.close() else: self.fh.close() @@ -502,7 +546,7 @@ def output(self, *data): self.write(fill(map(pdfRepr, data))) - self.write('\n') + self.write(b'\n') def beginStream(self, id, len, extra=None): assert self.currentstream is None @@ -544,13 +588,13 @@ def writeFonts(self): fonts = {} - for filename, Fx in self.fontNames.items(): + for filename, Fx in self.fontNames.iteritems(): matplotlib.verbose.report('Embedding font %s' % filename, 'debug') if filename.endswith('.afm'): # from pdf.use14corefonts matplotlib.verbose.report('Writing AFM font', 'debug') fonts[Fx] = self._write_afm_font(filename) - elif self.dviFontInfo.has_key(filename): + elif filename in self.dviFontInfo: # a Type 1 font from a dvi file; the filename is really the TeX name matplotlib.verbose.report('Writing Type-1 font', 'debug') fonts[Fx] = self.embedTeXFont(filename, self.dviFontInfo[filename]) @@ -564,9 +608,8 @@ self.writeObject(self.fontObject, fonts) def _write_afm_font(self, filename): - fh = file(filename) - font = AFM(fh) - fh.close() + with open(filename, 'rb') as fh: + font = AFM(fh) fontname = font.get_fontname() fontdict = { 'Type': Name('Font'), 'Subtype': Name('Type1'), @@ -578,7 +621,7 @@ def embedTeXFont(self, texname, fontinfo): matplotlib.verbose.report( - 'Embedding TeX font ' + texname + ' - fontinfo=' + `fontinfo.__dict__`, + 'Embedding TeX font ' + texname + ' - fontinfo=' + repr(fontinfo.__dict__), 'debug') # Widths @@ -801,7 +844,7 @@ rawcharprocs = ttconv.get_pdf_charprocs(filename, glyph_ids) charprocs = {} charprocsRef = {} - for charname, stream in rawcharprocs.items(): + for charname, stream in rawcharprocs.iteritems(): charprocDict = { 'Length': len(stream) } # The 2-byte characters are used as XObjects, so they # need extra info in their dictionary @@ -815,7 +858,7 @@ # from the stream here. It's not needed anyway, # since the Form XObject includes it in its BBox # value. - stream = stream[stream.find("d1") + 2:] + stream = stream[stream.find(b"d1") + 2:] charprocObject = self.reserveObject('charProc') self.beginStream(charprocObject.id, None, charprocDict) self.currentstream.write(stream) @@ -876,14 +919,13 @@ fontfileObject.id, self.reserveObject('length of font stream'), {'Length1': length1Object}) - fontfile = open(filename, 'rb') - length1 = 0 - while True: - data = fontfile.read(4096) - if not data: break - length1 += len(data) - self.currentstream.write(data) - fontfile.close() + with open(filename, 'rb') as fontfile: + length1 = 0 + while True: + data = fontfile.read(4096) + if not data: break + length1 += len(data) + self.currentstream.write(data) self.endStream() self.writeObject(length1Object, length1) @@ -1026,6 +1068,15 @@ return name def hatchPattern(self, hatch_style): + # The colors may come in as numpy arrays, which aren't hashable + if hatch_style is not None: + face, edge, hatch = hatch_style + if face is not None: + face = tuple(face) + if edge is not None: + edge = tuple(edge) + hatch_style = (face, edge, hatch) + pattern = self.hatchPatterns.get(hatch_style, None) if pattern is not None: return pattern @@ -1038,7 +1089,7 @@ def writeHatches(self): hatchDict = dict() sidelen = 72.0 - for hatch_style, name in self.hatchPatterns.items(): + for hatch_style, name in self.hatchPatterns.iteritems(): ob = self.reserveObject('hatch pattern') hatchDict[name] = ob res = { 'Procsets': @@ -1155,7 +1206,7 @@ return rgbat[0], rgbat[1], gray.tostring() def writeImages(self): - for img, pair in self.images.items(): + for img, pair in self.images.iteritems(): img.flipud_out() if img.is_grayscale: height, width, data = self._gray(img) @@ -1191,10 +1242,22 @@ img.flipud_out() - def markerObject(self, path, trans, fillp, lw, joinstyle, capstyle): + def markerObject(self, path, trans, fillp, strokep, lw, joinstyle, capstyle): """Return name of a marker XObject representing the given path.""" + # self.markers used by markerObject, writeMarkers, close: + # mapping from (path operations, fill?, stroke?) to + # [name, object reference, bounding box, linewidth] + # This enables different draw_markers calls to share the XObject + # if the gc is sufficiently similar: colors etc can vary, but + # the choices of whether to fill and whether to stroke cannot. + # We need a bounding box enclosing all of the XObject path, + # but since line width may vary, we store the maximum of all + # occurring line widths in self.markers. + # close() is somewhat tightly coupled in that it expects the + # first two components of each value in self.markers to be the + # name and object reference. pathops = self.pathOperations(path, trans, simplify=False) - key = (tuple(pathops), bool(fillp), joinstyle, capstyle) + key = (tuple(pathops), bool(fillp), bool(strokep), joinstyle, capstyle) result = self.markers.get(key) if result is None: name = Name('M%d' % len(self.markers)) @@ -1208,7 +1271,8 @@ return name def writeMarkers(self): - for (pathops, fillp, joinstyle, capstyle),(name, ob, bbox, lw) in self.markers.iteritems(): + for ((pathops, fillp, strokep, joinstyle, capstyle), + (name, ob, bbox, lw)) in self.markers.iteritems(): bbox = bbox.padded(lw * 0.5) self.beginStream( ob.id, None, @@ -1217,10 +1281,35 @@ self.output(GraphicsContextPdf.joinstyles[joinstyle], Op.setlinejoin) self.output(GraphicsContextPdf.capstyles[capstyle], Op.setlinecap) self.output(*pathops) - if fillp: - self.output(Op.fill_stroke) + self.output(Op.paint_path(False, fillp, strokep)) + self.endStream() + + def pathCollectionObject(self, gc, path, trans, padding, filled, stroked): + name = Name('P%d' % len(self.paths)) + ob = self.reserveObject('path %d' % len(self.paths)) + self.paths.append( + (name, path, trans, ob, gc.get_joinstyle(), gc.get_capstyle(), padding, + filled, stroked)) + return name + + def writePathCollectionTemplates(self): + for (name, path, trans, ob, joinstyle, capstyle, padding, filled, + stroked) in self.paths: + pathops = self.pathOperations(path, trans, simplify=False) + bbox = path.get_extents(trans) + if not np.all(np.isfinite(bbox.extents)): + extents = [0, 0, 0, 0] else: - self.output(Op.stroke) + bbox = bbox.padded(padding) + extents = list(bbox.extents) + self.beginStream( + ob.id, None, + {'Type': Name('XObject'), 'Subtype': Name('Form'), + 'BBox': extents}) + self.output(GraphicsContextPdf.joinstyles[joinstyle], Op.setlinejoin) + self.output(GraphicsContextPdf.capstyles[capstyle], Op.setlinecap) + self.output(*pathops) + self.output(Op.paint_path(False, filled, stroked)) self.endStream() @staticmethod @@ -1237,7 +1326,7 @@ cmds.append(Op.closepath) elif last_points is None: # The other operations require a previous point - raise ValueError, 'Path lacks initial MOVETO' + raise ValueError('Path lacks initial MOVETO') elif code == Path.LINETO: cmds.extend(points) cmds.append(Op.lineto) @@ -1273,7 +1362,7 @@ return Reference(id) def recordXref(self, id): - self.xrefTable[id][0] = self.fh.tell() + self.xrefTable[id][0] = self.fh.tell() - self.tell_base def writeObject(self, object, contents): self.recordXref(object.id) @@ -1282,23 +1371,22 @@ def writeXref(self): """Write out the xref table.""" - self.startxref = self.fh.tell() - self.write("xref\n0 %d\n" % self.nextObject) + self.startxref = self.fh.tell() - self.tell_base + self.write(("xref\n0 %d\n" % self.nextObject).encode('ascii')) i = 0 borken = False for offset, generation, name in self.xrefTable: if offset is None: - print >>sys.stderr, \ - 'No offset for object %d (%s)' % (i, name) + print('No offset for object %d (%s)' % (i, name), file=sys.stderr) borken = True else: if name == 'the zero object': - self.write("%010d %05d f \n" % (offset, generation)) + self.write(("%010d %05d f \n" % (offset, generation)).encode('ascii')) else: - self.write("%010d %05d n \n" % (offset, generation)) + self.write(("%010d %05d n \n" % (offset, generation)).encode('ascii')) i += 1 if borken: - raise AssertionError, 'Indirect object does not exist' + raise AssertionError('Indirect object does not exist') def writeInfoDict(self): """Write out the info dictionary, checking it for good form""" @@ -1315,7 +1403,7 @@ 'CreationDate': is_date, 'ModDate': is_date, 'Trapped': check_trapped} - for k in self.infoDict.keys(): + for k in self.infoDict.iterkeys(): if k not in keywords: warnings.warn('Unknown infodict keyword: %s' % k) else: @@ -1328,13 +1416,13 @@ def writeTrailer(self): """Write out the PDF trailer.""" - self.write("trailer\n") + self.write(b"trailer\n") self.write(pdfRepr( {'Size': self.nextObject, 'Root': self.rootObject, 'Info': self.infoObject })) # Could add 'ID' - self.write("\nstartxref\n%d\n%%%%EOF\n" % self.startxref) + self.write(("\nstartxref\n%d\n%%%%EOF\n" % self.startxref).encode('ascii')) class RendererPdf(RendererBase): truetype_font_cache = maxdict(50) @@ -1380,7 +1468,7 @@ used_characters[1].update([ord(x) for x in s]) def merge_used_characters(self, other): - for stat_key, (realpath, charset) in other.items(): + for stat_key, (realpath, charset) in other.iteritems(): used_characters = self.file.used_characters.setdefault( stat_key, (realpath, set())) used_characters[1].update(charset) @@ -1431,6 +1519,34 @@ rgbFace is None and gc.get_hatch_path() is None) self.file.output(self.gc.paint()) + def draw_path_collection(self, gc, master_transform, paths, all_transforms, + offsets, offsetTrans, facecolors, edgecolors, + linewidths, linestyles, antialiaseds, urls, + offset_position): + padding = np.max(linewidths) + path_codes = [] + filled = len(facecolors) + stroked = len(edgecolors) + for i, (path, transform) in enumerate(self._iter_collection_raw_paths( + master_transform, paths, all_transforms)): + name = self.file.pathCollectionObject( + gc, path, transform, padding, filled, stroked) + path_codes.append(name) + + output = self.file.output + output(*self.gc.push()) + lastx, lasty = 0, 0 + for xo, yo, path_id, gc0, rgbFace in self._iter_collection( + gc, master_transform, all_transforms, path_codes, offsets, + offsetTrans, facecolors, edgecolors, linewidths, linestyles, + antialiaseds, urls, offset_position): + + self.check_gc(gc0, rgbFace) + dx, dy = xo - lastx, yo - lasty + output(1, 0, 0, 1, dx, dy, Op.concat_matrix, path_id, Op.use_xobject) + lastx, lasty = xo, yo + output(*self.gc.pop()) + def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None): # For simple paths or small numbers of markers, don't bother # making an XObject @@ -1440,11 +1556,12 @@ return self.check_gc(gc, rgbFace) - fillp = rgbFace is not None + fillp = gc.fillp(rgbFace) + strokep = gc.strokep() output = self.file.output marker = self.file.markerObject( - marker_path, marker_trans, fillp, self.gc._linewidth, + marker_path, marker_trans, fillp, strokep, self.gc._linewidth, gc.get_joinstyle(), gc.get_capstyle()) output(Op.gsave) @@ -1575,7 +1692,7 @@ for x1, y1, dvifont, glyph, width in page.text: if dvifont != oldfont: pdfname = self.file.fontName(dvifont.texname) - if not self.file.dviFontInfo.has_key(dvifont.texname): + if dvifont.texname not in self.file.dviFontInfo: psfont = self.tex_font_mapping(dvifont.texname) self.file.dviFontInfo[dvifont.texname] = Bunch( fontfile=psfont.filename, @@ -1592,17 +1709,17 @@ # string (if any kerns would be less than 0.1 points). i, curx, fontsize = 0, 0, None while i < len(seq)-1: - elt, next = seq[i:i+2] + elt, nxt = seq[i:i+2] if elt[0] == 'font': fontsize = elt[2] - elif elt[0] == next[0] == 'text' and elt[2] == next[2]: - offset = elt[4] - next[1] + elif elt[0] == nxt[0] == 'text' and elt[2] == nxt[2]: + offset = elt[4] - nxt[1] if abs(offset) < 0.1: - elt[3][-1] += next[3][0] - elt[4] += next[4]-next[1] + elt[3][-1] += nxt[3][0] + elt[4] += nxt[4]-nxt[1] else: - elt[3] += [offset*1000.0/fontsize, next[3][0]] - elt[4] = next[4] + elt[3] += [offset*1000.0/fontsize, nxt[3][0]] + elt[4] = nxt[4] del seq[i+1] continue i += 1 @@ -1691,7 +1808,7 @@ chunks = [] if not rcParams['pdf.use14corefonts']: - if fonttype == 3 and not isinstance(s, str) and len(s) != 0: + if fonttype == 3 and not isinstance(s, bytes) and len(s) != 0: # Break the string into chunks where each chunk is either # a string of chars <= 255, or a single character > 255. s = unicode(s) @@ -1830,10 +1947,9 @@ directory=self.file._core14fontdir) font = self.afm_font_cache.get(filename) if font is None: - fh = file(filename) - font = AFM(fh) - self.afm_font_cache[filename] = font - fh.close() + with open(filename, 'rb') as fh: + font = AFM(fh) + self.afm_font_cache[filename] = font self.afm_font_cache[key] = font return font @@ -1873,56 +1989,47 @@ d = dict(self.__dict__) del d['file'] del d['parent'] - return `d` + return repr(d) - def _strokep(self): + def strokep(self): """ Predicate: does the path need to be stroked (its outline drawn)? This tests for the various conditions that disable stroking the path, in which case it would presumably be filled. """ + # _linewidth > 0: in pdf a line of width 0 is drawn at minimum + # possible device width, but e.g. agg doesn't draw at all return (self._linewidth > 0 and self._alpha > 0 and (len(self._rgb) <= 3 or self._rgb[3] != 0.0)) - def _fillp(self): + def fillp(self, *args): """ Predicate: does the path need to be filled? + + An optional argument can be used to specify an alternative + _fillcolor, as needed by RendererPdf.draw_markers. """ - return self._hatch or \ - (self._fillcolor is not None and - (len(self._fillcolor) <= 3 or self._fillcolor[3] != 0.0)) + if len(args): + _fillcolor = args[0] + else: + _fillcolor = self._fillcolor + return (self._hatch or + (_fillcolor is not None and + (len(_fillcolor) <= 3 or _fillcolor[3] != 0.0))) def close_and_paint(self): """ Return the appropriate pdf operator to close the path and cause it to be stroked, filled, or both. """ - if self._strokep(): - if self._fillp(): - return Op.close_fill_stroke - else: - return Op.close_stroke - else: - if self._fillp(): - return Op.fill - else: - return Op.endpath + return Op.paint_path(True, self.fillp(), self.strokep()) def paint(self): """ Return the appropriate pdf operator to cause the path to be stroked, filled, or both. """ - if self._strokep(): - if self._fillp(): - return Op.fill_stroke - else: - return Op.stroke - else: - if self._fillp(): - return Op.fill - else: - return Op.endpath + return Op.paint_path(False, self.fillp(), self.strokep()) capstyles = { 'butt': 0, 'round': 1, 'projecting': 2 } joinstyles = { 'miter': 0, 'round': 1, 'bevel': 2 } @@ -2082,7 +2189,14 @@ # main-level app (egg backend_gtk, backend_gtkagg) for pylab FigureClass = kwargs.pop('FigureClass', Figure) thisFig = FigureClass(*args, **kwargs) - canvas = FigureCanvasPdf(thisFig) + return new_figure_manager_given_figure(num, thisFig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + canvas = FigureCanvasPdf(figure) manager = FigureManagerPdf(canvas, num) return manager @@ -2148,9 +2262,9 @@ else: figureManager = Gcf.get_fig_manager(figure) if figureManager is None: - raise ValueError, "No such figure: " + `figure` + raise ValueError("No such figure: " + repr(figure)) else: - figureManager.canvas.figure.savefig(self, format='pdf') + figureManager.canvas.figure.savefig(self, format='pdf', **kwargs) class FigureCanvasPdf(FigureCanvasBase): """ @@ -2178,17 +2292,19 @@ file = filename._file else: file = PdfFile(filename) - file.newPage(width, height) - _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None) - renderer = MixedModeRenderer(self.figure, - width, height, image_dpi, RendererPdf(file, image_dpi), - bbox_inches_restore=_bbox_inches_restore) - self.figure.draw(renderer) - renderer.finalize() - if isinstance(filename, PdfPages): # finish off this page - file.endStream() - else: # we opened the file above; now finish it off - file.close() + try: + file.newPage(width, height) + _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None) + renderer = MixedModeRenderer(self.figure, + width, height, image_dpi, RendererPdf(file, image_dpi), + bbox_inches_restore=_bbox_inches_restore) + self.figure.draw(renderer) + renderer.finalize() + finally: + if isinstance(filename, PdfPages): # finish off this page + file.endStream() + else: # we opened the file above; now finish it off + file.close() class FigureManagerPdf(FigureManagerBase): pass diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_pgf.py matplotlib-1.2.0/lib/matplotlib/backends/backend_pgf.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_pgf.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_pgf.py 2012-11-06 15:42:20.000000000 +0000 @@ -0,0 +1,927 @@ +from __future__ import division + +import math +import os +import sys +import re +import shutil +import tempfile +import codecs +import subprocess +import atexit +import weakref + +import matplotlib as mpl +from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\ + FigureManagerBase, FigureCanvasBase +from matplotlib.figure import Figure +from matplotlib.text import Text +from matplotlib.path import Path +from matplotlib import _png, rcParams +from matplotlib import font_manager +from matplotlib.ft2font import FT2Font +from matplotlib.cbook import is_string_like, is_writable_file_like +from matplotlib.cbook import check_output + + +############################################################################### + +# create a list of system fonts, all of these should work with xe/lua-latex +system_fonts = [] +for f in font_manager.findSystemFonts(): + try: + system_fonts.append(FT2Font(str(f)).family_name) + except RuntimeError: + pass # some fonts on osx are known to fail, print? + except: + pass # unknown error, skip this font + + +def get_texcommand(): + """Get chosen TeX system from rc.""" + texsystem_options = ["xelatex", "lualatex", "pdflatex"] + texsystem = rcParams.get("pgf.texsystem", "xelatex") + return texsystem if texsystem in texsystem_options else "xelatex" + + +def get_fontspec(): + """Build fontspec preamble from rc.""" + latex_fontspec = [] + texcommand = get_texcommand() + + if texcommand is not "pdflatex": + latex_fontspec.append(r"\usepackage{fontspec}") + + if texcommand is not "pdflatex" and rcParams.get("pgf.rcfonts", True): + # try to find fonts from rc parameters + families = ["serif", "sans-serif", "monospace"] + fontspecs = [r"\setmainfont{%s}", r"\setsansfont{%s}", + r"\setmonofont{%s}"] + for family, fontspec in zip(families, fontspecs): + matches = [f for f in rcParams["font." + family] + if f in system_fonts] + if matches: + latex_fontspec.append(fontspec % matches[0]) + else: + pass # no fonts found, fallback to LaTeX defaule + + return "\n".join(latex_fontspec) + + +def get_preamble(): + """Get LaTeX preamble from rc.""" + latex_preamble = rcParams.get("pgf.preamble", "") + if type(latex_preamble) == list: + latex_preamble = "\n".join(latex_preamble) + return latex_preamble + +############################################################################### + +# This almost made me cry!!! +# In the end, it's better to use only one unit for all coordinates, since the +# arithmetic in latex seems to produce inaccurate conversions. +latex_pt_to_in = 1. / 72.27 +latex_in_to_pt = 1. / latex_pt_to_in +mpl_pt_to_in = 1. / 72. +mpl_in_to_pt = 1. / mpl_pt_to_in + +############################################################################### +# helper functions + +NO_ESCAPE = r"(? 3) and (rgbFace[3] != 1.0) + if has_fill: + writeln(self.fh, r"\definecolor{currentfill}{rgb}{%f,%f,%f}" % tuple(rgbFace[:3])) + writeln(self.fh, r"\pgfsetfillcolor{currentfill}") + if has_fill and (path_is_transparent or fill_is_transparent): + opacity = gc.get_alpha() * 1.0 if not fill_is_transparent else rgbFace[3] + writeln(self.fh, r"\pgfsetfillopacity{%f}" % opacity) + + # linewidth and color + lw = gc.get_linewidth() * mpl_pt_to_in * latex_in_to_pt + stroke_rgba = gc.get_rgb() + writeln(self.fh, r"\pgfsetlinewidth{%fpt}" % lw) + writeln(self.fh, r"\definecolor{currentstroke}{rgb}{%f,%f,%f}" % stroke_rgba[:3]) + writeln(self.fh, r"\pgfsetstrokecolor{currentstroke}") + if gc.get_alpha() != 1.0: + writeln(self.fh, r"\pgfsetstrokeopacity{%f}" % gc.get_alpha()) + + # line style + dash_offset, dash_list = gc.get_dashes() + ls = gc.get_linestyle(None) + if ls == "solid": + writeln(self.fh, r"\pgfsetdash{}{0pt}") + elif (ls == "dashed" or ls == "dashdot" or ls == "dotted"): + dash_str = r"\pgfsetdash{" + for dash in dash_list: + dash_str += r"{%fpt}" % dash + dash_str += r"}{%fpt}" % dash_offset + writeln(self.fh, dash_str) + + def _print_pgf_path(self, path, transform): + f = 1. / self.dpi + # build path + for points, code in path.iter_segments(transform): + if code == Path.MOVETO: + x, y = tuple(points) + writeln(self.fh, r"\pgfpathmoveto{\pgfqpoint{%fin}{%fin}}" % + (f * x, f * y)) + elif code == Path.CLOSEPOLY: + writeln(self.fh, r"\pgfpathclose") + elif code == Path.LINETO: + x, y = tuple(points) + writeln(self.fh, r"\pgfpathlineto{\pgfqpoint{%fin}{%fin}}" % + (f * x, f * y)) + elif code == Path.CURVE3: + cx, cy, px, py = tuple(points) + coords = cx * f, cy * f, px * f, py * f + writeln(self.fh, r"\pgfpathquadraticcurveto{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}" % coords) + elif code == Path.CURVE4: + c1x, c1y, c2x, c2y, px, py = tuple(points) + coords = c1x * f, c1y * f, c2x * f, c2y * f, px * f, py * f + writeln(self.fh, r"\pgfpathcurveto{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}" % coords) + + def _pgf_path_draw(self, stroke=True, fill=False): + actions = [] + if stroke: + actions.append("stroke") + if fill: + actions.append("fill") + writeln(self.fh, r"\pgfusepath{%s}" % ",".join(actions)) + + def draw_image(self, gc, x, y, im): + # TODO: Almost no documentation for the behavior of this function. + # Something missing? + + # save the images to png files + path = os.path.dirname(self.fh.name) + fname = os.path.splitext(os.path.basename(self.fh.name))[0] + fname_img = "%s-img%d.png" % (fname, self.image_counter) + self.image_counter += 1 + im.flipud_out() + rows, cols, buf = im.as_rgba_str() + _png.write_png(buf, cols, rows, os.path.join(path, fname_img)) + + # reference the image in the pgf picture + writeln(self.fh, r"\begin{pgfscope}") + self._print_pgf_clip(gc) + h, w = im.get_size_out() + f = 1. / self.dpi # from display coords to inch + writeln(self.fh, r"\pgftext[at=\pgfqpoint{%fin}{%fin},left,bottom]{\pgfimage[interpolate=true,width=%fin,height=%fin]{%s}}" % (x * f, y * f, w * f, h * f, fname_img)) + writeln(self.fh, r"\end{pgfscope}") + + def draw_tex(self, gc, x, y, s, prop, angle, ismath="TeX!"): + self.draw_text(gc, x, y, s, prop, angle, ismath) + + def draw_text(self, gc, x, y, s, prop, angle, ismath=False): + s = common_texification(s) + + # apply font properties + prop_cmds = _font_properties_str(prop) + s = ur"{%s %s}" % (prop_cmds, s) + + # draw text at given coordinates + x = x * 1. / self.dpi + y = y * 1. / self.dpi + writeln(self.fh, r"\begin{pgfscope}") + alpha = gc.get_alpha() + if alpha != 1.0: + writeln(self.fh, r"\pgfsetfillopacity{%f}" % alpha) + writeln(self.fh, r"\pgfsetstrokeopacity{%f}" % alpha) + stroke_rgb = tuple(gc.get_rgb())[:3] + if stroke_rgb != (0, 0, 0): + writeln(self.fh, r"\definecolor{textcolor}{rgb}{%f,%f,%f}" % stroke_rgb) + writeln(self.fh, r"\pgfsetstrokecolor{textcolor}") + writeln(self.fh, r"\pgfsetfillcolor{textcolor}") + writeln(self.fh, "\\pgftext[left,bottom,x=%fin,y=%fin,rotate=%f]{%s}\n" % (x, y, angle, s)) + writeln(self.fh, r"\end{pgfscope}") + + def get_text_width_height_descent(self, s, prop, ismath): + # check if the math is supposed to be displaystyled + s = common_texification(s) + + # get text metrics in units of latex pt, convert to display units + w, h, d = self.latexManager.get_width_height_descent(s, prop) + # TODO: this should be latex_pt_to_in instead of mpl_pt_to_in + # but having a little bit more space around the text looks better, + # plus the bounding box reported by LaTeX is VERY narrow + f = mpl_pt_to_in * self.dpi + return w * f, h * f, d * f + + def flipy(self): + return False + + def get_canvas_width_height(self): + return self.figure.get_figwidth(), self.figure.get_figheight() + + def points_to_pixels(self, points): + return points * mpl_pt_to_in * self.dpi + + def new_gc(self): + return GraphicsContextPgf() + + +class GraphicsContextPgf(GraphicsContextBase): + pass + +######################################################################## + + +def draw_if_interactive(): + pass + + +def new_figure_manager(num, *args, **kwargs): + """ + Create a new figure manager instance + """ + # if a main-level app must be created, this is the usual place to + # do it -- see backend_wx, backend_wxagg and backend_tkagg for + # examples. Not all GUIs require explicit instantiation of a + # main-level app (egg backend_gtk, backend_gtkagg) for pylab + FigureClass = kwargs.pop('FigureClass', Figure) + thisFig = FigureClass(*args, **kwargs) + return new_figure_manager_given_figure(num, thisFig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + canvas = FigureCanvasPgf(figure) + manager = FigureManagerPgf(canvas, num) + return manager + + +class TmpDirCleaner: + remaining_tmpdirs = set() + + @staticmethod + def add(tmpdir): + TmpDirCleaner.remaining_tmpdirs.add(tmpdir) + + @staticmethod + def cleanup_remaining_tmpdirs(): + for tmpdir in TmpDirCleaner.remaining_tmpdirs: + try: + shutil.rmtree(tmpdir) + except: + sys.stderr.write("error deleting tmp directory %s\n" % tmpdir) + + +class FigureCanvasPgf(FigureCanvasBase): + filetypes = {"pgf": "LaTeX PGF picture", + "pdf": "LaTeX compiled PGF picture", + "png": "Portable Network Graphics", } + + def __init__(self, *args): + FigureCanvasBase.__init__(self, *args) + + def get_default_filetype(self): + return 'pdf' + + def _print_pgf_to_fh(self, fh): + header_text = r"""%% Creator: Matplotlib, PGF backend +%% +%% To include the figure in your LaTeX document, write +%% \input{.pgf} +%% +%% Make sure the required packages are loaded in your preamble +%% \usepackage{pgf} +%% +%% Figures using additional raster images can only be included by \input if +%% they are in the same directory as the main LaTeX file. For loading figures +%% from other directories you can use the `import` package +%% \usepackage{import} +%% and then include the figures with +%% \import{}{.pgf} +%% +""" + + # append the preamble used by the backend as a comment for debugging + header_info_preamble = ["%% Matplotlib used the following preamble"] + for line in get_preamble().splitlines(): + header_info_preamble.append("%% " + line) + for line in get_fontspec().splitlines(): + header_info_preamble.append("%% " + line) + header_info_preamble.append("%%") + header_info_preamble = "\n".join(header_info_preamble) + + # get figure size in inch + w, h = self.figure.get_figwidth(), self.figure.get_figheight() + + # create pgfpicture environment and write the pgf code + fh.write(header_text) + fh.write(header_info_preamble) + fh.write("\n") + writeln(fh, r"\begingroup") + writeln(fh, r"\makeatletter") + writeln(fh, r"\begin{pgfpicture}") + writeln(fh, r"\pgfpathrectangle{\pgfpointorigin}{\pgfqpoint{%fin}{%fin}}" % (w, h)) + writeln(fh, r"\pgfusepath{use as bounding box}") + renderer = RendererPgf(self.figure, fh) + self.figure.draw(renderer) + + # end the pgfpicture environment + writeln(fh, r"\end{pgfpicture}") + writeln(fh, r"\makeatother") + writeln(fh, r"\endgroup") + + def print_pgf(self, fname_or_fh, *args, **kwargs): + """ + Output pgf commands for drawing the figure so it can be included and + rendered in latex documents. + """ + if kwargs.get("dryrun", False): + return + + # figure out where the pgf is to be written to + if is_string_like(fname_or_fh): + with codecs.open(fname_or_fh, "w", encoding="utf-8") as fh: + self._print_pgf_to_fh(fh) + elif is_writable_file_like(fname_or_fh): + raise ValueError("saving pgf to a stream is not supported, " + + "consider using the pdf option of the pgf-backend") + else: + raise ValueError("filename must be a path") + + def _print_pdf_to_fh(self, fh): + w, h = self.figure.get_figwidth(), self.figure.get_figheight() + + try: + # create temporary directory for compiling the figure + tmpdir = tempfile.mkdtemp(prefix="mpl_pgf_") + fname_pgf = os.path.join(tmpdir, "figure.pgf") + fname_tex = os.path.join(tmpdir, "figure.tex") + fname_pdf = os.path.join(tmpdir, "figure.pdf") + + # print figure to pgf and compile it with latex + self.print_pgf(fname_pgf) + + latex_preamble = get_preamble() + latex_fontspec = get_fontspec() + latexcode = r""" +\documentclass[12pt]{minimal} +\usepackage[paperwidth=%fin, paperheight=%fin, margin=0in]{geometry} +%s +%s +\usepackage{pgf} + +\begin{document} +\centering +\input{figure.pgf} +\end{document}""" % (w, h, latex_preamble, latex_fontspec) + with codecs.open(fname_tex, "w", "utf-8") as fh_tex: + fh_tex.write(latexcode) + + texcommand = get_texcommand() + cmdargs = [texcommand, "-interaction=nonstopmode", + "-halt-on-error", "figure.tex"] + try: + check_output(cmdargs, stderr=subprocess.STDOUT, cwd=tmpdir) + except subprocess.CalledProcessError as e: + raise RuntimeError("%s was not able to process your file.\n\nFull log:\n%s" % (texcommand, e.output)) + + # copy file contents to target + with open(fname_pdf, "rb") as fh_src: + shutil.copyfileobj(fh_src, fh) + finally: + try: + shutil.rmtree(tmpdir) + except: + TmpDirCleaner.add(tmpdir) + + def print_pdf(self, fname_or_fh, *args, **kwargs): + """ + Use LaTeX to compile a Pgf generated figure to PDF. + """ + # figure out where the pdf is to be written to + if is_string_like(fname_or_fh): + with open(fname_or_fh, "wb") as fh: + self._print_pdf_to_fh(fh) + elif is_writable_file_like(fname_or_fh): + self._print_pdf_to_fh(fname_or_fh) + else: + raise ValueError("filename must be a path or a file-like object") + + def _print_png_to_fh(self, fh): + converter = make_pdf_to_png_converter() + + try: + # create temporary directory for pdf creation and png conversion + tmpdir = tempfile.mkdtemp(prefix="mpl_pgf_") + fname_pdf = os.path.join(tmpdir, "figure.pdf") + fname_png = os.path.join(tmpdir, "figure.png") + # create pdf and try to convert it to png + self.print_pdf(fname_pdf) + converter(fname_pdf, fname_png, dpi=self.figure.dpi) + # copy file contents to target + with open(fname_png, "rb") as fh_src: + shutil.copyfileobj(fh_src, fh) + finally: + try: + shutil.rmtree(tmpdir) + except: + TmpDirCleaner.add(tmpdir) + + def print_png(self, fname_or_fh, *args, **kwargs): + """ + Use LaTeX to compile a pgf figure to pdf and convert it to png. + """ + if is_string_like(fname_or_fh): + with open(fname_or_fh, "wb") as fh: + self._print_png_to_fh(fh) + elif is_writable_file_like(fname_or_fh): + self._print_png_to_fh(fname_or_fh) + else: + raise ValueError("filename must be a path or a file-like object") + + def _render_texts_pgf(self, fh): + # TODO: currently unused code path + + # alignment anchors + valign = {"top": "top", "bottom": "bottom", "baseline": "base", "center": ""} + halign = {"left": "left", "right": "right", "center": ""} + # alignment anchors for 90deg. rotated labels + rvalign = {"top": "left", "bottom": "right", "baseline": "right", "center": ""} + rhalign = {"left": "top", "right": "bottom", "center": ""} + + # TODO: matplotlib does not hide unused tick labels yet, workaround + for tick in self.figure.findobj(mpl.axis.Tick): + tick.label1.set_visible(tick.label1On) + tick.label2.set_visible(tick.label2On) + # TODO: strange, first legend label is always "None", workaround + for legend in self.figure.findobj(mpl.legend.Legend): + labels = legend.findobj(mpl.text.Text) + labels[0].set_visible(False) + # TODO: strange, legend child labels are duplicated, + # find a list of unique text objects as workaround + texts = self.figure.findobj(match=Text, include_self=False) + texts = list(set(texts)) + + # draw text elements + for text in texts: + s = text.get_text() + if not s or not text.get_visible(): + continue + + s = common_texification(s) + + fontsize = text.get_fontsize() + angle = text.get_rotation() + transform = text.get_transform() + x, y = transform.transform_point(text.get_position()) + x = x * 1.0 / self.figure.dpi + y = y * 1.0 / self.figure.dpi + # TODO: positioning behavior unknown for rotated elements + # right now only the alignment for 90deg rotations is correct + if angle == 90.: + align = rvalign[text.get_va()] + "," + rhalign[text.get_ha()] + else: + align = valign[text.get_va()] + "," + halign[text.get_ha()] + + s = ur"{\fontsize{%f}{%f}\selectfont %s}" % (fontsize, fontsize*1.2, s) + writeln(fh, ur"\pgftext[%s,x=%fin,y=%fin,rotate=%f]{%s}" % (align,x,y,angle,s)) + + def get_renderer(self): + return RendererPgf(self.figure, None) + + +class FigureManagerPgf(FigureManagerBase): + def __init__(self, *args): + FigureManagerBase.__init__(self, *args) + +######################################################################## + +FigureManager = FigureManagerPgf + +def _cleanup_all(): + LatexManager._cleanup_remaining_instances() + TmpDirCleaner.cleanup_remaining_tmpdirs() + +atexit.register(_cleanup_all) diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_ps.py matplotlib-1.2.0/lib/matplotlib/backends/backend_ps.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_ps.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_ps.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,9 +2,14 @@ A PostScript backend, which can produce both PostScript .ps and .eps """ -from __future__ import division +# PY3KTODO: Get rid of "print >>fh" syntax + +from __future__ import division, print_function import glob, math, os, shutil, sys, time def _fn_name(): return sys._getframe(1).f_code.co_name +import io +if sys.version_info[0] < 3: + import cStringIO try: from hashlib import md5 @@ -12,7 +17,6 @@ from md5 import md5 #Deprecated in 2.5 from tempfile import mkstemp -from cStringIO import StringIO from matplotlib import verbose, __version__, rcParams from matplotlib._pylab_helpers import Gcf from matplotlib.afm import AFM @@ -86,7 +90,11 @@ from subprocess import Popen, PIPE pipe = Popen(self.gs_exe + " --version", shell=True, stdout=PIPE).stdout - gs_version = tuple(map(int, pipe.read().strip().split("."))) + if sys.version_info[0] >= 3: + ver = pipe.read().decode('ascii') + else: + ver = pipe.read() + gs_version = tuple(map(int, ver.strip().split("."))) self._cached["gs_version"] = gs_version return gs_version @@ -231,7 +239,7 @@ used_characters[1].update([ord(x) for x in s]) def merge_used_characters(self, other): - for stat_key, (realpath, charset) in other.items(): + for stat_key, (realpath, charset) in other.iteritems(): used_characters = self.used_characters.setdefault( stat_key, (realpath, set())) used_characters[1].update(charset) @@ -284,7 +292,7 @@ def create_hatch(self, hatch): sidelen = 72 - if self._hatches.has_key(hatch): + if hatch in self._hatches: return self._hatches[hatch] name = 'H%d' % len(self._hatches) self._pswriter.write("""\ @@ -371,7 +379,8 @@ "Helvetica", fontext='afm', directory=self._afm_font_dir) font = self.afmfontd.get(fname) if font is None: - font = AFM(file(fname)) + with open(fname, 'rb') as fh: + font = AFM(fh) self.afmfontd[fname] = font self.afmfontd[key] = font return font @@ -616,7 +625,8 @@ def draw_path_collection(self, gc, master_transform, paths, all_transforms, offsets, offsetTrans, facecolors, edgecolors, - linewidths, linestyles, antialiaseds, urls): + linewidths, linestyles, antialiaseds, urls, + offset_position): write = self._pswriter.write path_codes = [] @@ -631,8 +641,9 @@ path_codes.append(name) for xo, yo, path_id, gc0, rgbFace in self._iter_collection( - gc, path_codes, offsets, offsetTrans, facecolors, edgecolors, - linewidths, linestyles, antialiaseds, urls): + gc, master_transform, all_transforms, path_codes, offsets, + offsetTrans, facecolors, edgecolors, linewidths, linestyles, + antialiaseds, urls, offset_position): ps = "%g %g %s" % (xo, yo, path_id) self._draw_ps(ps, gc0, rgbFace) @@ -865,8 +876,7 @@ write = self._pswriter.write if debugPS and command: write("% "+command+"\n") - mightstroke = (gc.get_linewidth() > 0.0 and - (len(gc.get_rgb()) <= 3 or gc.get_rgb()[3] != 0.0)) + mightstroke = gc.shouldstroke() stroke = stroke and mightstroke fill = (fill and rgbFace is not None and (len(rgbFace) <= 3 or rgbFace[3] != 0.0)) @@ -927,11 +937,21 @@ 'round':1, 'bevel':2}[GraphicsContextBase.get_joinstyle(self)] + def shouldstroke(self): + return (self.get_linewidth() > 0.0 and + (len(self.get_rgb()) <= 3 or self.get_rgb()[3] != 0.0)) def new_figure_manager(num, *args, **kwargs): FigureClass = kwargs.pop('FigureClass', Figure) thisFig = FigureClass(*args, **kwargs) - canvas = FigureCanvasPS(thisFig) + return new_figure_manager_given_figure(num, thisFig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + canvas = FigureCanvasPS(figure) manager = FigureManagerPS(canvas, num) return manager @@ -965,7 +985,7 @@ pass elif papertype not in papersize: raise RuntimeError( '%s is not a valid papertype. Use one \ - of %s'% (papertype, ', '.join( papersize.keys() )) ) + of %s'% (papertype, ', '.join( papersize.iterkeys() )) ) orientation = kwargs.pop("orientation", "portrait").lower() if orientation == 'landscape': isLandscape = True @@ -1012,9 +1032,6 @@ else: raise ValueError("outfile must be a path or a file-like object") - fd, tmpfile = mkstemp() - fh = os.fdopen(fd, 'w') - # find the appropriate papertype width, height = self.figure.get_size_inches() if papertype == 'auto': @@ -1066,7 +1083,10 @@ self._pswriter = NullWriter() else: - self._pswriter = StringIO() + if sys.version_info[0] >= 3: + self._pswriter = io.StringIO() + else: + self._pswriter = cStringIO.StringIO() # mixed mode rendering @@ -1085,73 +1105,80 @@ self.figure.set_facecolor(origfacecolor) self.figure.set_edgecolor(origedgecolor) - # write the PostScript headers - if isEPSF: print >>fh, "%!PS-Adobe-3.0 EPSF-3.0" - else: print >>fh, "%!PS-Adobe-3.0" - if title: print >>fh, "%%Title: "+title - print >>fh, ("%%Creator: matplotlib version " - +__version__+", http://matplotlib.sourceforge.net/") - print >>fh, "%%CreationDate: "+time.ctime(time.time()) - print >>fh, "%%Orientation: " + orientation - if not isEPSF: print >>fh, "%%DocumentPaperSizes: "+papertype - print >>fh, "%%%%BoundingBox: %d %d %d %d" % bbox - if not isEPSF: print >>fh, "%%Pages: 1" - print >>fh, "%%EndComments" - - Ndict = len(psDefs) - print >>fh, "%%BeginProlog" - if not rcParams['ps.useafm']: - Ndict += len(ps_renderer.used_characters) - print >>fh, "/mpldict %d dict def"%Ndict - print >>fh, "mpldict begin" - for d in psDefs: - d=d.strip() - for l in d.split('\n'): - print >>fh, l.strip() - if not rcParams['ps.useafm']: - for font_filename, chars in ps_renderer.used_characters.values(): - if len(chars): - font = FT2Font(str(font_filename)) - cmap = font.get_charmap() - glyph_ids = [] - for c in chars: - gind = cmap.get(c) or 0 - glyph_ids.append(gind) - - fonttype = rcParams['ps.fonttype'] - - # Can not use more than 255 characters from a - # single font for Type 3 - if len(glyph_ids) > 255: - fonttype = 42 - - # The ttf to ps (subsetting) support doesn't work for - # OpenType fonts that are Postscript inside (like the - # STIX fonts). This will simply turn that off to avoid - # errors. - if is_opentype_cff_font(font_filename): - raise RuntimeError("OpenType CFF fonts can not be saved using the internal Postscript backend at this time.\nConsider using the Cairo backend.") - else: - convert_ttf_to_ps(font_filename, fh, fonttype, glyph_ids) - print >>fh, "end" - print >>fh, "%%EndProlog" - - if not isEPSF: print >>fh, "%%Page: 1 1" - print >>fh, "mpldict begin" - #print >>fh, "gsave" - print >>fh, "%s translate"%_nums_to_str(xo, yo) - if rotation: print >>fh, "%d rotate"%rotation - print >>fh, "%s clipbox"%_nums_to_str(width*72, height*72, 0, 0) - - # write the figure - print >>fh, self._pswriter.getvalue() - - # write the trailer - #print >>fh, "grestore" - print >>fh, "end" - print >>fh, "showpage" - if not isEPSF: print >>fh, "%%EOF" - fh.close() + fd, tmpfile = mkstemp() + with io.open(fd, 'wb') as raw_fh: + if sys.version_info[0] >= 3: + fh = io.TextIOWrapper(raw_fh, encoding="ascii") + else: + fh = raw_fh + + # write the PostScript headers + if isEPSF: print("%!PS-Adobe-3.0 EPSF-3.0", file=fh) + else: print("%!PS-Adobe-3.0", file=fh) + if title: print("%%Title: "+title, file=fh) + print(("%%Creator: matplotlib version " + +__version__+", http://matplotlib.org/"), file=fh) + print("%%CreationDate: "+time.ctime(time.time()), file=fh) + print("%%Orientation: " + orientation, file=fh) + if not isEPSF: print("%%DocumentPaperSizes: "+papertype, file=fh) + print("%%%%BoundingBox: %d %d %d %d" % bbox, file=fh) + if not isEPSF: print("%%Pages: 1", file=fh) + print("%%EndComments", file=fh) + + Ndict = len(psDefs) + print("%%BeginProlog", file=fh) + if not rcParams['ps.useafm']: + Ndict += len(ps_renderer.used_characters) + print("/mpldict %d dict def"%Ndict, file=fh) + print("mpldict begin", file=fh) + for d in psDefs: + d=d.strip() + for l in d.split('\n'): + print(l.strip(), file=fh) + if not rcParams['ps.useafm']: + for font_filename, chars in ps_renderer.used_characters.itervalues(): + if len(chars): + font = FT2Font(str(font_filename)) + cmap = font.get_charmap() + glyph_ids = [] + for c in chars: + gind = cmap.get(c) or 0 + glyph_ids.append(gind) + + fonttype = rcParams['ps.fonttype'] + + # Can not use more than 255 characters from a + # single font for Type 3 + if len(glyph_ids) > 255: + fonttype = 42 + + # The ttf to ps (subsetting) support doesn't work for + # OpenType fonts that are Postscript inside (like the + # STIX fonts). This will simply turn that off to avoid + # errors. + if is_opentype_cff_font(font_filename): + raise RuntimeError("OpenType CFF fonts can not be saved using the internal Postscript backend at this time.\nConsider using the Cairo backend.") + else: + fh.flush() + convert_ttf_to_ps(font_filename, raw_fh, fonttype, glyph_ids) + print("end", file=fh) + print("%%EndProlog", file=fh) + + if not isEPSF: print("%%Page: 1 1", file=fh) + print("mpldict begin", file=fh) + #print >>fh, "gsave" + print("%s translate"%_nums_to_str(xo, yo), file=fh) + if rotation: print("%d rotate"%rotation, file=fh) + print("%s clipbox"%_nums_to_str(width*72, height*72, 0, 0), file=fh) + + # write the figure + print(self._pswriter.getvalue(), file=fh) + + # write the trailer + #print >>fh, "grestore" + print("end", file=fh) + print("showpage", file=fh) + if not isEPSF: print("%%EOF", file=fh) if rcParams['ps.usedistiller'] == 'ghostscript': gs_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox) @@ -1159,10 +1186,11 @@ xpdf_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox) if passed_in_file_object: - fh = open(tmpfile) - print >>outfile, fh.read() + with open(tmpfile, 'rb') as fh: + print(fh.read(), file=outfile) else: - open(outfile, 'w') + with open(outfile, 'w') as fh: + pass mode = os.stat(outfile).st_mode shutil.move(tmpfile, outfile) os.chmod(outfile, mode) @@ -1178,10 +1206,6 @@ isEPSF = format == 'eps' title = outfile - # write to a temp file, we'll move it to outfile when done - fd, tmpfile = mkstemp() - fh = os.fdopen(fd, 'w') - self.figure.dpi = 72 # ignore the dpi kwarg width, height = self.figure.get_size_inches() xo = 0 @@ -1208,7 +1232,10 @@ self._pswriter = NullWriter() else: - self._pswriter = StringIO() + if sys.version_info[0] >= 3: + self._pswriter = io.StringIO() + else: + self._pswriter = cStringIO.StringIO() # mixed mode rendering @@ -1227,39 +1254,45 @@ self.figure.set_facecolor(origfacecolor) self.figure.set_edgecolor(origedgecolor) - # write the Encapsulated PostScript headers - print >>fh, "%!PS-Adobe-3.0 EPSF-3.0" - if title: print >>fh, "%%Title: "+title - print >>fh, ("%%Creator: matplotlib version " - +__version__+", http://matplotlib.sourceforge.net/") - print >>fh, "%%CreationDate: "+time.ctime(time.time()) - print >>fh, "%%%%BoundingBox: %d %d %d %d" % bbox - print >>fh, "%%EndComments" - - Ndict = len(psDefs) - print >>fh, "%%BeginProlog" - print >>fh, "/mpldict %d dict def"%Ndict - print >>fh, "mpldict begin" - for d in psDefs: - d=d.strip() - for l in d.split('\n'): - print >>fh, l.strip() - print >>fh, "end" - print >>fh, "%%EndProlog" - - print >>fh, "mpldict begin" - #print >>fh, "gsave" - print >>fh, "%s translate"%_nums_to_str(xo, yo) - print >>fh, "%s clipbox"%_nums_to_str(width*72, height*72, 0, 0) - - # write the figure - print >>fh, self._pswriter.getvalue() - - # write the trailer - #print >>fh, "grestore" - print >>fh, "end" - print >>fh, "showpage" - fh.close() + # write to a temp file, we'll move it to outfile when done + fd, tmpfile = mkstemp() + if sys.version_info[0] >= 3: + fh = io.open(fd, 'w', encoding='ascii') + else: + fh = io.open(fd, 'wb') + with fh: + # write the Encapsulated PostScript headers + print("%!PS-Adobe-3.0 EPSF-3.0", file=fh) + if title: print("%%Title: "+title, file=fh) + print(("%%Creator: matplotlib version " + +__version__+", http://matplotlib.org/"), file=fh) + print("%%CreationDate: "+time.ctime(time.time()), file=fh) + print("%%%%BoundingBox: %d %d %d %d" % bbox, file=fh) + print("%%EndComments", file=fh) + + Ndict = len(psDefs) + print("%%BeginProlog", file=fh) + print("/mpldict %d dict def"%Ndict, file=fh) + print("mpldict begin", file=fh) + for d in psDefs: + d=d.strip() + for l in d.split('\n'): + print(l.strip(), file=fh) + print("end", file=fh) + print("%%EndProlog", file=fh) + + print("mpldict begin", file=fh) + #print >>fh, "gsave" + print("%s translate"%_nums_to_str(xo, yo), file=fh) + print("%s clipbox"%_nums_to_str(width*72, height*72, 0, 0), file=fh) + + # write the figure + print(self._pswriter.getvalue(), file=fh) + + # write the trailer + #print >>fh, "grestore" + print("end", file=fh) + print("showpage", file=fh) if isLandscape: # now we are ready to rotate isLandscape = True @@ -1306,11 +1339,20 @@ else: gs_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox, rotated=psfrag_rotated) - if isinstance(outfile, file): - fh = file(tmpfile) - print >>outfile, fh.read() + is_file = False + if sys.version_info[0] >= 3: + if isinstance(outfile, io.IOBase): + is_file = True + else: + if isinstance(outfile, file): + is_file = True + + if is_file: + with open(tmpfile, 'rb') as fh: + outfile.write(fh.read()) else: - open(outfile, 'w') + with open(outfile, 'wb') as fh: + pass mode = os.stat(outfile).st_mode shutil.move(tmpfile, outfile) os.chmod(outfile, mode) @@ -1329,7 +1371,6 @@ shutil.move(tmpfile, epsfile) latexfile = tmpfile+'.tex' outfile = tmpfile+'.output' - latexh = file(latexfile, 'w') dvifile = tmpfile+'.dvi' psfile = tmpfile+'.ps' @@ -1337,7 +1378,7 @@ else: angle = 0 if rcParams['text.latex.unicode']: - unicode_preamble = """\usepackage{ucs} + unicode_preamble = r"""\usepackage{ucs} \usepackage[utf8x]{inputenc}""" else: unicode_preamble = '' @@ -1363,18 +1404,17 @@ paperWidth, paperHeight, '\n'.join(psfrags), angle, os.path.split(epsfile)[-1]) - if rcParams['text.latex.unicode']: - latexh.write(s.encode('utf8')) - else: - try: - latexh.write(s) - except UnicodeEncodeError, err: - verbose.report("You are using unicode and latex, but have " - "not enabled the matplotlib 'text.latex.unicode' " - "rcParam.", 'helpful') - raise - - latexh.close() + with io.open(latexfile, 'wb') as latexh: + if rcParams['text.latex.unicode']: + latexh.write(s.encode('utf8')) + else: + try: + latexh.write(s.encode('ascii')) + except UnicodeEncodeError: + verbose.report("You are using unicode and latex, but have " + "not enabled the matplotlib 'text.latex.unicode' " + "rcParam.", 'helpful') + raise # the split drive part of the command is necessary for windows users with # multiple @@ -1384,24 +1424,27 @@ %(precmd, tmpdir, latexfile, outfile) verbose.report(command, 'debug') exit_status = os.system(command) - fh = file(outfile) - if exit_status: - raise RuntimeError('LaTeX was not able to process your file:\ -\nHere is the full report generated by LaTeX: \n\n%s'% fh.read()) - else: verbose.report(fh.read(), 'debug') - fh.close() + + with io.open(outfile, 'rb') as fh: + if exit_status: + raise RuntimeError('LaTeX was not able to process your file:\ + \nHere is the full report generated by LaTeX: \n\n%s'% fh.read()) + else: + verbose.report(fh.read(), 'debug') os.remove(outfile) command = '%s cd "%s" && dvips -q -R0 -o "%s" "%s" > "%s"'%(precmd, tmpdir, os.path.split(psfile)[-1], os.path.split(dvifile)[-1], outfile) verbose.report(command, 'debug') exit_status = os.system(command) - fh = file(outfile) - if exit_status: raise RuntimeError('dvips was not able to \ -process the following file:\n%s\nHere is the full report generated by dvips: \ -\n\n'% dvifile + fh.read()) - else: verbose.report(fh.read(), 'debug') - fh.close() + + with io.open(outfile, 'rb') as fh: + if exit_status: + raise RuntimeError('dvips was not able to \ + process the following file:\n%s\nHere is the full report generated by dvips: \ + \n\n'% dvifile + fh.read()) + else: + verbose.report(fh.read(), 'debug') os.remove(outfile) os.remove(epsfile) shutil.move(psfile, tmpfile) @@ -1413,10 +1456,11 @@ # the generated ps file is in landscape and return this # information. The return value is used in pstoeps step to recover # the correct bounding box. 2010-06-05 JJL - if "Landscape" in open(tmpfile).read(1000): - psfrag_rotated = True - else: - psfrag_rotated = False + with open(tmpfile) as fh: + if "Landscape" in fh.read(1000): + psfrag_rotated = True + else: + psfrag_rotated = False if not debugPS: for fname in glob.glob(tmpfile+'.*'): @@ -1451,11 +1495,13 @@ verbose.report(command, 'debug') exit_status = os.system(command) - fh = file(outfile) - if exit_status: raise RuntimeError('ghostscript was not able to process \ -your image.\nHere is the full report generated by ghostscript:\n\n' + fh.read()) - else: verbose.report(fh.read(), 'debug') - fh.close() + + with io.open(outfile, 'rb') as fh: + if exit_status: + raise RuntimeError('ghostscript was not able to process \ + your image.\nHere is the full report generated by ghostscript:\n\n' + fh.read()) + else: + verbose.report(fh.read(), 'debug') os.remove(outfile) os.remove(tmpfile) shutil.move(psfile, tmpfile) @@ -1496,21 +1542,24 @@ if sys.platform == 'win32': command = command.replace('=', '#') verbose.report(command, 'debug') exit_status = os.system(command) - fh = file(outfile) - if exit_status: raise RuntimeError('ps2pdf was not able to process your \ + with io.open(outfile, 'rb') as fh: + if exit_status: + raise RuntimeError('ps2pdf was not able to process your \ image.\n\Here is the report generated by ghostscript:\n\n' + fh.read()) - else: verbose.report(fh.read(), 'debug') - fh.close() + else: + verbose.report(fh.read(), 'debug') os.remove(outfile) command = 'pdftops -paper match -level2 "%s" "%s" > "%s"'% \ (pdffile, psfile, outfile) verbose.report(command, 'debug') exit_status = os.system(command) - fh = file(outfile) - if exit_status: raise RuntimeError('pdftops was not able to process your \ + + with io.open(outfile, 'rb') as fh: + if exit_status: + raise RuntimeError('pdftops was not able to process your \ image.\nHere is the full report generated by pdftops: \n\n' + fh.read()) - else: verbose.report(fh.read(), 'debug') - fh.close() + else: + verbose.report(fh.read(), 'debug') os.remove(outfile) os.remove(tmpfile) shutil.move(psfile, tmpfile) @@ -1597,60 +1646,58 @@ bbox_info, rotate = None, None epsfile = tmpfile + '.eps' - epsh = file(epsfile, 'w') - - tmph = file(tmpfile) - line = tmph.readline() - # Modify the header: - while line: - if line.startswith('%!PS'): - print >>epsh, "%!PS-Adobe-3.0 EPSF-3.0" - if bbox: - print >>epsh, bbox_info - elif line.startswith('%%EndComments'): - epsh.write(line) - print >>epsh, '%%BeginProlog' - print >>epsh, 'save' - print >>epsh, 'countdictstack' - print >>epsh, 'mark' - print >>epsh, 'newpath' - print >>epsh, '/showpage {} def' - print >>epsh, '/setpagedevice {pop} def' - print >>epsh, '%%EndProlog' - print >>epsh, '%%Page 1 1' - if rotate: - print >>epsh, rotate - break - elif bbox and (line.startswith('%%Bound') \ - or line.startswith('%%HiResBound') \ - or line.startswith('%%DocumentMedia') \ - or line.startswith('%%Pages')): - pass - else: - epsh.write(line) - line = tmph.readline() - # Now rewrite the rest of the file, and modify the trailer. - # This is done in a second loop such that the header of the embedded - # eps file is not modified. - line = tmph.readline() - while line: - if line.startswith('%%Trailer'): - print >>epsh, '%%Trailer' - print >>epsh, 'cleartomark' - print >>epsh, 'countdictstack' - print >>epsh, 'exch sub { end } repeat' - print >>epsh, 'restore' - if rcParams['ps.usedistiller'] == 'xpdf': - # remove extraneous "end" operator: + with io.open(epsfile, 'wb') as epsh: + write = epsh.write + with io.open(tmpfile, 'rb') as tmph: + line = tmph.readline() + # Modify the header: + while line: + if line.startswith(b'%!PS'): + write(b"%!PS-Adobe-3.0 EPSF-3.0\n") + if bbox: + write(bbox_info.encode('ascii') + b'\n') + elif line.startswith(b'%%EndComments'): + write(line) + write(b'%%BeginProlog\n') + write(b'save\n') + write(b'countdictstack\n') + write(b'mark\n') + write(b'newpath\n') + write(b'/showpage {} def\n') + write(b'/setpagedevice {pop} def\n') + write(b'%%EndProlog\n') + write(b'%%Page 1 1\n') + if rotate: + write(rotate.encode('ascii') + b'\n') + break + elif bbox and (line.startswith(b'%%Bound') \ + or line.startswith(b'%%HiResBound') \ + or line.startswith(b'%%DocumentMedia') \ + or line.startswith(b'%%Pages')): + pass + else: + write(line) + line = tmph.readline() + # Now rewrite the rest of the file, and modify the trailer. + # This is done in a second loop such that the header of the embedded + # eps file is not modified. + line = tmph.readline() + while line: + if line.startswith(b'%%Trailer'): + write(b'%%Trailer\n') + write(b'cleartomark\n') + write(b'countdictstack\n') + write(b'exch sub { end } repeat\n') + write(b'restore\n') + if rcParams['ps.usedistiller'] == 'xpdf': + # remove extraneous "end" operator: + line = tmph.readline() + elif line.startswith(b'%%PageBoundingBox'): + pass + else: + write(line) line = tmph.readline() - elif line.startswith('%%PageBoundingBox'): - pass - else: - epsh.write(line) - line = tmph.readline() - tmph.close() - epsh.close() os.remove(tmpfile) shutil.move(epsfile, tmpfile) diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_qt.py matplotlib-1.2.0/lib/matplotlib/backends/backend_qt.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_qt.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_qt.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,12 @@ -from __future__ import division +from __future__ import division, print_function import math import os import sys +import warnings + +warnings.warn("QT3-based backends are deprecated and will be removed after" + " the v1.2.x release. Use the equivalent QT4 backend instead.", + DeprecationWarning) import matplotlib from matplotlib import verbose @@ -18,7 +23,9 @@ try: import qt except ImportError: - raise ImportError("Qt backend requires pyqt to be installed.") + raise ImportError("Qt backend requires pyqt to be installed." + " NOTE: QT3-based backends will not work in" + " Python 3.") backend_version = "0.9.1" def fn_name(): return sys._getframe(1).f_code.co_name @@ -46,7 +53,7 @@ Only one qApp can exist at a time, so check before creating one """ if qt.QApplication.startingUp(): - if DEBUG: print "Starting up QApplication" + if DEBUG: print("Starting up QApplication") global qApp qApp = qt.QApplication( [" "] ) qt.QObject.connect( qApp, qt.SIGNAL( "lastWindowClosed()" ), @@ -69,9 +76,16 @@ Create a new figure manager instance """ FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass( *args, **kwargs ) - canvas = FigureCanvasQT( thisFig ) - manager = FigureManagerQT( canvas, num ) + thisFig = FigureClass(*args, **kwargs) + return new_figure_manager_given_figure(num, thisFig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + canvas = FigureCanvasQT(figure) + manager = FigureManagerQT(canvas, num) return manager @@ -83,7 +97,7 @@ # left 1, middle 2, right 3 buttond = {1:1, 2:3, 4:2} def __init__( self, figure ): - if DEBUG: print 'FigureCanvasQt: ', figure + if DEBUG: print('FigureCanvasQt: ', figure) _create_qApp() qt.QWidget.__init__( self, None, "QWidget figure" ) @@ -106,14 +120,22 @@ y = self.figure.bbox.height - event.pos().y() button = self.buttond[event.button()] FigureCanvasBase.button_press_event( self, x, y, button ) - if DEBUG: print 'button pressed:', event.button() + if DEBUG: print('button pressed:', event.button()) + + def mouseDoubleClickEvent( self, event ): + x = event.pos().x() + # flipy so y=0 is bottom of canvas + y = self.figure.bbox.height - event.pos().y() + button = self.buttond[event.button()] + FigureCanvasBase.button_press_event( self, x, y, button, dblclick=True ) + if DEBUG: print('button doubleclicked:', event.button()) def mouseMoveEvent( self, event ): x = event.x() # flipy so y=0 is bottom of canvas y = self.figure.bbox.height - event.y() FigureCanvasBase.motion_notify_event( self, x, y ) - if DEBUG: print 'mouse move' + if DEBUG: print('mouse move') def mouseReleaseEvent( self, event ): x = event.x() @@ -121,24 +143,24 @@ y = self.figure.bbox.height - event.y() button = self.buttond[event.button()] FigureCanvasBase.button_release_event( self, x, y, button ) - if DEBUG: print 'button released' + if DEBUG: print('button released') def keyPressEvent( self, event ): key = self._get_key( event ) FigureCanvasBase.key_press_event( self, key ) - if DEBUG: print 'key press', key + if DEBUG: print('key press', key) def keyReleaseEvent( self, event ): key = self._get_key(event) FigureCanvasBase.key_release_event( self, key ) - if DEBUG: print 'key release', key + if DEBUG: print('key release', key) def resizeEvent( self, event ): - if DEBUG: print 'resize (%d x %d)' % (event.size().width(), event.size().height()) + if DEBUG: print('resize (%d x %d)' % (event.size().width(), event.size().height())) qt.QWidget.resizeEvent( self, event ) w = event.size().width() h = event.size().height() - if DEBUG: print "FigureCanvasQt.resizeEvent(", w, ",", h, ")" + if DEBUG: print("FigureCanvasQt.resizeEvent(", w, ",", h, ")") dpival = self.figure.dpi winch = w/dpival hinch = h/dpival @@ -173,6 +195,8 @@ else: key = None + # TODO: Handle ctrl, alt, super modifiers. qt4 backend has implemented. + return key def flush_events(self): @@ -197,7 +221,7 @@ """ def __init__( self, canvas, num ): - if DEBUG: print 'FigureManagerQT.%s' % fn_name() + if DEBUG: print('FigureManagerQT.%s' % fn_name()) FigureManagerBase.__init__( self, canvas, num ) self.canvas = canvas self.window = qt.QMainWindow( None, None, qt.Qt.WDestructiveClose ) @@ -209,7 +233,7 @@ # Give the keyboard focus to the figure instead of the manager self.canvas.setFocusPolicy( qt.QWidget.ClickFocus ) self.canvas.setFocus() - self.window.setCaption( "Figure %d" % num ) + self.set_window_title( "Figure %d" % num ) self.window._destroying = False @@ -241,9 +265,6 @@ if matplotlib.is_interactive(): self.window.show() - # attach a show method to the figure for pylab ease of use - self.canvas.figure.show = lambda *args: self.window.show() - def notify_axes_change( fig ): # This will be called whenever the current axes is changed if self.toolbar != None: self.toolbar.update() @@ -262,7 +283,7 @@ # must be inited after the window, drawingArea and figure # attrs are set if matplotlib.rcParams['toolbar'] == 'classic': - print "Classic toolbar is not yet supported" + print("Classic toolbar is not yet supported") elif matplotlib.rcParams['toolbar'] == 'toolbar2': toolbar = NavigationToolbar2QT(canvas, parent) else: @@ -280,27 +301,16 @@ if self.window._destroying: return self.window._destroying = True if self.toolbar: self.toolbar.destroy() - if DEBUG: print "destroy figure manager" + if DEBUG: print("destroy figure manager") self.window.close(True) + def get_window_title(self): + return str(self.window.caption()) + def set_window_title(self, title): self.window.setCaption(title) class NavigationToolbar2QT( NavigationToolbar2, qt.QWidget ): - # list of toolitems to add to the toolbar, format is: - # text, tooltip_text, image_file, callback(str) - toolitems = ( - ('Home', 'Reset original view', 'home.ppm', 'home'), - ('Back', 'Back to previous view','back.ppm', 'back'), - ('Forward', 'Forward to next view','forward.ppm', 'forward'), - (None, None, None, None), - ('Pan', 'Pan axes with left mouse, zoom with right', 'move.ppm', 'pan'), - ('Zoom', 'Zoom to rectangle','zoom_to_rect.ppm', 'zoom'), - (None, None, None, None), - ('Subplots', 'Configure subplots','subplots.png', 'configure_subplots'), - ('Save', 'Save the figure','filesave.ppm', 'save_figure'), - ) - def __init__( self, canvas, parent ): self.canvas = canvas self.buttons = {} @@ -321,7 +331,7 @@ self.layout.addSpacing( 8 ) continue - fname = os.path.join( basedir, image_file ) + fname = os.path.join(basedir, image_file + '.ppm') image = qt.QPixmap() image.load( fname ) @@ -377,7 +387,7 @@ self.locLabel.setText( s ) def set_cursor( self, cursor ): - if DEBUG: print 'Set cursor' , cursor + if DEBUG: print('Set cursor' , cursor) qt.QApplication.restoreOverrideCursor() qt.QApplication.setOverrideCursor( qt.QCursor( cursord[cursor] ) ) @@ -389,7 +399,7 @@ w = abs(x1 - x0) h = abs(y1 - y0) - rect = [ int(val)for val in min(x0,x1), min(y0, y1), w, h ] + rect = [ int(val)for val in (min(x0,x1), min(y0, y1), w, h) ] self.canvas.drawRectangle( rect ) def configure_subplots(self): @@ -424,7 +434,7 @@ sorted_filetypes.sort() default_filetype = self.canvas.get_default_filetype() - start = "image." + default_filetype + start = self.canvas.get_default_filename() filters = [] selectedFilter = None for name, exts in sorted_filetypes: @@ -441,7 +451,7 @@ if fname: try: self.canvas.print_figure( unicode(fname) ) - except Exception, e: + except Exception as e: qt.QMessageBox.critical( self, "Error saving file", str(e), qt.QMessageBox.Ok, qt.QMessageBox.NoButton) diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_qt4.py matplotlib-1.2.0/lib/matplotlib/backends/backend_qt4.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_qt4.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_qt4.py 2012-11-06 16:32:23.000000000 +0000 @@ -1,6 +1,7 @@ -from __future__ import division +from __future__ import division, print_function import math import os +import signal import sys import matplotlib @@ -48,7 +49,7 @@ Only one qApp can exist at a time, so check before creating one. """ if QtGui.QApplication.startingUp(): - if DEBUG: print "Starting up QApplication" + if DEBUG: print("Starting up QApplication") global qApp app = QtGui.QApplication.instance() if app is None: @@ -60,8 +61,10 @@ class Show(ShowBase): def mainloop(self): - QtGui.qApp.exec_() + # allow KeyboardInterrupt exceptions to close the plot window. + signal.signal(signal.SIGINT, signal.SIG_DFL) + QtGui.qApp.exec_() show = Show() @@ -69,9 +72,16 @@ """ Create a new figure manager instance """ - thisFig = Figure( *args, **kwargs ) - canvas = FigureCanvasQT( thisFig ) - manager = FigureManagerQT( canvas, num ) + thisFig = Figure(*args, **kwargs) + return new_figure_manager_given_figure(num, thisFig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + canvas = FigureCanvasQT(figure) + manager = FigureManagerQT(canvas, num) return manager @@ -96,12 +106,17 @@ self._timer = QtCore.QTimer() QtCore.QObject.connect(self._timer, QtCore.SIGNAL('timeout()'), self._on_timer) + self._timer_set_interval() def __del__(self): # Probably not necessary in practice, but is good behavior to disconnect - TimerBase.__del__(self) - QtCore.QObject.disconnect(self._timer , QtCore.SIGNAL('timeout()'), - self._on_timer) + try: + TimerBase.__del__(self) + QtCore.QObject.disconnect(self._timer, + QtCore.SIGNAL('timeout()'), self._on_timer) + except RuntimeError: + # Timer C++ object already deleted + pass def _timer_set_single_shot(self): self._timer.setSingleShot(self._single) @@ -120,8 +135,57 @@ keyvald = { QtCore.Qt.Key_Control : 'control', QtCore.Qt.Key_Shift : 'shift', QtCore.Qt.Key_Alt : 'alt', - QtCore.Qt.Key_Return : 'enter' + QtCore.Qt.Key_Meta : 'super', + QtCore.Qt.Key_Return : 'enter', + QtCore.Qt.Key_Left : 'left', + QtCore.Qt.Key_Up : 'up', + QtCore.Qt.Key_Right : 'right', + QtCore.Qt.Key_Down : 'down', + QtCore.Qt.Key_Escape : 'escape', + QtCore.Qt.Key_F1 : 'f1', + QtCore.Qt.Key_F2 : 'f2', + QtCore.Qt.Key_F3 : 'f3', + QtCore.Qt.Key_F4 : 'f4', + QtCore.Qt.Key_F5 : 'f5', + QtCore.Qt.Key_F6 : 'f6', + QtCore.Qt.Key_F7 : 'f7', + QtCore.Qt.Key_F8 : 'f8', + QtCore.Qt.Key_F9 : 'f9', + QtCore.Qt.Key_F10 : 'f10', + QtCore.Qt.Key_F11 : 'f11', + QtCore.Qt.Key_F12 : 'f12', + QtCore.Qt.Key_Home : 'home', + QtCore.Qt.Key_End : 'end', + QtCore.Qt.Key_PageUp : 'pageup', + QtCore.Qt.Key_PageDown : 'pagedown', } + + # define the modifier keys which are to be collected on keyboard events. + # format is: [(modifier_flag, modifier_name, equivalent_key) + _modifier_keys = [ + (QtCore.Qt.MetaModifier, 'super', QtCore.Qt.Key_Meta), + (QtCore.Qt.AltModifier, 'alt', QtCore.Qt.Key_Alt), + (QtCore.Qt.ControlModifier, 'ctrl', QtCore.Qt.Key_Control) + ] + + _ctrl_modifier = QtCore.Qt.ControlModifier + + if sys.platform == 'darwin': + # in OSX, the control and super (aka cmd/apple) keys are switched, so + # switch them back. + keyvald.update({ + QtCore.Qt.Key_Control : 'super', # cmd/apple key + QtCore.Qt.Key_Meta : 'control', + }) + + _modifier_keys = [ + (QtCore.Qt.ControlModifier, 'super', QtCore.Qt.Key_Control), + (QtCore.Qt.AltModifier, 'alt', QtCore.Qt.Key_Alt), + (QtCore.Qt.MetaModifier, 'ctrl', QtCore.Qt.Key_Meta), + ] + + _ctrl_modifier = QtCore.Qt.MetaModifier + # map Qt button codes to MouseEvent's ones: buttond = {QtCore.Qt.LeftButton : 1, QtCore.Qt.MidButton : 2, @@ -129,8 +193,9 @@ # QtCore.Qt.XButton1 : None, # QtCore.Qt.XButton2 : None, } + def __init__( self, figure ): - if DEBUG: print 'FigureCanvasQt: ', figure + if DEBUG: print('FigureCanvasQt: ', figure) _create_qApp() QtGui.QWidget.__init__( self ) @@ -171,23 +236,32 @@ # flipy so y=0 is bottom of canvas y = self.figure.bbox.height - event.pos().y() button = self.buttond.get(event.button()) - if button is not None: # only three buttons supported by MouseEvent + if button is not None: FigureCanvasBase.button_press_event( self, x, y, button ) if DEBUG: print('button pressed:', event.button()) + def mouseDoubleClickEvent(self, event): + x = event.pos().x() + # flipy so y=0 is bottom of canvas + y = self.figure.bbox.height - event.pos().y() + button = self.buttond.get(event.button()) + if button is not None: + FigureCanvasBase.button_press_event( self, x, y, button, dblclick=True ) + if DEBUG: print ('button doubleclicked:', event.button()) + def mouseMoveEvent( self, event ): x = event.x() # flipy so y=0 is bottom of canvas y = self.figure.bbox.height - event.y() FigureCanvasBase.motion_notify_event( self, x, y ) - #if DEBUG: print 'mouse move' + #if DEBUG: print('mouse move') def mouseReleaseEvent( self, event ): x = event.x() # flipy so y=0 is bottom of canvas y = self.figure.bbox.height - event.y() button = self.buttond.get(event.button()) - if button is not None: # only three buttons supported by MouseEvent + if button is not None: FigureCanvasBase.button_release_event( self, x, y, button ) if DEBUG: print('button released') @@ -199,27 +273,27 @@ steps = event.delta()/120 if (event.orientation() == QtCore.Qt.Vertical): FigureCanvasBase.scroll_event( self, x, y, steps) - if DEBUG: print 'scroll event : delta = %i, steps = %i ' % (event.delta(),steps) + if DEBUG: print('scroll event : delta = %i, steps = %i ' % (event.delta(),steps)) def keyPressEvent( self, event ): key = self._get_key( event ) if key is None: return FigureCanvasBase.key_press_event( self, key ) - if DEBUG: print 'key press', key + if DEBUG: print('key press', key) def keyReleaseEvent( self, event ): key = self._get_key(event) if key is None: return FigureCanvasBase.key_release_event( self, key ) - if DEBUG: print 'key release', key + if DEBUG: print('key release', key) def resizeEvent( self, event ): - if DEBUG: print 'resize (%d x %d)' % (event.size().width(), event.size().height()) + if DEBUG: print('resize (%d x %d)' % (event.size().width(), event.size().height())) w = event.size().width() h = event.size().height() - if DEBUG: print "FigureCanvasQtAgg.resizeEvent(", w, ",", h, ")" + if DEBUG: print("FigureCanvasQtAgg.resizeEvent(", w, ",", h, ")") dpival = self.figure.dpi winch = w/dpival hinch = h/dpival @@ -238,12 +312,32 @@ def _get_key( self, event ): if event.isAutoRepeat(): return None + if event.key() < 256: - key = str(event.text()) - elif event.key() in self.keyvald: - key = self.keyvald[ event.key() ] + key = unicode(event.text()) + # if the control key is being pressed, we don't get the correct + # characters, so interpret them directly from the event.key(). + # Unfortunately, this means that we cannot handle key's case + # since event.key() is not case sensitive, whereas event.text() is, + # Finally, since it is not possible to get the CapsLock state + # we cannot accurately compute the case of a pressed key when + # ctrl+shift+p is pressed. + if int(event.modifiers()) & self._ctrl_modifier: + # we always get an uppercase character + key = chr(event.key()) + # if shift is not being pressed, lowercase it (as mentioned, + # this does not take into account the CapsLock state) + if not int(event.modifiers()) & QtCore.Qt.ShiftModifier: + key = key.lower() + else: - key = None + key = self.keyvald.get(event.key()) + + if key is not None: + # prepend the ctrl, alt, super keys if appropriate (sorted in that order) + for modifier, prefix, Qt_key in self._modifier_keys: + if event.key() != Qt_key and int(event.modifiers()) & modifier == modifier: + key = u'{}+{}'.format(prefix, key) return key @@ -294,7 +388,7 @@ """ def __init__( self, canvas, num ): - if DEBUG: print 'FigureManagerQT.%s' % fn_name() + if DEBUG: print('FigureManagerQT.%s' % fn_name()) FigureManagerBase.__init__( self, canvas, num ) self.canvas = canvas self.window = QtGui.QMainWindow() @@ -304,8 +398,13 @@ image = os.path.join( matplotlib.rcParams['datapath'],'images','matplotlib.png' ) self.window.setWindowIcon(QtGui.QIcon( image )) - # Give the keyboard focus to the figure instead of the manager - self.canvas.setFocusPolicy( QtCore.Qt.ClickFocus ) + # Give the keyboard focus to the figure instead of the + # manager; StrongFocus accepts both tab and click to focus and + # will enable the canvas to process event w/o clicking. + # ClickFocus only takes the focus is the window has been + # clicked + # on. http://developer.qt.nokia.com/doc/qt-4.8/qt.html#FocusPolicy-enum + self.canvas.setFocusPolicy( QtCore.Qt.StrongFocus ) self.canvas.setFocus() QtCore.QObject.connect( self.window, QtCore.SIGNAL( 'destroyed()' ), @@ -334,13 +433,10 @@ if matplotlib.is_interactive(): self.window.show() - # attach a show method to the figure for pylab ease of use - self.canvas.figure.show = lambda *args: self.window.show() - def notify_axes_change( fig ): - # This will be called whenever the current axes is changed - if self.toolbar is not None: - self.toolbar.update() + # This will be called whenever the current axes is changed + if self.toolbar is not None: + self.toolbar.update() self.canvas.figure.add_axobserver( notify_axes_change ) @QtCore.Slot() @@ -348,6 +444,12 @@ # Fixes a PySide segfault. self.window.statusBar().showMessage(s) + def full_screen_toggle(self): + if self.window.isFullScreen(): + self.window.showNormal() + else: + self.window.showFullScreen() + def _widgetclosed( self ): if self.window._destroying: return self.window._destroying = True @@ -359,12 +461,11 @@ # Gcf can get destroyed before the Gcf.destroy # line is run, leading to a useless AttributeError. - def _get_toolbar(self, canvas, parent): # must be inited after the window, drawingArea and figure # attrs are set if matplotlib.rcParams['toolbar'] == 'classic': - print "Classic toolbar is not supported" + print("Classic toolbar is not supported") elif matplotlib.rcParams['toolbar'] == 'toolbar2': toolbar = NavigationToolbar2QT(canvas, parent, False) else: @@ -386,9 +487,12 @@ QtCore.QObject.disconnect( self.window, QtCore.SIGNAL( 'destroyed()' ), self._widgetclosed ) if self.toolbar: self.toolbar.destroy() - if DEBUG: print "destroy figure manager" + if DEBUG: print("destroy figure manager") self.window.close() + def get_window_title(self): + return str(self.window.windowTitle()) + def set_window_title(self, title): self.window.setWindowTitle(title) @@ -397,6 +501,9 @@ """ coordinates: should we show the coordinates on the right? """ self.canvas = canvas self.coordinates = coordinates + self._actions = {} + """A mapping of toolitem method names to their QActions""" + QtGui.QToolBar.__init__( self, parent ) NavigationToolbar2.__init__( self, canvas ) @@ -406,32 +513,23 @@ def _init_toolbar(self): self.basedir = os.path.join(matplotlib.rcParams[ 'datapath' ],'images') - a = self.addAction(self._icon('home.png'), 'Home', self.home) - a.setToolTip('Reset original view') - a = self.addAction(self._icon('back.png'), 'Back', self.back) - a.setToolTip('Back to previous view') - a = self.addAction(self._icon('forward.png'), 'Forward', self.forward) - a.setToolTip('Forward to next view') - self.addSeparator() - a = self.addAction(self._icon('move.png'), 'Pan', self.pan) - a.setToolTip('Pan axes with left mouse, zoom with right') - a = self.addAction(self._icon('zoom_to_rect.png'), 'Zoom', self.zoom) - a.setToolTip('Zoom to rectangle') - self.addSeparator() - a = self.addAction(self._icon('subplots.png'), 'Subplots', - self.configure_subplots) - a.setToolTip('Configure subplots') + for text, tooltip_text, image_file, callback in self.toolitems: + if text is None: + self.addSeparator() + else: + a = self.addAction(self._icon(image_file + '.png'), + text, getattr(self, callback)) + self._actions[callback] = a + if callback in ['zoom', 'pan']: + a.setCheckable(True) + if tooltip_text is not None: + a.setToolTip(tooltip_text) if figureoptions is not None: a = self.addAction(self._icon("qt4_editor_options.png"), 'Customize', self.edit_parameters) a.setToolTip('Edit curves line and axes parameters') - a = self.addAction(self._icon('filesave.png'), 'Save', - self.save_figure) - a.setToolTip('Save the figure') - - self.buttons = {} # Add the x,y location widget at the right side of the toolbar @@ -482,6 +580,18 @@ figureoptions.figure_edit(axes, self) + def _update_buttons_checked(self): + #sync button checkstates to match active mode + self._actions['pan'].setChecked(self._active == 'PAN') + self._actions['zoom'].setChecked(self._active == 'ZOOM') + + def pan(self, *args): + super(NavigationToolbar2QT, self).pan(*args) + self._update_buttons_checked() + + def zoom(self, *args): + super(NavigationToolbar2QT, self).zoom(*args) + self._update_buttons_checked() def dynamic_update( self ): self.canvas.draw() @@ -492,9 +602,8 @@ self.locLabel.setText(s.replace(', ', '\n')) def set_cursor( self, cursor ): - if DEBUG: print 'Set cursor' , cursor - QtGui.QApplication.restoreOverrideCursor() - QtGui.QApplication.setOverrideCursor( QtGui.QCursor( cursord[cursor] ) ) + if DEBUG: print('Set cursor' , cursor) + self.canvas.window().setCursor(cursord[cursor]) def draw_rubberband( self, event, x0, y0, x1, y1 ): height = self.canvas.figure.bbox.height @@ -504,7 +613,7 @@ w = abs(x1 - x0) h = abs(y1 - y0) - rect = [ int(val)for val in min(x0,x1), min(y0, y1), w, h ] + rect = [ int(val)for val in (min(x0,x1), min(y0, y1), w, h) ] self.canvas.drawRectangle( rect ) def configure_subplots(self): @@ -531,7 +640,7 @@ sorted_filetypes.sort() default_filetype = self.canvas.get_default_filetype() - start = "image." + default_filetype + start = self.canvas.get_default_filename() filters = [] selectedFilter = None for name, exts in sorted_filetypes: @@ -541,13 +650,12 @@ selectedFilter = filter filters.append(filter) filters = ';;'.join(filters) - fname = _getSaveFileName(self, "Choose a filename to save to", start, filters, selectedFilter) if fname: try: self.canvas.print_figure( unicode(fname) ) - except Exception, e: + except Exception as e: QtGui.QMessageBox.critical( self, "Error saving file", str(e), QtGui.QMessageBox.Ok, QtGui.QMessageBox.NoButton) diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_qt4agg.py matplotlib-1.2.0/lib/matplotlib/backends/backend_qt4agg.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_qt4agg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_qt4agg.py 2012-11-06 15:42:20.000000000 +0000 @@ -1,9 +1,10 @@ """ Render to qt from agg """ -from __future__ import division +from __future__ import division, print_function import os, sys +import ctypes import matplotlib from matplotlib.figure import Figure @@ -15,17 +16,29 @@ DEBUG = False +_decref = ctypes.pythonapi.Py_DecRef +_decref.argtypes = [ctypes.py_object] +_decref.restype = None + def new_figure_manager( num, *args, **kwargs ): """ Create a new figure manager instance """ - if DEBUG: print 'backend_qtagg.new_figure_manager' + if DEBUG: print('backend_qtagg.new_figure_manager') FigureClass = kwargs.pop('FigureClass', Figure) thisFig = FigureClass( *args, **kwargs ) - canvas = FigureCanvasQTAgg( thisFig ) + return new_figure_manager_given_figure(num, thisFig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + canvas = FigureCanvasQTAgg(figure) return FigureManagerQT( canvas, num ) + class NavigationToolbar2QTAgg(NavigationToolbar2QT): def _get_canvas(self, fig): return FigureCanvasQTAgg(fig) @@ -35,7 +48,7 @@ # must be inited after the window, drawingArea and figure # attrs are set if matplotlib.rcParams['toolbar']=='classic': - print "Classic toolbar is not supported" + print("Classic toolbar is not supported") elif matplotlib.rcParams['toolbar']=='toolbar2': toolbar = NavigationToolbar2QTAgg(canvas, parent) else: @@ -53,7 +66,7 @@ """ def __init__( self, figure ): - if DEBUG: print 'FigureCanvasQtAgg: ', figure + if DEBUG: print('FigureCanvasQtAgg: ', figure) FigureCanvasQT.__init__( self, figure ) FigureCanvasAgg.__init__( self, figure ) self.drawRect = False @@ -74,8 +87,8 @@ """ #FigureCanvasQT.paintEvent( self, e ) - if DEBUG: print 'FigureCanvasQtAgg.paintEvent: ', self, \ - self.get_width_height() + if DEBUG: print('FigureCanvasQtAgg.paintEvent: ', self, \ + self.get_width_height()) if self.blitbox is None: # matplotlib is in rgba byte order. QImage wants to put the bytes @@ -87,6 +100,8 @@ else: stringBuffer = self.renderer._renderer.tostring_argb() + refcnt = sys.getrefcount(stringBuffer) + qImage = QtGui.QImage(stringBuffer, self.renderer.width, self.renderer.height, QtGui.QImage.Format_ARGB32) @@ -98,6 +113,14 @@ p.setPen( QtGui.QPen( QtCore.Qt.black, 1, QtCore.Qt.DotLine ) ) p.drawRect( self.rect[0], self.rect[1], self.rect[2], self.rect[3] ) p.end() + + # This works around a bug in PySide 1.1.2 on Python 3.x, + # where the reference count of stringBuffer is incremented + # but never decremented by QImage. + # TODO: revert PR #1323 once the issue is fixed in PySide. + del qImage + if refcnt != sys.getrefcount(stringBuffer): + _decref(stringBuffer) else: bbox = self.blitbox l, b, r, t = bbox.extents diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_qtagg.py matplotlib-1.2.0/lib/matplotlib/backends/backend_qtagg.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_qtagg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_qtagg.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,7 @@ """ Render to qt from agg """ -from __future__ import division +from __future__ import division, print_function import os, sys import matplotlib @@ -20,11 +20,19 @@ """ Create a new figure manager instance """ - if DEBUG: print 'backend_qtagg.new_figure_manager' + if DEBUG: print('backend_qtagg.new_figure_manager') FigureClass = kwargs.pop('FigureClass', Figure) thisFig = FigureClass( *args, **kwargs ) - canvas = FigureCanvasQTAgg( thisFig ) - return FigureManagerQTAgg( canvas, num ) + return new_figure_manager_given_figure(num, thisFig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + canvas = FigureCanvasQTAgg(figure) + return FigureManagerQTAgg(canvas, num) + class NavigationToolbar2QTAgg(NavigationToolbar2QT): def _get_canvas(self, fig): @@ -35,7 +43,7 @@ # must be inited after the window, drawingArea and figure # attrs are set if matplotlib.rcParams['toolbar']=='classic': - print "Classic toolbar is not yet supported" + print("Classic toolbar is not yet supported") elif matplotlib.rcParams['toolbar']=='toolbar2': toolbar = NavigationToolbar2QTAgg(canvas, parent) else: @@ -53,7 +61,7 @@ """ def __init__( self, figure ): - if DEBUG: print 'FigureCanvasQtAgg: ', figure + if DEBUG: print('FigureCanvasQtAgg: ', figure) FigureCanvasQT.__init__( self, figure ) FigureCanvasAgg.__init__( self, figure ) self.drawRect = False @@ -78,8 +86,8 @@ """ FigureCanvasQT.paintEvent( self, e ) - if DEBUG: print 'FigureCanvasQtAgg.paintEvent: ', self, \ - self.get_width_height() + if DEBUG: print('FigureCanvasQtAgg.paintEvent: ', self, \ + self.get_width_height()) p = qt.QPainter( self ) @@ -132,7 +140,7 @@ Draw the figure when xwindows is ready for the update """ - if DEBUG: print "FigureCanvasQtAgg.draw", self + if DEBUG: print("FigureCanvasQtAgg.draw", self) self.replot = True FigureCanvasAgg.draw(self) self.repaint(False) diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_svg.py matplotlib-1.2.0/lib/matplotlib/backends/backend_svg.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_svg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_svg.py 2012-11-06 15:42:20.000000000 +0000 @@ -1,6 +1,6 @@ from __future__ import division -import os, codecs, base64, tempfile, urllib, gzip, cStringIO, re, sys +import os, base64, tempfile, urllib, gzip, io, sys, codecs import numpy as np @@ -212,34 +212,34 @@ def generate_transform(transform_list=[]): if len(transform_list): - output = cStringIO.StringIO() + output = io.StringIO() for type, value in transform_list: - if type == 'scale' and (value == (1.0,) or value == (1.0, 1.0)): + if type == u'scale' and (value == (1.0,) or value == (1.0, 1.0)): continue - if type == 'translate' and value == (0.0, 0.0): + if type == u'translate' and value == (0.0, 0.0): continue - if type == 'rotate' and value == (0.0,): + if type == u'rotate' and value == (0.0,): continue - if type == 'matrix' and isinstance(value, Affine2DBase): + if type == u'matrix' and isinstance(value, Affine2DBase): value = value.to_values() - output.write('%s(%s)' % (type, ' '.join(str(x) for x in value))) + output.write(u'%s(%s)' % (type, ' '.join(str(x) for x in value))) return output.getvalue() return '' def generate_css(attrib={}): if attrib: - output = cStringIO.StringIO() + output = io.StringIO() attrib = attrib.items() attrib.sort() for k, v in attrib: k = escape_attrib(k) v = escape_attrib(v) - output.write("%s:%s;" % (k, v)) + output.write(u"%s:%s;" % (k, v)) return output.getvalue() return '' -_capstyle_d = {'projecting' : 'square', 'butt' : 'butt', 'round': 'round',} +_capstyle_d = {'projecting' : u'square', 'butt' : u'butt', 'round': u'round',} class RendererSVG(RendererBase): FONT_SCALE = 100.0 fontd = maxdict(50) @@ -270,12 +270,12 @@ svgwriter.write(svgProlog) self._start_id = self.writer.start( - 'svg', - width='%ipt' % width, height='%ipt' % height, - viewBox='0 0 %i %i' % (width, height), - xmlns="http://www.w3.org/2000/svg", - version="1.1", - attrib={'xmlns:xlink': "http://www.w3.org/1999/xlink"}) + u'svg', + width=u'%ipt' % width, height='%ipt' % height, + viewBox=u'0 0 %i %i' % (width, height), + xmlns=u"http://www.w3.org/2000/svg", + version=u"1.1", + attrib={u'xmlns:xlink': u"http://www.w3.org/1999/xlink"}) self._write_default_style() def finalize(self): @@ -283,20 +283,24 @@ self._write_hatches() self._write_svgfonts() self.writer.close(self._start_id) + self.writer.flush() def _write_default_style(self): writer = self.writer default_style = generate_css({ - 'stroke-linejoin': 'round', - 'stroke-linecap': 'square'}) - writer.start('defs') - writer.start('style', type='text/css') - writer.data('*{%s}\n' % default_style) - writer.end('style') - writer.end('defs') + u'stroke-linejoin': u'round', + u'stroke-linecap': u'square'}) + writer.start(u'defs') + writer.start(u'style', type=u'text/css') + writer.data(u'*{%s}\n' % default_style) + writer.end(u'style') + writer.end(u'defs') def _make_id(self, type, content): - return '%s%s' % (type, md5(str(content)).hexdigest()[:10]) + content = str(content) + if sys.version_info[0] >= 3: + content = content.encode('utf8') + return u'%s%s' % (type, md5(content).hexdigest()[:10]) def _make_flip_transform(self, transform): return (transform + @@ -323,11 +327,16 @@ """ Create a new hatch pattern """ - dictkey = (gc.get_hatch(), rgbFace, gc.get_rgb()) + if rgbFace is not None: + rgbFace = tuple(rgbFace) + edge = gc.get_rgb() + if edge is not None: + edge = tuple(edge) + dictkey = (gc.get_hatch(), rgbFace, edge) oid = self._hatchd.get(dictkey) if oid is None: - oid = self._make_id('h', dictkey) - self._hatchd[dictkey] = ((gc.get_hatch_path(), rgbFace, gc.get_rgb()), oid) + oid = self._make_id(u'h', dictkey) + self._hatchd[dictkey] = ((gc.get_hatch_path(), rgbFace, edge), oid) else: _, oid = oid return oid @@ -340,35 +349,35 @@ writer.start('defs') for ((path, face, stroke), oid) in self._hatchd.values(): writer.start( - 'pattern', + u'pattern', id=oid, - patternUnits="userSpaceOnUse", - x="0", y="0", width=str(HATCH_SIZE), height=str(HATCH_SIZE)) + patternUnits=u"userSpaceOnUse", + x=u"0", y=u"0", width=unicode(HATCH_SIZE), height=unicode(HATCH_SIZE)) path_data = self._convert_path( path, Affine2D().scale(HATCH_SIZE).scale(1.0, -1.0).translate(0, HATCH_SIZE), simplify=False) if face is None: - fill = 'none' + fill = u'none' else: fill = rgb2hex(face) writer.element( - 'rect', - x="0", y="0", width=str(HATCH_SIZE+1), height=str(HATCH_SIZE+1), + u'rect', + x=u"0", y=u"0", width=unicode(HATCH_SIZE+1), height=unicode(HATCH_SIZE+1), fill=fill) writer.element( - 'path', + u'path', d=path_data, style=generate_css({ - 'fill': rgb2hex(stroke), - 'stroke': rgb2hex(stroke), - 'stroke-width': str(1.0), - 'stroke-linecap': 'butt', - 'stroke-linejoin': 'miter' + u'fill': rgb2hex(stroke), + u'stroke': rgb2hex(stroke), + u'stroke-width': u'1.0', + u'stroke-linecap': u'butt', + u'stroke-linejoin': u'miter' }) ) - writer.end('pattern') - writer.end('defs') + writer.end(u'pattern') + writer.end(u'defs') def _get_style_dict(self, gc, rgbFace): """ @@ -378,30 +387,30 @@ attrib = {} if gc.get_hatch() is not None: - attrib['fill'] = "url(#%s)" % self._get_hatch(gc, rgbFace) + attrib[u'fill'] = u"url(#%s)" % self._get_hatch(gc, rgbFace) else: if rgbFace is None: - attrib['fill'] = 'none' + attrib[u'fill'] = u'none' elif tuple(rgbFace[:3]) != (0, 0, 0): - attrib['fill'] = rgb2hex(rgbFace) + attrib[u'fill'] = rgb2hex(rgbFace) if gc.get_alpha() != 1.0: - attrib['opacity'] = str(gc.get_alpha()) + attrib[u'opacity'] = str(gc.get_alpha()) offset, seq = gc.get_dashes() if seq is not None: - attrib['stroke-dasharray'] = ','.join(['%f' % val for val in seq]) - attrib['stroke-dashoffset'] = str(float(offset)) + attrib[u'stroke-dasharray'] = u','.join([u'%f' % val for val in seq]) + attrib[u'stroke-dashoffset'] = unicode(float(offset)) linewidth = gc.get_linewidth() if linewidth: - attrib['stroke'] = rgb2hex(gc.get_rgb()) + attrib[u'stroke'] = rgb2hex(gc.get_rgb()) if linewidth != 1.0: - attrib['stroke-width'] = str(linewidth) + attrib[u'stroke-width'] = str(linewidth) if gc.get_joinstyle() != 'round': - attrib['stroke-linejoin'] = gc.get_joinstyle() + attrib[u'stroke-linejoin'] = gc.get_joinstyle() if gc.get_capstyle() != 'projecting': - attrib['stroke-linecap'] = _capstyle_d[gc.get_capstyle()] + attrib[u'stroke-linecap'] = _capstyle_d[gc.get_capstyle()] return attrib @@ -423,7 +432,7 @@ clip = self._clipd.get(dictkey) if clip is None: - oid = self._make_id('p', dictkey) + oid = self._make_id(u'p', dictkey) if clippath is not None: self._clipd[dictkey] = ((clippath, clippath_trans), oid) else: @@ -442,31 +451,31 @@ if len(clip) == 2: clippath, clippath_trans = clip path_data = self._convert_path(clippath, clippath_trans, simplify=False) - writer.element('path', d=path_data) + writer.element(u'path', d=path_data) else: x, y, w, h = clip - writer.element('rect', x=str(x), y=str(y), width=str(w), height=str(h)) - writer.end('clipPath') - writer.end('defs') + writer.element(u'rect', x=unicode(x), y=unicode(y), width=unicode(w), height=unicode(h)) + writer.end(u'clipPath') + writer.end(u'defs') def _write_svgfonts(self): if not rcParams['svg.fonttype'] == 'svgfont': return writer = self.writer - writer.start('defs') + writer.start(u'defs') for font_fname, chars in self._fonts.items(): font = FT2Font(font_fname) font.set_size(72, 72) sfnt = font.get_sfnt() - writer.start('font', id=sfnt[(1, 0, 0, 4)]) + writer.start(u'font', id=sfnt[(1, 0, 0, 4)]) writer.element( - 'font-face', + u'font-face', attrib={ - 'font-family': font.family_name, - 'font-style': font.style_name.lower(), - 'units-per-em': '72', - 'bbox': ' '.join(str(x / 64.0) for x in font.bbox)}) + u'font-family': font.family_name, + u'font-style': font.style_name.lower(), + u'units-per-em': u'72', + u'bbox': u' '.join(unicode(x / 64.0) for x in font.bbox)}) for char in chars: glyph = font.load_char(char, flags=LOAD_NO_HINTING) verts, codes = font.get_path() @@ -474,14 +483,14 @@ path_data = self._convert_path(path) # name = font.get_glyph_name(char) writer.element( - 'glyph', + u'glyph', d=path_data, attrib={ # 'glyph-name': name, - 'unicode': unichr(char), - 'horiz-adv-x': str(glyph.linearHoriAdvance / 65536.0)}) - writer.end('font') - writer.end('defs') + u'unicode': unichr(char), + u'horiz-adv-x': unicode(glyph.linearHoriAdvance / 65536.0)}) + writer.end(u'font') + writer.end(u'defs') def open_group(self, s, gid=None): """ @@ -492,7 +501,7 @@ self.writer.start('g', id=gid) else: self._groupd[s] = self._groupd.get(s, 0) + 1 - self.writer.start('g', id="%s_%d" % (s, self._groupd[s])) + self.writer.start(u'g', id=u"%s_%d" % (s, self._groupd[s])) def close_group(self, s): self.writer.end('g') @@ -518,17 +527,17 @@ path, trans_and_flip, clip=clip, simplify=simplify) attrib = {} - attrib['style'] = self._get_style(gc, rgbFace) + attrib[u'style'] = self._get_style(gc, rgbFace) clipid = self._get_clip(gc) if clipid is not None: - attrib['clip-path'] = 'url(#%s)' % clipid + attrib[u'clip-path'] = u'url(#%s)' % clipid if gc.get_url() is not None: - self.writer.start('a', {'xlink:href': gc.get_url()}) - self.writer.element('path', d=path_data, attrib=attrib) + self.writer.start(u'a', {u'xlink:href': gc.get_url()}) + self.writer.element(u'path', d=path_data, attrib=attrib) if gc.get_url() is not None: - self.writer.end('') + self.writer.end(u'a') def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None): if not len(path.vertices): @@ -548,65 +557,67 @@ style = generate_css(style) if oid is None: - oid = self._make_id('m', dictkey) - writer.start('defs') - writer.element('path', id=oid, d=path_data, style=style) - writer.end('defs') + oid = self._make_id(u'm', dictkey) + writer.start(u'defs') + writer.element(u'path', id=oid, d=path_data, style=style) + writer.end(u'defs') self._markers[dictkey] = oid attrib = {} clipid = self._get_clip(gc) if clipid is not None: - attrib['clip-path'] = 'url(#%s)' % clipid - writer.start('g', attrib=attrib) + attrib[u'clip-path'] = u'url(#%s)' % clipid + writer.start(u'g', attrib=attrib) trans_and_flip = self._make_flip_transform(trans) - attrib = {'xlink:href': '#%s' % oid} + attrib = {u'xlink:href': u'#%s' % oid} for vertices, code in path.iter_segments(trans_and_flip, simplify=False): if len(vertices): x, y = vertices[-2:] - attrib['x'] = str(x) - attrib['y'] = str(y) - attrib['style'] = self._get_style(gc, rgbFace) - writer.element('use', attrib=attrib) + attrib[u'x'] = unicode(x) + attrib[u'y'] = unicode(y) + attrib[u'style'] = self._get_style(gc, rgbFace) + writer.element(u'use', attrib=attrib) writer.end('g') def draw_path_collection(self, gc, master_transform, paths, all_transforms, offsets, offsetTrans, facecolors, edgecolors, - linewidths, linestyles, antialiaseds, urls): + linewidths, linestyles, antialiaseds, urls, + offset_position): writer = self.writer path_codes = [] - writer.start('defs') + writer.start(u'defs') for i, (path, transform) in enumerate(self._iter_collection_raw_paths( master_transform, paths, all_transforms)): transform = Affine2D(transform.get_matrix()).scale(1.0, -1.0) d = self._convert_path(path, transform, simplify=False) - oid = 'C%x_%x_%s' % (self._path_collection_id, i, - self._make_id('', d)) - writer.element('path', id=oid, d=d) + oid = u'C%x_%x_%s' % (self._path_collection_id, i, + self._make_id(u'', d)) + writer.element(u'path', id=oid, d=d) path_codes.append(oid) - writer.end('defs') + writer.end(u'defs') for xo, yo, path_id, gc0, rgbFace in self._iter_collection( - gc, path_codes, offsets, offsetTrans, facecolors, edgecolors, - linewidths, linestyles, antialiaseds, urls): + gc, master_transform, all_transforms, path_codes, offsets, + offsetTrans, facecolors, edgecolors, linewidths, linestyles, + antialiaseds, urls, offset_position): clipid = self._get_clip(gc0) url = gc0.get_url() if url is not None: - writer.start('a', attrib={'xlink:href': url}) + writer.start(u'a', attrib={u'xlink:href': url}) if clipid is not None: - writer.start('g', attrib={'clip-path': 'url(#%s)' % clipid}) + writer.start(u'g', attrib={u'clip-path': u'url(#%s)' % clipid}) attrib = { - 'xlink:href': '#%s' % path_id, - 'x': str(xo), - 'y': str(self.height - yo), - 'style': self._get_style(gc0, rgbFace) + u'xlink:href': u'#%s' % path_id, + u'x': unicode(xo), + u'y': unicode(self.height - yo), + u'style': self._get_style(gc0, rgbFace) } - writer.element('use', attrib=attrib) + writer.element(u'use', attrib=attrib) if clipid is not None: - writer.end('g') + writer.end(u'g') if url is not None: - writer.end('a') + writer.end(u'a') self._path_collection_id += 1 @@ -626,15 +637,15 @@ if not self._has_gouraud: self._has_gouraud = True writer.start( - 'filter', - id='colorAdd') + u'filter', + id=u'colorAdd') writer.element( - 'feComposite', - attrib={'in': 'SourceGraphic'}, - in2='BackgroundImage', - operator='arithmetic', - k2="1", k3="1") - writer.end('filter') + u'feComposite', + attrib={u'in': u'SourceGraphic'}, + in2=u'BackgroundImage', + operator=u'arithmetic', + k2=u"1", k3=u"1") + writer.end(u'filter') avg_color = np.sum(colors[:, :], axis=0) / 3.0 # Just skip fully-transparent triangles @@ -644,11 +655,11 @@ trans_and_flip = self._make_flip_transform(trans) tpoints = trans_and_flip.transform(points) - writer.start('defs') + writer.start(u'defs') for i in range(3): - x1, y1 = points[i] - x2, y2 = points[(i + 1) % 3] - x3, y3 = points[(i + 2) % 3] + x1, y1 = tpoints[i] + x2, y2 = tpoints[(i + 1) % 3] + x3, y3 = tpoints[(i + 2) % 3] c = colors[i][:] if x2 == x3: @@ -666,41 +677,41 @@ yb = m2 * xb + b2 writer.start( - 'linearGradient', - id="GR%x_%d" % (self._n_gradients, i), - x1=str(x1), y1=str(y1), x2=str(xb), y2=str(yb)) + u'linearGradient', + id=u"GR%x_%d" % (self._n_gradients, i), + x1=unicode(x1), y1=unicode(y1), x2=unicode(xb), y2=unicode(yb)) writer.element( - 'stop', - offset='0', + u'stop', + offset=u'0', style=generate_css({'stop-color': rgb2hex(c), - 'stop-opacity': str(c[-1])})) + 'stop-opacity': unicode(c[-1])})) writer.element( - 'stop', - offset='1', - style=generate_css({'stop-color': rgb2hex(c), - 'stop-opacity': "0"})) - writer.end('linearGradient') + u'stop', + offset=u'1', + style=generate_css({u'stop-color': rgb2hex(c), + u'stop-opacity': u"0"})) + writer.end(u'linearGradient') writer.element( - 'polygon', - id='GT%x' % self._n_gradients, - points=" ".join([str(x) for x in x1,y1,x2,y2,x3,y3])) + u'polygon', + id=u'GT%x' % self._n_gradients, + points=u" ".join([unicode(x) for x in x1,y1,x2,y2,x3,y3])) writer.end('defs') avg_color = np.sum(colors[:, :], axis=0) / 3.0 - href = '#GT%x' % self._n_gradients + href = u'#GT%x' % self._n_gradients writer.element( - 'use', - attrib={'xlink:href': href, - 'fill': rgb2hex(avg_color), - 'fill-opacity': str(avg_color[-1])}) + u'use', + attrib={u'xlink:href': href, + u'fill': rgb2hex(avg_color), + u'fill-opacity': str(avg_color[-1])}) for i in range(3): writer.element( - 'use', - attrib={'xlink:href': href, - 'fill': 'url(#GR%x_%d)' % (self._n_gradients, i), - 'fill-opacity': '1', - 'filter': 'url(#colorAdd)'}) + u'use', + attrib={u'xlink:href': href, + u'fill': u'url(#GR%x_%d)' % (self._n_gradients, i), + u'fill-opacity': u'1', + u'filter': u'url(#colorAdd)'}) self._n_gradients += 1 @@ -709,15 +720,15 @@ attrib = {} clipid = self._get_clip(gc) if clipid is not None: - attrib['clip-path'] = 'url(#%s)' % clipid + attrib[u'clip-path'] = u'url(#%s)' % clipid - self.writer.start('g', attrib=attrib) + self.writer.start(u'g', attrib=attrib) transform = transform.frozen() for tri, col in zip(triangles_array, colors_array): self.draw_gouraud_triangle(gc, tri, col, transform) - self.writer.end('g') + self.writer.end(u'g') def option_scale_image(self): return True @@ -729,13 +740,13 @@ # Can't apply clip-path directly to the image because the # image has a transformation, which would also be applied # to the clip-path - self.writer.start('g', attrib={'clip-path': 'url(#%s)' % clipid}) + self.writer.start(u'g', attrib={u'clip-path': u'url(#%s)' % clipid}) trans = [1,0,0,1,0,0] if rcParams['svg.image_noscale']: trans = list(im.get_matrix()) trans[5] = -trans[5] - attrib['transform'] = generate_transform([('matrix', tuple(trans))]) + attrib[u'transform'] = generate_transform([(u'matrix', tuple(trans))]) assert trans[1] == 0 assert trans[2] == 0 numrows, numcols = im.get_size() @@ -744,54 +755,65 @@ im.resize(numcols, numrows) h,w = im.get_size_out() - + oid = getattr(im, '_gid', None) url = getattr(im, '_url', None) if url is not None: - self.writer.start('a', attrib={'xlink:href': url}) + self.writer.start(u'a', attrib={u'xlink:href': url}) if rcParams['svg.image_inline']: - stringio = cStringIO.StringIO() + bytesio = io.BytesIO() im.flipud_out() rows, cols, buffer = im.as_rgba_str() - _png.write_png(buffer, cols, rows, stringio) + _png.write_png(buffer, cols, rows, bytesio) im.flipud_out() - attrib['xlink:href'] = ("data:image/png;base64,\n" + - base64.encodestring(stringio.getvalue())) + oid = oid or self._make_id('image', bytesio) + attrib['xlink:href'] = ( + u"data:image/png;base64,\n" + + base64.b64encode(bytesio.getvalue()).decode('ascii')) else: self._imaged[self.basename] = self._imaged.get(self.basename,0) + 1 - filename = '%s.image%d.png'%(self.basename, self._imaged[self.basename]) + filename = u'%s.image%d.png'%(self.basename, self._imaged[self.basename]) verbose.report( 'Writing image file for inclusion: %s' % filename) im.flipud_out() rows, cols, buffer = im.as_rgba_str() _png.write_png(buffer, cols, rows, filename) im.flipud_out() - attrib['xlink:href'] = filename + oid = oid or 'Im_' + self._make_id('image', filename) + attrib[u'xlink:href'] = filename alpha = gc.get_alpha() if alpha != 1.0: attrib['opacity'] = str(alpha) + attrib['id'] = oid + if transform is None: self.writer.element( - 'image', - x=str(x/trans[0]), y=str((self.height-y)/trans[3]-h), - width=str(w), height=str(h), + u'image', + x=unicode(x/trans[0]), y=unicode((self.height-y)/trans[3]-h), + width=unicode(w), height=unicode(h), attrib=attrib) else: flipped = self._make_flip_transform(transform) - attrib['transform'] = generate_transform( - [('matrix', flipped.to_values())]) + flipped = np.array(flipped.to_values()) + y = y+dy + if dy > 0.0: + flipped[3] *= -1.0 + y *= -1.0 + attrib[u'transform'] = generate_transform( + [(u'matrix', flipped)]) self.writer.element( - 'image', - x=str(x), y=str(y+dy), width=str(dx), height=str(-dy), + u'image', + x=unicode(x), y=unicode(y), + width=unicode(dx), height=unicode(abs(dy)), attrib=attrib) if url is not None: - self.writer.end('a') + self.writer.end(u'a') if clipid is not None: - self.writer.end('g') + self.writer.end(u'g') def _adjust_char_id(self, char_id): - return char_id.replace("%20", "_") + return char_id.replace(u"%20", u"_") def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath): """ @@ -823,7 +845,7 @@ if color != '#000000': style['fill'] = color if gc.get_alpha() != 1.0: - style['opacity'] = str(gc.get_alpha()) + style[u'opacity'] = unicode(gc.get_alpha()) if not ismath: font = text2path._get_font(prop) @@ -834,35 +856,35 @@ (prop.get_size_in_points() / text2path.FONT_SCALE)) if glyph_map_new: - writer.start('defs') + writer.start(u'defs') for char_id, glyph_path in glyph_map_new.iteritems(): path = Path(*glyph_path) path_data = self._convert_path(path, simplify=False) - writer.element('path', id=char_id, d=path_data) - writer.end('defs') + writer.element(u'path', id=char_id, d=path_data) + writer.end(u'defs') glyph_map.update(glyph_map_new) attrib = {} - attrib['style'] = generate_css(style) + attrib[u'style'] = generate_css(style) font_scale = fontsize / text2path.FONT_SCALE - attrib['transform'] = generate_transform([ - ('translate', (x, y)), - ('rotate', (-angle,)), - ('scale', (font_scale, -font_scale))]) + attrib[u'transform'] = generate_transform([ + (u'translate', (x, y)), + (u'rotate', (-angle,)), + (u'scale', (font_scale, -font_scale))]) - writer.start('g', attrib=attrib) + writer.start(u'g', attrib=attrib) for glyph_id, xposition, yposition, scale in glyph_info: - attrib={'xlink:href': '#%s' % glyph_id} + attrib={u'xlink:href': u'#%s' % glyph_id} if xposition != 0.0: - attrib['x'] = str(xposition) + attrib[u'x'] = str(xposition) if yposition != 0.0: - attrib['y'] = str(yposition) + attrib[u'y'] = str(yposition) writer.element( - 'use', + u'use', attrib=attrib) - writer.end('g') + writer.end(u'g') else: if ismath == "TeX": _glyphs = text2path.get_glyphs_tex(prop, s, glyph_map=glyph_map, @@ -877,44 +899,44 @@ # coordinate will be flipped when this characters are # used. if glyph_map_new: - writer.start('defs') + writer.start(u'defs') for char_id, glyph_path in glyph_map_new.iteritems(): char_id = self._adjust_char_id(char_id) # Some characters are blank if not len(glyph_path[0]): - path_data = "" + path_data = u"" else: path = Path(*glyph_path) path_data = self._convert_path(path, simplify=False) - writer.element('path', id=char_id, d=path_data) - writer.end('defs') + writer.element(u'path', id=char_id, d=path_data) + writer.end(u'defs') glyph_map.update(glyph_map_new) attrib = {} font_scale = fontsize / text2path.FONT_SCALE - attrib['style'] = generate_css(style) - attrib['transform'] = generate_transform([ - ('translate', (x, y)), - ('rotate', (-angle,)), - ('scale', (font_scale, - font_scale))]) + attrib[u'style'] = generate_css(style) + attrib[u'transform'] = generate_transform([ + (u'translate', (x, y)), + (u'rotate', (-angle,)), + (u'scale', (font_scale, -font_scale))]) - writer.start('g', attrib=attrib) + writer.start(u'g', attrib=attrib) for char_id, xposition, yposition, scale in glyph_info: char_id = self._adjust_char_id(char_id) writer.element( - 'use', + u'use', transform=generate_transform([ - ('translate', (xposition, yposition)), - ('scale', (scale,)), + (u'translate', (xposition, yposition)), + (u'scale', (scale,)), ]), - attrib={'xlink:href': '#%s' % char_id}) + attrib={u'xlink:href': u'#%s' % char_id}) for verts, codes in rects: path = Path(verts, codes) path_data = self._convert_path(path, simplify=False) - writer.element('path', d=path_data) + writer.element(u'path', d=path_data) writer.end('g') @@ -924,9 +946,9 @@ color = rgb2hex(gc.get_rgb()) style = {} if color != '#000000': - style['fill'] = color + style[u'fill'] = color if gc.get_alpha() != 1.0: - style['opacity'] = str(gc.get_alpha()) + style[u'opacity'] = unicode(gc.get_alpha()) if not ismath: font = self._get_font(prop) @@ -940,16 +962,16 @@ attrib = {} # Must add "px" to workaround a Firefox bug - style['font-size'] = str(fontsize) + 'px' - style['font-family'] = str(fontfamily) - style['font-style'] = prop.get_style().lower() - attrib['style'] = generate_css(style) - - attrib['transform'] = generate_transform([ - ('translate', (x, y)), - ('rotate', (-angle,))]) + style[u'font-size'] = str(fontsize) + 'px' + style[u'font-family'] = str(fontfamily) + style[u'font-style'] = prop.get_style().lower() + attrib[u'style'] = generate_css(style) + + attrib[u'transform'] = generate_transform([ + (u'translate', (x, y)), + (u'rotate', (-angle,))]) - writer.element('text', s, attrib=attrib) + writer.element(u'text', s, attrib=attrib) if rcParams['svg.fonttype'] == 'svgfont': fontset = self._fonts.setdefault(font.fname, set()) @@ -964,27 +986,26 @@ svg_rects = svg_elements.svg_rects attrib = {} - attrib['style'] = generate_css(style) - attrib['transform'] = generate_transform([ - ('translate', (x, y)), - ('rotate', (-angle,))]) + attrib[u'style'] = generate_css(style) + attrib[u'transform'] = generate_transform([ + (u'translate', (x, y)), + (u'rotate', (-angle,))]) # Apply attributes to 'g', not 'text', because we likely # have some rectangles as well with the same style and # transformation - writer.start('g', attrib=attrib) + writer.start(u'g', attrib=attrib) - writer.start('text') + writer.start(u'text') # Sort the characters by font, and output one tspan for # each spans = {} for font, fontsize, thetext, new_x, new_y, metrics in svg_glyphs: style = generate_css({ - # Must add "px" to work around a Firefox bug - 'font-size': str(fontsize) + 'px', - 'font-family': font.family_name, - 'font-style': font.style_name.lower()}) + u'font-size': unicode(fontsize) + 'px', + u'font-family': font.family_name, + u'font-style': font.style_name.lower()}) if thetext == 32: thetext = 0xa0 # non-breaking space spans.setdefault(style, []).append((new_x, -new_y, thetext)) @@ -1005,32 +1026,32 @@ same_y = False break if same_y: - ys = str(chars[0][1]) + ys = unicode(chars[0][1]) else: - ys = ' '.join(str(c[1]) for c in chars) + ys = ' '.join(unicode(c[1]) for c in chars) attrib = { - 'style': style, - 'x': ' '.join(str(c[0]) for c in chars), - 'y': ys + u'style': style, + u'x': ' '.join(unicode(c[0]) for c in chars), + u'y': ys } writer.element( - 'tspan', - ''.join(unichr(c[2]) for c in chars), + u'tspan', + u''.join(unichr(c[2]) for c in chars), attrib=attrib) - writer.end('text') + writer.end(u'text') if len(svg_rects): for x, y, width, height in svg_rects: writer.element( - 'rect', - x=str(x), y=str(-y + height), - width=str(width), height=str(height) + u'rect', + x=unicode(x), y=unicode(-y + height), + width=unicode(width), height=unicode(height) ) - writer.end('g') + writer.end(u'g') def draw_tex(self, gc, x, y, s, prop, angle): self._draw_text_as_path(gc, x, y, s, prop, angle, ismath="TeX") @@ -1041,7 +1062,7 @@ # Cannot apply clip-path directly to the text, because # is has a transformation self.writer.start( - 'g', attrib={'clip-path': 'url(#%s)' % clipid}) + u'g', attrib={u'clip-path': u'url(#%s)' % clipid}) if rcParams['svg.fonttype'] == 'path': self._draw_text_as_path(gc, x, y, s, prop, angle, ismath) @@ -1049,7 +1070,7 @@ self._draw_text_as_text(gc, x, y, s, prop, angle, ismath) if clipid is not None: - self.writer.end('g') + self.writer.end(u'g') def flipy(self): return True @@ -1067,9 +1088,15 @@ def print_svg(self, filename, *args, **kwargs): if is_string_like(filename): - fh_to_close = svgwriter = codecs.open(filename, 'w', 'utf-8') + fh_to_close = svgwriter = io.open(filename, 'w', encoding='utf-8') elif is_writable_file_like(filename): - svgwriter = codecs.getwriter('utf-8')(filename) + if not isinstance(filename, io.TextIOBase): + if sys.version_info[0] >= 3: + svgwriter = io.TextIOWrapper(filename, 'utf-8') + else: + svgwriter = codecs.getwriter('utf-8')(filename) + else: + svgwriter = filename fh_to_close = None else: raise ValueError("filename must be a path or a file-like object") @@ -1077,41 +1104,43 @@ def print_svgz(self, filename, *args, **kwargs): if is_string_like(filename): - gzipwriter = gzip.GzipFile(filename, 'w') - fh_to_close = svgwriter = codecs.getwriter('utf-8')(gzipwriter) + fh_to_close = gzipwriter = gzip.GzipFile(filename, 'w') + svgwriter = io.TextIOWrapper(gzipwriter, 'utf-8') elif is_writable_file_like(filename): fh_to_close = gzipwriter = gzip.GzipFile(fileobj=filename, mode='w') - svgwriter = codecs.getwriter('utf-8')(gzipwriter) + svgwriter = io.TextIOWrapper(gzipwriter, 'utf-8') else: raise ValueError("filename must be a path or a file-like object") return self._print_svg(filename, svgwriter, fh_to_close) def _print_svg(self, filename, svgwriter, fh_to_close=None, **kwargs): - self.figure.set_dpi(72.0) - width, height = self.figure.get_size_inches() - w, h = width*72, height*72 + try: + self.figure.set_dpi(72.0) + width, height = self.figure.get_size_inches() + w, h = width*72, height*72 - if rcParams['svg.image_noscale']: - renderer = RendererSVG(w, h, svgwriter, filename) - else: - # setting mixed renderer dpi other than 72 results in - # incorrect size of the rasterized image. It seems that the - # svg internally uses fixed dpi of 72 and seems to cause - # the problem. I hope someone who knows the svg backends - # take a look at this problem. Meanwhile, the dpi - # parameter is ignored and image_dpi is fixed at 72. - JJL - - #image_dpi = kwargs.pop("dpi", 72) - image_dpi = 72 - _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None) - renderer = MixedModeRenderer(self.figure, - width, height, image_dpi, RendererSVG(w, h, svgwriter, filename), - bbox_inches_restore=_bbox_inches_restore) - - self.figure.draw(renderer) - renderer.finalize() - if fh_to_close is not None: - svgwriter.close() + if rcParams['svg.image_noscale']: + renderer = RendererSVG(w, h, svgwriter, filename) + else: + # setting mixed renderer dpi other than 72 results in + # incorrect size of the rasterized image. It seems that the + # svg internally uses fixed dpi of 72 and seems to cause + # the problem. I hope someone who knows the svg backends + # take a look at this problem. Meanwhile, the dpi + # parameter is ignored and image_dpi is fixed at 72. - JJL + + #image_dpi = kwargs.pop("dpi", 72) + image_dpi = 72 + _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None) + renderer = MixedModeRenderer(self.figure, + width, height, image_dpi, RendererSVG(w, h, svgwriter, filename), + bbox_inches_restore=_bbox_inches_restore) + + self.figure.draw(renderer) + renderer.finalize() + finally: + if fh_to_close is not None: + svgwriter.close() def get_default_filetype(self): return 'svg' @@ -1124,13 +1153,21 @@ def new_figure_manager(num, *args, **kwargs): FigureClass = kwargs.pop('FigureClass', Figure) thisFig = FigureClass(*args, **kwargs) - canvas = FigureCanvasSVG(thisFig) + return new_figure_manager_given_figure(num, thisFig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + canvas = FigureCanvasSVG(figure) manager = FigureManagerSVG(canvas, num) return manager + svgProlog = u"""\ - + """ diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_template.py matplotlib-1.2.0/lib/matplotlib/backends/backend_template.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_template.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_template.py 2012-10-31 00:11:13.000000000 +0000 @@ -54,7 +54,7 @@ """ -from __future__ import division +from __future__ import division, print_function import matplotlib from matplotlib._pylab_helpers import Gcf @@ -98,7 +98,7 @@ # performance will probably want to implement it # def draw_quad_mesh(self, gc, master_transform, meshWidth, meshHeight, # coordinates, offsets, offsetTrans, facecolors, -# antialiased, showedges): +# antialiased, edgecolors): # pass def draw_image(self, gc, x, y, im): @@ -184,13 +184,21 @@ """ Create a new figure manager instance """ - # if a main-level app must be created, this is the usual place to + # if a main-level app must be created, this (and + # new_figure_manager_given_figure) is the usual place to # do it -- see backend_wx, backend_wxagg and backend_tkagg for # examples. Not all GUIs require explicit instantiation of a # main-level app (egg backend_gtk, backend_gtkagg) for pylab FigureClass = kwargs.pop('FigureClass', Figure) thisFig = FigureClass(*args, **kwargs) - canvas = FigureCanvasTemplate(thisFig) + return new_figure_manager_given_figure(num, thisFig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + canvas = FigureCanvasTemplate(figure) manager = FigureManagerTemplate(canvas, num) return manager @@ -253,4 +261,3 @@ FigureManager = FigureManagerTemplate - diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_tkagg.py matplotlib-1.2.0/lib/matplotlib/backends/backend_tkagg.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_tkagg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_tkagg.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,6 @@ # Todd Miller jmiller@stsci.edu -from __future__ import division +from __future__ import division, print_function import os, sys, math import os.path @@ -74,10 +74,35 @@ """ Create a new figure manager instance """ - _focus = windowing.FocusManager() FigureClass = kwargs.pop('FigureClass', Figure) figure = FigureClass(*args, **kwargs) + return new_figure_manager_given_figure(num, figure) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + _focus = windowing.FocusManager() window = Tk.Tk() + window.withdraw() + + if Tk.TkVersion >= 8.5: + # put a mpl icon on the window rather than the default tk icon. Tkinter + # doesn't allow colour icons on linux systems, but tk >=8.5 has a iconphoto + # command which we call directly. Source: + # http://mail.python.org/pipermail/tkinter-discuss/2006-November/000954.html + icon_fname = os.path.join(rcParams['datapath'], 'images', 'matplotlib.gif') + icon_img = Tk.PhotoImage(file=icon_fname) + try: + window.tk.call('wm', 'iconphoto', window._w, icon_img) + except (SystemExit, KeyboardInterrupt): + # re-raise exit type Exceptions + raise + except: + # log the failure, but carry on + verbose.report('Could not load matplotlib icon: %s' % sys.exc_info()[1]) + canvas = FigureCanvasTkAgg(figure, master=window) figManager = FigureManagerTkAgg(canvas, num, window) if matplotlib.is_interactive(): @@ -127,6 +152,7 @@ keyvald = {65507 : 'control', 65505 : 'shift', 65513 : 'alt', + 65515 : 'super', 65508 : 'control', 65506 : 'shift', 65514 : 'alt', @@ -175,6 +201,18 @@ 65421 : 'enter', } + _keycode_lookup = { + 262145: 'control', + 524320: 'alt', + 524352: 'alt', + 1048584: 'super', + 1048592: 'super', + 131074: 'shift', + 131076: 'shift', + } + """_keycode_lookup is used for badly mapped (i.e. no event.key_sym set) + keys on apple keyboards.""" + def __init__(self, figure, master=None, resize_callback=None): FigureCanvasAgg.__init__(self, figure) self._idle = True @@ -193,6 +231,8 @@ self._tkcanvas.bind("", self.key_release) for name in "", "", "": self._tkcanvas.bind(name, self.button_press_event) + for name in "", "", "": + self._tkcanvas.bind(name, self.button_dblclick_event) for name in "", "", "": self._tkcanvas.bind(name, self.button_release_event) @@ -235,6 +275,75 @@ self.resize_event() self.show() + # a resizing will in general move the pointer position + # relative to the canvas, so process it as a motion notify + # event. An intended side effect of this call is to allow + # window raises (which trigger a resize) to get the cursor + # position to the mpl event framework so key presses which are + # over the axes will work w/o clicks or explicit motion + self._update_pointer_position(event) + + def _update_pointer_position(self, guiEvent=None): + """ + Figure out if we are inside the canvas or not and update the + canvas enter/leave events + """ + # if the pointer if over the canvas, set the lastx and lasty + # attrs of the canvas so it can process event w/o mouse click + # or move + + # the window's upper, left coords in screen coords + xw = self._tkcanvas.winfo_rootx() + yw = self._tkcanvas.winfo_rooty() + # the pointer's location in screen coords + xp, yp = self._tkcanvas.winfo_pointerxy() + + # not figure out the canvas coordinates of the pointer + xc = xp - xw + yc = yp - yw + + # flip top/bottom + yc = self.figure.bbox.height - yc + + # JDH: this method was written originally to get the pointer + # location to the backend lastx and lasty attrs so that events + # like KeyEvent can be handled without mouse events. Eg, if + # the cursor is already above the axes, then key presses like + # 'g' should toggle the grid. In order for this to work in + # backend_bases, the canvas needs to know _lastx and _lasty. + # There are three ways to get this info the canvas: + # + # 1) set it explicity + # + # 2) call enter/leave events explicity. The downside of this + # in the impl below is that enter could be repeatedly + # triggered if thes mouse is over the axes and one is + # resizing with the keyboard. This is not entirely bad, + # because the mouse position relative to the canvas is + # changing, but it may be surprising to get repeated entries + # without leaves + # + # 3) process it as a motion notify event. This also has pros + # and cons. The mouse is moving relative to the window, but + # this may surpise an event handler writer who is getting + # motion_notify_events even if the mouse has not moved + + # here are the three scenarios + if 1: + # just manually set it + self._lastx, self._lasty = xc, yc + elif 0: + # alternate implementation: process it as a motion + FigureCanvasBase.motion_notify_event(self, xc, yc, guiEvent) + elif 0: + # alternate implementation -- process enter/leave events + # instead of motion/notify + if self.figure.bbox.contains(xc, yc): + self.enter_notify_event(guiEvent, xy=(xc,yc)) + else: + self.leave_notify_event(guiEvent) + + def draw(self): FigureCanvasAgg.draw(self) tkagg.blit(self._tkphoto, self.renderer._renderer, colormode=2) @@ -271,7 +380,7 @@ FigureCanvasBase.motion_notify_event(self, x, y, guiEvent=event) - def button_press_event(self, event): + def button_press_event(self, event, dblclick=False): x = event.x # flipy so y=0 is bottom of canvas y = self.figure.bbox.height - event.y @@ -283,7 +392,10 @@ if num==2: num=3 elif num==3: num=2 - FigureCanvasBase.button_press_event(self, x, y, num, guiEvent=event) + FigureCanvasBase.button_press_event(self, x, y, num, dblclick=dblclick, guiEvent=event) + + def button_dblclick_event(self,event): + self.button_press_event(event,dblclick=True) def button_release_event(self, event): x = event.x @@ -325,12 +437,39 @@ val = event.keysym_num if val in self.keyvald: key = self.keyvald[val] - elif val<256: + elif val == 0 and sys.platform == 'darwin' and \ + event.keycode in self._keycode_lookup: + key = self._keycode_lookup[event.keycode] + elif val < 256: key = chr(val) else: key = None - return key + # add modifier keys to the key string. Bit details originate from + # http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm + # BIT_SHIFT = 0x001; BIT_CAPSLOCK = 0x002; BIT_CONTROL = 0x004; + # BIT_LEFT_ALT = 0x008; BIT_NUMLOCK = 0x010; BIT_RIGHT_ALT = 0x080; + # BIT_MB_1 = 0x100; BIT_MB_2 = 0x200; BIT_MB_3 = 0x400; + # In general, the modifier key is excluded from the modifier flag, + # however this is not the case on "darwin", so double check that + # we aren't adding repeat modifier flags to a modifier key. + modifiers = [(6, 'super', 'super'), + (3, 'alt', 'alt'), + (2, 'ctrl', 'control'), + ] + if sys.platform == 'darwin': + modifiers = [(3, 'super', 'super'), + (4, 'alt', 'alt'), + (2, 'ctrl', 'control'), + ] + + if key is not None: + # note, shift is not added to the keys as this is already accounted for + for bitmask, prefix, key_name in modifiers: + if event.state & (1 << bitmask) and key_name not in key: + key = '{}+{}'.format(prefix, key) + + return key def key_press(self, event): key = self._get_key(event) @@ -380,10 +519,10 @@ FigureManagerBase.__init__(self, canvas, num) self.window = window self.window.withdraw() - self.window.wm_title("Figure %d" % num) + self.set_window_title("Figure %d" % num) self.canvas = canvas self._num = num - t1,t2,w,h = canvas.figure.bbox.bounds + _, _, w, h = canvas.figure.bbox.bounds w, h = int(w), int(h) self.window.minsize(int(w*3/4),int(h*3/4)) if matplotlib.rcParams['toolbar']=='classic': @@ -402,12 +541,6 @@ if self.toolbar != None: self.toolbar.update() self.canvas.figure.add_axobserver(notify_axes_change) - - - # attach a show method to the figure for pylab ease of use - self.canvas.figure.show = lambda *args: self.show() - - def resize(self, width, height=None): # before 09-12-22, the resize method takes a single *event* # parameter. On the other hand, the resize method of other @@ -425,7 +558,6 @@ self.toolbar.configure(width=width) - def show(self): """ this function doesn't segfault but causes the @@ -444,7 +576,6 @@ self.canvas.draw_idle() self._shown = True - def destroy(self, *args): if self.window is not None: #self.toolbar.destroy() @@ -456,9 +587,17 @@ self.window.quit() self.window = None + def get_window_title(self): + return self.window.wm_title() + def set_window_title(self, title): self.window.wm_title(title) + def full_screen_toggle(self): + is_fullscreen = bool(self.window.attributes('-fullscreen')) + self.window.attributes('-fullscreen', not is_fullscreen) + + class AxisMenu: def __init__(self, master, naxes): self._master = master @@ -521,9 +660,10 @@ a.set(1) self.set_active() + class NavigationToolbar(Tk.Frame): """ - Public attriubutes + Public attributes canvas - the FigureCanvas (gtk.DrawingArea) win - the gtk.Window @@ -551,39 +691,39 @@ self.update() # Make axes menu self.bLeft = self._Button( - text="Left", file="stock_left.ppm", + text="Left", file="stock_left", command=lambda x=-1: self.panx(x)) self.bRight = self._Button( - text="Right", file="stock_right.ppm", + text="Right", file="stock_right", command=lambda x=1: self.panx(x)) self.bZoomInX = self._Button( - text="ZoomInX",file="stock_zoom-in.ppm", + text="ZoomInX",file="stock_zoom-in", command=lambda x=1: self.zoomx(x)) self.bZoomOutX = self._Button( - text="ZoomOutX", file="stock_zoom-out.ppm", + text="ZoomOutX", file="stock_zoom-out", command=lambda x=-1: self.zoomx(x)) self.bUp = self._Button( - text="Up", file="stock_up.ppm", + text="Up", file="stock_up", command=lambda y=1: self.pany(y)) self.bDown = self._Button( - text="Down", file="stock_down.ppm", + text="Down", file="stock_down", command=lambda y=-1: self.pany(y)) self.bZoomInY = self._Button( - text="ZoomInY", file="stock_zoom-in.ppm", + text="ZoomInY", file="stock_zoom-in", command=lambda y=1: self.zoomy(y)) self.bZoomOutY = self._Button( - text="ZoomOutY",file="stock_zoom-out.ppm", + text="ZoomOutY",file="stock_zoom-out", command=lambda y=-1: self.zoomy(y)) self.bSave = self._Button( - text="Save", file="stock_save_as.ppm", + text="Save", file="stock_save_as", command=self.save_figure) self.pack(side=Tk.BOTTOM, fill=Tk.X) @@ -630,7 +770,7 @@ self.lastDir = os.path.dirname(fname) try: self.canvas.print_figure(fname) - except IOError, msg: + except IOError as msg: err = '\n'.join(map(str, msg)) msg = 'Failed to save %s: Error msg was\n\n%s' % ( fname, err) @@ -648,7 +788,7 @@ class NavigationToolbar2TkAgg(NavigationToolbar2, Tk.Frame): """ - Public attriubutes + Public attributes canvas - the FigureCanvas (gtk.DrawingArea) win - the gtk.Window @@ -688,9 +828,9 @@ def set_cursor(self, cursor): self.window.configure(cursor=cursord[cursor]) - def _Button(self, text, file, command): - file = os.path.join(rcParams['datapath'], 'images', file) - im = Tk.PhotoImage(master=self, file=file) + def _Button(self, text, file, command, extension='.ppm'): + img_file = os.path.join(rcParams['datapath'], 'images', file + extension) + im = Tk.PhotoImage(master=self, file=img_file) b = Tk.Button( master=self, text=text, padx=2, pady=2, image=im, command=command) b._ntimage = im @@ -706,27 +846,16 @@ self.update() # Make axes menu - self.bHome = self._Button( text="Home", file="home.ppm", - command=self.home) + for text, tooltip_text, image_file, callback in self.toolitems: + if text is None: + # spacer, unhandled in Tk + pass + else: + button = self._Button(text=text, file=image_file, + command=getattr(self, callback)) + if tooltip_text is not None: + ToolTip.createToolTip(button, tooltip_text) - self.bBack = self._Button( text="Back", file="back.ppm", - command = self.back) - - self.bForward = self._Button(text="Forward", file="forward.ppm", - command = self.forward) - - self.bPan = self._Button( text="Pan", file="move.ppm", - command = self.pan) - - self.bZoom = self._Button( text="Zoom", - file="zoom_to_rect.ppm", - command = self.zoom) - - self.bsubplot = self._Button( text="Configure Subplots", file="subplots.ppm", - command = self.configure_subplots) - - self.bsave = self._Button( text="Save", file="filesave.ppm", - command = self.save_figure) self.message = Tk.StringVar(master=self) self._message_label = Tk.Label(master=self, textvariable=self.message) self._message_label.pack(side=Tk.RIGHT) @@ -770,7 +899,8 @@ master=self.window, title='Save the figure', filetypes = tk_filetypes, - defaultextension = defaultextension + defaultextension = defaultextension, + initialfile=self.canvas.get_default_filename(), ) if fname == "" or fname == (): @@ -779,7 +909,7 @@ try: # This method will handle the delegation to the correct type self.canvas.print_figure(fname) - except Exception, e: + except Exception as e: showerror("Error saving file", str(e)) def set_active(self, ind): @@ -804,3 +934,54 @@ FigureManager = FigureManagerTkAgg + + +class ToolTip(object): + """ + Tooltip recipe from + http://www.voidspace.org.uk/python/weblog/arch_d7_2006_07_01.shtml#e387 + """ + @staticmethod + def createToolTip(widget, text): + toolTip = ToolTip(widget) + def enter(event): + toolTip.showtip(text) + def leave(event): + toolTip.hidetip() + widget.bind('', enter) + widget.bind('', leave) + + def __init__(self, widget): + self.widget = widget + self.tipwindow = None + self.id = None + self.x = self.y = 0 + + def showtip(self, text): + "Display text in tooltip window" + self.text = text + if self.tipwindow or not self.text: + return + x, y, _, _ = self.widget.bbox("insert") + x = x + self.widget.winfo_rootx() + 27 + y = y + self.widget.winfo_rooty() + self.tipwindow = tw = Tk.Toplevel(self.widget) + tw.wm_overrideredirect(1) + tw.wm_geometry("+%d+%d" % (x, y)) + try: + # For Mac OS + tw.tk.call("::tk::unsupported::MacWindowStyle", + "style", tw._w, + "help", "noActivates") + except Tk.TclError: + pass + label = Tk.Label(tw, text=self.text, justify=Tk.LEFT, + background="#ffffe0", relief=Tk.SOLID, borderwidth=1, + ) + label.pack(ipadx=1) + + def hidetip(self): + tw = self.tipwindow + self.tipwindow = None + if tw: + tw.destroy() diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_wx.py matplotlib-1.2.0/lib/matplotlib/backends/backend_wx.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_wx.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_wx.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,8 +1,5 @@ -from __future__ import division +from __future__ import division, print_function """ - - backend_wx.py - A wxPython backend for matplotlib, based (very heavily) on backend_template.py and backend_gtk.py @@ -18,14 +15,17 @@ """ -cvs_id = '$Id$' +import sys +import os +import os.path +import math +import StringIO +import weakref +import warnings - -import sys, os, os.path, math, StringIO, weakref, warnings import numpy as np - # Debugging settings here... # Debug level set here. If the debug level is less than 5, information # messages (progressively more info for lower value) are printed. In addition, @@ -36,6 +36,11 @@ import traceback, pdb _DEBUG_lvls = {1 : 'Low ', 2 : 'Med ', 3 : 'High', 4 : 'Error' } +if sys.version_info[0] >= 3: + warnings.warn( + "The wx and wxagg backends have not been tested with Python 3.x", + ImportWarning) + missingwx = "Matplotlib backend_wx and backend_wxagg require wxPython >=2.8" missingwxversion = ("Matplotlib backend_wx and backend_wxagg " "require wxversion, which was not found.") @@ -71,7 +76,7 @@ # there really *is* a problem with the version. major, minor = [int(n) for n in backend_version.split('.')[:2]] if major < 2 or (major < 3 and minor < 8): - print " wxPython version %s was imported." % backend_version + print(" wxPython version %s was imported." % backend_version) raise ImportError(missingwx) @@ -85,12 +90,12 @@ # one below does. I think WX is redefining stderr, damned # beast #print >>sys.stderr, "%s- %s in %s" % (_DEBUG_lvls[lvl], string, cls) - print "%s- %s in %s" % (_DEBUG_lvls[lvl], string, cls) + print("%s- %s in %s" % (_DEBUG_lvls[lvl], string, cls)) def debug_on_error(type, value, tb): """Code due to Thomas Heller - published in Python Cookbook (O'Reilley)""" traceback.print_exc(type, value, tb) - print + print() pdb.pm() # jdh uncomment class fake_stderr: @@ -98,7 +103,7 @@ is probably no console. This redirects stderr to the console, since we know that there is one!""" def write(self, msg): - print "Stderr: %s\n\r" % msg + print("Stderr: %s\n\r" % msg) #if _DEBUG < 5: # sys.excepthook = debug_on_error @@ -183,7 +188,6 @@ # Unbinding causes Wx to stop for some reason. Disabling for now. # def __del__(self): -# import wx # TimerBase.__del__(self) # self.parent.Bind(wx.EVT_TIMER, None, self._timer) @@ -405,7 +409,6 @@ assert self.gc != None, "gc must be defined" return self.gc - def get_wx_font(self, s, prop): """ Return a wx font. Cache instances in a font dictionary for @@ -443,7 +446,6 @@ return font - def points_to_pixels(self, points): """ convert point measures to pixes using dpi and the pixels per @@ -451,6 +453,7 @@ """ return points*(PIXELS_PER_INCH/72.0*self.dpi/72.0) + class GraphicsContextWx(GraphicsContextBase): """ The graphics context provides the color, line styles, etc... @@ -622,6 +625,7 @@ a *= 255 return wx.Colour(red=int(r), green=int(g), blue=int(b), alpha=int(a)) + class FigureCanvasWx(FigureCanvasBase, wx.Panel): """ The FigureCanvas contains the figure and does event handling. @@ -741,11 +745,11 @@ bind(self, wx.EVT_KEY_DOWN, self._onKeyDown) bind(self, wx.EVT_KEY_UP, self._onKeyUp) bind(self, wx.EVT_RIGHT_DOWN, self._onRightButtonDown) - bind(self, wx.EVT_RIGHT_DCLICK, self._onRightButtonDown) + bind(self, wx.EVT_RIGHT_DCLICK, self._onRightButtonDClick) bind(self, wx.EVT_RIGHT_UP, self._onRightButtonUp) bind(self, wx.EVT_MOUSEWHEEL, self._onMouseWheel) bind(self, wx.EVT_LEFT_DOWN, self._onLeftButtonDown) - bind(self, wx.EVT_LEFT_DCLICK, self._onLeftButtonDown) + bind(self, wx.EVT_LEFT_DCLICK, self._onLeftButtonDClick) bind(self, wx.EVT_LEFT_UP, self._onLeftButtonUp) bind(self, wx.EVT_MOTION, self._onMotion) bind(self, wx.EVT_LEAVE_WINDOW, self._onLeave) @@ -753,7 +757,7 @@ bind(self, wx.EVT_IDLE, self._onIdle) #Add middle button events bind(self, wx.EVT_MIDDLE_DOWN, self._onMiddleButtonDown) - bind(self, wx.EVT_MIDDLE_DCLICK, self._onMiddleButtonDown) + bind(self, wx.EVT_MIDDLE_DCLICK, self._onMiddleButtonDClick) bind(self, wx.EVT_MIDDLE_UP, self._onMiddleButtonUp) self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) @@ -774,10 +778,13 @@ "copy bitmap of canvas to system clipboard" bmp_obj = wx.BitmapDataObject() bmp_obj.SetBitmap(self.bitmap) - wx.TheClipboard.Open() - wx.TheClipboard.SetData(bmp_obj) - wx.TheClipboard.Close() - wx.TheClipboard.Flush() + + if not wx.TheClipboard.IsOpened(): + open_success = wx.TheClipboard.Open() + if open_success: + wx.TheClipboard.SetData(bmp_obj) + wx.TheClipboard.Close() + wx.TheClipboard.Flush() def Printer_Init(self): """ @@ -920,7 +927,7 @@ po2 = PrintoutWx(self, width=self.printer_width, margin=self.printer_margin) self.preview = wx.PrintPreview(po1,po2,self.printerData) - if not self.preview.Ok(): print "error with preview" + if not self.preview.Ok(): print("error with preview") self.preview.SetZoom(50) frameInst= self @@ -1182,9 +1189,6 @@ self.draw() self.Refresh() - def get_default_filetype(self): - return 'png' - def _onPaint(self, evt): """ Called when wxPaintEvt is generated @@ -1237,13 +1241,20 @@ keyval = evt.m_keyCode if keyval in self.keyvald: key = self.keyvald[keyval] - elif keyval <256: + elif keyval < 256: key = chr(keyval) + # wx always returns an uppercase, so make it lowercase if the shift + # key is not depressed (NOTE: this will not handle Caps Lock) + if not evt.ShiftDown(): + key = key.lower() else: key = None - # why is wx upcasing this? - if key is not None: key = key.lower() + for meth, prefix in ( + [evt.AltDown, 'alt'], + [evt.ControlDown, 'ctrl'], ): + if meth(): + key = '{}+{}'.format(prefix, key) return key @@ -1273,6 +1284,13 @@ self.CaptureMouse() FigureCanvasBase.button_press_event(self, x, y, 3, guiEvent=evt) + def _onRightButtonDClick(self, evt): + """Start measuring on an axis.""" + x = evt.GetX() + y = self.figure.bbox.height - evt.GetY() + evt.Skip() + self.CaptureMouse() + FigureCanvasBase.button_press_event(self, x, y, 3, dblclick=True,guiEvent=evt) def _onRightButtonUp(self, evt): """End measuring on an axis.""" @@ -1290,6 +1308,14 @@ self.CaptureMouse() FigureCanvasBase.button_press_event(self, x, y, 1, guiEvent=evt) + def _onLeftButtonDClick(self, evt): + """Start measuring on an axis.""" + x = evt.GetX() + y = self.figure.bbox.height - evt.GetY() + evt.Skip() + self.CaptureMouse() + FigureCanvasBase.button_press_event(self, x, y, 1, dblclick=True, guiEvent=evt) + def _onLeftButtonUp(self, evt): """End measuring on an axis.""" x = evt.GetX() @@ -1308,6 +1334,14 @@ self.CaptureMouse() FigureCanvasBase.button_press_event(self, x, y, 2, guiEvent=evt) + def _onMiddleButtonDClick(self, evt): + """Start measuring on an axis.""" + x = evt.GetX() + y = self.figure.bbox.height - evt.GetY() + evt.Skip() + self.CaptureMouse() + FigureCanvasBase.button_press_event(self, x, y, 2, dblclick=True, guiEvent=evt) + def _onMiddleButtonUp(self, evt): """End measuring on an axis.""" x = evt.GetX() @@ -1422,6 +1456,14 @@ FigureClass = kwargs.pop('FigureClass', Figure) fig = FigureClass(*args, **kwargs) + return new_figure_manager_given_figure(num, fig) + + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + fig = figure frame = FigureFrameWx(num, fig) figmgr = frame.get_figure_manager() if matplotlib.is_interactive(): @@ -1429,6 +1471,7 @@ return figmgr + class FigureFrameWx(wx.Frame): def __init__(self, num, fig): # On non-Windows platform, explicitly set the position - fix @@ -1448,6 +1491,7 @@ self.SetStatusBar(statbar) self.canvas = self.get_canvas(fig) self.canvas.SetInitialSize(wx.Size(fig.bbox.width, fig.bbox.height)) + self.canvas.SetFocus() self.sizer =wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.canvas, 1, wx.TOP | wx.LEFT | wx.EXPAND) # By adding toolbar in sizer, we are able to put it at the bottom @@ -1477,14 +1521,23 @@ self.canvas.SetMinSize((2, 2)) + # give the window a matplotlib icon rather than the stock one. + # This is not currently working on Linux and is untested elsewhere. + #icon_path = os.path.join(matplotlib.rcParams['datapath'], + # 'images', 'matplotlib.png') + #icon = wx.IconFromBitmap(wx.Bitmap(icon_path)) + # for xpm type icons try: + #icon = wx.Icon(icon_path, wx.BITMAP_TYPE_XPM) + #self.SetIcon(icon) + self.figmgr = FigureManagerWx(self.canvas, num, self) bind(self, wx.EVT_CLOSE, self._onClose) def _get_toolbar(self, statbar): - if matplotlib.rcParams['toolbar']=='classic': + if rcParams['toolbar']=='classic': toolbar = NavigationToolbarWx(self.canvas, True) - elif matplotlib.rcParams['toolbar']=='toolbar2': + elif rcParams['toolbar']=='toolbar2': toolbar = NavigationToolbar2Wx(self.canvas) toolbar.set_status_bar(statbar) else: @@ -1523,6 +1576,7 @@ wxapp.Yield() return True + class FigureManagerWx(FigureManagerBase): """ This class contains the FigureCanvas and GUI frame @@ -1530,8 +1584,6 @@ It is instantiated by GcfWx whenever a new figure is created. GcfWx is responsible for managing multiple instances of FigureManagerWx. - NB: FigureManagerBase is found in _pylab_helpers - public attrs canvas - a FigureCanvasWx(wx.Panel) instance @@ -1550,12 +1602,6 @@ if self.tb != None: self.tb.update() self.canvas.figure.add_axobserver(notify_axes_change) - def showfig(*args): - frame.Show() - - # attach a show method to the figure - self.canvas.figure.show = showfig - def show(self): self.frame.Show() @@ -1563,10 +1609,12 @@ DEBUG_MSG("destroy()", 1, self) self.frame.Destroy() #if self.tb is not None: self.tb.Destroy() - import wx #wx.GetApp().ProcessIdle() wx.WakeUpIdle() + def get_window_title(self): + return self.window.GetTitle() + def set_window_title(self, title): self.window.SetTitle(title) @@ -1714,8 +1762,6 @@ self.SetLabel("Axes: %s" % axis_txt[:-1]) - - cursord = { cursors.MOVE : wx.CURSOR_HAND, cursors.HAND : wx.CURSOR_HAND, @@ -1759,57 +1805,33 @@ DEBUG_MSG("_init_toolbar", 1, self) self._parent = self.canvas.GetParent() - _NTB2_HOME =wx.NewId() - self._NTB2_BACK =wx.NewId() - self._NTB2_FORWARD =wx.NewId() - self._NTB2_PAN =wx.NewId() - self._NTB2_ZOOM =wx.NewId() - _NTB2_SAVE = wx.NewId() - _NTB2_SUBPLOT =wx.NewId() - - self.SetToolBitmapSize(wx.Size(24,24)) - - self.AddSimpleTool(_NTB2_HOME, _load_bitmap('home.png'), - 'Home', 'Reset original view') - self.AddSimpleTool(self._NTB2_BACK, _load_bitmap('back.png'), - 'Back', 'Back navigation view') - self.AddSimpleTool(self._NTB2_FORWARD, _load_bitmap('forward.png'), - 'Forward', 'Forward navigation view') - # todo: get new bitmap - self.AddCheckTool(self._NTB2_PAN, _load_bitmap('move.png'), - shortHelp='Pan', - longHelp='Pan with left, zoom with right') - self.AddCheckTool(self._NTB2_ZOOM, _load_bitmap('zoom_to_rect.png'), - shortHelp='Zoom', longHelp='Zoom to rectangle') - self.AddSeparator() - self.AddSimpleTool(_NTB2_SUBPLOT, _load_bitmap('subplots.png'), - 'Configure subplots', 'Configure subplot parameters') - - self.AddSimpleTool(_NTB2_SAVE, _load_bitmap('filesave.png'), - 'Save', 'Save plot contents to file') - bind(self, wx.EVT_TOOL, self.home, id=_NTB2_HOME) - bind(self, wx.EVT_TOOL, self.forward, id=self._NTB2_FORWARD) - bind(self, wx.EVT_TOOL, self.back, id=self._NTB2_BACK) - bind(self, wx.EVT_TOOL, self.zoom, id=self._NTB2_ZOOM) - bind(self, wx.EVT_TOOL, self.pan, id=self._NTB2_PAN) - bind(self, wx.EVT_TOOL, self.configure_subplot, id=_NTB2_SUBPLOT) - bind(self, wx.EVT_TOOL, self.save, id=_NTB2_SAVE) + self.wx_ids = {} + for text, tooltip_text, image_file, callback in self.toolitems: + if text is None: + self.AddSeparator() + continue + self.wx_ids[text] = wx.NewId() + if text in ['Pan', 'Zoom']: + self.AddCheckTool(self.wx_ids[text], _load_bitmap(image_file + '.png'), + shortHelp=text, longHelp=tooltip_text) + else: + self.AddSimpleTool(self.wx_ids[text], _load_bitmap(image_file + '.png'), + text, tooltip_text) + bind(self, wx.EVT_TOOL, getattr(self, callback), id=self.wx_ids[text]) self.Realize() - def zoom(self, *args): - self.ToggleTool(self._NTB2_PAN, False) + self.ToggleTool(self.wx_ids['Pan'], False) NavigationToolbar2.zoom(self, *args) def pan(self, *args): - self.ToggleTool(self._NTB2_ZOOM, False) + self.ToggleTool(self.wx_ids['Zoom'], False) NavigationToolbar2.pan(self, *args) - - def configure_subplot(self, evt): + def configure_subplots(self, evt): frame = wx.Frame(None, -1, "Configure subplots") toolfig = Figure((6,3)) @@ -1827,10 +1849,10 @@ tool = SubplotTool(self.canvas.figure, toolfig) frame.Show() - def save(self, evt): + def save_figure(self, *args): # Fetch the required filename and file type. filetypes, exts, filter_index = self.canvas._get_imagesave_wildcards() - default_file = "image." + self.canvas.get_default_filetype() + default_file = self.canvas.get_default_filename() dlg = wx.FileDialog(self._parent, "Save to file", "", default_file, filetypes, wx.SAVE|wx.OVERWRITE_PROMPT) @@ -1851,7 +1873,7 @@ try: self.canvas.print_figure( os.path.join(dirname, filename), format=format) - except Exception, e: + except Exception as e: error_msg_wx(str(e)) def set_cursor(self, cursor): @@ -1920,17 +1942,12 @@ def set_history_buttons(self): can_backward = (self._views._pos > 0) can_forward = (self._views._pos < len(self._views._elements) - 1) - self.EnableTool(self._NTB2_BACK, can_backward) - self.EnableTool(self._NTB2_FORWARD, can_forward) + self.EnableTool(self.wx_ids['Back'], can_backward) + self.EnableTool(self.wx_ids['Forward'], can_forward) class NavigationToolbarWx(wx.ToolBar): def __init__(self, canvas, can_kill=False): - """ - figure is the Figure instance that the toolboar controls - - win, if not None, is the wxWindow the Figure is embedded in - """ wx.ToolBar.__init__(self, canvas.GetParent(), -1) DEBUG_MSG("__init__()", 1, self) self.canvas = canvas @@ -2121,13 +2138,12 @@ direction = -1 self.button_fn(direction) - _onSave = NavigationToolbar2Wx.save + _onSave = NavigationToolbar2Wx.save_figure def _onClose(self, evt): self.GetParent().Destroy() - class StatusBarWx(wx.StatusBar): """ A status bar is added to _FigureFrame to allow measurements and the diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/backend_wxagg.py matplotlib-1.2.0/lib/matplotlib/backends/backend_wxagg.py --- matplotlib-1.1.1/lib/matplotlib/backends/backend_wxagg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/backend_wxagg.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,3 @@ -from __future__ import division """ backend_wxagg.py @@ -16,6 +15,7 @@ """ +from __future__ import division, print_function import matplotlib from matplotlib.figure import Figure @@ -121,14 +121,20 @@ FigureClass = kwargs.pop('FigureClass', Figure) fig = FigureClass(*args, **kwargs) - frame = FigureFrameWxAgg(num, fig) + + return new_figure_manager_given_figure(num, fig) + +def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + frame = FigureFrameWxAgg(num, figure) figmgr = frame.get_figure_manager() if matplotlib.is_interactive(): figmgr.frame.Show() return figmgr - # # agg/wxPython image conversion functions (wxPython >= 2.8) # @@ -160,7 +166,7 @@ if bbox is None: # agg => rgba buffer -> bitmap return wx.BitmapFromBufferRGBA(int(agg.width), int(agg.height), - agg.buffer_rgba(0, 0)) + agg.buffer_rgba()) else: # agg => rgba buffer -> bitmap => clipped bitmap return _WX28_clipped_agg_as_bitmap(agg, bbox) @@ -177,7 +183,7 @@ t = b + height srcBmp = wx.BitmapFromBufferRGBA(int(agg.width), int(agg.height), - agg.buffer_rgba(0, 0)) + agg.buffer_rgba()) srcDC = wx.MemoryDC() srcDC.SelectObject(srcBmp) diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/qt4_editor/__init__.py matplotlib-1.2.0/lib/matplotlib/backends/qt4_editor/__init__.py --- matplotlib-1.1.1/lib/matplotlib/backends/qt4_editor/__init__.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/qt4_editor/__init__.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1 @@ +from __future__ import print_function diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/qt4_editor/figureoptions.py matplotlib-1.2.0/lib/matplotlib/backends/qt4_editor/figureoptions.py --- matplotlib-1.1.1/lib/matplotlib/backends/qt4_editor/figureoptions.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/qt4_editor/figureoptions.py 2012-10-31 00:11:13.000000000 +0000 @@ -4,8 +4,10 @@ # Licensed under the terms of the MIT License # see the mpl licenses directory for a copy of the license + """Module that provides a GUI-based editor for matplotlib's figure options""" +from __future__ import print_function import os.path as osp import matplotlib.backends.qt4_editor.formlayout as formlayout diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/qt4_editor/formlayout.py matplotlib-1.2.0/lib/matplotlib/backends/qt4_editor/formlayout.py --- matplotlib-1.1.1/lib/matplotlib/backends/qt4_editor/formlayout.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/qt4_editor/formlayout.py 2012-10-31 00:11:13.000000000 +0000 @@ -33,6 +33,8 @@ OTHER DEALINGS IN THE SOFTWARE. """ +from __future__ import print_function + # History: # 1.0.10: added float validator (disable "Ok" and "Apply" button when not valid) # 1.0.7: added support for "Apply" button @@ -237,11 +239,11 @@ self.formlayout.addRow(QLabel(comment)) self.formlayout.addRow(QLabel(" ")) if DEBUG: - print "\n"+("*"*80) - print "DATA:", self.data - print "*"*80 - print "COMMENT:", comment - print "*"*80 + print("\n"+("*"*80)) + print("DATA:", self.data) + print("*"*80) + print("COMMENT:", comment) + print("*"*80) def get_dialog(self): """Return FormDialog instance""" @@ -253,7 +255,7 @@ def setup(self): for label, value in self.data: if DEBUG: - print "value:", value + print("value:", value) if label is None and value is None: # Separator: (None, None) self.formlayout.addRow(QLabel(" "), QLabel(" ")) @@ -286,13 +288,13 @@ elif selindex in keys: selindex = keys.index(selindex) elif not isinstance(selindex, int): - print >>STDERR, "Warning: '%s' index is invalid (label: " \ - "%s, value: %s)" % (selindex, label, value) + print("Warning: '%s' index is invalid (label: " \ + "%s, value: %s)" % (selindex, label, value), file=STDERR) selindex = 0 field.setCurrentIndex(selindex) elif isinstance(value, bool): field = QCheckBox(self) - if value : + if value: field.setCheckState(Qt.Checked) else : field.setCheckState(Qt.Unchecked) @@ -509,7 +511,6 @@ # (e.g. if the module is used directly from the interpreter) if QApplication.startingUp(): _app = QApplication([]) - dialog = FormDialog(data, title, comment, icon, parent, apply) if dialog.exec_(): return dialog.get() @@ -543,19 +544,19 @@ #--------- datalist example datalist = create_datalist_example() def apply_test(data): - print "data:", data - print "result:", fedit(datalist, title="Example", + print("data:", data) + print("result:", fedit(datalist, title="Example", comment="This is just an example.", - apply=apply_test) + apply=apply_test)) #--------- datagroup example datagroup = create_datagroup_example() - print "result:", fedit(datagroup, "Global title") + print("result:", fedit(datagroup, "Global title")) #--------- datagroup inside a datagroup example datalist = create_datalist_example() datagroup = create_datagroup_example() - print "result:", fedit(((datagroup, "Title 1", "Tab 1 comment"), + print("result:", fedit(((datagroup, "Title 1", "Tab 1 comment"), (datalist, "Title 2", "Tab 2 comment"), (datalist, "Title 3", "Tab 3 comment")), - "Global title") + "Global title")) diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/tkagg.py matplotlib-1.2.0/lib/matplotlib/backends/tkagg.py --- matplotlib-1.1.1/lib/matplotlib/backends/tkagg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/tkagg.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,5 @@ -import _tkagg +from __future__ import print_function +from matplotlib.backends import _tkagg import Tkinter as Tk def blit(photoimage, aggimage, bbox=None, colormode=1): @@ -10,7 +11,7 @@ bbox_array = None try: tk.call("PyAggImagePhoto", photoimage, id(aggimage), colormode, id(bbox_array)) - except Tk.TclError, v: + except Tk.TclError: try: try: _tkagg.tkinit(tk.interpaddr(), 1) diff -Nru matplotlib-1.1.1/lib/matplotlib/backends/windowing.py matplotlib-1.2.0/lib/matplotlib/backends/windowing.py --- matplotlib-1.1.1/lib/matplotlib/backends/windowing.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/backends/windowing.py 2012-10-31 00:11:13.000000000 +0000 @@ -6,6 +6,7 @@ It uses a tiny C++ extension module to access MS Win functions. """ +from __future__ import print_function from matplotlib import rcParams try: diff -Nru matplotlib-1.1.1/lib/matplotlib/bezier.py matplotlib-1.2.0/lib/matplotlib/bezier.py --- matplotlib-1.1.1/lib/matplotlib/bezier.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/bezier.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,10 +2,8 @@ A module providing some utility functions regarding bezier path manipulation. """ - +from __future__ import print_function import numpy as np -from math import sqrt - from matplotlib.path import Path from operator import xor @@ -17,6 +15,7 @@ # some functions + def get_intersection(cx1, cy1, cos_t1, sin_t1, cx2, cy2, cos_t2, sin_t2): """ return a intersecting point between a line through (cx1, cy1) @@ -33,7 +32,7 @@ a, b = sin_t1, -cos_t1 c, d = sin_t2, -cos_t2 - ad_bc = a*d-b*c + ad_bc = a * d - b * c if ad_bc == 0.: raise ValueError("Given lines do not intersect") @@ -42,17 +41,17 @@ c_, d_ = -c, a a_, b_, c_, d_ = [k / ad_bc for k in [a_, b_, c_, d_]] - x = a_* line1_rhs + b_ * line2_rhs - y = c_* line1_rhs + d_ * line2_rhs + x = a_ * line1_rhs + b_ * line2_rhs + y = c_ * line1_rhs + d_ * line2_rhs return x, y - def get_normal_points(cx, cy, cos_t, sin_t, length): """ - For a line passing through (*cx*, *cy*) and having a angle *t*, - return locations of the two points located along its perpendicular line at the distance of *length*. + For a line passing through (*cx*, *cy*) and having a angle *t*, return + locations of the two points located along its perpendicular line at the + distance of *length*. """ if length == 0.: @@ -61,27 +60,23 @@ cos_t1, sin_t1 = sin_t, -cos_t cos_t2, sin_t2 = -sin_t, cos_t - x1, y1 = length*cos_t1 + cx, length*sin_t1 + cy - x2, y2 = length*cos_t2 + cx, length*sin_t2 + cy + x1, y1 = length * cos_t1 + cx, length * sin_t1 + cy + x2, y2 = length * cos_t2 + cx, length * sin_t2 + cy return x1, y1, x2, y2 - - ## BEZIER routines - - - - # subdividing bezier curve # http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/bezier-sub.html + def _de_casteljau1(beta, t): - next_beta = beta[:-1] * (1-t) + beta[1:] * t + next_beta = beta[:-1] * (1 - t) + beta[1:] * t return next_beta + def split_de_casteljau(beta, t): """split a bezier segment defined by its controlpoints *beta* into two separate segment divided at *t* and return their control points. @@ -100,12 +95,9 @@ return left_beta, right_beta - - - - - -def find_bezier_t_intersecting_with_closedpath(bezier_point_at_t, inside_closedpath, +# FIXME spelling mistake in the name of the parameter ``tolerence`` +def find_bezier_t_intersecting_with_closedpath(bezier_point_at_t, + inside_closedpath, t0=0., t1=1., tolerence=0.01): """ Find a parameter t0 and t1 of the given bezier path which bounds the intersecting points with a provided closed @@ -129,16 +121,18 @@ end_inside = inside_closedpath(end) if not xor(start_inside, end_inside): - raise NonIntersectingPathException("the segment does not seemed to intersect with the path") + raise NonIntersectingPathException( + "the segment does not seem to intersect with the path") while 1: # return if the distance is smaller than the tolerence - if (start[0]-end[0])**2 + (start[1]-end[1])**2 < tolerence**2: + if (start[0] - end[0]) ** 2 + \ + (start[1] - end[1]) ** 2 < tolerence ** 2: return t0, t1 # calculate the middle point - middle_t = 0.5*(t0+t1) + middle_t = 0.5 * (t0 + t1) middle = bezier_point_at_t(middle_t) middle_inside = inside_closedpath(middle) @@ -152,19 +146,16 @@ start_inside = middle_inside - - - -class BezierSegment: +class BezierSegment(object): """ A simple class of a 2-dimensional bezier segment """ - # Highrt order bezier lines can be supported by simplying adding - # correcponding values. - _binom_coeff = {1:np.array([1., 1.]), - 2:np.array([1., 2., 1.]), - 3:np.array([1., 3., 3., 1.])} + # Higher order bezier lines can be supported by simplying adding + # corresponding values. + _binom_coeff = {1: np.array([1., 1.]), + 2: np.array([1., 2., 1.]), + 3: np.array([1., 3., 3., 1.])} def __init__(self, control_points): """ @@ -177,15 +168,15 @@ _coeff = BezierSegment._binom_coeff[_o - 1] _control_points = np.asarray(control_points) - xx = _control_points[:,0] - yy = _control_points[:,1] + xx = _control_points[:, 0] + yy = _control_points[:, 1] self._px = xx * _coeff self._py = yy * _coeff def point_at_t(self, t): "evaluate a point at t" - one_minus_t_powers = np.power(1.-t, self._orders)[::-1] + one_minus_t_powers = np.power(1. - t, self._orders)[::-1] t_powers = np.power(t, self._orders) tt = one_minus_t_powers * t_powers @@ -201,7 +192,8 @@ """ bezier : control points of the bezier segment - inside_closedpath : a function which returns true if the point is inside the path + inside_closedpath : a function which returns true if the point is inside + the path """ bz = BezierSegment(bezier) @@ -211,11 +203,10 @@ inside_closedpath, tolerence=tolerence) - _left, _right = split_de_casteljau(bezier, (t0+t1)/2.) + _left, _right = split_de_casteljau(bezier, (t0 + t1) / 2.) return _left, _right - def find_r_to_boundary_of_closedpath(inside_closedpath, xy, cos_t, sin_t, rmin=0., rmax=1., tolerence=0.01): @@ -230,16 +221,17 @@ """ cx, cy = xy + def _f(r): - return cos_t*r + cx, sin_t*r + cy + return cos_t * r + cx, sin_t * r + cy find_bezier_t_intersecting_with_closedpath(_f, inside_closedpath, - t0=rmin, t1=rmax, tolerence=tolerence) - - + t0=rmin, t1=rmax, + tolerence=tolerence) ## matplotlib specific + def split_path_inout(path, inside, tolerence=0.01, reorder_inout=False): """ divide a path into two segment at the point where inside(x, y) becomes False. @@ -247,20 +239,20 @@ path_iter = path.iter_segments() - ctl_points, command = path_iter.next() - begin_inside = inside(ctl_points[-2:]) # true if begin point is inside + ctl_points, command = next(path_iter) + begin_inside = inside(ctl_points[-2:]) # true if begin point is inside bezier_path = None ctl_points_old = ctl_points concat = np.concatenate - iold=0 + iold = 0 i = 1 for ctl_points, command in path_iter: - iold=i - i += len(ctl_points)/2 + iold = i + i += len(ctl_points) / 2 if inside(ctl_points[-2:]) != begin_inside: bezier_path = concat([ctl_points_old[-2:], ctl_points]) break @@ -308,24 +300,22 @@ return path_in, path_out - - - def inside_circle(cx, cy, r): - r2 = r**2 + r2 = r ** 2 + def _f(xy): x, y = xy - return (x-cx)**2 + (y-cy)**2 < r2 + return (x - cx) ** 2 + (y - cy) ** 2 < r2 return _f - # quadratic bezier lines def get_cos_sin(x0, y0, x1, y1): - dx, dy = x1-x0, y1-y0 - d = (dx*dx + dy*dy)**.5 - return dx/d, dy/d + dx, dy = x1 - x0, y1 - y0 + d = (dx * dx + dy * dy) ** .5 + return dx / d, dy / d + def check_if_parallel(dx1, dy1, dx2, dy2, tolerence=1.e-5): """ returns @@ -346,27 +336,31 @@ def get_parallels(bezier2, width): """ - Given the quadraitc bezier control points *bezier2*, returns - control points of quadrativ bezier lines roughly parralel to given + Given the quadratic bezier control points *bezier2*, returns + control points of quadratic bezier lines roughly parallel to given one separated by *width*. """ - # The parallel bezier lines constructed by following ways. - # c1 and c2 are contol points representing the begin and end of the bezier line. + # The parallel bezier lines are constructed by following ways. + # c1 and c2 are contol points representing the begin and end of the + # bezier line. # cm is the middle point + c1x, c1y = bezier2[0] cmx, cmy = bezier2[1] c2x, c2y = bezier2[2] - parallel_test = check_if_parallel(c1x-cmx, c1y-cmy, cmx-c2x, cmy-c2y) + parallel_test = check_if_parallel(c1x - cmx, c1y - cmy, + cmx - c2x, cmy - c2y) if parallel_test == -1: - warnings.warn("Lines do not intersect. A straight line is used instead.") + warnings.warn( + "Lines do not intersect. A straight line is used instead.") #cmx, cmy = 0.5*(c1x+c2x), 0.5*(c1y+c2y) cos_t1, sin_t1 = get_cos_sin(c1x, c1y, c2x, c2y) cos_t2, sin_t2 = cos_t1, sin_t1 else: - # t1 and t2 is the anlge between c1 and cm, cm, c2. They are + # t1 and t2 is the angle between c1 and cm, cm, c2. They are # also a angle of the tangential line of the path at c1 and c2 cos_t1, sin_t1 = get_cos_sin(c1x, c1y, cmx, cmy) cos_t2, sin_t2 = get_cos_sin(cmx, cmy, c2x, c2y) @@ -387,9 +381,9 @@ # a special case for a straight line, i.e., angle between two # lines are smaller than some (arbitrtay) value. cmx_left, cmy_left = \ - 0.5*(c1x_left+c2x_left), 0.5*(c1y_left+c2y_left) + 0.5 * (c1x_left + c2x_left), 0.5 * (c1y_left + c2y_left) cmx_right, cmy_right = \ - 0.5*(c1x_right+c2x_right), 0.5*(c1y_right+c2y_right) + 0.5 * (c1x_right + c2x_right), 0.5 * (c1y_right + c2y_right) else: cmx_left, cmy_left = \ get_intersection(c1x_left, c1y_left, cos_t1, sin_t1, @@ -401,62 +395,32 @@ # the parralel bezier lines are created with control points of # [c1_left, cm_left, c2_left] and [c1_right, cm_right, c2_right] - path_left = [(c1x_left, c1y_left), (cmx_left, cmy_left), (c2x_left, c2y_left)] - path_right = [(c1x_right, c1y_right), (cmx_right, cmy_right), (c2x_right, c2y_right)] + path_left = [(c1x_left, c1y_left), + (cmx_left, cmy_left), + (c2x_left, c2y_left)] + path_right = [(c1x_right, c1y_right), + (cmx_right, cmy_right), + (c2x_right, c2y_right)] return path_left, path_right - -def make_wedged_bezier2(bezier2, length, shrink_factor=0.5): - """ - Being similar to get_parallels, returns - control points of two quadrativ bezier lines having a width roughly parralel to given - one separated by *width*. - """ - - xx1, yy1 = bezier2[2] - xx2, yy2 = bezier2[1] - xx3, yy3 = bezier2[0] - - cx, cy = xx3, yy3 - x0, y0 = xx2, yy2 - - dist = sqrt((x0-cx)**2 + (y0-cy)**2) - cos_t, sin_t = (x0-cx)/dist, (y0-cy)/dist, - - x1, y1, x2, y2 = get_normal_points(cx, cy, cos_t, sin_t, length) - - xx12, yy12 = (xx1+xx2)/2., (yy1+yy2)/2., - xx23, yy23 = (xx2+xx3)/2., (yy2+yy3)/2., - - dist = sqrt((xx12-xx23)**2 + (yy12-yy23)**2) - cos_t, sin_t = (xx12-xx23)/dist, (yy12-yy23)/dist, - - xm1, ym1, xm2, ym2 = get_normal_points(xx2, yy2, cos_t, sin_t, length*shrink_factor) - - l_plus = [(x1, y1), (xm1, ym1), (xx1, yy1)] - l_minus = [(x2, y2), (xm2, ym2), (xx1, yy1)] - - return l_plus, l_minus - - def find_control_points(c1x, c1y, mmx, mmy, c2x, c2y): """ Find control points of the bezier line throught c1, mm, c2. We - simply assume that c1, mm, c2 which have parameteric value 0, 0.5, and 1. + simply assume that c1, mm, c2 which have parametric value 0, 0.5, and 1. """ - cmx = .5 * (4*mmx - (c1x + c2x)) - cmy = .5 * (4*mmy - (c1y + c2y)) + cmx = .5 * (4 * mmx - (c1x + c2x)) + cmy = .5 * (4 * mmy - (c1y + c2y)) return [(c1x, c1y), (cmx, cmy), (c2x, c2y)] def make_wedged_bezier2(bezier2, width, w1=1., wm=0.5, w2=0.): """ - Being similar to get_parallels, returns - control points of two quadrativ bezier lines having a width roughly parralel to given - one separated by *width*. + Being similar to get_parallels, returns control points of two quadrativ + bezier lines having a width roughly parralel to given one separated by + *width*. """ # c1, cm, c2 @@ -464,7 +428,6 @@ cmx, cmy = bezier2[1] c3x, c3y = bezier2[2] - # t1 and t2 is the anlge between c1 and cm, cm, c3. # They are also a angle of the tangential line of the path at c1 and c3 cos_t1, sin_t1 = get_cos_sin(c1x, c1y, cmx, cmy) @@ -475,24 +438,21 @@ # bezier path at a distance of width. Same thing for c3_left and # c3_right with respect to c3. c1x_left, c1y_left, c1x_right, c1y_right = \ - get_normal_points(c1x, c1y, cos_t1, sin_t1, width*w1) + get_normal_points(c1x, c1y, cos_t1, sin_t1, width * w1) c3x_left, c3y_left, c3x_right, c3y_right = \ - get_normal_points(c3x, c3y, cos_t2, sin_t2, width*w2) - - + get_normal_points(c3x, c3y, cos_t2, sin_t2, width * w2) - - # find c12, c23 and c123 which are middle points of c1-cm, cm-c3 and c12-c23 - c12x, c12y = (c1x+cmx)*.5, (c1y+cmy)*.5 - c23x, c23y = (cmx+c3x)*.5, (cmy+c3y)*.5 - c123x, c123y = (c12x+c23x)*.5, (c12y+c23y)*.5 + # find c12, c23 and c123 which are middle points of c1-cm, cm-c3 and + # c12-c23 + c12x, c12y = (c1x + cmx) * .5, (c1y + cmy) * .5 + c23x, c23y = (cmx + c3x) * .5, (cmy + c3y) * .5 + c123x, c123y = (c12x + c23x) * .5, (c12y + c23y) * .5 # tangential angle of c123 (angle between c12 and c23) cos_t123, sin_t123 = get_cos_sin(c12x, c12y, c23x, c23y) c123x_left, c123y_left, c123x_right, c123y_right = \ - get_normal_points(c123x, c123y, cos_t123, sin_t123, width*wm) - + get_normal_points(c123x, c123y, cos_t123, sin_t123, width * wm) path_left = find_control_points(c1x_left, c1y_left, c123x_left, c123y_left, @@ -504,8 +464,6 @@ return path_left, path_right - - def make_path_regular(p): """ fill in the codes if None. @@ -520,6 +478,7 @@ else: return p + def concatenate_paths(paths): """ concatenate list of paths into a single path. @@ -535,15 +494,3 @@ _path = Path(np.concatenate(vertices), np.concatenate(codes)) return _path - - - -if 0: - path = Path([(0, 0), (1, 0), (2, 2)], - [Path.MOVETO, Path.CURVE3, Path.CURVE3]) - left, right = divide_path_inout(path, inside) - clf() - ax = gca() - - - diff -Nru matplotlib-1.1.1/lib/matplotlib/blocking_input.py matplotlib-1.2.0/lib/matplotlib/blocking_input.py --- matplotlib-1.1.1/lib/matplotlib/blocking_input.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/blocking_input.py 2012-11-06 15:42:20.000000000 +0000 @@ -1,26 +1,33 @@ """ -This provides several classes used for blocking interaction with figure windows: +This provides several classes used for blocking interaction with figure +windows: :class:`BlockingInput` - creates a callable object to retrieve events in a blocking way for interactive sessions + creates a callable object to retrieve events in a blocking way for + interactive sessions :class:`BlockingKeyMouseInput` - creates a callable object to retrieve key or mouse clicks in a blocking way for interactive sessions. + creates a callable object to retrieve key or mouse clicks in a blocking + way for interactive sessions. Note: Subclass of BlockingInput. Used by waitforbuttonpress :class:`BlockingMouseInput` - creates a callable object to retrieve mouse clicks in a blocking way for interactive sessions. + creates a callable object to retrieve mouse clicks in a blocking way for + interactive sessions. Note: Subclass of BlockingInput. Used by ginput :class:`BlockingContourLabeler` - creates a callable object to retrieve mouse clicks in a blocking way that will then be used to place labels on a ContourSet + creates a callable object to retrieve mouse clicks in a blocking way that + will then be used to place labels on a ContourSet Note: Subclass of BlockingMouseInput. Used by clabel """ -from matplotlib import path, verbose +from __future__ import print_function +from matplotlib import verbose from matplotlib.cbook import is_sequence_of_strings import matplotlib.lines as mlines + class BlockingInput(object): """ Class that creates a callable object to retrieve events in a @@ -28,7 +35,8 @@ """ def __init__(self, fig, eventslist=()): self.fig = fig - assert is_sequence_of_strings(eventslist), "Requires a sequence of event name strings" + assert is_sequence_of_strings( + eventslist), "Requires a sequence of event name strings" self.eventslist = eventslist def on_event(self, event): @@ -59,13 +67,13 @@ for cb in self.callbacks: self.fig.canvas.mpl_disconnect(cb) - self.callbacks=[] + self.callbacks = [] - def add_event(self,event): + def add_event(self, event): """For base class, this just appends an event to events.""" self.events.append(event) - def pop_event(self,index=-1): + def pop_event(self, index=-1): """ This removes an event from the event list. Defaults to removing last event, but an index can be supplied. Note that @@ -75,11 +83,11 @@ """ self.events.pop(index) - def pop(self,index=-1): + def pop(self, index=-1): self.pop_event(index) - pop.__doc__=pop_event.__doc__ + pop.__doc__ = pop_event.__doc__ - def __call__(self, n=1, timeout=30 ): + def __call__(self, n=1, timeout=30): """ Blocking call to retrieve n events """ @@ -95,18 +103,20 @@ # connect the events to the on_event function call for n in self.eventslist: - self.callbacks.append( self.fig.canvas.mpl_connect(n, self.on_event) ) + self.callbacks.append( + self.fig.canvas.mpl_connect(n, self.on_event)) try: # Start event loop self.fig.canvas.start_event_loop(timeout=timeout) - finally: # Run even on exception like ctrl-c + finally: # Run even on exception like ctrl-c # Disconnect the callbacks self.cleanup() # Return the events in this case return self.events + class BlockingMouseInput(BlockingInput): """ Class that creates a callable object to retrieve mouse clicks in a @@ -117,25 +127,23 @@ enter is like mouse button 2 and all others are like mouse button 1). """ - button_add = 1 - button_pop = 3 - button_stop = 2 + button_add = 1 + button_pop = 3 + button_stop = 2 def __init__(self, fig, mouse_add=1, mouse_pop=3, mouse_stop=2): BlockingInput.__init__(self, fig=fig, eventslist=('button_press_event', - 'key_press_event') ) + 'key_press_event')) self.button_add = mouse_add self.button_pop = mouse_pop - self.button_stop= mouse_stop - - + self.button_stop = mouse_stop def post_event(self): """ This will be called to process events """ - assert len(self.events)>0, "No events yet" + assert len(self.events) > 0, "No events yet" if self.events[-1].name == 'key_press_event': self.key_event() @@ -170,29 +178,30 @@ if key in ['backspace', 'delete']: self.mouse_event_pop(event) - elif key in ['escape', 'enter']: # on windows XP and wxAgg, the enter key doesn't seem to register + elif key in ['escape', 'enter']: + # on windows XP and wxAgg, the enter key doesn't seem to register self.mouse_event_stop(event) else: self.mouse_event_add(event) - def mouse_event_add( self, event ): + def mouse_event_add(self, event): """ Will be called for any event involving a button other than button 2 or 3. This will add a click if it is inside axes. """ if event.inaxes: self.add_click(event) - else: # If not a valid click, remove from event list - BlockingInput.pop(self,-1) + else: # If not a valid click, remove from event list + BlockingInput.pop(self, -1) - def mouse_event_stop( self, event ): + def mouse_event_stop(self, event): """ Will be called for any event involving button 2. Button 2 ends blocking input. """ # Remove last event just for cleanliness - BlockingInput.pop(self,-1) + BlockingInput.pop(self, -1) # This will exit even if not in infinite mode. This is # consistent with MATLAB and sometimes quite useful, but will @@ -200,26 +209,26 @@ # returned before using data. self.fig.canvas.stop_event_loop() - def mouse_event_pop( self, event ): + def mouse_event_pop(self, event): """ Will be called for any event involving button 3. Button 3 removes the last click. """ # Remove this last event - BlockingInput.pop(self,-1) + BlockingInput.pop(self, -1) # Now remove any existing clicks if possible - if len(self.events)>0: - self.pop(event,-1) + if len(self.events) > 0: + self.pop(event, -1) - def add_click(self,event): + def add_click(self, event): """ This add the coordinates of an event to the list of clicks """ - self.clicks.append((event.xdata,event.ydata)) + self.clicks.append((event.xdata, event.ydata)) verbose.report("input %i: %f,%f" % - (len(self.clicks),event.xdata, event.ydata)) + (len(self.clicks), event.xdata, event.ydata)) # If desired plot up click if self.show_clicks: @@ -229,9 +238,7 @@ self.marks.append(line) self.fig.canvas.draw() - - - def pop_click(self,event,index=-1): + def pop_click(self, event, index=-1): """ This removes a click from the list of clicks. Defaults to removing the last click. @@ -248,17 +255,16 @@ # for the keyboard backspace event on windows XP wxAgg. # maybe event.inaxes here is a COPY of the actual axes? - - def pop(self,event,index=-1): + def pop(self, event, index=-1): """ This removes a click and the associated event from the object. Defaults to removing the last click, but any index can be supplied. """ - self.pop_click(event,index) - BlockingInput.pop(self,index) + self.pop_click(event, index) + BlockingInput.pop(self, index) - def cleanup(self,event=None): + def cleanup(self, event=None): # clean the figure if self.show_clicks: @@ -277,20 +283,21 @@ clicks. """ self.show_clicks = show_clicks - self.clicks = [] - self.marks = [] - BlockingInput.__call__(self,n=n,timeout=timeout) + self.clicks = [] + self.marks = [] + BlockingInput.__call__(self, n=n, timeout=timeout) return self.clicks -class BlockingContourLabeler( BlockingMouseInput ): + +class BlockingContourLabeler(BlockingMouseInput): """ Class that creates a callable object that uses mouse clicks or key clicks on a figure window to place contour labels. """ - def __init__(self,cs): + def __init__(self, cs): self.cs = cs - BlockingMouseInput.__init__(self, fig=cs.ax.figure ) + BlockingMouseInput.__init__(self, fig=cs.ax.figure) def add_click(self, event): self.button1(event) @@ -298,64 +305,22 @@ def pop_click(self, event, index=-1): self.button3(event) - def button1(self,event): + def button1(self, event): """ This will be called if an event involving a button other than 2 or 3 occcurs. This will add a label to a contour. """ # Shorthand - cs = self.cs - - if event.inaxes == cs.ax: - conmin,segmin,imin,xmin,ymin = cs.find_nearest_contour( - event.x, event.y, cs.labelIndiceList)[:5] - - # Get index of nearest level in subset of levels used for labeling - lmin = cs.labelIndiceList.index(conmin) - - # Coordinates of contour - paths = cs.collections[conmin].get_paths() - lc = paths[segmin].vertices - - # In pixel/screen space - slc = cs.ax.transData.transform(lc) - - # Get label width for rotating labels and breaking contours - lw = cs.get_label_width(cs.labelLevelList[lmin], - cs.labelFmt, cs.labelFontSizeList[lmin]) - - """ - # requires python 2.5 - # Figure out label rotation. - rotation,nlc = cs.calc_label_rot_and_inline( - slc, imin, lw, lc if self.inline else [], - self.inline_spacing ) - """ - # Figure out label rotation. - if self.inline: lcarg = lc - else: lcarg = None - rotation,nlc = cs.calc_label_rot_and_inline( - slc, imin, lw, lcarg, - self.inline_spacing ) - - cs.add_label(xmin,ymin,rotation,cs.labelLevelList[lmin], - cs.labelCValueList[lmin]) - - if self.inline: - # Remove old, not looping over paths so we can do this up front - paths.pop(segmin) - - # Add paths if not empty or single point - for n in nlc: - if len(n)>1: - paths.append( path.Path(n) ) - + if event.inaxes == self.cs.ax: + self.cs.add_label_near(event.x, event.y, self.inline, + inline_spacing=self.inline_spacing, + transform=False) self.fig.canvas.draw() - else: # Remove event if not valid + else: # Remove event if not valid BlockingInput.pop(self) - def button3(self,event): + def button3(self, event): """ This will be called if button 3 is clicked. This will remove a label if not in inline mode. Unfortunately, if one is doing @@ -370,26 +335,28 @@ self.cs.pop_label() self.cs.ax.figure.canvas.draw() - def __call__(self,inline,inline_spacing=5,n=-1,timeout=-1): - self.inline=inline - self.inline_spacing=inline_spacing + def __call__(self, inline, inline_spacing=5, n=-1, timeout=-1): + self.inline = inline + self.inline_spacing = inline_spacing - BlockingMouseInput.__call__(self,n=n,timeout=timeout, + BlockingMouseInput.__call__(self, n=n, timeout=timeout, show_clicks=False) + class BlockingKeyMouseInput(BlockingInput): """ Class that creates a callable object to retrieve a single mouse or keyboard click """ def __init__(self, fig): - BlockingInput.__init__(self, fig=fig, eventslist=('button_press_event','key_press_event') ) + BlockingInput.__init__(self, fig=fig, eventslist=( + 'button_press_event', 'key_press_event')) def post_event(self): """ Determines if it is a key event """ - assert len(self.events)>0, "No events yet" + assert len(self.events) > 0, "No events yet" self.keyormouse = self.events[-1].name == 'key_press_event' @@ -399,7 +366,6 @@ Returns True if key click, False if mouse, or None if timeout """ self.keyormouse = None - BlockingInput.__call__(self,n=1,timeout=timeout) + BlockingInput.__call__(self, n=1, timeout=timeout) return self.keyormouse - diff -Nru matplotlib-1.1.1/lib/matplotlib/cbook.py matplotlib-1.2.0/lib/matplotlib/cbook.py --- matplotlib-1.1.1/lib/matplotlib/cbook.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/cbook.py 2012-11-06 15:42:20.000000000 +0000 @@ -2,22 +2,34 @@ A collection of utility functions and classes. Many (but not all) from the Python Cookbook -- hence the name cbook """ -from __future__ import generators -import re, os, errno, sys, StringIO, traceback, locale, threading, types -import time, datetime +from __future__ import print_function + +import datetime +import errno +from functools import reduce +import glob +import gzip +import io +import locale +import os +import re +import subprocess +import sys +import threading +import time +import traceback import warnings -import numpy as np -import numpy.ma as ma from weakref import ref, WeakKeyDictionary -import cPickle -import os.path -import random -import new -import matplotlib -major, minor1, minor2, s, tmp = sys.version_info +import numpy as np +import numpy.ma as ma + +if sys.version_info[0] >= 3: + import types +else: + import new # On some systems, locale.getpreferredencoding returns None, # which can break unicode; and the sage project reports that @@ -28,20 +40,42 @@ # On some systems, getpreferredencoding sets the locale, which has # side effects. Passing False eliminates those side effects. +if sys.version_info[0] >= 3: + def unicode_safe(s): + import matplotlib -def unicode_safe(s): - import matplotlib + try: + preferredencoding = locale.getpreferredencoding( + matplotlib.rcParams['axes.formatter.use_locale']).strip() + if not preferredencoding: + preferredencoding = None + except (ValueError, ImportError, AttributeError): + preferredencoding = None - try: - preferredencoding = locale.getpreferredencoding( - matplotlib.rcParams['axes.formatter.use_locale']).strip() - if not preferredencoding: + if isinstance(s, bytes): + if preferredencoding is None: + return unicode(s) + else: + # We say "unicode" and not "str" here so it passes through + # 2to3 correctly. + return unicode(s, preferredencoding) + return s +else: + def unicode_safe(s): + import matplotlib + + try: + preferredencoding = locale.getpreferredencoding( + matplotlib.rcParams['axes.formatter.use_locale']).strip() + if not preferredencoding: + preferredencoding = None + except (ValueError, ImportError, AttributeError): preferredencoding = None - except (ValueError, ImportError, AttributeError): - preferredencoding = None - if preferredencoding is None: return unicode(s) - else: return unicode(s, preferredencoding) + if preferredencoding is None: + return unicode(s) + else: + return unicode(s, preferredencoding) class converter: @@ -52,18 +86,22 @@ def __init__(self, missing='Null', missingval=None): self.missing = missing self.missingval = missingval + def __call__(self, s): - if s==self.missing: return self.missingval + if s == self.missing: + return self.missingval return s def is_missing(self, s): - return not s.strip() or s==self.missing + return not s.strip() or s == self.missing + class tostr(converter): 'convert to string or None' def __init__(self, missing='Null', missingval=''): converter.__init__(self, missing=missing, missingval=missingval) + class todatetime(converter): 'convert to a datetime or None' def __init__(self, fmt='%Y-%m-%d', missing='Null', missingval=None): @@ -72,30 +110,35 @@ self.fmt = fmt def __call__(self, s): - if self.is_missing(s): return self.missingval + if self.is_missing(s): + return self.missingval tup = time.strptime(s, self.fmt) return datetime.datetime(*tup[:6]) - class todate(converter): 'convert to a date or None' def __init__(self, fmt='%Y-%m-%d', missing='Null', missingval=None): 'use a :func:`time.strptime` format string for conversion' converter.__init__(self, missing, missingval) self.fmt = fmt + def __call__(self, s): - if self.is_missing(s): return self.missingval + if self.is_missing(s): + return self.missingval tup = time.strptime(s, self.fmt) return datetime.date(*tup[:3]) + class tofloat(converter): 'convert to a float or None' def __init__(self, missing='Null', missingval=None): converter.__init__(self, missing) self.missingval = missingval + def __call__(self, s): - if self.is_missing(s): return self.missingval + if self.is_missing(s): + return self.missingval return float(s) @@ -105,32 +148,118 @@ converter.__init__(self, missing) def __call__(self, s): - if self.is_missing(s): return self.missingval + if self.is_missing(s): + return self.missingval return int(s) -class CallbackRegistry: - """ - Handle registering and disconnecting for a set of signals and - callbacks:: - def oneat(x): - print 'eat', x +class _BoundMethodProxy(object): + ''' + Our own proxy object which enables weak references to bound and unbound + methods and arbitrary callables. Pulls information about the function, + class, and instance out of a bound method. Stores a weak reference to the + instance to support garbage collection. + + @organization: IBM Corporation + @copyright: Copyright (c) 2005, 2006 IBM Corporation + @license: The BSD License + + Minor bugfixes by Michael Droettboom + ''' + def __init__(self, cb): + try: + try: + self.inst = ref(cb.im_self) + except TypeError: + self.inst = None + self.func = cb.im_func + self.klass = cb.im_class + except AttributeError: + self.inst = None + self.func = cb + self.klass = None + + def __getstate__(self): + d = self.__dict__.copy() + # de-weak reference inst + inst = d['inst'] + if inst is not None: + d['inst'] = inst() + return d + + def __setstate__(self, statedict): + self.__dict__ = statedict + inst = statedict['inst'] + # turn inst back into a weakref + if inst is not None: + self.inst = ref(inst) + + def __call__(self, *args, **kwargs): + ''' + Proxy for a call to the weak referenced object. Take + arbitrary params to pass to the callable. + + Raises `ReferenceError`: When the weak reference refers to + a dead object + ''' + if self.inst is not None and self.inst() is None: + raise ReferenceError + elif self.inst is not None: + # build a new instance method with a strong reference to the + # instance + if sys.version_info[0] >= 3: + mtd = types.MethodType(self.func, self.inst()) + else: + mtd = new.instancemethod(self.func, self.inst(), self.klass) + else: + # not a bound method, just return the func + mtd = self.func + # invoke the callable and return the result + return mtd(*args, **kwargs) - def ondrink(x): - print 'drink', x + def __eq__(self, other): + ''' + Compare the held function and instance with that held by + another proxy. + ''' + try: + if self.inst is None: + return self.func == other.func and other.inst is None + else: + return self.func == other.func and self.inst() == other.inst() + except Exception: + return False - callbacks = CallbackRegistry() + def __ne__(self, other): + ''' + Inverse of __eq__. + ''' + return not self.__eq__(other) - ideat = callbacks.connect('eat', oneat) - iddrink = callbacks.connect('drink', ondrink) - #tmp = callbacks.connect('drunk', ondrink) # this will raise a ValueError +class CallbackRegistry: + """ + Handle registering and disconnecting for a set of signals and + callbacks: - callbacks.process('drink', 123) # will call oneat - callbacks.process('eat', 456) # will call ondrink - callbacks.process('be merry', 456) # nothing will be called - callbacks.disconnect(ideat) # disconnect oneat - callbacks.process('eat', 456) # nothing will be called + >>> def oneat(x): + ... print 'eat', x + >>> def ondrink(x): + ... print 'drink', x + + >>> from matplotlib.cbook import CallbackRegistry + >>> callbacks = CallbackRegistry() + + >>> id_eat = callbacks.connect('eat', oneat) + >>> id_drink = callbacks.connect('drink', ondrink) + + >>> callbacks.process('drink', 123) + drink 123 + >>> callbacks.process('eat', 456) + eat 456 + >>> callbacks.process('be merry', 456) # nothing will be called + >>> callbacks.disconnect(id_eat) + >>> callbacks.process('eat', 456) # nothing will be called In practice, one should always disconnect all callbacks when they are no longer needed to avoid dangling references (and thus memory @@ -146,92 +275,41 @@ `"Mindtrove" blog `_. """ - class BoundMethodProxy(object): - ''' - Our own proxy object which enables weak references to bound and unbound - methods and arbitrary callables. Pulls information about the function, - class, and instance out of a bound method. Stores a weak reference to the - instance to support garbage collection. - - @organization: IBM Corporation - @copyright: Copyright (c) 2005, 2006 IBM Corporation - @license: The BSD License - - Minor bugfixes by Michael Droettboom - ''' - def __init__(self, cb): - try: - try: - self.inst = ref(cb.im_self) - except TypeError: - self.inst = None - self.func = cb.im_func - self.klass = cb.im_class - except AttributeError: - self.inst = None - self.func = cb - self.klass = None - - def __call__(self, *args, **kwargs): - ''' - Proxy for a call to the weak referenced object. Take - arbitrary params to pass to the callable. - - Raises `ReferenceError`: When the weak reference refers to - a dead object - ''' - if self.inst is not None and self.inst() is None: - raise ReferenceError - elif self.inst is not None: - # build a new instance method with a strong reference to the instance - mtd = new.instancemethod(self.func, self.inst(), self.klass) - else: - # not a bound method, just return the func - mtd = self.func - # invoke the callable and return the result - return mtd(*args, **kwargs) - - def __eq__(self, other): - ''' - Compare the held function and instance with that held by - another proxy. - ''' - try: - if self.inst is None: - return self.func == other.func and other.inst is None - else: - return self.func == other.func and self.inst() == other.inst() - except Exception: - return False - - def __ne__(self, other): - ''' - Inverse of __eq__. - ''' - return not self.__eq__(other) - def __init__(self, *args): if len(args): warnings.warn( - 'CallbackRegistry no longer requires a list of callback types. Ignoring arguments', + 'CallbackRegistry no longer requires a list of callback types.' + ' Ignoring arguments', DeprecationWarning) self.callbacks = dict() self._cid = 0 - self._func_cid_map = WeakKeyDictionary() + self._func_cid_map = {} + + def __getstate__(self): + # We cannot currently pickle the callables in the registry, so + # return an empty dictionary. + return {} + + def __setstate__(self, state): + # re-initialise an empty callback registry + self.__init__() def connect(self, s, func): """ register *func* to be called when a signal *s* is generated func will be called """ - if func in self._func_cid_map: - return self._func_cid_map[func] - proxy = self.BoundMethodProxy(func) + self._func_cid_map.setdefault(s, WeakKeyDictionary()) + if func in self._func_cid_map[s]: + return self._func_cid_map[s][func] + self._cid += 1 + cid = self._cid + self._func_cid_map[s][func] = cid self.callbacks.setdefault(s, dict()) - self.callbacks[s][self._cid] = proxy - self._func_cid_map[func] = self._cid - return self._cid + proxy = _BoundMethodProxy(func) + self.callbacks[s][cid] = proxy + return cid def disconnect(self, cid): """ @@ -277,11 +355,13 @@ self._stopevent = threading.Event() def stop(self): - if self._stopped: return + if self._stopped: + return self._stopevent.set() self.join() self._stopped = True + class Timeout(Scheduler): """ Schedule recurring events with a wait time in seconds @@ -298,7 +378,9 @@ Scheduler.idlelock.acquire() b = self.func(self) Scheduler.idlelock.release() - if not b: break + if not b: + break + class Idle(Scheduler): """ @@ -308,6 +390,7 @@ # just implements a short wait time. But it will provide a # placeholder for a proper impl ater waittime = 0.05 + def __init__(self, func): Scheduler.__init__(self) self.func = func @@ -319,37 +402,51 @@ Scheduler.idlelock.acquire() b = self.func(self) Scheduler.idlelock.release() - if not b: break + if not b: + break + class silent_list(list): """ override repr when returning a list of matplotlib artists to prevent long, meaningless output. This is meant to be used for a - homogeneous list of a give type + homogeneous list of a given type """ def __init__(self, type, seq=None): self.type = type - if seq is not None: self.extend(seq) + if seq is not None: + self.extend(seq) def __repr__(self): return '' % (len(self), self.type) def __str__(self): - return '' % (len(self), self.type) + return repr(self) + + def __getstate__(self): + # store a dictionary of this SilentList's state + return {'type': self.type, 'seq': self[:]} + + def __setstate__(self, state): + self.type = state['type'] + self.extend(state['seq']) + def strip_math(s): 'remove latex formatting from mathtext' remove = (r'\mathdefault', r'\rm', r'\cal', r'\tt', r'\it', '\\', '{', '}') s = s[1:-1] - for r in remove: s = s.replace(r,'') + for r in remove: + s = s.replace(r, '') return s + class Bunch: """ Often we want to just collect a bunch of stuff together, naming each item of the bunch; a dictionary's OK for that, but a small do- nothing class is even handier, and prettier to use. Whenever you want to - group a few variables: + group a few variables:: >>> point = Bunch(datum=2, squared=4, coord=12) >>> point.datum @@ -360,14 +457,17 @@ def __init__(self, **kwds): self.__dict__.update(kwds) - def __repr__(self): - keys = self.__dict__.keys() - return 'Bunch(%s)'%', '.join(['%s=%s'%(k,self.__dict__[k]) for k in keys]) + keys = self.__dict__.iterkeys() + return 'Bunch(%s)' % ', '.join(['%s=%s' % (k, self.__dict__[k]) + for k + in keys]) + def unique(x): 'Return a list of unique elements of *x*' - return dict([ (val, 1) for val in x]).keys() + return dict([(val, 1) for val in x]).keys() + def iterable(obj): 'return true if *obj* is iterable' @@ -380,40 +480,54 @@ def is_string_like(obj): 'Return True if *obj* looks like a string' - if isinstance(obj, (str, unicode)): return True + if isinstance(obj, (str, unicode)): + return True # numpy strings are subclass of str, ma strings are not if ma.isMaskedArray(obj): if obj.ndim == 0 and obj.dtype.kind in 'SU': return True else: return False - try: obj + '' - except: return False + try: + obj + '' + except: + return False return True + def is_sequence_of_strings(obj): """ Returns true if *obj* is iterable and contains strings """ - if not iterable(obj): return False - if is_string_like(obj): return False + if not iterable(obj): + return False + if is_string_like(obj): + return False for o in obj: - if not is_string_like(o): return False + if not is_string_like(o): + return False return True + def is_writable_file_like(obj): 'return true if *obj* looks like a file object with a *write* method' return hasattr(obj, 'write') and callable(obj.write) + def is_scalar(obj): 'return true if *obj* is not string like and is not iterable' return not is_string_like(obj) and not iterable(obj) + def is_numlike(obj): 'return true if *obj* looks like a number' - try: obj+1 - except: return False - else: return True + try: + obj + 1 + except: + return False + else: + return True + def to_filehandle(fname, flag='rU', return_opened=False): """ @@ -425,15 +539,15 @@ if fname.endswith('.gz'): import gzip # get rid of 'U' in flag for gzipped files. - flag = flag.replace('U','') + flag = flag.replace('U', '') fh = gzip.open(fname, flag) elif fname.endswith('.bz2'): # get rid of 'U' in flag for bz2 files - flag = flag.replace('U','') + flag = flag.replace('U', '') import bz2 fh = bz2.BZ2File(fname, flag) else: - fh = file(fname, flag) + fh = open(fname, flag) opened = True elif hasattr(fname, 'seek'): fh = fname @@ -444,288 +558,64 @@ return fh, opened return fh + def is_scalar_or_string(val): + """Return whether the given object is a scalar or string like.""" return is_string_like(val) or not iterable(val) -def _get_data_server(cache_dir, baseurl): - import urllib2 - class ViewVCCachedServer(urllib2.HTTPSHandler): - """ - Urllib2 handler that takes care of caching files. - The file cache.pck holds the directory of files that have been cached. - """ - def __init__(self, cache_dir, baseurl): - urllib2.HTTPSHandler.__init__(self) - self.cache_dir = cache_dir - self.baseurl = baseurl - self.read_cache() - self.remove_stale_files() - self.opener = urllib2.build_opener(self) - - def in_cache_dir(self, fn): - # make sure the datadir exists - reldir, filename = os.path.split(fn) - datadir = os.path.join(self.cache_dir, reldir) - if not os.path.exists(datadir): - os.makedirs(datadir) - - return os.path.join(datadir, filename) - - def read_cache(self): - """ - Read the cache file from the cache directory. - """ - fn = self.in_cache_dir('cache.pck') - if not os.path.exists(fn): - self.cache = {} - return - - f = open(fn, 'rb') - cache = cPickle.load(f) - f.close() - - # Earlier versions did not have the full paths in cache.pck - for url, (fn, x, y) in cache.items(): - if not os.path.isabs(fn): - cache[url] = (self.in_cache_dir(fn), x, y) - - # If any files are deleted, drop them from the cache - for url, (fn, _, _) in cache.items(): - if not os.path.exists(fn): - del cache[url] - - self.cache = cache - - def remove_stale_files(self): - """ - Remove files from the cache directory that are not listed in - cache.pck. - """ - # TODO: remove empty subdirectories - listed = set(fn for (_, (fn, _, _)) in self.cache.items()) - existing = reduce(set.union, - (set(os.path.join(dirpath, fn) for fn in filenames) - for (dirpath, _, filenames) in os.walk(self.cache_dir))) - matplotlib.verbose.report( - 'ViewVCCachedServer: files listed in cache.pck: %s' % listed, - 'debug') - matplotlib.verbose.report( - 'ViewVCCachedServer: files in cache directory: %s' % existing, - 'debug') - - for path in existing - listed - \ - set([self.in_cache_dir('cache.pck')]): - matplotlib.verbose.report( - 'ViewVCCachedServer:remove_stale_files: removing %s'%path, - level='debug') - os.remove(path) - - def write_cache(self): - """ - Write the cache data structure into the cache directory. - """ - fn = self.in_cache_dir('cache.pck') - f = open(fn, 'wb') - cPickle.dump(self.cache, f, -1) - f.close() - - def cache_file(self, url, data, headers): - """ - Store a received file in the cache directory. - """ - # Pick a filename - fn = url[len(self.baseurl):] - fullpath = self.in_cache_dir(fn) - - f = open(fullpath, 'wb') - f.write(data) - f.close() - - # Update the cache - self.cache[url] = (fullpath, headers.get('ETag'), - headers.get('Last-Modified')) - self.write_cache() - - # These urllib2 entry points are used: - # http_request for preprocessing requests - # http_error_304 for handling 304 Not Modified responses - # http_response for postprocessing requests - - def https_request(self, req): - """ - Make the request conditional if we have a cached file. - """ - url = req.get_full_url() - if url in self.cache: - _, etag, lastmod = self.cache[url] - if etag is not None: - req.add_header("If-None-Match", etag) - if lastmod is not None: - req.add_header("If-Modified-Since", lastmod) - matplotlib.verbose.report( - "ViewVCCachedServer: request headers %s" % req.header_items(), - "debug") - return req - - def https_error_304(self, req, fp, code, msg, hdrs): - """ - Read the file from the cache since the server has no newer version. - """ - url = req.get_full_url() - fn, _, _ = self.cache[url] - matplotlib.verbose.report( - 'ViewVCCachedServer: reading data file from cache file "%s"' - %fn, 'debug') - file = open(fn, 'rb') - handle = urllib2.addinfourl(file, hdrs, url) - handle.code = 304 - return handle - - def https_response(self, req, response): - """ - Update the cache with the returned file. - """ - matplotlib.verbose.report( - 'ViewVCCachedServer: received response %d: %s' - % (response.code, response.msg), 'debug') - if response.code != 200: - return response - else: - data = response.read() - self.cache_file(req.get_full_url(), data, response.headers) - result = urllib2.addinfourl(StringIO.StringIO(data), - response.headers, - req.get_full_url()) - result.code = response.code - result.msg = response.msg - return result - - def get_sample_data(self, fname, asfileobj=True): - """ - Check the cachedirectory for a sample_data file. If it does - not exist, fetch it with urllib from the git repo and - store it in the cachedir. - - If asfileobj is True, a file object will be returned. Else the - path to the file as a string will be returned. - """ - # TODO: time out if the connection takes forever - # (may not be possible with urllib2 only - spawn a helper process?) - - # quote is not in python2.4, so check for it and get it from - # urllib if it is not available - quote = getattr(urllib2, 'quote', None) - if quote is None: - import urllib - quote = urllib.quote - - # retrieve the URL for the side effect of refreshing the cache - url = self.baseurl + quote(fname) - error = 'unknown error' - matplotlib.verbose.report('ViewVCCachedServer: retrieving %s' - % url, 'debug') - try: - response = self.opener.open(url) - except urllib2.URLError, e: - # could be a missing network connection - error = str(e) - - cached = self.cache.get(url) - if cached is None: - msg = 'file %s not in cache; received %s when trying to '\ - 'retrieve' % (fname, error) - raise KeyError(msg) - - fname = cached[0] - - if asfileobj: - if (os.path.splitext(fname)[-1].lower() in - ('.csv', '.xrc', '.txt')): - mode = 'r' - else: - mode = 'rb' - return open(fname, mode) - else: - return fname - - return ViewVCCachedServer(cache_dir, baseurl) - def get_sample_data(fname, asfileobj=True): """ - Check the cachedirectory ~/.matplotlib/sample_data for a sample_data - file. If it does not exist, fetch it with urllib from the mpl git repo - - https://raw.github.com/matplotlib/sample_data/master - - and store it in the cachedir. - - If asfileobj is True, a file object will be returned. Else the - path to the file as a string will be returned - - To add a datafile to this directory, you need to check out - sample_data from matplotlib git:: - - git clone git@github.com:matplotlib/sample_data - - and git add the data file you want to support. This is primarily - intended for use in mpl examples that need custom data. - - To bypass all downloading, set the rc parameter examples.download to False - and examples.directory to the directory where we should look. - """ - - if not matplotlib.rcParams['examples.download']: - directory = matplotlib.rcParams['examples.directory'] - f = os.path.join(directory, fname) - if asfileobj: - return open(f, 'rb') + Return a sample data file. *fname* is a path relative to the + `mpl-data/sample_data` directory. If *asfileobj* is `True` + return a file object, otherwise just a file path. + + If the filename ends in .gz, the file is implicitly ungzipped. + """ + root = os.path.join(os.path.dirname(__file__), "mpl-data", "sample_data") + path = os.path.join(root, fname) + + if asfileobj: + if (os.path.splitext(fname)[-1].lower() in + ('.csv', '.xrc', '.txt')): + mode = 'r' else: - return f - - myserver = get_sample_data.myserver - if myserver is None: - configdir = matplotlib.get_configdir() - cachedir = os.path.join(configdir, 'sample_data') - baseurl = 'https://raw.github.com/matplotlib/sample_data/master/' - try: - myserver = _get_data_server(cachedir, baseurl) - get_sample_data.myserver = myserver - except ImportError: - raise ImportError( - 'Python must be built with SSL support to fetch sample data ' - 'from the matplotlib repository') + mode = 'rb' - return myserver.get_sample_data(fname, asfileobj=asfileobj) + base, ext = os.path.splitext(fname) + if ext == '.gz': + return gzip.open(path, mode) + else: + return open(path, mode) + else: + return path -get_sample_data.myserver = None def flatten(seq, scalarp=is_scalar_or_string): """ - this generator flattens nested containers such as + Returns a generator of flattened nested containers - >>> l=( ('John', 'Hunter'), (1,23), [[[[42,(5,23)]]]]) - - so that + For example: - >>> for i in flatten(l): print i, - John Hunter 1 23 42 5 23 + >>> from matplotlib.cbook import flatten + >>> l = (('John', ['Hunter']), (1, 23), [[([42, (5, 23)], )]]) + >>> print list(flatten(l)) + ['John', 'Hunter', 1, 23, 42, 5, 23] By: Composite of Holger Krekel and Luther Blissett From: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/121294 and Recipe 1.12 in cookbook """ for item in seq: - if scalarp(item): yield item + if scalarp(item): + yield item else: for subitem in flatten(item, scalarp): yield subitem - class Sorter: """ - Sort by attribute or item Example usage:: @@ -746,7 +636,8 @@ def _helper(self, data, aux, inplace): aux.sort() result = [data[i] for junk, i in aux] - if inplace: data[:] = result + if inplace: + data[:] = result return result def byItem(self, data, itemindex=None, inplace=1): @@ -763,7 +654,7 @@ return self._helper(data, aux, inplace) def byAttribute(self, data, attributename, inplace=1): - aux = [(getattr(data[i],attributename),i) for i in range(len(data))] + aux = [(getattr(data[i], attributename), i) for i in range(len(data))] return self._helper(data, aux, inplace) # a couple of handy synonyms @@ -771,9 +662,6 @@ __call__ = byItem - - - class Xlator(dict): """ All-in-one multiple-string-substitution class @@ -795,7 +683,7 @@ def _make_regex(self): """ Build re object based on the keys of the current dictionary """ - return re.compile("|".join(map(re.escape, self.keys()))) + return re.compile("|".join(map(re.escape, self.iterkeys()))) def __call__(self, match): """ Handler invoked for each regex *match* """ @@ -806,7 +694,6 @@ return self._make_regex().sub(self, text) - def soundex(name, len=4): """ soundex module conforming to Odell-Russell algorithm """ @@ -818,8 +705,9 @@ # Translate letters in name to soundex digits for c in name.upper(): if c.isalpha(): - if not fc: fc = c # Remember first letter - d = soundex_digits[ord(c)-ord('A')] + if not fc: + fc = c # Remember first letter + d = soundex_digits[ord(c) - ord('A')] # Duplicate consecutive soundex digits are skipped if not sndx or (d != sndx[-1]): sndx += d @@ -834,24 +722,35 @@ return (sndx + (len * '0'))[:len] - class Null: """ Null objects always and reliably "do nothing." """ - def __init__(self, *args, **kwargs): pass - def __call__(self, *args, **kwargs): return self - def __str__(self): return "Null()" - def __repr__(self): return "Null()" - def __nonzero__(self): return 0 + def __init__(self, *args, **kwargs): + pass - def __getattr__(self, name): return self - def __setattr__(self, name, value): return self - def __delattr__(self, name): return self + def __call__(self, *args, **kwargs): + return self + def __str__(self): + return "Null()" + + def __repr__(self): + return "Null()" + def __nonzero__(self): + return 0 + def __getattr__(self, name): + return self -def mkdirs(newdir, mode=0777): + def __setattr__(self, name, value): + return self + + def __delattr__(self, name): + return self + + +def mkdirs(newdir, mode=0o777): """ make directory *newdir* recursively, and set *mode*. Equivalent to :: @@ -861,12 +760,12 @@ try: if not os.path.exists(newdir): parts = os.path.split(newdir) - for i in range(1, len(parts)+1): + for i in range(1, len(parts) + 1): thispart = os.path.join(*parts[:i]) if not os.path.exists(thispart): os.makedirs(thispart, mode) - except OSError, err: + except OSError as err: # Reraise the error unless it's about an already existing directory if err.errno != errno.EEXIST or not os.path.isdir(newdir): raise @@ -890,16 +789,19 @@ return result get_realpath_and_stat = GetRealpathAndStat() + def dict_delall(d, keys): 'delete all of the *keys* from the :class:`dict` *d*' for key in keys: - try: del d[key] - except KeyError: pass + try: + del d[key] + except KeyError: + pass class RingBuffer: """ class that implements a not-yet-full buffer """ - def __init__(self,size_max): + def __init__(self, size_max): self.max = size_max self.data = [] @@ -908,12 +810,13 @@ def append(self, x): """ Append an element overwriting the oldest one. """ self.data[self.cur] = x - self.cur = (self.cur+1) % self.max + self.cur = (self.cur + 1) % self.max + def get(self): """ return list of elements in correct order """ - return self.data[self.cur:]+self.data[:self.cur] + return self.data[self.cur:] + self.data[:self.cur] - def append(self,x): + def append(self, x): """append an element at the end of the buffer""" self.data.append(x) if len(self.data) == self.max: @@ -929,7 +832,6 @@ return self.data[i % len(self.data)] - def get_split_ind(seq, N): """ *seq* is a list of words. Return the index into seq such that:: @@ -941,22 +843,23 @@ sLen = 0 # todo: use Alex's xrange pattern from the cbook for efficiency - for (word, ind) in zip(seq, range(len(seq))): + for (word, ind) in zip(seq, xrange(len(seq))): sLen += len(word) + 1 # +1 to account for the len(' ') - if sLen>=N: return ind + if sLen >= N: + return ind return len(seq) def wrap(prefix, text, cols): 'wrap *text* with *prefix* at length *cols*' - pad = ' '*len(prefix.expandtabs()) + pad = ' ' * len(prefix.expandtabs()) available = cols - len(pad) seq = text.split(' ') Nseq = len(seq) ind = 0 lines = [] - while ind>sh, s +def exception_to_str(s=None): + + sh = io.StringIO() + if s is not None: + print(s, file=sh) traceback.print_exc(file=sh) return sh.getvalue() @@ -1085,33 +989,42 @@ Return *True* if all elements of *seq* compare equal. If *seq* is 0 or 1 length, return *True* """ - if len(seq)<2: return True + if len(seq) < 2: + return True val = seq[0] for i in xrange(1, len(seq)): thisval = seq[i] - if thisval != val: return False + if thisval != val: + return False return True + def alltrue(seq): """ Return *True* if all elements of *seq* evaluate to *True*. If *seq* is empty, return *False*. """ - if not len(seq): return False + if not len(seq): + return False for val in seq: - if not val: return False + if not val: + return False return True + def onetrue(seq): """ Return *True* if one element of *seq* is *True*. It *seq* is empty, return *False*. """ - if not len(seq): return False + if not len(seq): + return False for val in seq: - if val: return True + if val: + return True return False + def allpairs(x): """ return all possible pairs in sequence *x* @@ -1120,8 +1033,7 @@ .. _thread: http://groups.google.com/groups?q=all+pairs+group:*python*&hl=en&lr=&ie=UTF-8&selm=mailman.4028.1096403649.5135.python-list%40python.org&rnum=1 """ - return [ (s, f) for i, f in enumerate(x) for s in x[i+1:] ] - + return [(s, f) for i, f in enumerate(x) for s in x[i + 1:]] class maxdict(dict): @@ -1134,16 +1046,16 @@ dict.__init__(self) self.maxsize = maxsize self._killkeys = [] + def __setitem__(self, k, v): if k not in self: - if len(self)>=self.maxsize: + if len(self) >= self.maxsize: del self[self._killkeys[0]] del self._killkeys[0] self._killkeys.append(k) dict.__setitem__(self, k, v) - class Stack(object): """ Implement a stack where elements can be pushed on and you can move @@ -1157,8 +1069,10 @@ def __call__(self): 'return the current element, or None' - if not len(self._elements): return self._default - else: return self._elements[self._pos] + if not len(self._elements): + return self._default + else: + return self._elements[self._pos] def __len__(self): return self._elements.__len__() @@ -1169,12 +1083,14 @@ def forward(self): 'move the position forward and return the current element' N = len(self._elements) - if self._pos0: self._pos -= 1 + if self._pos > 0: + self._pos -= 1 return self() def push(self, o): @@ -1182,19 +1098,20 @@ push object onto stack at current position - all elements occurring later than the current position are discarded """ - self._elements = self._elements[:self._pos+1] + self._elements = self._elements[:self._pos + 1] self._elements.append(o) - self._pos = len(self._elements)-1 + self._pos = len(self._elements) - 1 return self() def home(self): 'push the first element onto the top of the stack' - if not len(self._elements): return + if not len(self._elements): + return self.push(self._elements[0]) return self() def empty(self): - return len(self._elements)==0 + return len(self._elements) == 0 def clear(self): 'empty the stack' @@ -1213,8 +1130,10 @@ self.clear() bubbles = [] for thiso in old: - if thiso==o: bubbles.append(thiso) - else: self.push(thiso) + if thiso == o: + bubbles.append(thiso) + else: + self.push(thiso) for thiso in bubbles: self.push(o) return o @@ -1226,12 +1145,17 @@ old = self._elements[:] self.clear() for thiso in old: - if thiso==o: continue - else: self.push(thiso) + if thiso == o: + continue + else: + self.push(thiso) + def popall(seq): 'empty a list' - for i in xrange(len(seq)): seq.pop() + for i in xrange(len(seq)): + seq.pop() + def finddir(o, match, case=False): """ @@ -1239,62 +1163,69 @@ is True require an exact case match. """ if case: - names = [(name,name) for name in dir(o) if is_string_like(name)] + names = [(name, name) for name in dir(o) if is_string_like(name)] else: - names = [(name.lower(), name) for name in dir(o) if is_string_like(name)] + names = [(name.lower(), name) for name in dir(o) + if is_string_like(name)] match = match.lower() - return [orig for name, orig in names if name.find(match)>=0] + return [orig for name, orig in names if name.find(match) >= 0] + def reverse_dict(d): 'reverse the dictionary -- may lose data if values are not unique!' - return dict([(v,k) for k,v in d.items()]) + return dict([(v, k) for k, v in d.iteritems()]) + def restrict_dict(d, keys): """ Return a dictionary that contains those keys that appear in both d and keys, with values from d. """ - return dict([(k,v) for (k,v) in d.iteritems() if k in keys]) + return dict([(k, v) for (k, v) in d.iteritems() if k in keys]) + def report_memory(i=0): # argument may go away 'return the memory consumed by process' from subprocess import Popen, PIPE pid = os.getpid() - if sys.platform=='sunos5': + if sys.platform == 'sunos5': a2 = Popen('ps -p %d -o osz' % pid, shell=True, - stdout=PIPE).stdout.readlines() + stdout=PIPE).stdout.readlines() mem = int(a2[-1].strip()) elif sys.platform.startswith('linux'): a2 = Popen('ps -p %d -o rss,sz' % pid, shell=True, - stdout=PIPE).stdout.readlines() + stdout=PIPE).stdout.readlines() mem = int(a2[1].split()[1]) elif sys.platform.startswith('darwin'): a2 = Popen('ps -p %d -o rss,vsz' % pid, shell=True, - stdout=PIPE).stdout.readlines() + stdout=PIPE).stdout.readlines() mem = int(a2[1].split()[0]) elif sys.platform.startswith('win'): try: a2 = Popen(["tasklist", "/nh", "/fi", "pid eq %d" % pid], - stdout=PIPE).stdout.read() + stdout=PIPE).stdout.read() except OSError: raise NotImplementedError( "report_memory works on Windows only if " "the 'tasklist' program is found") - mem = int(a2.strip().split()[-2].replace(',','')) + mem = int(a2.strip().split()[-2].replace(',', '')) else: raise NotImplementedError( - "We don't have a memory monitor for %s" % sys.platform) + "We don't have a memory monitor for %s" % sys.platform) return mem _safezip_msg = 'In safezip, len(args[0])=%d but len(args[%d])=%d' + + def safezip(*args): 'make sure *args* are equal len before zipping' Nx = len(args[0]) for i, arg in enumerate(args[1:]): if len(arg) != Nx: - raise ValueError(_safezip_msg % (Nx, i+1, len(arg))) + raise ValueError(_safezip_msg % (Nx, i + 1, len(arg))) return zip(*args) + def issubclass_safe(x, klass): 'return issubclass(x, klass) and return False on a TypeError' @@ -1303,6 +1234,7 @@ except TypeError: return False + def safe_masked_invalid(x): x = np.asanyarray(x) try: @@ -1312,6 +1244,7 @@ return x return xm + class MemoryMonitor: def __init__(self, nmax=20000): self._nmax = nmax @@ -1334,21 +1267,21 @@ def report(self, segments=4): n = self._n segments = min(n, segments) - dn = int(n/segments) + dn = int(n / segments) ii = range(0, n, dn) - ii[-1] = n-1 - print - print 'memory report: i, mem, dmem, dmem/nloops' - print 0, self._mem[0] + ii[-1] = n - 1 + print() + print('memory report: i, mem, dmem, dmem/nloops') + print(0, self._mem[0]) for i in range(1, len(ii)): - di = ii[i] - ii[i-1] + di = ii[i] - ii[i - 1] if di == 0: continue - dm = self._mem[ii[i]] - self._mem[ii[i-1]] - print '%5d %5d %3d %8.3f' % (ii[i], self._mem[ii[i]], - dm, dm / float(di)) + dm = self._mem[ii[i]] - self._mem[ii[i - 1]] + print('%5d %5d %3d %8.3f' % (ii[i], self._mem[ii[i]], + dm, dm / float(di))) if self._overflow: - print "Warning: array size was too small for the number of calls." + print("Warning: array size was too small for the number of calls.") def xy(self, i0=0, isub=1): x = np.arange(i0, self._n, isub) @@ -1387,7 +1320,7 @@ outstream.write(" %s -- " % str(type(step))) if isinstance(step, dict): - for key, val in step.items(): + for key, val in step.iteritems(): if val is next: outstream.write("[%s]" % repr(key)) break @@ -1428,7 +1361,8 @@ for obj in objects: outstream.write("Examining: %r\n" % (obj,)) - recurse(obj, obj, { }, []) + recurse(obj, obj, {}, []) + class Grouper(object): """ @@ -1444,25 +1378,27 @@ For example: - >>> class Foo: - ... def __init__(self, s): - ... self.s = s - ... def __repr__(self): - ... return self.s - ... - >>> a, b, c, d, e, f = [Foo(x) for x in 'abcdef'] - >>> g = Grouper() - >>> g.join(a, b) - >>> g.join(b, c) - >>> g.join(d, e) - >>> list(g) - [[d, e], [a, b, c]] - >>> g.joined(a, b) - True - >>> g.joined(a, c) - True - >>> g.joined(a, d) - False + >>> from matplotlib.cbook import Grouper + >>> class Foo(object): + ... def __init__(self, s): + ... self.s = s + ... def __repr__(self): + ... return self.s + ... + >>> a, b, c, d, e, f = [Foo(x) for x in 'abcdef'] + >>> grp = Grouper() + >>> grp.join(a, b) + >>> grp.join(b, c) + >>> grp.join(d, e) + >>> sorted(map(tuple, grp)) + [(d, e), (a, b, c)] + >>> grp.joined(a, b) + True + >>> grp.joined(a, c) + True + >>> grp.joined(a, d) + False + """ def __init__(self, init=[]): mapping = self._mapping = {} @@ -1477,10 +1413,10 @@ Clean dead weak references from the dictionary """ mapping = self._mapping - for key, val in mapping.items(): - if key() is None: - del mapping[key] - val.remove(key) + to_drop = [key for key in mapping if key() is None] + for key in to_drop: + val = mapping.pop(key) + val.remove(key) def join(self, a, *args): """ @@ -1524,7 +1460,8 @@ """ self.clean() - class Token: pass + class Token: + pass token = Token() # Mark each group as we come across if by appending a token, @@ -1561,7 +1498,7 @@ result[0] = a[0] a0 = a[0:-1] - a1 = a[1: ] + a1 = a[1:] delta = ((a1 - a0) / steps) for i in range(1, int(steps)): @@ -1570,9 +1507,11 @@ return result + def recursive_remove(path): if os.path.isdir(path): - for fname in glob.glob(os.path.join(path, '*')) + glob.glob(os.path.join(path, '.*')): + for fname in glob.glob(os.path.join(path, '*')) + \ + glob.glob(os.path.join(path, '.*')): if os.path.isdir(fname): recursive_remove(fname) os.removedirs(fname) @@ -1582,6 +1521,7 @@ else: os.remove(path) + def delete_masked_points(*args): """ Find all masked and/or non-finite points in a set of arguments, @@ -1644,7 +1584,7 @@ mask = np.isfinite(xd) if isinstance(mask, np.ndarray): masks.append(mask) - except: #Fixme: put in tuple of possible exceptions? + except: # Fixme: put in tuple of possible exceptions? pass if len(masks): mask = reduce(np.logical_and, masks) @@ -1658,7 +1598,8 @@ margs[i] = x.filled() return margs -def unmasked_index_ranges(mask, compressed = True): + +def unmasked_index_ranges(mask, compressed=True): ''' Find index ranges where *mask* is *False*. @@ -1710,52 +1651,50 @@ # a dict to cross-map linestyle arguments _linestyles = [('-', 'solid'), - ('--', 'dashed'), - ('-.', 'dashdot'), - (':', 'dotted')] + ('--', 'dashed'), + ('-.', 'dashdot'), + (':', 'dotted')] ls_mapper = dict(_linestyles) ls_mapper.update([(ls[1], ls[0]) for ls in _linestyles]) -def less_simple_linear_interpolation( x, y, xi, extrap=False ): - """ - This function has been moved to matplotlib.mlab -- please import - it from there - """ - # deprecated from cbook in 0.98.4 - warnings.warn('less_simple_linear_interpolation has been moved to matplotlib.mlab -- please import it from there', DeprecationWarning) - import matplotlib.mlab as mlab - return mlab.less_simple_linear_interpolation( x, y, xi, extrap=extrap ) -def isvector(X): +def less_simple_linear_interpolation(x, y, xi, extrap=False): """ This function has been moved to matplotlib.mlab -- please import it from there """ # deprecated from cbook in 0.98.4 - warnings.warn('isvector has been moved to matplotlib.mlab -- please import it from there', DeprecationWarning) + warnings.warn('less_simple_linear_interpolation has been moved to ' + 'matplotlib.mlab -- please import it from there', + DeprecationWarning) import matplotlib.mlab as mlab - return mlab.isvector( x, y, xi, extrap=extrap ) + return mlab.less_simple_linear_interpolation(x, y, xi, extrap=extrap) + -def vector_lengths( X, P=2., axis=None ): +def vector_lengths(X, P=2.0, axis=None): """ This function has been moved to matplotlib.mlab -- please import it from there """ # deprecated from cbook in 0.98.4 - warnings.warn('vector_lengths has been moved to matplotlib.mlab -- please import it from there', DeprecationWarning) + warnings.warn('vector_lengths has been moved to matplotlib.mlab -- ' + 'please import it from there', DeprecationWarning) import matplotlib.mlab as mlab - return mlab.vector_lengths( X, P=2., axis=axis ) + return mlab.vector_lengths(X, P=2.0, axis=axis) -def distances_along_curve( X ): + +def distances_along_curve(X): """ This function has been moved to matplotlib.mlab -- please import it from there """ # deprecated from cbook in 0.98.4 - warnings.warn('distances_along_curve has been moved to matplotlib.mlab -- please import it from there', DeprecationWarning) + warnings.warn('distances_along_curve has been moved to matplotlib.mlab ' + '-- please import it from there', DeprecationWarning) import matplotlib.mlab as mlab - return mlab.distances_along_curve( X ) + return mlab.distances_along_curve(X) + def path_length(X): """ @@ -1763,36 +1702,42 @@ it from there """ # deprecated from cbook in 0.98.4 - warnings.warn('path_length has been moved to matplotlib.mlab -- please import it from there', DeprecationWarning) + warnings.warn('path_length has been moved to matplotlib.mlab ' + '-- please import it from there', DeprecationWarning) import matplotlib.mlab as mlab return mlab.path_length(X) + def is_closed_polygon(X): """ This function has been moved to matplotlib.mlab -- please import it from there """ # deprecated from cbook in 0.98.4 - warnings.warn('is_closed_polygon has been moved to matplotlib.mlab -- please import it from there', DeprecationWarning) + warnings.warn('is_closed_polygon has been moved to matplotlib.mlab ' + '-- please import it from there', DeprecationWarning) import matplotlib.mlab as mlab return mlab.is_closed_polygon(X) + def quad2cubic(q0x, q0y, q1x, q1y, q2x, q2y): """ This function has been moved to matplotlib.mlab -- please import it from there """ # deprecated from cbook in 0.98.4 - warnings.warn('quad2cubic has been moved to matplotlib.mlab -- please import it from there', DeprecationWarning) + warnings.warn('quad2cubic has been moved to matplotlib.mlab -- please ' + 'import it from there', DeprecationWarning) import matplotlib.mlab as mlab return mlab.quad2cubic(q0x, q0y, q1x, q1y, q2x, q2y) + def align_iterators(func, *iterables): """ This generator takes a bunch of iterables that are ordered by func - It sends out ordered tuples: + It sends out ordered tuples:: - (func(row), [rows from all iterators matching func(row)]) + (func(row), [rows from all iterators matching func(row)]) It is used by :func:`matplotlib.mlab.recs_join` to join record arrays """ @@ -1804,7 +1749,7 @@ def iternext(self): try: - self.value = self.it.next() + self.value = next(self.it) self.key = func(self.value) except StopIteration: self.value = self.key = None @@ -1815,20 +1760,22 @@ retval = self.value self.iternext() elif self.key and key > self.key: - raise ValueError, "Iterator has been left behind" + raise ValueError("Iterator has been left behind") return retval - # This can be made more efficient by not computing the minimum key for each iteration + # This can be made more efficient by not computing the minimum key for each + # iteration iters = [myiter(it) for it in iterables] minvals = minkey = True while 1: - minvals = (filter(None, [it.key for it in iters])) + minvals = ([_f for _f in [it.key for it in iters] if _f]) if minvals: minkey = min(minvals) yield (minkey, [it(minkey) for it in iters]) else: break + def is_math_text(s): # Did we find an even number of non-escaped dollar signs? # If so, treat is as math text. @@ -1836,13 +1783,49 @@ s = unicode(s) except UnicodeDecodeError: raise ValueError( - "matplotlib display text must have all code points < 128 or use Unicode strings") + "matplotlib display text must have all code points < 128 or use " + "Unicode strings") dollar_count = s.count(r'$') - s.count(r'\$') even_dollars = (dollar_count > 0 and dollar_count % 2 == 0) return even_dollars + +class _NestedClassGetter(object): + # recipe from http://stackoverflow.com/a/11493777/741316 + """ + When called with the containing class as the first argument, + and the name of the nested class as the second argument, + returns an instance of the nested class. + """ + def __call__(self, containing_class, class_name): + nested_class = getattr(containing_class, class_name) + + # make an instance of a simple object (this one will do), for which we + # can change the __class__ later on. + nested_instance = _NestedClassGetter() + + # set the class of the instance, the __init__ will never be called on + # the class but the original state will be set later on by pickle. + nested_instance.__class__ = nested_class + return nested_instance + + +class _InstanceMethodPickler(object): + """ + Pickle cannot handle instancemethod saving. _InstanceMethodPickler + provides a solution to this. + """ + def __init__(self, instancemethod): + """Takes an instancemethod as its only argument.""" + self.parent_obj = instancemethod.im_self + self.instancemethod_name = instancemethod.im_func.__name__ + + def get_instancemethod(self): + return getattr(self.parent_obj, self.instancemethod_name) + + # Numpy > 1.6.x deprecates putmask in favor of the new copyto. # So long as we support versions 1.6.x and less, we need the # following local version of putmask. We choose to make a @@ -1861,9 +1844,51 @@ return np.copyto(a, values, where=mask) -if __name__=='__main__': - assert( allequal([1,1,1]) ) - assert(not allequal([1,1,0]) ) - assert( allequal([]) ) - assert( allequal(('a', 'a'))) - assert( not allequal(('a', 'b'))) +def _check_output(*popenargs, **kwargs): + r"""Run command with arguments and return its output as a byte + string. + + If the exit code was non-zero it raises a CalledProcessError. The + CalledProcessError object will have the return code in the + returncode + attribute and output in the output attribute. + + The arguments are the same as for the Popen constructor. Example:: + + >>> check_output(["ls", "-l", "/dev/null"]) + 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' + + The stdout argument is not allowed as it is used internally. + To capture standard error in the result, use stderr=STDOUT.:: + + >>> check_output(["/bin/sh", "-c", + ... "ls -l non_existent_file ; exit 0"], + ... stderr=STDOUT) + 'ls: non_existent_file: No such file or directory\n' + """ + if 'stdout' in kwargs: + raise ValueError('stdout argument not allowed, it will be overridden.') + process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs) + output, unused_err = process.communicate() + retcode = process.poll() + if retcode: + cmd = kwargs.get("args") + if cmd is None: + cmd = popenargs[0] + raise subprocess.CalledProcessError(retcode, cmd, output=output) + return output + + +# python2.7's subprocess provides a check_output method +if hasattr(subprocess, 'check_output'): + check_output = subprocess.check_output +else: + check_output = _check_output + + +if __name__ == '__main__': + assert(allequal([1, 1, 1])) + assert(not allequal([1, 1, 0])) + assert(allequal([])) + assert(allequal(('a', 'a'))) + assert(not allequal(('a', 'b'))) diff -Nru matplotlib-1.1.1/lib/matplotlib/cm.py matplotlib-1.2.0/lib/matplotlib/cm.py --- matplotlib-1.1.1/lib/matplotlib/cm.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/cm.py 2012-11-08 13:38:03.000000000 +0000 @@ -4,6 +4,7 @@ and a mixin class for adding color mapping functionality. """ +from __future__ import print_function, division import os @@ -79,7 +80,7 @@ # Precache the cmaps with ``lutsize = LUTSIZE`` ... # Use datad.keys() to also add the reversed ones added in the section above: -for cmapname in datad.keys(): +for cmapname in datad.iterkeys(): cmap_d[cmapname] = _generate_cmap(cmapname, LUTSIZE) locals().update(cmap_d) @@ -150,8 +151,8 @@ return cmap_d[name] elif name in datad: return _generate_cmap(name, lut) - else: - raise ValueError("Colormap %s is not recognized" % name) + + raise ValueError("Colormap %s is not recognized" % name) class ScalarMappable: """ @@ -182,33 +183,59 @@ self.colorbar = im, ax def to_rgba(self, x, alpha=None, bytes=False): - '''Return a normalized rgba array corresponding to *x*. If *x* - is already an rgb array, insert *alpha*; if it is already - rgba, return it unchanged. If *bytes* is True, return rgba as - 4 uint8s instead of 4 floats. - ''' - if alpha is None: - _alpha = 1.0 - else: - _alpha = alpha + """ + Return a normalized rgba array corresponding to *x*. + + In the normal case, *x* is a 1-D or 2-D sequence of scalars, and + the corresponding ndarray of rgba values will be returned, + based on the norm and colormap set for this ScalarMappable. + + There is one special case, for handling images that are already + rgb or rgba, such as might have been read from an image file. + If *x* is an ndarray with 3 dimensions, + and the last dimension is either 3 or 4, then it will be + treated as an rgb or rgba array, and no mapping will be done. + If the last dimension is 3, the *alpha* kwarg (defaulting to 1) + will be used to fill in the transparency. If the last dimension + is 4, the *alpha* kwarg is ignored; it does not + replace the pre-existing alpha. A ValueError will be raised + if the third dimension is other than 3 or 4. + + In either case, if *bytes* is *False* (default), the rgba + array will be floats in the 0-1 range; if it is *True*, + the returned rgba array will be uint8 in the 0 to 255 range. + + Note: this method assumes the input is well-behaved; it does + not check for anomalies such as *x* being a masked rgba + array, or being an integer type other than uint8, or being + a floating point rgba array with values outside the 0-1 range. + """ + # First check for special case, image input: try: if x.ndim == 3: if x.shape[2] == 3: + if alpha is None: + alpha = 1 if x.dtype == np.uint8: - _alpha = np.array(_alpha*255, np.uint8) + alpha = np.uint8(alpha * 255) m, n = x.shape[:2] xx = np.empty(shape=(m,n,4), dtype = x.dtype) xx[:,:,:3] = x - xx[:,:,3] = _alpha + xx[:,:,3] = alpha elif x.shape[2] == 4: xx = x else: raise ValueError("third dimension must be 3 or 4") if bytes and xx.dtype != np.uint8: xx = (xx * 255).astype(np.uint8) + if not bytes and xx.dtype == np.uint8: + xx = xx.astype(float) / 255 return xx except AttributeError: + # e.g., x is not an ndarray; so try mapping it pass + + # This is the normal case, mapping a scalar array: x = ma.asarray(x) x = self.norm(x) x = self.cmap(x, alpha=alpha, bytes=bytes) diff -Nru matplotlib-1.1.1/lib/matplotlib/collections.py matplotlib-1.2.0/lib/matplotlib/collections.py --- matplotlib-1.1.1/lib/matplotlib/collections.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/collections.py 2012-11-08 13:38:03.000000000 +0000 @@ -8,6 +8,7 @@ they are meant to be fast for common use cases (e.g. a large set of solid line segemnts) """ +from __future__ import print_function import warnings import numpy as np import numpy.ma as ma @@ -41,13 +42,19 @@ * *antialiaseds*: None * *offsets*: None * *transOffset*: transforms.IdentityTransform() + * *offset_position*: 'screen' (default) or 'data' * *norm*: None (optional for :class:`matplotlib.cm.ScalarMappable`) * *cmap*: None (optional for :class:`matplotlib.cm.ScalarMappable`) + * *hatch*: None *offsets* and *transOffset* are used to translate the patch after - rendering (default no offsets). + rendering (default no offsets). If offset_position is 'screen' + (default) the offset is applied after the master transform has + been applied, that is, the offsets are in screen coordinates. If + offset_position is 'data', the offset is applied before the master + transform, i.e., the offsets are in data coordinates. If any of *edgecolors*, *facecolors*, *linewidths*, *antialiaseds* are None, they default to their :data:`matplotlib.rcParams` patch @@ -76,7 +83,9 @@ norm = None, # optional for ScalarMappable cmap = None, # ditto pickradius = 5.0, + hatch=None, urls = None, + offset_position='screen', **kwargs ): """ @@ -94,7 +103,8 @@ self.set_antialiased(antialiaseds) self.set_pickradius(pickradius) self.set_urls(urls) - + self.set_hatch(hatch) + self.set_offset_position(offset_position) self._uniform_offsets = None self._offsets = np.array([], np.float_) @@ -146,9 +156,16 @@ def get_transforms(self): return self._transforms + def get_offset_transform(self): + t = self._transOffset + if (not isinstance(t, transforms.Transform) + and hasattr(t, '_as_mpl_transform')): + t = t._as_mpl_transform(self.axes) + return t + def get_datalim(self, transData): transform = self.get_transform() - transOffset = self._transOffset + transOffset = self.get_offset_transform() offsets = self._offsets paths = self.get_paths() @@ -182,7 +199,7 @@ """Point prep for drawing and hit testing""" transform = self.get_transform() - transOffset = self._transOffset + transOffset = self.get_offset_transform() offsets = self._offsets paths = self.get_paths() @@ -222,7 +239,7 @@ @allow_rasterization def draw(self, renderer): if not self.get_visible(): return - renderer.open_group(self.__class__.__name__) + renderer.open_group(self.__class__.__name__, self.get_gid()) self.update_scalarmappable() @@ -232,10 +249,14 @@ self._set_gc_clip(gc) gc.set_snap(self.get_snap()) + if self._hatch: + gc.set_hatch(self._hatch) + renderer.draw_path_collection( gc, transform.frozen(), paths, self.get_transforms(), offsets, transOffset, self.get_facecolor(), self.get_edgecolor(), - self._linewidths, self._linestyles, self._antialiaseds, self._urls) + self._linewidths, self._linestyles, self._antialiaseds, self._urls, + self._offset_position) gc.restore() renderer.close_group(self.__class__.__name__) @@ -291,6 +312,42 @@ def get_urls(self): return self._urls + def set_hatch(self, hatch): + """ + Set the hatching pattern + + *hatch* can be one of:: + + / - diagonal hatching + \ - back diagonal + | - vertical + - - horizontal + + - crossed + x - crossed diagonal + o - small circle + O - large circle + . - dots + * - stars + + Letters can be combined, in which case all the specified + hatchings are done. If same letter repeats, it increases the + density of hatching of that pattern. + + Hatching is supported in the PostScript, PDF, SVG and Agg + backends only. + + Unlike other properties such as linewidth and colors, hatching + can only be specified for the collection as a whole, not separately + for each member. + + ACCEPTS: [ '/' | '\\\\' | '|' | '-' | '+' | 'x' | 'o' | 'O' | '.' | '*' ] + """ + self._hatch = hatch + + def get_hatch(self): + 'Return the current hatching pattern' + return self._hatch + def set_offsets(self, offsets): """ Set the offsets for the collection. *offsets* can be a scalar @@ -316,6 +373,29 @@ else: return self._uniform_offsets + def set_offset_position(self, offset_position): + """ + Set how offsets are applied. If *offset_position* is 'screen' + (default) the offset is applied after the master transform has + been applied, that is, the offsets are in screen coordinates. + If offset_position is 'data', the offset is applied before the + master transform, i.e., the offsets are in data coordinates. + """ + if offset_position not in ('screen', 'data'): + raise ValueError("offset_position must be 'screen' or 'data'") + self._offset_position = offset_position + + def get_offset_position(self): + """ + Returns how offsets are applied for the collection. If + *offset_position* is 'screen', the offset is applied after the + master transform has been applied, that is, the offsets are in + screen coordinates. If offset_position is 'data', the offset + is applied before the master transform, i.e., the offsets are + in data coordinates. + """ + return self._offset_position + def set_linewidth(self, lw): """ Set the linewidth(s) for the collection. *lw* can be a scalar @@ -546,6 +626,7 @@ self._linewidths = other._linewidths self._linestyles = other._linestyles self._pickradius = other._pickradius + self._hatch = other._hatch # update_from for scalarmappable self._A = other._A @@ -1129,6 +1210,74 @@ for p in patches] self._paths = paths +class TriMesh(Collection): + """ + Class for the efficient drawing of a triangular mesh using + Gouraud shading. + + A triangular mesh is a :class:`~matplotlib.tri.Triangulation` + object. + """ + def __init__(self, triangulation, **kwargs): + Collection.__init__(self, **kwargs) + self._triangulation = triangulation; + self._shading = 'gouraud' + self._is_filled = True + + self._bbox = transforms.Bbox.unit() + + # Unfortunately this requires a copy, unless Triangulation + # was rewritten. + xy = np.hstack((triangulation.x.reshape(-1,1), + triangulation.y.reshape(-1,1))) + self._bbox.update_from_data_xy(xy) + + def get_paths(self): + if self._paths is None: + self.set_paths() + return self._paths + + def set_paths(self): + self._paths = self.convert_mesh_to_paths(self._triangulation) + + @staticmethod + def convert_mesh_to_paths(tri): + """ + Converts a given mesh into a sequence of + :class:`matplotlib.path.Path` objects for easier rendering by + backends that do not directly support meshes. + + This function is primarily of use to backend implementers. + """ + Path = mpath.Path + triangles = tri.get_masked_triangles() + verts = np.concatenate((tri.x[triangles][...,np.newaxis], + tri.y[triangles][...,np.newaxis]), axis=2) + return [Path(x) for x in verts] + + @allow_rasterization + def draw(self, renderer): + if not self.get_visible(): return + renderer.open_group(self.__class__.__name__) + transform = self.get_transform() + + # Get a list of triangles and the color at each vertex. + tri = self._triangulation + triangles = tri.get_masked_triangles() + + verts = np.concatenate((tri.x[triangles][...,np.newaxis], + tri.y[triangles][...,np.newaxis]), axis=2) + + self.update_scalarmappable() + colors = self._facecolors[triangles]; + + gc = renderer.new_gc() + self._set_gc_clip(gc) + gc.set_linewidth(self.get_linewidth()[0]) + renderer.draw_gouraud_triangles(gc, verts, colors, transform.frozen()) + gc.restore() + renderer.close_group(self.__class__.__name__) + class QuadMesh(Collection): """ @@ -1159,15 +1308,14 @@ at (0, 1), then at (0, 2) .. (0, meshWidth), (1, 0), (1, 1), and so on. - *shading* may be 'flat', 'faceted' or 'gouraud' + *shading* may be 'flat', or 'gouraud' """ - def __init__(self, meshWidth, meshHeight, coordinates, showedges, + def __init__(self, meshWidth, meshHeight, coordinates, antialiased=True, shading='flat', **kwargs): Collection.__init__(self, **kwargs) self._meshWidth = meshWidth self._meshHeight = meshHeight self._coordinates = coordinates - self._showedges = showedges self._antialiased = antialiased self._shading = shading @@ -1264,9 +1412,9 @@ @allow_rasterization def draw(self, renderer): if not self.get_visible(): return - renderer.open_group(self.__class__.__name__) + renderer.open_group(self.__class__.__name__, self.get_gid()) transform = self.get_transform() - transOffset = self._transOffset + transOffset = self.get_offset_transform() offsets = self._offsets if self.have_units(): @@ -1307,7 +1455,7 @@ renderer.draw_quad_mesh( gc, transform.frozen(), self._meshWidth, self._meshHeight, coordinates, offsets, transOffset, self.get_facecolor(), - self._antialiased, self._showedges) + self._antialiased, self.get_edgecolors()) gc.restore() renderer.close_group(self.__class__.__name__) @@ -1315,7 +1463,7 @@ patchstr = artist.kwdoc(Collection) -for k in ('QuadMesh', 'PolyCollection', 'BrokenBarHCollection', +for k in ('QuadMesh', 'TriMesh', 'PolyCollection', 'BrokenBarHCollection', 'RegularPolyCollection', 'PathCollection', 'StarPolygonCollection', 'PatchCollection', 'CircleCollection', 'Collection',): diff -Nru matplotlib-1.1.1/lib/matplotlib/colorbar.py matplotlib-1.2.0/lib/matplotlib/colorbar.py --- matplotlib-1.1.1/lib/matplotlib/colorbar.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/colorbar.py 2012-11-08 13:38:03.000000000 +0000 @@ -18,23 +18,25 @@ is a thin wrapper over :meth:`~matplotlib.figure.Figure.colorbar`. ''' +from __future__ import print_function import warnings import numpy as np + import matplotlib as mpl -import matplotlib.colors as colors -import matplotlib.cm as cm -from matplotlib import docstring -import matplotlib.ticker as ticker +import matplotlib.artist as martist import matplotlib.cbook as cbook -import matplotlib.lines as lines -import matplotlib.patches as patches import matplotlib.collections as collections +import matplotlib.colors as colors import matplotlib.contour as contour -import matplotlib.artist as martist - +import matplotlib.cm as cm import matplotlib.gridspec as gridspec +import matplotlib.lines as lines +import matplotlib.patches as mpatches +import matplotlib.path as mpath +import matplotlib.ticker as ticker +from matplotlib import docstring make_axes_kw_doc = ''' @@ -57,13 +59,29 @@ colormap_kw_doc = ''' - =========== ==================================================== + ============ ==================================================== Property Description - =========== ==================================================== + ============ ==================================================== *extend* [ 'neither' | 'both' | 'min' | 'max' ] If not 'neither', make pointed end(s) for out-of- range values. These are set for a given colormap using the colormap set_under and set_over methods. + *extendfrac* [ *None* | 'auto' | length | lengths ] + If set to *None*, both the minimum and maximum + triangular colorbar extensions with have a length of + 5% of the interior colorbar length (this is the + default setting). If set to 'auto', makes the + triangular colorbar extensions the same lengths as + the interior boxes (when *spacing* is set to + 'uniform') or the same lengths as the respective + adjacent interior boxes (when *spacing* is set to + 'proportional'). If a scalar, indicates the length + of both the minimum and maximum triangular colorbar + extensions as a fraction of the interior colorbar + length. A two-element sequence of fractions may also + be given, indicating the lengths of the minimum and + maximum colorbar extensions respectively as a + fraction of the interior colorbar length. *spacing* [ 'uniform' | 'proportional' ] Uniform spacing gives each discrete color the same space; proportional makes the space proportional to @@ -80,7 +98,7 @@ given instead. *drawedges* [ False | True ] If true, draw lines at color boundaries. - =========== ==================================================== + ============ ==================================================== The following will probably be useful only in the context of indexed colors (that is, when the mappable has norm=NoNorm()), @@ -133,7 +151,7 @@ False | If *cax* is None, a new *cax* is created as an instance of Axes. If *ax* is an instance of Subplot and *use_gridspec* is True, *cax* is created as an instance of Subplot using the - grid_spec module. + grid_spec module. Additional keyword arguments are of two kinds: @@ -156,6 +174,19 @@ the axes objects in which the mappable and the colorbar are drawn. In this case, do not use any of the axes properties kwargs. +It is known that some vector graphics viewer (svg and pdf) renders white gaps +between segments of the colorbar. This is due to bugs in the viewers not +matplotlib. As a workaround the colorbar can be rendered with overlapping +segments:: + + cbar = colorbar() + cbar.solids.set_edgecolor("face") + draw() + +However this has negative consequences in other circumstances. Particularly with +semi transparent images (alpha < 1) and colorbar extensions and is not enabled +by default see (issue #1188). + returns: :class:`~matplotlib.colorbar.Colorbar` instance; see also its base class, :class:`~matplotlib.colorbar.ColorbarBase`. Call the @@ -167,6 +198,12 @@ docstring.interpd.update(colorbar_doc=colorbar_doc) +def _set_ticks_on_axis_warn(*args, **kw): + # a top level function which gets put in at the axes' + # set_xticks set_yticks by _patch_ax + warnings.warn("Use the colorbar set_ticks() method instead.") + + class ColorbarBase(cm.ScalarMappable): ''' Draw a colorbar in an existing axes. @@ -194,7 +231,8 @@ the Axes instance in which the colorbar is drawn :attr:`lines` - a LineCollection if lines were drawn, otherwise None + a list of LineCollection if lines were drawn, otherwise + an empty list :attr:`dividers` a LineCollection if *drawedges* is True, otherwise None @@ -202,10 +240,10 @@ Useful public methods are :meth:`set_label` and :meth:`add_lines`. ''' - _slice_dict = {'neither': slice(0,1000000), - 'both': slice(1,-1), - 'min': slice(1,1000000), - 'max': slice(0,-1)} + _slice_dict = {'neither': slice(0, None), + 'both': slice(1, -1), + 'min': slice(1, None), + 'max': slice(0, -1)} def __init__(self, ax, cmap=None, norm=None, @@ -219,6 +257,7 @@ format=None, drawedges=False, filled=True, + extendfrac=None, ): self.ax = ax self._patch_ax() @@ -234,8 +273,9 @@ self.orientation = orientation self.drawedges = drawedges self.filled = filled + self.extendfrac = extendfrac self.solids = None - self.lines = None + self.lines = list() self.outline = None self.patch = None self.dividers = None @@ -257,12 +297,19 @@ self.config_axis() self.draw_all() - def _patch_ax(self): - def _warn(*args, **kw): - warnings.warn("Use the colorbar set_ticks() method instead.") + def _extend_lower(self): + """Returns whether the lower limit is open ended.""" + return self.extend in ('both', 'min') + + def _extend_upper(self): + """Returns whether the uper limit is open ended.""" + return self.extend in ('both', 'max') - self.ax.set_xticks = _warn - self.ax.set_yticks = _warn + def _patch_ax(self): + # bind some methods to the axes to warn users + # against using those methods. + self.ax.set_xticks = _set_ticks_on_axis_warn + self.ax.set_yticks = _set_ticks_on_axis_warn def draw_all(self): ''' @@ -272,7 +319,7 @@ self._process_values() self._find_range() X, Y = self._mesh() - C = self._values[:,np.newaxis] + C = self._values[:, np.newaxis] self._config_axes(X, Y) if self.filled: self._add_solids(X, Y, C) @@ -353,7 +400,7 @@ c = mpl.rcParams['axes.facecolor'] if self.patch is not None: self.patch.remove() - self.patch = patches.Polygon(xy, edgecolor=c, + self.patch = mpatches.Polygon(xy, edgecolor=c, facecolor=c, linewidth=0.01, zorder=-1) @@ -372,7 +419,7 @@ ''' Label the long axis of the colorbar ''' - self._label = label + self._label = '%s' % (label, ) self._labelkw = kw self._set_label() @@ -400,21 +447,23 @@ # Using the non-array form of these line segments is much # simpler than making them into arrays. if self.orientation == 'vertical': - return [zip(X[i], Y[i]) for i in range(1, N-1)] + return [zip(X[i], Y[i]) for i in xrange(1, N-1)] else: - return [zip(Y[i], X[i]) for i in range(1, N-1)] + return [zip(Y[i], X[i]) for i in xrange(1, N-1)] def _add_solids(self, X, Y, C): ''' - Draw the colors using :meth:`~matplotlib.axes.Axes.pcolor`; + Draw the colors using :meth:`~matplotlib.axes.Axes.pcolormesh`; optionally add separators. ''' if self.orientation == 'vertical': args = (X, Y, C) else: args = (np.transpose(Y), np.transpose(X), np.transpose(C)) - kw = {'cmap':self.cmap, 'norm':self.norm, - 'alpha':self.alpha,} + kw = dict(cmap=self.cmap, + norm=self.norm, + alpha=self.alpha, + edgecolors='None') # Save, set, and restore hold state to keep pcolor from # clearing the axes. Ordinarily this will not be needed, # since the axes object should already have hold set. @@ -437,25 +486,38 @@ ) self.ax.add_collection(self.dividers) - def add_lines(self, levels, colors, linewidths): + def add_lines(self, levels, colors, linewidths, erase=True): ''' Draw lines on the colorbar. + + *colors* and *linewidths* must be scalars or + sequences the same length as *levels*. + + Set *erase* to False to add lines without first + removing any previously added lines. ''' - N = len(levels) - dummy, y = self._locate(levels) - if len(y) <> N: - raise ValueError("levels are outside colorbar range") + y = self._locate(levels) + nlevs = len(levels) + igood = (y < 1.001) & (y > -0.001) + y = y[igood] + if cbook.iterable(colors): + colors = np.asarray(colors)[igood] + if cbook.iterable(linewidths): + linewidths = np.asarray(linewidths)[igood] + N = len(y) x = np.array([0.0, 1.0]) X, Y = np.meshgrid(x,y) if self.orientation == 'vertical': - xy = [zip(X[i], Y[i]) for i in range(N)] + xy = [zip(X[i], Y[i]) for i in xrange(N)] else: - xy = [zip(Y[i], X[i]) for i in range(N)] + xy = [zip(Y[i], X[i]) for i in xrange(N)] col = collections.LineCollection(xy, linewidths=linewidths) - if self.lines: - self.lines.remove() - self.lines = col + if erase and self.lines: + for lc in self.lines: + lc.remove() + self.lines = [] + self.lines.append(col) col.set_color(colors) self.ax.add_collection(col) @@ -487,18 +549,18 @@ intv = self._values[0], self._values[-1] else: intv = self.vmin, self.vmax - locator.create_dummy_axis() - formatter.create_dummy_axis() + locator.create_dummy_axis(minpos=intv[0]) + formatter.create_dummy_axis(minpos=intv[0]) locator.set_view_interval(*intv) locator.set_data_interval(*intv) formatter.set_view_interval(*intv) formatter.set_data_interval(*intv) - # the dummy axis is expecting a minpos - locator.axis.get_minpos = lambda : intv[0] - formatter.axis.get_minpos = lambda : intv[0] b = np.array(locator()) - b, ticks = self._locate(b) + ticks = self._locate(b) + inrange = (ticks > -0.001) & (ticks < 1.001) + ticks = ticks[inrange] + b = b[inrange] formatter.set_locs(b) ticklabels = [formatter(t, i) for i, t in enumerate(b)] offset_string = formatter.get_offset() @@ -539,26 +601,26 @@ b = self._uniform_y(self.cmap.N+1) * self.cmap.N - 0.5 v = np.zeros((len(b)-1,), dtype=np.int16) v[self._inside] = np.arange(self.cmap.N, dtype=np.int16) - if self.extend in ('both', 'min'): + if self._extend_lower(): v[0] = -1 - if self.extend in ('both', 'max'): + if self._extend_upper(): v[-1] = self.cmap.N self._boundaries = b self._values = v return elif isinstance(self.norm, colors.BoundaryNorm): b = list(self.norm.boundaries) - if self.extend in ('both', 'min'): + if self._extend_lower(): b = [b[0]-1] + b - if self.extend in ('both', 'max'): + if self._extend_upper(): b = b + [b[-1] + 1] b = np.array(b) v = np.zeros((len(b)-1,), dtype=float) bi = self.norm.boundaries v[self._inside] = 0.5*(bi[:-1] + bi[1:]) - if self.extend in ('both', 'min'): + if self._extend_lower(): v[0] = b[0] - 1 - if self.extend in ('both', 'max'): + if self._extend_upper(): v[-1] = b[-1] + 1 self._boundaries = b self._values = v @@ -568,9 +630,9 @@ self.norm.vmin = 0 self.norm.vmax = 1 b = self.norm.inverse(self._uniform_y(self.cmap.N+1)) - if self.extend in ('both', 'min'): + if self._extend_lower(): b[0] = b[0] - 1 - if self.extend in ('both', 'max'): + if self._extend_upper(): b[-1] = b[-1] + 1 self._process_values(b) @@ -604,6 +666,35 @@ N += 1 return N + def _get_extension_lengths(self, frac, automin, automax, default=0.05): + ''' + Get the lengths of colorbar extensions. + + A helper method for _uniform_y and _proportional_y. + ''' + # Set the default value. + extendlength = np.array([default, default]) + if isinstance(frac, str): + if frac.lower() == 'auto': + # Use the provided values when 'auto' is required. + extendlength[0] = automin + extendlength[1] = automax + else: + # Any other string is invalid. + raise ValueError('invalid value for extendfrac') + elif frac is not None: + try: + # Try to set min and max extension fractions directly. + extendlength[:] = frac + # If frac is a sequence contaning None then NaN may + # be encountered. This is an error. + if np.isnan(extendlength).any(): + raise ValueError() + except (TypeError, ValueError): + # Raise an error on encountering an invalid value for frac. + raise ValueError('invalid value for extendfrac') + return extendlength + def _uniform_y(self, N): ''' Return colorbar data coordinates for *N* uniformly @@ -612,16 +703,19 @@ if self.extend == 'neither': y = np.linspace(0, 1, N) else: + automin = automax = 1. / (N - 1.) + extendlength = self._get_extension_lengths(self.extendfrac, + automin, automax, default=0.05) if self.extend == 'both': y = np.zeros(N + 2, 'd') - y[0] = -0.05 - y[-1] = 1.05 + y[0] = 0. - extendlength[0] + y[-1] = 1. + extendlength[1] elif self.extend == 'min': y = np.zeros(N + 1, 'd') - y[0] = -0.05 + y[0] = 0. - extendlength[0] else: y = np.zeros(N + 1, 'd') - y[-1] = 1.05 + y[-1] = 1. + extendlength[1] y[self._inside] = np.linspace(0, 1, N) return y @@ -636,10 +730,27 @@ y = y / (self._boundaries[-1] - self._boundaries[0]) else: y = self.norm(self._boundaries.copy()) + if self.extend == 'min': + # Exclude leftmost interval of y. + clen = y[-1] - y[1] + automin = (y[2] - y[1]) / clen + automax = (y[-1] - y[-2]) / clen + elif self.extend == 'max': + # Exclude rightmost interval in y. + clen = y[-2] - y[0] + automin = (y[1] - y[0]) / clen + automax = (y[-2] - y[-3]) / clen + else: + # Exclude leftmost and rightmost intervals in y. + clen = y[-2] - y[1] + automin = (y[2] - y[1]) / clen + automax = (y[-2] - y[-3]) / clen + extendlength = self._get_extension_lengths(self.extendfrac, + automin, automax, default=0.05) if self.extend in ('both', 'min'): - y[0] = -0.05 + y[0] = 0. - extendlength[0] if self.extend in ('both', 'max'): - y[-1] = 1.05 + y[-1] = 1. + extendlength[1] yi = y[self._inside] norm = colors.Normalize(yi[0], yi[-1]) y[self._inside] = norm(yi) @@ -659,49 +770,49 @@ y = self._proportional_y() self._y = y X, Y = np.meshgrid(x,y) - if self.extend in ('min', 'both'): - X[0,:] = 0.5 - if self.extend in ('max', 'both'): - X[-1,:] = 0.5 + if self._extend_lower(): + X[0, :] = 0.5 + if self._extend_upper(): + X[-1, :] = 0.5 return X, Y def _locate(self, x): ''' - Given a possible set of color data values, return the ones - within range, together with their corresponding colorbar - data coordinates. + Given a set of color data values, return their + corresponding colorbar data coordinates. ''' if isinstance(self.norm, (colors.NoNorm, colors.BoundaryNorm)): b = self._boundaries xn = x - xout = x else: # Do calculations using normalized coordinates so # as to make the interpolation more accurate. b = self.norm(self._boundaries, clip=False).filled() - # We do our own clipping so that we can allow a tiny - # bit of slop in the end point ticks to allow for - # floating point errors. xn = self.norm(x, clip=False).filled() - in_cond = (xn > -0.001) & (xn < 1.001) - xn = np.compress(in_cond, xn) - xout = np.compress(in_cond, x) - # The rest is linear interpolation with clipping. + # The rest is linear interpolation with extrapolation at ends. y = self._y N = len(b) - ii = np.minimum(np.searchsorted(b, xn), N-1) - i0 = np.maximum(ii - 1, 0) + ii = np.searchsorted(b, xn) + i0 = ii - 1 + itop = (ii == N) + ibot = (ii == 0) + i0[itop] -= 1 + ii[itop] -= 1 + i0[ibot] += 1 + ii[ibot] += 1 + #db = b[ii] - b[i0] db = np.take(b, ii) - np.take(b, i0) - db = np.where(i0==ii, 1.0, db) #dy = y[ii] - y[i0] dy = np.take(y, ii) - np.take(y, i0) z = np.take(y, i0) + (xn-np.take(b,i0))*dy/db - return xout, z + + return z def set_alpha(self, alpha): self.alpha = alpha + class Colorbar(ColorbarBase): """ This class connects a :class:`ColorbarBase` to a @@ -742,11 +853,25 @@ ColorbarBase.__init__(self, ax, **kw) + def on_mappable_changed(self, mappable): + """ + Updates this colorbar to match the mappable's properties. - def add_lines(self, CS): + Typically this is automatically registered as an event handler + by :func:`colorbar_factory` and should not be called manually. + + """ + self.set_cmap(mappable.get_cmap()) + self.set_clim(mappable.get_clim()) + self.update_normal(mappable) + + def add_lines(self, CS, erase=True): ''' Add the lines from a non-filled :class:`~matplotlib.contour.ContourSet` to the colorbar. + + Set *erase* to False if these lines should be added to + any pre-existing lines. ''' if not isinstance(CS, contour.ContourSet) or CS.filled: raise ValueError('add_lines is only for a ContourSet of lines') @@ -760,7 +885,8 @@ #tcolors = [col.get_colors()[0] for col in CS.collections] #tlinewidths = [col.get_linewidth()[0] for lw in CS.collections] #print 'tlinewidths:', tlinewidths - ColorbarBase.add_lines(self, CS.levels, tcolors, tlinewidths) + ColorbarBase.add_lines(self, CS.levels, tcolors, tlinewidths, + erase=erase) def update_normal(self, mappable): ''' @@ -793,7 +919,7 @@ self.outline = None self.patch = None self.solids = None - self.lines = None + self.lines = list() self.dividers = None self.set_alpha(mappable.get_alpha()) self.cmap = mappable.cmap @@ -870,7 +996,7 @@ * *make_axes* creates an instance of Axes. *make_axes_gridspec* creates an instance of Subplot. - + * *make_axes* updates the position of the parent. *make_axes_gridspec* replaces the grid_spec attribute of the parent with a new one. @@ -951,3 +1077,103 @@ cax = fig.add_subplot(gs2[1]) cax.set_aspect(aspect, anchor=anchor, adjustable='box') return cax, kw + + +class ColorbarPatch(Colorbar): + """ + A Colorbar which is created using :class:`~matplotlib.patches.Patch` + rather than the default :func:`~matplotlib.axes.pcolor`. + + It uses a list of Patch instances instead of a + :class:`~matplotlib.collections.PatchCollection` because the + latter does not allow the hatch pattern to vary among the + members of the collection. + """ + def __init__(self, ax, mappable, **kw): + # we do not want to override the behaviour of solids + # so add a new attribute which will be a list of the + # colored patches in the colorbar + self.solids_patches = [] + Colorbar.__init__(self, ax, mappable, **kw) + + def _add_solids(self, X, Y, C): + """ + Draw the colors using :class:`~matplotlib.patches.Patch`; + optionally add separators. + """ + # Save, set, and restore hold state to keep pcolor from + # clearing the axes. Ordinarily this will not be needed, + # since the axes object should already have hold set. + _hold = self.ax.ishold() + self.ax.hold(True) + + kw = {'alpha':self.alpha,} + + n_segments = len(C) + + # ensure there are sufficent hatches + hatches = self.mappable.hatches * n_segments + + patches = [] + for i in xrange(len(X)-1): + val = C[i][0] + hatch = hatches[i] + + xy = np.array([[X[i][0], Y[i][0]], [X[i][1], Y[i][0]], + [X[i+1][1], Y[i+1][0]], [X[i+1][0], Y[i+1][1]]]) + + if self.orientation == 'horizontal': + # if horizontal swap the xs and ys + xy = xy[..., ::-1] + + patch = mpatches.PathPatch(mpath.Path(xy), + facecolor=self.cmap(self.norm(val)), + hatch=hatch, + edgecolor='none', linewidth=0, + antialiased=False, **kw + ) + + self.ax.add_patch(patch) + patches.append(patch) + + if self.solids_patches: + for solid in self.solids_patches: + solid.remove() + + self.solids_patches = patches + + if self.dividers is not None: + self.dividers.remove() + self.dividers = None + + if self.drawedges: + self.dividers = collections.LineCollection(self._edges(X,Y), + colors=(mpl.rcParams['axes.edgecolor'],), + linewidths=(0.5*mpl.rcParams['axes.linewidth'],) + ) + self.ax.add_collection(self.dividers) + + self.ax.hold(_hold) + + +def colorbar_factory(cax, mappable, **kwargs): + """ + Creates a colorbar on the given axes for the given mappable. + + Typically, for automatic colorbar placement given only a mappable use + :meth:`~matplotlib.figure.Figure.colorbar`. + + """ + # if the given mappable is a contourset with any hatching, use + # ColorbarPatch else use Colorbar + if (isinstance(mappable, contour.ContourSet) \ + and any([hatch is not None for hatch in mappable.hatches])): + cb = ColorbarPatch(cax, mappable, **kwargs) + else: + cb = Colorbar(cax, mappable, **kwargs) + + mappable.callbacksSM.connect('changed', cb.on_mappable_changed) + mappable.set_colorbar(cb, cax) + + return cb + diff -Nru matplotlib-1.1.1/lib/matplotlib/colors.py matplotlib-1.2.0/lib/matplotlib/colors.py --- matplotlib-1.1.1/lib/matplotlib/colors.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/colors.py 2012-11-08 13:38:03.000000000 +0000 @@ -5,16 +5,15 @@ range 0-1. This module includes functions and classes for color specification -conversions, and for mapping numbers to colors in a 1-D array of -colors called a colormap. Colormapping typically involves two steps: -a data array is first mapped onto the range 0-1 using an instance -of :class:`Normalize` or of a subclass; then this number in the 0-1 -range is mapped to a color using an instance of a subclass of -:class:`Colormap`. Two are provided here: -:class:`LinearSegmentedColormap`, which is used to generate all -the built-in colormap instances, but is also useful for making -custom colormaps, and :class:`ListedColormap`, which is used for -generating a custom colormap from a list of color specifications. +conversions, and for mapping numbers to colors in a 1-D array of colors called +a colormap. Colormapping typically involves two steps: a data array is first +mapped onto the range 0-1 using an instance of :class:`Normalize` or of a +subclass; then this number in the 0-1 range is mapped to a color using an +instance of a subclass of :class:`Colormap`. Two are provided here: +:class:`LinearSegmentedColormap`, which is used to generate all the built-in +colormap instances, but is also useful for making custom colormaps, and +:class:`ListedColormap`, which is used for generating a custom colormap from a +list of color specifications. The module also provides a single instance, *colorConverter*, of the :class:`ColorConverter` class providing methods for converting single @@ -23,14 +22,14 @@ Commands which take color arguments can use several formats to specify the colors. For the basic builtin colors, you can use a single letter - - b : blue - - g : green - - r : red - - c : cyan - - m : magenta - - y : yellow - - k : black - - w : white + - b: blue + - g: green + - r: red + - c: cyan + - m: magenta + - y: yellow + - k: black + - w: white Gray shades can be given as a string encoding a float in the 0-1 range, e.g.:: @@ -48,6 +47,7 @@ Finally, legal html names for colors, like 'red', 'burlywood' and 'chartreuse' are supported. """ +from __future__ import print_function, division import re import numpy as np from numpy import ma @@ -56,157 +56,158 @@ parts = np.__version__.split('.') NP_MAJOR, NP_MINOR = map(int, parts[:2]) # true if clip supports the out kwarg -NP_CLIP_OUT = NP_MAJOR>=1 and NP_MINOR>=2 +NP_CLIP_OUT = NP_MAJOR >= 1 and NP_MINOR >= 2 cnames = { - 'aliceblue' : '#F0F8FF', - 'antiquewhite' : '#FAEBD7', - 'aqua' : '#00FFFF', - 'aquamarine' : '#7FFFD4', - 'azure' : '#F0FFFF', - 'beige' : '#F5F5DC', - 'bisque' : '#FFE4C4', - 'black' : '#000000', - 'blanchedalmond' : '#FFEBCD', - 'blue' : '#0000FF', - 'blueviolet' : '#8A2BE2', - 'brown' : '#A52A2A', - 'burlywood' : '#DEB887', - 'cadetblue' : '#5F9EA0', - 'chartreuse' : '#7FFF00', - 'chocolate' : '#D2691E', - 'coral' : '#FF7F50', - 'cornflowerblue' : '#6495ED', - 'cornsilk' : '#FFF8DC', - 'crimson' : '#DC143C', - 'cyan' : '#00FFFF', - 'darkblue' : '#00008B', - 'darkcyan' : '#008B8B', - 'darkgoldenrod' : '#B8860B', - 'darkgray' : '#A9A9A9', - 'darkgreen' : '#006400', - 'darkkhaki' : '#BDB76B', - 'darkmagenta' : '#8B008B', - 'darkolivegreen' : '#556B2F', - 'darkorange' : '#FF8C00', - 'darkorchid' : '#9932CC', - 'darkred' : '#8B0000', - 'darksalmon' : '#E9967A', - 'darkseagreen' : '#8FBC8F', - 'darkslateblue' : '#483D8B', - 'darkslategray' : '#2F4F4F', - 'darkturquoise' : '#00CED1', - 'darkviolet' : '#9400D3', - 'deeppink' : '#FF1493', - 'deepskyblue' : '#00BFFF', - 'dimgray' : '#696969', - 'dodgerblue' : '#1E90FF', - 'firebrick' : '#B22222', - 'floralwhite' : '#FFFAF0', - 'forestgreen' : '#228B22', - 'fuchsia' : '#FF00FF', - 'gainsboro' : '#DCDCDC', - 'ghostwhite' : '#F8F8FF', - 'gold' : '#FFD700', - 'goldenrod' : '#DAA520', - 'gray' : '#808080', - 'green' : '#008000', - 'greenyellow' : '#ADFF2F', - 'honeydew' : '#F0FFF0', - 'hotpink' : '#FF69B4', - 'indianred' : '#CD5C5C', - 'indigo' : '#4B0082', - 'ivory' : '#FFFFF0', - 'khaki' : '#F0E68C', - 'lavender' : '#E6E6FA', - 'lavenderblush' : '#FFF0F5', - 'lawngreen' : '#7CFC00', - 'lemonchiffon' : '#FFFACD', - 'lightblue' : '#ADD8E6', - 'lightcoral' : '#F08080', - 'lightcyan' : '#E0FFFF', - 'lightgoldenrodyellow' : '#FAFAD2', - 'lightgreen' : '#90EE90', - 'lightgray' : '#D3D3D3', - 'lightpink' : '#FFB6C1', - 'lightsalmon' : '#FFA07A', - 'lightseagreen' : '#20B2AA', - 'lightskyblue' : '#87CEFA', - 'lightslategray' : '#778899', - 'lightsteelblue' : '#B0C4DE', - 'lightyellow' : '#FFFFE0', - 'lime' : '#00FF00', - 'limegreen' : '#32CD32', - 'linen' : '#FAF0E6', - 'magenta' : '#FF00FF', - 'maroon' : '#800000', - 'mediumaquamarine' : '#66CDAA', - 'mediumblue' : '#0000CD', - 'mediumorchid' : '#BA55D3', - 'mediumpurple' : '#9370DB', - 'mediumseagreen' : '#3CB371', - 'mediumslateblue' : '#7B68EE', - 'mediumspringgreen' : '#00FA9A', - 'mediumturquoise' : '#48D1CC', - 'mediumvioletred' : '#C71585', - 'midnightblue' : '#191970', - 'mintcream' : '#F5FFFA', - 'mistyrose' : '#FFE4E1', - 'moccasin' : '#FFE4B5', - 'navajowhite' : '#FFDEAD', - 'navy' : '#000080', - 'oldlace' : '#FDF5E6', - 'olive' : '#808000', - 'olivedrab' : '#6B8E23', - 'orange' : '#FFA500', - 'orangered' : '#FF4500', - 'orchid' : '#DA70D6', - 'palegoldenrod' : '#EEE8AA', - 'palegreen' : '#98FB98', - 'palevioletred' : '#AFEEEE', - 'papayawhip' : '#FFEFD5', - 'peachpuff' : '#FFDAB9', - 'peru' : '#CD853F', - 'pink' : '#FFC0CB', - 'plum' : '#DDA0DD', - 'powderblue' : '#B0E0E6', - 'purple' : '#800080', - 'red' : '#FF0000', - 'rosybrown' : '#BC8F8F', - 'royalblue' : '#4169E1', - 'saddlebrown' : '#8B4513', - 'salmon' : '#FA8072', - 'sandybrown' : '#FAA460', - 'seagreen' : '#2E8B57', - 'seashell' : '#FFF5EE', - 'sienna' : '#A0522D', - 'silver' : '#C0C0C0', - 'skyblue' : '#87CEEB', - 'slateblue' : '#6A5ACD', - 'slategray' : '#708090', - 'snow' : '#FFFAFA', - 'springgreen' : '#00FF7F', - 'steelblue' : '#4682B4', - 'tan' : '#D2B48C', - 'teal' : '#008080', - 'thistle' : '#D8BFD8', - 'tomato' : '#FF6347', - 'turquoise' : '#40E0D0', - 'violet' : '#EE82EE', - 'wheat' : '#F5DEB3', - 'white' : '#FFFFFF', - 'whitesmoke' : '#F5F5F5', - 'yellow' : '#FFFF00', - 'yellowgreen' : '#9ACD32', + 'aliceblue': '#F0F8FF', + 'antiquewhite': '#FAEBD7', + 'aqua': '#00FFFF', + 'aquamarine': '#7FFFD4', + 'azure': '#F0FFFF', + 'beige': '#F5F5DC', + 'bisque': '#FFE4C4', + 'black': '#000000', + 'blanchedalmond': '#FFEBCD', + 'blue': '#0000FF', + 'blueviolet': '#8A2BE2', + 'brown': '#A52A2A', + 'burlywood': '#DEB887', + 'cadetblue': '#5F9EA0', + 'chartreuse': '#7FFF00', + 'chocolate': '#D2691E', + 'coral': '#FF7F50', + 'cornflowerblue': '#6495ED', + 'cornsilk': '#FFF8DC', + 'crimson': '#DC143C', + 'cyan': '#00FFFF', + 'darkblue': '#00008B', + 'darkcyan': '#008B8B', + 'darkgoldenrod': '#B8860B', + 'darkgray': '#A9A9A9', + 'darkgreen': '#006400', + 'darkkhaki': '#BDB76B', + 'darkmagenta': '#8B008B', + 'darkolivegreen': '#556B2F', + 'darkorange': '#FF8C00', + 'darkorchid': '#9932CC', + 'darkred': '#8B0000', + 'darksalmon': '#E9967A', + 'darkseagreen': '#8FBC8F', + 'darkslateblue': '#483D8B', + 'darkslategray': '#2F4F4F', + 'darkturquoise': '#00CED1', + 'darkviolet': '#9400D3', + 'deeppink': '#FF1493', + 'deepskyblue': '#00BFFF', + 'dimgray': '#696969', + 'dodgerblue': '#1E90FF', + 'firebrick': '#B22222', + 'floralwhite': '#FFFAF0', + 'forestgreen': '#228B22', + 'fuchsia': '#FF00FF', + 'gainsboro': '#DCDCDC', + 'ghostwhite': '#F8F8FF', + 'gold': '#FFD700', + 'goldenrod': '#DAA520', + 'gray': '#808080', + 'green': '#008000', + 'greenyellow': '#ADFF2F', + 'honeydew': '#F0FFF0', + 'hotpink': '#FF69B4', + 'indianred': '#CD5C5C', + 'indigo': '#4B0082', + 'ivory': '#FFFFF0', + 'khaki': '#F0E68C', + 'lavender': '#E6E6FA', + 'lavenderblush': '#FFF0F5', + 'lawngreen': '#7CFC00', + 'lemonchiffon': '#FFFACD', + 'lightblue': '#ADD8E6', + 'lightcoral': '#F08080', + 'lightcyan': '#E0FFFF', + 'lightgoldenrodyellow': '#FAFAD2', + 'lightgreen': '#90EE90', + 'lightgray': '#D3D3D3', + 'lightpink': '#FFB6C1', + 'lightsalmon': '#FFA07A', + 'lightseagreen': '#20B2AA', + 'lightskyblue': '#87CEFA', + 'lightslategray': '#778899', + 'lightsteelblue': '#B0C4DE', + 'lightyellow': '#FFFFE0', + 'lime': '#00FF00', + 'limegreen': '#32CD32', + 'linen': '#FAF0E6', + 'magenta': '#FF00FF', + 'maroon': '#800000', + 'mediumaquamarine': '#66CDAA', + 'mediumblue': '#0000CD', + 'mediumorchid': '#BA55D3', + 'mediumpurple': '#9370DB', + 'mediumseagreen': '#3CB371', + 'mediumslateblue': '#7B68EE', + 'mediumspringgreen': '#00FA9A', + 'mediumturquoise': '#48D1CC', + 'mediumvioletred': '#C71585', + 'midnightblue': '#191970', + 'mintcream': '#F5FFFA', + 'mistyrose': '#FFE4E1', + 'moccasin': '#FFE4B5', + 'navajowhite': '#FFDEAD', + 'navy': '#000080', + 'oldlace': '#FDF5E6', + 'olive': '#808000', + 'olivedrab': '#6B8E23', + 'orange': '#FFA500', + 'orangered': '#FF4500', + 'orchid': '#DA70D6', + 'palegoldenrod': '#EEE8AA', + 'palegreen': '#98FB98', + 'palevioletred': '#AFEEEE', + 'papayawhip': '#FFEFD5', + 'peachpuff': '#FFDAB9', + 'peru': '#CD853F', + 'pink': '#FFC0CB', + 'plum': '#DDA0DD', + 'powderblue': '#B0E0E6', + 'purple': '#800080', + 'red': '#FF0000', + 'rosybrown': '#BC8F8F', + 'royalblue': '#4169E1', + 'saddlebrown': '#8B4513', + 'salmon': '#FA8072', + 'sandybrown': '#FAA460', + 'seagreen': '#2E8B57', + 'seashell': '#FFF5EE', + 'sienna': '#A0522D', + 'silver': '#C0C0C0', + 'skyblue': '#87CEEB', + 'slateblue': '#6A5ACD', + 'slategray': '#708090', + 'snow': '#FFFAFA', + 'springgreen': '#00FF7F', + 'steelblue': '#4682B4', + 'tan': '#D2B48C', + 'teal': '#008080', + 'thistle': '#D8BFD8', + 'tomato': '#FF6347', + 'turquoise': '#40E0D0', + 'violet': '#EE82EE', + 'wheat': '#F5DEB3', + 'white': '#FFFFFF', + 'whitesmoke': '#F5F5F5', + 'yellow': '#FFFF00', + 'yellowgreen': '#9ACD32', } # add british equivs for k, v in cnames.items(): - if k.find('gray')>=0: + if k.find('gray') >= 0: k = k.replace('gray', 'grey') cnames[k] = v + def is_color_like(c): 'Return *True* if *c* can be converted to *RGB*' try: @@ -218,10 +219,11 @@ def rgb2hex(rgb): 'Given an rgb or rgba sequence of 0-1 floats, return the hex string' - return '#%02x%02x%02x' % tuple([round(val*255) for val in rgb[:3]]) + return '#%02x%02x%02x' % tuple([np.round(val * 255) for val in rgb[:3]]) hexColorPattern = re.compile("\A#[a-fA-F0-9]{6}\Z") + def hex2color(s): """ Take a hex string *s* and return the corresponding rgb 3-tuple @@ -231,9 +233,10 @@ raise TypeError('hex2color requires a string argument') if hexColorPattern.match(s) is None: raise ValueError('invalid hex color string "%s"' % s) - return tuple([int(n, 16)/255.0 for n in (s[1:3], s[3:5], s[5:7])]) + return tuple([int(n, 16) / 255.0 for n in (s[1:3], s[3:5], s[5:7])]) + -class ColorConverter: +class ColorConverter(object): """ Provides methods for converting color specifications to *RGB* or *RGBA* @@ -244,17 +247,18 @@ *colorConverter*, is needed. """ colors = { - 'b' : (0.0, 0.0, 1.0), - 'g' : (0.0, 0.5, 0.0), - 'r' : (1.0, 0.0, 0.0), - 'c' : (0.0, 0.75, 0.75), - 'm' : (0.75, 0, 0.75), - 'y' : (0.75, 0.75, 0), - 'k' : (0.0, 0.0, 0.0), - 'w' : (1.0, 1.0, 1.0), + 'b': (0.0, 0.0, 1.0), + 'g': (0.0, 0.5, 0.0), + 'r': (1.0, 0.0, 0.0), + 'c': (0.0, 0.75, 0.75), + 'm': (0.75, 0, 0.75), + 'y': (0.75, 0.75, 0), + 'k': (0.0, 0.0, 0.0), + 'w': (1.0, 1.0, 1.0), } cache = {} + def to_rgb(self, arg): """ Returns an *RGB* tuple of three floats from 0-1. @@ -269,12 +273,16 @@ if *arg* is *RGBA*, the *A* will simply be discarded. """ - try: return self.cache[arg] - except KeyError: pass - except TypeError: # could be unhashable rgb seq + try: + return self.cache[arg] + except KeyError: + pass + except TypeError: # could be unhashable rgb seq arg = tuple(arg) - try: return self.cache[arg] - except KeyError: pass + try: + return self.cache[arg] + except KeyError: + pass except TypeError: raise ValueError( 'to_rgb: arg "%s" is unhashable even inside a tuple' @@ -293,22 +301,25 @@ if fl < 0 or fl > 1: raise ValueError( 'gray (string) must be in range 0-1') - color = tuple([fl]*3) + color = tuple([fl] * 3) elif cbook.iterable(arg): if len(arg) > 4 or len(arg) < 3: raise ValueError( - 'sequence length is %d; must be 3 or 4'%len(arg)) + 'sequence length is %d; must be 3 or 4' % len(arg)) color = tuple(arg[:3]) if [x for x in color if (float(x) < 0) or (x > 1)]: # This will raise TypeError if x is not a number. - raise ValueError('number in rbg sequence outside 0-1 range') + raise ValueError( + 'number in rbg sequence outside 0-1 range') else: - raise ValueError('cannot convert argument to rgb sequence') + raise ValueError( + 'cannot convert argument to rgb sequence') self.cache[arg] = color - except (KeyError, ValueError, TypeError), exc: - raise ValueError('to_rgb: Invalid rgb arg "%s"\n%s' % (str(arg), exc)) + except (KeyError, ValueError, TypeError) as exc: + raise ValueError( + 'to_rgb: Invalid rgb arg "%s"\n%s' % (str(arg), exc)) # Error messages could be improved by handling TypeError # separately; but this should be rare and not too hard # for the user to figure out as-is. @@ -335,22 +346,25 @@ if len(arg) == 4: if [x for x in arg if (float(x) < 0) or (x > 1)]: # This will raise TypeError if x is not a number. - raise ValueError('number in rbga sequence outside 0-1 range') + raise ValueError( + 'number in rbga sequence outside 0-1 range') if alpha is None: return tuple(arg) if alpha < 0.0 or alpha > 1.0: raise ValueError("alpha must be in range 0-1") return arg[0], arg[1], arg[2], alpha - r,g,b = arg[:3] - if [x for x in (r,g,b) if (float(x) < 0) or (x > 1)]: - raise ValueError('number in rbg sequence outside 0-1 range') + r, g, b = arg[:3] + if [x for x in (r, g, b) if (float(x) < 0) or (x > 1)]: + raise ValueError( + 'number in rbg sequence outside 0-1 range') else: - r,g,b = self.to_rgb(arg) + r, g, b = self.to_rgb(arg) if alpha is None: alpha = 1.0 - return r,g,b,alpha - except (TypeError, ValueError), exc: - raise ValueError('to_rgba: Invalid rgba arg "%s"\n%s' % (str(arg), exc)) + return r, g, b, alpha + except (TypeError, ValueError) as exc: + raise ValueError( + 'to_rgba: Invalid rgba arg "%s"\n%s' % (str(arg), exc)) def to_rgba_array(self, c, alpha=None): """ @@ -368,7 +382,7 @@ "Cannot convert argument type %s to rgba array" % type(c)) try: if nc == 0 or c.lower() == 'none': - return np.zeros((0,4), dtype=np.float) + return np.zeros((0, 4), dtype=np.float) except AttributeError: pass try: @@ -386,7 +400,7 @@ if alpha is not None: if alpha > 1 or alpha < 0: raise ValueError("alpha must be in 0-1 range") - result[:,3] = alpha + result[:, 3] = alpha return result # This alpha operation above is new, and depends # on higher levels to refrain from setting alpha @@ -399,8 +413,10 @@ result[i] = self.to_rgba(cc, alpha) return result + colorConverter = ColorConverter() + def makeMappingArray(N, data, gamma=1.0): """Create an *N* -element 1-d lookup table @@ -423,7 +439,7 @@ """ if callable(data): - xind = np.linspace(0, 1, N)**gamma + xind = np.linspace(0, 1, N) ** gamma lut = np.clip(np.array(data(xind), dtype=np.float), 0, 1) return lut @@ -435,24 +451,24 @@ if len(shape) != 2 and shape[1] != 3: raise ValueError("data must be nx3 format") - x = adata[:,0] - y0 = adata[:,1] - y1 = adata[:,2] + x = adata[:, 0] + y0 = adata[:, 1] + y1 = adata[:, 2] if x[0] != 0. or x[-1] != 1.0: raise ValueError( "data mapping points must start with x=0. and end with x=1") - if np.sometrue(np.sort(x)-x): + if np.sometrue(np.sort(x) - x): raise ValueError( "data mapping points must have x in increasing order") # begin generation of lookup table - x = x * (N-1) + x = x * (N - 1) lut = np.zeros((N,), np.float) - xind = (N - 1) * np.linspace(0, 1, N)**gamma + xind = (N - 1) * np.linspace(0, 1, N) ** gamma ind = np.searchsorted(x, xind)[1:-1] - lut[1:-1] = ( ((xind[1:-1] - x[ind-1]) / (x[ind] - x[ind-1])) - * (y0[ind] - y1[ind-1]) + y1[ind-1]) + lut[1:-1] = (((xind[1:-1] - x[ind - 1]) / (x[ind] - x[ind - 1])) + * (y0[ind] - y1[ind - 1]) + y1[ind - 1]) lut[0] = y1[0] lut[-1] = y0[-1] # ensure that the lut is confined to values between 0 and 1 by clipping it @@ -462,7 +478,7 @@ return lut -class Colormap: +class Colormap(object): """Base class for all scalar to rgb mappings Important methods: @@ -474,21 +490,21 @@ def __init__(self, name, N=256): """ Public class attributes: - :attr:`N` : number of rgb quantization levels - :attr:`name` : name of colormap + :attr:`N` : number of rgb quantization levels + :attr:`name` : name of colormap """ self.name = name self.N = N - self._rgba_bad = (0.0, 0.0, 0.0, 0.0) # If bad, don't paint anything. + self._rgba_bad = (0.0, 0.0, 0.0, 0.0) # If bad, don't paint anything. self._rgba_under = None self._rgba_over = None self._i_under = N - self._i_over = N+1 - self._i_bad = N+2 + self._i_over = N + 1 + self._i_bad = N + 2 self._isinit = False - + # FIXME FIXME FIXME bytes is a *keyword* in python def __call__(self, X, alpha=None, bytes=False): """ *X* is either a scalar or an array (of any dimension). @@ -502,23 +518,30 @@ 0-1 scale; if True, they will be uint8, 0-255. """ - if not self._isinit: self._init() + if not self._isinit: + self._init() mask_bad = None if not cbook.iterable(X): vtype = 'scalar' xa = np.array([X]) else: vtype = 'array' - xma = ma.array(X, copy=False) - mask_bad = xma.mask - xa = xma.data.copy() # Copy here to avoid side effects. + xma = ma.array(X, copy=True) # Copy here to avoid side effects. + mask_bad = xma.mask # Mask will be used below. + xa = xma.filled() # Fill to avoid infs, etc. del xma - # masked values are substituted below; no need to fill them here - if xa.dtype.char in np.typecodes['Float']: + # Calculations with native byteorder are faster, and avoid a + # bug that otherwise can occur with putmask when the last + # argument is a numpy scalar. + if not xa.dtype.isnative: + xa = xa.byteswap().newbyteorder() + + if xa.dtype.kind == "f": # Treat 1.0 as slightly less than 1. - cbook._putmask(xa, xa==1.0, np.nextafter(xa.dtype.type(1), - xa.dtype.type(0))) + vals = np.array([1, 0], dtype=xa.dtype) + almost_one = np.nextafter(*vals) + cbook._putmask(xa, xa == 1.0, almost_one) # The following clip is fast, and prevents possible # conversion of large positive values to negative integers. @@ -530,12 +553,12 @@ # ensure that all 'under' values will still have negative # value after casting to int - cbook._putmask(xa, xa<0.0, -1) + cbook._putmask(xa, xa < 0.0, -1) xa = xa.astype(int) # Set the over-range indices before the under-range; # otherwise the under-range values get converted to over-range. - cbook._putmask(xa, xa>self.N-1, self._i_over) - cbook._putmask(xa, xa<0, self._i_under) + cbook._putmask(xa, xa > self.N - 1, self._i_over) + cbook._putmask(xa, xa < 0, self._i_under) if mask_bad is not None: if mask_bad.shape == xa.shape: cbook._putmask(xa, mask_bad, self._i_bad) @@ -544,10 +567,10 @@ if bytes: lut = (self._lut * 255).astype(np.uint8) else: - lut = self._lut.copy() # Don't let alpha modify original _lut. + lut = self._lut.copy() # Don't let alpha modify original _lut. if alpha is not None: - alpha = min(alpha, 1.0) # alpha must be between 0 and 1 + alpha = min(alpha, 1.0) # alpha must be between 0 and 1 alpha = max(alpha, 0.0) if bytes: alpha = int(alpha * 255) @@ -557,38 +580,41 @@ # color, which is no color--fully transparent. We # don't want to override this. else: - lut[:,-1] = alpha + lut[:, -1] = alpha # If the bad value is set to have a color, then we # override its alpha just as for any other value. - rgba = np.empty(shape=xa.shape+(4,), dtype=lut.dtype) + rgba = np.empty(shape=xa.shape + (4,), dtype=lut.dtype) lut.take(xa, axis=0, mode='clip', out=rgba) # twice as fast as lut[xa]; # using the clip or wrap mode and providing an # output array speeds it up a little more. if vtype == 'scalar': - rgba = tuple(rgba[0,:]) + rgba = tuple(rgba[0, :]) return rgba - def set_bad(self, color = 'k', alpha = None): + def set_bad(self, color='k', alpha=None): '''Set color to be used for masked values. ''' self._rgba_bad = colorConverter.to_rgba(color, alpha) - if self._isinit: self._set_extremes() + if self._isinit: + self._set_extremes() - def set_under(self, color = 'k', alpha = None): + def set_under(self, color='k', alpha=None): '''Set color to be used for low out-of-range values. Requires norm.clip = False ''' self._rgba_under = colorConverter.to_rgba(color, alpha) - if self._isinit: self._set_extremes() + if self._isinit: + self._set_extremes() - def set_over(self, color = 'k', alpha = None): + def set_over(self, color='k', alpha=None): '''Set color to be used for high out-of-range values. Requires norm.clip = False ''' self._rgba_over = colorConverter.to_rgba(color, alpha) - if self._isinit: self._set_extremes() + if self._isinit: + self._set_extremes() def _set_extremes(self): if self._rgba_under: @@ -598,7 +624,7 @@ if self._rgba_over: self._lut[self._i_over] = self._rgba_over else: - self._lut[self._i_over] = self._lut[self.N-1] + self._lut[self._i_over] = self._lut[self.N - 1] self._lut[self._i_bad] = self._rgba_bad def _init(self): @@ -606,9 +632,10 @@ raise NotImplementedError("Abstract class only") def is_gray(self): - if not self._isinit: self._init() - return (np.alltrue(self._lut[:,0] == self._lut[:,1]) - and np.alltrue(self._lut[:,0] == self._lut[:,2])) + if not self._isinit: + self._init() + return (np.alltrue(self._lut[:, 0] == self._lut[:, 1]) + and np.alltrue(self._lut[:, 0] == self._lut[:, 2])) class LinearSegmentedColormap(Colormap): @@ -623,7 +650,7 @@ segmentdata argument is a dictionary with a red, green and blue entries. Each entry should be a list of *x*, *y0*, *y1* tuples, - forming rows in a table. + forming rows in a table. Entries for alpha are optional. Example: suppose you want red to increase from 0 to 1 over the bottom half, green to do the same over the middle half, @@ -658,15 +685,15 @@ .. seealso:: - :meth:`LinearSegmentedColormap.from_list` + :meth:`LinearSegmentedColormap.from_list` Static method; factory function for generating a smoothly-varying LinearSegmentedColormap. - :func:`makeMappingArray` + :func:`makeMappingArray` For information about making a mapping array. """ - self.monochrome = False # True only if all colors in map are identical; - # needed for contouring. + self.monochrome = False # True only if all colors in map are + # identical; needed for contouring. Colormap.__init__(self, name, N) self._segmentdata = segmentdata self._gamma = gamma @@ -679,6 +706,9 @@ self._segmentdata['green'], self._gamma) self._lut[:-3, 2] = makeMappingArray(self.N, self._segmentdata['blue'], self._gamma) + if 'alpha' in self._segmentdata: + self._lut[:-3, 3] = makeMappingArray(self.N, + self._segmentdata['alpha'], 1) self._isinit = True self._set_extremes() @@ -710,15 +740,17 @@ else: vals = np.linspace(0., 1., len(colors)) - cdict = dict(red=[], green=[], blue=[]) + cdict = dict(red=[], green=[], blue=[], alpha=[]) for val, color in zip(vals, colors): - r,g,b = colorConverter.to_rgb(color) + r, g, b, a = colorConverter.to_rgba(color) cdict['red'].append((val, r, r)) cdict['green'].append((val, g, g)) cdict['blue'].append((val, b, b)) + cdict['alpha'].append((val, a, a)) return LinearSegmentedColormap(name, cdict, N, gamma) + class ListedColormap(Colormap): """Colormap object generated from a list of colors. @@ -726,13 +758,14 @@ but it can also be used to generate special colormaps for ordinary mapping. """ - def __init__(self, colors, name = 'from_list', N = None): + def __init__(self, colors, name='from_list', N=None): """ Make a colormap from a list of colors. *colors* a list of matplotlib color specifications, - or an equivalent Nx3 floating point array (*N* rgb values) + or an equivalent Nx3 or Nx4 floating point array + (*N* rgb or rgba values) *name* a string to identify the colormap *N* @@ -749,8 +782,8 @@ the list will be extended by repetition. """ self.colors = colors - self.monochrome = False # True only if all colors in map are identical; - # needed for contouring. + self.monochrome = False # True only if all colors in map are + # identical; needed for contouring. if N is None: N = len(self.colors) else: @@ -758,31 +791,31 @@ self.colors = [self.colors] * N self.monochrome = True elif cbook.iterable(self.colors): - self.colors = list(self.colors) # in case it was a tuple + self.colors = list(self.colors) # in case it was a tuple if len(self.colors) == 1: self.monochrome = True if len(self.colors) < N: self.colors = list(self.colors) * N del(self.colors[N:]) else: - try: gray = float(self.colors) - except TypeError: pass - else: self.colors = [gray] * N + try: + gray = float(self.colors) + except TypeError: + pass + else: + self.colors = [gray] * N self.monochrome = True Colormap.__init__(self, name, N) - def _init(self): - rgb = np.array([colorConverter.to_rgb(c) - for c in self.colors], np.float) + rgba = colorConverter.to_rgba_array(self.colors) self._lut = np.zeros((self.N + 3, 4), np.float) - self._lut[:-3, :-1] = rgb - self._lut[:-3, -1] = 1 + self._lut[:-3] = rgba self._isinit = True self._set_extremes() -class Normalize: +class Normalize(object): """ Normalize a given value to the 0-1 range """ @@ -896,6 +929,7 @@ 'return true if vmin and vmax set' return (self.vmin is not None and self.vmax is not None) + class LogNorm(Normalize): """ Normalize a given value to the 0-1 range on a log scale @@ -912,16 +946,15 @@ vmin, vmax = self.vmin, self.vmax if vmin > vmax: raise ValueError("minvalue must be less than or equal to maxvalue") - elif vmin<=0: + elif vmin <= 0: raise ValueError("values must all be positive") - elif vmin==vmax: + elif vmin == vmax: result.fill(0) else: if clip: mask = ma.getmask(result) - val = ma.array(np.clip(result.filled(vmax), vmin, vmax), + result = ma.array(np.clip(result.filled(vmax), vmin, vmax), mask=mask) - #result = (ma.log(result)-np.log(vmin))/(np.log(vmax)-np.log(vmin)) # in-place equivalent of above can be much faster resdat = result.data mask = result.mask @@ -945,9 +978,9 @@ if cbook.iterable(value): val = ma.asarray(value) - return vmin * ma.power((vmax/vmin), val) + return vmin * ma.power((vmax / vmin), val) else: - return vmin * pow((vmax/vmin), value) + return vmin * pow((vmax / vmin), value) def autoscale(self, A): ''' @@ -967,6 +1000,7 @@ if self.vmax is None: self.vmax = ma.max(A) + class BoundaryNorm(Normalize): ''' Generate a colormap index based on discrete intervals. @@ -1005,7 +1039,7 @@ self.boundaries = np.asarray(boundaries) self.N = len(self.boundaries) self.Ncmap = ncolors - if self.N-1 == self.Ncmap: + if self.N - 1 == self.Ncmap: self._interp = False else: self._interp = True @@ -1015,16 +1049,17 @@ clip = self.clip x = ma.asarray(x) mask = ma.getmaskarray(x) - xx = x.filled(self.vmax+1) + xx = x.filled(self.vmax + 1) if clip: np.clip(xx, self.vmin, self.vmax) iret = np.zeros(x.shape, dtype=np.int16) for i, b in enumerate(self.boundaries): - iret[xx>=b] = i + iret[xx >= b] = i if self._interp: - iret = (iret * (float(self.Ncmap-1)/(self.N-2))).astype(np.int16) - iret[xx=self.vmax] = self.Ncmap + scalefac = float(self.Ncmap - 1) / (self.N - 2) + iret = (iret * scalefac).astype(np.int16) + iret[xx < self.vmin] = -1 + iret[xx >= self.vmax] = self.Ncmap ret = ma.array(iret, mask=mask) if ret.shape == () and not mask: ret = int(ret) # assume python scalar @@ -1050,6 +1085,7 @@ normalize = Normalize no_norm = NoNorm + def rgb_to_hsv(arr): """ convert rgb values in a numpy array to hsv values @@ -1063,49 +1099,81 @@ s[ipos] = delta[ipos] / arr_max[ipos] ipos = delta > 0 # red is max - idx = (arr[:,:,0] == arr_max) & ipos + idx = (arr[:, :, 0] == arr_max) & ipos out[idx, 0] = (arr[idx, 1] - arr[idx, 2]) / delta[idx] # green is max - idx = (arr[:,:,1] == arr_max) & ipos - out[idx, 0] = 2. + (arr[idx, 2] - arr[idx, 0] ) / delta[idx] + idx = (arr[:, :, 1] == arr_max) & ipos + out[idx, 0] = 2. + (arr[idx, 2] - arr[idx, 0]) / delta[idx] # blue is max - idx = (arr[:,:,2] == arr_max) & ipos - out[idx, 0] = 4. + (arr[idx, 0] - arr[idx, 1] ) / delta[idx] - out[:,:,0] = (out[:,:,0]/6.0) % 1.0 - out[:,:,1] = s - out[:,:,2] = arr_max + idx = (arr[:, :, 2] == arr_max) & ipos + out[idx, 0] = 4. + (arr[idx, 0] - arr[idx, 1]) / delta[idx] + out[:, :, 0] = (out[:, :, 0] / 6.0) % 1.0 + out[:, :, 1] = s + out[:, :, 2] = arr_max return out + def hsv_to_rgb(hsv): """ convert hsv values in a numpy array to rgb values both input and output arrays have shape (M,N,3) """ - h = hsv[:,:,0]; s = hsv[:,:,1]; v = hsv[:,:,2] - r = np.empty_like(h); g = np.empty_like(h); b = np.empty_like(h) - i = (h*6.0).astype(np.int) - f = (h*6.0) - i - p = v*(1.0 - s) - q = v*(1.0 - s*f) - t = v*(1.0 - s*(1.0-f)) - idx = i%6 == 0 - r[idx] = v[idx]; g[idx] = t[idx]; b[idx] = p[idx] + h = hsv[:, :, 0] + s = hsv[:, :, 1] + v = hsv[:, :, 2] + + r = np.empty_like(h) + g = np.empty_like(h) + b = np.empty_like(h) + + i = (h * 6.0).astype(np.int) + f = (h * 6.0) - i + p = v * (1.0 - s) + q = v * (1.0 - s * f) + t = v * (1.0 - s * (1.0 - f)) + + idx = i % 6 == 0 + r[idx] = v[idx] + g[idx] = t[idx] + b[idx] = p[idx] + idx = i == 1 - r[idx] = q[idx]; g[idx] = v[idx]; b[idx] = p[idx] + r[idx] = q[idx] + g[idx] = v[idx] + b[idx] = p[idx] + idx = i == 2 - r[idx] = p[idx]; g[idx] = v[idx]; b[idx] = t[idx] + r[idx] = p[idx] + g[idx] = v[idx] + b[idx] = t[idx] + idx = i == 3 - r[idx] = p[idx]; g[idx] = q[idx]; b[idx] = v[idx] + r[idx] = p[idx] + g[idx] = q[idx] + b[idx] = v[idx] + idx = i == 4 - r[idx] = t[idx]; g[idx] = p[idx]; b[idx] = v[idx] + r[idx] = t[idx] + g[idx] = p[idx] + b[idx] = v[idx] + idx = i == 5 - r[idx] = v[idx]; g[idx] = p[idx]; b[idx] = q[idx] + r[idx] = v[idx] + g[idx] = p[idx] + b[idx] = q[idx] + idx = s == 0 - r[idx] = v[idx]; g[idx] = v[idx]; b[idx] = v[idx] + r[idx] = v[idx] + g[idx] = v[idx] + b[idx] = v[idx] + rgb = np.empty_like(hsv) - rgb[:,:,0]=r; rgb[:,:,1]=g; rgb[:,:,2]=b + rgb[:, :, 0] = r + rgb[:, :, 1] = g + rgb[:, :, 2] = b return rgb + class LightSource(object): """ Create a light source coming from the specified azimuth and elevation. @@ -1114,30 +1182,32 @@ The :meth:`shade` is used to produce rgb values for a shaded relief image given a data array. """ - def __init__(self,azdeg=315,altdeg=45,\ - hsv_min_val=0,hsv_max_val=1,hsv_min_sat=1,hsv_max_sat=0): - """ - Specify the azimuth (measured clockwise from south) and altitude - (measured up from the plane of the surface) of the light source - in degrees. - - The color of the resulting image will be darkened - by moving the (s,v) values (in hsv colorspace) toward - (hsv_min_sat, hsv_min_val) in the shaded regions, or - lightened by sliding (s,v) toward - (hsv_max_sat hsv_max_val) in regions that are illuminated. - The default extremes are chose so that completely shaded points - are nearly black (s = 1, v = 0) and completely illuminated points - are nearly white (s = 0, v = 1). - """ - self.azdeg = azdeg - self.altdeg = altdeg - self.hsv_min_val = hsv_min_val - self.hsv_max_val = hsv_max_val - self.hsv_min_sat = hsv_min_sat - self.hsv_max_sat = hsv_max_sat + def __init__(self, azdeg=315, altdeg=45, + hsv_min_val=0, hsv_max_val=1, hsv_min_sat=1, + hsv_max_sat=0): + + """ + Specify the azimuth (measured clockwise from south) and altitude + (measured up from the plane of the surface) of the light source + in degrees. + + The color of the resulting image will be darkened + by moving the (s,v) values (in hsv colorspace) toward + (hsv_min_sat, hsv_min_val) in the shaded regions, or + lightened by sliding (s,v) toward + (hsv_max_sat hsv_max_val) in regions that are illuminated. + The default extremes are chose so that completely shaded points + are nearly black (s = 1, v = 0) and completely illuminated points + are nearly white (s = 0, v = 1). + """ + self.azdeg = azdeg + self.altdeg = altdeg + self.hsv_min_val = hsv_min_val + self.hsv_max_val = hsv_max_val + self.hsv_min_sat = hsv_min_sat + self.hsv_max_sat = hsv_max_sat - def shade(self,data,cmap): + def shade(self, data, cmap): """ Take the input data array, convert to HSV values in the given colormap, then adjust those color values @@ -1147,48 +1217,63 @@ plot the shaded image with imshow. """ - rgb0 = cmap((data-data.min())/(data.max()-data.min())) + rgb0 = cmap((data - data.min()) / (data.max() - data.min())) rgb1 = self.shade_rgb(rgb0, elevation=data) - rgb0[:,:,0:3] = rgb1 + rgb0[:, :, 0:3] = rgb1 return rgb0 - def shade_rgb(self,rgb, elevation, fraction=1.): + def shade_rgb(self, rgb, elevation, fraction=1.): """ Take the input RGB array (ny*nx*3) adjust their color values to given the impression of a shaded relief map with a specified light source using the elevation (ny*nx). A new RGB array ((ny*nx*3)) is returned. """ - # imagine an artificial sun placed at infinity in - # some azimuth and elevation position illuminating our surface. The parts of - # the surface that slope toward the sun should brighten while those sides - # facing away should become darker. - # convert alt, az to radians - az = self.azdeg*np.pi/180.0 - alt = self.altdeg*np.pi/180.0 + # imagine an artificial sun placed at infinity in some azimuth and + # elevation position illuminating our surface. The parts of the + # surface that slope toward the sun should brighten while those sides + # facing away should become darker. convert alt, az to radians + az = self.azdeg * np.pi / 180.0 + alt = self.altdeg * np.pi / 180.0 # gradient in x and y directions dx, dy = np.gradient(elevation) - slope = 0.5*np.pi - np.arctan(np.hypot(dx, dy)) + slope = 0.5 * np.pi - np.arctan(np.hypot(dx, dy)) aspect = np.arctan2(dx, dy) - intensity = np.sin(alt)*np.sin(slope) + np.cos(alt)*np.cos(slope)*np.cos(-az -\ - aspect - 0.5*np.pi) + intensity = np.sin(alt) * np.sin(slope) + np.cos(alt) *\ + np.cos(slope) * np.cos(-az - aspect - 0.5 * np.pi) # rescale to interval -1,1 # +1 means maximum sun exposure and -1 means complete shade. - intensity = (intensity - intensity.min())/(intensity.max() - intensity.min()) - intensity = (2.*intensity - 1.)*fraction + intensity = (intensity - intensity.min()) / \ + (intensity.max() - intensity.min()) + intensity = (2. * intensity - 1.) * fraction # convert to rgb, then rgb to hsv #rgb = cmap((data-data.min())/(data.max()-data.min())) - hsv = rgb_to_hsv(rgb[:,:,0:3]) + hsv = rgb_to_hsv(rgb[:, :, 0:3]) # modify hsv values to simulate illumination. - hsv[:,:,1] = np.where(np.logical_and(np.abs(hsv[:,:,1])>1.e-10,intensity>0),\ - (1.-intensity)*hsv[:,:,1]+intensity*self.hsv_max_sat, hsv[:,:,1]) - hsv[:,:,2] = np.where(intensity > 0, (1.-intensity)*hsv[:,:,2] +\ - intensity*self.hsv_max_val, hsv[:,:,2]) - hsv[:,:,1] = np.where(np.logical_and(np.abs(hsv[:,:,1])>1.e-10,intensity<0),\ - (1.+intensity)*hsv[:,:,1]-intensity*self.hsv_min_sat, hsv[:,:,1]) - hsv[:,:,2] = np.where(intensity < 0, (1.+intensity)*hsv[:,:,2] -\ - intensity*self.hsv_min_val, hsv[:,:,2]) - hsv[:,:,1:] = np.where(hsv[:,:,1:]<0.,0,hsv[:,:,1:]) - hsv[:,:,1:] = np.where(hsv[:,:,1:]>1.,1,hsv[:,:,1:]) + + hsv[:, :, 1] = np.where(np.logical_and( + np.abs(hsv[:, :, 1]) > 1.e-10, + intensity > 0), + (1. - intensity) * hsv[:, :, 1] + \ + intensity * self.hsv_max_sat, + hsv[:, :, 1]) + + hsv[:, :, 2] = np.where(intensity > 0, + (1. - intensity) * hsv[:, :, 2] + \ + intensity * self.hsv_max_val, + hsv[:, :, 2]) + + hsv[:, :, 1] = np.where(np.logical_and( + np.abs(hsv[:, :, 1]) > 1.e-10, + intensity < 0), + (1. + intensity) * hsv[:, :, 1] - \ + intensity * self.hsv_min_sat, + hsv[:, :, 1]) + hsv[:, :, 2] = np.where(intensity < 0, + (1. + intensity) * hsv[:, :, 2] -\ + intensity * self.hsv_min_val, + hsv[:, :, 2]) + hsv[:, :, 1:] = np.where(hsv[:, :, 1:] < 0., 0, hsv[:, :, 1:]) + hsv[:, :, 1:] = np.where(hsv[:, :, 1:] > 1., 1, hsv[:, :, 1:]) # convert modified hsv back to rgb. return hsv_to_rgb(hsv) diff -Nru matplotlib-1.1.1/lib/matplotlib/container.py matplotlib-1.2.0/lib/matplotlib/container.py --- matplotlib-1.1.1/lib/matplotlib/container.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/container.py 2012-11-08 13:38:03.000000000 +0000 @@ -29,7 +29,7 @@ c.remove() if self._remove_method: - self._remove_method() + self._remove_method(self) def get_label(self): """ @@ -41,9 +41,9 @@ """ Set the label to *s* for auto legend. - ACCEPTS: any string + ACCEPTS: string or anything printable with '%s' conversion. """ - self._label = s + self._label = '%s' % (s, ) self.pchanged() def add_callback(self, func): diff -Nru matplotlib-1.1.1/lib/matplotlib/contour.py matplotlib-1.2.0/lib/matplotlib/contour.py --- matplotlib-1.1.1/lib/matplotlib/contour.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/contour.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,7 +2,7 @@ These are classes to support contour plotting and labelling for the axes class """ -from __future__ import division +from __future__ import division, print_function import warnings import matplotlib as mpl import numpy as np @@ -12,13 +12,15 @@ import matplotlib.ticker as ticker import matplotlib.cm as cm import matplotlib.colors as colors -import matplotlib.collections as collections +import matplotlib.collections as mcoll import matplotlib.font_manager as font_manager import matplotlib.text as text import matplotlib.cbook as cbook import matplotlib.mlab as mlab import matplotlib.mathtext as mathtext +import matplotlib.patches as mpatches import matplotlib.texmanager as texmanager +import matplotlib.transforms as mtrans # Import needed for adding manual selection capability to clabel from matplotlib.blocking_input import BlockingContourLabeler @@ -51,11 +53,13 @@ def clabel(self, *args, **kwargs): """ + Label a contour plot. + Call signature:: clabel(cs, **kwargs) - adds labels to line contours in *cs*, where *cs* is a + Adds labels to line contours in *cs*, where *cs* is a :class:`~matplotlib.contour.ContourSet` object returned by contour. @@ -68,7 +72,7 @@ Optional keyword arguments: *fontsize*: - See http://matplotlib.sf.net/fonts.html + size in points or relative size eg 'smaller', 'x-large' *colors*: - if *None*, the color of each label matches the color of @@ -110,6 +114,9 @@ placement, delete or backspace act like the third mouse button, and any other key will select a label location). + *manual* can be an iterable object of x,y tuples. Contour labels + will be created as if mouse is clicked at each x,y positions. + *rightside_up*: if *True* (default), label rotations will always be plus or minus 90 degrees from level. @@ -148,10 +155,9 @@ self.labelManual=kwargs.get('manual',False) self.rightside_up = kwargs.get('rightside_up', True) - if len(args) == 0: levels = self.levels - indices = range(len(levels)) + indices = range(len(self.cvalues)) elif len(args) == 1: levlabs = list(args[0]) indices, levels = [], [] @@ -197,11 +203,16 @@ #self.labelCValues = [] # same self.labelXYs = [] - if self.labelManual: - print 'Select label locations manually using first mouse button.' - print 'End manual selection with second mouse button.' + if cbook.iterable(self.labelManual): + for x,y in self.labelManual: + self.add_label_near(x, y, inline, + inline_spacing) + + elif self.labelManual: + print('Select label locations manually using first mouse button.') + print('End manual selection with second mouse button.') if not inline: - print 'Remove last label by clicking third mouse button.' + print('Remove last label by clicking third mouse button.') blocking_contour_labeler = BlockingContourLabeler(self) blocking_contour_labeler(inline,inline_spacing) @@ -447,11 +458,11 @@ pl, np.arange(len(pl)), xi, extrap=False ) # If those indices aren't beyond contour edge, find x,y - if (not np.isnan(I[0])) and int(I[0])<>I[0]: + if (not np.isnan(I[0])) and int(I[0])!=I[0]: xy1 = mlab.less_simple_linear_interpolation( pl, lc, [ xi[0] ] ) - if (not np.isnan(I[1])) and int(I[1])<>I[1]: + if (not np.isnan(I[1])) and int(I[1])!=I[1]: xy2 = mlab.less_simple_linear_interpolation( pl, lc, [ xi[1] ] ) @@ -532,6 +543,67 @@ self._add_label(t, x, y, lev, cvalue) + def add_label_near(self, x, y, inline=True, inline_spacing=5, + transform=None): + """ + Add a label near the point (x, y) of the given transform. + If transform is None, data transform is used. If transform is + False, IdentityTransform is used. + + *inline*: + controls whether the underlying contour is removed or + not. Default is *True*. + + *inline_spacing*: + space in pixels to leave on each side of label when + placing inline. Defaults to 5. This spacing will be + exact for labels at locations where the contour is + straight, less so for labels on curved contours. + """ + + if transform is None: + transform = self.ax.transData + + if transform: + x,y = transform.transform_point((x, y)) + + conmin,segmin,imin,xmin,ymin = self.find_nearest_contour( + x, y, self.labelIndiceList)[:5] + + # Get index of nearest level in subset of levels used for labeling + lmin = self.labelIndiceList.index(conmin) + + # Coordinates of contour + paths = self.collections[conmin].get_paths() + lc = paths[segmin].vertices + + # In pixel/screen space + slc = self.ax.transData.transform(lc) + + # Get label width for rotating labels and breaking contours + lw = self.get_label_width(self.labelLevelList[lmin], + self.labelFmt, self.labelFontSizeList[lmin]) + + # Figure out label rotation. + if inline: + lcarg = lc + else: + lcarg = None + rotation,nlc = self.calc_label_rot_and_inline( + slc, imin, lw, lcarg, + inline_spacing ) + + self.add_label(xmin,ymin,rotation,self.labelLevelList[lmin], + self.labelCValueList[lmin]) + + if inline: + # Remove old, not looping over paths so we can do this up front + paths.pop(segmin) + + # Add paths if not empty or single point + for n in nlc: + if len(n)>1: + paths.append( mpath.Path(n) ) def pop_label(self,index=-1): '''Defaults to removing last label, but any index can be supplied''' @@ -613,7 +685,7 @@ layers: same as levels for line contours; half-way between - levels for filled contours. See _process_colors method. + levels for filled contours. See :meth:`_process_colors`. """ def __init__(self, ax, *args, **kwargs): """ @@ -665,12 +737,16 @@ self.linewidths = kwargs.get('linewidths', None) self.linestyles = kwargs.get('linestyles', None) + self.hatches = kwargs.get('hatches', [None]) + self.alpha = kwargs.get('alpha', None) self.origin = kwargs.get('origin', None) self.extent = kwargs.get('extent', None) cmap = kwargs.get('cmap', None) self.colors = kwargs.get('colors', None) norm = kwargs.get('norm', None) + vmin = kwargs.get('vmin', None) + vmax = kwargs.get('vmax', None) self.extend = kwargs.get('extend', 'neither') self.antialiased = kwargs.get('antialiased', None) if self.antialiased is None and self.filled: @@ -695,11 +771,12 @@ if self.origin is not None: assert(self.origin in ['lower', 'upper', 'image']) if self.extent is not None: assert(len(self.extent) == 4) - if cmap is not None: assert(isinstance(cmap, colors.Colormap)) if self.colors is not None and cmap is not None: raise ValueError('Either colors or cmap must be None') if self.origin == 'image': self.origin = mpl.rcParams['image.origin'] + self._transform = kwargs.get('transform', None) + self._process_args(*args, **kwargs) self._process_levels() @@ -709,9 +786,9 @@ ncolors -= 1 cmap = colors.ListedColormap(self.colors, N=ncolors) if self.filled: - self.collections = cbook.silent_list('collections.PathCollection') + self.collections = cbook.silent_list('mcoll.PathCollection') else: - self.collections = cbook.silent_list('collections.LineCollection') + self.collections = cbook.silent_list('mcoll.LineCollection') # label lists must be initialized here self.labelTexts = [] self.labelCValues = [] @@ -719,7 +796,11 @@ kw = {'cmap': cmap} if norm is not None: kw['norm'] = norm - cm.ScalarMappable.__init__(self, **kw) # sets self.cmap; + cm.ScalarMappable.__init__(self, **kw) # sets self.cmap, norm if needed; + if vmin is not None: + self.norm.vmin = vmin + if vmax is not None: + self.norm.vmax = vmax self._process_colors() self.allsegs, self.allkinds = self._get_allsegs_and_allkinds() @@ -740,10 +821,11 @@ paths = self._make_paths(segs, kinds) # Default zorder taken from Collection zorder = kwargs.get('zorder', 1) - col = collections.PathCollection(paths, + col = mcoll.PathCollection(paths, antialiaseds = (self.antialiased,), edgecolors= 'none', alpha=self.alpha, + transform=self.get_transform(), zorder=zorder) self.ax.add_collection(col) self.collections.append(col) @@ -758,16 +840,86 @@ zip(self.levels, tlinewidths, tlinestyles, self.allsegs): # Default zorder taken from LineCollection zorder = kwargs.get('zorder', 2) - col = collections.LineCollection(segs, + col = mcoll.LineCollection(segs, antialiaseds = aa, linewidths = width, linestyle = lstyle, alpha=self.alpha, + transform=self.get_transform(), zorder=zorder) col.set_label('_nolegend_') self.ax.add_collection(col, False) self.collections.append(col) self.changed() # set the colors + + def get_transform(self): + """ + Return the :class:`~matplotlib.transforms.Transform` + instance used by this ContourSet. + """ + if self._transform is None: + self._transform = self.ax.transData + elif (not isinstance(self._transform, mtrans.Transform) + and hasattr(self._transform, '_as_mpl_transform')): + self._transform = self._transform._as_mpl_transform(self.ax) + return self._transform + + def __getstate__(self): + state = self.__dict__.copy() + # the C object Cntr cannot currently be pickled. This isn't a big issue + # as it is not actually used once the contour has been calculated + state['Cntr'] = None + return state + + def legend_elements(self, variable_name='x', str_format=str): + """ + Return a list of artist and labels suitable for passing through + to :func:`plt.legend` which represent this ContourSet. + + Args: + + *variable_name*: the string used inside the inequality used + on the labels + + *str_format*: function used to format the numbers in the labels + """ + artists = [] + labels = [] + + if self.filled: + lowers, uppers = self._get_lowers_and_uppers() + n_levels = len(self.collections) + + for i, (collection, lower, upper) in enumerate(zip(self.collections, + lowers, uppers)): + patch = mpatches.Rectangle((0, 0), 1, 1, + facecolor=collection.get_facecolor()[0], + hatch=collection.get_hatch(), + alpha=collection.get_alpha(), + ) + artists.append(patch) + + lower = str_format(lower) + upper = str_format(upper) + + if i == 0 and self.extend in ('min', 'both'): + labels.append(r'$%s \leq %s$' % (variable_name, lower, )) + elif i == n_levels-1 and self.extend in ('max', 'both'): + labels.append(r'$%s > %s$' % (variable_name, upper, )) + else: + labels.append(r'$%s < %s \leq %s$' % (lower, variable_name, upper)) + else: + for collection, level in zip(self.collections, self.levels): + + patch = mcoll.LineCollection(None) + patch.update_from(collection) + + artists.append(patch) + # format the level for insertion into the labels + level = str_format(level) + labels.append(r'$%s = %s$' % (variable_name, level)) + + return artists, labels def _process_args(self, *args, **kwargs): """ @@ -807,6 +959,7 @@ min = seg.min(axis=0) max = seg.max(axis=0) havelimits = True + if havelimits: self.ax.update_datalim([min, max]) self.ax.autoscale_view(tight=True) @@ -843,9 +996,12 @@ tcolors = [ (tuple(rgba),) for rgba in self.to_rgba(self.cvalues, alpha=self.alpha)] self.tcolors = tcolors - for color, collection in zip(tcolors, self.collections): + hatches = self.hatches * len(tcolors) + for color, hatch, collection in zip(tcolors, hatches, self.collections): if self.filled: collection.set_facecolor(color) + # update the collection's hatch (may be None) + collection.set_hatch(hatch) else: collection.set_color(color) for label, cv in zip(self.labelTexts, self.labelCValues): @@ -870,11 +1026,9 @@ self.locator = ticker.LogLocator() else: self.locator = ticker.MaxNLocator(N+1) - self.locator.create_dummy_axis() zmax = self.zmax zmin = self.zmin - self.locator.set_bounds(zmin, zmax) - lev = self.locator() + lev = self.locator.tick_values(zmin, zmax) self._auto = True if self.filled: return lev @@ -906,58 +1060,86 @@ raise ValueError("Filled contours require at least 2 levels.") def _process_levels(self): + """ + Assign values to :attr:`layers` based on :attr:`levels`, + adding extended layers as needed if contours are filled. + + For line contours, layers simply coincide with levels; + a line is a thin layer. No extended levels are needed + with line contours. + """ + # The following attributes are no longer needed, and + # should be deprecated and removed to reduce confusion. + self.vmin = np.amin(self.levels) + self.vmax = np.amax(self.levels) + + # Make a private _levels to include extended regions; we + # want to leave the original levels attribute unchanged. + # (Colorbar needs this even for line contours.) self._levels = list(self.levels) + + if not self.filled: + self.layers = self.levels + return + if self.extend in ('both', 'min'): self._levels.insert(0, min(self.levels[0],self.zmin) - 1) if self.extend in ('both', 'max'): self._levels.append(max(self.levels[-1],self.zmax) + 1) self._levels = np.asarray(self._levels) - self.vmin = np.amin(self.levels) # alternative would be self.layers - self.vmax = np.amax(self.levels) + + # layer values are mid-way between levels + self.layers = 0.5 * (self._levels[:-1] + self._levels[1:]) + # ...except that extended layers must be outside the + # normed range: if self.extend in ('both', 'min'): - self.vmin = 2 * self.levels[0] - self.levels[1] + self.layers[0] = -np.inf if self.extend in ('both', 'max'): - self.vmax = 2 * self.levels[-1] - self.levels[-2] - if self.filled: - self.layers = 0.5 * (self._levels[:-1] + self._levels[1:]) - if self.extend in ('both', 'min'): - self.layers[0] = 0.5 * (self.vmin + self._levels[1]) - if self.extend in ('both', 'max'): - self.layers[-1] = 0.5 * (self.vmax + self._levels[-2]) - else: - self.layers = self.levels # contour: a line is a thin layer - # Use only original levels--no extended levels + self.layers[-1] = np.inf def _process_colors(self): """ Color argument processing for contouring. - Note that we base the color mapping on the contour levels, - not on the actual range of the Z values. This means we - don't have to worry about bad values in Z, and we always have - the full dynamic range available for the selected levels. + Note that we base the color mapping on the contour levels + and layers, not on the actual range of the Z values. This + means we don't have to worry about bad values in Z, and we + always have the full dynamic range available for the selected + levels. The color is based on the midpoint of the layer, except for - an extended end layers. + extended end layers. By default, the norm vmin and vmax + are the extreme values of the non-extended levels. Hence, + the layer color extremes are not the extreme values of + the colormap itself, but approach those values as the number + of levels increases. An advantage of this scheme is that + line contours, when added to filled contours, take on + colors that are consistent with those of the filled regions; + for example, a contour line on the boundary between two + regions will have a color intermediate between those + of the regions. + """ self.monochrome = self.cmap.monochrome if self.colors is not None: + # Generate integers for direct indexing. i0, i1 = 0, len(self.levels) if self.filled: i1 -= 1 + # Out of range indices for over and under: if self.extend in ('both', 'min'): i0 = -1 if self.extend in ('both', 'max'): i1 += 1 - self.cvalues = range(i0, i1) + self.cvalues = list(range(i0, i1)) self.set_norm(colors.NoNorm()) else: self.cvalues = self.layers - if not self.norm.scaled(): - self.set_clim(self.vmin, self.vmax) + self.set_array(self.levels) + self.autoscale_None() if self.extend in ('both', 'max', 'min'): self.norm.clip = False - self.set_array(self.layers) + # self.tcolors are set by the "changed" method def _process_linewidths(self): @@ -1123,17 +1305,31 @@ self.zmax = args[0].zmax else: x, y, z = self._contour_args(args, kwargs) - + + _mask = ma.getmask(z) + if _mask is ma.nomask: + _mask = None + C = _cntr.Cntr(x, y, z.filled(), _mask) + + t = self.get_transform() + + # if the transform is not trans data, and some part of it + # contains transData, transform the xs and ys to data coordinates + if (t != self.ax.transData and + any(t.contains_branch_seperately(self.ax.transData))): + trans_to_data = t - self.ax.transData + pts = (np.vstack([x.flat, y.flat]).T) + transformed_pts = trans_to_data.transform(pts) + x = transformed_pts[..., 0] + y = transformed_pts[..., 1] + x0 = ma.minimum(x) x1 = ma.maximum(x) y0 = ma.minimum(y) y1 = ma.maximum(y) self.ax.update_datalim([(x0,y0), (x1,y1)]) self.ax.autoscale_view(tight=True) - _mask = ma.getmask(z) - if _mask is ma.nomask: - _mask = None - C = _cntr.Cntr(x, y, z.filled(), _mask) + self.Cntr = C def _get_allsegs_and_allkinds(self): @@ -1254,6 +1450,8 @@ return np.meshgrid(x,y) contour_doc = """ + Plot contours. + :func:`~matplotlib.pyplot.contour` and :func:`~matplotlib.pyplot.contourf` draw contour lines and filled contours, respectively. Except as noted, function @@ -1337,6 +1535,12 @@ scaling data values to colors. If *norm* is *None* and *colors* is *None*, the default linear scaling is used. + *vmin*, *vmax*: [ *None* | scalar ] + If not *None*, either or both of these values will be + supplied to the :class:`matplotlib.colors.Normalize` + instance, overriding the default color scaling based on + *levels*. + *levels*: [level0, level1, ..., leveln] A list of floating point numbers indicating the level curves to draw; eg to draw just the zero contour pass @@ -1398,18 +1602,16 @@ linewidths in the order specified *linestyles*: [ *None* | 'solid' | 'dashed' | 'dashdot' | 'dotted' ] - If *linestyles* is *None*, the 'solid' is used. + If *linestyles* is *None*, the default is 'solid' unless + the lines are monochrome. In that case, negative + contours will take their linestyle from the ``matplotlibrc`` + ``contour.negative_linestyle`` setting. *linestyles* can also be an iterable of the above strings specifying a set of linestyles to be used. If this iterable is shorter than the number of contour levels it will be repeated as necessary. - If contour is using a monochrome colormap and the contour - level is less than 0, then the linestyle specified - in ``contour.negative_linestyle`` in ``matplotlibrc`` - will be used. - contourf-only keyword arguments: *nchunk*: [ 0 | integer ] @@ -1419,6 +1621,13 @@ be removed. Chunking introduces artifacts at the chunk boundaries unless *antialiased* is *False*. + *hatches*: + A list of cross hatch patterns to use on the filled areas. + If None, no hatching will be added to the contour. + Hatching is supported in the PostScript, PDF, SVG and Agg + backends only. + + Note: contourf fills intervals that are closed at the top; that is, for boundaries *z1* and *z2*, the filled region is:: diff -Nru matplotlib-1.1.1/lib/matplotlib/dates.py matplotlib-1.2.0/lib/matplotlib/dates.py --- matplotlib-1.1.1/lib/matplotlib/dates.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/dates.py 2012-11-06 22:31:09.000000000 +0000 @@ -86,7 +86,7 @@ :class:`matplotlib.dates.rrulewrapper`. The :class:`rrulewrapper` is a simple wrapper around a :class:`dateutils.rrule` (`dateutil - `_) which allow almost + `_) which allow almost arbitrary date tick specifications. See `rrule example <../examples/pylab_examples/date_demo_rrule.html>`_. @@ -107,7 +107,10 @@ * :class:`IndexDateFormatter`: date plots with implicit *x* indexing. """ +from __future__ import print_function + import re, time, math, datetime +from itertools import izip import matplotlib import numpy as np @@ -299,13 +302,13 @@ delta.microseconds/MUSECONDS_PER_DAY) f1 = _to_ordinalf(dstart) f2 = _to_ordinalf(dend) - + num = int(np.ceil((f2-f1)/step)) #calculate the difference between dend and dstart in times of delta dinterval_end = dstart + num*delta #calculate end of the interval which will be generated if dinterval_end >= dend: #ensure, that an half open interval will be generated [dstart, dend) dinterval_end -= delta #if the endpoint is greated than dend, just subtract one delta num -= 1 - + f2 = _to_ordinalf(dinterval_end) #new float-endpoint return np.linspace(f1, f2, num+1) @@ -730,7 +733,7 @@ # Assume we were given an integer. Use this as the maximum # number of ticks for every frequency and create a # dictionary for this - self.maxticks = dict(zip(self._freqs, + self.maxticks = dict(izip(self._freqs, [maxticks]*len(self._freqs))) self.interval_multiples = interval_multiples self.intervald = { @@ -790,7 +793,7 @@ # an interval from an list specific to that frequency that gives no # more than maxticks tick positions. Also, set up some ranges # (bymonth, etc.) as appropriate to be passed to rrulewrapper. - for i, (freq, num) in enumerate(zip(self._freqs, nums)): + for i, (freq, num) in enumerate(izip(self._freqs, nums)): # If this particular frequency doesn't give enough ticks, continue if num < self.minticks: # Since we're not using this particular frequency, set @@ -1215,4 +1218,4 @@ #for t in ticks: print formatter(t) - for t in dates: print formatter(t) + for t in dates: print(formatter(t)) diff -Nru matplotlib-1.1.1/lib/matplotlib/delaunay/__init__.py matplotlib-1.2.0/lib/matplotlib/delaunay/__init__.py --- matplotlib-1.1.1/lib/matplotlib/delaunay/__init__.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/delaunay/__init__.py 2012-10-31 00:11:13.000000000 +0000 @@ -5,6 +5,7 @@ :License: BSD-style license. See LICENSE.txt in the scipy source directory. """ +from __future__ import print_function from matplotlib._delaunay import delaunay from triangulate import * from interpolate import * diff -Nru matplotlib-1.1.1/lib/matplotlib/delaunay/_delaunay.cpp matplotlib-1.2.0/lib/matplotlib/delaunay/_delaunay.cpp --- matplotlib-1.1.1/lib/matplotlib/delaunay/_delaunay.cpp 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/delaunay/_delaunay.cpp 2012-10-31 00:11:13.000000000 +0000 @@ -726,16 +726,40 @@ {NULL, NULL, 0, NULL} }; +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef delaunay_module = { + PyModuleDef_HEAD_INIT, + "_delaunay", + "Tools for computing the Delaunay triangulation and some operations on it.\n", + -1, + delaunay_methods, + NULL, NULL, NULL, NULL +}; + +PyMODINIT_FUNC +PyInit__delaunay(void) +{ + PyObject* m; + import_array(); + m = PyModule_Create(&delaunay_module); + if (m == NULL) + return NULL; + + return m; +} +#else PyMODINIT_FUNC init_delaunay(void) { PyObject* m; + import_array(); + m = Py_InitModule3("_delaunay", delaunay_methods, "Tools for computing the Delaunay triangulation and some operations on it.\n" ); if (m == NULL) return; - import_array(); } +#endif } // extern "C" diff -Nru matplotlib-1.1.1/lib/matplotlib/delaunay/interpolate.py matplotlib-1.2.0/lib/matplotlib/delaunay/interpolate.py --- matplotlib-1.1.1/lib/matplotlib/delaunay/interpolate.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/delaunay/interpolate.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import numpy as np from matplotlib._delaunay import compute_planes, linear_interpolate_grid, nn_interpolate_grid diff -Nru matplotlib-1.1.1/lib/matplotlib/delaunay/testfuncs.py matplotlib-1.2.0/lib/matplotlib/delaunay/testfuncs.py --- matplotlib-1.1.1/lib/matplotlib/delaunay/testfuncs.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/delaunay/testfuncs.py 2012-10-31 00:11:13.000000000 +0000 @@ -4,6 +4,8 @@ http://netlib.org/toms/792 """ +from __future__ import print_function + import numpy as np from triangulate import Triangulation @@ -359,7 +361,7 @@ nnt = NNTester(npoints=1000) lpt = LinearTester(npoints=1000) for func in allfuncs: - print func.title + print(func.title) nnt.plot(func, interp=False, plotter='imshow') pl.savefig('%s-ref-img.png' % func.func_name) nnt.plot(func, interp=True, plotter='imshow') @@ -437,7 +439,7 @@ r2 = 1.0 - SSE/SSM - print func.func_name, r2, SSE, SSM, numgood + print(func.func_name, r2, SSE, SSM, numgood) return r2 def allquality(interpolator='nn', allfuncs=allfuncs, data=data, n=33): diff -Nru matplotlib-1.1.1/lib/matplotlib/delaunay/triangulate.py matplotlib-1.2.0/lib/matplotlib/delaunay/triangulate.py --- matplotlib-1.1.1/lib/matplotlib/delaunay/triangulate.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/delaunay/triangulate.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import warnings # 2.3 compatibility try: @@ -5,6 +6,7 @@ except NameError: import sets set = sets.Set +from itertools import izip import numpy as np @@ -126,8 +128,6 @@ """ # Indices of sorted x,y points. j_sorted = np.lexsort(keys=(self.x, self.y)) - - # Mask, in j_sorted order, which is True for duplicate points. mask_duplicates = np.hstack([ False, (np.diff(self.x[j_sorted]) == 0) & (np.diff(self.y[j_sorted]) == 0), @@ -145,12 +145,12 @@ border = (self.triangle_neighbors == -1) edges = {} - edges.update(dict(zip(self.triangle_nodes[border[:,0]][:,1], - self.triangle_nodes[border[:,0]][:,2]))) - edges.update(dict(zip(self.triangle_nodes[border[:,1]][:,2], - self.triangle_nodes[border[:,1]][:,0]))) - edges.update(dict(zip(self.triangle_nodes[border[:,2]][:,0], - self.triangle_nodes[border[:,2]][:,1]))) + edges.update(dict(izip(self.triangle_nodes[border[:,0]][:,1], + self.triangle_nodes[border[:,0]][:,2]))) + edges.update(dict(izip(self.triangle_nodes[border[:,1]][:,2], + self.triangle_nodes[border[:,1]][:,0]))) + edges.update(dict(izip(self.triangle_nodes[border[:,2]][:,0], + self.triangle_nodes[border[:,2]][:,1]))) # Take an arbitrary starting point and its subsequent node hull = list(edges.popitem()) diff -Nru matplotlib-1.1.1/lib/matplotlib/docstring.py matplotlib-1.2.0/lib/matplotlib/docstring.py --- matplotlib-1.1.1/lib/matplotlib/docstring.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/docstring.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,29 +1,32 @@ +from __future__ import print_function from matplotlib import cbook +import sys +import types class Substitution(object): """ A decorator to take a function's docstring and perform string substitution on it. - + This decorator should be robust even if func.__doc__ is None (for example, if -OO was passed to the interpreter) - + Usage: construct a docstring.Substitution with a sequence or dictionary suitable for performing substitution; then decorate a suitable function with the constructed object. e.g. - + sub_author_name = Substitution(author='Jason') - + @sub_author_name def some_function(x): "%(author)s wrote this function" - + # note that some_function.__doc__ is now "Jason wrote this function" - + One can also use positional arguments. - + sub_first_last_names = Substitution('Edgar Allen', 'Poe') - + @sub_first_last_names def some_function(x): "%s %s wrote the Raven" @@ -56,16 +59,16 @@ """ A function decorator that will append an addendum to the docstring of the target function. - + This decorator should be robust even if func.__doc__ is None (for example, if -OO was passed to the interpreter). - + Usage: construct a docstring.Appender with a string to be joined to the original docstring. An optional 'join' parameter may be supplied which will be used to join the docstring and addendum. e.g. - + add_copyright = Appender("Copyright (c) 2009", join='\n') - + @add_copyright def my_dog(has='fleas'): "This docstring will have a copyright below" @@ -100,6 +103,8 @@ def dedent_interpd(func): """A special case of the interpd that first performs a dedent on the incoming docstring""" + if isinstance(func, types.MethodType) and sys.version_info[0] < 3: + func = func.im_func return interpd(dedent(func)) def copy_dedent(source): diff -Nru matplotlib-1.1.1/lib/matplotlib/dviread.py matplotlib-1.2.0/lib/matplotlib/dviread.py --- matplotlib-1.1.1/lib/matplotlib/dviread.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/dviread.py 2012-10-31 00:11:13.000000000 +0000 @@ -18,6 +18,7 @@ ... """ +from __future__ import print_function import errno import matplotlib @@ -25,6 +26,11 @@ import numpy as np import struct import subprocess +import sys + +if sys.version_info[0] >= 3: + def ord(x): + return x _dvistate = mpl_cbook.Bunch(pre=0, outer=1, inpage=2, post_post=3, finale=4) @@ -117,7 +123,7 @@ False if there were no more pages. """ while True: - byte = ord(self.file.read(1)) + byte = ord(self.file.read(1)[0]) self._dispatch(byte) # if self.state == _dvistate.inpage: # matplotlib.verbose.report( @@ -214,41 +220,41 @@ elif byte == 248: self._post() elif byte == 249: self._post_post() else: - raise ValueError, "unknown command: byte %d"%byte + raise ValueError("unknown command: byte %d"%byte) def _pre(self, i, num, den, mag, comment): if self.state != _dvistate.pre: - raise ValueError, "pre command in middle of dvi file" + raise ValueError("pre command in middle of dvi file") if i != 2: - raise ValueError, "Unknown dvi format %d"%i + raise ValueError("Unknown dvi format %d"%i) if num != 25400000 or den != 7227 * 2**16: - raise ValueError, "nonstandard units in dvi file" + raise ValueError("nonstandard units in dvi file") # meaning: TeX always uses those exact values, so it # should be enough for us to support those # (There are 72.27 pt to an inch so 7227 pt = # 7227 * 2**16 sp to 100 in. The numerator is multiplied # by 10^5 to get units of 10**-7 meters.) if mag != 1000: - raise ValueError, "nonstandard magnification in dvi file" + raise ValueError("nonstandard magnification in dvi file") # meaning: LaTeX seems to frown on setting \mag, so # I think we can assume this is constant self.state = _dvistate.outer def _set_char(self, char): if self.state != _dvistate.inpage: - raise ValueError, "misplaced set_char in dvi file" + raise ValueError("misplaced set_char in dvi file") self._put_char(char) self.h += self.fonts[self.f]._width_of(char) def _set_rule(self, a, b): if self.state != _dvistate.inpage: - raise ValueError, "misplaced set_rule in dvi file" + raise ValueError("misplaced set_rule in dvi file") self._put_rule(a, b) self.h += b def _put_char(self, char): if self.state != _dvistate.inpage: - raise ValueError, "misplaced put_char in dvi file" + raise ValueError("misplaced put_char in dvi file") font = self.fonts[self.f] if font._vf is None: self.text.append((self.h, self.v, font, char, @@ -271,7 +277,7 @@ def _put_rule(self, a, b): if self.state != _dvistate.inpage: - raise ValueError, "misplaced put_rule in dvi file" + raise ValueError("misplaced put_rule in dvi file") if a > 0 and b > 0: self.boxes.append((self.h, self.v, a, b)) # matplotlib.verbose.report( @@ -283,8 +289,7 @@ def _bop(self, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, p): if self.state != _dvistate.outer: - raise ValueError, \ - "misplaced bop in dvi file (state %d)" % self.state + raise ValueError("misplaced bop in dvi file (state %d)" % self.state) self.state = _dvistate.inpage self.h, self.v, self.w, self.x, self.y, self.z = 0, 0, 0, 0, 0, 0 self.stack = [] @@ -293,87 +298,95 @@ def _eop(self): if self.state != _dvistate.inpage: - raise ValueError, "misplaced eop in dvi file" + raise ValueError("misplaced eop in dvi file") self.state = _dvistate.outer del self.h, self.v, self.w, self.x, self.y, self.z, self.stack def _push(self): if self.state != _dvistate.inpage: - raise ValueError, "misplaced push in dvi file" + raise ValueError("misplaced push in dvi file") self.stack.append((self.h, self.v, self.w, self.x, self.y, self.z)) def _pop(self): if self.state != _dvistate.inpage: - raise ValueError, "misplaced pop in dvi file" + raise ValueError("misplaced pop in dvi file") self.h, self.v, self.w, self.x, self.y, self.z = self.stack.pop() def _right(self, b): if self.state != _dvistate.inpage: - raise ValueError, "misplaced right in dvi file" + raise ValueError("misplaced right in dvi file") self.h += b def _right_w(self, new_w): if self.state != _dvistate.inpage: - raise ValueError, "misplaced w in dvi file" + raise ValueError("misplaced w in dvi file") if new_w is not None: self.w = new_w self.h += self.w def _right_x(self, new_x): if self.state != _dvistate.inpage: - raise ValueError, "misplaced x in dvi file" + raise ValueError("misplaced x in dvi file") if new_x is not None: self.x = new_x self.h += self.x def _down(self, a): if self.state != _dvistate.inpage: - raise ValueError, "misplaced down in dvi file" + raise ValueError("misplaced down in dvi file") self.v += a def _down_y(self, new_y): if self.state != _dvistate.inpage: - raise ValueError, "misplaced y in dvi file" + raise ValueError("misplaced y in dvi file") if new_y is not None: self.y = new_y self.v += self.y def _down_z(self, new_z): if self.state != _dvistate.inpage: - raise ValueError, "misplaced z in dvi file" + raise ValueError("misplaced z in dvi file") if new_z is not None: self.z = new_z self.v += self.z def _fnt_num(self, k): if self.state != _dvistate.inpage: - raise ValueError, "misplaced fnt_num in dvi file" + raise ValueError("misplaced fnt_num in dvi file") self.f = k def _xxx(self, special): - matplotlib.verbose.report( - 'Dvi._xxx: encountered special: %s' - % ''.join([(32 <= ord(ch) < 127) and ch - or '<%02x>' % ord(ch) - for ch in special]), - 'debug') + if sys.version_info[0] >= 3: + matplotlib.verbose.report( + 'Dvi._xxx: encountered special: %s' + % ''.join([(32 <= ord(ch) < 127) and chr(ch) + or '<%02x>' % ord(ch) + for ch in special]), + 'debug') + else: + matplotlib.verbose.report( + 'Dvi._xxx: encountered special: %s' + % ''.join([(32 <= ord(ch) < 127) and ch + or '<%02x>' % ord(ch) + for ch in special]), + 'debug') def _fnt_def(self, k, c, s, d, a, l, n): - tfm = _tfmfile(n[-l:]) + tfm = _tfmfile(n[-l:].decode('ascii')) if c != 0 and tfm.checksum != 0 and c != tfm.checksum: - raise ValueError, 'tfm checksum mismatch: %s'%n + raise ValueError('tfm checksum mismatch: %s'%n) # It seems that the assumption behind the following check is incorrect: #if d != tfm.design_size: # raise ValueError, 'tfm design size mismatch: %d in dvi, %d in %s'%\ # (d, tfm.design_size, n) - vf = _vffile(n[-l:]) + vf = _vffile(n[-l:].decode('ascii')) self.fonts[k] = DviFont(scale=s, tfm=tfm, texname=n, vf=vf) def _post(self): if self.state != _dvistate.outer: - raise ValueError, "misplaced post in dvi file" + raise ValueError("misplaced post in dvi file") self.state = _dvistate.post_post # TODO: actually read the postamble and finale? # currently post_post just triggers closing the file @@ -391,26 +404,28 @@ The size is in Adobe points (converted from TeX points). .. attribute:: texname - + Name of the font as used internally by TeX and friends. This is usually very different from any external font names, and :class:`dviread.PsfontsMap` can be used to find the external name of the font. .. attribute:: size - + Size of the font in Adobe points, converted from the slightly smaller TeX points. .. attribute:: widths - + Widths of glyphs in glyph-space units, typically 1/1000ths of the point size. - + """ __slots__ = ('texname', 'size', 'widths', '_scale', '_vf', '_tfm') def __init__(self, scale, tfm, texname, vf): + if sys.version_info[0] >= 3 and isinstance(texname, bytes): + texname = texname.decode('ascii') self._scale, self._tfm, self.texname, self._vf = \ scale, tfm, texname, vf self.size = scale * (72.0 / (72.27 * 2**16)) @@ -459,7 +474,7 @@ else: result.append(_mul2012(value, self._scale)) return result - + class Vf(Dvi): """ A virtual font (\*.vf file) containing subroutines for dvi files. @@ -473,11 +488,13 @@ def __init__(self, filename): Dvi.__init__(self, filename, 0) - self._first_font = None - self._chars = {} - self._packet_ends = None - self._read() - self.close() + try: + self._first_font = None + self._chars = {} + self._packet_ends = None + self._read() + finally: + self.close() def __getitem__(self, code): return self._chars[code] @@ -490,10 +507,10 @@ self._finalize_packet() # fall through elif byte_at > self._packet_ends: - raise ValueError, "Packet length mismatch in vf file" + raise ValueError("Packet length mismatch in vf file") else: if byte in (139, 140) or byte >= 243: - raise ValueError, "Inappropriate opcode %d in vf file" % byte + raise ValueError("Inappropriate opcode %d in vf file" % byte) Dvi._dispatch(self, byte) return @@ -514,11 +531,11 @@ elif byte == 248: # postamble (just some number of 248s) self.state = _dvistate.post_post else: - raise ValueError, "unknown vf opcode %d" % byte + raise ValueError("unknown vf opcode %d" % byte) def _init_packet(self, pl, cc, tfm): if self.state != _dvistate.outer: - raise ValueError, "Misplaced packet in vf file" + raise ValueError("Misplaced packet in vf file") self.state = _dvistate.inpage self._packet_ends = self.file.tell() + pl self._packet_char = cc @@ -534,9 +551,9 @@ def _pre(self, i, x, cs, ds): if self.state != _dvistate.pre: - raise ValueError, "pre command in middle of vf file" + raise ValueError("pre command in middle of vf file") if i != 202: - raise ValueError, "Unknown vf format %d" % i + raise ValueError("Unknown vf format %d" % i) if len(x): matplotlib.verbose.report('vf file comment: ' + x, 'debug') self.state = _dvistate.outer @@ -586,18 +603,16 @@ .. attribute:: height Height of each character. - + .. attribute:: depth - + Depth of each character. """ __slots__ = ('checksum', 'design_size', 'width', 'height', 'depth') def __init__(self, filename): matplotlib.verbose.report('opening tfm file ' + filename, 'debug') - file = open(filename, 'rb') - - try: + with open(filename, 'rb') as file: header1 = file.read(24) lh, bc, ec, nw, nh, nd = \ struct.unpack('!6H', header1[2:14]) @@ -612,14 +627,12 @@ widths = file.read(4*nw) heights = file.read(4*nh) depths = file.read(4*nd) - finally: - file.close() self.width, self.height, self.depth = {}, {}, {} widths, heights, depths = \ [ struct.unpack('!%dI' % (len(x)/4), x) for x in (widths, heights, depths) ] - for idx, char in enumerate(range(bc, ec+1)): + for idx, char in enumerate(xrange(bc, ec+1)): self.width[char] = _fix2comp(widths[ord(char_info[4*idx])]) self.height[char] = _fix2comp(heights[ord(char_info[4*idx+1]) >> 4]) self.depth[char] = _fix2comp(depths[ord(char_info[4*idx+1]) & 0xf]) @@ -663,14 +676,14 @@ def __init__(self, filename): self._font = {} - file = open(filename, 'rt') - try: + with open(filename, 'rt') as file: self._parse(file) - finally: - file.close() def __getitem__(self, texname): - result = self._font[texname] + try: + result = self._font[texname] + except KeyError: + result = self._font[texname.decode('ascii')] fn, enc = result.filename, result.encoding if fn is not None and not fn.startswith('/'): result.filename = find_tex_file(fn) @@ -769,13 +782,10 @@ __slots__ = ('encoding',) def __init__(self, filename): - file = open(filename, 'rt') - try: + with open(filename, 'rt') as file: matplotlib.verbose.report('Parsing TeX encoding ' + filename, 'debug-annoying') self.encoding = self._parse(file) - matplotlib.verbose.report('Result: ' + `self.encoding`, 'debug-annoying') - finally: - file.close() + matplotlib.verbose.report('Result: ' + repr(self.encoding), 'debug-annoying') def __iter__(self): for name in self.encoding: @@ -808,7 +818,7 @@ subwords = w.split('/') result.extend(subwords[1:]) else: - raise ValueError, "Broken name in encoding file: " + w + raise ValueError("Broken name in encoding file: " + w) return result @@ -832,7 +842,7 @@ if format is not None: cmd += ['--format=' + format] cmd += [filename] - + matplotlib.verbose.report('find_tex_file(%s): %s' \ % (filename,cmd), 'debug') # stderr is unused, but reading it avoids a subprocess optimization @@ -844,7 +854,7 @@ result = pipe.communicate()[0].rstrip() matplotlib.verbose.report('find_tex_file result: %s' % result, 'debug') - return result + return result.decode('ascii') # With multiple text objects per figure (e.g. tick labels) we may end # up reading the same tfm and vf files many times, so we implement a @@ -885,12 +895,12 @@ dvi = Dvi(fname, dpi) fontmap = PsfontsMap(find_tex_file('pdftex.map')) for page in dvi: - print '=== new page ===' + print('=== new page ===') fPrev = None for x,y,f,c,w in page.text: if f != fPrev: - print 'font', f.texname, 'scaled', f._scale/pow(2.0,20) + print('font', f.texname, 'scaled', f._scale/pow(2.0,20)) fPrev = f - print x,y,c, 32 <= c < 128 and chr(c) or '.', w + print(x,y,c, 32 <= c < 128 and chr(c) or '.', w) for x,y,w,h in page.boxes: - print x,y,'BOX',w,h + print(x,y,'BOX',w,h) diff -Nru matplotlib-1.1.1/lib/matplotlib/figure.py matplotlib-1.2.0/lib/matplotlib/figure.py --- matplotlib-1.1.1/lib/matplotlib/figure.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/figure.py 2012-10-31 00:11:14.000000000 +0000 @@ -11,40 +11,55 @@ """ +from __future__ import print_function +import warnings +from operator import itemgetter + import numpy as np -import artist -from artist import Artist, allow_rasterization -from axes import Axes, SubplotBase, subplot_class_factory -from cbook import flatten, allequal, Stack, iterable, is_string_like -import _image -import colorbar as cbar -from image import FigureImage from matplotlib import rcParams -from patches import Rectangle -from text import Text, _process_text_args +from matplotlib import docstring +from matplotlib import __version__ as _mpl_version -from legend import Legend -from transforms import Affine2D, Bbox, BboxTransformTo, TransformedBbox -from projections import projection_factory, get_projection_names, \ - get_projection_class -from matplotlib.blocking_input import BlockingMouseInput, BlockingKeyMouseInput +import matplotlib.artist as martist +from matplotlib.artist import Artist, allow_rasterization import matplotlib.cbook as cbook -from matplotlib import docstring -from operator import itemgetter -import os.path +from matplotlib.cbook import Stack, iterable + +from matplotlib import _image +from matplotlib.image import FigureImage + +import matplotlib.colorbar as cbar + +from matplotlib.axes import Axes, SubplotBase, subplot_class_factory +from matplotlib.blocking_input import BlockingMouseInput, BlockingKeyMouseInput +from matplotlib.legend import Legend +from matplotlib.patches import Rectangle +from matplotlib.projections import (get_projection_names, + process_projection_requirements) +from matplotlib.text import Text, _process_text_args +from matplotlib.transforms import (Affine2D, Bbox, BboxTransformTo, + TransformedBbox) +from matplotlib.backend_bases import NonGuiException docstring.interpd.update(projection_names = get_projection_names()) class AxesStack(Stack): """ - Specialization of the Stack to handle all - tracking of Axes in a Figure. This requires storing - key, (ind, axes) pairs. The key is based on the args and kwargs - used in generating the Axes. ind is a serial number for tracking - the order in which axes were added. + Specialization of the Stack to handle all tracking of Axes in a Figure. + This stack stores ``key, (ind, axes)`` pairs, where: + + * **key** should be a hash of the args and kwargs + used in generating the Axes. + * **ind** is a serial number for tracking the order + in which axes were added. + + The AxesStack is a callable, where ``ax_stack()`` returns + the current axes. Alternatively the :meth:`current_key_axes` will + return the current key and associated axes. + """ def __init__(self): Stack.__init__(self) @@ -73,9 +88,14 @@ return (k, (ind, e)) def remove(self, a): + """Remove the axes from the stack.""" Stack.remove(self, self._entry_from_axes(a)) def bubble(self, a): + """ + Move the given axes, which must already exist in the + stack, to the top. + """ return Stack.bubble(self, self._entry_from_axes(a)) def add(self, key, a): @@ -97,7 +117,7 @@ a_existing = self.get(key) if a_existing is not None: Stack.remove(self, (key, a_existing)) - warnings.Warn( + warnings.warn( "key %s already existed; Axes is being replaced" % key) # I don't think the above should ever happen. @@ -106,15 +126,26 @@ self._ind += 1 return Stack.push(self, (key, (self._ind, a))) - def __call__(self): + def current_key_axes(self): + """ + Return a tuple of ``(key, axes)`` for the active axes. + + If no axes exists on the stack, then returns ``(None, None)``. + + """ if not len(self._elements): - return self._default + return self._default, self._default else: - return self._elements[self._pos][1][1] + key, (index, axes) = self._elements[self._pos] + return key, axes + + def __call__(self): + return self.current_key_axes()[1] def __contains__(self, a): return a in self.as_list() + class SubplotParams: """ A class to hold the parameters for a subplot @@ -189,8 +220,6 @@ reset() raise ValueError('bottom cannot be >= top') - - def _update_this(self, s, val): if val is None: val = getattr(self, s, None) @@ -200,6 +229,7 @@ setattr(self, s, val) + class Figure(Artist): """ @@ -217,7 +247,7 @@ For multiple figure images, the figure will make composite images depending on the renderer option_image_nocomposite function. If suppressComposite is True|False, this will - override the renderer + override the renderer. """ def __str__(self): @@ -231,6 +261,7 @@ linewidth = 0.0, # the default linewidth of the frame frameon = True, # whether or not to draw the figure frame subplotpars = None, # default to rc + tight_layout = None, # default to rc figure.autolayout ): """ *figsize* @@ -253,6 +284,11 @@ *subplotpars* A :class:`SubplotParams` instance, defaults to rc + + *tight_layout* + If *False* use *subplotpars*; if *True* adjust subplot + parameters using :meth:`tight_layout`. Defaults to + rc ``figure.autolayout``. """ Artist.__init__(self) @@ -288,11 +324,43 @@ subplotpars = SubplotParams() self.subplotpars = subplotpars + self.set_tight_layout(tight_layout) self._axstack = AxesStack() # track all figure axes and current axes self.clf() self._cachedRenderer = None + def show(self, warn=True): + """ + If using a GUI backend with pyplot, display the figure window. + + If the figure was not created using + :func:`~matplotlib.pyplot.figure`, it will lack a + :class:`~matplotlib.backend_bases.FigureManagerBase`, and + will raise an AttributeError. + + For non-GUI backends, this does nothing, in which case + a warning will be issued if *warn* is True (default). + """ + try: + manager = getattr(self.canvas, 'manager') + except AttributeError as err: + raise AttributeError("%s\n Figure.show works only " + "for figures managed by pyplot,\n normally " + "created by pyplot.figure()." % err) + + if manager is not None: + try: + manager.show() + return + except NonGuiException: + pass + if warn: + import warnings + warnings.warn( + "matplotlib is currently using a non-GUI backend, " + "so cannot show the figure") + def _get_axes(self): return self._axstack.as_list() @@ -306,6 +374,24 @@ self.callbacks.process('dpi_changed', self) dpi = property(_get_dpi, _set_dpi) + def get_tight_layout(self): + """ + Return the Boolean flag, True to use :meth`tight_layout` when drawing. + """ + return self._tight + + def set_tight_layout(self, tight): + """ + Set whether :meth:`tight_layout` is used upon drawing. + If None, the rcParams['figure.autolayout'] value will be set. + + ACCEPTS: [True | False | None] + """ + if tight is None: + tight = rcParams['figure.autolayout'] + tight = bool(tight) + self._tight = tight + def autofmt_xdate(self, bottom=0.2, rotation=30, ha='right'): """ Date ticklabels often overlap, so it is useful to rotate them @@ -326,7 +412,7 @@ """ allsubplots = np.alltrue([hasattr(ax, 'is_last_row') for ax in self.axes]) if len(self.axes)==1: - for label in ax.get_xticklabels(): + for label in self.axes[0].get_xticklabels(): label.set_ha(ha) label.set_rotation(rotation) else: @@ -441,6 +527,8 @@ origin=None, **kwargs): """ + Adds a non-resampled image to the figure. + call signatures:: figimage(X, **kwargs) @@ -638,7 +726,7 @@ ret.append(a) return tuple(ret) - key = fixlist(args), fixitems(kwargs.items()) + key = fixlist(args), fixitems(kwargs.iteritems()) return key @docstring.dedent_interpd @@ -691,6 +779,8 @@ """ if not len(args): return + # shortcut the projection "key" modifications later on, if an axes + # with the exact args/kwargs exists, return it immediately. key = self._make_key(*args, **kwargs) ax = self._axstack.get(key) if ax is not None: @@ -702,17 +792,18 @@ assert(a.get_figure() is self) else: rect = args[0] - ispolar = kwargs.pop('polar', False) - projection = kwargs.pop('projection', None) - if ispolar: - if projection is not None and projection != 'polar': - raise ValueError( - "polar=True, yet projection='%s'. " + - "Only one of these arguments should be supplied." % - projection) - projection = 'polar' + projection_class, kwargs, key = \ + process_projection_requirements(self, *args, **kwargs) - a = projection_factory(projection, self, rect, **kwargs) + # check that an axes of this type doesn't already exist, if it + # does, set it as active and return it + ax = self._axstack.get(key) + if ax is not None and isinstance(ax, projection_class): + self.sca(ax) + return ax + + # create the new axes using the axes class given + a = projection_class(self, rect, **kwargs) self._axstack.add(key, a) self.sca(a) @@ -724,10 +815,18 @@ Add a subplot. Examples:: fig.add_subplot(111) - fig.add_subplot(1,1,1) # equivalent but more general - fig.add_subplot(212, axisbg='r') # add subplot with red background - fig.add_subplot(111, polar=True) # add a polar subplot - fig.add_subplot(sub) # add Subplot instance sub + + # equivalent but more general + fig.add_subplot(1,1,1) + + # add subplot with red background + fig.add_subplot(212, axisbg='r') + + # add a polar subplot + fig.add_subplot(111, projection='polar') + + # add Subplot instance sub + fig.add_subplot(sub) *kwargs* are legal :class:`~matplotlib.axes.Axes` kwargs plus *projection*, which chooses a projection type for the axes. @@ -754,39 +853,34 @@ args = tuple([int(c) for c in str(args[0])]) if isinstance(args[0], SubplotBase): + a = args[0] assert(a.get_figure() is self) + # make a key for the subplot (which includes the axes object id + # in the hash) key = self._make_key(*args, **kwargs) else: - kwargs = kwargs.copy() - ispolar = kwargs.pop('polar', False) - projection = kwargs.pop('projection', None) - if ispolar: - if projection is not None and projection != 'polar': - raise ValueError( - "polar=True, yet projection='%s'. " + - "Only one of these arguments should be supplied." % - projection) - projection = 'polar' - - projection_class = get_projection_class(projection) + projection_class, kwargs, key = \ + process_projection_requirements(self, *args, **kwargs) - # Remake the key without projection kwargs: - key = self._make_key(*args, **kwargs) + # try to find the axes with this key in the stack ax = self._axstack.get(key) + if ax is not None: if isinstance(ax, projection_class): + # the axes already existed, so set it as active & return self.sca(ax) return ax else: - self._axstack.remove(ax) # Undocumented convenience behavior: # subplot(111); subplot(111, projection='polar') # will replace the first with the second. # Without this, add_subplot would be simpler and # more similar to add_axes. + self._axstack.remove(ax) a = subplot_class_factory(projection_class)(self, *args, **kwargs) + self._axstack.add(key, a) self.sca(a) return a @@ -834,6 +928,13 @@ if not self.get_visible(): return renderer.open_group('figure') + if self.get_tight_layout() and self.axes: + try: + self.tight_layout(renderer) + except ValueError: + pass + # ValueError can occur when resizing a window. + if self.frameon: self.patch.draw(renderer) # a list of (zorder, func_to_call, list_of_args) @@ -855,7 +956,7 @@ not_composite = self.suppressComposite if len(self.images)<=1 or not_composite or \ - not allequal([im.origin for im in self.images]): + not cbook.allequal([im.origin for im in self.images]): for a in self.images: dsu.append( (a.get_zorder(), a, a.draw, [renderer])) else: @@ -1012,6 +1113,8 @@ @docstring.dedent_interpd def text(self, x, y, s, *args, **kwargs): """ + Add text to figure. + Call signature:: text(x, y, s, fontdict=None, **kwargs) @@ -1045,25 +1148,43 @@ """ Return the current axes, creating one if necessary - The following kwargs are supported + The following kwargs are supported for ensuring the returned axes + adheres to the given projection etc., and for axes creation if + the active axes does not exist: + %(Axes)s + """ - ax = self._axstack() - if ax is not None: - ispolar = kwargs.get('polar', False) - projection = kwargs.get('projection', None) - if ispolar: - if projection is not None and projection != 'polar': - raise ValueError( - "polar=True, yet projection='%s'. " + - "Only one of these arguments should be supplied." % - projection) - projection = 'polar' + ckey, cax = self._axstack.current_key_axes() + # if there exists an axes on the stack see if it maches + # the desired axes configuration + if cax is not None: + + # if no kwargs are given just return the current axes + # this is a convenience for gca() on axes such as polar etc. + if not kwargs: + return cax - projection_class = get_projection_class(projection) - if isinstance(ax, projection_class): - return ax - return self.add_subplot(111, **kwargs) + # if the user has specified particular projection detail + # then build up a key which can represent this + else: + # we don't want to modify the original kwargs + # so take a copy so that we can do what we like to it + kwargs_copy = kwargs.copy() + projection_class, _, key = \ + process_projection_requirements(self, **kwargs_copy) + + # let the returned axes have any gridspec by removing it from the key + ckey = ckey[1:] + key = key[1:] + + # if the cax matches this key then return the axes, otherwise + # continue and a new axes will be created + if key == ckey and isinstance(cax, projection_class): + return cax + + # no axes found, so create one which spans the figure + return self.add_subplot(1, 1, 1, **kwargs) def sca(self, a): 'Set the current axes to be a and return a' @@ -1082,20 +1203,83 @@ return im return None + def __getstate__(self): + state = self.__dict__.copy() + # the axobservers cannot currently be pickled. + # Additionally, the canvas cannot currently be pickled, but this has + # the benefit of meaning that a figure can be detached from one canvas, + # and re-attached to another. + for attr_to_pop in ('_axobservers', 'show', 'canvas', '_cachedRenderer') : + state.pop(attr_to_pop, None) + + # add version information to the state + state['__mpl_version__'] = _mpl_version + + # check to see if the figure has a manager and whether it is registered + # with pyplot + if getattr(self.canvas, 'manager', None) is not None: + manager = self.canvas.manager + import matplotlib._pylab_helpers + if manager in matplotlib._pylab_helpers.Gcf.figs.values(): + state['_restore_to_pylab'] = True + + return state + + def __setstate__(self, state): + version = state.pop('__mpl_version__') + restore_to_pylab = state.pop('_restore_to_pylab', False) + + if version != _mpl_version: + import warnings + warnings.warn("This figure was saved with matplotlib version %s " + "and is unlikely to function correctly." % + (version, )) + + self.__dict__ = state + + # re-initialise some of the unstored state information + self._axobservers = [] + self.canvas = None + + if restore_to_pylab: + # lazy import to avoid circularity + import matplotlib.pyplot as plt + import matplotlib._pylab_helpers as pylab_helpers + allnums = plt.get_fignums() + num = max(allnums) + 1 if allnums else 1 + mgr = plt._backend_mod.new_figure_manager_given_figure(num, self) + + # XXX The following is a copy and paste from pyplot. Consider + # factoring to pylab_helpers + + if self.get_label(): + mgr.set_window_title(self.get_label()) + + # make this figure current on button press event + def make_active(event): + pylab_helpers.Gcf.set_active(mgr) + + mgr._cidgcf = mgr.canvas.mpl_connect('button_press_event', + make_active) + + pylab_helpers.Gcf.set_active(mgr) + self.number = num + + plt.draw_if_interactive() + def add_axobserver(self, func): 'whenever the axes state change, ``func(self)`` will be called' self._axobservers.append(func) - def savefig(self, *args, **kwargs): """ + Save the current figure. + Call signature:: savefig(fname, dpi=None, facecolor='w', edgecolor='w', orientation='portrait', papertype=None, format=None, - transparent=False, bbox_inches=None, pad_inches=0.1): - - Save the current figure. + transparent=False, bbox_inches=None, pad_inches=0.1) The output formats available depend on the backend being used. @@ -1109,8 +1293,7 @@ If *format* is *None* and *fname* is a string, the output format is deduced from the extension of the filename. If the filename has no extension, the value of the rc parameter - ``savefig.extension`` is used. If that value is 'auto', - the backend determines the extension. + ``savefig.format`` is used. If *fname* is not a string, remember to specify *format* to ensure that the correct backend is used. @@ -1162,11 +1345,6 @@ kwargs.setdefault('dpi', rcParams['savefig.dpi']) - extension = rcParams['savefig.extension'] - if args and is_string_like(args[0]) and '.' not in os.path.splitext(args[0])[-1] and extension != 'auto': - fname = args[0] + '.' + extension - args = (fname,) + args[1:] - transparent = kwargs.pop('transparent', False) if transparent: kwargs.setdefault('facecolor', 'none') @@ -1199,23 +1377,15 @@ """ if ax is None: ax = self.gca() - use_gridspec = kw.pop("use_gridspec", False) + use_gridspec = kw.pop("use_gridspec", True) if cax is None: if use_gridspec and isinstance(ax, SubplotBase): cax, kw = cbar.make_axes_gridspec(ax, **kw) else: cax, kw = cbar.make_axes(ax, **kw) cax.hold(True) - cb = cbar.Colorbar(cax, mappable, **kw) - - def on_changed(m): - #print 'calling on changed', m.get_cmap().name - cb.set_cmap(m.get_cmap()) - cb.set_clim(m.get_clim()) - cb.update_normal(m) + cb = cbar.colorbar_factory(cax, mappable, **kw) - self.cbid = mappable.callbacksSM.connect('changed', on_changed) - mappable.set_colorbar(cb, cax) self.sca(ax) return cb @@ -1330,8 +1500,7 @@ return bbox_inches - - def tight_layout(self, renderer=None, pad=1.2, h_pad=None, w_pad=None): + def tight_layout(self, renderer=None, pad=1.08, h_pad=None, w_pad=None, rect=None): """ Adjust subplot parameters to give specified padding. @@ -1343,80 +1512,32 @@ *h_pad*, *w_pad* : float padding (height/width) between edges of adjacent subplots. Defaults to `pad_inches`. + *rect* : if rect is given, it is interpreted as a rectangle + (left, bottom, right, top) in the normalized figure + coordinate that the whole subplots area (including + labels) will fit into. Default is (0, 0, 1, 1). """ - from tight_layout import auto_adjust_subplotpars, get_renderer + from tight_layout import (get_renderer, get_tight_layout_figure, + get_subplotspec_list) + + subplotspec_list = get_subplotspec_list(self.axes) + if None in subplotspec_list: + warnings.warn("This figure includes Axes that are not " + "compatible with tight_layout, so its " + "results might be incorrect.") if renderer is None: renderer = get_renderer(self) - subplotspec_list = [] - subplot_list = [] - nrows_list = [] - ncols_list = [] - ax_bbox_list = [] - - subplot_dict = {} # for axes_grid1, multiple axes can share - # same subplot_interface. Thus we need to - # join them together. - - for ax in self.axes: - locator = ax.get_axes_locator() - if hasattr(locator, "get_subplotspec"): - subplotspec = locator.get_subplotspec().get_topmost_subplotspec() - elif hasattr(ax, "get_subplotspec"): - subplotspec = ax.get_subplotspec().get_topmost_subplotspec() - else: - continue - - if (subplotspec is None) or \ - subplotspec.get_gridspec().locally_modified_subplot_params(): - continue - - subplots = subplot_dict.setdefault(subplotspec, []) - - if not subplots: - myrows, mycols, _, _ = subplotspec.get_geometry() - nrows_list.append(myrows) - ncols_list.append(mycols) - subplotspec_list.append(subplotspec) - subplot_list.append(subplots) - ax_bbox_list.append(subplotspec.get_position(self)) - - subplots.append(ax) - - max_nrows = max(nrows_list) - max_ncols = max(ncols_list) - - num1num2_list = [] - for subplotspec in subplotspec_list: - rows, cols, num1, num2 = subplotspec.get_geometry() - div_row, mod_row = divmod(max_nrows, rows) - div_col, mod_col = divmod(max_ncols, cols) - if (mod_row != 0) or (mod_col != 0): - raise RuntimeError("") - - rowNum1, colNum1 = divmod(num1, cols) - if num2 is None: - rowNum2, colNum2 = rowNum1, colNum1 - else: - rowNum2, colNum2 = divmod(num2, cols) - - num1num2_list.append((rowNum1*div_row*max_ncols + colNum1*div_col, - ((rowNum2+1)*div_row-1)*max_ncols + (colNum2+1)*div_col-1)) - - - kwargs = auto_adjust_subplotpars(self, renderer, - nrows_ncols=(max_nrows, max_ncols), - num1num2_list=num1num2_list, - subplot_list=subplot_list, - ax_bbox_list=ax_bbox_list, - pad=pad, h_pad=h_pad, w_pad=w_pad) + kwargs = get_tight_layout_figure(self, self.axes, subplotspec_list, + renderer, + pad=pad, h_pad=h_pad, w_pad=w_pad, + rect=rect) self.subplots_adjust(**kwargs) - def figaspect(arg): """ Create a figure with specified aspect ratio. If *arg* is a number, @@ -1479,4 +1600,4 @@ newsize = np.clip(newsize,figsize_min,figsize_max) return newsize -docstring.interpd.update(Figure=artist.kwdoc(Figure)) +docstring.interpd.update(Figure=martist.kwdoc(Figure)) diff -Nru matplotlib-1.1.1/lib/matplotlib/finance.py matplotlib-1.2.0/lib/matplotlib/finance.py --- matplotlib-1.1.1/lib/matplotlib/finance.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/finance.py 2012-11-06 18:14:21.000000000 +0000 @@ -3,21 +3,23 @@ financial data. User contributions welcome! """ -#from __future__ import division -import os, warnings +from __future__ import division, print_function +import os, sys, warnings from urllib2 import urlopen -try: +if sys.version_info[0] < 3: from hashlib import md5 -except ImportError: - from md5 import md5 #Deprecated in 2.5 +else: + import hashlib + md5 = lambda x: hashlib.md5(x.encode()) + import datetime import numpy as np from matplotlib import verbose, get_configdir from matplotlib.dates import date2num -from matplotlib.cbook import iterable +from matplotlib.cbook import iterable, mkdirs from matplotlib.collections import LineCollection, PolyCollection from matplotlib.colors import colorConverter from matplotlib.lines import Line2D, TICKLEFT, TICKRIGHT @@ -179,18 +181,17 @@ if cachename is None: cachename = os.path.join(cachedir, md5(url).hexdigest()) if os.path.exists(cachename): - fh = file(cachename) + fh = open(cachename) verbose.report('Using cachefile %s for %s'%(cachename, ticker)) else: - if not os.path.isdir(cachedir): - os.mkdir(cachedir) + mkdirs(cachedir) urlfh = urlopen(url) - fh = file(cachename, 'w') + fh = open(cachename, 'wb') fh.write(urlfh.read()) fh.close() verbose.report('Saved %s data to cache file %s'%(ticker, cachename)) - fh = file(cachename, 'r') + fh = open(cachename, 'r') return fh @@ -230,7 +231,7 @@ adjusted=adjusted) if len(ret) == 0: return None - except IOError, exc: + except IOError as exc: warnings.warn('fh failure\n%s'%(exc.strerror[1])) return None diff -Nru matplotlib-1.1.1/lib/matplotlib/font_manager.py matplotlib-1.2.0/lib/matplotlib/font_manager.py --- matplotlib-1.1.1/lib/matplotlib/font_manager.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/font_manager.py 2012-10-31 00:11:14.000000000 +0000 @@ -19,6 +19,7 @@ platforms, so if a font is installed, it is much more likely to be found. """ +from __future__ import print_function """ KNOWN ISSUES @@ -258,7 +259,6 @@ files.extend(list_fonts(path, fontext)) return files - def get_fontconfig_fonts(fontext='ttf'): """ Grab a list of all the fonts that are being tracked by fontconfig @@ -277,6 +277,7 @@ return fontfiles if pipe.returncode == 0: + output = str(output) for line in output.split('\n'): fname = line.split(':')[0] if (os.path.splitext(fname)[1][1:] in fontext and @@ -324,7 +325,7 @@ for fname in files: fontfiles[os.path.abspath(fname)] = 1 - return [fname for fname in fontfiles.keys() if os.path.exists(fname)] + return [fname for fname in fontfiles.iterkeys() if os.path.exists(fname)] def weight_as_number(weight): """ @@ -339,7 +340,7 @@ elif weight in range(100, 1000, 100): pass else: - raise ValueError, 'weight not a valid integer' + raise ValueError('weight not a valid integer') return weight @@ -421,7 +422,7 @@ # lighter and bolder are also allowed. weight = None - for w in weight_dict.keys(): + for w in weight_dict.iterkeys(): if sfnt4.find(w) >= 0: weight = w break @@ -552,7 +553,7 @@ else: seen[fname] = 1 if fontext == 'afm': try: - fh = open(fpath, 'r') + fh = open(fpath, 'rb') except: verbose.report("Could not open font file %s" % fpath) continue @@ -575,8 +576,7 @@ verbose.report("Cannot handle unicode filenames") #print >> sys.stderr, 'Bad file is', fpath continue - try: prop = ttfFontProperty(font) - except: continue + prop = ttfFontProperty(font) fontlist.append(prop) return fontlist @@ -892,7 +892,7 @@ 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(): + for key, val in self._parse_fontconfig_pattern(pattern).iteritems(): if type(val) == list: getattr(self, "set_" + key)(val[0]) else: @@ -907,12 +907,12 @@ flatten a ttfdict to all the filenames it contains """ fnames = [] - for named in d.values(): - for styled in named.values(): - for variantd in styled.values(): - for weightd in variantd.values(): - for stretchd in weightd.values(): - for fname in stretchd.values(): + for named in d.itervalues(): + for styled in named.itervalues(): + for variantd in styled.itervalues(): + for weightd in variantd.itervalues(): + for stretchd in weightd.itervalues(): + for fname in stretchd.itervalues(): fnames.append(fname) return fnames @@ -921,22 +921,16 @@ Equivalent to pickle.dump(data, open(filename, 'w')) but closes the file to prevent filehandle leakage. """ - fh = open(filename, 'w') - try: + with open(filename, 'wb') as fh: pickle.dump(data, fh) - finally: - fh.close() def pickle_load(filename): """ Equivalent to pickle.load(open(filename, 'r')) but closes the file to prevent filehandle leakage. """ - fh = open(filename, 'r') - try: + with open(filename, 'rb') as fh: data = pickle.load(fh) - finally: - fh.close() return data class FontManager: @@ -951,7 +945,7 @@ # Increment this version number whenever the font cache data # format or behavior has changed and requires a existing font # cache files to be rebuilt. - __version__ = 7 + __version__ = 101 def __init__(self, size=None, weight='normal'): self._version = self.__version__ @@ -997,7 +991,7 @@ self.afmfiles = findSystemFonts(paths, fontext='afm') + \ findSystemFonts(fontext='afm') self.afmlist = createFontList(self.afmfiles, fontext='afm') - self.defaultFont['afm'] = None + self.defaultFont['afm'] = self.afmfiles[0] self.ttf_lookup_cache = {} self.afm_lookup_cache = {} @@ -1041,6 +1035,8 @@ No match will return 1.0. """ + if not isinstance(families, (list, tuple)): + families = [families] family2 = family2.lower() for i, family1 in enumerate(families): family1 = family1.lower() @@ -1258,9 +1254,8 @@ if os.path.splitext(filename)[1].lower() == '.otf': result = _is_opentype_cff_font_cache.get(filename) if result is None: - fd = open(filename, 'rb') - tag = fd.read(4) - fd.close() + with open(filename, 'rb') as fd: + tag = fd.read(4) result = (tag == 'OTTO') _is_opentype_cff_font_cache[filename] = result return result @@ -1268,14 +1263,6 @@ fontManager = None -_fmcache = os.path.join(get_configdir(), 'fontList.cache') - -def _rebuild(): - global fontManager - fontManager = FontManager() - pickle_dump(fontManager, _fmcache) - verbose.report("generated new fontManager") - # The experimental fontconfig-based backend. if USE_FONTCONFIG and sys.platform != 'win32': import re @@ -1313,6 +1300,19 @@ return result else: + if sys.version_info[0] >= 3: + _fmcache = os.path.join(get_configdir(), 'fontList.py3k.cache') + else: + _fmcache = os.path.join(get_configdir(), 'fontList.cache') + + fontManager = None + + def _rebuild(): + global fontManager + fontManager = FontManager() + pickle_dump(fontManager, _fmcache) + verbose.report("generated new fontManager") + try: fontManager = pickle_load(_fmcache) if (not hasattr(fontManager, '_version') or diff -Nru matplotlib-1.1.1/lib/matplotlib/fontconfig_pattern.py matplotlib-1.2.0/lib/matplotlib/fontconfig_pattern.py --- matplotlib-1.1.1/lib/matplotlib/fontconfig_pattern.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/fontconfig_pattern.py 2012-11-06 22:31:09.000000000 +0000 @@ -19,9 +19,14 @@ # 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 +from __future__ import print_function +import re, sys +if sys.version_info[0] >= 3: + from matplotlib.pyparsing_py3 import Literal, ZeroOrMore, \ + Optional, Regex, StringEnd, ParseException, Suppress +else: + from matplotlib.pyparsing_py2 import Literal, ZeroOrMore, \ + Optional, Regex, StringEnd, ParseException, Suppress family_punc = r'\\\-:,' family_unescape = re.compile(r'\\([%s])' % family_punc).sub @@ -123,10 +128,14 @@ props = self._properties = {} try: self._parser.parseString(pattern) - except self.ParseException, e: - raise ValueError("Could not parse font string: '%s'\n%s" % (pattern, e)) + except self.ParseException as e: + raise ValueError( + "Could not parse font string: '%s'\n%s" % (pattern, e)) self._properties = None + + self._parser.resetCache() + return props def _family(self, s, loc, tokens): diff -Nru matplotlib-1.1.1/lib/matplotlib/gridspec.py matplotlib-1.2.0/lib/matplotlib/gridspec.py --- matplotlib-1.1.1/lib/matplotlib/gridspec.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/gridspec.py 2012-10-31 00:11:14.000000000 +0000 @@ -14,7 +14,7 @@ """ -from __future__ import division +from __future__ import division, print_function import matplotlib rcParams = matplotlib.rcParams @@ -22,6 +22,7 @@ import matplotlib.transforms as mtransforms import numpy as np +import warnings class GridSpecBase(object): """ @@ -218,7 +219,7 @@ the current value, if set, otherwise to rc. """ - for k, v in kwargs.items(): + for k, v in kwargs.iteritems(): if k in self._AllowedKeys: setattr(self, k, v) else: @@ -227,20 +228,24 @@ from matplotlib import _pylab_helpers from matplotlib.axes import SubplotBase - for figmanager in _pylab_helpers.Gcf.figs.values(): + for figmanager in _pylab_helpers.Gcf.figs.itervalues(): for ax in figmanager.canvas.figure.axes: # copied from Figure.subplots_adjust if not isinstance(ax, SubplotBase): # Check if sharing a subplots axis if ax._sharex is not None and isinstance(ax._sharex, SubplotBase): - ax._sharex.update_params() - ax.set_position(ax._sharex.figbox) + if ax._sharex.get_subplotspec().get_gridspec() == self: + ax._sharex.update_params() + ax.set_position(ax._sharex.figbox) elif ax._sharey is not None and isinstance(ax._sharey,SubplotBase): - ax._sharey.update_params() - ax.set_position(ax._sharey.figbox) + if ax._sharey.get_subplotspec().get_gridspec() == self: + ax._sharey.update_params() + ax.set_position(ax._sharey.figbox) else: - ax.update_params() - ax.set_position(ax.figbox) + ss = ax.get_subplotspec().get_topmost_subplotspec() + if ss.get_gridspec() == self: + ax.update_params() + ax.set_position(ax.figbox) @@ -267,81 +272,42 @@ return [k for k in self._AllowedKeys if getattr(self, k)] - def tight_layout(self, fig, renderer=None, pad=1.2, h_pad=None, w_pad=None, rect=None): + def tight_layout(self, fig, renderer=None, pad=1.08, h_pad=None, w_pad=None, rect=None): """ Adjust subplot parameters to give specified padding. Parameters: - + pad : float padding between the figure edge and the edges of subplots, as a fraction of the font-size. h_pad, w_pad : float padding (height/width) between edges of adjacent subplots. Defaults to `pad_inches`. + rect : if rect is given, it is interpreted as a rectangle + (left, bottom, right, top) in the normalized figure + coordinate that the whole subplots area (including + labels) will fit into. Default is (0, 0, 1, 1). """ - from tight_layout import auto_adjust_subplotpars, get_renderer + from tight_layout import (get_subplotspec_list, + get_tight_layout_figure, + get_renderer) + + subplotspec_list = get_subplotspec_list(fig.axes, grid_spec=self) + if None in subplotspec_list: + warnings.warn("This figure includes Axes that are not " + "compatible with tight_layout, so its " + "results might be incorrect.") if renderer is None: renderer = get_renderer(fig) - subplot_list = [] - num1num2_list = [] - subplot_dict = {} - - for ax in fig.axes: - locator = ax.get_axes_locator() - if hasattr(locator, "get_subplotspec"): - subplotspec = locator.get_subplotspec() - elif hasattr(ax, "get_subplotspec"): - subplotspec = ax.get_subplotspec() - else: - continue - - if subplotspec.get_gridspec() != self: continue - - subplots = subplot_dict.get(subplotspec, []) - - if not subplots: - _, _, num1, num2 = subplotspec.get_geometry() - num1num2_list.append((num1, num2)) - subplot_list.append(subplots) - - subplots.append(ax) - - - kwargs = auto_adjust_subplotpars(fig, renderer, - nrows_ncols=self.get_geometry(), - num1num2_list=num1num2_list, - subplot_list=subplot_list, - pad=pad, h_pad=h_pad, w_pad=w_pad) - - if rect is not None: - # if rect is given, the whole subplots area (including - # labels) will fit into the rect instead of the - # figure. Note that the rect argument of - # *auto_adjust_subplotpars* specify the area that will be - # covered by the total area of axes.bbox. Thus we call - # auto_adjust_subplotpars twice, where the second run - # with adjusted rect parameters. - - left, bottom, right, top = rect - if left is not None: left += kwargs["left"] - if bottom is not None: bottom += kwargs["bottom"] - if right is not None: right -= (1 - kwargs["right"]) - if top is not None: top -= (1 - kwargs["top"]) - - #if h_pad is None: h_pad = pad - #if w_pad is None: w_pad = pad - - kwargs = auto_adjust_subplotpars(fig, renderer, - nrows_ncols=self.get_geometry(), - num1num2_list=num1num2_list, - subplot_list=subplot_list, - pad=pad, h_pad=h_pad, w_pad=w_pad, - rect=(left, bottom, right, top)) + kwargs = get_tight_layout_figure(fig, fig.axes, subplotspec_list, + renderer, + pad=pad, h_pad=h_pad, w_pad=w_pad, + rect=rect, + ) - self.update(**kwargs) diff -Nru matplotlib-1.1.1/lib/matplotlib/hatch.py matplotlib-1.2.0/lib/matplotlib/hatch.py --- matplotlib-1.1.1/lib/matplotlib/hatch.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/hatch.py 2012-11-06 15:42:20.000000000 +0000 @@ -2,22 +2,27 @@ Contains a classes for generating hatch patterns. """ +from __future__ import print_function import numpy as np from matplotlib.path import Path + class HatchPatternBase: """ The base class for a hatch pattern. """ pass + class HorizontalHatch(HatchPatternBase): def __init__(self, hatch, density): self.num_lines = (hatch.count('-') + hatch.count('+')) * density self.num_vertices = self.num_lines * 2 def set_vertices_and_codes(self, vertices, codes): - steps = np.linspace(0.0, 1.0, self.num_lines, False) + steps, stepsize = np.linspace(0.0, 1.0, self.num_lines, False, + retstep=True) + steps += stepsize / 2. vertices[0::2, 0] = 0.0 vertices[0::2, 1] = steps vertices[1::2, 0] = 1.0 @@ -25,13 +30,16 @@ codes[0::2] = Path.MOVETO codes[1::2] = Path.LINETO + class VerticalHatch(HatchPatternBase): def __init__(self, hatch, density): self.num_lines = (hatch.count('|') + hatch.count('+')) * density self.num_vertices = self.num_lines * 2 def set_vertices_and_codes(self, vertices, codes): - steps = np.linspace(0.0, 1.0, self.num_lines, False) + steps, stepsize = np.linspace(0.0, 1.0, self.num_lines, False, + retstep=True) + steps += stepsize / 2. vertices[0::2, 0] = steps vertices[0::2, 1] = 0.0 vertices[1::2, 0] = steps @@ -39,45 +47,49 @@ codes[0::2] = Path.MOVETO codes[1::2] = Path.LINETO + class NorthEastHatch(HatchPatternBase): def __init__(self, hatch, density): - self.num_lines = (hatch.count('/') + hatch.count('x') + hatch.count('X')) * density - self.num_vertices = self.num_lines * 4 + self.num_lines = (hatch.count('/') + hatch.count('x') + + hatch.count('X')) * density + if self.num_lines: + self.num_vertices = (self.num_lines + 1) * 2 + else: + self.num_vertices = 0 def set_vertices_and_codes(self, vertices, codes): - steps = np.linspace(0.0, 1.0, self.num_lines, False) - rev_steps = 1.0 - steps - vertices[0::4, 0] = 0.0 - vertices[0::4, 1] = steps - vertices[1::4, 0] = rev_steps - vertices[1::4, 1] = 1.0 - vertices[2::4, 0] = rev_steps - vertices[2::4, 1] = 0.0 - vertices[3::4, 0] = 1.0 - vertices[3::4, 1] = steps + steps = np.linspace(-0.5, 0.5, self.num_lines + 1, True) + vertices[0::2, 0] = 0.0 + steps + vertices[0::2, 1] = 0.0 - steps + vertices[1::2, 0] = 1.0 + steps + vertices[1::2, 1] = 1.0 - steps codes[0::2] = Path.MOVETO codes[1::2] = Path.LINETO + class SouthEastHatch(HatchPatternBase): def __init__(self, hatch, density): - self.num_lines = (hatch.count('\\') + hatch.count('x') + hatch.count('X')) * density - self.num_vertices = self.num_lines * 4 + self.num_lines = (hatch.count('\\') + hatch.count('x') + + hatch.count('X')) * density + self.num_vertices = (self.num_lines + 1) * 2 + if self.num_lines: + self.num_vertices = (self.num_lines + 1) * 2 + else: + self.num_vertices = 0 def set_vertices_and_codes(self, vertices, codes): - steps = np.linspace(0.0, 1.0, self.num_lines, False) - vertices[0::4, 0] = 1.0 - vertices[0::4, 1] = steps - vertices[1::4, 0] = steps - vertices[1::4, 1] = 1.0 - vertices[2::4, 0] = steps - vertices[2::4, 1] = 0.0 - vertices[3::4, 0] = 0.0 - vertices[3::4, 1] = steps + steps = np.linspace(-0.5, 0.5, self.num_lines + 1, True) + vertices[0::2, 0] = 0.0 + steps + vertices[0::2, 1] = 1.0 + steps + vertices[1::2, 0] = 1.0 + steps + vertices[1::2, 1] = 0.0 + steps codes[0::2] = Path.MOVETO codes[1::2] = Path.LINETO + class Shapes(HatchPatternBase): filled = False + def __init__(self, hatch, density): if self.num_rows == 0: self.num_shapes = 0 @@ -102,17 +114,21 @@ if row % 2 == 0: cols = np.linspace(0.0, 1.0, self.num_rows + 1, True) else: - cols = np.linspace(offset / 2.0, 1.0 - offset / 2.0, self.num_rows, True) + cols = np.linspace(offset / 2.0, 1.0 - offset / 2.0, + self.num_rows, True) row_pos = row * offset for col_pos in cols: - vertices[cursor:cursor+shape_size] = shape_vertices + (col_pos, row_pos) - codes[cursor:cursor+shape_size] = shape_codes + vertices[cursor:cursor + shape_size] = (shape_vertices + + (col_pos, row_pos)) + codes[cursor:cursor + shape_size] = shape_codes cursor += shape_size if not self.filled: - vertices[cursor:cursor+shape_size] = inner_vertices + (col_pos, row_pos) - codes[cursor:cursor+shape_size] = shape_codes + vertices[cursor:cursor + shape_size] = (inner_vertices + + (col_pos, row_pos)) + codes[cursor:cursor + shape_size] = shape_codes cursor += shape_size + class Circles(Shapes): def __init__(self, hatch, density): path = Path.unit_circle() @@ -120,6 +136,7 @@ self.shape_codes = path.codes Shapes.__init__(self, hatch, density) + class SmallCircles(Circles): size = 0.2 @@ -127,6 +144,7 @@ self.num_rows = (hatch.count('o')) * density Circles.__init__(self, hatch, density) + class LargeCircles(Circles): size = 0.35 @@ -134,6 +152,7 @@ self.num_rows = (hatch.count('O')) * density Circles.__init__(self, hatch, density) + class SmallFilledCircles(SmallCircles): size = 0.1 filled = True @@ -142,6 +161,7 @@ self.num_rows = (hatch.count('.')) * density Circles.__init__(self, hatch, density) + class Stars(Shapes): size = 1.0 / 3.0 filled = True @@ -165,23 +185,24 @@ Stars ] + def get_path(hatchpattern, density=6): """ Given a hatch specifier, *hatchpattern*, generates Path to render the hatch in a unit square. *density* is the number of lines per unit square. """ - size = 1.0 density = int(density) - patterns = [hatch_type(hatchpattern, density) for hatch_type in _hatch_types] + patterns = [hatch_type(hatchpattern, density) + for hatch_type in _hatch_types] num_vertices = sum([pattern.num_vertices for pattern in patterns]) if num_vertices == 0: return Path(np.empty((0, 2))) vertices = np.empty((num_vertices, 2)) - codes = np.empty((num_vertices,), np.uint8) + codes = np.empty((num_vertices,), np.uint8) cursor = 0 for pattern in patterns: diff -Nru matplotlib-1.1.1/lib/matplotlib/image.py matplotlib-1.2.0/lib/matplotlib/image.py --- matplotlib-1.1.1/lib/matplotlib/image.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/image.py 2012-11-06 15:42:20.000000000 +0000 @@ -3,8 +3,9 @@ operations. """ -from __future__ import division +from __future__ import division, print_function import os, warnings +import math import numpy as np from numpy import ma @@ -24,7 +25,7 @@ # the image namespace: from matplotlib._image import * -from matplotlib.transforms import BboxBase, Bbox +from matplotlib.transforms import BboxBase, Bbox, IdentityTransform import matplotlib.transforms as mtransforms @@ -53,7 +54,7 @@ } # reverse interp dict - _interpdr = dict([ (v,k) for k,v in _interpd.items()]) + _interpdr = dict([ (v,k) for k,v in _interpd.iteritems()]) interpnames = _interpd.keys() @@ -198,7 +199,14 @@ im.is_grayscale = False else: if self._rgbacache is None: - x = self.to_rgba(self._A, bytes=True) + x = self.to_rgba(self._A, bytes=False) + # Avoid side effects: to_rgba can return its argument + # unchanged. + if np.may_share_memory(x, self._A): + x = x.copy() + # premultiply the colors + x[...,0:3] *= x[...,3:4] + x = (x * 255).astype(np.uint8) self._rgbacache = x else: x = self._rgbacache @@ -262,8 +270,8 @@ # firs, convert the image extent to the ic x_llc, x_trc, y_llc, y_trc = self.get_extent() - xy = trans.transform_non_affine(np.array([(x_llc, y_llc), - (x_trc, y_trc)])) + xy = trans.transform(np.array([(x_llc, y_llc), + (x_trc, y_trc)])) _xx1, _yy1 = xy[0] _xx2, _yy2 = xy[1] @@ -275,15 +283,16 @@ if self._image_skew_coordinate: # skew the image when required. x_lrc, y_lrc = self._image_skew_coordinate - xy2 = trans.transform_non_affine(np.array([(x_lrc, y_lrc)])) + xy2 = trans.transform(np.array([(x_lrc, y_lrc)])) _xx3, _yy3 = xy2[0] tr_rotate_skew = self._get_rotate_and_skew_transform(_xx1, _yy1, _xx2, _yy2, _xx3, _yy3) - trans_ic_to_canvas = tr_rotate_skew+trans.get_affine() + trans_ic_to_canvas = tr_rotate_skew else: - trans_ic_to_canvas = trans.get_affine() + trans_ic_to_canvas = IdentityTransform() + # Now, viewLim in the ic. It can be rotated and can be # skewed. Make it big enough. @@ -317,6 +326,7 @@ # may be better solution -JJL im._url = self.get_url() + im._gid = self.get_gid() renderer.draw_image(gc, xmin, ymin, im, dxintv, dyintv, trans_ic_to_canvas) @@ -351,6 +361,7 @@ if im is None: return im._url = self.get_url() + im._gid = self.get_gid() renderer.draw_image(gc, l, b, im) gc.restore() @@ -674,13 +685,34 @@ def make_image(self, magnification=1.0): if self._A is None: raise RuntimeError('You must first set the image array') + + A = self._A + if len(A.shape) == 2: + if A.dtype != np.uint8: + A = self.to_rgba(A, bytes=True) + self.is_grayscale = self.cmap.is_gray() + else: + A = np.repeat(A[:,:,np.newaxis], 4, 2) + A[:,:,3] = 255 + self.is_grayscale = True + else: + if A.dtype != np.uint8: + A = (255*A).astype(np.uint8) + if A.shape[2] == 3: + B = np.zeros(tuple(list(A.shape[0:2]) + [4]), np.uint8) + B[:,:,0:3] = A + B[:,:,3] = 255 + A = B + self.is_grayscale = False + + x0, y0, v_width, v_height = self.axes.viewLim.bounds l, b, r, t = self.axes.bbox.extents width = (round(r) + 0.5) - (round(l) - 0.5) height = (round(t) + 0.5) - (round(b) - 0.5) width *= magnification height *= magnification - im = _image.pcolor(self._Ax, self._Ay, self._A, + im = _image.pcolor(self._Ax, self._Ay, A, height, width, (x0, x0+v_width, y0, y0+v_height), self._interpd[self._interpolation]) @@ -714,23 +746,6 @@ raise TypeError("3D arrays must have three (RGB) or four (RGBA) color components") if len(A.shape) == 3 and A.shape[2] == 1: A.shape = A.shape[0:2] - if len(A.shape) == 2: - if A.dtype != np.uint8: - A = self.to_rgba(A, bytes=True) - self.is_grayscale = self.cmap.is_gray() - else: - A = np.repeat(A[:,:,np.newaxis], 4, 2) - A[:,:,3] = 255 - self.is_grayscale = True - else: - if A.dtype != np.uint8: - A = (255*A).astype(np.uint8) - if A.shape[2] == 3: - B = zeros(tuple(list(A.shape[0:2]) + [4]), np.uint8) - B[:,:,0:3] = A - B[:,:,3] = 255 - A = B - self.is_grayscale = False self._A = A self._Ax = x self._Ay = y @@ -865,9 +880,9 @@ y = np.asarray(y, np.float64).ravel() if A.shape[:2] != (y.size-1, x.size-1): - print A.shape - print y.size - print x.size + print(A.shape) + print(y.size) + print(x.size) raise ValueError("Axes don't match array shape") if A.ndim not in [2, 3]: raise ValueError("A must be 2D or 3D") @@ -1018,6 +1033,7 @@ filternorm=1, filterrad=4.0, resample = False, + interp_at_native=True, **kwargs ): @@ -1025,6 +1041,13 @@ cmap is a colors.Colormap instance norm is a colors.Normalize instance to map luminance to 0-1 + interp_at_native is a flag that determines whether or not interpolation should + still be applied when the image is displayed at its native resolution. A common + use case for this is when displaying an image for annotational purposes; it is + treated similarly to Photoshop (interpolation is only used when displaying the + image at non-native resolutions). + + kwargs are an optional list of Artist keyword args """ @@ -1040,6 +1063,7 @@ ) self.bbox = bbox + self.interp_at_native = interp_at_native def get_window_extent(self, renderer=None): if renderer is None: @@ -1052,10 +1076,10 @@ else: raise ValueError("unknown type of bbox") - def contains(self, mouseevent): """Test whether the mouse event occured within the image.""" - if callable(self._contains): return self._contains(self,mouseevent) + if callable(self._contains): + return self._contains(self, mouseevent) if not self.get_visible():# or self.get_figure()._renderer is None: return False,{} @@ -1106,13 +1130,16 @@ im.set_resample(self._resample) l, b, r, t = self.get_window_extent(renderer).extents #bbox.extents - widthDisplay = (round(r) + 0.5) - (round(l) - 0.5) - heightDisplay = (round(t) + 0.5) - (round(b) - 0.5) + widthDisplay = round(r) - round(l) + heightDisplay = round(t) - round(b) widthDisplay *= magnification heightDisplay *= magnification numrows, numcols = self._A.shape[:2] + if not self.interp_at_native and widthDisplay==numcols and heightDisplay==numrows: + im.set_interpolation(0) + # resize viewport to display rx = widthDisplay / numcols ry = heightDisplay / numrows @@ -1141,8 +1168,10 @@ def imread(fname, format=None): """ - Return image file in *fname* as :class:`numpy.array`. *fname* may - be a string path or a Python file-like object. + Read an image from a file into an array. + + *fname* may be a string path or a Python file-like object. If + using a file object, it must be opened in binary mode. If *format* is provided, will try to read file of that type, otherwise the format is deduced from the filename. If nothing can @@ -1158,25 +1187,36 @@ can be used with :func:`~matplotlib.pyplot.imshow`. """ - def pilread(): + def pilread(fname): """try to load the image with PIL or return None""" - try: from PIL import Image - except ImportError: return None - image = Image.open( fname ) - return pil_to_array(image) + try: + from PIL import Image + except ImportError: + return None + if cbook.is_string_like(fname): + # force close the file after reading the image + with open(fname, "rb") as fh: + image = Image.open(fh) + return pil_to_array(image) + else: + image = Image.open(fname) + return pil_to_array(image) handlers = {'png' :_png.read_png, } if format is None: if cbook.is_string_like(fname): basename, ext = os.path.splitext(fname) ext = ext.lower()[1:] + elif hasattr(fname, 'name'): + basename, ext = os.path.splitext(fname.name) + ext = ext.lower()[1:] else: ext = 'png' else: ext = format - if ext not in handlers.keys(): - im = pilread() + if ext not in handlers.iterkeys(): + im = pilread(fname) if im is None: raise ValueError('Only know how to handle extensions: %s; with PIL installed matplotlib can handle more images' % handlers.keys()) return im @@ -1187,15 +1227,17 @@ # reader extension, since Python handles them quite well, but it's # tricky in C. if cbook.is_string_like(fname): - fname = open(fname, 'rb') - - return handler(fname) + with open(fname, 'rb') as fd: + return handler(fd) + else: + return handler(fname) def imsave(fname, arr, vmin=None, vmax=None, cmap=None, format=None, origin=None, dpi=100): """ - Saves a 2D :class:`numpy.array` as an image with one pixel per element. + Save an array as in image file. + The output formats available depend on the backend being used. Arguments: @@ -1204,7 +1246,7 @@ If *format* is *None* and *fname* is a string, the output format is deduced from the extension of the filename. *arr*: - A 2D array. + An MxN (luminance), MxNx3 (RGB) or MxNx4 (RGBA) array. Keyword arguments: *vmin*/*vmax*: [ None | scalar ] *vmin* and *vmax* set the color scaling for the image by fixing the @@ -1227,7 +1269,7 @@ from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas from matplotlib.figure import Figure - figsize = [x / float(dpi) for x in arr.shape[::-1]] + figsize = [x / float(dpi) for x in (arr.shape[1], arr.shape[0])] fig = Figure(figsize=figsize, dpi=dpi, frameon=False) canvas = FigureCanvas(fig) im = fig.figimage(arr, cmap=cmap, vmin=vmin, vmax=vmax, origin=origin) @@ -1236,14 +1278,14 @@ def pil_to_array( pilImage ): """ - load a PIL image and return it as a numpy array of uint8. For - grayscale images, the return array is MxN. For RGB images, the - return value is MxNx3. For RGBA images the return value is MxNx4 + Load a PIL image and return it as a numpy array. For grayscale + images, the return array is MxN. For RGB images, the return value + is MxNx3. For RGBA images the return value is MxNx4 """ - def toarray(im): - """Teturn a 1D array of floats.""" - x_str = im.tostring('raw',im.mode,0,-1) - x = np.fromstring(x_str,np.uint8) + def toarray(im, dtype=np.uint8): + """Teturn a 1D array of dtype.""" + x_str = im.tostring('raw', im.mode) + x = np.fromstring(x_str, dtype) return x if pilImage.mode in ('RGBA', 'RGBX'): @@ -1260,7 +1302,15 @@ x = toarray(im) x.shape = im.size[1], im.size[0], 3 return x - + elif pilImage.mode.startswith('I;16'): + # return MxN luminance array of uint16 + im = pilImage + if im.mode.endswith('B'): + x = toarray(im, '>u2') + else: + x = toarray(im, 'FigureCanvasAgg, 'pdf'->FigureCanvasPDF, + 'png'->FigureCanvasAgg, 'pdf'->FigureCanvasPdf, 'svg'->FigureCanvasSVG @@ -1333,7 +1383,7 @@ if extension=='.png': from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas elif extension=='.pdf': - from matplotlib.backends.backend_pdf import FigureCanvasPDF as FigureCanvas + from matplotlib.backends.backend_pdf import FigureCanvasPdf as FigureCanvas elif extension=='.svg': from matplotlib.backends.backend_svg import FigureCanvasSVG as FigureCanvas else: diff -Nru matplotlib-1.1.1/lib/matplotlib/legend.py matplotlib-1.2.0/lib/matplotlib/legend.py --- matplotlib-1.1.1/lib/matplotlib/legend.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/legend.py 2012-11-08 02:24:13.000000000 +0000 @@ -11,7 +11,7 @@ that not all kinds of artist are supported by the legend yet (See :ref:`plotting-guide-legend` for more information). """ -from __future__ import division +from __future__ import division, print_function import warnings import numpy as np @@ -24,9 +24,11 @@ from matplotlib.patches import Patch, Rectangle, Shadow, FancyBboxPatch from matplotlib.collections import LineCollection, RegularPolyCollection, \ CircleCollection, PathCollection -from matplotlib.transforms import Bbox, BboxBase, TransformedBbox, BboxTransformTo, BboxTransformFrom +from matplotlib.transforms import Bbox, BboxBase, TransformedBbox +from matplotlib.transforms import BboxTransformTo, BboxTransformFrom -from matplotlib.offsetbox import HPacker, VPacker, TextArea, DrawingArea, DraggableOffsetBox +from matplotlib.offsetbox import HPacker, VPacker, TextArea, DrawingArea +from matplotlib.offsetbox import DraggableOffsetBox from matplotlib.container import ErrorbarContainer, BarContainer, StemContainer import legend_handler @@ -39,12 +41,13 @@ legend upon finalizing. If "bbox", update *bbox_to_anchor* parameter. """ - self.legend=legend + self.legend = legend if update in ["loc", "bbox"]: self._update = update else: - raise ValueError("update parameter '%s' is not supported." % update) + raise ValueError("update parameter '%s' is not supported." % + update) DraggableOffsetBox.__init__(self, legend, legend._legend_box, use_blit=use_blit) @@ -60,20 +63,21 @@ elif self._update == "bbox": self._update_bbox_to_anchor(loc_in_canvas) else: - raise RuntimeError("update parameter '%s' is not supported." % self.update) + raise RuntimeError("update parameter '%s' is not supported." % + self.update) def _update_loc(self, loc_in_canvas): bbox = self.legend.get_bbox_to_anchor() # if bbox has zero width or height, the transformation is # ill-defined. Fall back to the defaul bbox_to_anchor. - if bbox.width ==0 or bbox.height ==0: + if bbox.width == 0 or bbox.height == 0: self.legend.set_bbox_to_anchor(None) bbox = self.legend.get_bbox_to_anchor() _bbox_transform = BboxTransformFrom(bbox) - self.legend._loc = tuple(_bbox_transform.transform_point(loc_in_canvas)) - + self.legend._loc = tuple( + _bbox_transform.transform_point(loc_in_canvas)) def _update_bbox_to_anchor(self, loc_in_canvas): @@ -107,79 +111,88 @@ respect its parent. """ - - - codes = {'best' : 0, # only implemented for axis legends - 'upper right' : 1, - 'upper left' : 2, - 'lower left' : 3, - 'lower right' : 4, - 'right' : 5, - 'center left' : 6, - 'center right' : 7, - 'lower center' : 8, - 'upper center' : 9, - 'center' : 10, + codes = {'best': 0, # only implemented for axis legends + 'upper right': 1, + 'upper left': 2, + 'lower left': 3, + 'lower right': 4, + 'right': 5, + 'center left': 6, + 'center right': 7, + 'lower center': 8, + 'upper center': 9, + 'center': 10, } - zorder = 5 + def __str__(self): return "Legend" def __init__(self, parent, handles, labels, - loc = None, - numpoints = None, # the number of points in the legend line - markerscale = None, # the relative size of legend markers vs. original - scatterpoints = 3, # TODO: may be an rcParam + loc=None, + numpoints=None, # the number of points in the legend line + markerscale=None, # the relative size of legend markers + # vs. original + scatterpoints=3, # TODO: may be an rcParam scatteryoffsets=None, - prop = None, # properties for the legend texts + prop=None, # properties for the legend texts + fontsize=None, # keyword to set font size directly # the following dimensions are in axes coords - pad = None, # deprecated; use borderpad - labelsep = None, # deprecated; use labelspacing - handlelen = None, # deprecated; use handlelength - handletextsep = None, # deprecated; use handletextpad - axespad = None, # deprecated; use borderaxespad + pad=None, # deprecated; use borderpad + labelsep=None, # deprecated; use labelspacing + handlelen=None, # deprecated; use handlelength + handletextsep=None, # deprecated; use handletextpad + axespad=None, # deprecated; use borderaxespad # spacing & pad defined as a fraction of the font-size - borderpad = None, # the whitespace inside the legend border - labelspacing=None, #the vertical space between the legend entries - handlelength=None, # the length of the legend handles - handleheight=None, # the height of the legend handles - handletextpad=None, # the pad between the legend handle and text - borderaxespad=None, # the pad between the axes and legend border - columnspacing=None, # spacing between columns - - ncol=1, # number of columns - mode=None, # mode for horizontal distribution of columns. None, "expand" - - fancybox=None, # True use a fancy box, false use a rounded box, none use rc - shadow = None, - title = None, # set a title for the legend - bbox_to_anchor = None, # bbox that the legend will be anchored. - bbox_transform = None, # transform for the bbox - frameon = None, # draw frame - handler_map = None, + borderpad=None, # the whitespace inside the legend border + labelspacing=None, # the vertical space between the legend + # entries + handlelength=None, # the length of the legend handles + handleheight=None, # the height of the legend handles + handletextpad=None, # the pad between the legend handle + # and text + borderaxespad=None, # the pad between the axes and legend + # border + columnspacing=None, # spacing between columns + + ncol=1, # number of columns + mode=None, # mode for horizontal distribution of columns. + # None, "expand" + + fancybox=None, # True use a fancy box, false use a rounded + # box, none use rc + shadow=None, + title=None, # set a title for the legend + bbox_to_anchor=None, # bbox that the legend will be anchored. + bbox_transform=None, # transform for the bbox + frameon=None, # draw frame + handler_map=None, ): """ - - *parent* : the artist that contains the legend - - *handles* : a list of artists (lines, patches) to be added to the legend - - *labels* : a list of strings to label the legend + - *parent*: the artist that contains the legend + - *handles*: a list of artists (lines, patches) to be added to the + legend + - *labels*: a list of strings to label the legend Optional keyword arguments: - ================ ================================================================== + ================ ==================================================== Keyword Description - ================ ================================================================== + ================ ==================================================== loc a location code prop the font property + fontsize the font size (used only if prop is not specified) markerscale the relative size of legend markers vs. original numpoints the number of points in the legend for line scatterpoints the number of points in the legend for scatter plot scatteryoffsets a list of yoffsets for scatter symbols in legend - frameon if True, draw a frame around the legend. If None, use rc - fancybox if True, draw a frame with a round fancybox. If None, use rc + frameon if True, draw a frame around the legend. + If None, use rc + fancybox if True, draw a frame with a round fancybox. + If None, use rc shadow if True, draw a shadow behind legend ncol number of columns borderpad the fractional whitespace inside the legend border @@ -192,114 +205,118 @@ title the legend title bbox_to_anchor the bbox that the legend will be anchored. bbox_transform the transform for the bbox. transAxes if None. - ================ ================================================================== + ================ ===================================================== -The pad and spacing parameters are measured in font-size units. E.g., -a fontsize of 10 points and a handlelength=5 implies a handlelength of -50 points. Values from rcParams will be used if None. + The pad and spacing parameters are measured in font-size units. E.g., + a fontsize of 10 points and a handlelength=5 implies a handlelength of + 50 points. Values from rcParams will be used if None. -Users can specify any arbitrary location for the legend using the -*bbox_to_anchor* keyword argument. bbox_to_anchor can be an instance -of BboxBase(or its derivatives) or a tuple of 2 or 4 floats. -See :meth:`set_bbox_to_anchor` for more detail. + Users can specify any arbitrary location for the legend using the + *bbox_to_anchor* keyword argument. bbox_to_anchor can be an instance + of BboxBase(or its derivatives) or a tuple of 2 or 4 floats. + See :meth:`set_bbox_to_anchor` for more detail. -The legend location can be specified by setting *loc* with a tuple of -2 floats, which is interpreted as the lower-left corner of the legend -in the normalized axes coordinate. + The legend location can be specified by setting *loc* with a tuple of + 2 floats, which is interpreted as the lower-left corner of the legend + in the normalized axes coordinate. """ - from matplotlib.axes import Axes # local import only to avoid circularity - from matplotlib.figure import Figure # local import only to avoid circularity + # local import only to avoid circularity + from matplotlib.axes import Axes + from matplotlib.figure import Figure Artist.__init__(self) if prop is None: - self.prop=FontProperties(size=rcParams["legend.fontsize"]) + if fontsize is not None: + self.prop = FontProperties(size=fontsize) + else: + self.prop = FontProperties(size=rcParams["legend.fontsize"]) elif isinstance(prop, dict): - self.prop=FontProperties(**prop) + self.prop = FontProperties(**prop) if "size" not in prop: self.prop.set_size(rcParams["legend.fontsize"]) else: - self.prop=prop + self.prop = prop self._fontsize = self.prop.get_size_in_points() - propnames=['numpoints', 'markerscale', 'shadow', "columnspacing", - "scatterpoints", "handleheight"] + propnames = ["numpoints", "markerscale", "shadow", "columnspacing", + "scatterpoints", "handleheight"] self.texts = [] self.legendHandles = [] self._legend_title_box = None - self._handler_map = handler_map localdict = locals() for name in propnames: if localdict[name] is None: - value = rcParams["legend."+name] + value = rcParams["legend." + name] else: value = localdict[name] setattr(self, name, value) # Take care the deprecated keywords - deprecated_kwds = {"pad":"borderpad", - "labelsep":"labelspacing", - "handlelen":"handlelength", - "handletextsep":"handletextpad", - "axespad":"borderaxespad"} + deprecated_kwds = {"pad": "borderpad", + "labelsep": "labelspacing", + "handlelen": "handlelength", + "handletextsep": "handletextpad", + "axespad": "borderaxespad"} # convert values of deprecated keywords (ginve in axes coords) # to new vaules in a fraction of the font size # conversion factor bbox = parent.bbox - axessize_fontsize = min(bbox.width, bbox.height)/self._fontsize + axessize_fontsize = min(bbox.width, bbox.height) / self._fontsize - for k, v in deprecated_kwds.items(): + for k, v in deprecated_kwds.iteritems(): # use deprecated value if not None and if their newer # counter part is None. if localdict[k] is not None and localdict[v] is None: warnings.warn("Use '%s' instead of '%s'." % (v, k), DeprecationWarning) - setattr(self, v, localdict[k]*axessize_fontsize) + setattr(self, v, localdict[k] * axessize_fontsize) continue # Otherwise, use new keywords if localdict[v] is None: - setattr(self, v, rcParams["legend."+v]) + setattr(self, v, rcParams["legend." + v]) else: setattr(self, v, localdict[v]) del localdict handles = list(handles) - if len(handles)<2: + if len(handles) < 2: ncol = 1 self._ncol = ncol if self.numpoints <= 0: - raise ValueError("numpoints must be > 0; it was %d"% numpoints) + raise ValueError("numpoints must be > 0; it was %d" % numpoints) # introduce y-offset for handles of the scatter plot if scatteryoffsets is None: - self._scatteryoffsets = np.array([3./8., 4./8., 2.5/8.]) + self._scatteryoffsets = np.array([3. / 8., 4. / 8., 2.5 / 8.]) else: self._scatteryoffsets = np.asarray(scatteryoffsets) - reps = int(self.scatterpoints / len(self._scatteryoffsets)) + 1 - self._scatteryoffsets = np.tile(self._scatteryoffsets, reps)[:self.scatterpoints] + reps = int(self.scatterpoints / len(self._scatteryoffsets)) + 1 + self._scatteryoffsets = np.tile(self._scatteryoffsets, + reps)[:self.scatterpoints] # _legend_box is an OffsetBox instance that contains all # legend items and will be initialized from _init_legend_box() # method. self._legend_box = None - if isinstance(parent,Axes): + if isinstance(parent, Axes): self.isaxes = True self.set_axes(parent) self.set_figure(parent.figure) - elif isinstance(parent,Figure): + elif isinstance(parent, Figure): self.isaxes = False self.set_figure(parent) else: @@ -308,24 +325,26 @@ if loc is None: loc = rcParams["legend.loc"] - if not self.isaxes and loc in [0,'best']: + if not self.isaxes and loc in [0, 'best']: loc = 'upper right' if is_string_like(loc): if loc not in self.codes: if self.isaxes: - warnings.warn('Unrecognized location "%s". Falling back on "best"; ' - 'valid locations are\n\t%s\n' - % (loc, '\n\t'.join(self.codes.keys()))) + warnings.warn('Unrecognized location "%s". Falling back ' + 'on "best"; valid locations are\n\t%s\n' + % (loc, '\n\t'.join(self.codes.iterkeys()))) loc = 0 else: - warnings.warn('Unrecognized location "%s". Falling back on "upper right"; ' + warnings.warn('Unrecognized location "%s". Falling back ' + 'on "upper right"; ' 'valid locations are\n\t%s\n' - % (loc, '\n\t'.join(self.codes.keys()))) + % (loc, '\n\t'.join(self.codes.iterkeys()))) loc = 1 else: loc = self.codes[loc] if not self.isaxes and loc == 0: - warnings.warn('Automatic legend placement (loc="best") not implemented for figure legend. ' + warnings.warn('Automatic legend placement (loc="best") not ' + 'implemented for figure legend. ' 'Falling back on "upper right".') loc = 1 @@ -349,11 +368,11 @@ if fancybox is None: fancybox = rcParams["legend.fancybox"] - if fancybox == True: - self.legendPatch.set_boxstyle("round",pad=0, + if fancybox: + self.legendPatch.set_boxstyle("round", pad=0, rounding_size=0.2) else: - self.legendPatch.set_boxstyle("square",pad=0) + self.legendPatch.set_boxstyle("square", pad=0) self._set_artist_props(self.legendPatch) @@ -381,7 +400,6 @@ a.set_axes(self.axes) a.set_transform(self.get_transform()) - def _set_loc(self, loc): # find_offset function will be provided to _legend_box and # _legend_box will draw itself at the location of the return @@ -407,38 +425,39 @@ def _findoffset_best(self, width, height, xdescent, ydescent, renderer): "Helper function to locate the legend at its best position" ox, oy = self._find_best_position(width, height, renderer) - return ox+xdescent, oy+ydescent + return ox + xdescent, oy + ydescent def _findoffset_loc(self, width, height, xdescent, ydescent, renderer): - "Heper function to locate the legend using the location code" + "Helper function to locate the legend using the location code" - if iterable(self._loc) and len(self._loc)==2: + if iterable(self._loc) and len(self._loc) == 2: # when loc is a tuple of axes(or figure) coordinates. fx, fy = self._loc bbox = self.get_bbox_to_anchor() x, y = bbox.x0 + bbox.width * fx, bbox.y0 + bbox.height * fy else: bbox = Bbox.from_bounds(0, 0, width, height) - x, y = self._get_anchored_bbox(self._loc, bbox, self.get_bbox_to_anchor(), renderer) + x, y = self._get_anchored_bbox(self._loc, bbox, + self.get_bbox_to_anchor(), + renderer) - return x+xdescent, y+ydescent + return x + xdescent, y + ydescent @allow_rasterization def draw(self, renderer): "Draw everything that belongs to the legend" - if not self.get_visible(): return - + if not self.get_visible(): + return renderer.open_group('legend') - fontsize = renderer.points_to_pixels(self._fontsize) # if mode == fill, set the width of the legend_box to the # width of the paret (minus pads) if self._mode in ["expand"]: - pad = 2*(self.borderaxespad+self.borderpad)*fontsize - self._legend_box.set_width(self.get_bbox_to_anchor().width-pad) + pad = 2 * (self.borderaxespad + self.borderpad) * fontsize + self._legend_box.set_width(self.get_bbox_to_anchor().width - pad) if self._drawFrame: # update the location and size of the legend @@ -458,7 +477,6 @@ renderer.close_group('legend') - def _approx_text_height(self, renderer=None): """ Return the approximate height of the text. This is used to place @@ -469,21 +487,21 @@ else: return renderer.points_to_pixels(self._fontsize) - # _default_handler_map defines the default mapping between plot # elements and the legend handlers. _default_handler_map = { - StemContainer:legend_handler.HandlerStem(), - ErrorbarContainer:legend_handler.HandlerErrorbar(), - Line2D:legend_handler.HandlerLine2D(), - Patch:legend_handler.HandlerPatch(), - LineCollection:legend_handler.HandlerLineCollection(), - RegularPolyCollection:legend_handler.HandlerRegularPolyCollection(), - CircleCollection:legend_handler.HandlerCircleCollection(), - BarContainer:legend_handler.HandlerPatch(update_func=legend_handler.update_from_first_child), - tuple:legend_handler.HandlerTuple(), - PathCollection:legend_handler.HandlerPathCollection() + StemContainer: legend_handler.HandlerStem(), + ErrorbarContainer: legend_handler.HandlerErrorbar(), + Line2D: legend_handler.HandlerLine2D(), + Patch: legend_handler.HandlerPatch(), + LineCollection: legend_handler.HandlerLineCollection(), + RegularPolyCollection: legend_handler.HandlerRegularPolyCollection(), + CircleCollection: legend_handler.HandlerCircleCollection(), + BarContainer: legend_handler.HandlerPatch( + update_func=legend_handler.update_from_first_child), + tuple: legend_handler.HandlerTuple(), + PathCollection: legend_handler.HandlerPathCollection() } # (get|set|update)_default_handler_maps are public interfaces to @@ -553,7 +571,6 @@ return handler - def _init_legend_box(self, handles, labels): """ Initialize the legend_box. The legend_box is an instance of @@ -572,7 +589,6 @@ # is an instance of offsetbox.TextArea which contains legend # text. - text_list = [] # the list of text instances handle_list = [] # the list of text instances @@ -584,14 +600,13 @@ labelboxes = [] handleboxes = [] - # The approximate height and descent of text. These values are # only used for plotting the legend handle. - descent = 0.35*self._approx_text_height()*(self.handleheight - 0.7) + descent = 0.35 * self._approx_text_height() * (self.handleheight - 0.7) # 0.35 and 0.7 are just heuristic numbers. this may need to be improbed height = self._approx_text_height() * self.handleheight - descent # each handle needs to be drawn inside a box of (x, y, w, h) = - # (0, -descent, width, height). And their corrdinates should + # (0, -descent, width, height). And their coordinates should # be given in the display coordinates. # The transformation of each handle will be automatically set @@ -599,7 +614,6 @@ # default trasnform (eg, Collections), you need to # manually set their transform to the self.get_transform(). - legend_handler_map = self.get_legend_handler_map() for orig_handle, lab in zip(handles, labels): @@ -607,7 +621,11 @@ handler = self.get_legend_handler(legend_handler_map, orig_handle) if handler is None: - warnings.warn("Legend does not support %s\nUse proxy artist instead.\n\nhttp://matplotlib.sourceforge.net/users/legend_guide.html#using-proxy-artist\n" % (str(orig_handle),)) + warnings.warn( + "Legend does not support %s\nUse proxy artist " + "instead.\n\n" + "http://matplotlib.sourceforge.net/users/legend_guide.html#using-proxy-artist\n" % + (str(orig_handle),)) handle_list.append(None) continue @@ -617,53 +635,54 @@ labelboxes.append(textbox) - handlebox = DrawingArea(width=self.handlelength*fontsize, + handlebox = DrawingArea(width=self.handlelength * fontsize, height=height, xdescent=0., ydescent=descent) - handle = handler(self, orig_handle, \ + handle = handler(self, orig_handle, #xdescent, ydescent, width, height, fontsize, handlebox) - handle_list.append(handle) - - + handle_list.append(handle) handleboxes.append(handlebox) - if len(handleboxes) > 0: - # We calculate number of lows in each column. The first - # (num_largecol) columns will have (nrows+1) rows, and remaing + # We calculate number of rows in each column. The first + # (num_largecol) columns will have (nrows+1) rows, and remaining # (num_smallcol) columns will have (nrows) rows. ncol = min(self._ncol, len(handleboxes)) nrows, num_largecol = divmod(len(handleboxes), ncol) - num_smallcol = ncol-num_largecol + num_smallcol = ncol - num_largecol # starting index of each column and number of rows in it. - largecol = safezip(range(0, num_largecol*(nrows+1), (nrows+1)), - [nrows+1] * num_largecol) - smallcol = safezip(range(num_largecol*(nrows+1), len(handleboxes), nrows), + largecol = safezip(range(0, + num_largecol * (nrows + 1), + (nrows + 1)), + [nrows + 1] * num_largecol) + smallcol = safezip(range(num_largecol * (nrows + 1), + len(handleboxes), + nrows), [nrows] * num_smallcol) else: largecol, smallcol = [], [] handle_label = safezip(handleboxes, labelboxes) columnbox = [] - for i0, di in largecol+smallcol: + for i0, di in largecol + smallcol: # pack handleBox and labelBox into itemBox itemBoxes = [HPacker(pad=0, - sep=self.handletextpad*fontsize, + sep=self.handletextpad * fontsize, children=[h, t], align="baseline") - for h, t in handle_label[i0:i0+di]] + for h, t in handle_label[i0:i0 + di]] # minimumdescent=False for the text of the last row of the column itemBoxes[-1].get_children()[1].set_minimumdescent(False) # pack columnBox columnbox.append(VPacker(pad=0, - sep=self.labelspacing*fontsize, + sep=self.labelspacing * fontsize, align="baseline", children=itemBoxes)) @@ -672,7 +691,7 @@ else: mode = "fixed" - sep = self.columnspacing*fontsize + sep = self.columnspacing * fontsize self._legend_handle_box = HPacker(pad=0, sep=sep, align="baseline", @@ -681,8 +700,8 @@ self._legend_title_box = TextArea("") - self._legend_box = VPacker(pad=self.borderpad*fontsize, - sep=self.labelspacing*fontsize, + self._legend_box = VPacker(pad=self.borderpad * fontsize, + sep=self.labelspacing * fontsize, align="center", children=[self._legend_title_box, self._legend_handle_box]) @@ -692,7 +711,6 @@ self.texts = text_list self.legendHandles = handle_list - def _auto_legend_data(self): """ Returns list of vertices and extents covered by the plot. @@ -706,8 +724,8 @@ Second element is a list of bounding boxes for all the patches in the legend's handles. """ - - assert self.isaxes # should always hold because function is only called internally + # should always hold because function is only called internally + assert self.isaxes ax = self.parent vertices = [] @@ -761,16 +779,26 @@ def get_patches(self): 'return a list of patch instances in the legend' - return silent_list('Patch', [h for h in self.legendHandles if isinstance(h, Patch)]) + return silent_list('Patch', + [h for h in self.legendHandles + if isinstance(h, Patch)]) def get_texts(self): 'return a list of text.Text instance in the legend' return silent_list('Text', self.texts) - def set_title(self, title): - 'set the legend title' + def set_title(self, title, prop=None): + """ + set the legend title. Fontproperties can be optionally set + with *prop* parameter. + """ self._legend_title_box._text.set_text(title) + if prop is not None: + if isinstance(prop, dict): + prop = FontProperties(**prop) + self._legend_title_box._text.set_fontproperties(prop) + if title: self._legend_title_box.set_visible(True) else: @@ -780,11 +808,10 @@ 'return Text instance for the legend title' return self._legend_title_box._text - def get_window_extent(self, *args, **kwargs) : + def get_window_extent(self, *args, **kwargs): 'return a extent of the the legend' return self.legendPatch.get_window_extent(*args, **kwargs) - def get_frame_on(self): """ Get whether the legend box patch is drawn @@ -808,7 +835,6 @@ else: return self._bbox_to_anchor - def set_bbox_to_anchor(self, bbox, transform=None): """ set the bbox that the legend will be anchored. @@ -840,34 +866,33 @@ self._bbox_to_anchor = TransformedBbox(self._bbox_to_anchor, transform) - - def _get_anchored_bbox(self, loc, bbox, parentbbox, renderer): """ Place the *bbox* inside the *parentbbox* according to a given location code. Return the (x,y) coordinate of the bbox. - loc: a location code in range(1, 11). - This corresponds to the possible values for self._loc, excluding "best". + This corresponds to the possible values for self._loc, excluding + "best". - bbox: bbox to be placed, display coodinate units. - parentbbox: a parent box which will contain the bbox. In display coordinates. """ - assert loc in range(1,11) # called only internally + assert loc in range(1, 11) # called only internally BEST, UR, UL, LL, LR, R, CL, CR, LC, UC, C = range(11) - anchor_coefs={UR:"NE", - UL:"NW", - LL:"SW", - LR:"SE", - R:"E", - CL:"W", - CR:"E", - LC:"S", - UC:"N", - C:"C"} + anchor_coefs = {UR: "NE", + UL: "NW", + LL: "SW", + LR: "SE", + R: "E", + CL: "W", + CR: "E", + LC: "S", + UC: "N", + C: "C"} c = anchor_coefs[loc] @@ -876,7 +901,6 @@ anchored_box = bbox.anchored(c, container=container) return anchored_box.x0, anchored_box.y0 - def _find_best_position(self, width, height, renderer, consider=None): """ Determine the best location to place the legend. @@ -884,14 +908,16 @@ `consider` is a list of (x, y) pairs to consider as a potential lower-left corner of the legend. All are display coords. """ - - assert self.isaxes # should always hold because function is only called internally + # should always hold because function is only called internally + assert self.isaxes verts, bboxes, lines = self._auto_legend_data() bbox = Bbox.from_bounds(0, 0, width, height) consider = [self._get_anchored_bbox(x, bbox, self.get_bbox_to_anchor(), - renderer) for x in range(1, len(self.codes))] + renderer) + for x + in range(1, len(self.codes))] #tx, ty = self.legendPatch.get_x(), self.legendPatch.get_y() @@ -953,7 +979,9 @@ if state: if self._draggable is None: - self._draggable = DraggableLegend(self, use_blit, update=update) + self._draggable = DraggableLegend(self, + use_blit, + update=update) else: if self._draggable is not None: self._draggable.disconnect() diff -Nru matplotlib-1.1.1/lib/matplotlib/legend_handler.py matplotlib-1.2.0/lib/matplotlib/legend_handler.py --- matplotlib-1.1.1/lib/matplotlib/legend_handler.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/legend_handler.py 2012-10-31 00:11:14.000000000 +0000 @@ -29,8 +29,7 @@ from matplotlib.lines import Line2D from matplotlib.patches import Rectangle import matplotlib.collections as mcoll -# from matplotlib.collections import LineCollection, RegularPolyCollection, \ -# CircleCollection + def update_from_first_child(tgt, src): tgt.update_from(src.get_children()[0]) @@ -41,14 +40,14 @@ A Base class for default legend handlers. The derived classes are meant to override *create_artists* method, which - has a following signatture.:: + has a following signature.:: def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans): - The overriden method needs to create artists of the given - transform that fits in the given dimension (xdescent, ydescemt, + The overridden method needs to create artists of the given + transform that fits in the given dimension (xdescent, ydescent, width, height) that are scaled by fontsize if necessary. """ @@ -65,7 +64,6 @@ def _default_update_prop(self, legend_handle, orig_handle): legend_handle.update_from(orig_handle) - def update_prop(self, legend_handle, orig_handle, legend): self._update_prop(legend_handle, orig_handle) @@ -74,17 +72,13 @@ legend_handle.set_clip_box(None) legend_handle.set_clip_path(None) - # make usre that transform is not set since they will be set - # when added to an handlerbox. - legend_handle._transformSet = False - def adjust_drawing_area(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, ): - xdescent = xdescent-self._xpad*fontsize - ydescent = ydescent-self._ypad*fontsize - width = width-self._xpad*fontsize - height = height-self._ypad*fontsize + xdescent = xdescent - self._xpad * fontsize + ydescent = ydescent - self._ypad * fontsize + width = width - self._xpad * fontsize + height = height - self._ypad * fontsize return xdescent, ydescent, width, height def __call__(self, legend, orig_handle, @@ -94,7 +88,6 @@ x, y, w, h in display coordinate w/ default dpi (72) fontsize in points """ - width, height, xdescent, ydescent = handlebox.width, \ handlebox.height, \ handlebox.xdescent, \ @@ -116,7 +109,6 @@ # we only return the first artist return a_list[0] - def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans): @@ -143,35 +135,31 @@ if numpoints > 1: # we put some pad here to compensate the size of the # marker - xdata = np.linspace(-xdescent+self._marker_pad*fontsize, - width-self._marker_pad*fontsize, + xdata = np.linspace(-xdescent + self._marker_pad * fontsize, + width - self._marker_pad * fontsize, numpoints) xdata_marker = xdata elif numpoints == 1: xdata = np.linspace(-xdescent, width, 2) - xdata_marker = [0.5*width-0.5*xdescent] + xdata_marker = [0.5 * width - 0.5 * xdescent] return xdata, xdata_marker - class HandlerNpointsYoffsets(HandlerNpoints): def __init__(self, numpoints=None, yoffsets=None, **kw): - HandlerNpoints.__init__(self,numpoints=numpoints, **kw) + HandlerNpoints.__init__(self, numpoints=numpoints, **kw) self._yoffsets = yoffsets def get_ydata(self, legend, xdescent, ydescent, width, height, fontsize): if self._yoffsets is None: - ydata = height*legend._scatteryoffsets + ydata = height * legend._scatteryoffsets else: - ydata = height*np.asarray(self._yoffsets) + ydata = height * np.asarray(self._yoffsets) return ydata - - - class HandlerLine2D(HandlerNpoints): """ Handler for Line2D instances @@ -179,7 +167,6 @@ def __init__(self, marker_pad=0.3, numpoints=None, **kw): HandlerNpoints.__init__(self, marker_pad=marker_pad, numpoints=numpoints, **kw) - def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans): @@ -187,36 +174,28 @@ xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent, width, height, fontsize) - ydata = ((height-ydescent)/2.)*np.ones(xdata.shape, float) + ydata = ((height - ydescent) / 2.) * np.ones(xdata.shape, float) legline = Line2D(xdata, ydata) self.update_prop(legline, orig_handle, legend) - #legline.update_from(orig_handle) - #legend._set_artist_props(legline) # after update - #legline.set_clip_box(None) - #legline.set_clip_path(None) legline.set_drawstyle('default') legline.set_marker("") - legline_marker = Line2D(xdata_marker, ydata[:len(xdata_marker)]) self.update_prop(legline_marker, orig_handle, legend) - #legline_marker.update_from(orig_handle) - #legend._set_artist_props(legline_marker) - #legline_marker.set_clip_box(None) - #legline_marker.set_clip_path(None) legline_marker.set_linestyle('None') - if legend.markerscale !=1: - newsz = legline_marker.get_markersize()*legend.markerscale + if legend.markerscale != 1: + newsz = legline_marker.get_markersize() * legend.markerscale legline_marker.set_markersize(newsz) # we don't want to add this to the return list because # the texts and handles are assumed to be in one-to-one - # correpondence. + # correspondence. legline._legmarker = legline_marker - return [legline, legline_marker] - + legline.set_transform(trans) + legline_marker.set_transform(trans) + return [legline, legline_marker] class HandlerPatch(HandlerBase): """ @@ -231,12 +210,11 @@ xdescent, ydescent, width, height, fontsize): if self._patch_func is None: p = Rectangle(xy=(-xdescent, -ydescent), - width = width, height=height) + width=width, height=height) else: p = self._patch_func(legend=legend, orig_handle=orig_handle, xdescent=xdescent, ydescent=ydescent, width=width, height=height, fontsize=fontsize) - return p def create_artists(self, legend, orig_handle, @@ -246,16 +224,14 @@ xdescent, ydescent, width, height, fontsize) self.update_prop(p, orig_handle, legend) - + p.set_transform(trans) return [p] - class HandlerLineCollection(HandlerLine2D): """ Handler for LineCollections """ - def get_numpoints(self, legend): if self._numpoints is None: return legend.scatterpoints @@ -271,21 +247,20 @@ if dashes[0] is not None: # dashed line legend_handle.set_dashes(dashes[1]) - def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans): xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent, width, height, fontsize) - ydata = ((height-ydescent)/2.)*np.ones(xdata.shape, float) + ydata = ((height - ydescent) / 2.) * np.ones(xdata.shape, float) legline = Line2D(xdata, ydata) self.update_prop(legline, orig_handle, legend) + legline.set_transform(trans) return [legline] - class HandlerRegularPolyCollection(HandlerNpointsYoffsets): """ Handler for RegularPolyCollections. @@ -304,17 +279,18 @@ def get_sizes(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize): if self._sizes is None: - size_max = max(orig_handle.get_sizes())*legend.markerscale**2 - size_min = min(orig_handle.get_sizes())*legend.markerscale**2 + size_max = max(orig_handle.get_sizes()) * legend.markerscale ** 2 + size_min = min(orig_handle.get_sizes()) * legend.markerscale ** 2 numpoints = self.get_numpoints(legend) if numpoints < 4: - sizes = [.5*(size_max+size_min), size_max, + sizes = [.5 * (size_max + size_min), size_max, size_min] else: - sizes = (size_max-size_min)*np.linspace(0,1,numpoints)+size_min + rng = (size_max - size_min) + sizes = rng * np.linspace(0, 1, numpoints) + size_min else: - sizes = self._sizes #[:legend.scatterpoints] + sizes = self._sizes return sizes @@ -339,12 +315,9 @@ def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans): - - xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent, width, height, fontsize) - ydata = self.get_ydata(legend, xdescent, ydescent, width, height, fontsize) @@ -352,16 +325,14 @@ width, height, fontsize) p = self.create_collection(orig_handle, sizes, - offsets=zip(xdata_marker,ydata), + offsets=zip(xdata_marker, ydata), transOffset=trans) self.update_prop(p, orig_handle, legend) - p._transOffset = trans - p.set_transform(None) - return [p] + class HandlerPathCollection(HandlerRegularPolyCollection): """ Handler for PathCollections, which are used by scatter @@ -374,7 +345,7 @@ ) return p - + class HandlerCircleCollection(HandlerRegularPolyCollection): """ Handler for CircleCollections @@ -401,17 +372,15 @@ **kw) def get_err_size(self, legend, xdescent, ydescent, width, height, fontsize): - xerr_size = self._xerr_size*fontsize + xerr_size = self._xerr_size * fontsize if self._yerr_size is None: yerr_size = xerr_size else: - yerr_size = self._yerr_size*fontsize + yerr_size = self._yerr_size * fontsize return xerr_size, yerr_size - - def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans): @@ -421,7 +390,7 @@ xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent, width, height, fontsize) - ydata = ((height-ydescent)/2.)*np.ones(xdata.shape, float) + ydata = ((height - ydescent) / 2.) * np.ones(xdata.shape, float) legline = Line2D(xdata, ydata) @@ -431,7 +400,6 @@ xerr_size, yerr_size = self.get_err_size(legend, xdescent, ydescent, width, height, fontsize) - legline_marker = Line2D(xdata_marker, ydata_marker) # when plotlines are None (only errorbars are drawn), we just @@ -448,24 +416,23 @@ self.update_prop(legline_marker, plotlines, legend) legline_marker.set_linestyle('None') - if legend.markerscale !=1: - newsz = legline_marker.get_markersize()*legend.markerscale + if legend.markerscale != 1: + newsz = legline_marker.get_markersize() * legend.markerscale legline_marker.set_markersize(newsz) - handle_barlinecols = [] handle_caplines = [] if orig_handle.has_xerr: - verts = [ ((x-xerr_size, y), (x+xerr_size, y)) - for x,y in zip(xdata_marker, ydata_marker)] + verts = [ ((x - xerr_size, y), (x + xerr_size, y)) + for x, y in zip(xdata_marker, ydata_marker)] coll = mcoll.LineCollection(verts) self.update_prop(coll, barlinecols[0], legend) handle_barlinecols.append(coll) if caplines: - capline_left = Line2D(xdata_marker-xerr_size, ydata_marker) - capline_right = Line2D(xdata_marker+xerr_size, ydata_marker) + capline_left = Line2D(xdata_marker - xerr_size, ydata_marker) + capline_right = Line2D(xdata_marker + xerr_size, ydata_marker) self.update_prop(capline_left, caplines[0], legend) self.update_prop(capline_right, caplines[0], legend) capline_left.set_marker("|") @@ -475,15 +442,15 @@ handle_caplines.append(capline_right) if orig_handle.has_yerr: - verts = [ ((x, y-yerr_size), (x, y+yerr_size)) - for x,y in zip(xdata_marker, ydata_marker)] + verts = [ ((x, y - yerr_size), (x, y + yerr_size)) + for x, y in zip(xdata_marker, ydata_marker)] coll = mcoll.LineCollection(verts) self.update_prop(coll, barlinecols[0], legend) handle_barlinecols.append(coll) if caplines: - capline_left = Line2D(xdata_marker, ydata_marker-yerr_size) - capline_right = Line2D(xdata_marker, ydata_marker+yerr_size) + capline_left = Line2D(xdata_marker, ydata_marker - yerr_size) + capline_right = Line2D(xdata_marker, ydata_marker + yerr_size) self.update_prop(capline_left, caplines[0], legend) self.update_prop(capline_right, caplines[0], legend) capline_left.set_marker("_") @@ -498,9 +465,10 @@ artists.append(legline) artists.append(legline_marker) - return artists - + for artist in artists: + artist.set_transform(trans) + return artists class HandlerStem(HandlerNpointsYoffsets): """ @@ -513,19 +481,16 @@ numpoints=numpoints, yoffsets=yoffsets, **kw) - self._bottom = bottom - def get_ydata(self, legend, xdescent, ydescent, width, height, fontsize): if self._yoffsets is None: - ydata = height*(0.5*legend._scatteryoffsets + 0.5) + ydata = height * (0.5 * legend._scatteryoffsets + 0.5) else: - ydata = height*np.asarray(self._yoffsets) + ydata = height * np.asarray(self._yoffsets) return ydata - def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans): @@ -543,15 +508,12 @@ else: bottom = self._bottom - ax = markerline.axes - #saved_dict = self.pre_plot_commands(ax) - leg_markerline = Line2D(xdata_marker, ydata[:len(xdata_marker)]) self.update_prop(leg_markerline, markerline, legend) leg_stemlines = [] for thisx, thisy in zip(xdata_marker, ydata): - l = Line2D([thisx,thisx], [bottom, thisy]) + l = Line2D([thisx, thisx], [bottom, thisy]) leg_stemlines.append(l) for lm, m in zip(leg_stemlines, stemlines): @@ -566,6 +528,9 @@ artists.extend(leg_stemlines) artists.append(leg_baseline) + for artist in artists: + artist.set_transform(trans) + return artists @@ -576,8 +541,6 @@ def __init__(self, **kwargs): HandlerBase.__init__(self, **kwargs) - #self._handle_list = handle_list - def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans): diff -Nru matplotlib-1.1.1/lib/matplotlib/lines.py matplotlib-1.2.0/lib/matplotlib/lines.py --- matplotlib-1.1.1/lib/matplotlib/lines.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/lines.py 2012-10-31 00:11:14.000000000 +0000 @@ -4,7 +4,9 @@ """ # TODO: expose cap and join style attrs -from __future__ import division +from __future__ import division, print_function + +import warnings import numpy as np from numpy import ma @@ -237,10 +239,11 @@ TODO: sort returned indices by distance """ - if callable(self._contains): return self._contains(self,mouseevent) + if callable(self._contains): + return self._contains(self,mouseevent) if not is_numlike(self.pickradius): - raise ValueError,"pick radius should be a distance" + raise ValueError("pick radius should be a distance") # Make sure we have data to plot if self._invalidy or self._invalidx: @@ -248,39 +251,45 @@ if len(self._xy)==0: return False,{} # Convert points to pixels - if self._transformed_path is None: - self._transform_path() - path, affine = self._transformed_path.get_transformed_path_and_affine() + path, affine = self._get_transformed_path().get_transformed_path_and_affine() path = affine.transform_path(path) xy = path.vertices xt = xy[:, 0] yt = xy[:, 1] # Convert pick radius from points to pixels - if self.figure == None: - warning.warn('no figure set when check if mouse is on line') + if self.figure is None: + warnings.warn('no figure set when check if mouse is on line') pixels = self.pickradius else: pixels = self.figure.dpi/72. * self.pickradius - # Check for collision - if self._linestyle in ['None',None]: - # If no line, return the nearby point(s) - d = (xt-mouseevent.x)**2 + (yt-mouseevent.y)**2 - ind, = np.nonzero(np.less_equal(d, pixels**2)) - else: - # If line, return the nearby segment(s) - ind = segment_hits(mouseevent.x,mouseevent.y,xt,yt,pixels) + # the math involved in checking for containment (here and inside of segment_hits) assumes + # that it is OK to overflow. In case the application has set the error flags such that + # an exception is raised on overflow, we temporarily set the appropriate error flags here + # and set them back when we are finished. + olderrflags = np.seterr(all='ignore') + try: + # Check for collision + if self._linestyle in ['None',None]: + # If no line, return the nearby point(s) + d = (xt-mouseevent.x)**2 + (yt-mouseevent.y)**2 + ind, = np.nonzero(np.less_equal(d, pixels**2)) + else: + # If line, return the nearby segment(s) + ind = segment_hits(mouseevent.x,mouseevent.y,xt,yt,pixels) + finally: + np.seterr(**olderrflags) ind += self.ind_offset # Debugging message - if False and self._label != u'': - print "Checking line",self._label,"at",mouseevent.x,mouseevent.y - print 'xt', xt - print 'yt', yt + if False and self._label != '': + print("Checking line",self._label,"at",mouseevent.x,mouseevent.y) + print('xt', xt) + print('yt', yt) #print 'dx,dy', (xt-mouseevent.x)**2., (yt-mouseevent.y)**2. - print 'ind',ind + print('ind',ind) # Return the point(s) within radius return len(ind)>0,dict(ind=ind) @@ -305,9 +314,9 @@ def set_fillstyle(self, fs): """ Set the marker fill style; 'full' means fill the whole marker. - The other options are for half filled markers + 'none' means no filling; other options are for half-filled markers. - ACCEPTS: ['full' | 'left' | 'right' | 'bottom' | 'top'] + ACCEPTS: ['full' | 'left' | 'right' | 'bottom' | 'top' | 'none'] """ self._marker.set_fillstyle(fs) @@ -437,6 +446,11 @@ self._invalidy = False def _transform_path(self, subslice=None): + """ + Puts a TransformedPath instance at self._transformed_path, + all invalidation of the transform is then handled by the + TransformedPath instance. + """ # Masked arrays are now handled by the Path class itself if subslice is not None: _path = Path(self._xy[subslice,:]) @@ -444,6 +458,14 @@ _path = self._path self._transformed_path = TransformedPath(_path, self.get_transform()) + def _get_transformed_path(self): + """ + Return the :class:`~matplotlib.transforms.TransformedPath` instance + of this line. + """ + if self._transformed_path is None: + self._transform_path() + return self._transformed_path def set_transform(self, t): """ @@ -473,8 +495,8 @@ subslice = slice(max(i0-1, 0), i1+1) self.ind_offset = subslice.start self._transform_path(subslice) - if self._transformed_path is None: - self._transform_path() + + transformed_path = self._get_transformed_path() if not self.get_visible(): return @@ -498,7 +520,7 @@ funcname = self._lineStyles.get(self._linestyle, '_draw_nothing') if funcname != '_draw_nothing': - tpath, affine = self._transformed_path.get_transformed_path_and_affine() + tpath, affine = transformed_path.get_transformed_path_and_affine() if len(tpath.vertices): self._lineFunc = getattr(self, funcname) funcname = self.drawStyles.get(self._drawstyle, '_draw_lines') @@ -519,7 +541,7 @@ gc.set_linewidth(self._markeredgewidth) gc.set_alpha(self._alpha) marker = self._marker - tpath, affine = self._transformed_path.get_transformed_points_and_affine() + tpath, affine = transformed_path.get_transformed_points_and_affine() if len(tpath.vertices): # subsample the markers if markevery is not None markevery = self.get_markevery() @@ -576,15 +598,16 @@ def get_marker(self): return self._marker.get_marker() def get_markeredgecolor(self): - if (is_string_like(self._markeredgecolor) and - self._markeredgecolor == 'auto'): + mec = self._markeredgecolor + if (is_string_like(mec) and mec == 'auto'): if self._marker.get_marker() in ('.', ','): return self._color - if self._marker.is_filled(): + if self._marker.is_filled() and self.get_fillstyle() != 'none': return 'k' # Bad hard-wired default... else: return self._color - return self._markeredgecolor + else: + return mec def get_markeredgewidth(self): return self._markeredgewidth @@ -594,10 +617,11 @@ else: fc = self._markerfacecolor - if (fc is None or (is_string_like(fc) and fc.lower()=='none') ): - return fc - elif (is_string_like(fc) and fc.lower() == 'auto'): - return self._color + if (is_string_like(fc) and fc.lower() == 'auto'): + if self.get_fillstyle() == 'none': + return 'none' + else: + return self._color else: return fc @@ -1188,4 +1212,4 @@ # You can not set the docstring of an instancemethod, # but you can on the underlying function. Go figure. -docstring.dedent_interpd(Line2D.__init__.im_func) +docstring.dedent_interpd(Line2D.__init__) diff -Nru matplotlib-1.1.1/lib/matplotlib/markers.py matplotlib-1.2.0/lib/matplotlib/markers.py --- matplotlib-1.1.1/lib/matplotlib/markers.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/markers.py 2012-10-31 00:11:14.000000000 +0000 @@ -49,7 +49,7 @@ ===== ============================================= *angle*: - the angle of rotation of the symbol + the angle of rotation of the symbol, in degrees For backward compatibility, the form (*verts*, 0) is also accepted, but it is equivalent to just *verts* for giving a raw set of vertices @@ -102,7 +102,8 @@ filled_markers = ( 'o', 'v', '^', '<', '>', '8', 's', 'p', '*', 'h', 'H', 'D', 'd') - fillstyles = ('full', 'left' , 'right' , 'bottom' , 'top') + fillstyles = ('full', 'left' , 'right' , 'bottom' , 'top', 'none') + _half_fillstyles = ('left' , 'right' , 'bottom' , 'top') # TODO: Is this ever used as a non-constant? _point_size_reduction = 0.5 @@ -112,6 +113,16 @@ self.set_marker(marker) self.set_fillstyle(fillstyle) + def __getstate__(self): + d = self.__dict__.copy() + d.pop('_marker_function') + return d + + def __setstate__(self, statedict): + self.__dict__ = statedict + self.set_marker(self._marker) + self._recache() + def _recache(self): self._path = Path(np.empty((0,2))) self._transform = IdentityTransform() @@ -124,7 +135,7 @@ self._marker_function() def __nonzero__(self): - return len(self._path.vertices) + return bool(len(self._path.vertices)) def is_filled(self): return self._filled @@ -258,11 +269,16 @@ self._path = text self._snap = False + def _half_fill(self): + fs = self.get_fillstyle() + result = fs in self._half_fillstyles + return result + def _set_circle(self, reduction = 1.0): self._transform = Affine2D().scale(0.5 * reduction) - self._snap_threshold = 3.0 + self._snap_threshold = 6.0 fs = self.get_fillstyle() - if fs=='full': + if not self._half_fill(): self._path = Path.unit_circle() else: # build a right-half circle @@ -313,7 +329,7 @@ self._snap_threshold = 5.0 fs = self.get_fillstyle() - if fs=='full': + if not self._half_fill(): self._path = self._triangle_path else: mpaths = [self._triangle_path_u, @@ -354,7 +370,7 @@ self._transform = Affine2D().translate(-0.5, -0.5) self._snap_threshold = 2.0 fs = self.get_fillstyle() - if fs=='full': + if not self._half_fill(): self._path = Path.unit_rectangle() else: # build a bottom filled square out of two rectangles, one @@ -376,7 +392,7 @@ self._transform = Affine2D().translate(-0.5, -0.5).rotate_deg(45) self._snap_threshold = 5.0 fs = self.get_fillstyle() - if fs=='full': + if not self._half_fill(): self._path = Path.unit_rectangle() else: self._path = Path([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]) @@ -403,7 +419,7 @@ polypath = Path.unit_regular_polygon(5) fs = self.get_fillstyle() - if fs == 'full': + if not self._half_fill(): self._path = polypath else: verts = polypath.vertices @@ -435,7 +451,7 @@ fs = self.get_fillstyle() polypath = Path.unit_regular_star(5, innerCircle=0.381966) - if fs == 'full': + if not self._half_fill(): self._path = polypath else: verts = polypath.vertices @@ -466,7 +482,7 @@ fs = self.get_fillstyle() polypath = Path.unit_regular_polygon(6) - if fs == 'full': + if not self._half_fill(): self._path = polypath else: verts = polypath.vertices @@ -500,7 +516,7 @@ fs = self.get_fillstyle() polypath = Path.unit_regular_polygon(6) - if fs == 'full': + if not self._half_fill(): self._path = polypath else: verts = polypath.vertices @@ -534,7 +550,7 @@ fs = self.get_fillstyle() polypath = Path.unit_regular_polygon(8) - if fs == 'full': + if not self._half_fill(): self._transform.rotate_deg(22.5) self._path = polypath else: @@ -672,7 +688,7 @@ self._path = self._x_path _styles = [(repr(x), y) for x, y in MarkerStyle.markers.items()] -_styles.sort(lambda x, y: cmp(x[1], y[1])) +_styles.sort(key = lambda x: x[1]) MarkerStyle.style_table = ( MarkerStyle.style_table % '\n'.join(['%-30s %-33s' % ('``%s``' % x, y) for (x, y) in _styles])) diff -Nru matplotlib-1.1.1/lib/matplotlib/mathtext.py matplotlib-1.2.0/lib/matplotlib/mathtext.py --- matplotlib-1.1.1/lib/matplotlib/mathtext.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/mathtext.py 2012-11-06 22:31:09.000000000 +0000 @@ -17,9 +17,12 @@ If you find TeX expressions that don't parse or render properly, please email mdroe@stsci.edu, but please check KNOWN ISSUES below first. """ -from __future__ import division -import os -from cStringIO import StringIO +from __future__ import division, print_function +import os, sys +if sys.version_info[0] >= 3: + from io import StringIO +else: + from cStringIO import StringIO from math import ceil try: set @@ -30,10 +33,18 @@ from numpy import inf, isinf import numpy as np -from matplotlib.pyparsing import Combine, Group, Optional, Forward, \ - Literal, OneOrMore, ZeroOrMore, ParseException, Empty, \ - ParseResults, Suppress, oneOf, StringEnd, ParseFatalException, \ - FollowedBy, Regex, ParserElement + +if sys.version_info[0] >= 3: + from matplotlib.pyparsing_py3 import Combine, Group, Optional, Forward, \ + Literal, OneOrMore, ZeroOrMore, ParseException, Empty, \ + ParseResults, Suppress, oneOf, StringEnd, ParseFatalException, \ + FollowedBy, Regex, ParserElement, QuotedString, ParseBaseException +else: + from matplotlib.pyparsing_py2 import Combine, Group, Optional, Forward, \ + Literal, OneOrMore, ZeroOrMore, ParseException, Empty, \ + ParseResults, Suppress, oneOf, StringEnd, ParseFatalException, \ + FollowedBy, Regex, ParserElement, QuotedString, ParseBaseException + # Enable packrat parsing ParserElement.enablePackrat() @@ -46,8 +57,6 @@ latex_to_standard, tex2uni, latex_to_cmex, stix_virtual_fonts from matplotlib import get_data_path, rcParams - - import matplotlib.colors as mcolors import matplotlib._png as _png #################### @@ -80,7 +89,7 @@ except KeyError: message = """'%(symbol)s' is not a valid Unicode character or TeX/Type1 symbol"""%locals() - raise ValueError, message + raise ValueError(message) def unichr_safe(index): """Return the Unicode character corresponding to the index, @@ -108,7 +117,9 @@ - :meth:`get_hinting_type` """ def __init__(self): - self.fonts_object = None + self.width = 0 + self.height = 0 + self.depth = 0 def set_canvas_size(self, w, h, d): 'Dimension the drawing canvas' @@ -143,16 +154,18 @@ """ return LOAD_NO_HINTING -class MathtextBackendBbox(MathtextBackend): +class MathtextBackendAgg(MathtextBackend): """ - A backend whose only purpose is to get a precise bounding box. - Only required for the Agg backend. + Render glyphs and rectangles to an FTImage buffer, which is later + transferred to the Agg image by the Agg backend. """ - - def __init__(self, real_backend): - MathtextBackend.__init__(self) + def __init__(self): + self.ox = 0 + self.oy = 0 + self.image = None + self.mode = 'bbox' self.bbox = [0, 0, 0, 0] - self.real_backend = real_backend + MathtextBackend.__init__(self) def _update_bbox(self, x1, y1, x2, y2): self.bbox = [min(self.bbox[0], x1), @@ -160,95 +173,66 @@ max(self.bbox[2], x2), max(self.bbox[3], y2)] + def set_canvas_size(self, w, h, d): + MathtextBackend.set_canvas_size(self, w, h, d) + if self.mode != 'bbox': + self.image = FT2Image(ceil(w), ceil(h + d)) + def render_glyph(self, ox, oy, info): - self._update_bbox(ox + info.metrics.xmin, - oy - info.metrics.ymax, - ox + info.metrics.xmax, - oy - info.metrics.ymin) + if self.mode == 'bbox': + self._update_bbox(ox + info.metrics.xmin, + oy - info.metrics.ymax, + ox + info.metrics.xmax, + oy - info.metrics.ymin) + else: + info.font.draw_glyph_to_bitmap( + self.image, ox, oy - info.metrics.iceberg, info.glyph, + antialiased=rcParams['text.antialiased']) def render_rect_filled(self, x1, y1, x2, y2): - self._update_bbox(x1, y1, x2, y2) + if self.mode == 'bbox': + self._update_bbox(x1, y1, x2, y2) + else: + height = max(int(y2 - y1) - 1, 0) + if height == 0: + center = (y2 + y1) / 2.0 + y = int(center - (height + 1) / 2.0) + else: + y = int(y1) + self.image.draw_rect_filled(int(x1), y, ceil(x2), y + height) - def get_results(self, box): + def get_results(self, box, used_characters): + self.mode = 'bbox' orig_height = box.height orig_depth = box.depth ship(0, 0, box) bbox = self.bbox bbox = [bbox[0] - 1, bbox[1] - 1, bbox[2] + 1, bbox[3] + 1] - self._switch_to_real_backend() - self.fonts_object.set_canvas_size( + self.mode = 'render' + self.set_canvas_size( bbox[2] - bbox[0], (bbox[3] - bbox[1]) - orig_depth, (bbox[3] - bbox[1]) - orig_height) ship(-bbox[0], -bbox[1], box) - return self.fonts_object.get_results(box) - - def get_hinting_type(self): - return self.real_backend.get_hinting_type() - - def _switch_to_real_backend(self): - self.fonts_object.mathtext_backend = self.real_backend - self.real_backend.fonts_object = self.fonts_object - self.real_backend.ox = self.bbox[0] - self.real_backend.oy = self.bbox[1] - -class MathtextBackendAggRender(MathtextBackend): - """ - Render glyphs and rectangles to an FTImage buffer, which is later - transferred to the Agg image by the Agg backend. - """ - def __init__(self): - self.ox = 0 - self.oy = 0 + result = (self.ox, + self.oy, + self.width, + self.height + self.depth, + self.depth, + self.image, + used_characters) self.image = None - MathtextBackend.__init__(self) - - def set_canvas_size(self, w, h, d): - MathtextBackend.set_canvas_size(self, w, h, d) - self.image = FT2Image(ceil(w), ceil(h + d)) - - def render_glyph(self, ox, oy, info): - info.font.draw_glyph_to_bitmap( - self.image, ox, oy - info.metrics.iceberg, info.glyph, - antialiased=rcParams['text.antialiased']) - - def render_rect_filled(self, x1, y1, x2, y2): - height = max(int(y2 - y1) - 1, 0) - if height == 0: - center = (y2 + y1) / 2.0 - y = int(center - (height + 1) / 2.0) - else: - y = int(y1) - self.image.draw_rect_filled(int(x1), y, ceil(x2), y + height) - - def get_results(self, box): - return (self.ox, - self.oy, - self.width, - self.height + self.depth, - self.depth, - self.image, - self.fonts_object.get_used_characters()) + return result def get_hinting_type(self): - if rcParams['text.hinting']: - return LOAD_FORCE_AUTOHINT - else: - return LOAD_NO_HINTING - -def MathtextBackendAgg(): - return MathtextBackendBbox(MathtextBackendAggRender()) - -class MathtextBackendBitmapRender(MathtextBackendAggRender): - def get_results(self, box): - return self.image, self.depth + from matplotlib.backends import backend_agg + return backend_agg.get_hinting_flag() -def MathtextBackendBitmap(): - """ - A backend to generate standalone mathtext images. No additional - matplotlib backend is required. - """ - return MathtextBackendBbox(MathtextBackendBitmapRender()) +class MathtextBackendBitmap(MathtextBackendAgg): + def get_results(self, box, used_characters): + ox, oy, width, height, depth, image, characters = \ + MathtextBackendAgg.get_results(self, box, used_characters) + return image, depth class MathtextBackendPs(MathtextBackend): """ @@ -282,14 +266,13 @@ ps = "%f %f %f %f rectfill\n" % (x1, self.height - y2, x2 - x1, y2 - y1) self.pswriter.write(ps) - def get_results(self, box): + def get_results(self, box, used_characters): ship(0, -self.depth, box) - #print self.depth return (self.width, self.height + self.depth, self.depth, self.pswriter, - self.fonts_object.get_used_characters()) + used_characters) class MathtextBackendPdf(MathtextBackend): """ @@ -310,14 +293,14 @@ def render_rect_filled(self, x1, y1, x2, y2): self.rects.append((x1, self.height - y2, x2 - x1, y2 - y1)) - def get_results(self, box): + def get_results(self, box, used_characters): ship(0, -self.depth, box) return (self.width, self.height + self.depth, self.depth, self.glyphs, self.rects, - self.fonts_object.get_used_characters()) + used_characters) class MathtextBackendSvg(MathtextBackend): """ @@ -338,7 +321,7 @@ self.svg_rects.append( (x1, self.height - y1 + 1, x2 - x1, y2 - y1)) - def get_results(self, box): + def get_results(self, box, used_characters): ship(0, -self.depth, box) svg_elements = Bunch(svg_glyphs = self.svg_glyphs, svg_rects = self.svg_rects) @@ -346,7 +329,7 @@ self.height + self.depth, self.depth, svg_elements, - self.fonts_object.get_used_characters()) + used_characters) class MathtextBackendPath(MathtextBackend): """ @@ -368,7 +351,7 @@ self.rects.append( (x1, self.height-y2 , x2 - x1, y2 - y1)) - def get_results(self, box): + def get_results(self, box, used_characters): ship(0, -self.depth, box) return (self.width, self.height + self.depth, @@ -396,7 +379,7 @@ self.rects.append( (x1, y1 - self.height, x2 - x1, y2 - y1)) - def get_results(self, box): + def get_results(self, box, used_characters): ship(0, -self.depth, box) return (self.width, self.height + self.depth, @@ -425,8 +408,6 @@ """ self.default_font_prop = default_font_prop self.mathtext_backend = mathtext_backend - # Make these classes doubly-linked - self.mathtext_backend.fonts_object = self self.used_characters = {} def destroy(self): @@ -549,7 +530,9 @@ Get the data needed by the backend to render the math expression. The return value is backend-specific. """ - return self.mathtext_backend.get_results(box) + result = self.mathtext_backend.get_results(box, self.get_used_characters()) + self.destroy() + return result def get_sized_alternatives_for_symbol(self, fontname, sym): """ @@ -787,7 +770,11 @@ ('\leftbrace', '{'), ('\rightbrace', '}'), ('\leftbracket', '['), - ('\rightbracket', ']')]: + ('\rightbracket', ']'), + (r'\{', '{'), + (r'\}', '}'), + (r'\[', '['), + (r'\]', ']')]: _size_alternatives[alias] = _size_alternatives[target] def get_sized_alternatives_for_symbol(self, fontname, sym): @@ -986,6 +973,9 @@ _size_alternatives = {} def get_sized_alternatives_for_symbol(self, fontname, sym): + fixes = {'\{': '{', '\}': '}', '\[': '[', '\]': ']'} + sym = fixes.get(sym, sym) + alternatives = self._size_alternatives.get(sym) if alternatives: return alternatives @@ -1051,7 +1041,8 @@ if filename is None: filename = findfont('Helvetica', fontext='afm', directory=self.basepath) - default_font = AFM(file(filename, 'r')) + with open(filename, 'r') as fd: + default_font = AFM(fd) default_font.fname = filename self.fonts['default'] = default_font @@ -1067,7 +1058,8 @@ cached_font = self.fonts.get(basename) if cached_font is None: fname = os.path.join(self.basepath, basename + ".afm") - cached_font = AFM(file(fname, 'r')) + with open(fname, 'r') as fd: + cached_font = AFM(fd) cached_font.fname = fname self.fonts[basename] = cached_font self.fonts[cached_font.get_fontname()] = cached_font @@ -1843,7 +1835,7 @@ fonts), the correct glyph will be selected, otherwise this will always just return a scaled version of the glyph. """ - def __init__(self, c, height, depth, state, always=False): + def __init__(self, c, height, depth, state, always=False, factor=None): alternatives = state.font_output.get_sized_alternatives_for_symbol( state.font, c) @@ -1855,7 +1847,8 @@ if char.height + char.depth >= target_total: break - factor = target_total / (char.height + char.depth) + if factor is None: + factor = target_total / (char.height + char.depth) state.fontsize *= factor char = Char(sym, state) @@ -2047,7 +2040,7 @@ Helper class to raise parser errors. """ def raise_error(s, loc, toks): - raise ParseFatalException(msg + "\n" + s) + raise ParseFatalException(s, loc, msg) empty = Empty() empty.setParseAction(raise_error) @@ -2124,226 +2117,213 @@ liminf sin cos exp limsup sinh cosh gcd ln sup cot hom log tan coth inf max tanh""".split()) - _ambiDelim = set(r""" + _ambi_delim = set(r""" | \| / \backslash \uparrow \downarrow \updownarrow \Uparrow \Downarrow \Updownarrow .""".split()) - _leftDelim = set(r"( [ { < \lfloor \langle \lceil".split()) + _left_delim = set(r"( [ \{ < \lfloor \langle \lceil".split()) - _rightDelim = set(r") ] } > \rfloor \rangle \rceil".split()) + _right_delim = set(r") ] \} > \rfloor \rangle \rceil".split()) def __init__(self): # All forward declarations are here - font = Forward().setParseAction(self.font).setName("font") - latexfont = Forward() - subsuper = Forward().setParseAction(self.subsuperscript).setName("subsuper") - placeable = Forward().setName("placeable") - simple = Forward().setName("simple") - autoDelim = Forward().setParseAction(self.auto_sized_delimiter) - self._expression = Forward().setParseAction(self.finish).setName("finish") - - float = Regex(r"[-+]?([0-9]+\.?[0-9]*|\.[0-9]+)") - - lbrace = Literal('{').suppress() - rbrace = Literal('}').suppress() - start_group = (Optional(latexfont) - lbrace) - start_group.setParseAction(self.start_group) - end_group = rbrace.copy() - end_group.setParseAction(self.end_group) - - bslash = Literal('\\') - - accent = oneOf(self._accent_map.keys() + - list(self._wide_accents)) - - function = oneOf(list(self._function_names)) - - fontname = oneOf(list(self._fontnames)) - latex2efont = oneOf(['math' + x for x in self._fontnames]) - - space =(FollowedBy(bslash) - + oneOf([r'\ ', - r'\/', - r'\,', - r'\;', - r'\quad', - r'\qquad', - r'\!']) - ).setParseAction(self.space).setName('space') - - customspace =(Literal(r'\hspace') - - (( lbrace - - float - - rbrace - ) | Error(r"Expected \hspace{n}")) - ).setParseAction(self.customspace).setName('customspace') - - unicode_range = u"\U00000080-\U0001ffff" - symbol =(Regex(UR"([a-zA-Z0-9 +\-*/<>=:,.;!\?&@()\[\]|%s])|(\\[%%${}\[\]_|])" % unicode_range) - | (Combine( - bslash - + oneOf(tex2uni.keys()) - ) + FollowedBy(Regex("[^a-zA-Z]"))) - ).setParseAction(self.symbol).leaveWhitespace() - - apostrophe = Regex(r"'+") - - c_over_c =(Suppress(bslash) - + oneOf(self._char_over_chars.keys()) - ).setParseAction(self.char_over_chars) - - accent = Group( - Suppress(bslash) - + accent - - placeable - ).setParseAction(self.accent).setName("accent") - - function =(Suppress(bslash) - + function - ).setParseAction(self.function).setName("function") - - group = Group( - start_group - + ZeroOrMore( - autoDelim - ^ simple) - - end_group - ).setParseAction(self.group).setName("group") - - font <<(Suppress(bslash) - + fontname) - - latexfont <<(Suppress(bslash) - + latex2efont) - - frac = Group( - Suppress(Literal(r"\frac")) - + ((group + group) - | Error(r"Expected \frac{num}{den}")) - ).setParseAction(self.frac).setName("frac") - - stackrel = Group( - Suppress(Literal(r"\stackrel")) - + ((group + group) - | Error(r"Expected \stackrel{num}{den}")) - ).setParseAction(self.stackrel).setName("stackrel") - - - binom = Group( - Suppress(Literal(r"\binom")) - + ((group + group) - | Error(r"Expected \binom{num}{den}")) - ).setParseAction(self.binom).setName("binom") - - ambiDelim = oneOf(list(self._ambiDelim)) - leftDelim = oneOf(list(self._leftDelim)) - rightDelim = oneOf(list(self._rightDelim)) - rightDelimSafe = oneOf(list(self._rightDelim - set(['}']))) - genfrac = Group( - Suppress(Literal(r"\genfrac")) - + ((Suppress(Literal('{')) + - oneOf(list(self._ambiDelim | self._leftDelim | set(['']))) + - Suppress(Literal('}')) + - Suppress(Literal('{')) + - oneOf(list(self._ambiDelim | - (self._rightDelim - set(['}'])) | - set(['', r'\}']))) + - Suppress(Literal('}')) + - Suppress(Literal('{')) + - Regex("[0-9]*(\.?[0-9]*)?") + - Suppress(Literal('}')) + - group + group + group) - | Error(r"Expected \genfrac{ldelim}{rdelim}{rulesize}{style}{num}{den}")) - ).setParseAction(self.genfrac).setName("genfrac") - - sqrt = Group( - Suppress(Literal(r"\sqrt")) - + Optional( - Suppress(Literal("[")) - - Regex("[0-9]+") - - Suppress(Literal("]")), - default = None - ) - + (group | Error("Expected \sqrt{value}")) - ).setParseAction(self.sqrt).setName("sqrt") - - overline = Group( - Suppress(Literal(r"\overline")) - + (group | Error("Expected \overline{value}")) - ).setParseAction(self.overline).setName("overline") - - placeable <<(function - ^ (c_over_c | symbol) - ^ accent - ^ group - ^ frac - ^ stackrel - ^ binom - ^ genfrac - ^ sqrt - ^ overline - ) - - simple <<(space - | customspace - | font - | subsuper - ) - - subsuperop = oneOf(["_", "^"]) - - subsuper << Group( - ( Optional(placeable) - + OneOrMore( - subsuperop + accent = Forward() + ambi_delim = Forward() + apostrophe = Forward() + auto_delim = Forward() + binom = Forward() + bslash = Forward() + c_over_c = Forward() + customspace = Forward() + end_group = Forward() + float_literal = Forward() + font = Forward() + frac = Forward() + function = Forward() + genfrac = Forward() + group = Forward() + int_literal = Forward() + latexfont = Forward() + lbracket = Forward() + left_delim = Forward() + lbrace = Forward() + main = Forward() + math = Forward() + math_string = Forward() + non_math = Forward() + operatorname = Forward() + overline = Forward() + placeable = Forward() + rbrace = Forward() + rbracket = Forward() + required_group = Forward() + right_delim = Forward() + right_delim_safe = Forward() + simple = Forward() + simple_group = Forward() + single_symbol = Forward() + space = Forward() + sqrt = Forward() + stackrel = Forward() + start_group = Forward() + subsuper = Forward() + subsuperop = Forward() + symbol = Forward() + symbol_name = Forward() + token = Forward() + unknown_symbol = Forward() + + # Set names on everything -- very useful for debugging + for key, val in locals().items(): + if key != 'self': + val.setName(key) + + float_literal << Regex(r"[-+]?([0-9]+\.?[0-9]*|\.[0-9]+)") + int_literal << Regex("[-+]?[0-9]+") + + lbrace << Literal('{').suppress() + rbrace << Literal('}').suppress() + lbracket << Literal('[').suppress() + rbracket << Literal(']').suppress() + bslash << Literal('\\') + + space << oneOf(self._space_widths.keys()) + customspace << (Suppress(Literal(r'\hspace')) + - ((lbrace + float_literal + rbrace) + | Error(r"Expected \hspace{n}"))) + + unicode_range = u"\U00000080-\U0001ffff" + single_symbol << Regex(UR"([a-zA-Z0-9 +\-*/<>=:,.;!\?&'@()\[\]|%s])|(\\[%%${}\[\]_|])" % + unicode_range) + symbol_name << (Combine(bslash + oneOf(tex2uni.keys())) + + FollowedBy(Regex("[^A-Za-z]").leaveWhitespace() | StringEnd())) + symbol << (single_symbol | symbol_name).leaveWhitespace() + + apostrophe << Regex("'+") + + c_over_c << Suppress(bslash) + oneOf(self._char_over_chars.keys()) + + accent << Group( + Suppress(bslash) + + oneOf(self._accent_map.keys() + list(self._wide_accents)) - placeable - ) - + Optional(apostrophe) ) - | (placeable + Optional(apostrophe)) - | apostrophe - ) - - autoDelim <<(Suppress(Literal(r"\left")) - + ((leftDelim | ambiDelim) | Error("Expected a delimiter")) - + Group( - OneOrMore( - autoDelim - ^ simple)) - + Suppress(Literal(r"\right")) - + ((rightDelim | ambiDelim) | Error("Expected a delimiter")) - ) - - math = OneOrMore( - autoDelim - ^ simple - ).setParseAction(self.math).setName("math") - - math_delim = ~bslash + Literal('$') - - non_math = Regex(r"(?:(?:\\[$])|[^$])*" - ).setParseAction(self.non_math).setName("non_math").leaveWhitespace() - - self._expression << ( - non_math - + ZeroOrMore( - Suppress(math_delim) - + Optional(math) - + (Suppress(math_delim) - | Error("Expected end of math '$'")) - + non_math - ) - ) + StringEnd() - self.clear() + function << Suppress(bslash) + oneOf(list(self._function_names)) - def clear(self): - """ - Clear any state before parsing. - """ - self._expr = None - self._state_stack = None - self._em_width_cache = {} + start_group << Optional(latexfont) + lbrace + end_group << rbrace.copy() + simple_group << Group(lbrace + ZeroOrMore(token) + rbrace) + required_group<< Group(lbrace + OneOrMore(token) + rbrace) + group << Group(start_group + ZeroOrMore(token) + end_group) + + font << Suppress(bslash) + oneOf(list(self._fontnames)) + latexfont << Suppress(bslash) + oneOf(['math' + x for x in self._fontnames]) + + frac << Group( + Suppress(Literal(r"\frac")) + - ((required_group + required_group) | Error(r"Expected \frac{num}{den}")) + ) + + stackrel << Group( + Suppress(Literal(r"\stackrel")) + - ((required_group + required_group) | Error(r"Expected \stackrel{num}{den}")) + ) + + binom << Group( + Suppress(Literal(r"\binom")) + - ((required_group + required_group) | Error(r"Expected \binom{num}{den}")) + ) + + ambi_delim << oneOf(list(self._ambi_delim)) + left_delim << oneOf(list(self._left_delim)) + right_delim << oneOf(list(self._right_delim)) + right_delim_safe << oneOf(list(self._right_delim - set(['}'])) + [r'\}']) + + genfrac << Group( + Suppress(Literal(r"\genfrac")) + - (((lbrace + Optional(ambi_delim | left_delim, default='') + rbrace) + + (lbrace + Optional(ambi_delim | right_delim_safe, default='') + rbrace) + + (lbrace + float_literal + rbrace) + + simple_group + required_group + required_group) + | Error(r"Expected \genfrac{ldelim}{rdelim}{rulesize}{style}{num}{den}")) + ) + + sqrt << Group( + Suppress(Literal(r"\sqrt")) + - ((Optional(lbracket + int_literal + rbracket, default=None) + + required_group) + | Error("Expected \sqrt{value}")) + ) + + overline << Group( + Suppress(Literal(r"\overline")) + - (required_group | Error("Expected \overline{value}")) + ) + + unknown_symbol<< Combine(bslash + Regex("[A-Za-z]*")) + + operatorname << Group( + Suppress(Literal(r"\operatorname")) + - ((lbrace + ZeroOrMore(simple | unknown_symbol) + rbrace) + | Error("Expected \operatorname{value}")) + ) + + placeable << ( accent # Must be first + | symbol # Must be second + | c_over_c + | function + | group + | frac + | stackrel + | binom + | genfrac + | sqrt + | overline + | operatorname + ) + + simple << ( space + | customspace + | font + | subsuper + ) + + subsuperop << oneOf(["_", "^"]) + + subsuper << Group( + (Optional(placeable) + OneOrMore(subsuperop - placeable) + Optional(apostrophe)) + | (placeable + Optional(apostrophe)) + | apostrophe + ) + + token << ( simple + | auto_delim + | unknown_symbol # Must be last + ) + + auto_delim << (Suppress(Literal(r"\left")) + - ((left_delim | ambi_delim) | Error("Expected a delimiter")) + + Group(ZeroOrMore(simple | auto_delim)) + + Suppress(Literal(r"\right")) + - ((right_delim | ambi_delim) | Error("Expected a delimiter")) + ) + + math << OneOrMore(token) + + math_string << QuotedString('$', '\\', unquoteResults=False) + + non_math << Regex(r"(?:(?:\\[$])|[^$])*").leaveWhitespace() + + main << (non_math + ZeroOrMore(math_string + non_math)) + StringEnd() + + # Set actions + for key, val in locals().items(): + if hasattr(self, key): + val.setParseAction(getattr(self, key)) + + self._expression = main + self._math_expression = math def parse(self, s, fonts_object, fontsize, dpi): """ @@ -2353,15 +2333,19 @@ Returns the parse tree of :class:`Node` instances. """ self._state_stack = [self.State(fonts_object, 'default', 'rm', fontsize, dpi)] + self._em_width_cache = {} try: - self._expression.parseString(s) - except ParseException, err: + result = self._expression.parseString(s) + except ParseBaseException as err: raise ValueError("\n".join([ "", err.line, " " * (err.column - 1) + "^", str(err)])) - return self._expr + self._state_stack = None + self._em_width_cache = {} + self._expression.resetCache() + return result[0] # The state of the parser is maintained in a stack. Upon # entering and leaving a group { } or math/non-math, the stack @@ -2416,10 +2400,13 @@ """ self._state_stack.append(self.get_state().copy()) - def finish(self, s, loc, toks): + def main(self, s, loc, toks): #~ print "finish", toks - self._expr = Hlist(toks) - return [self._expr] + return [Hlist(toks)] + + def math_string(self, s, loc, toks): + # print "math_string", toks[0][1:-1] + return self._math_expression.parseString(toks[0][1:-1]) def math(self, s, loc, toks): #~ print "math", toks @@ -2463,7 +2450,7 @@ return [box] def customspace(self, s, loc, toks): - return [self._make_space(float(toks[1]))] + return [self._make_space(float(toks[0]))] def symbol(self, s, loc, toks): # print "symbol", toks @@ -2471,7 +2458,7 @@ try: char = Char(c, self.get_state()) except ValueError: - raise ParseFatalException("Unknown symbol: %s" % c) + raise ParseFatalException(s, loc, "Unknown symbol: %s" % c) if c in self._spaced_symbols: return [Hlist( [self._make_space(0.2), @@ -2484,6 +2471,11 @@ do_kern = False)] return [char] + def unknown_symbol(self, s, loc, toks): + # print "symbol", toks + c = toks[0] + raise ParseFatalException(s, loc, "Unknown symbol: %s" % c) + _char_over_chars = { # The first 2 entires in the tuple are (font, char, sizescale) for # the two symbols under and over. The third element is the space @@ -2491,7 +2483,7 @@ r'AA' : ( ('rm', 'A', 1.0), (None, '\circ', 0.5), 0.0), } - def char_over_chars(self, s, loc, toks): + def c_over_c(self, s, loc, toks): sym = toks[0] state = self.get_state() thickness = state.font_output.get_underline_thickness( @@ -2581,6 +2573,18 @@ hlist.function_name = toks[0] return hlist + def operatorname(self, s, loc, toks): + self.push_state() + state = self.get_state() + state.font = 'rm' + # Change the font of Chars, but leave Kerns alone + for c in toks[0]: + if isinstance(c, Char): + c.font = 'rm' + c._update_metrics() + self.pop_state() + return Hlist(toks[0]) + def start_group(self, s, loc, toks): self.push_state() # Deal with LaTeX-style font tokens @@ -2591,6 +2595,7 @@ def group(self, s, loc, toks): grp = Hlist(toks[0]) return [grp] + required_group = simple_group = group def end_group(self, s, loc, toks): self.pop_state() @@ -2619,9 +2624,9 @@ return nucleus.is_slanted() return False - def subsuperscript(self, s, loc, toks): + def subsuper(self, s, loc, toks): assert(len(toks)==1) - # print 'subsuperscript', toks + # print 'subsuper', toks nucleus = None sub = None @@ -2798,8 +2803,6 @@ ldelim = '.' if rdelim == '': rdelim = '.' - elif rdelim == r'\}': - rdelim = '}' return self._auto_sized_delimiter(ldelim, result, rdelim) return result @@ -2858,7 +2861,7 @@ padded_body]) # Stretch the glue between the hrule and the body rightside.vpack(height + (state.fontsize * state.dpi) / (100.0 * 12.0), - depth, 'exactly') + 'exactly', depth) # Add the root and shift it upward so it is above the tick. # The value of 0.6 is a hard-coded hack ;) @@ -2899,28 +2902,33 @@ # Stretch the glue between the hrule and the body rightside.vpack(height + (state.fontsize * state.dpi) / (100.0 * 12.0), - depth, 'exactly') + 'exactly', depth) hlist = Hlist([rightside]) return [hlist] def _auto_sized_delimiter(self, front, middle, back): state = self.get_state() - height = max([x.height for x in middle]) - depth = max([x.depth for x in middle]) + if len(middle): + height = max([x.height for x in middle]) + depth = max([x.depth for x in middle]) + factor = None + else: + height = 0 + depth = 0 + factor = 1.0 parts = [] # \left. and \right. aren't supposed to produce any symbols if front != '.': - parts.append(AutoHeightChar(front, height, depth, state)) + parts.append(AutoHeightChar(front, height, depth, state, factor=factor)) parts.extend(middle) if back != '.': - parts.append(AutoHeightChar(back, height, depth, state)) + parts.append(AutoHeightChar(back, height, depth, state, factor=factor)) hlist = Hlist(parts) return hlist - - def auto_sized_delimiter(self, s, loc, toks): - #~ print "auto_sized_delimiter", toks + def auto_delim(self, s, loc, toks): + #~ print "auto_delim", toks front, middle, back = toks return self._auto_sized_delimiter(front, middle.asList(), back) @@ -2969,8 +2977,11 @@ The results are cached, so multiple calls to :meth:`parse` with the same expression should be fast. """ + # There is a bug in Python 3.x where it leaks frame references, + # and therefore can't handle this caching if prop is None: prop = FontProperties() + cacheKey = (s, dpi, hash(prop)) result = self._cache.get(cacheKey) if result is not None: @@ -3000,14 +3011,6 @@ font_output.set_canvas_size(box.width, box.height, box.depth) result = font_output.get_results(box) self._cache[cacheKey] = result - # Free up the transient data structures - self._parser.clear() - - # Fix cyclical references - font_output.destroy() - font_output.mathtext_backend.fonts_object = None - font_output.mathtext_backend = None - return result def to_mask(self, texstr, dpi=120, fontsize=14): diff -Nru matplotlib-1.1.1/lib/matplotlib/mlab.py matplotlib-1.2.0/lib/matplotlib/mlab.py --- matplotlib-1.1.1/lib/matplotlib/mlab.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/mlab.py 2012-11-06 18:14:56.000000000 +0000 @@ -141,16 +141,17 @@ """ -from __future__ import division +from __future__ import division, print_function import csv, warnings, copy, os, operator +from itertools import izip import numpy as np ma = np.ma from matplotlib import verbose -import matplotlib.nxutils as nxutils import matplotlib.cbook as cbook from matplotlib import docstring +from matplotlib.path import Path def logspace(xmin,xmax,N): @@ -331,10 +332,6 @@ argument, it must take a data segment as an argument and return the windowed version of the segment. - *noverlap*: integer - The number of points of overlap between blocks. The default value - is 0 (no overlap). - *pad_to*: integer The number of points to which the data segment is padded when performing the FFT. This can be different from *NFFT*, which @@ -376,6 +373,10 @@ %(PSD)s + *noverlap*: integer + The number of points of overlap between blocks. The default value + is 0 (no overlap). + Returns the tuple (*Pxx*, *freqs*). Refs: @@ -408,6 +409,10 @@ %(PSD)s + *noverlap*: integer + The number of points of overlap between blocks. The default value + is 0 (no overlap). + Returns the tuple (*Pxy*, *freqs*). Refs: @@ -436,6 +441,10 @@ %(PSD)s + *noverlap*: integer + The number of points of overlap between blocks. The default value + is 128. + Returns a tuple (*Pxx*, *freqs*, *t*): - *Pxx*: 2-D array, columns are the periodograms of @@ -481,6 +490,10 @@ %(PSD)s + *noverlap*: integer + The number of points of overlap between blocks. The default value + is 0 (no overlap). + The return value is the tuple (*Cxy*, *f*), where *f* are the frequencies of the coherence vector. For cohere, scaling the individual densities by the sampling frequency has no effect, @@ -686,16 +699,15 @@ x = mu + sigma * randn(200000) Sanalytic = 0.5 * ( 1.0 + log(2*pi*sigma**2.0) ) """ - n,bins = np.histogram(y, bins) + n, bins = np.histogram(y, bins) n = n.astype(np.float_) n = np.take(n, np.nonzero(n)[0]) # get the positive p = np.divide(n, len(y)) - delta = bins[1]-bins[0] - S = -1.0*np.sum(p*log(p)) + log(delta) - #S = -1.0*np.sum(p*log(p)) + delta = bins[1] - bins[0] + S = -1.0 * np.sum(p * np.log(p)) + np.log(delta) return S def normpdf(x, *args): @@ -709,22 +721,20 @@ N = len(x) - if N%2 != 0: - raise ValueError, 'x must be an event length array; try\n' + \ - 'x = np.linspace(minx, maxx, N), where N is even' + if N % 2 != 0: + raise ValueError('x must be an event length array; try\n' + \ + 'x = np.linspace(minx, maxx, N), where N is even') + dx = x[1] - x[0] - dx = x[1]-x[0] + f = 1/(N*dx)*np.arange(-N / 2, N / 2, np.float_) + ind = np.concatenate([np.arange(N / 2, N, int), + np.arange(0, N / 2, int)]) + df = f[1] - f[0] + cfl = np.exp(-gamma * np.absolute(2 * np.pi * f) ** alpha) - f = 1/(N*dx)*np.arange(-N/2, N/2, np.float_) - - ind = np.concatenate([np.arange(N/2, N, int), - np.arange(0, N/2, int)]) - df = f[1]-f[0] - cfl = exp(-gamma*np.absolute(2*pi*f)**alpha) - - px = np.fft.fft(np.take(cfl,ind)*df).astype(np.float_) + px = np.fft.fft(np.take(cfl, ind) * df).astype(np.float_) return np.take(px, ind) @@ -1256,7 +1266,7 @@ self._xs[ind] = x self._ys[ind] = y - for N,funcs in self.callbackd.items(): + for N,funcs in self.callbackd.iteritems(): if (self._ind%N)==0: for func in funcs: func(self) @@ -1336,7 +1346,7 @@ import gzip fh = gzip.open(fname,'wb') else: - fh = file(fname,'w') + fh = open(fname,'w') elif hasattr(fname, 'seek'): fh = fname else: @@ -1445,7 +1455,6 @@ else: row = [converterseq[j](val) for j,val in enumerate(splitfunc(line))] - thisLen = len(row) X.append(row) X = np.array(X, dtype) @@ -1498,7 +1507,6 @@ """ -import operator import math @@ -1520,7 +1528,7 @@ """ if type(x) is np.ndarray: - return exp(np.clip(x,exp_safe_MIN,exp_safe_MAX)) + return np.exp(np.clip(x,exp_safe_MIN,exp_safe_MAX)) else: return math.exp(x) @@ -1774,7 +1782,7 @@ if (not cbook.is_string_like(names) and cbook.iterable(names) \ and len(names) and cbook.is_string_like(names[0])): if len(names) != len(arrs): - raise ValueError, "number of arrays do not match number of names" + raise ValueError("number of arrays do not match number of names") else: # we have only 1 name and 1 array names = [names] arrs = [arrs] @@ -1787,7 +1795,7 @@ if len(dtypes) == 1: dtypes = dtypes * len(arrs) else: - raise ValueError, "dtypes must be None, a single dtype or a list" + raise ValueError("dtypes must be None, a single dtype or a list") newdtype = np.dtype(rec.dtype.descr + zip(names, dtypes)) newrec = np.recarray(rec.shape, dtype=newdtype) @@ -1804,7 +1812,6 @@ """ names = set(names) - Nr = len(rec) newdtype = np.dtype([(name, rec.dtype[name]) for name in rec.dtype.names if name not in names]) @@ -2004,7 +2011,7 @@ if jointype != 'inner' and defaults is not None: # fill in the defaults enmasse newrec_fields = newrec.dtype.fields.keys() - for k, v in defaults.items(): + for k, v in defaults.iteritems(): if k in newrec_fields: newrec[k] = v @@ -2133,8 +2140,6 @@ import dateutil.parser import datetime - parsedate = dateutil.parser.parse - fh = cbook.to_filehandle(fname) @@ -2160,8 +2165,8 @@ return ' '.join(s.split()) - def next(self): - return self.fix(self.fh.next()) + def __next__(self): + return self.fix(next(self.fh)) def __iter__(self): for line in self.fh: @@ -2246,7 +2251,7 @@ break #print i, len(names), len(row) #print 'converters', zip(converters, row) - for j, (name, item) in enumerate(zip(names, row)): + for j, (name, item) in enumerate(izip(names, row)): func = converterd.get(j) if func is None: func = converterd.get(name) @@ -2309,7 +2314,7 @@ if needheader: while 1: # skip past any comments and consume one line of column header - row = reader.next() + row = next(reader) if len(row) and row[0].startswith(comments): continue break @@ -2755,7 +2760,7 @@ xo = xi.astype(np.float) yo = yi.astype(np.float) if min(xo[1:]-xo[0:-1]) < 0 or min(yo[1:]-yo[0:-1]) < 0: - raise ValueError, 'output grid defined by xi,yi must be monotone increasing' + raise ValueError('output grid defined by xi,yi must be monotone increasing') # allocate array for output (buffer will be overwritten by nagridd) zo = np.empty((yo.shape[0],xo.shape[0]), np.float) _natgrid.natgridd(x,y,z,xo,yo,zo) @@ -2925,7 +2930,6 @@ x=np.asarray(x, np.float_) y=np.asarray(y, np.float_) assert x.shape == y.shape - N=len(y) if yp is None: yp = slopes(x,y) @@ -2980,8 +2984,11 @@ Return value is a sequence of indices into points for the points that are inside the polygon. """ - res, = np.nonzero(nxutils.points_inside_poly(points, verts)) - return res + # Make a closed polygon path + poly = Path( verts ) + + # Check to see which points are contained withing the Path + return [ idx for idx, p in enumerate(points) if poly.contains_point(p) ] def poly_below(xmin, xs, ys): """ @@ -2995,17 +3002,17 @@ ax.fill(xv, yv) """ if ma.isMaskedArray(xs) or ma.isMaskedArray(ys): - nx = ma + numpy = ma else: - nx = np + numpy = np - xs = nx.asarray(xs) - ys = nx.asarray(ys) + xs = numpy.asarray(xs) + ys = numpy.asarray(ys) Nx = len(xs) Ny = len(ys) assert(Nx==Ny) - x = xmin*nx.ones(2*Nx) - y = nx.ones(2*Nx) + x = xmin*numpy.ones(2*Nx) + y = numpy.ones(2*Nx) x[:Nx] = xs y[:Nx] = ys y[Nx:] = ys[::-1] @@ -3024,19 +3031,19 @@ :meth:`matplotlib.axes.Axes.fill`. """ if ma.isMaskedArray(ylower) or ma.isMaskedArray(yupper) or ma.isMaskedArray(x): - nx = ma + numpy = ma else: - nx = np + numpy = np Nx = len(x) if not cbook.iterable(ylower): - ylower = ylower*nx.ones(Nx) + ylower = ylower*numpy.ones(Nx) if not cbook.iterable(yupper): - yupper = yupper*nx.ones(Nx) + yupper = yupper*numpy.ones(Nx) - x = nx.concatenate( (x, x[::-1]) ) - y = nx.concatenate( (yupper, ylower[::-1]) ) + x = numpy.concatenate( (x, x[::-1]) ) + y = numpy.concatenate( (yupper, ylower[::-1]) ) return x,y @@ -3178,3 +3185,33 @@ c2x, c2y = c1x + 1./3. * (q2x - q0x), c1y + 1./3. * (q2y - q0y) # c3x, c3y = q2x, q2y return q0x, q0y, c1x, c1y, c2x, c2y, q2x, q2y + +def offset_line(y, yerr): + """ + Offsets an array *y* by +/- an error and returns a tuple (y - err, y + err). + + The error term can be: + + * A scalar. In this case, the returned tuple is obvious. + * A vector of the same length as *y*. The quantities y +/- err are computed + component-wise. + * A tuple of length 2. In this case, yerr[0] is the error below *y* and + yerr[1] is error above *y*. For example:: + + from pylab import * + x = linspace(0, 2*pi, num=100, endpoint=True) + y = sin(x) + y_minus, y_plus = mlab.offset_line(y, 0.1) + plot(x, y) + fill_between(x, ym, y2=yp) + show() + + """ + if cbook.is_numlike(yerr) or (cbook.iterable(yerr) and len(yerr) == len(y)): + ymin = y - yerr + ymax = y + yerr + elif len(yerr) == 2: + ymin, ymax = y - yerr[0], y + yerr[1] + else: + raise ValueError("yerr must be scalar, 1xN or 2xN") + return ymin, ymax Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/mpl-data/images/matplotlib.gif and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/mpl-data/images/matplotlib.gif differ diff -Nru matplotlib-1.1.1/lib/matplotlib/mpl-data/matplotlib.conf matplotlib-1.2.0/lib/matplotlib/mpl-data/matplotlib.conf --- matplotlib-1.1.1/lib/matplotlib/mpl-data/matplotlib.conf 2012-06-30 19:37:12.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/mpl-data/matplotlib.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,413 +0,0 @@ -# MPLConfig - plaintext (in .conf format) - -# This is a sample matplotlib configuration file. It should be placed -# in HOME/.matplotlib (unix/linux like systems) and -# C:\Documents and Settings\yourname\.matplotlib (win32 systems) -# -# By default, the installer will overwrite the existing file in the install -# path, so if you want to preserve yours, please move it to your HOME dir and -# set the environment variable if necessary. -# -# This file is best viewed in a editor which supports ini or conf mode syntax -# highlighting. -# -# Blank lines, or lines starting with a comment symbol, are ignored, -# as are trailing comments. Other lines must have the format -# -# key = val optional comment -# -# val should be valid python syntax, just as you would use when setting -# properties using rcParams. This should become more obvious by inspecting -# the default values listed herein. -# -# Colors: for the color values below, you can either use -# - a matplotlib color string, such as r | k | b -# - an rgb tuple, such as (1.0, 0.5, 0.0) -# - a hex string, such as #ff00ff or ff00ff -# - a scalar grayscale intensity such as 0.75 -# - a legal html color name, eg red | blue | darkslategray -# -# Interactivity: see http://matplotlib.sourceforge.net/interactive.html. -# -# ### CONFIGURATION BEGINS HERE ### - -# a value of type 'str' -#datapath = '/usr/lib64/python2.5/site-packages/matplotlib/mpl-data' -# one of: 0 | on | false | 1 | no | n | y | off | yes | true -interactive = False -# a boolean -maskedarray = False -# 'numpy' or 'numeric' or 'numarray' -numerix = 'numpy' -# 'Africa/Abidjan' or 'Africa/Accra' or 'Africa/Addis_Ababa' or -# 'Africa/Algiers' or 'Africa/Asmara' or 'Africa/Asmera' or 'Africa/Bamako' or -# 'Africa/Bangui' or 'Africa/Banjul' or 'Africa/Bissau' or 'Africa/Blantyre' -# <...snipped 156 lines...> -# 'US/Michigan' or 'US/Mountain' or 'US/Pacific' or 'US/Pacific-New' or -# 'US/Samoa' or 'UTC' or 'Universal' or 'W-SU' or 'WET' or 'Zulu' or -# 'posixrules' -timezone = 'UTC' -# 'toolbar2' or None -toolbar = 'toolbar2' -# a boolean -units = False - -[axes] - # a boolean - axisbelow = False - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - edgecolor = 'black' - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - facecolor = 'white' - # one of: 0 | on | false | 1 | no | n | y | off | yes | true - grid = False - # one of: 0 | on | false | 1 | no | n | y | off | yes | true - hold = True - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - labelcolor = 'black' - # a float or 'xx-small' or 'x-small' or 'small' or 'medium' or 'large' or - # 'x-large' or 'xx-large' - labelsize = 'medium' - # a float - linewidth = 1.0 - # one of: 0 | on | false | 1 | no | n | y | off | yes | true - polargrid = True - # a float or 'xx-small' or 'x-small' or 'small' or 'medium' or 'large' or - # 'x-large' or 'xx-large' - titlesize = 'large' - - [[formatter]] - # a list of from 2 to 2 items which are a float - limits = [-7.0, 7.0] - -[backend] - # one of: ps | qt4agg | fltkagg | gtkagg | agg | cairo | gtk | gtkcairo | - # wxagg | tkagg | qtagg | template | svg | cocoaagg | pdf | wx - use = 'GTKAgg' - - [[cairo]] - # 'png' or 'ps' or 'pdf' or 'svg' - format = 'png' - - [[pdf]] - # 0 <= an integer <= 9 - compression = 6 - # 3 or 42 - fonttype = 3 - # a boolean - inheritcolor = False - # a boolean - use14corefonts = False - - [[ps]] - # 3 or 42 - fonttype = 3 - # 'auto' or 'letter' or 'legal' or 'ledger' or 'A0' or 'A1' or 'A2' or - # 'A3' or 'A4' or 'A5' or 'A6' or 'A7' or 'A8' or 'A9' or 'A10' or - # 'B0' or 'B1' or 'B2' or 'B3' or 'B4' or 'B5' or 'B6' or 'B7' or 'B8' - # or 'B9' or 'B10' - papersize = 'letter' - # a boolean - useafm = False - - [[[distiller]]] - # a float - resolution = 6000 - # an implementor of, or can be adapted to implement, bool or None - # or None or 'ghostscript' or 'xpdf' - use = None - - [[svg]] - # a boolean - embed_chars = True - # a boolean - image_inline = True - # a boolean - image_noscale = False - - [[tk]] - # window_focus : Maintain shell focus for TkAgg - # pythoninspect: tk sets PYTHONINSPECT - - # a boolean - pythoninspect = False - # a boolean - window_focus = False - -[contour] - # 'dashed' or 'solid' - negative_linestyle = 'dashed' - -[figure] - # a float - dpi = 80 - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - edgecolor = 'white' - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - facecolor = '0.75' - # a list of from 2 to 2 items which are a float - figsize = [8.0, 6.0] - - [[subplot]] - # The figure subplot parameters. All dimensions are fraction - # of the figure width or height - # a float - bottom = 0.10000000000000001 - # a float - hspace = 0.20000000000000001 - # a float - left = 0.125 - # a float - right = 0.90000000000000002 - # a float - top = 0.90000000000000002 - # a float - wspace = 0.20000000000000001 - -[font] - # a list of items which are a value of type 'str' - cursive = ['Apple Chancery', 'Textile', 'Zapf Chancery', 'Sand', 'cursive'] - # 'sans-serif' or 'serif' or 'cursive' or 'fantasy' or 'monospace' - family = 'sans-serif' - # a list of items which are a value of type 'str' - fantasy = ['Comic Sans MS', 'Chicago', 'Charcoal', 'Impact', 'Western', 'fantasy'] - # a list of items which are a value of type 'str' - monospace = ['Bitstream Vera Sans Mono', 'Andale Mono', 'Nimbus Mono L', 'Courier New', 'Courier', 'Fixed', 'Terminal', 'monospace'] - # a list of items which are a value of type 'str' - sans_serif = ['Bitstream Vera Sans', 'Lucida Grande', 'Verdana', 'Geneva', 'Lucid', 'Arial', 'Helvetica', 'Avant Garde', 'sans-serif'] - # a list of items which are a value of type 'str' - serif = ['Bitstream Vera Serif', 'New Century Schoolbook', 'Century Schoolbook L', 'Utopia', 'ITC Bookman', 'Bookman', 'Nimbus Roman No9 L', 'Times New Roman', 'Times', 'Palatino', 'Charter', 'serif'] - # a float - size = 12.0 - # 'ultra-condensed' or 'extra-condensed' or 'condensed' or - # 'semi-condensed' or 'normal' or 'semi-expanded' or 'expanded' or - # 'extra-expanded' or 'ultra-expanded' or 'wider' or 'narrower' - stretch = 'normal' - # 'normal' or 'italic' or 'oblique' - style = 'normal' - # 'normal' or 'small-caps' - variant = 'normal' - # 'normal' or 'bold' or 'bolder' or 'lighter' or 100 or 200 or 300 or 400 - # or 500 or 600 or 700 or 800 or 900 - weight = 'normal' - -[grid] - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - color = 'black' - # '-' or '--' or '-.' or ':' or 'steps' or '' or ' ' - linestyle = ':' - # a float - linewidth = 0.5 - -[image] - # a float or 'equal' or 'auto' - aspect = 'equal' - # 'Accent' or 'Accent_r' or 'Blues' or 'Blues_r' or 'BrBG' or 'BrBG_r' or - # 'BuGn' or 'BuGn_r' or 'BuPu' or 'BuPu_r' or 'Dark2' or 'Dark2_r' or - # 'GnBu' or 'GnBu_r' or 'Greens' or 'Greens_r' or 'Greys' or 'Greys_r' or - # <...snipped 16 lines...> - # 'pink_r' or 'prism' or 'prism_r' or 'spectral' or 'spectral_r' or - # 'spring' or 'spring_r' or 'summer' or 'summer_r' or 'winter' or - # 'winter_r' - cmap = 'jet' - # 'bilinear' or 'nearest' or 'bicubic' or 'spline16' or 'spline36' or - # 'hanning' or 'hamming' or 'hermite' or 'kaiser' or 'quadric' or 'catrom' - # or 'gaussian' or 'bessel' or 'mitchell' or 'sinc' or 'lanczos' or - # 'blackman' - interpolation = 'bilinear' - # an integer - lut = 256 - # 'upper' or 'lower' - origin = 'upper' - -[legend] - # a float or 'xx-small' or 'x-small' or 'small' or 'medium' or 'large' or - # 'x-large' or 'xx-large' - fontsize = 'medium' - # a boolean - isaxes = True - # 'best' or 'upper right' or 'upper left' or 'lower left' or 'lower right' - # or 'right' or 'center left' or 'center right' or 'lower center' or - # 'upper center' or 'center' - loc = 'upper right' - # a float - markerscale = 1.0 - # an integer - numpoints = 3 - # a boolean - shadow = False - # float - borderpad = 0.4 - # float - labelspacing = 0.5 - # float - handlelength = 2. - # float - handletextpad = 0.8 - # float - borderaxespad = 0.5 - # float - columnspacing = 2. - - -[lines] - # a boolean - antialiased = True - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - color = 'blue' - # 'butt' or 'round' or 'projecting' - dash_capstyle = 'butt' - # 'miter' or 'round' or 'bevel' - dash_joinstyle = 'miter' - # '-' or '--' or '-.' or ':' or 'steps' or '' or ' ' or None - linestyle = '-' - # a float - linewidth = 1.0 - # 'None' or 'o' or '.' or ',' or '^' or 'v' or '<' or '>' or 's' or '+' or - # 'x' or 'D' or 'd' or '1' or '2' or '3' or '4' or 'h' or 'H' or 'p' or - # '|' or '_' - marker = 'None' - # a float - markeredgewidth = 0.5 - # a float - markersize = 6 - # 'butt' or 'round' or 'projecting' - solid_capstyle = 'butt' - # 'miter' or 'round' or 'bevel' - solid_joinstyle = 'miter' - -[mathtext] - # A fontconfig pattern. See the fontconfig user manual for more - # information. - bf = 'serif:bold' - # A fontconfig pattern. See the fontconfig user manual for more - # information. - cal = 'cursive' - # a boolean - fallback_to_cm = True - # 'cm' or 'stix' or 'stixsans' or 'custom' - fontset = 'cm' - # A fontconfig pattern. See the fontconfig user manual for more - # information. - it = 'serif:oblique' - # A fontconfig pattern. See the fontconfig user manual for more - # information. - rm = 'serif' - # A fontconfig pattern. See the fontconfig user manual for more - # information. - sf = 'sans' - # A fontconfig pattern. See the fontconfig user manual for more - # information. - tt = 'monospace' - -[patch] - # a boolean - antialiased = True - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - edgecolor = 'black' - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - facecolor = 'blue' - # a float - linewidth = 1.0 - -[savefig] - # a float - dpi = 100 - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - edgecolor = 'white' - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - facecolor = 'white' - # 'portrait' or 'landscape' - orientation = 'portrait' - -[text] - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - color = 'black' - # a boolean - usetex = False - - [[latex]] - # a boolean - dvipnghack = False - # a list of items which are a value of type 'str' - preamble = [] - # a boolean - unicode = False - # a boolean - preview = False - -[verbose] - # a file name or 'sys.stdout' - fileo = 'sys.stdout' - # 'silent' or 'helpful' or 'debug' or 'debug-annoying' - level = 'silent' - -[xticks] - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - color = 'black' - # 'in' or 'out' - direction = 'in' - # a float or 'xx-small' or 'x-small' or 'small' or 'medium' or 'large' or - # 'x-large' or 'xx-large' - labelsize = 'small' - - [[major]] - # a float - pad = 4 - # a float - size = 4 - - [[minor]] - # a float - pad = 4 - # a float - size = 2 - -[yticks] - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - color = 'black' - # 'in' or 'out' - direction = 'in' - # a float or 'xx-small' or 'x-small' or 'small' or 'medium' or 'large' or - # 'x-large' or 'xx-large' - labelsize = 'small' - - [[major]] - # a float - pad = 4 - # a float - size = 4 - - [[minor]] - # a float - pad = 4 - # a float - size = 2 \ No newline at end of file diff -Nru matplotlib-1.1.1/lib/matplotlib/mpl-data/matplotlib.conf.template matplotlib-1.2.0/lib/matplotlib/mpl-data/matplotlib.conf.template --- matplotlib-1.1.1/lib/matplotlib/mpl-data/matplotlib.conf.template 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/mpl-data/matplotlib.conf.template 1970-01-01 00:00:00.000000000 +0000 @@ -1,413 +0,0 @@ -# MPLConfig - plaintext (in .conf format) - -# This is a sample matplotlib configuration file. It should be placed -# in HOME/.matplotlib (unix/linux like systems) and -# C:\Documents and Settings\yourname\.matplotlib (win32 systems) -# -# By default, the installer will overwrite the existing file in the install -# path, so if you want to preserve yours, please move it to your HOME dir and -# set the environment variable if necessary. -# -# This file is best viewed in a editor which supports ini or conf mode syntax -# highlighting. -# -# Blank lines, or lines starting with a comment symbol, are ignored, -# as are trailing comments. Other lines must have the format -# -# key = val optional comment -# -# val should be valid python syntax, just as you would use when setting -# properties using rcParams. This should become more obvious by inspecting -# the default values listed herein. -# -# Colors: for the color values below, you can either use -# - a matplotlib color string, such as r | k | b -# - an rgb tuple, such as (1.0, 0.5, 0.0) -# - a hex string, such as #ff00ff or ff00ff -# - a scalar grayscale intensity such as 0.75 -# - a legal html color name, eg red | blue | darkslategray -# -# Interactivity: see http://matplotlib.sourceforge.net/interactive.html. -# -# ### CONFIGURATION BEGINS HERE ### - -# a value of type 'str' -datapath = '/usr/lib64/python2.5/site-packages/matplotlib/mpl-data' -# one of: 0 | on | false | 1 | no | n | y | off | yes | true -interactive = False -# a boolean -maskedarray = False -# 'numpy' or 'numeric' or 'numarray' -numerix = 'numpy' -# 'Africa/Abidjan' or 'Africa/Accra' or 'Africa/Addis_Ababa' or -# 'Africa/Algiers' or 'Africa/Asmara' or 'Africa/Asmera' or 'Africa/Bamako' or -# 'Africa/Bangui' or 'Africa/Banjul' or 'Africa/Bissau' or 'Africa/Blantyre' -# <...snipped 156 lines...> -# 'US/Michigan' or 'US/Mountain' or 'US/Pacific' or 'US/Pacific-New' or -# 'US/Samoa' or 'UTC' or 'Universal' or 'W-SU' or 'WET' or 'Zulu' or -# 'posixrules' -timezone = 'UTC' -# 'toolbar2' or None -toolbar = 'toolbar2' -# a boolean -units = False - -[axes] - # a boolean - axisbelow = False - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - edgecolor = 'black' - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - facecolor = 'white' - # one of: 0 | on | false | 1 | no | n | y | off | yes | true - grid = False - # one of: 0 | on | false | 1 | no | n | y | off | yes | true - hold = True - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - labelcolor = 'black' - # a float or 'xx-small' or 'x-small' or 'small' or 'medium' or 'large' or - # 'x-large' or 'xx-large' - labelsize = 'medium' - # a float - linewidth = 1.0 - # one of: 0 | on | false | 1 | no | n | y | off | yes | true - polargrid = True - # a float or 'xx-small' or 'x-small' or 'small' or 'medium' or 'large' or - # 'x-large' or 'xx-large' - titlesize = 'large' - - [[formatter]] - # a list of from 2 to 2 items which are a float - limits = [-7.0, 7.0] - -[backend] - # one of: ps | qt4agg | fltkagg | gtkagg | agg | cairo | gtk | gtkcairo | - # wxagg | tkagg | qtagg | template | svg | cocoaagg | pdf | wx - use = 'Agg' - - [[cairo]] - # 'png' or 'ps' or 'pdf' or 'svg' - format = 'png' - - [[pdf]] - # 0 <= an integer <= 9 - compression = 6 - # 3 or 42 - fonttype = 3 - # a boolean - inheritcolor = False - # a boolean - use14corefonts = False - - [[ps]] - # 3 or 42 - fonttype = 3 - # 'auto' or 'letter' or 'legal' or 'ledger' or 'A0' or 'A1' or 'A2' or - # 'A3' or 'A4' or 'A5' or 'A6' or 'A7' or 'A8' or 'A9' or 'A10' or - # 'B0' or 'B1' or 'B2' or 'B3' or 'B4' or 'B5' or 'B6' or 'B7' or 'B8' - # or 'B9' or 'B10' - papersize = 'letter' - # a boolean - useafm = False - - [[[distiller]]] - # a float - resolution = 6000 - # an implementor of, or can be adapted to implement, bool or None - # or None or 'ghostscript' or 'xpdf' - use = None - - [[svg]] - # a boolean - embed_chars = True - # a boolean - image_inline = True - # a boolean - image_noscale = False - - [[tk]] - # window_focus : Maintain shell focus for TkAgg - # pythoninspect: tk sets PYTHONINSPECT - - # a boolean - pythoninspect = False - # a boolean - window_focus = False - -[contour] - # 'dashed' or 'solid' - negative_linestyle = 'dashed' - -[figure] - # a float - dpi = 80 - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - edgecolor = 'white' - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - facecolor = '0.75' - # a list of from 2 to 2 items which are a float - figsize = [8.0, 6.0] - - [[subplot]] - # The figure subplot parameters. All dimensions are fraction - # of the figure width or height - # a float - bottom = 0.10000000000000001 - # a float - hspace = 0.20000000000000001 - # a float - left = 0.125 - # a float - right = 0.90000000000000002 - # a float - top = 0.90000000000000002 - # a float - wspace = 0.20000000000000001 - -[font] - # a list of items which are a value of type 'str' - cursive = ['Apple Chancery', 'Textile', 'Zapf Chancery', 'Sand', 'cursive'] - # 'sans-serif' or 'serif' or 'cursive' or 'fantasy' or 'monospace' - family = 'sans-serif' - # a list of items which are a value of type 'str' - fantasy = ['Comic Sans MS', 'Chicago', 'Charcoal', 'Impact', 'Western', 'fantasy'] - # a list of items which are a value of type 'str' - monospace = ['Bitstream Vera Sans Mono', 'Andale Mono', 'Nimbus Mono L', 'Courier New', 'Courier', 'Fixed', 'Terminal', 'monospace'] - # a list of items which are a value of type 'str' - sans_serif = ['Bitstream Vera Sans', 'Lucida Grande', 'Verdana', 'Geneva', 'Lucid', 'Arial', 'Helvetica', 'Avant Garde', 'sans-serif'] - # a list of items which are a value of type 'str' - serif = ['Bitstream Vera Serif', 'New Century Schoolbook', 'Century Schoolbook L', 'Utopia', 'ITC Bookman', 'Bookman', 'Nimbus Roman No9 L', 'Times New Roman', 'Times', 'Palatino', 'Charter', 'serif'] - # a float - size = 12.0 - # 'ultra-condensed' or 'extra-condensed' or 'condensed' or - # 'semi-condensed' or 'normal' or 'semi-expanded' or 'expanded' or - # 'extra-expanded' or 'ultra-expanded' or 'wider' or 'narrower' - stretch = 'normal' - # 'normal' or 'italic' or 'oblique' - style = 'normal' - # 'normal' or 'small-caps' - variant = 'normal' - # 'normal' or 'bold' or 'bolder' or 'lighter' or 100 or 200 or 300 or 400 - # or 500 or 600 or 700 or 800 or 900 - weight = 'normal' - -[grid] - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - color = 'black' - # '-' or '--' or '-.' or ':' or 'steps' or '' or ' ' - linestyle = ':' - # a float - linewidth = 0.5 - -[image] - # a float or 'equal' or 'auto' - aspect = 'equal' - # 'Accent' or 'Accent_r' or 'Blues' or 'Blues_r' or 'BrBG' or 'BrBG_r' or - # 'BuGn' or 'BuGn_r' or 'BuPu' or 'BuPu_r' or 'Dark2' or 'Dark2_r' or - # 'GnBu' or 'GnBu_r' or 'Greens' or 'Greens_r' or 'Greys' or 'Greys_r' or - # <...snipped 16 lines...> - # 'pink_r' or 'prism' or 'prism_r' or 'spectral' or 'spectral_r' or - # 'spring' or 'spring_r' or 'summer' or 'summer_r' or 'winter' or - # 'winter_r' - cmap = 'jet' - # 'bilinear' or 'nearest' or 'bicubic' or 'spline16' or 'spline36' or - # 'hanning' or 'hamming' or 'hermite' or 'kaiser' or 'quadric' or 'catrom' - # or 'gaussian' or 'bessel' or 'mitchell' or 'sinc' or 'lanczos' or - # 'blackman' - interpolation = 'bilinear' - # an integer - lut = 256 - # 'upper' or 'lower' - origin = 'upper' - -[legend] - # a float or 'xx-small' or 'x-small' or 'small' or 'medium' or 'large' or - # 'x-large' or 'xx-large' - fontsize = 'medium' - # a boolean - isaxes = True - # 'best' or 'upper right' or 'upper left' or 'lower left' or 'lower right' - # or 'right' or 'center left' or 'center right' or 'lower center' or - # 'upper center' or 'center' - loc = 'upper right' - # a float - markerscale = 1.0 - # an integer - numpoints = 3 - # a boolean - shadow = False - # float - borderpad = 0.4 - # float - labelspacing = 0.5 - # float - handlelength = 2. - # float - handletextpad = 0.8 - # float - borderaxespad = 0.5 - # float - columnspacing = 2. - - -[lines] - # a boolean - antialiased = True - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - color = 'blue' - # 'butt' or 'round' or 'projecting' - dash_capstyle = 'butt' - # 'miter' or 'round' or 'bevel' - dash_joinstyle = 'miter' - # '-' or '--' or '-.' or ':' or 'steps' or '' or ' ' or None - linestyle = '-' - # a float - linewidth = 1.0 - # 'None' or 'o' or '.' or ',' or '^' or 'v' or '<' or '>' or 's' or '+' or - # 'x' or 'D' or 'd' or '1' or '2' or '3' or '4' or 'h' or 'H' or 'p' or - # '|' or '_' - marker = 'None' - # a float - markeredgewidth = 0.5 - # a float - markersize = 6 - # 'butt' or 'round' or 'projecting' - solid_capstyle = 'butt' - # 'miter' or 'round' or 'bevel' - solid_joinstyle = 'miter' - -[mathtext] - # A fontconfig pattern. See the fontconfig user manual for more - # information. - bf = 'serif:bold' - # A fontconfig pattern. See the fontconfig user manual for more - # information. - cal = 'cursive' - # a boolean - fallback_to_cm = True - # 'cm' or 'stix' or 'stixsans' or 'custom' - fontset = 'cm' - # A fontconfig pattern. See the fontconfig user manual for more - # information. - it = 'serif:oblique' - # A fontconfig pattern. See the fontconfig user manual for more - # information. - rm = 'serif' - # A fontconfig pattern. See the fontconfig user manual for more - # information. - sf = 'sans' - # A fontconfig pattern. See the fontconfig user manual for more - # information. - tt = 'monospace' - -[patch] - # a boolean - antialiased = True - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - edgecolor = 'black' - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - facecolor = 'blue' - # a float - linewidth = 1.0 - -[savefig] - # a float - dpi = 100 - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - edgecolor = 'white' - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - facecolor = 'white' - # 'portrait' or 'landscape' - orientation = 'portrait' - -[text] - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - color = 'black' - # a boolean - usetex = False - - [[latex]] - # a boolean - dvipnghack = False - # a list of items which are a value of type 'str' - preamble = [] - # a boolean - unicode = False - # a boolean - preview = False - -[verbose] - # a file name or 'sys.stdout' - fileo = 'sys.stdout' - # 'silent' or 'helpful' or 'debug' or 'debug-annoying' - level = 'silent' - -[xticks] - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - color = 'black' - # 'in' or 'out' - direction = 'in' - # a float or 'xx-small' or 'x-small' or 'small' or 'medium' or 'large' or - # 'x-large' or 'xx-large' - labelsize = 'small' - - [[major]] - # a float - pad = 4 - # a float - size = 4 - - [[minor]] - # a float - pad = 4 - # a float - size = 2 - -[yticks] - # any valid matplotlib color, eg an abbreviation like 'r' for red, a full - # name like 'orange', a hex color like '#efefef', a grayscale intensity - # like '0.5', or an RGBA tuple (1,0,0,1) - color = 'black' - # 'in' or 'out' - direction = 'in' - # a float or 'xx-small' or 'x-small' or 'small' or 'medium' or 'large' or - # 'x-large' or 'xx-large' - labelsize = 'small' - - [[major]] - # a float - pad = 4 - # a float - size = 4 - - [[minor]] - # a float - pad = 4 - # a float - size = 2 \ No newline at end of file diff -Nru matplotlib-1.1.1/lib/matplotlib/mpl-data/matplotlibrc matplotlib-1.2.0/lib/matplotlib/mpl-data/matplotlibrc --- matplotlib-1.1.1/lib/matplotlib/mpl-data/matplotlibrc 2012-06-30 19:37:12.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/mpl-data/matplotlibrc 2012-11-08 16:39:20.000000000 +0000 @@ -23,8 +23,9 @@ #### CONFIGURATION BEGINS HERE -# the default backend; one of GTK GTKAgg GTKCairo CocoaAgg FltkAgg -# MacOSX QtAgg Qt4Agg TkAgg WX WXAgg Agg Cairo GDK PS PDF SVG Template +# the default backend; one of GTK GTKAgg GTKCairo GTK3Agg GTK3Cairo +# CocoaAgg FltkAgg MacOSX QtAgg Qt4Agg TkAgg WX WXAgg Agg Cairo GDK PS +# PDF SVG Template # You can also deploy your own backend outside of matplotlib by # referring to the module name (which must be in the PYTHONPATH) as # 'module://my_backend' @@ -46,7 +47,7 @@ #backend_fallback: True #interactive : False -#toolbar : toolbar2 # None | classic | toolbar2 +#toolbar : toolbar2 # None | toolbar2 ("classic" is deprecated) #timezone : UTC # a pytz timezone string, eg US/Central or Europe/Paris # Where your matplotlib data lives if you installed to a non-default @@ -55,11 +56,11 @@ ### LINES -# See http://matplotlib.sourceforge.net/api/artist_api.html#module-matplotlib.lines for more +# See http://matplotlib.org/api/artist_api.html#module-matplotlib.lines for more # information on line properties. #lines.linewidth : 1.0 # line width in points #lines.linestyle : - # solid line -#lines.color : blue +#lines.color : blue # has no affect on plot(); see axes.color_cycle #lines.marker : None # the default marker #lines.markeredgewidth : 0.5 # the line width around the marker symbol #lines.markersize : 6 # markersize, in points @@ -72,7 +73,7 @@ ### PATCHES # Patches are graphical objects that fill 2D space, like polygons or # circles. See -# http://matplotlib.sourceforge.net/api/artist_api.html#module-matplotlib.patches +# http://matplotlib.org/api/artist_api.html#module-matplotlib.patches # information on patch properties #patch.linewidth : 1.0 # edge width in points #patch.facecolor : blue @@ -82,7 +83,7 @@ ### FONT # # font properties used by text.Text. See -# http://matplotlib.sourceforge.net/api/font_manager_api.html for more +# http://matplotlib.org/api/font_manager_api.html for more # information on font properties. The 6 font properties used for font # matching are given below with their default values. # @@ -133,7 +134,7 @@ ### TEXT # text properties used by text.Text. See -# http://matplotlib.sourceforge.net/api/artist_api.html#module-matplotlib.text for more +# http://matplotlib.org/api/artist_api.html#module-matplotlib.text for more # information on text properties #text.color : black @@ -169,8 +170,19 @@ # correction off. None will try and # guess based on your dvipng version -#text.hinting : True # If True, text will be hinted, otherwise not. This only - # affects the Agg backend. +#text.hinting : 'auto' # May be one of the following: + # 'none': Perform no hinting + # 'auto': Use freetype's autohinter + # 'native': Use the hinting information in the + # font file, if available, and if your + # freetype library supports it + # 'either': Use the native hinting information, + # or the autohinter if none is available. + # For backward compatibility, this value may also be + # True === 'auto' or False === 'none'. +text.hinting_factor : 8 # Specifies the amount of softness for hinting in the + # horizontal direction. A value of 1 will hint to full + # pixels. A value of 2 will hint to half pixels etc. #text.antialiased : True # If True (default), the text will be antialiased. # This only affects the Agg backend. @@ -200,7 +212,7 @@ ### AXES # default face and edge color, default tick sizes, # default fontsizes for ticklabels, and so on. See -# http://matplotlib.sourceforge.net/api/axes_api.html#module-matplotlib.axes +# http://matplotlib.org/api/axes_api.html#module-matplotlib.axes #axes.hold : True # whether to clear the axes by default on #axes.facecolor : white # axes background color #axes.edgecolor : black # axes edge color @@ -219,6 +231,8 @@ # according to the user's locale. # For example, use ',' as a decimal # separator in the fr_FR locale. +#axes.formatter.use_mathtext : False # When True, use mathtext for scientific + # notation. #axes.unicode_minus : True # use unicode for the minus symbol # rather than hyphen. See # http://en.wikipedia.org/wiki/Plus_and_minus_signs#Character_codes @@ -231,7 +245,7 @@ #axes3d.grid : True # display grid on 3d axes ### TICKS -# see http://matplotlib.sourceforge.net/api/axis_api.html#matplotlib.axis.Tick +# see http://matplotlib.org/api/axis_api.html#matplotlib.axis.Tick #xtick.major.size : 4 # major tick size in points #xtick.minor.size : 2 # minor tick size in points #xtick.major.width : 0.5 # major tick width in points @@ -240,7 +254,7 @@ #xtick.minor.pad : 4 # distance to the minor tick label in points #xtick.color : k # color of the tick labels #xtick.labelsize : medium # fontsize of the tick labels -#xtick.direction : in # direction: in or out +#xtick.direction : in # direction: in, out, or inout #ytick.major.size : 4 # major tick size in points #ytick.minor.size : 2 # minor tick size in points @@ -250,13 +264,14 @@ #ytick.minor.pad : 4 # distance to the minor tick label in points #ytick.color : k # color of the tick labels #ytick.labelsize : medium # fontsize of the tick labels -#ytick.direction : in # direction: in or out +#ytick.direction : in # direction: in, out, or inout ### GRIDS #grid.color : black # grid color #grid.linestyle : : # dotted #grid.linewidth : 0.5 # in points +#grid.alpha : 1.0 # transparency, between 0.0 and 1.0 ### Legend #legend.fancybox : False # if True, use a rounded box for the @@ -282,11 +297,13 @@ #legend.frameon : True # whether or not to draw a frame around legend ### FIGURE -# See http://matplotlib.sourceforge.net/api/figure_api.html#matplotlib.figure.Figure +# See http://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure #figure.figsize : 8, 6 # figure size in inches #figure.dpi : 80 # figure dots per inch #figure.facecolor : 0.75 # figure facecolor; 0.75 is scalar gray #figure.edgecolor : white # figure edgecolor +#figure.autolayout : False # When True, automatically adjust subplot + # parameters to make the plot fit the figure # The figure subplot parameters. All dimensions are a fraction of the # figure width or height @@ -332,12 +349,12 @@ # the default savefig params can be different from the display params # Eg, you may want a higher resolution, or to make the figure # background white -#savefig.dpi : 100 # figure dots per inch -#savefig.facecolor : white # figure facecolor when saving -#savefig.edgecolor : white # figure edgecolor when saving -#savefig.extension : auto # what extension to use for savefig('foo'), or 'auto' - -#cairo.format : png # png, ps, pdf, svg +#savefig.dpi : 100 # figure dots per inch +#savefig.facecolor : white # figure facecolor when saving +#savefig.edgecolor : white # figure edgecolor when saving +#savefig.format : png # png, ps, pdf, svg +#savefig.bbox : standard # 'tight' or 'standard'. +#savefig.pad_inches : 0.1 # Padding to be used when bbox is set to 'tight' # tk backend params #tk.window_focus : False # Maintain shell focus for TkAgg @@ -400,16 +417,21 @@ #keymap.pan : p # pan mnemonic #keymap.zoom : o # zoom mnemonic #keymap.save : s # saving current figure +#keymap.quit : ctrl+w # close the current figure #keymap.grid : g # switching on/off a grid in current axes #keymap.yscale : l # toggle scaling of y-axes ('log'/'linear') #keymap.xscale : L, k # toggle scaling of x-axes ('log'/'linear') #keymap.all_axes : a # enable all axes -# Control downloading of example data. Various examples download some -# data from the Matplotlib git repository to avoid distributing extra -# files, but sometimes you want to avoid that. In that case set -# examples.download to False and examples.directory to the directory -# where you have a checkout of https://github.com/matplotlib/sample_data - -#examples.download : True # False to bypass downloading mechanism -#examples.directory : '' # directory to look in if download is false +###ANIMATION settings +#animation.writer : ffmpeg # MovieWriter 'backend' to use +#animation.codec : mp4 # Codec to use for writing movie +#animation.bitrate: -1 # Controls size/quality tradeoff for movie. + # -1 implies let utility auto-determine +#animation.frame_format: 'png' # Controls frame format used by temp files +#animation.ffmpeg_path: 'ffmpeg' # Path to ffmpeg binary. Without full path + # $PATH is searched +#animation.ffmpeg_args: '' # Additional arugments to pass to mencoder +#animation.mencoder_path: 'ffmpeg' # Path to mencoder binary. Without full path + # $PATH is searched +#animation.mencoder_args: '' # Additional arugments to pass to mencoder Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/AAPL.dat.gz and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/AAPL.dat.gz differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/INTC.dat.gz and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/INTC.dat.gz differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/Minduka_Present_Blue_Pack.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/Minduka_Present_Blue_Pack.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/README.txt matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/README.txt --- matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/README.txt 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/README.txt 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,2 @@ +This is the sample data needed for some of matplotlib's examples and +docs. See matplotlib.cbook.get_sample_data for more info. diff -Nru matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/aapl.csv matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/aapl.csv --- matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/aapl.csv 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/aapl.csv 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,6082 @@ +Date,Open,High,Low,Close,Volume,Adj Close +2008-10-14,116.26,116.40,103.14,104.08,70749800,104.08 +2008-10-13,104.55,110.53,101.02,110.26,54967000,110.26 +2008-10-10,85.70,100.00,85.00,96.80,79260700,96.80 +2008-10-09,93.35,95.80,86.60,88.74,57763700,88.74 +2008-10-08,85.91,96.33,85.68,89.79,78847900,89.79 +2008-10-07,100.48,101.50,88.95,89.16,67099000,89.16 +2008-10-06,91.96,98.78,87.54,98.14,75264900,98.14 +2008-10-03,104.00,106.50,94.65,97.07,81942800,97.07 +2008-10-02,108.01,108.79,100.00,100.10,57477300,100.10 +2008-10-01,111.92,112.36,107.39,109.12,46303000,109.12 +2008-09-30,108.25,115.00,106.30,113.66,58095800,113.66 +2008-09-29,119.62,119.68,100.59,105.26,93581400,105.26 +2008-09-26,124.91,129.80,123.00,128.24,40208700,128.24 +2008-09-25,129.80,134.79,128.52,131.93,35865600,131.93 +2008-09-24,127.27,130.95,125.15,128.71,37393400,128.71 +2008-09-23,131.85,135.80,126.66,126.84,45727300,126.84 +2008-09-22,139.94,140.25,130.66,131.05,30577300,131.05 +2008-09-19,142.60,144.20,136.31,140.91,51102700,140.91 +2008-09-18,130.57,135.43,120.68,134.09,59819300,134.09 +2008-09-17,138.49,138.51,127.83,127.83,42847200,127.83 +2008-09-16,133.86,142.50,132.15,139.88,42804800,139.88 +2008-09-15,142.03,147.69,140.36,140.36,32852600,140.36 +2008-09-12,150.91,150.91,146.50,148.94,28322400,148.94 +2008-09-11,148.18,152.99,146.00,152.65,34666800,152.65 +2008-09-10,152.32,154.99,148.80,151.61,34755100,151.61 +2008-09-09,156.86,159.96,149.79,151.68,44442500,151.68 +2008-09-08,164.57,164.89,151.46,157.92,37356400,157.92 +2008-09-05,158.59,162.40,157.65,160.18,28083800,160.18 +2008-09-04,165.86,167.91,160.81,161.22,26549500,161.22 +2008-09-03,166.84,168.68,164.00,166.96,26244100,166.96 +2008-09-02,172.40,173.50,165.00,166.19,27884400,166.19 +2008-08-29,172.96,173.50,169.04,169.53,21403200,169.53 +2008-08-28,175.28,176.25,172.75,173.74,15394500,173.74 +2008-08-27,173.31,175.76,172.19,174.67,17045900,174.67 +2008-08-26,172.76,174.88,172.61,173.64,15912500,173.64 +2008-08-25,176.15,176.23,171.66,172.55,17300900,172.55 +2008-08-22,175.82,177.50,175.57,176.79,15700400,176.79 +2008-08-21,174.47,175.45,171.89,174.29,19276600,174.29 +2008-08-20,174.77,176.94,173.61,175.84,18105400,175.84 +2008-08-19,174.54,177.07,171.81,173.53,21997000,173.53 +2008-08-18,175.57,177.81,173.82,175.39,19691200,175.39 +2008-08-15,179.04,179.75,175.05,175.74,25294700,175.74 +2008-08-14,178.33,180.45,177.84,179.32,25393200,179.32 +2008-08-13,177.98,180.00,175.90,179.30,30083800,179.30 +2008-08-12,173.52,179.29,173.51,176.73,29867100,176.73 +2008-08-11,170.07,176.50,169.67,173.56,31821100,173.56 +2008-08-08,163.86,169.65,163.75,169.55,25499900,169.55 +2008-08-07,162.71,166.15,161.50,163.57,24013300,163.57 +2008-08-06,159.97,167.40,158.00,164.19,28264600,164.19 +2008-08-05,155.42,160.80,154.82,160.64,24584700,160.64 +2008-08-04,156.60,157.90,152.91,153.23,21161700,153.23 +2008-08-01,159.90,159.99,155.75,156.66,19451400,156.66 +2008-07-31,157.54,162.20,156.98,158.95,22767800,158.95 +2008-07-30,157.78,160.49,156.08,159.88,25899400,159.88 +2008-07-29,155.41,159.45,153.65,157.08,24431100,157.08 +2008-07-28,162.34,162.47,154.02,154.40,27882600,154.40 +2008-07-25,160.40,163.00,158.65,162.12,22629900,162.12 +2008-07-24,164.32,165.26,158.45,159.03,29986400,159.03 +2008-07-23,164.99,168.37,161.56,166.26,37920300,166.26 +2008-07-22,149.00,162.76,146.53,162.02,67128300,162.02 +2008-07-21,166.90,167.50,161.12,166.29,48588200,166.29 +2008-07-18,168.52,169.65,165.00,165.15,31014800,165.15 +2008-07-17,174.10,174.98,171.39,171.81,27054500,171.81 +2008-07-16,170.20,172.93,168.60,172.81,26706800,172.81 +2008-07-15,172.48,173.74,166.39,169.64,37144400,169.64 +2008-07-14,179.24,179.30,173.08,173.88,31644800,173.88 +2008-07-11,175.47,177.11,171.00,172.58,33214700,172.58 +2008-07-10,174.92,177.34,171.37,176.63,30024600,176.63 +2008-07-09,180.20,180.91,174.14,174.25,31992000,174.25 +2008-07-08,175.40,179.70,172.74,179.55,31726800,179.55 +2008-07-07,173.16,177.13,171.90,175.16,29299700,175.16 +2008-07-03,169.59,172.17,165.75,170.12,18691500,170.12 +2008-07-02,175.20,177.45,168.18,168.18,29911400,168.18 +2008-07-01,164.23,174.72,164.00,174.68,39688600,174.68 +2008-06-30,170.19,172.00,166.62,167.44,24435600,167.44 +2008-06-27,166.51,170.57,164.15,170.09,37223200,170.09 +2008-06-26,174.07,174.84,168.01,168.26,31057500,168.26 +2008-06-25,174.61,178.83,173.88,177.39,23016100,177.39 +2008-06-24,172.37,175.78,171.63,173.25,22212400,173.25 +2008-06-23,174.74,175.88,171.56,173.16,23063600,173.16 +2008-06-20,179.35,181.00,175.00,175.27,31727400,175.27 +2008-06-19,178.55,182.34,176.80,180.90,28283900,180.90 +2008-06-18,181.12,182.20,177.35,178.75,28981000,178.75 +2008-06-17,178.10,181.99,177.41,181.43,32130600,181.43 +2008-06-16,171.30,177.90,169.07,176.84,37561800,176.84 +2008-06-13,171.64,174.16,165.31,172.37,48069900,172.37 +2008-06-12,181.49,182.60,171.20,173.26,46726200,173.26 +2008-06-11,184.34,186.00,179.59,180.81,34341100,180.81 +2008-06-10,180.51,186.78,179.02,185.64,40728600,185.64 +2008-06-09,184.79,184.94,175.75,181.61,67442600,181.61 +2008-06-06,188.00,189.95,185.55,185.64,34438700,185.64 +2008-06-05,186.34,189.84,185.70,189.43,26980200,189.43 +2008-06-04,184.02,187.09,183.23,185.19,25963700,185.19 +2008-06-03,186.86,188.20,182.34,185.37,26804300,185.37 +2008-06-02,188.60,189.65,184.53,186.10,24280000,186.10 +2008-05-30,187.45,189.54,187.38,188.75,21792300,188.75 +2008-05-29,186.76,188.20,185.50,186.69,23113800,186.69 +2008-05-28,187.41,187.95,183.72,187.01,26570700,187.01 +2008-05-27,182.75,186.43,181.84,186.43,28210900,186.43 +2008-05-23,180.77,181.99,177.80,181.17,32389900,181.17 +2008-05-22,179.26,181.33,172.00,177.05,43097700,177.05 +2008-05-21,185.67,187.95,176.25,178.19,41344900,178.19 +2008-05-20,181.82,186.16,180.12,185.90,34637500,185.90 +2008-05-19,187.86,188.69,181.30,183.60,33779300,183.60 +2008-05-16,190.11,190.30,187.00,187.62,27348900,187.62 +2008-05-15,186.81,189.90,184.20,189.73,31186000,189.73 +2008-05-14,191.23,192.24,185.57,186.26,32743700,186.26 +2008-05-13,188.61,191.45,187.86,189.96,29401300,189.96 +2008-05-12,185.21,188.87,182.85,188.16,29234400,188.16 +2008-05-09,183.16,184.25,181.37,183.45,24038300,183.45 +2008-05-08,183.77,186.50,183.07,185.06,32110200,185.06 +2008-05-07,186.05,188.20,180.54,182.59,41326200,182.59 +2008-05-06,184.66,187.12,182.18,186.66,32816800,186.66 +2008-05-05,181.92,185.31,181.05,184.73,30519900,184.73 +2008-05-02,180.19,181.92,178.55,180.94,35931500,180.94 +2008-05-01,174.96,180.00,174.86,180.00,32270600,180.00 +2008-04-30,176.19,180.00,172.92,173.95,40697300,173.95 +2008-04-29,171.11,175.66,170.25,175.05,32981300,175.05 +2008-04-28,169.75,173.75,169.13,172.24,28114800,172.24 +2008-04-25,170.70,171.10,166.42,169.73,35445500,169.73 +2008-04-24,165.34,169.98,159.19,168.94,60573800,168.94 +2008-04-23,164.05,164.84,161.08,162.89,53721100,162.89 +2008-04-22,167.40,168.00,158.09,160.20,51413300,160.20 +2008-04-21,162.21,168.50,161.76,168.16,37112600,168.16 +2008-04-18,159.12,162.26,158.38,161.04,36670200,161.04 +2008-04-17,154.17,156.00,153.35,154.49,25152400,154.49 +2008-04-16,151.72,154.10,150.62,153.70,28420500,153.70 +2008-04-15,149.40,149.72,145.72,148.38,24929900,148.38 +2008-04-14,146.77,149.25,144.54,147.78,30181700,147.78 +2008-04-11,152.72,153.30,146.40,147.14,43217000,147.14 +2008-04-10,151.13,155.42,150.60,154.55,34134400,154.55 +2008-04-09,153.31,153.89,150.46,151.44,31192800,151.44 +2008-04-08,153.55,156.45,152.32,152.84,36224800,152.84 +2008-04-07,156.13,159.69,155.11,155.89,41368800,155.89 +2008-04-04,152.19,154.71,150.75,153.08,30514900,153.08 +2008-04-03,147.06,153.63,147.00,151.61,37556000,151.61 +2008-04-02,148.78,151.20,145.85,147.49,37320300,147.49 +2008-04-01,146.30,149.66,143.61,149.53,36877400,149.53 +2008-03-31,143.27,145.71,142.52,143.50,27430900,143.50 +2008-03-28,141.80,144.65,141.60,143.01,25521800,143.01 +2008-03-27,144.95,145.31,139.99,140.25,35708200,140.25 +2008-03-26,140.87,145.74,140.64,145.06,42217300,145.06 +2008-03-25,139.96,143.10,137.33,140.98,37585400,140.98 +2008-03-24,134.01,140.85,133.64,139.53,38104300,139.53 +2008-03-20,131.12,133.29,129.18,133.27,32456700,133.27 +2008-03-19,133.12,134.29,129.67,129.67,36090600,129.67 +2008-03-18,129.18,133.00,128.67,132.82,43040000,132.82 +2008-03-17,122.55,128.59,122.55,126.73,38307100,126.73 +2008-03-14,129.88,130.30,124.20,126.61,41308600,126.61 +2008-03-13,124.10,129.50,123.00,127.94,45075100,127.94 +2008-03-12,127.04,128.68,125.17,126.03,37843900,126.03 +2008-03-11,124.10,127.48,122.00,127.35,41569400,127.35 +2008-03-10,121.98,123.46,119.37,119.69,35699600,119.69 +2008-03-07,120.41,122.98,119.05,122.25,43945100,122.25 +2008-03-06,124.61,127.50,120.81,120.93,52632100,120.93 +2008-03-05,123.58,125.14,122.25,124.49,43637000,124.49 +2008-03-04,121.99,124.88,120.40,124.62,63763700,124.62 +2008-03-03,124.44,125.98,118.00,121.73,56894400,121.73 +2008-02-29,129.29,130.21,124.80,125.02,44838600,125.02 +2008-02-28,127.20,132.20,125.77,129.91,57794800,129.91 +2008-02-27,118.23,123.05,118.09,122.96,52683500,122.96 +2008-02-26,117.64,121.09,115.44,119.15,53746000,119.15 +2008-02-25,118.59,120.17,116.66,119.74,44884800,119.74 +2008-02-22,122.48,122.51,115.87,119.46,54638500,119.46 +2008-02-21,126.05,126.47,120.86,121.54,33504100,121.54 +2008-02-20,122.20,124.60,121.68,123.82,34551400,123.82 +2008-02-19,125.99,126.75,121.44,122.18,35894500,122.18 +2008-02-15,126.27,127.08,124.06,124.63,32189300,124.63 +2008-02-14,129.40,130.80,127.01,127.46,34074900,127.46 +2008-02-13,126.68,129.78,125.63,129.40,34590500,129.40 +2008-02-12,130.70,131.00,123.62,124.86,43785000,124.86 +2008-02-11,128.01,129.98,127.20,129.45,42908300,129.45 +2008-02-08,122.08,125.70,121.60,125.48,48427600,125.48 +2008-02-07,119.97,124.78,117.27,121.24,74404700,121.24 +2008-02-06,130.83,131.92,121.77,122.00,56188300,122.00 +2008-02-05,130.43,134.00,128.90,129.36,40751500,129.36 +2008-02-04,134.21,135.90,131.42,131.65,32115500,131.65 +2008-02-01,136.24,136.59,132.18,133.75,36098000,133.75 +2008-01-31,129.45,136.65,129.40,135.36,48059800,135.36 +2008-01-30,131.37,135.45,130.00,132.18,44394700,132.18 +2008-01-29,131.15,132.79,129.05,131.54,39285100,131.54 +2008-01-28,128.16,133.20,126.45,130.01,52673000,130.01 +2008-01-25,138.99,139.09,129.61,130.01,55526400,130.01 +2008-01-24,139.99,140.70,132.01,135.60,71638100,135.60 +2008-01-23,136.19,140.00,126.14,139.07,120463200,139.07 +2008-01-22,148.06,159.98,146.00,155.64,86955500,155.64 +2008-01-18,161.71,165.75,159.61,161.36,61583700,161.36 +2008-01-17,161.51,165.36,158.42,160.89,62780700,160.89 +2008-01-16,165.23,169.01,156.70,159.64,79065900,159.64 +2008-01-15,177.72,179.22,164.66,169.04,83688500,169.04 +2008-01-14,177.52,179.42,175.17,178.78,39301800,178.78 +2008-01-11,176.00,177.85,170.00,172.69,44010200,172.69 +2008-01-10,177.58,181.00,175.41,178.02,52963400,178.02 +2008-01-09,171.30,179.50,168.30,179.40,64781500,179.40 +2008-01-08,180.14,182.46,170.80,171.25,54422000,171.25 +2008-01-07,181.25,183.60,170.23,177.64,74006900,177.64 +2008-01-04,191.45,193.00,178.89,180.05,51994000,180.05 +2008-01-03,195.41,197.39,192.69,194.93,30073800,194.93 +2008-01-02,199.27,200.26,192.55,194.84,38542100,194.84 +2007-12-31,199.50,200.50,197.75,198.08,19261900,198.08 +2007-12-28,200.59,201.56,196.88,199.83,24987400,199.83 +2007-12-27,198.95,202.96,197.80,198.57,28411700,198.57 +2007-12-26,199.01,200.96,196.82,198.95,25133300,198.95 +2007-12-24,195.03,199.33,194.79,198.80,17150100,198.80 +2007-12-21,190.12,193.91,189.89,193.91,35498600,193.91 +2007-12-20,185.43,187.83,183.33,187.21,27644900,187.21 +2007-12-19,182.98,184.64,180.90,183.12,29552800,183.12 +2007-12-18,186.52,187.33,178.60,182.98,43664400,182.98 +2007-12-17,190.72,192.65,182.98,184.40,36596200,184.40 +2007-12-14,190.37,193.20,189.54,190.39,24082600,190.39 +2007-12-13,190.19,192.12,187.82,191.83,30879200,191.83 +2007-12-12,193.44,194.48,185.76,190.86,43773600,190.86 +2007-12-11,194.75,196.83,187.39,188.54,39675900,188.54 +2007-12-10,193.59,195.66,192.69,194.21,25799200,194.21 +2007-12-07,190.54,194.99,188.04,194.30,38073800,194.30 +2007-12-06,186.19,190.10,186.12,189.95,32136100,189.95 +2007-12-05,182.89,186.00,182.41,185.50,31871500,185.50 +2007-12-04,177.15,180.90,176.99,179.81,27635700,179.81 +2007-12-03,181.86,184.14,177.70,178.86,34338200,178.86 +2007-11-30,187.34,187.70,179.70,182.22,42421500,182.22 +2007-11-29,179.43,185.17,179.15,184.29,37533100,184.29 +2007-11-28,176.82,180.60,175.35,180.22,41104000,180.22 +2007-11-27,175.22,175.79,170.01,174.81,47036800,174.81 +2007-11-26,173.59,177.27,172.35,172.54,46634100,172.54 +2007-11-23,172.00,172.05,169.75,171.54,16634200,171.54 +2007-11-21,165.84,172.35,164.67,168.46,43493200,168.46 +2007-11-20,165.67,171.79,163.53,168.85,55130100,168.85 +2007-11-19,166.10,168.20,162.10,163.95,41196800,163.95 +2007-11-16,165.30,167.02,159.33,166.39,49391300,166.39 +2007-11-15,166.39,169.59,160.30,164.30,53095600,164.30 +2007-11-14,177.16,177.57,163.74,166.11,51695400,166.11 +2007-11-13,160.85,170.98,153.76,169.96,62034100,169.96 +2007-11-12,165.28,167.70,150.63,153.76,63057700,153.76 +2007-11-09,171.15,175.12,165.21,165.37,54458700,165.37 +2007-11-08,186.67,186.90,167.77,175.47,67458500,175.47 +2007-11-07,190.61,192.68,186.13,186.30,35473400,186.30 +2007-11-06,187.05,192.00,185.27,191.79,34097400,191.79 +2007-11-05,185.29,188.96,184.24,186.18,28720600,186.18 +2007-11-02,189.21,189.44,183.49,187.87,35789800,187.87 +2007-11-01,188.60,190.10,180.00,187.44,28751300,187.44 +2007-10-31,187.63,190.12,184.95,189.95,29761100,189.95 +2007-10-30,186.18,189.37,184.73,187.00,33550500,187.00 +2007-10-29,185.45,186.59,184.70,185.09,19305500,185.09 +2007-10-26,185.29,185.37,182.88,184.70,25219800,184.70 +2007-10-25,184.87,185.90,181.66,182.78,34771500,182.78 +2007-10-24,185.81,187.21,179.24,185.93,46017200,185.93 +2007-10-23,188.56,188.60,182.76,186.16,64113000,186.16 +2007-10-22,170.35,174.90,169.96,174.36,58910700,174.36 +2007-10-19,174.24,174.63,170.00,170.42,46135000,170.42 +2007-10-18,171.50,174.19,171.05,173.50,29417000,173.50 +2007-10-17,172.69,173.04,169.18,172.75,40271900,172.75 +2007-10-16,165.54,170.18,165.15,169.58,38136800,169.58 +2007-10-15,167.98,169.57,163.50,166.98,38497500,166.98 +2007-10-12,163.01,167.28,161.80,167.25,35292000,167.25 +2007-10-11,169.49,171.88,153.21,162.23,58714000,162.23 +2007-10-10,167.55,167.88,165.60,166.79,23842500,166.79 +2007-10-09,170.20,171.11,166.68,167.86,39438800,167.86 +2007-10-08,163.49,167.91,162.97,167.91,29854600,167.91 +2007-10-05,158.37,161.58,157.70,161.45,33695400,161.45 +2007-10-04,158.00,158.08,153.50,156.24,23462800,156.24 +2007-10-03,157.78,159.18,157.01,157.92,24732800,157.92 +2007-10-02,156.55,158.59,155.89,158.45,28288200,158.45 +2007-10-01,154.63,157.41,152.93,156.34,29895300,156.34 +2007-09-28,153.44,154.60,152.75,153.47,21967900,153.47 +2007-09-27,153.77,154.52,152.32,154.50,23507100,154.50 +2007-09-26,154.47,155.00,151.25,152.77,34831000,152.77 +2007-09-25,146.84,153.22,146.82,153.18,42591100,153.18 +2007-09-24,146.73,149.85,146.65,148.28,37577200,148.28 +2007-09-21,141.14,144.65,140.31,144.15,40674300,144.15 +2007-09-20,140.15,141.79,139.32,140.31,24708600,140.31 +2007-09-19,143.02,143.16,139.40,140.77,36674300,140.77 +2007-09-18,139.06,142.85,137.83,140.92,38003200,140.92 +2007-09-17,138.99,140.59,137.60,138.41,28334700,138.41 +2007-09-14,136.57,138.98,136.20,138.81,21690000,138.81 +2007-09-13,138.83,139.00,136.65,137.20,23434400,137.20 +2007-09-12,135.99,139.40,135.75,136.85,36527500,136.85 +2007-09-11,137.90,138.30,133.75,135.49,34710200,135.49 +2007-09-10,136.99,138.04,133.95,136.71,53137100,136.71 +2007-09-07,132.01,132.30,130.00,131.77,51092000,131.77 +2007-09-06,135.56,137.57,132.71,135.01,67902200,135.01 +2007-09-05,144.97,145.84,136.10,136.76,83150800,136.76 +2007-09-04,139.94,145.73,139.84,144.16,47030100,144.16 +2007-08-31,139.49,139.65,137.41,138.48,31317400,138.48 +2007-08-30,132.67,138.25,132.30,136.25,51270800,136.25 +2007-08-29,129.88,134.18,129.54,134.08,41673600,134.08 +2007-08-28,130.99,132.41,126.63,126.82,42120200,126.82 +2007-08-27,133.39,134.66,132.10,132.25,25265700,132.25 +2007-08-24,130.53,135.37,129.81,135.30,32565500,135.30 +2007-08-23,133.09,133.34,129.76,131.07,30958500,131.07 +2007-08-22,131.22,132.75,130.33,132.51,37920200,132.51 +2007-08-21,122.21,128.96,121.00,127.57,46537400,127.57 +2007-08-20,123.96,124.50,120.50,122.22,28689900,122.22 +2007-08-17,122.01,123.50,119.82,122.06,42680800,122.06 +2007-08-16,117.01,118.50,111.62,117.05,66667500,117.05 +2007-08-15,122.74,124.86,119.65,119.90,35459000,119.90 +2007-08-14,128.29,128.30,123.71,124.03,26393100,124.03 +2007-08-13,128.32,129.35,126.50,127.79,26889700,127.79 +2007-08-10,123.12,127.75,120.30,125.00,50383900,125.00 +2007-08-09,131.11,133.00,125.09,126.39,40192700,126.39 +2007-08-08,136.76,136.86,132.00,134.01,28860600,134.01 +2007-08-07,134.94,137.24,132.63,135.03,33926300,135.03 +2007-08-06,132.90,135.27,128.30,135.25,33041800,135.25 +2007-08-03,135.26,135.95,131.50,131.85,24256700,131.85 +2007-08-02,136.65,136.96,134.15,136.49,30451600,136.49 +2007-08-01,133.64,135.38,127.77,135.00,62505600,135.00 +2007-07-31,142.97,143.48,131.52,131.76,62942600,131.76 +2007-07-30,144.33,145.45,139.57,141.43,39535300,141.43 +2007-07-27,146.19,148.92,143.78,143.85,41467800,143.85 +2007-07-26,145.91,148.50,136.96,146.00,78093900,146.00 +2007-07-25,137.35,138.36,135.00,137.26,53435100,137.26 +2007-07-24,138.88,141.00,134.15,134.89,64117600,134.89 +2007-07-23,143.31,145.22,140.93,143.70,37017500,143.70 +2007-07-20,141.65,144.18,140.00,143.75,41706200,143.75 +2007-07-19,140.30,140.81,139.65,140.00,26174700,140.00 +2007-07-18,138.19,138.44,136.04,138.12,27030600,138.12 +2007-07-17,138.30,139.60,137.50,138.91,25355700,138.91 +2007-07-16,138.39,139.98,137.50,138.10,33432600,138.10 +2007-07-13,135.03,137.85,134.52,137.73,32414500,137.73 +2007-07-12,133.85,134.24,132.39,134.07,25164600,134.07 +2007-07-11,132.07,133.70,131.31,132.39,29349000,132.39 +2007-07-10,128.88,134.50,128.81,132.35,44821700,132.35 +2007-07-09,132.38,132.90,129.18,130.33,35565000,130.33 +2007-07-06,133.13,133.34,130.40,132.30,31239100,132.30 +2007-07-05,128.80,132.97,128.69,132.75,51894700,132.75 +2007-07-03,122.00,127.40,121.50,127.17,41517200,127.17 +2007-07-02,121.05,122.09,119.30,121.26,35530800,121.26 +2007-06-29,121.97,124.00,121.09,122.04,40637200,122.04 +2007-06-28,122.36,122.49,120.00,120.56,29933700,120.56 +2007-06-27,120.61,122.04,119.26,121.89,34810600,121.89 +2007-06-26,123.98,124.00,118.72,119.65,48035900,119.65 +2007-06-25,124.19,125.09,121.06,122.34,34478700,122.34 +2007-06-22,123.85,124.45,122.38,123.00,22567000,123.00 +2007-06-21,121.70,124.29,120.72,123.90,30965900,123.90 +2007-06-20,123.87,124.66,121.50,121.55,32054000,121.55 +2007-06-19,124.69,125.01,122.91,123.66,33679500,123.66 +2007-06-18,123.28,125.18,122.54,125.09,32521600,125.09 +2007-06-15,120.62,120.67,119.86,120.50,28972100,120.50 +2007-06-14,117.20,119.45,116.42,118.75,34759500,118.75 +2007-06-13,121.15,121.19,115.40,117.50,61476900,117.50 +2007-06-12,119.35,121.71,118.31,120.38,50948800,120.38 +2007-06-11,126.00,126.15,119.54,120.19,66937800,120.19 +2007-06-08,125.82,125.83,122.29,124.49,44345800,124.49 +2007-06-07,124.99,127.61,123.19,124.07,68395700,124.07 +2007-06-06,122.30,124.05,121.95,123.64,39722900,123.64 +2007-06-05,121.41,122.69,120.50,122.67,32885200,122.67 +2007-06-04,118.63,121.73,117.90,121.33,31666900,121.33 +2007-06-01,121.10,121.19,118.29,118.40,31616500,118.40 +2007-05-31,120.07,122.17,119.54,121.19,46323800,121.19 +2007-05-30,114.30,118.88,113.53,118.77,52801600,118.77 +2007-05-29,114.45,114.86,112.69,114.35,23060500,114.35 +2007-05-25,112.00,113.78,111.50,113.62,22605700,113.62 +2007-05-24,112.81,114.46,110.37,110.69,31691500,110.69 +2007-05-23,114.02,115.00,112.59,112.89,32549100,112.89 +2007-05-22,112.49,113.75,112.01,113.54,20443200,113.54 +2007-05-21,110.31,112.45,110.05,111.98,22853300,111.98 +2007-05-18,110.23,110.64,109.77,110.02,22190900,110.02 +2007-05-17,107.15,109.87,107.15,109.44,26260400,109.44 +2007-05-16,108.53,108.83,103.42,107.34,40241700,107.34 +2007-05-15,109.57,110.20,106.48,107.52,34089800,107.52 +2007-05-14,109.62,110.00,108.25,109.36,23283800,109.36 +2007-05-11,107.74,109.13,106.78,108.74,23346300,108.74 +2007-05-10,106.63,108.84,105.92,107.34,42759200,107.34 +2007-05-09,104.91,106.96,104.89,106.88,25634200,106.88 +2007-05-08,103.47,105.15,103.42,105.06,27999900,105.06 +2007-05-07,101.08,104.35,101.01,103.92,30769900,103.92 +2007-05-04,100.80,101.60,100.50,100.81,13642400,100.81 +2007-05-03,100.73,101.45,100.01,100.40,20574200,100.40 +2007-05-02,99.65,100.54,99.47,100.39,18040900,100.39 +2007-05-01,99.59,100.35,98.55,99.47,19018700,99.47 +2007-04-30,100.09,101.00,99.67,99.80,22018200,99.80 +2007-04-27,98.18,99.95,97.69,99.92,24978700,99.92 +2007-04-26,101.58,102.50,98.30,98.84,62063500,98.84 +2007-04-25,94.23,95.40,93.80,95.35,42398000,95.35 +2007-04-24,93.96,96.39,91.30,93.24,37687600,93.24 +2007-04-23,91.59,93.80,91.42,93.51,27867500,93.51 +2007-04-20,90.89,91.18,90.55,90.97,18670700,90.97 +2007-04-19,90.19,91.25,89.83,90.27,15211200,90.27 +2007-04-18,90.16,90.85,89.60,90.40,16573000,90.40 +2007-04-17,92.00,92.30,89.70,90.35,26854300,90.35 +2007-04-16,90.57,91.50,90.25,91.43,21751200,91.43 +2007-04-13,90.90,91.40,90.06,90.24,25712200,90.24 +2007-04-12,92.04,92.31,90.72,92.19,23452700,92.19 +2007-04-11,93.90,93.95,92.33,92.59,19607800,92.59 +2007-04-10,93.67,94.26,93.41,94.25,12588100,94.25 +2007-04-09,95.21,95.30,93.04,93.65,14762200,93.65 +2007-04-05,94.12,94.68,93.52,94.68,12697000,94.68 +2007-04-04,94.94,95.14,94.13,94.27,17028000,94.27 +2007-04-03,94.14,95.23,93.76,94.50,20854800,94.50 +2007-04-02,94.14,94.25,93.02,93.65,17928300,93.65 +2007-03-30,94.28,94.68,92.75,92.91,21448500,92.91 +2007-03-29,94.19,94.19,92.23,93.75,25918700,93.75 +2007-03-28,94.88,95.40,93.15,93.24,33654900,93.24 +2007-03-27,95.71,96.83,95.00,95.46,33287600,95.46 +2007-03-26,93.99,95.90,93.30,95.85,30892400,95.85 +2007-03-23,93.35,94.07,93.30,93.52,16103000,93.52 +2007-03-22,93.73,94.36,93.00,93.96,20053300,93.96 +2007-03-21,91.99,94.00,91.65,93.87,24532000,93.87 +2007-03-20,91.35,91.84,91.06,91.48,17461300,91.48 +2007-03-19,90.24,91.55,89.59,91.13,25462900,91.13 +2007-03-16,89.54,89.99,89.32,89.59,20418000,89.59 +2007-03-15,89.96,90.36,89.31,89.57,19982100,89.57 +2007-03-14,88.60,90.00,87.92,90.00,28449500,90.00 +2007-03-13,89.41,90.60,88.40,88.40,30996100,88.40 +2007-03-12,88.07,89.99,87.99,89.87,26050300,89.87 +2007-03-09,88.80,88.85,87.40,87.97,16137000,87.97 +2007-03-08,88.59,88.72,87.46,88.00,18250400,88.00 +2007-03-07,88.05,88.97,87.45,87.72,22367300,87.72 +2007-03-06,87.80,88.31,87.40,88.19,25828100,88.19 +2007-03-05,85.89,88.65,85.76,86.32,29960700,86.32 +2007-03-02,86.77,87.54,85.21,85.41,30714300,85.41 +2007-03-01,84.03,88.31,83.75,87.06,50554600,87.06 +2007-02-28,83.00,85.60,83.00,84.61,32838400,84.61 +2007-02-27,86.30,87.08,83.41,83.93,40921900,83.93 +2007-02-26,89.84,90.00,87.61,88.51,21994600,88.51 +2007-02-23,89.16,90.34,88.85,89.07,18496200,89.07 +2007-02-22,90.80,90.81,88.53,89.51,29936600,89.51 +2007-02-21,85.98,89.49,85.96,89.20,41261200,89.20 +2007-02-20,84.65,86.16,84.16,85.90,22060800,85.90 +2007-02-16,85.25,85.41,84.66,84.83,14281000,84.83 +2007-02-15,85.44,85.62,84.78,85.21,12987900,85.21 +2007-02-14,84.63,85.64,84.57,85.30,18142200,85.30 +2007-02-13,85.16,85.29,84.30,84.70,20749500,84.70 +2007-02-12,84.43,85.18,83.63,84.88,25859700,84.88 +2007-02-09,85.88,86.20,83.21,83.27,30733600,83.27 +2007-02-08,85.43,86.51,85.41,86.18,24251100,86.18 +2007-02-07,84.48,86.38,83.55,86.15,38100900,86.15 +2007-02-06,84.45,84.47,82.86,84.15,30871200,84.15 +2007-02-05,84.30,85.23,83.94,83.94,20673300,83.94 +2007-02-02,84.12,85.25,83.70,84.75,22197500,84.75 +2007-02-01,86.23,86.27,84.74,84.74,23726500,84.74 +2007-01-31,84.86,86.00,84.35,85.73,30573900,85.73 +2007-01-30,86.43,86.49,85.25,85.55,20641800,85.55 +2007-01-29,86.30,86.65,85.53,85.94,32202300,85.94 +2007-01-26,87.11,87.37,84.99,85.38,35245500,85.38 +2007-01-25,87.11,88.50,86.03,86.25,32356200,86.25 +2007-01-24,86.68,87.15,86.08,86.70,33136200,86.70 +2007-01-23,85.73,87.51,85.51,85.70,43122300,85.70 +2007-01-22,89.14,89.16,85.65,86.79,51929500,86.79 +2007-01-19,88.63,89.65,88.12,88.50,48731200,88.50 +2007-01-18,92.10,92.11,89.05,89.07,84450200,89.07 +2007-01-17,97.56,97.60,94.82,94.95,58795000,94.95 +2007-01-16,95.68,97.25,95.45,97.10,44431300,97.10 +2007-01-12,94.59,95.06,93.23,94.62,46881800,94.62 +2007-01-11,95.94,96.78,95.10,95.80,51437600,95.80 +2007-01-10,94.75,97.80,93.45,97.00,105460000,97.00 +2007-01-09,86.45,92.98,85.15,92.57,119617800,92.57 +2007-01-08,85.96,86.53,85.28,85.47,28468100,85.47 +2007-01-05,85.77,86.20,84.40,85.05,29812200,85.05 +2007-01-04,84.05,85.95,83.82,85.66,30259300,85.66 +2007-01-03,86.29,86.58,81.90,83.80,44225700,83.80 +2006-12-29,83.95,85.40,83.36,84.84,38443900,84.84 +2006-12-28,80.22,81.25,79.65,80.87,39995600,80.87 +2006-12-27,78.15,82.00,76.77,81.52,69134100,81.52 +2006-12-26,82.15,82.57,80.89,81.51,17524600,81.51 +2006-12-22,83.46,84.04,81.60,82.20,21903700,82.20 +2006-12-21,84.70,85.48,82.20,82.90,32271400,82.90 +2006-12-20,86.47,86.67,84.74,84.76,20274700,84.76 +2006-12-19,84.73,86.68,83.62,86.31,32550200,86.31 +2006-12-18,87.63,88.00,84.59,85.47,25770600,85.47 +2006-12-15,89.02,89.22,87.33,87.72,26426400,87.72 +2006-12-14,89.05,90.00,88.26,88.55,29726100,88.55 +2006-12-13,87.95,89.07,87.15,89.05,30609000,89.05 +2006-12-12,88.61,88.84,85.53,86.14,36665000,86.14 +2006-12-11,88.90,89.30,88.05,88.75,17849300,88.75 +2006-12-08,87.23,89.39,87.00,88.26,28009900,88.26 +2006-12-07,90.03,90.50,86.90,87.04,35886700,87.04 +2006-12-06,90.64,91.39,89.67,89.83,22792300,89.83 +2006-12-05,91.65,92.33,90.87,91.27,23672800,91.27 +2006-12-04,91.88,92.05,90.50,91.12,25340600,91.12 +2006-12-01,91.80,92.33,90.10,91.32,28395700,91.32 +2006-11-30,92.21,92.68,91.06,91.66,31088800,91.66 +2006-11-29,93.00,93.15,90.25,91.80,41324400,91.80 +2006-11-28,90.36,91.97,89.91,91.81,37006200,91.81 +2006-11-27,92.51,93.16,89.50,89.54,38387000,89.54 +2006-11-24,89.53,93.08,89.50,91.63,18524200,91.63 +2006-11-22,88.99,90.75,87.85,90.31,23997900,90.31 +2006-11-21,87.42,88.60,87.11,88.60,22238100,88.60 +2006-11-20,85.40,87.00,85.20,86.47,20385500,86.47 +2006-11-17,85.14,85.94,85.00,85.85,16658000,85.85 +2006-11-16,84.87,86.30,84.62,85.61,24783600,85.61 +2006-11-15,85.05,85.90,84.00,84.05,23404400,84.05 +2006-11-14,84.80,85.00,83.90,85.00,21034100,85.00 +2006-11-13,83.22,84.45,82.64,84.35,16095500,84.35 +2006-11-10,83.55,83.60,82.50,83.12,13352300,83.12 +2006-11-09,82.90,84.69,82.12,83.34,32966200,83.34 +2006-11-08,80.02,82.69,79.89,82.45,24675600,82.45 +2006-11-07,80.45,81.00,80.13,80.51,18783300,80.51 +2006-11-06,78.95,80.06,78.43,79.71,15520600,79.71 +2006-11-03,79.36,79.53,77.79,78.29,15424600,78.29 +2006-11-02,78.92,79.32,78.50,78.98,16624400,78.98 +2006-11-01,81.10,81.38,78.36,79.16,21828300,79.16 +2006-10-31,81.45,81.68,80.23,81.08,17909800,81.08 +2006-10-30,79.99,80.90,79.50,80.42,17854200,80.42 +2006-10-27,81.75,82.45,80.01,80.41,21248800,80.41 +2006-10-26,81.90,82.60,81.13,82.19,15455600,82.19 +2006-10-25,81.35,82.00,81.01,81.68,17329100,81.68 +2006-10-24,81.21,81.68,80.20,81.05,16543300,81.05 +2006-10-23,79.99,81.90,79.75,81.46,29732400,81.46 +2006-10-20,78.97,79.99,78.67,79.95,22836200,79.95 +2006-10-19,79.26,79.95,78.16,78.99,54034900,78.99 +2006-10-18,74.75,75.37,73.91,74.53,40496700,74.53 +2006-10-17,75.04,75.27,74.04,74.29,17175900,74.29 +2006-10-16,75.19,75.88,74.79,75.40,18167600,75.40 +2006-10-13,75.63,76.88,74.74,75.02,24435600,75.02 +2006-10-12,73.61,75.39,73.60,75.26,21173400,75.26 +2006-10-11,73.42,73.98,72.60,73.23,20423400,73.23 +2006-10-10,74.54,74.58,73.08,73.81,18985300,73.81 +2006-10-09,73.80,75.08,73.53,74.63,15650800,74.63 +2006-10-06,74.42,75.04,73.81,74.22,16677100,74.22 +2006-10-05,74.53,76.16,74.13,74.83,24424400,74.83 +2006-10-04,74.10,75.46,73.16,75.38,29610100,75.38 +2006-10-03,74.45,74.95,73.19,74.08,28239600,74.08 +2006-10-02,75.10,75.87,74.30,74.86,25451400,74.86 +2006-09-29,77.11,77.52,76.68,76.98,14493300,76.98 +2006-09-28,77.02,77.48,75.95,77.01,25843200,77.01 +2006-09-27,77.17,77.47,75.82,76.41,28941900,76.41 +2006-09-26,76.18,77.78,76.10,77.61,39391000,77.61 +2006-09-25,73.81,75.86,73.72,75.75,30678300,75.75 +2006-09-22,74.30,74.34,72.58,73.00,23754000,73.00 +2006-09-21,75.25,76.06,74.02,74.65,28361600,74.65 +2006-09-20,74.38,75.68,74.22,75.26,29385400,75.26 +2006-09-19,74.10,74.36,72.80,73.77,25358900,73.77 +2006-09-18,73.80,74.86,73.30,73.89,25188500,73.89 +2006-09-15,74.60,74.98,73.29,74.10,35066200,74.10 +2006-09-14,73.72,74.67,73.46,74.17,28633200,74.17 +2006-09-13,72.85,74.32,72.30,74.20,40933500,74.20 +2006-09-12,72.81,73.45,71.45,72.63,60167400,72.63 +2006-09-11,72.43,73.73,71.42,72.50,33897300,72.50 +2006-09-08,73.37,73.57,71.91,72.52,31997200,72.52 +2006-09-07,70.60,73.48,70.25,72.80,45284200,72.80 +2006-09-06,71.08,71.69,69.70,70.03,34789400,70.03 +2006-09-05,68.97,71.50,68.55,71.48,36159200,71.48 +2006-09-01,68.48,68.65,67.82,68.38,14589100,68.38 +2006-08-31,67.28,68.30,66.66,67.85,20524900,67.85 +2006-08-30,67.34,67.82,66.68,66.96,24290800,66.96 +2006-08-29,66.99,67.26,65.12,66.48,33833300,66.48 +2006-08-28,68.50,68.61,66.68,66.98,26362900,66.98 +2006-08-25,67.34,69.05,67.31,68.75,19427100,68.75 +2006-08-24,67.89,68.19,66.27,67.81,23399700,67.81 +2006-08-23,68.00,68.65,66.94,67.31,19152100,67.31 +2006-08-22,66.68,68.32,66.50,67.62,20606000,67.62 +2006-08-21,67.30,67.31,66.15,66.56,18793800,66.56 +2006-08-18,67.71,68.40,67.26,67.91,19155500,67.91 +2006-08-17,68.00,68.66,67.18,67.59,20755300,67.59 +2006-08-16,67.10,68.07,66.33,67.98,27903000,67.98 +2006-08-15,65.34,66.50,64.80,66.45,30762600,66.45 +2006-08-14,64.05,65.22,63.60,63.94,25629300,63.94 +2006-08-11,63.23,64.13,62.58,63.65,27768900,63.65 +2006-08-10,63.25,64.81,62.70,64.07,24920000,64.07 +2006-08-09,65.43,65.60,63.40,63.59,34137100,63.59 +2006-08-08,67.09,67.11,64.51,64.78,35638000,64.78 +2006-08-07,67.72,69.60,66.31,67.21,44482600,67.21 +2006-08-04,67.05,68.61,64.96,68.30,66173800,68.30 +2006-08-03,67.91,70.00,67.81,69.59,30037300,69.59 +2006-08-02,67.65,68.68,67.51,68.16,19670300,68.16 +2006-08-01,67.22,67.93,65.94,67.18,25420200,67.18 +2006-07-31,66.83,68.63,66.28,67.96,31887200,67.96 +2006-07-28,63.94,65.68,63.50,65.59,24696700,65.59 +2006-07-27,64.50,65.02,62.86,63.40,26251600,63.40 +2006-07-26,62.00,64.64,61.68,63.87,32086700,63.87 +2006-07-25,61.78,62.09,60.78,61.93,21038200,61.93 +2006-07-24,61.26,62.10,60.43,61.42,25816300,61.42 +2006-07-21,59.82,61.15,59.64,60.72,31853300,60.72 +2006-07-20,60.96,61.59,59.72,60.50,70433800,60.50 +2006-07-19,52.96,55.08,52.36,54.10,49669400,54.10 +2006-07-18,53.16,53.85,51.85,52.90,35730300,52.90 +2006-07-17,51.73,53.11,51.65,52.37,36590800,52.37 +2006-07-14,52.50,52.89,50.16,50.67,35465600,50.67 +2006-07-13,52.03,54.12,51.41,52.25,44639500,52.25 +2006-07-12,55.17,55.24,52.92,52.96,33118900,52.96 +2006-07-11,55.11,55.99,54.53,55.65,29465100,55.65 +2006-07-10,55.70,56.49,54.50,55.00,18905200,55.00 +2006-07-07,55.48,56.55,54.67,55.40,28548600,55.40 +2006-07-06,57.09,57.40,55.61,55.77,22614600,55.77 +2006-07-05,57.15,57.60,56.56,57.00,18508600,57.00 +2006-07-03,57.52,58.18,57.34,57.95,6956100,57.95 +2006-06-30,57.59,57.75,56.50,57.27,26417700,57.27 +2006-06-29,56.76,59.09,56.39,58.97,31192800,58.97 +2006-06-28,57.29,57.30,55.41,56.02,30382300,56.02 +2006-06-27,59.09,59.22,57.40,57.43,19664700,57.43 +2006-06-26,59.17,59.20,58.37,58.99,16662000,58.99 +2006-06-23,59.72,60.17,58.73,58.83,23578700,58.83 +2006-06-22,58.20,59.75,58.07,59.58,34486900,59.58 +2006-06-21,57.74,58.71,57.30,57.86,30832000,57.86 +2006-06-20,57.61,58.35,57.29,57.47,24034800,57.47 +2006-06-19,57.83,58.18,57.00,57.20,25163400,57.20 +2006-06-16,58.96,59.19,57.52,57.56,29932200,57.56 +2006-06-15,57.30,59.74,56.75,59.38,42513700,59.38 +2006-06-14,58.28,58.78,56.69,57.61,31362000,57.61 +2006-06-13,57.61,59.10,57.36,58.33,38594400,58.33 +2006-06-12,59.40,59.73,56.96,57.00,25635200,57.00 +2006-06-09,61.18,61.56,59.10,59.24,27708500,59.24 +2006-06-08,58.44,60.93,57.15,60.76,49910100,60.76 +2006-06-07,60.10,60.40,58.35,58.56,26803800,58.56 +2006-06-06,60.22,60.63,58.91,59.72,25929900,59.72 +2006-06-05,61.15,61.15,59.97,60.00,21635200,60.00 +2006-06-02,62.99,63.10,60.88,61.66,24492400,61.66 +2006-06-01,59.85,62.28,59.52,62.17,33661000,62.17 +2006-05-31,61.76,61.79,58.69,59.77,45749200,59.77 +2006-05-30,63.29,63.30,61.22,61.22,20121500,61.22 +2006-05-26,64.31,64.56,63.14,63.55,15462500,63.55 +2006-05-25,64.26,64.45,63.29,64.33,16549000,64.33 +2006-05-24,62.99,63.65,61.56,63.34,32715400,63.34 +2006-05-23,64.86,65.19,63.00,63.15,24800500,63.15 +2006-05-22,63.87,63.99,62.77,63.38,25677700,63.38 +2006-05-19,63.26,64.88,62.82,64.51,35209500,64.51 +2006-05-18,65.68,66.26,63.12,63.18,23515800,63.18 +2006-05-17,64.71,65.70,64.07,65.26,26935500,65.26 +2006-05-16,68.10,68.25,64.75,64.98,33455000,64.98 +2006-05-15,67.37,68.38,67.12,67.79,18899200,67.79 +2006-05-12,67.85,68.69,66.86,67.70,22920500,67.70 +2006-05-11,70.79,70.84,67.55,68.15,29024600,68.15 +2006-05-10,71.29,71.33,69.61,70.60,16424600,70.60 +2006-05-09,71.82,72.56,70.62,71.03,18988100,71.03 +2006-05-08,72.99,73.80,71.72,71.89,21244700,71.89 +2006-05-05,71.86,72.25,71.15,71.89,20139700,71.89 +2006-05-04,71.22,72.89,70.46,71.13,30729300,71.13 +2006-05-03,71.83,71.95,70.18,71.14,24535400,71.14 +2006-05-02,70.15,71.98,70.11,71.62,27559400,71.62 +2006-05-01,70.77,71.54,69.16,69.60,26799300,69.60 +2006-04-28,69.38,71.30,69.20,70.39,27144200,70.39 +2006-04-27,67.73,69.86,67.35,69.36,30212400,69.36 +2006-04-26,66.65,68.28,66.40,68.15,25388800,68.15 +2006-04-25,65.96,66.59,65.56,66.17,18895100,66.17 +2006-04-24,66.85,66.92,65.50,65.75,25251000,65.75 +2006-04-21,68.19,68.64,66.47,67.04,28178100,67.04 +2006-04-20,69.51,70.00,66.20,67.63,59535100,67.63 +2006-04-19,66.82,67.00,65.47,65.65,38786900,65.65 +2006-04-18,65.04,66.47,64.79,66.22,28387300,66.22 +2006-04-17,66.51,66.84,64.35,64.81,25783500,64.81 +2006-04-13,66.34,67.44,65.81,66.47,26238500,66.47 +2006-04-12,68.01,68.17,66.30,66.71,26424800,66.71 +2006-04-11,68.99,69.30,67.07,67.99,33547000,67.99 +2006-04-10,70.29,70.93,68.45,68.67,32268400,68.67 +2006-04-07,70.93,71.21,68.47,69.79,55187100,69.79 +2006-04-06,68.30,72.05,68.20,71.24,95134600,71.24 +2006-04-05,64.71,67.21,64.15,67.21,79764600,67.21 +2006-04-04,62.10,62.22,61.05,61.17,33283000,61.17 +2006-04-03,63.67,64.12,62.61,62.65,29135400,62.65 +2006-03-31,63.25,63.61,62.24,62.72,29119900,62.72 +2006-03-30,62.82,63.30,61.53,62.75,49666100,62.75 +2006-03-29,59.13,62.52,57.67,62.33,83815500,62.33 +2006-03-28,59.63,60.14,58.25,58.71,48940100,58.71 +2006-03-27,60.35,61.38,59.40,59.51,39574000,59.51 +2006-03-24,60.25,60.94,59.03,59.96,38285000,59.96 +2006-03-23,61.82,61.90,59.61,60.16,50993800,60.16 +2006-03-22,62.16,63.25,61.27,61.67,48067700,61.67 +2006-03-21,64.29,64.34,61.39,61.81,47991700,61.81 +2006-03-20,65.22,65.46,63.87,63.99,21622900,63.99 +2006-03-17,64.75,65.54,64.11,64.66,29001500,64.66 +2006-03-16,66.85,66.90,64.30,64.31,26772800,64.31 +2006-03-15,67.71,68.04,65.52,66.23,31857000,66.23 +2006-03-14,65.77,67.32,65.50,67.32,22929300,67.32 +2006-03-13,65.05,66.28,64.79,65.68,30756700,65.68 +2006-03-10,64.05,64.49,62.45,63.19,37255100,63.19 +2006-03-09,65.98,66.47,63.81,63.93,28546600,63.93 +2006-03-08,66.29,67.20,65.35,65.66,23330400,65.66 +2006-03-07,65.76,66.90,65.08,66.31,31174200,66.31 +2006-03-06,67.69,67.72,64.94,65.48,32595200,65.48 +2006-03-03,69.40,69.91,67.53,67.72,26345300,67.72 +2006-03-02,68.99,69.99,68.67,69.61,22331200,69.61 +2006-03-01,68.84,69.49,68.02,69.10,27279200,69.10 +2006-02-28,71.58,72.40,68.10,68.49,45249300,68.49 +2006-02-27,71.99,72.12,70.65,70.99,28258600,70.99 +2006-02-24,72.14,72.89,71.20,71.46,19098000,71.46 +2006-02-23,71.79,73.00,71.43,71.75,30604200,71.75 +2006-02-22,69.00,71.67,68.00,71.32,34937100,71.32 +2006-02-21,70.59,70.80,68.68,69.08,27843100,69.08 +2006-02-17,70.30,70.89,69.61,70.29,20571400,70.29 +2006-02-16,69.91,71.01,69.48,70.57,33863400,70.57 +2006-02-15,67.16,69.62,66.75,69.22,41420400,69.22 +2006-02-14,65.10,68.10,65.00,67.64,41462100,67.64 +2006-02-13,66.63,66.75,64.64,64.71,31553500,64.71 +2006-02-10,65.18,67.67,62.90,67.31,62874200,67.31 +2006-02-09,69.10,69.23,64.53,64.95,41063000,64.95 +2006-02-08,68.49,69.08,66.00,68.81,34039800,68.81 +2006-02-07,68.27,69.48,66.68,67.60,49601100,67.60 +2006-02-06,72.02,72.51,66.74,67.30,58991700,67.30 +2006-02-03,72.24,72.79,71.04,71.85,24718700,71.85 +2006-02-02,75.10,75.36,72.05,72.10,25261500,72.10 +2006-02-01,74.95,76.46,74.64,75.42,18613800,75.42 +2006-01-31,75.50,76.34,73.75,75.51,32626500,75.51 +2006-01-30,71.17,76.60,70.87,75.00,49942900,75.00 +2006-01-27,72.95,73.60,71.10,72.03,34066600,72.03 +2006-01-26,74.53,75.43,71.93,72.33,42192400,72.33 +2006-01-25,77.39,77.50,73.25,74.20,45563800,74.20 +2006-01-24,78.76,79.42,75.77,76.04,40794800,76.04 +2006-01-23,76.10,79.56,76.00,77.67,37847500,77.67 +2006-01-20,79.28,80.04,75.83,76.09,40527100,76.09 +2006-01-19,81.25,81.66,78.74,79.04,60566000,79.04 +2006-01-18,83.08,84.05,81.85,82.49,42879900,82.49 +2006-01-17,85.70,86.38,83.87,84.71,29843700,84.71 +2006-01-13,84.99,86.01,84.60,85.59,27725200,85.59 +2006-01-12,84.97,86.40,83.62,84.29,45743200,84.29 +2006-01-11,83.84,84.80,82.59,83.90,53349800,83.90 +2006-01-10,76.25,81.89,75.83,80.86,81423900,80.86 +2006-01-09,76.73,77.20,75.74,76.05,24108600,76.05 +2006-01-06,75.25,76.70,74.55,76.30,25159200,76.30 +2006-01-05,74.83,74.90,73.75,74.38,16050800,74.38 +2006-01-04,75.13,75.98,74.50,74.97,22128700,74.97 +2006-01-03,72.38,74.75,72.25,74.75,28829800,74.75 +2005-12-30,70.91,72.43,70.34,71.89,22295100,71.89 +2005-12-29,73.78,73.82,71.42,71.45,17500900,71.45 +2005-12-28,74.47,74.76,73.32,73.57,14218400,73.57 +2005-12-27,74.00,75.18,73.95,74.23,21092500,74.23 +2005-12-23,74.17,74.26,73.30,73.35,8209200,73.35 +2005-12-22,73.91,74.49,73.60,74.02,13236100,74.02 +2005-12-21,72.60,73.61,72.54,73.50,16990600,73.50 +2005-12-20,71.63,72.38,71.12,72.11,17111000,72.11 +2005-12-19,71.11,72.60,71.04,71.38,18903400,71.38 +2005-12-16,72.14,72.30,71.06,71.11,23970400,71.11 +2005-12-15,72.68,72.86,71.35,72.18,20041500,72.18 +2005-12-14,72.53,73.30,70.27,72.01,51811300,72.01 +2005-12-13,74.85,75.46,74.21,74.98,17636300,74.98 +2005-12-12,74.87,75.35,74.56,74.91,18749800,74.91 +2005-12-09,74.21,74.59,73.35,74.33,19835800,74.33 +2005-12-08,73.20,74.17,72.60,74.08,28231500,74.08 +2005-12-07,74.23,74.46,73.12,73.95,24266600,73.95 +2005-12-06,73.93,74.83,73.35,74.05,30608200,74.05 +2005-12-05,71.95,72.53,71.49,71.82,20845400,71.82 +2005-12-02,72.27,72.74,70.70,72.63,31991500,72.63 +2005-12-01,68.95,71.73,68.81,71.60,29031900,71.60 +2005-11-30,68.43,68.85,67.52,67.82,21274100,67.82 +2005-11-29,69.99,70.30,67.35,68.10,31836900,68.10 +2005-11-28,70.72,71.07,69.07,69.66,36375700,69.66 +2005-11-25,67.66,69.54,67.50,69.34,14107600,69.34 +2005-11-23,66.88,67.98,66.69,67.11,17351900,67.11 +2005-11-22,64.84,66.76,64.52,66.52,19295800,66.52 +2005-11-21,64.82,65.19,63.72,64.96,18275400,64.96 +2005-11-18,65.31,65.43,64.37,64.56,18748700,64.56 +2005-11-17,65.59,65.88,64.25,64.52,24150200,64.52 +2005-11-16,63.15,65.06,63.09,64.95,28018400,64.95 +2005-11-15,61.60,63.08,61.46,62.28,19172900,62.28 +2005-11-14,61.54,61.98,60.91,61.45,13211900,61.45 +2005-11-11,61.54,62.11,61.34,61.54,15194600,61.54 +2005-11-10,60.64,61.20,59.01,61.18,23762300,61.18 +2005-11-09,60.00,61.21,60.00,60.11,19747500,60.11 +2005-11-08,59.95,60.38,59.10,59.90,16920200,59.90 +2005-11-07,60.85,61.67,60.14,60.23,22815400,60.23 +2005-11-04,60.35,61.24,59.62,61.15,31358400,61.15 +2005-11-03,60.26,62.32,60.07,61.85,31585100,61.85 +2005-11-02,57.72,60.00,57.60,59.95,30609300,59.95 +2005-11-01,57.24,58.14,56.87,57.50,26774500,57.50 +2005-10-31,55.20,57.98,54.75,57.59,33601600,57.59 +2005-10-28,56.04,56.43,54.17,54.47,27492400,54.47 +2005-10-27,56.99,57.01,55.41,55.41,14697900,55.41 +2005-10-26,56.28,57.56,55.92,57.03,22556900,57.03 +2005-10-25,56.40,56.85,55.69,56.10,16611700,56.10 +2005-10-24,55.25,56.79,55.09,56.79,21776900,56.79 +2005-10-21,56.84,56.98,55.36,55.66,28454500,55.66 +2005-10-20,54.47,56.50,54.35,56.14,48491500,56.14 +2005-10-19,52.07,54.96,51.21,54.94,36024400,54.94 +2005-10-18,53.25,53.95,52.20,52.21,21771000,52.21 +2005-10-17,53.98,54.23,52.68,53.44,22029800,53.44 +2005-10-14,54.03,54.35,52.79,54.00,36984000,54.00 +2005-10-13,49.44,53.95,49.27,53.74,66627700,53.74 +2005-10-12,48.65,50.30,47.87,49.25,96338800,49.25 +2005-10-11,51.23,51.87,50.40,51.59,43781600,51.59 +2005-10-10,51.76,51.91,50.28,50.37,18125200,50.37 +2005-10-07,51.72,51.93,50.55,51.30,24210100,51.30 +2005-10-06,53.20,53.49,50.87,51.70,27054900,51.70 +2005-10-05,54.33,54.36,52.75,52.78,21813200,52.78 +2005-10-04,54.95,55.35,53.64,53.75,19266400,53.75 +2005-10-03,54.16,54.54,53.68,54.44,18126900,54.44 +2005-09-30,52.33,53.65,51.88,53.61,18986900,53.61 +2005-09-29,51.23,52.59,50.81,52.34,22744500,52.34 +2005-09-28,53.07,53.11,50.59,51.08,40198000,51.08 +2005-09-27,53.92,54.24,53.43,53.44,12203700,53.44 +2005-09-26,54.03,54.56,53.32,53.84,19520100,53.84 +2005-09-23,52.10,53.50,51.84,53.20,19944900,53.20 +2005-09-22,51.88,52.47,51.32,51.90,16561700,51.90 +2005-09-21,52.96,53.05,51.86,52.11,15526700,52.11 +2005-09-20,52.99,53.81,52.92,53.19,29279600,53.19 +2005-09-19,51.05,52.89,51.05,52.64,27990400,52.64 +2005-09-16,50.23,51.21,49.95,51.21,21107300,51.21 +2005-09-15,50.00,50.18,49.33,49.87,14827000,49.87 +2005-09-14,51.06,51.19,49.46,49.61,16943800,49.61 +2005-09-13,51.02,51.29,50.32,50.82,17603000,50.82 +2005-09-12,51.10,51.63,50.58,51.40,16171300,51.40 +2005-09-09,50.07,51.35,49.79,51.31,21987200,51.31 +2005-09-08,49.35,50.12,49.14,49.78,25094300,49.78 +2005-09-07,49.05,49.40,47.92,48.68,34395500,48.68 +2005-09-06,46.70,48.88,46.55,48.80,29236400,48.80 +2005-09-02,46.30,46.80,46.12,46.22,7942100,46.22 +2005-09-01,47.00,47.17,46.09,46.26,12727400,46.26 +2005-08-31,46.86,47.03,46.27,46.89,14391300,46.89 +2005-08-30,45.99,46.79,45.92,46.57,18527200,46.57 +2005-08-29,45.27,46.03,45.26,45.84,9153400,45.84 +2005-08-26,46.12,46.34,45.36,45.74,9323500,45.74 +2005-08-25,46.12,46.49,45.81,46.06,9866200,46.06 +2005-08-24,45.60,47.12,45.59,45.77,20431100,45.77 +2005-08-23,45.85,46.10,45.32,45.74,10557300,45.74 +2005-08-22,46.15,46.75,45.26,45.87,13847600,45.87 +2005-08-19,46.28,46.70,45.77,45.83,13448900,45.83 +2005-08-18,46.91,47.00,45.75,46.30,15805700,46.30 +2005-08-17,46.40,47.44,46.37,47.15,17847300,47.15 +2005-08-16,47.39,47.50,46.21,46.25,19200800,46.25 +2005-08-15,46.48,48.33,46.45,47.68,38811700,47.68 +2005-08-12,43.46,46.22,43.36,46.10,32715600,46.10 +2005-08-11,43.39,44.12,43.25,44.00,9713700,44.00 +2005-08-10,44.00,44.39,43.31,43.38,12890900,43.38 +2005-08-09,42.93,43.89,42.91,43.82,13601400,43.82 +2005-08-08,43.00,43.25,42.61,42.65,6299400,42.65 +2005-08-05,42.49,43.36,42.02,42.99,8640400,42.99 +2005-08-04,42.89,43.00,42.29,42.71,9618000,42.71 +2005-08-03,43.19,43.31,42.77,43.22,9225800,43.22 +2005-08-02,42.89,43.50,42.61,43.19,10602700,43.19 +2005-08-01,42.57,43.08,42.08,42.75,11223200,42.75 +2005-07-29,43.56,44.38,42.26,42.65,20074300,42.65 +2005-07-28,43.85,44.00,43.30,43.80,8975400,43.80 +2005-07-27,43.83,44.07,42.67,43.99,10133900,43.99 +2005-07-26,44.01,44.11,43.36,43.63,9592600,43.63 +2005-07-25,43.99,44.28,43.73,43.81,10522400,43.81 +2005-07-22,43.44,44.00,43.39,44.00,10753800,44.00 +2005-07-21,43.70,44.04,42.90,43.29,14438000,43.29 +2005-07-20,42.86,43.80,42.65,43.63,16192700,43.63 +2005-07-19,41.52,43.23,41.07,43.19,23966500,43.19 +2005-07-18,41.41,42.10,41.37,41.49,20939200,41.49 +2005-07-15,40.97,41.57,40.46,41.55,24560100,41.55 +2005-07-14,40.79,42.01,40.23,40.75,74859300,40.75 +2005-07-13,38.29,38.50,37.90,38.35,24458400,38.35 +2005-07-12,38.23,38.40,37.91,38.24,13822800,38.24 +2005-07-11,38.37,38.65,37.78,38.10,13885300,38.10 +2005-07-08,37.87,38.28,37.47,38.25,10383400,38.25 +2005-07-07,36.81,37.76,36.80,37.63,13704400,37.63 +2005-07-06,37.71,38.16,37.20,37.39,14093800,37.39 +2005-07-05,36.55,38.15,36.50,37.98,16223900,37.98 +2005-07-01,36.83,36.97,36.29,36.50,8928600,36.50 +2005-06-30,36.61,37.16,36.31,36.81,14942500,36.81 +2005-06-29,37.23,37.29,36.12,36.37,16012800,36.37 +2005-06-28,37.49,37.59,37.17,37.31,12510700,37.31 +2005-06-27,36.84,38.10,36.68,37.10,21434700,37.10 +2005-06-24,39.09,39.12,37.68,37.76,14668200,37.76 +2005-06-23,38.83,39.78,38.65,38.89,24080500,38.89 +2005-06-22,38.26,38.60,38.14,38.55,15175900,38.55 +2005-06-21,37.72,38.19,37.38,37.86,13233100,37.86 +2005-06-20,37.85,38.09,37.45,37.61,11561300,37.61 +2005-06-17,38.47,38.54,37.83,38.31,21290200,38.31 +2005-06-16,37.19,38.08,36.82,37.98,19559800,37.98 +2005-06-15,36.87,37.30,36.30,37.13,20119400,37.13 +2005-06-14,35.92,36.15,35.75,36.00,12423100,36.00 +2005-06-13,35.89,36.61,35.82,35.90,15563300,35.90 +2005-06-10,37.40,37.40,35.52,35.81,24247600,35.81 +2005-06-09,37.00,37.94,36.82,37.65,13937700,37.65 +2005-06-08,36.63,37.25,36.57,36.92,14428800,36.92 +2005-06-07,37.60,37.73,36.45,36.54,26616600,36.54 +2005-06-06,38.33,38.63,37.56,37.92,28998800,37.92 +2005-06-03,38.16,38.58,37.77,38.24,34173900,38.24 +2005-06-02,40.05,40.32,39.60,40.04,13356200,40.04 +2005-06-01,39.89,40.76,39.86,40.30,16207600,40.30 +2005-05-31,40.66,40.74,39.58,39.76,14435900,39.76 +2005-05-27,40.64,40.79,40.01,40.56,11286000,40.56 +2005-05-26,39.94,40.94,39.94,40.74,18768600,40.74 +2005-05-25,39.50,39.95,39.32,39.78,14143100,39.78 +2005-05-24,39.45,39.99,39.03,39.70,21195000,39.70 +2005-05-23,37.85,39.90,37.85,39.76,37234800,39.76 +2005-05-20,37.25,37.65,37.19,37.55,16166100,37.55 +2005-05-19,35.78,37.68,35.78,37.55,28327200,37.55 +2005-05-18,35.45,37.56,34.99,35.84,22740100,35.84 +2005-05-17,35.14,35.46,34.54,35.36,21012300,35.36 +2005-05-16,34.56,35.70,34.53,35.55,16939100,35.55 +2005-05-13,34.20,35.23,34.07,34.77,25096900,34.77 +2005-05-12,35.42,35.59,34.00,34.13,34651500,34.13 +2005-05-11,35.20,35.67,33.11,35.61,72927900,35.61 +2005-05-10,36.75,37.25,36.33,36.42,15723700,36.42 +2005-05-09,37.28,37.45,36.75,36.97,12703400,36.97 +2005-05-06,36.89,37.33,36.79,37.24,11651700,37.24 +2005-05-05,37.25,37.27,36.47,36.68,13834500,36.68 +2005-05-04,36.11,37.20,36.10,37.15,16006300,37.15 +2005-05-03,36.40,36.74,36.03,36.21,17740700,36.21 +2005-05-02,36.21,36.65,36.02,36.43,16640000,36.43 +2005-04-29,36.15,36.23,35.22,36.06,23986800,36.06 +2005-04-28,36.29,36.34,35.24,35.54,20539500,35.54 +2005-04-27,35.89,36.36,35.51,35.95,21924600,35.95 +2005-04-26,36.78,37.51,36.12,36.19,28946700,36.19 +2005-04-25,36.49,37.02,36.11,36.98,26659300,36.98 +2005-04-22,36.84,37.00,34.90,35.50,29968900,35.50 +2005-04-21,36.40,37.21,35.90,37.18,27128300,37.18 +2005-04-20,37.66,37.74,35.44,35.51,33754700,35.51 +2005-04-19,36.60,37.44,35.87,37.09,38630100,37.09 +2005-04-18,35.00,36.30,34.00,35.62,47399200,35.62 +2005-04-15,36.62,37.25,35.28,35.35,61717400,35.35 +2005-04-14,38.81,39.56,36.84,37.26,98328300,37.26 +2005-04-13,42.95,42.99,40.39,41.04,48998100,41.04 +2005-04-12,42.49,43.19,42.01,42.66,35037900,42.66 +2005-04-11,44.15,44.25,41.91,41.92,29345100,41.92 +2005-04-08,43.70,44.45,43.54,43.74,23212500,43.74 +2005-04-07,42.33,43.75,42.25,43.56,18106700,43.56 +2005-04-06,42.40,42.81,42.15,42.33,14815200,42.33 +2005-04-05,41.22,42.24,41.09,41.89,19865700,41.89 +2005-04-04,40.99,41.31,40.16,41.09,20714800,41.09 +2005-04-01,42.09,42.18,40.57,40.89,22903000,40.89 +2005-03-31,42.45,42.52,41.59,41.67,22719100,41.67 +2005-03-30,42.07,42.80,41.82,42.80,14105700,42.80 +2005-03-29,42.56,42.83,41.50,41.75,16477000,41.75 +2005-03-28,42.75,42.96,42.47,42.53,9836100,42.53 +2005-03-24,42.91,43.00,42.50,42.50,12596600,42.50 +2005-03-23,42.45,43.40,42.02,42.55,21779400,42.55 +2005-03-22,43.71,43.96,42.68,42.83,19693400,42.83 +2005-03-21,43.29,43.97,42.86,43.70,19326000,43.70 +2005-03-18,43.33,43.44,42.50,42.96,33576800,42.96 +2005-03-17,41.53,42.88,41.32,42.25,28640000,42.25 +2005-03-16,41.21,42.31,40.78,41.18,24921900,41.18 +2005-03-15,40.64,41.14,40.25,40.96,18164600,40.96 +2005-03-14,40.52,40.79,39.52,40.32,21620900,40.32 +2005-03-11,40.21,40.59,39.80,40.27,22601100,40.27 +2005-03-10,39.53,40.26,39.10,39.83,27753900,39.83 +2005-03-09,39.64,40.28,38.83,39.35,47230900,39.35 +2005-03-08,41.90,42.16,40.10,40.53,36480400,40.53 +2005-03-07,42.80,43.25,42.35,42.75,16094000,42.75 +2005-03-04,42.76,43.01,41.85,42.81,27022100,42.81 +2005-03-03,44.37,44.41,41.22,41.79,50416200,41.79 +2005-03-02,44.25,44.89,44.08,44.12,16362900,44.12 +2005-03-01,44.99,45.11,44.16,44.50,16721000,44.50 +2005-02-28,44.68,45.14,43.96,44.86,23271800,44.86 +2005-02-25,89.62,89.91,88.19,88.99,32696800,44.49 +2005-02-24,88.48,89.31,87.73,88.93,54251000,44.47 +2005-02-23,86.72,88.45,85.55,88.23,48042200,44.12 +2005-02-22,86.30,88.30,85.29,85.29,43546200,42.65 +2005-02-18,87.74,87.86,86.25,86.81,41544800,43.40 +2005-02-17,90.65,90.88,87.45,87.81,54231200,43.90 +2005-02-16,88.15,90.20,87.35,90.13,58544400,45.06 +2005-02-15,86.66,89.08,86.00,88.41,82579200,44.21 +2005-02-14,82.73,84.79,82.05,84.63,45409400,42.31 +2005-02-11,79.86,81.76,78.94,81.21,42894800,40.60 +2005-02-10,78.72,79.28,76.66,78.36,39036400,39.18 +2005-02-09,81.04,81.99,78.10,78.74,42552000,39.37 +2005-02-08,79.07,81.38,78.79,80.90,31786400,40.45 +2005-02-07,78.93,79.35,77.50,78.94,18730600,39.47 +2005-02-04,77.87,78.93,77.53,78.84,20127000,39.42 +2005-02-03,79.10,79.43,77.33,77.81,26130400,38.90 +2005-02-02,77.95,79.91,77.69,79.63,36430800,39.81 +2005-02-01,77.05,77.77,76.58,77.53,24228400,38.76 +2005-01-31,74.58,77.89,74.51,76.90,60039200,38.45 +2005-01-28,72.62,73.98,72.44,73.98,28629000,36.99 +2005-01-27,72.16,72.92,71.55,72.64,17722400,36.32 +2005-01-26,72.66,72.75,71.22,72.25,26410600,36.12 +2005-01-25,71.37,72.84,70.94,72.05,34615400,36.03 +2005-01-24,70.98,71.78,70.55,70.76,30058200,35.38 +2005-01-21,71.31,71.60,70.00,70.49,32547600,35.24 +2005-01-20,69.65,71.27,69.47,70.46,32675800,35.23 +2005-01-19,70.49,71.46,69.75,69.88,26853400,34.94 +2005-01-18,69.85,70.70,67.75,70.65,35945000,35.33 +2005-01-14,70.25,71.72,69.19,70.20,63240800,35.10 +2005-01-13,73.71,74.42,69.73,69.80,113025600,34.90 +2005-01-12,65.45,65.90,63.30,65.46,68560800,32.73 +2005-01-11,68.25,69.15,64.14,64.56,93272400,32.28 +2005-01-10,69.83,70.70,67.88,68.96,61618200,34.48 +2005-01-07,65.00,69.63,64.75,69.25,79551800,34.62 +2005-01-06,64.67,64.91,63.33,64.55,25198400,32.28 +2005-01-05,64.46,65.25,64.05,64.50,24301200,32.25 +2005-01-04,63.79,65.47,62.97,63.94,39171800,31.97 +2005-01-03,64.78,65.11,62.60,63.29,24714000,31.65 +2004-12-31,64.89,65.00,64.03,64.40,9949600,32.20 +2004-12-30,64.81,65.03,64.22,64.80,12333600,32.40 +2004-12-29,63.81,64.98,63.57,64.44,16055800,32.22 +2004-12-28,63.30,64.25,62.05,64.18,21848400,32.09 +2004-12-27,64.80,65.15,62.88,63.16,19981800,31.58 +2004-12-23,63.75,64.25,63.60,64.01,8783200,32.01 +2004-12-22,63.66,64.36,63.40,63.75,20208200,31.88 +2004-12-21,63.56,63.77,61.60,63.69,38014800,31.84 +2004-12-20,65.47,66.00,61.76,62.72,41718800,31.36 +2004-12-17,66.84,67.04,64.90,64.99,27982000,32.49 +2004-12-16,66.15,67.50,66.05,66.60,40218400,33.30 +2004-12-15,65.24,65.46,64.66,65.26,14227200,32.63 +2004-12-14,65.40,65.88,65.02,65.29,14847200,32.65 +2004-12-13,65.62,65.90,64.60,64.91,14108600,32.46 +2004-12-10,65.03,66.05,64.70,65.15,27706200,32.58 +2004-12-09,62.81,64.40,62.07,63.99,26482200,32.00 +2004-12-08,63.08,64.43,62.05,63.28,24710800,31.64 +2004-12-07,65.93,66.73,62.56,62.89,37746400,31.44 +2004-12-06,64.25,66.24,62.95,65.78,44568600,32.89 +2004-12-03,64.53,65.00,61.75,62.68,44244600,31.34 +2004-12-02,66.13,66.90,64.66,65.21,35265800,32.60 +2004-12-01,67.79,67.95,66.27,67.79,28591200,33.90 +2004-11-30,68.79,68.79,67.05,67.05,36732800,33.53 +2004-11-29,68.95,69.57,67.41,68.44,61175600,34.22 +2004-11-26,65.35,65.76,64.34,64.55,19648000,32.28 +2004-11-24,61.69,65.20,61.55,64.05,49671000,32.03 +2004-11-23,62.30,62.45,61.05,61.27,32551800,30.64 +2004-11-22,61.80,64.00,57.90,61.35,91721800,30.67 +2004-11-19,55.49,56.91,54.50,55.17,27331400,27.58 +2004-11-18,54.30,55.45,54.29,55.39,16398200,27.69 +2004-11-17,55.19,55.45,54.22,54.90,14205400,27.45 +2004-11-16,55.16,55.20,54.48,54.94,10539400,27.47 +2004-11-15,55.20,55.46,54.34,55.24,13430200,27.62 +2004-11-12,55.01,55.69,54.84,55.50,14132200,27.75 +2004-11-11,54.95,55.43,54.23,55.30,14546400,27.65 +2004-11-10,53.95,55.39,53.91,54.75,18167000,27.38 +2004-11-09,54.23,54.55,53.38,54.05,16991600,27.02 +2004-11-08,54.27,55.45,53.86,54.38,18818600,27.19 +2004-11-05,54.86,55.00,52.04,54.72,43037400,27.36 +2004-11-04,55.03,55.55,54.37,54.45,33165200,27.23 +2004-11-03,54.37,56.11,53.99,55.31,43006200,27.66 +2004-11-02,52.40,54.08,52.40,53.50,26071000,26.75 +2004-11-01,52.50,53.26,52.04,52.45,21501800,26.23 +2004-10-29,51.84,53.20,51.80,52.40,28936400,26.20 +2004-10-28,49.98,52.22,49.50,52.19,30866600,26.09 +2004-10-27,48.51,50.62,48.17,50.30,42624800,25.15 +2004-10-26,47.45,48.05,46.97,47.97,21227200,23.99 +2004-10-25,47.20,47.84,47.07,47.55,14023000,23.77 +2004-10-22,47.54,47.67,47.02,47.41,17252400,23.70 +2004-10-21,47.48,48.13,47.36,47.94,25875200,23.97 +2004-10-20,47.18,47.60,46.65,47.47,21611000,23.74 +2004-10-19,48.10,48.35,47.31,47.42,28642600,23.71 +2004-10-18,44.70,47.75,44.70,47.75,42884000,23.88 +2004-10-15,44.88,45.61,44.19,45.50,36826000,22.75 +2004-10-14,43.19,45.75,42.55,44.98,98872400,22.49 +2004-10-13,38.87,39.76,38.74,39.75,41536000,19.88 +2004-10-12,38.50,38.58,37.65,38.29,16435400,19.15 +2004-10-11,38.80,39.06,38.20,38.59,11566800,19.30 +2004-10-08,39.56,39.77,38.84,39.06,12829600,19.53 +2004-10-07,40.54,40.93,39.46,39.62,15219600,19.81 +2004-10-06,39.50,40.76,39.47,40.64,15939400,20.32 +2004-10-05,38.56,39.67,38.40,39.37,14505800,19.68 +2004-10-04,39.18,39.18,38.75,38.79,20503000,19.40 +2004-10-01,39.12,39.19,38.58,38.67,16621600,19.33 +2004-09-30,39.00,39.27,38.45,38.75,15179000,19.38 +2004-09-29,37.93,38.86,37.82,38.68,9768200,19.34 +2004-09-28,37.46,38.29,37.45,38.04,12613800,19.02 +2004-09-27,36.95,37.98,36.83,37.53,14197000,18.76 +2004-09-24,37.45,38.00,37.15,37.29,13196000,18.65 +2004-09-23,37.04,37.50,36.93,37.27,14193000,18.64 +2004-09-22,38.10,38.14,36.81,36.92,14346000,18.46 +2004-09-21,37.75,38.87,37.46,38.01,13809000,19.00 +2004-09-20,36.88,37.98,36.87,37.71,8750000,18.85 +2004-09-17,36.55,37.38,36.40,37.14,17939600,18.57 +2004-09-16,35.20,36.76,35.08,36.35,17925600,18.17 +2004-09-15,35.36,35.48,34.80,35.20,8309600,17.60 +2004-09-14,35.24,35.55,34.78,35.49,9100800,17.75 +2004-09-13,35.88,36.07,35.32,35.59,10070600,17.80 +2004-09-10,35.66,36.23,35.46,35.87,11714800,17.93 +2004-09-09,36.10,36.30,35.28,35.70,16476400,17.85 +2004-09-08,35.70,36.57,35.68,36.35,12268800,18.17 +2004-09-07,35.40,36.19,35.23,35.76,10784200,17.88 +2004-09-03,35.01,35.92,35.01,35.23,10481000,17.61 +2004-09-02,35.50,35.81,34.83,35.66,14511600,17.83 +2004-09-01,34.30,35.99,34.19,35.86,18418800,17.93 +2004-08-31,34.07,34.95,34.00,34.49,13448600,17.25 +2004-08-30,34.00,34.72,33.96,34.12,7790800,17.06 +2004-08-27,34.68,34.76,34.00,34.35,13886200,17.17 +2004-08-26,33.04,35.18,32.74,34.66,34137800,17.33 +2004-08-25,31.87,33.15,31.73,33.05,18057800,16.52 +2004-08-24,31.26,31.95,31.19,31.95,13362000,15.98 +2004-08-23,30.86,31.27,30.60,31.08,9095000,15.54 +2004-08-20,30.71,30.99,30.49,30.80,11313600,15.40 +2004-08-19,31.51,31.86,30.36,30.71,13890000,15.35 +2004-08-18,30.51,31.85,30.49,31.74,13023400,15.87 +2004-08-17,30.58,31.13,30.35,30.87,11536400,15.44 +2004-08-16,31.00,31.72,30.64,30.78,15559800,15.39 +2004-08-13,30.60,31.28,30.40,30.84,11716000,15.42 +2004-08-12,30.45,30.85,30.28,30.37,8078600,15.19 +2004-08-11,31.10,31.13,30.26,31.01,11514000,15.51 +2004-08-10,30.39,31.54,30.35,31.52,12537000,15.76 +2004-08-09,29.85,30.45,29.81,30.30,10387400,15.15 +2004-08-06,30.90,31.10,29.70,29.78,17581800,14.89 +2004-08-05,31.81,32.30,31.25,31.39,8732200,15.69 +2004-08-04,31.19,32.12,31.17,31.79,9874600,15.90 +2004-08-03,31.45,31.72,31.15,31.29,7558200,15.65 +2004-08-02,31.18,32.20,31.13,31.58,13039000,15.79 +2004-07-30,32.65,33.00,32.00,32.34,8679400,16.17 +2004-07-29,32.47,32.82,32.13,32.64,7934200,16.32 +2004-07-28,32.31,32.41,31.16,32.27,10180400,16.14 +2004-07-27,31.80,32.75,31.57,32.43,15178800,16.22 +2004-07-26,30.85,31.45,30.78,31.26,14069000,15.63 +2004-07-23,31.53,31.75,30.48,30.70,9770400,15.35 +2004-07-22,31.25,31.73,31.06,31.68,11932800,15.84 +2004-07-21,32.42,32.71,31.34,31.62,10759200,15.81 +2004-07-20,31.95,32.20,31.55,32.20,11562400,16.10 +2004-07-19,32.01,32.22,31.66,31.97,19041800,15.98 +2004-07-16,32.80,32.92,32.12,32.20,17442200,16.10 +2004-07-15,32.66,33.63,32.11,32.93,63133000,16.47 +2004-07-14,28.86,29.97,28.74,29.58,29850000,14.79 +2004-07-13,29.25,29.60,29.02,29.22,11292000,14.61 +2004-07-12,30.02,30.04,28.93,29.14,18272200,14.57 +2004-07-09,30.27,30.50,30.03,30.03,7459400,15.02 +2004-07-08,30.13,30.68,29.95,30.14,8335000,15.07 +2004-07-07,30.85,31.36,30.13,30.39,14214000,15.19 +2004-07-06,31.27,31.42,30.80,30.95,12463600,15.48 +2004-07-02,30.48,31.18,29.73,31.08,32524400,15.54 +2004-07-01,32.10,32.48,31.90,32.30,12212200,16.15 +2004-06-30,32.56,32.97,31.89,32.54,13323000,16.27 +2004-06-29,32.07,32.99,31.41,32.50,21091200,16.25 +2004-06-28,34.18,34.19,32.21,32.49,18610600,16.25 +2004-06-25,33.07,33.70,33.00,33.70,11551000,16.85 +2004-06-24,33.51,33.70,32.98,33.18,9018400,16.59 +2004-06-23,33.00,33.83,32.89,33.70,13959600,16.85 +2004-06-22,32.30,33.09,32.29,33.00,12875400,16.50 +2004-06-21,33.12,33.50,32.12,32.33,13936200,16.17 +2004-06-18,32.66,33.41,32.43,32.91,14509000,16.45 +2004-06-17,32.56,33.13,32.21,32.81,19690000,16.41 +2004-06-16,30.66,33.32,30.53,32.74,32487200,16.37 +2004-06-15,30.54,31.14,30.26,30.69,15879800,15.35 +2004-06-14,30.65,30.68,29.50,30.12,8713800,15.06 +2004-06-10,30.20,30.97,30.20,30.74,9199200,15.37 +2004-06-09,30.09,30.71,30.00,30.20,12471600,15.10 +2004-06-08,29.99,30.44,29.83,30.35,14843600,15.18 +2004-06-07,29.04,29.98,28.81,29.81,10567000,14.90 +2004-06-04,28.56,29.25,28.51,28.78,14254000,14.39 +2004-06-03,28.72,28.99,28.29,28.40,8961800,14.20 +2004-06-02,28.03,29.17,27.80,28.92,11382600,14.46 +2004-06-01,27.79,28.20,27.61,28.06,6504800,14.03 +2004-05-28,28.08,28.27,27.80,28.06,5204200,14.03 +2004-05-27,28.46,28.60,27.82,28.17,8427600,14.09 +2004-05-26,28.33,28.78,28.00,28.51,11506000,14.26 +2004-05-25,27.50,28.51,27.29,28.41,11427800,14.20 +2004-05-24,27.29,27.90,27.11,27.34,8414400,13.67 +2004-05-21,26.90,27.20,26.73,27.11,6424800,13.56 +2004-05-20,26.63,27.00,26.47,26.71,7010600,13.35 +2004-05-19,27.40,27.50,26.42,26.47,13414000,13.23 +2004-05-18,26.97,27.29,26.80,27.06,7359400,13.53 +2004-05-17,26.70,27.06,26.36,26.64,10730200,13.32 +2004-05-14,27.25,27.32,26.45,27.06,9207200,13.53 +2004-05-13,27.10,27.72,26.90,27.19,8209000,13.60 +2004-05-12,26.79,27.34,26.24,27.30,8765000,13.65 +2004-05-11,26.40,27.19,26.40,27.14,10899000,13.57 +2004-05-10,26.27,26.60,25.94,26.28,8927800,13.14 +2004-05-07,26.55,27.57,26.55,26.67,14965600,13.34 +2004-05-06,26.40,26.75,25.90,26.58,9412800,13.29 +2004-05-05,26.20,26.75,25.96,26.65,8503800,13.32 +2004-05-04,25.97,26.55,25.50,26.14,9999400,13.07 +2004-05-03,26.00,26.33,25.74,26.07,10629800,13.03 +2004-04-30,26.71,26.96,25.49,25.78,16660800,12.89 +2004-04-29,26.45,27.00,25.98,26.77,16456800,13.39 +2004-04-28,26.82,27.01,26.34,26.45,8256000,13.23 +2004-04-27,27.24,27.44,26.69,26.94,10138000,13.47 +2004-04-26,27.58,27.64,27.00,27.13,8254600,13.56 +2004-04-23,27.70,28.00,27.05,27.70,11279600,13.85 +2004-04-22,27.56,28.18,27.11,27.78,12306600,13.89 +2004-04-21,27.60,28.12,27.37,27.73,11638400,13.86 +2004-04-20,28.21,28.41,27.56,27.73,12661400,13.86 +2004-04-19,28.12,28.75,27.83,28.35,25441200,14.18 +2004-04-16,29.15,29.31,28.50,29.18,14390400,14.59 +2004-04-15,28.82,29.58,28.16,29.30,62908800,14.65 +2004-04-14,26.74,27.07,26.31,26.64,22847600,13.32 +2004-04-13,27.98,28.03,26.84,26.93,15585600,13.47 +2004-04-12,27.50,28.10,27.49,28.04,8233600,14.02 +2004-04-08,27.88,28.00,27.20,27.53,8604200,13.77 +2004-04-07,27.61,27.70,26.92,27.31,9111400,13.65 +2004-04-06,27.71,28.15,27.43,27.83,9214000,13.91 +2004-04-05,27.48,28.37,27.44,28.32,13774000,14.16 +2004-04-02,27.75,27.93,27.23,27.50,9802800,13.75 +2004-04-01,26.89,27.27,26.62,27.11,11369000,13.56 +2004-03-31,27.92,27.98,26.95,27.04,13956200,13.52 +2004-03-30,27.74,27.95,27.34,27.92,12845600,13.96 +2004-03-29,27.37,27.99,27.20,27.91,12526000,13.95 +2004-03-26,27.00,27.36,26.91,27.04,14996200,13.52 +2004-03-25,26.14,26.91,25.89,26.87,20230200,13.44 +2004-03-24,25.27,25.75,25.27,25.50,15293400,12.75 +2004-03-23,25.88,26.00,25.22,25.29,13768400,12.65 +2004-03-22,25.37,26.17,25.25,25.86,14965400,12.93 +2004-03-19,25.56,26.94,25.54,25.86,14592000,12.93 +2004-03-18,25.94,26.06,25.59,25.67,11467200,12.84 +2004-03-17,25.96,26.38,25.78,26.19,14694000,13.10 +2004-03-16,26.55,26.61,25.39,25.82,21622600,12.91 +2004-03-15,27.03,27.35,26.26,26.45,17204200,13.23 +2004-03-12,27.32,27.78,27.17,27.56,11758000,13.78 +2004-03-11,27.27,28.04,27.09,27.15,21280400,13.57 +2004-03-10,27.04,28.14,26.94,27.68,35963000,13.84 +2004-03-09,25.90,27.23,25.75,27.10,22084400,13.55 +2004-03-08,26.62,26.79,25.80,26.00,18674000,13.00 +2004-03-05,24.95,27.49,24.90,26.74,55021400,13.37 +2004-03-04,23.93,25.22,23.91,25.16,23579400,12.58 +2004-03-03,23.60,24.19,23.60,23.92,8040400,11.96 +2004-03-02,24.00,24.10,23.77,23.81,9167400,11.90 +2004-03-01,24.10,24.30,23.87,24.02,11488600,12.01 +2004-02-27,22.96,24.02,22.95,23.92,16744200,11.96 +2004-02-26,22.88,23.18,22.80,23.04,7086000,11.52 +2004-02-25,22.28,22.90,22.21,22.81,9867000,11.40 +2004-02-24,22.14,22.74,22.00,22.36,9252000,11.18 +2004-02-23,22.34,22.46,21.89,22.19,6931400,11.10 +2004-02-20,22.50,22.51,22.21,22.40,9914400,11.20 +2004-02-19,23.33,23.64,22.41,22.47,11538600,11.23 +2004-02-18,23.18,23.44,23.05,23.26,5058400,11.63 +2004-02-17,23.10,23.49,23.10,23.16,6105600,11.58 +2004-02-13,23.85,24.10,22.83,23.00,11285000,11.50 +2004-02-12,23.61,23.99,23.60,23.73,6571000,11.86 +2004-02-11,23.09,23.87,23.05,23.80,12448000,11.90 +2004-02-10,22.62,23.12,22.44,22.98,9119400,11.49 +2004-02-09,22.62,22.86,22.50,22.67,6723600,11.34 +2004-02-06,22.45,22.89,22.40,22.71,6905000,11.35 +2004-02-05,21.82,22.91,21.81,22.42,12601600,11.21 +2004-02-04,22.00,22.09,21.70,21.79,10912600,10.90 +2004-02-03,22.30,22.40,22.00,22.26,6457600,11.13 +2004-02-02,22.46,22.81,22.08,22.32,10265400,11.16 +2004-01-30,22.65,22.87,22.42,22.56,6617800,11.28 +2004-01-29,22.63,22.80,22.19,22.68,7596400,11.34 +2004-01-28,22.84,23.38,22.41,22.52,9835800,11.26 +2004-01-27,23.04,23.25,22.80,23.07,10966800,11.53 +2004-01-26,22.46,23.06,22.43,23.01,9688200,11.51 +2004-01-23,22.42,22.74,22.25,22.56,8113200,11.28 +2004-01-22,22.56,22.83,22.18,22.18,7321600,11.09 +2004-01-21,22.70,22.97,22.43,22.61,8095000,11.31 +2004-01-20,22.67,22.80,22.25,22.73,11283800,11.36 +2004-01-16,22.89,23.04,22.61,22.72,13315000,11.36 +2004-01-15,22.91,23.40,22.50,22.85,36364600,11.43 +2004-01-14,24.40,24.54,23.78,24.20,22144400,12.10 +2004-01-13,24.70,24.84,23.86,24.12,24250600,12.06 +2004-01-12,23.25,24.00,23.10,23.73,17412400,11.86 +2004-01-09,23.23,24.13,22.79,23.00,15266400,11.50 +2004-01-08,22.84,23.73,22.65,23.36,16439400,11.68 +2004-01-07,22.10,22.83,21.93,22.59,20959800,11.30 +2004-01-06,22.25,22.42,21.71,22.09,18191000,11.05 +2004-01-05,21.42,22.39,21.42,22.17,14107800,11.09 +2004-01-02,21.55,21.75,21.18,21.28,5165800,10.64 +2003-12-31,21.35,21.53,21.18,21.37,6230400,10.69 +2003-12-30,21.18,21.50,21.15,21.28,7316200,10.64 +2003-12-29,20.91,21.16,20.86,21.15,8337800,10.57 +2003-12-26,20.35,20.91,20.34,20.78,3703400,10.39 +2003-12-24,19.72,20.59,19.65,20.41,6338400,10.20 +2003-12-23,19.92,19.95,19.60,19.81,11017800,9.90 +2003-12-22,19.65,19.89,19.25,19.85,13466600,9.93 +2003-12-19,20.19,20.42,19.62,19.70,16198600,9.85 +2003-12-18,19.90,20.18,19.90,20.04,11818400,10.02 +2003-12-17,20.08,20.13,19.79,19.88,9795000,9.94 +2003-12-16,20.19,20.49,20.01,20.12,13355600,10.06 +2003-12-15,21.49,21.49,20.07,20.17,13889600,10.09 +2003-12-12,21.32,21.32,20.70,20.89,6881200,10.44 +2003-12-11,20.25,21.34,20.21,21.21,6540600,10.60 +2003-12-10,20.45,20.61,19.96,20.38,9690600,10.19 +2003-12-09,21.17,21.25,20.40,20.45,4826600,10.23 +2003-12-08,20.78,21.08,20.41,21.05,5294200,10.52 +2003-12-05,20.90,21.15,20.73,20.85,6649200,10.43 +2003-12-04,20.94,21.17,20.77,21.15,6355000,10.57 +2003-12-03,21.54,21.84,20.96,21.03,6832000,10.52 +2003-12-02,21.60,21.90,21.41,21.54,7332000,10.77 +2003-12-01,21.04,21.85,21.00,21.71,12912000,10.85 +2003-11-28,20.78,21.07,20.52,20.91,2717800,10.45 +2003-11-26,20.89,21.15,20.25,20.72,8754600,10.36 +2003-11-25,21.23,21.25,20.61,20.68,9594800,10.34 +2003-11-24,20.50,21.27,20.45,21.15,13636600,10.57 +2003-11-21,20.34,20.58,19.85,20.28,8637000,10.14 +2003-11-20,20.10,21.08,20.10,20.38,8556800,10.19 +2003-11-19,20.56,20.65,20.26,20.42,12306600,10.21 +2003-11-18,21.21,21.34,20.35,20.41,9542600,10.20 +2003-11-17,21.35,21.37,20.95,21.13,8152000,10.56 +2003-11-14,22.48,22.61,21.28,21.46,8466000,10.73 +2003-11-13,22.07,22.56,21.92,22.42,7599000,11.21 +2003-11-12,21.48,22.72,21.48,22.33,10714400,11.16 +2003-11-11,21.90,22.02,21.48,21.54,7681200,10.77 +2003-11-10,22.45,22.65,21.84,21.90,8367000,10.95 +2003-11-07,23.19,23.24,22.45,22.50,7505200,11.25 +2003-11-06,22.91,23.15,22.65,23.12,14181200,11.56 +2003-11-05,22.82,23.13,22.47,23.03,11516800,11.52 +2003-11-04,23.07,23.10,22.59,22.91,8901200,11.45 +2003-11-03,22.83,23.30,22.78,23.15,10815800,11.57 +2003-10-31,23.30,23.35,22.78,22.89,7791200,11.44 +2003-10-30,23.99,24.00,22.87,23.09,9305600,11.55 +2003-10-29,23.51,23.90,23.34,23.69,9538600,11.85 +2003-10-28,22.56,23.77,22.40,23.72,8989800,11.86 +2003-10-27,22.75,22.89,22.49,22.60,5786200,11.30 +2003-10-24,22.56,22.85,22.23,22.60,7852000,11.30 +2003-10-23,22.73,23.15,22.59,22.99,5900400,11.49 +2003-10-22,22.94,23.20,22.68,22.76,5771400,11.38 +2003-10-21,23.31,23.40,22.75,23.18,6302200,11.59 +2003-10-20,22.60,23.34,22.38,23.22,9969000,11.61 +2003-10-17,23.38,23.49,22.43,22.75,12850400,11.38 +2003-10-16,23.80,23.84,22.41,23.25,34845800,11.62 +2003-10-15,24.85,25.01,24.58,24.82,21789400,12.41 +2003-10-14,24.32,24.74,24.19,24.55,9836400,12.27 +2003-10-13,23.73,24.41,23.72,24.35,9995200,12.18 +2003-10-10,23.50,23.81,23.37,23.68,6244200,11.84 +2003-10-09,23.30,23.67,22.79,23.45,12419600,11.73 +2003-10-08,23.25,23.54,22.73,23.06,15309600,11.53 +2003-10-07,22.05,23.41,21.91,23.22,14934800,11.61 +2003-10-06,21.67,22.33,21.58,22.29,9583200,11.15 +2003-10-03,20.99,21.86,20.88,21.69,10700000,10.85 +2003-10-02,20.80,20.80,20.28,20.57,7287800,10.28 +2003-10-01,20.71,21.10,20.19,20.79,8432600,10.40 +2003-09-30,21.09,21.22,20.44,20.72,10193800,10.36 +2003-09-29,21.49,21.67,20.65,21.30,13060800,10.65 +2003-09-26,20.30,21.70,20.15,20.69,12401800,10.35 +2003-09-25,21.34,21.37,20.25,20.43,20513600,10.22 +2003-09-24,22.21,22.31,21.08,21.32,10760200,10.66 +2003-09-23,22.02,22.46,21.88,22.43,4730400,11.22 +2003-09-22,22.18,22.50,21.92,22.08,6422200,11.04 +2003-09-19,22.88,23.05,22.43,22.58,7355600,11.29 +2003-09-18,22.10,22.99,21.95,22.88,9032400,11.44 +2003-09-17,22.37,22.38,21.85,22.12,10335600,11.06 +2003-09-16,22.21,22.69,22.20,22.36,9607400,11.18 +2003-09-15,22.81,22.90,22.12,22.21,8101600,11.10 +2003-09-12,22.51,23.14,22.31,23.10,6428200,11.55 +2003-09-11,22.25,22.79,22.10,22.56,7631600,11.28 +2003-09-10,22.25,22.61,22.11,22.18,8031800,11.09 +2003-09-09,22.53,22.67,22.12,22.37,6441800,11.19 +2003-09-08,22.48,22.79,22.47,22.74,5973000,11.37 +2003-09-05,22.73,23.15,22.41,22.50,8576200,11.25 +2003-09-04,23.16,23.25,22.77,22.83,7135000,11.41 +2003-09-03,22.80,23.32,22.76,22.95,9601000,11.48 +2003-09-02,22.66,22.90,22.40,22.85,8647600,11.43 +2003-08-29,22.20,22.85,22.05,22.61,9398400,11.31 +2003-08-28,21.33,22.22,21.33,22.19,11415200,11.10 +2003-08-27,20.91,21.48,20.66,21.48,8060800,10.74 +2003-08-26,20.75,21.07,20.35,21.05,5891400,10.52 +2003-08-25,20.78,20.91,20.49,20.86,4920800,10.43 +2003-08-22,21.81,22.00,20.64,20.88,8938000,10.44 +2003-08-21,21.03,21.71,20.95,21.68,9118800,10.84 +2003-08-20,20.18,21.27,20.14,21.01,9757600,10.51 +2003-08-19,20.37,20.45,20.00,20.32,4774600,10.16 +2003-08-18,19.86,20.41,19.72,20.34,6884800,10.17 +2003-08-15,20.02,20.07,19.66,19.71,4495200,9.85 +2003-08-14,20.21,20.33,19.94,19.97,6885000,9.98 +2003-08-13,19.86,20.34,19.58,20.18,10146400,10.09 +2003-08-12,19.76,19.80,19.46,19.70,5872800,9.85 +2003-08-11,19.82,19.93,19.51,19.66,4901000,9.83 +2003-08-08,20.11,20.13,19.60,19.64,4916400,9.82 +2003-08-07,19.73,20.09,19.42,19.93,6227800,9.97 +2003-08-06,20.06,20.17,19.50,19.63,8766600,9.81 +2003-08-05,21.35,21.40,20.10,20.38,8908600,10.19 +2003-08-04,20.53,21.50,20.28,21.21,8218400,10.60 +2003-08-01,21.00,21.27,20.64,20.73,5343000,10.36 +2003-07-31,20.74,21.35,20.57,21.08,10766600,10.54 +2003-07-30,20.77,20.90,20.17,20.28,6199800,10.14 +2003-07-29,20.99,21.08,20.52,20.72,7040000,10.36 +2003-07-28,21.50,21.50,20.86,20.99,6084200,10.49 +2003-07-25,20.41,21.57,20.40,21.54,7738800,10.77 +2003-07-24,21.04,21.50,20.38,20.51,8187000,10.26 +2003-07-23,20.95,20.96,20.46,20.79,5108400,10.40 +2003-07-22,20.87,20.96,20.50,20.80,7086600,10.40 +2003-07-21,20.69,20.80,20.30,20.61,6564600,10.31 +2003-07-18,20.90,21.18,20.40,20.86,10672800,10.43 +2003-07-17,20.19,20.95,20.13,20.90,26829000,10.45 +2003-07-16,19.97,20.00,19.38,19.87,8961800,9.94 +2003-07-15,20.02,20.24,19.43,19.61,7380200,9.81 +2003-07-14,20.01,20.40,19.87,19.90,6728800,9.95 +2003-07-11,19.66,20.00,19.53,19.85,4887800,9.93 +2003-07-10,19.88,19.94,19.37,19.58,6104800,9.79 +2003-07-09,20.21,20.45,19.89,19.89,7630200,9.94 +2003-07-08,19.52,20.50,19.49,20.40,9169200,10.20 +2003-07-07,19.27,20.18,19.13,19.87,10224000,9.94 +2003-07-03,19.00,19.55,18.98,19.13,4920400,9.56 +2003-07-02,19.03,19.40,19.02,19.27,11617800,9.64 +2003-07-01,18.87,19.18,18.51,19.09,6464000,9.55 +2003-06-30,18.68,19.21,18.59,19.06,7934000,9.53 +2003-06-27,19.30,19.31,18.48,18.73,13064000,9.36 +2003-06-26,18.70,19.32,18.70,19.29,5775200,9.65 +2003-06-25,18.86,19.40,18.71,19.09,11779000,9.55 +2003-06-24,19.47,19.67,18.72,18.78,18370800,9.39 +2003-06-23,19.30,19.69,18.75,19.06,10977200,9.53 +2003-06-20,19.35,19.58,18.90,19.20,12733800,9.60 +2003-06-19,19.36,19.61,18.77,19.14,13626000,9.57 +2003-06-18,18.45,19.48,18.31,19.12,16249400,9.56 +2003-06-17,18.41,18.50,17.99,18.19,6338000,9.10 +2003-06-16,17.60,18.27,17.45,18.27,8518800,9.14 +2003-06-13,17.75,17.95,17.13,17.42,6830200,8.71 +2003-06-12,17.55,17.88,17.45,17.77,9021000,8.89 +2003-06-11,17.15,17.51,16.81,17.45,8039800,8.73 +2003-06-10,16.89,17.29,16.75,17.18,6308800,8.59 +2003-06-09,16.94,17.04,16.63,16.79,9284000,8.40 +2003-06-06,17.74,18.04,17.14,17.15,8621000,8.57 +2003-06-05,17.45,17.74,17.33,17.64,7339200,8.82 +2003-06-04,17.30,17.79,17.14,17.60,9685800,8.80 +2003-06-03,17.44,17.67,17.02,17.31,12887800,8.65 +2003-06-02,18.10,18.29,17.27,17.45,14949600,8.73 +2003-05-30,18.12,18.18,17.53,17.95,13669600,8.98 +2003-05-29,18.29,18.50,17.90,18.10,11920200,9.05 +2003-05-28,18.50,18.66,18.15,18.28,12131400,9.14 +2003-05-27,17.96,18.90,17.91,18.88,10361800,9.44 +2003-05-23,18.21,18.46,17.96,18.32,7382800,9.16 +2003-05-22,17.89,18.40,17.74,18.24,6373600,9.12 +2003-05-21,17.79,18.09,17.67,17.85,10893200,8.93 +2003-05-20,18.10,18.16,17.60,17.79,14865000,8.90 +2003-05-19,18.53,18.65,18.06,18.10,15924600,9.05 +2003-05-16,18.59,19.01,18.28,18.80,12201000,9.40 +2003-05-15,18.60,18.85,18.47,18.73,10178400,9.36 +2003-05-14,18.83,18.84,18.43,18.55,12696000,9.27 +2003-05-13,18.43,18.97,17.95,18.67,15957000,9.34 +2003-05-12,18.15,18.74,18.13,18.56,14977600,9.28 +2003-05-09,18.33,18.40,17.88,18.30,21013800,9.15 +2003-05-08,17.70,18.07,17.29,18.00,24562000,9.00 +2003-05-07,17.33,18.24,17.11,17.65,37656400,8.82 +2003-05-06,16.12,17.90,16.10,17.50,54089000,8.75 +2003-05-05,14.77,16.88,14.75,16.09,55561000,8.05 +2003-05-02,14.46,14.59,14.34,14.45,11470800,7.22 +2003-05-01,14.25,14.39,14.00,14.36,12241400,7.18 +2003-04-30,13.93,14.35,13.85,14.22,16363400,7.11 +2003-04-29,13.98,14.16,13.58,14.06,16365600,7.03 +2003-04-28,13.48,13.96,13.43,13.86,22742800,6.93 +2003-04-25,13.46,13.58,13.23,13.35,7332800,6.68 +2003-04-24,13.52,13.61,13.00,13.44,11611000,6.72 +2003-04-23,13.53,13.63,13.36,13.58,7488600,6.79 +2003-04-22,13.18,13.62,13.09,13.51,10734600,6.76 +2003-04-21,13.13,13.19,12.98,13.14,5440000,6.57 +2003-04-17,13.20,13.25,12.72,13.12,22009200,6.56 +2003-04-16,12.99,13.67,12.92,13.24,36292000,6.62 +2003-04-15,13.59,13.60,13.30,13.39,10856000,6.70 +2003-04-14,13.71,13.75,13.50,13.58,17962800,6.79 +2003-04-11,14.05,14.44,12.93,13.20,49739600,6.60 +2003-04-10,14.20,14.39,14.20,14.37,3825000,7.18 +2003-04-09,14.52,14.62,14.14,14.19,5240200,7.09 +2003-04-08,14.51,14.65,14.36,14.45,4604800,7.22 +2003-04-07,14.85,14.95,14.41,14.49,7030800,7.24 +2003-04-04,14.52,14.67,14.39,14.41,5215000,7.20 +2003-04-03,14.56,14.70,14.35,14.46,5204000,7.23 +2003-04-02,14.36,14.69,14.27,14.60,6120400,7.30 +2003-04-01,14.20,14.31,14.07,14.16,5512200,7.08 +2003-03-31,14.33,14.53,14.04,14.14,9166400,7.07 +2003-03-28,14.40,14.62,14.37,14.57,5189400,7.28 +2003-03-27,14.32,14.70,14.32,14.49,4371200,7.24 +2003-03-26,14.55,14.56,14.30,14.41,6369400,7.20 +2003-03-25,14.41,14.83,14.37,14.55,5989200,7.28 +2003-03-24,14.67,14.80,14.35,14.37,5753600,7.18 +2003-03-21,15.09,15.15,14.82,15.00,10641000,7.50 +2003-03-20,14.93,14.99,14.60,14.91,5827800,7.45 +2003-03-19,15.07,15.15,14.79,14.95,5047000,7.47 +2003-03-18,15.00,15.09,14.82,15.00,8213600,7.50 +2003-03-17,14.89,15.07,14.71,15.01,14282600,7.51 +2003-03-14,14.68,15.01,14.64,14.78,5467800,7.39 +2003-03-13,14.47,14.80,14.17,14.72,11980200,7.36 +2003-03-12,14.17,14.39,14.06,14.22,7948600,7.11 +2003-03-11,14.36,14.49,14.12,14.23,5756800,7.11 +2003-03-10,14.51,14.67,14.30,14.37,4806200,7.18 +2003-03-07,14.47,14.71,14.31,14.53,7178000,7.26 +2003-03-06,14.58,14.60,14.40,14.56,3566400,7.28 +2003-03-05,14.61,14.80,14.52,14.62,4524400,7.31 +2003-03-04,14.74,14.81,14.44,14.56,4514800,7.28 +2003-03-03,15.01,15.16,14.55,14.65,7277200,7.32 +2003-02-28,14.86,15.09,14.77,15.01,6967800,7.51 +2003-02-27,14.57,15.00,14.51,14.86,5512200,7.43 +2003-02-26,14.99,15.02,14.48,14.50,7753400,7.25 +2003-02-25,14.68,15.08,14.58,15.02,6737200,7.51 +2003-02-24,14.86,15.03,13.80,14.74,6437600,7.37 +2003-02-21,14.82,15.06,14.65,15.00,5623000,7.50 +2003-02-20,14.85,14.96,14.71,14.77,8012600,7.39 +2003-02-19,15.07,15.15,14.68,14.85,8584600,7.43 +2003-02-18,14.75,15.30,14.72,15.27,10389200,7.64 +2003-02-14,14.61,14.72,14.35,14.67,8689200,7.34 +2003-02-13,14.41,14.64,14.24,14.54,7446200,7.27 +2003-02-12,14.27,14.60,14.27,14.39,8167400,7.20 +2003-02-11,14.50,14.63,14.20,14.35,5885000,7.18 +2003-02-10,14.26,14.57,14.06,14.35,5996000,7.18 +2003-02-07,14.55,14.60,14.07,14.15,9632200,7.07 +2003-02-06,14.36,14.59,14.22,14.43,6398200,7.22 +2003-02-05,14.71,14.93,14.44,14.45,7914800,7.22 +2003-02-04,14.45,14.65,14.31,14.60,11336200,7.30 +2003-02-03,14.41,14.91,14.35,14.66,9456600,7.33 +2003-01-31,14.19,14.55,14.05,14.36,12186600,7.18 +2003-01-30,14.98,15.07,14.29,14.32,14537800,7.16 +2003-01-29,14.55,15.10,14.30,14.93,13323000,7.47 +2003-01-28,14.24,14.69,14.16,14.58,10223400,7.29 +2003-01-27,13.68,14.50,13.65,14.13,13978800,7.07 +2003-01-24,14.24,14.24,13.56,13.80,10909600,6.90 +2003-01-23,14.05,14.36,13.95,14.17,8152000,7.09 +2003-01-22,13.98,14.15,13.80,13.88,7683600,6.94 +2003-01-21,14.21,14.41,14.00,14.02,9052000,7.01 +2003-01-17,14.56,14.56,14.08,14.10,9527200,7.05 +2003-01-16,14.21,14.76,14.21,14.62,19966800,7.31 +2003-01-15,14.59,14.70,14.26,14.43,13254600,7.22 +2003-01-14,14.69,14.82,14.49,14.61,6673600,7.30 +2003-01-13,14.90,14.90,14.36,14.63,6390800,7.32 +2003-01-10,14.58,14.82,14.49,14.72,6253600,7.36 +2003-01-09,14.62,14.92,14.50,14.68,7687600,7.34 +2003-01-08,14.58,14.71,14.44,14.55,8201600,7.28 +2003-01-07,14.79,15.00,14.47,14.85,12226600,7.43 +2003-01-06,15.03,15.38,14.88,14.90,13947600,7.45 +2003-01-03,14.80,14.93,14.59,14.90,5266200,7.45 +2003-01-02,14.36,14.92,14.35,14.80,6479600,7.40 +2002-12-31,14.00,14.36,13.95,14.33,7168800,7.16 +2002-12-30,14.08,14.15,13.84,14.07,5537200,7.03 +2002-12-27,14.31,14.38,14.01,14.06,2858400,7.03 +2002-12-26,14.42,14.81,14.28,14.40,3050800,7.20 +2002-12-24,14.44,14.47,14.30,14.36,1405000,7.18 +2002-12-23,14.16,14.55,14.12,14.49,4493800,7.24 +2002-12-20,14.29,14.56,13.78,14.14,11360600,7.07 +2002-12-19,14.53,14.92,14.10,14.20,12411400,7.10 +2002-12-18,14.80,14.86,14.50,14.57,5382200,7.28 +2002-12-17,14.85,15.19,14.66,15.08,7952200,7.54 +2002-12-16,14.81,15.10,14.61,14.85,8986600,7.43 +2002-12-13,15.14,15.15,14.65,14.79,5885000,7.39 +2002-12-12,15.51,15.55,15.01,15.19,5333600,7.59 +2002-12-11,15.30,15.49,15.08,15.49,9053600,7.74 +2002-12-10,14.75,15.45,14.73,15.28,11021800,7.64 +2002-12-09,14.94,14.95,14.67,14.75,8431600,7.38 +2002-12-06,14.65,15.19,14.52,14.95,8762800,7.47 +2002-12-05,15.03,15.08,14.53,14.63,8692800,7.32 +2002-12-04,15.18,15.19,14.50,14.97,11634200,7.49 +2002-12-03,15.20,15.34,15.10,15.16,8138200,7.58 +2002-12-02,15.90,16.10,15.01,15.18,14240800,7.59 +2002-11-29,15.79,15.88,15.41,15.50,5122600,7.75 +2002-11-27,15.60,15.86,15.45,15.72,10242800,7.86 +2002-11-26,15.85,15.90,15.27,15.41,8580800,7.70 +2002-11-25,16.03,16.14,15.71,15.97,7122400,7.99 +2002-11-22,16.09,16.30,15.90,16.01,8137800,8.01 +2002-11-21,15.90,16.44,15.75,16.35,14945800,8.18 +2002-11-20,15.30,15.70,15.25,15.53,7455000,7.76 +2002-11-19,15.55,15.75,15.01,15.27,7534000,7.64 +2002-11-18,16.19,16.20,15.52,15.65,5877800,7.82 +2002-11-15,16.23,16.24,15.76,15.95,5749800,7.97 +2002-11-14,15.90,16.41,15.78,16.30,5061200,8.15 +2002-11-13,15.50,16.07,15.28,15.59,8276400,7.80 +2002-11-12,15.32,16.04,15.28,15.64,7992600,7.82 +2002-11-11,15.74,15.89,15.12,15.16,5463400,7.58 +2002-11-08,16.01,16.20,15.52,15.84,6788000,7.92 +2002-11-07,16.94,17.10,15.81,16.00,12006400,8.00 +2002-11-06,17.08,17.32,16.70,17.22,7728200,8.61 +2002-11-05,16.75,16.96,16.35,16.90,7524800,8.45 +2002-11-04,16.50,17.38,16.35,16.89,13457800,8.44 +2002-11-01,15.94,16.50,15.89,16.36,6779600,8.18 +2002-10-31,15.99,16.44,15.92,16.07,10565600,8.03 +2002-10-30,15.49,16.37,15.48,15.98,9667000,7.99 +2002-10-29,15.57,15.88,14.96,15.44,9256400,7.72 +2002-10-28,15.55,15.95,15.25,15.61,12475000,7.80 +2002-10-25,14.69,15.45,14.59,15.42,9966800,7.71 +2002-10-24,15.02,15.21,14.55,14.69,6241000,7.34 +2002-10-23,14.63,14.98,14.50,14.88,7465600,7.44 +2002-10-22,14.47,14.88,14.26,14.70,7791000,7.35 +2002-10-21,14.26,14.63,14.00,14.56,8518600,7.28 +2002-10-18,14.00,14.35,13.93,14.34,10296400,7.17 +2002-10-17,14.21,14.38,13.98,14.11,16760600,7.05 +2002-10-16,14.86,15.13,13.90,14.56,10986600,7.28 +2002-10-15,15.22,15.25,14.78,15.16,14482800,7.58 +2002-10-14,14.55,14.98,14.44,14.77,6943000,7.39 +2002-10-11,14.25,14.78,14.10,14.51,10524200,7.26 +2002-10-10,13.63,14.22,13.58,14.11,11484800,7.05 +2002-10-09,13.54,13.85,13.41,13.59,12738800,6.80 +2002-10-08,13.90,13.96,13.36,13.68,16201600,6.84 +2002-10-07,13.97,14.21,13.76,13.77,8739200,6.89 +2002-10-04,14.36,14.40,13.99,14.03,6815200,7.01 +2002-10-03,14.18,14.60,14.06,14.30,7782000,7.15 +2002-10-02,14.33,14.63,14.10,14.17,8191000,7.09 +2002-10-01,14.59,14.60,14.00,14.51,12229400,7.26 +2002-09-30,14.40,14.57,14.14,14.50,8489200,7.25 +2002-09-27,14.49,14.85,14.48,14.72,7362600,7.36 +2002-09-26,15.10,15.19,14.55,14.70,7451600,7.35 +2002-09-25,14.69,15.17,14.65,14.93,9095800,7.47 +2002-09-24,14.40,14.82,14.40,14.64,8952200,7.32 +2002-09-23,14.76,14.96,14.45,14.85,9418200,7.43 +2002-09-20,14.62,14.94,14.52,14.87,12599600,7.43 +2002-09-19,14.75,14.80,14.48,14.58,7355200,7.29 +2002-09-18,14.69,15.09,14.52,15.02,11737200,7.51 +2002-09-17,14.57,15.03,14.57,14.80,15285600,7.40 +2002-09-16,14.14,14.61,14.12,14.50,10237200,7.25 +2002-09-13,14.13,14.34,14.05,14.17,10105400,7.09 +2002-09-12,14.20,14.51,14.12,14.14,9636800,7.07 +2002-09-11,14.34,14.60,14.15,14.29,7229000,7.14 +2002-09-10,14.41,14.49,14.12,14.33,8909600,7.16 +2002-09-09,14.28,14.53,14.15,14.37,5651600,7.18 +2002-09-06,14.51,14.65,14.23,14.38,6485400,7.19 +2002-09-05,14.22,14.36,14.05,14.18,8077800,7.09 +2002-09-04,14.20,14.78,14.17,14.48,15023600,7.24 +2002-09-03,14.49,14.55,14.05,14.05,9890600,7.03 +2002-08-30,14.73,15.14,14.58,14.75,6911400,7.38 +2002-08-29,14.65,15.08,14.51,14.70,5863200,7.35 +2002-08-28,14.80,15.12,14.65,14.70,8856200,7.35 +2002-08-27,15.71,15.74,14.71,14.85,9365400,7.43 +2002-08-26,15.95,15.95,15.16,15.53,6784600,7.76 +2002-08-23,15.90,15.93,15.45,15.73,5830200,7.86 +2002-08-22,16.20,16.25,15.66,15.97,9225400,7.99 +2002-08-21,16.01,16.24,15.45,16.12,7229600,8.06 +2002-08-20,15.97,16.09,15.53,15.91,6665200,7.95 +2002-08-19,15.78,16.25,15.72,15.98,7734200,7.99 +2002-08-16,15.45,16.10,15.28,15.81,8758000,7.91 +2002-08-15,15.25,15.75,15.01,15.61,11502800,7.80 +2002-08-14,14.67,15.35,14.54,15.17,14253000,7.59 +2002-08-13,14.90,15.21,14.55,14.59,9638200,7.30 +2002-08-12,14.90,15.02,14.69,14.99,6420200,7.49 +2002-08-09,15.25,15.25,14.75,15.00,7347000,7.50 +2002-08-08,14.77,15.38,14.77,15.30,8119600,7.65 +2002-08-07,15.09,15.36,14.35,15.03,11909800,7.51 +2002-08-06,14.21,15.23,14.08,14.74,9716200,7.37 +2002-08-05,14.51,14.70,13.97,13.99,7286600,6.99 +2002-08-02,14.74,15.00,14.25,14.45,6395000,7.22 +2002-08-01,15.11,15.42,14.73,14.80,8177000,7.40 +2002-07-31,15.40,15.42,14.90,15.26,11096400,7.63 +2002-07-30,14.85,15.51,14.56,15.43,12672800,7.72 +2002-07-29,14.48,15.10,14.37,15.02,9820000,7.51 +2002-07-26,14.46,14.53,13.80,14.34,7418000,7.17 +2002-07-25,14.93,14.95,14.01,14.36,17119800,7.18 +2002-07-24,14.33,15.22,14.25,15.20,14521200,7.60 +2002-07-23,14.90,15.13,14.44,14.47,14281800,7.24 +2002-07-22,14.75,15.19,14.61,14.92,15389200,7.46 +2002-07-19,14.70,15.17,14.53,14.96,13757400,7.48 +2002-07-18,15.50,15.56,14.75,14.99,19980800,7.49 +2002-07-17,16.13,16.20,15.19,15.63,43410200,7.82 +2002-07-16,18.15,18.57,17.61,17.86,15956000,8.93 +2002-07-15,17.43,18.60,16.81,18.23,10571200,9.11 +2002-07-12,18.55,18.79,17.26,17.51,15839000,8.76 +2002-07-11,17.26,18.35,16.97,18.30,13345600,9.15 +2002-07-10,17.71,18.17,17.25,17.32,7388600,8.66 +2002-07-09,18.09,18.29,17.46,17.53,8098200,8.77 +2002-07-08,18.52,18.61,17.68,18.01,7543000,9.01 +2002-07-05,17.71,18.75,17.71,18.74,5773200,9.37 +2002-07-03,16.81,17.68,16.75,17.55,7108200,8.77 +2002-07-02,17.03,17.16,16.83,16.94,10899600,8.47 +2002-07-01,17.71,17.88,17.05,17.06,7953200,8.53 +2002-06-28,17.10,17.82,17.00,17.72,9637800,8.86 +2002-06-27,16.79,17.27,16.42,17.06,8987800,8.53 +2002-06-26,16.80,17.29,15.98,16.55,19962600,8.27 +2002-06-25,17.40,17.68,16.86,17.14,10757200,8.57 +2002-06-24,16.77,17.73,16.70,17.27,15426200,8.64 +2002-06-21,16.97,17.49,16.79,16.85,15899200,8.43 +2002-06-20,17.17,17.60,16.85,17.11,14165600,8.56 +2002-06-19,17.37,17.60,16.88,17.12,61052400,8.56 +2002-06-18,20.42,20.59,19.98,20.15,12620000,10.07 +2002-06-17,20.24,20.63,19.85,20.54,11593200,10.27 +2002-06-14,19.24,20.36,18.11,20.10,15175000,10.05 +2002-06-13,20.02,20.05,19.38,19.54,12574400,9.77 +2002-06-12,20.41,20.75,19.94,20.09,18882800,10.05 +2002-06-11,21.64,21.70,20.41,20.46,12482000,10.23 +2002-06-10,21.48,21.84,21.34,21.48,9913400,10.74 +2002-06-07,21.76,21.94,20.93,21.40,21870600,10.70 +2002-06-06,22.96,23.23,22.04,22.16,9285600,11.08 +2002-06-05,22.83,22.83,22.35,22.72,9895800,11.36 +2002-06-04,22.88,23.04,22.18,22.78,12422200,11.39 +2002-06-03,23.39,23.45,22.58,22.91,8396800,11.45 +2002-05-31,24.09,24.25,23.28,23.30,13053400,11.65 +2002-05-30,23.77,24.38,23.51,24.20,7013400,12.10 +2002-05-29,23.92,24.44,23.45,23.98,7921200,11.99 +2002-05-28,23.69,24.20,23.43,23.98,5347000,11.99 +2002-05-24,24.99,24.99,23.96,24.15,5934800,12.07 +2002-05-23,24.45,25.24,24.07,25.18,13192800,12.59 +2002-05-22,23.37,24.37,23.32,24.32,10388400,12.16 +2002-05-21,24.83,25.00,23.40,23.46,10035400,11.73 +2002-05-20,24.57,24.93,24.53,24.74,9639800,12.37 +2002-05-17,25.49,25.78,24.61,25.01,8446200,12.51 +2002-05-16,25.06,25.45,24.75,25.21,8109000,12.60 +2002-05-15,25.37,25.98,24.84,25.28,11993800,12.64 +2002-05-14,24.45,25.68,24.22,25.61,18803800,12.81 +2002-05-13,23.52,24.09,22.94,23.94,9486000,11.97 +2002-05-10,24.29,24.29,22.98,23.32,8407000,11.66 +2002-05-09,24.25,24.35,23.80,24.19,8022000,12.10 +2002-05-08,23.20,24.52,23.04,24.37,15595800,12.19 +2002-05-07,22.94,22.95,22.14,22.47,8669600,11.23 +2002-05-06,23.35,23.50,22.46,22.65,8916600,11.32 +2002-05-03,23.57,24.02,23.43,23.51,8242200,11.76 +2002-05-02,23.81,24.34,23.60,23.69,8548000,11.85 +2002-05-01,24.29,24.29,23.36,23.98,7668000,11.99 +2002-04-30,23.89,24.38,23.75,24.27,10034400,12.14 +2002-04-29,23.16,24.06,23.09,23.96,9724600,11.98 +2002-04-26,24.28,24.37,23.00,23.01,10892200,11.51 +2002-04-25,23.56,24.34,23.55,24.12,6935800,12.06 +2002-04-24,24.30,24.50,23.68,23.77,5016000,11.89 +2002-04-23,24.54,24.78,24.09,24.25,8338200,12.12 +2002-04-22,24.84,24.93,24.23,24.53,9622400,12.27 +2002-04-19,25.49,25.49,24.93,24.98,13407400,12.49 +2002-04-18,25.50,25.52,24.88,25.41,14346800,12.70 +2002-04-17,25.93,26.17,25.38,26.11,14151800,13.06 +2002-04-16,25.15,25.99,25.12,25.74,21949200,12.87 +2002-04-15,25.06,25.15,24.80,25.00,10691800,12.50 +2002-04-12,25.01,25.17,24.57,25.06,11437200,12.53 +2002-04-11,25.03,25.20,24.75,24.86,14544800,12.43 +2002-04-10,24.21,24.95,24.01,24.66,8035000,12.33 +2002-04-09,24.59,25.00,24.01,24.10,6840400,12.05 +2002-04-08,24.16,24.68,23.78,24.56,9339800,12.28 +2002-04-05,24.95,25.19,24.10,24.74,9941000,12.37 +2002-04-04,23.67,25.05,23.67,24.90,12089200,12.45 +2002-04-03,24.05,24.49,23.60,23.75,7661800,11.88 +2002-04-02,24.00,24.30,23.87,24.07,7278400,12.03 +2002-04-01,23.38,24.70,23.28,24.46,7108800,12.23 +2002-03-28,23.70,23.88,23.46,23.67,3873400,11.84 +2002-03-27,23.35,23.72,23.26,23.47,4560800,11.73 +2002-03-26,23.20,23.64,23.00,23.46,9208600,11.73 +2002-03-25,24.07,24.09,23.24,23.35,9386800,11.68 +2002-03-22,24.22,24.56,23.87,24.09,7221200,12.05 +2002-03-21,23.86,24.30,23.26,24.27,22012600,12.14 +2002-03-20,24.66,25.14,24.50,24.92,10511400,12.46 +2002-03-19,24.69,25.30,24.30,24.85,8655200,12.43 +2002-03-18,24.95,25.05,24.32,24.74,10877000,12.37 +2002-03-15,24.46,24.96,24.25,24.95,8603600,12.48 +2002-03-14,24.30,24.60,23.87,24.43,7760600,12.22 +2002-03-13,24.37,24.85,24.15,24.49,7170200,12.24 +2002-03-12,24.51,24.74,24.10,24.72,9073400,12.36 +2002-03-11,24.60,25.14,24.10,25.06,9385200,12.53 +2002-03-08,24.74,25.09,24.30,24.66,9634800,12.33 +2002-03-07,24.06,24.53,23.61,24.38,9223200,12.19 +2002-03-06,23.48,24.34,22.93,24.07,8078800,12.03 +2002-03-05,24.15,24.43,23.40,23.53,9810800,11.77 +2002-03-04,23.26,24.58,22.76,24.29,12437800,12.15 +2002-03-01,21.93,23.50,21.82,23.45,12464000,11.73 +2002-02-28,22.15,22.59,21.35,21.70,16319200,10.85 +2002-02-27,23.94,24.25,20.94,21.96,36791400,10.98 +2002-02-26,23.91,24.37,23.25,23.67,9290400,11.84 +2002-02-25,22.85,24.72,22.36,23.81,15244600,11.90 +2002-02-22,21.66,22.95,21.50,22.74,14517000,11.37 +2002-02-21,22.92,23.00,21.45,21.50,15955400,10.75 +2002-02-20,22.77,23.20,22.35,23.13,10194400,11.56 +2002-02-19,23.76,23.87,22.48,22.62,13937800,11.31 +2002-02-15,24.53,24.98,23.85,23.90,9292400,11.95 +2002-02-14,25.05,25.23,24.38,24.60,9291800,12.30 +2002-02-13,24.73,25.24,24.65,25.01,11174000,12.51 +2002-02-12,24.66,25.04,24.45,24.71,8010000,12.35 +2002-02-11,23.93,25.00,23.74,24.98,14235800,12.49 +2002-02-08,24.40,24.64,23.37,24.03,12690400,12.02 +2002-02-07,24.65,25.29,24.08,24.30,12422600,12.15 +2002-02-06,25.60,25.98,24.15,24.67,21342000,12.34 +2002-02-05,25.09,25.98,25.08,25.45,16317400,12.73 +2002-02-04,24.32,25.52,24.20,25.35,18656200,12.68 +2002-02-01,24.34,24.96,24.34,24.41,14225200,12.20 +2002-01-31,24.16,24.73,24.11,24.72,16730200,12.36 +2002-01-30,23.07,24.14,22.94,24.09,16842000,12.05 +2002-01-29,23.22,23.54,22.85,23.07,8583000,11.53 +2002-01-28,23.40,23.55,22.72,23.27,6658800,11.64 +2002-01-25,22.89,23.42,22.66,23.25,6639800,11.62 +2002-01-24,22.91,23.51,22.90,23.21,12285800,11.60 +2002-01-23,21.80,23.04,21.59,23.02,15831400,11.51 +2002-01-22,22.27,22.37,21.82,21.82,11689800,10.91 +2002-01-18,22.00,22.60,21.96,22.17,12100400,11.09 +2002-01-17,21.96,22.74,21.87,22.48,23592000,11.24 +2002-01-16,21.41,21.41,20.50,20.78,20246200,10.39 +2002-01-15,21.32,21.76,21.21,21.70,10368600,10.85 +2002-01-14,21.01,21.40,20.90,21.15,14857000,10.57 +2002-01-11,21.39,21.84,20.60,21.05,12457200,10.52 +2002-01-10,21.22,21.46,20.25,21.23,16169200,10.61 +2002-01-09,22.80,22.93,21.28,21.65,11708400,10.82 +2002-01-08,22.75,23.05,22.46,22.61,16072800,11.31 +2002-01-07,23.72,24.00,22.75,22.90,15878000,11.45 +2002-01-04,23.34,23.95,22.99,23.69,14642000,11.85 +2002-01-03,23.00,23.75,22.77,23.58,21857400,11.79 +2002-01-02,22.05,23.30,21.96,23.30,18910600,11.65 +2001-12-31,22.51,22.66,21.83,21.90,4920800,10.95 +2001-12-28,21.97,23.00,21.96,22.43,10683000,11.22 +2001-12-27,21.58,22.25,21.58,22.07,6839600,11.03 +2001-12-26,21.35,22.30,21.14,21.49,5228600,10.74 +2001-12-24,20.90,21.45,20.90,21.36,1808200,10.68 +2001-12-21,21.01,21.54,20.80,21.00,9154800,10.50 +2001-12-20,21.40,21.47,20.62,20.67,7888000,10.34 +2001-12-19,20.58,21.68,20.47,21.62,10355600,10.81 +2001-12-18,20.89,21.33,20.22,21.01,8401400,10.51 +2001-12-17,20.40,21.00,20.19,20.62,6204000,10.31 +2001-12-14,20.73,20.83,20.09,20.39,6781600,10.19 +2001-12-13,21.49,21.55,20.50,21.00,7065800,10.50 +2001-12-12,21.87,21.92,21.25,21.49,6873600,10.74 +2001-12-11,22.67,22.85,21.65,21.78,7338400,10.89 +2001-12-10,22.29,22.99,22.23,22.54,6071800,11.27 +2001-12-07,22.46,22.71,22.00,22.54,7268400,11.27 +2001-12-06,23.48,23.50,22.14,22.78,12104800,11.39 +2001-12-05,22.36,24.03,22.17,23.76,20306400,11.88 +2001-12-04,21.05,22.56,20.72,22.40,13586400,11.20 +2001-12-03,21.06,21.28,20.60,21.05,6470200,10.52 +2001-11-30,20.47,21.44,20.25,21.30,10854000,10.65 +2001-11-29,20.60,20.70,20.19,20.42,7241600,10.21 +2001-11-28,20.85,21.21,20.41,20.53,8950400,10.27 +2001-11-27,21.20,21.52,20.50,21.00,9591200,10.50 +2001-11-26,19.94,21.55,19.88,21.37,16453200,10.69 +2001-11-23,19.71,19.95,19.57,19.84,2143000,9.92 +2001-11-21,19.61,19.80,19.26,19.68,7199400,9.84 +2001-11-20,19.82,20.20,19.50,19.53,9878000,9.77 +2001-11-19,19.00,20.05,18.96,20.00,11878200,10.00 +2001-11-16,19.27,19.29,18.40,18.97,8238000,9.48 +2001-11-15,19.45,19.90,19.23,19.45,7608200,9.73 +2001-11-14,19.59,19.90,19.15,19.61,7898200,9.81 +2001-11-13,19.08,19.39,18.71,19.37,8024000,9.69 +2001-11-12,18.66,19.17,17.96,18.75,7196400,9.38 +2001-11-09,18.60,19.25,18.55,18.71,4796200,9.35 +2001-11-08,19.63,19.89,18.57,18.71,12219400,9.35 +2001-11-07,19.46,20.13,19.33,19.59,13678200,9.80 +2001-11-06,18.96,19.62,18.53,19.57,11286400,9.78 +2001-11-05,18.84,19.25,18.61,19.07,8421200,9.53 +2001-11-02,18.52,18.86,18.16,18.57,7043000,9.28 +2001-11-01,17.65,18.78,17.25,18.59,11178400,9.30 +2001-10-31,17.73,18.40,17.44,17.56,9776800,8.78 +2001-10-30,17.38,18.00,17.06,17.60,9884400,8.80 +2001-10-29,18.57,18.67,17.60,17.63,8542200,8.81 +2001-10-26,18.86,19.25,18.62,18.67,9963000,9.34 +2001-10-25,18.44,19.25,18.16,19.19,9105400,9.60 +2001-10-24,18.06,19.09,17.75,18.95,13372400,9.48 +2001-10-23,19.12,19.42,17.87,18.14,24463600,9.07 +2001-10-22,18.21,19.07,18.09,19.02,13997800,9.51 +2001-10-19,17.94,18.40,17.88,18.30,5956800,9.15 +2001-10-18,17.29,18.23,17.29,18.00,21877600,9.00 +2001-10-17,18.34,18.41,16.96,16.99,10197800,8.49 +2001-10-16,18.09,18.20,17.77,18.01,7248200,9.01 +2001-10-15,17.95,18.38,17.95,17.99,11384000,8.99 +2001-10-12,17.31,18.08,16.86,18.01,10279000,9.01 +2001-10-11,16.92,17.74,16.85,17.74,11934400,8.87 +2001-10-10,16.10,16.85,15.95,16.82,10991400,8.41 +2001-10-09,16.05,16.20,15.63,16.00,6215200,8.00 +2001-10-08,15.57,16.35,15.50,16.20,7428000,8.10 +2001-10-05,15.40,16.15,14.99,16.14,12238800,8.07 +2001-10-04,15.35,16.25,14.99,15.88,14325800,7.94 +2001-10-03,14.95,15.36,14.83,14.98,24394400,7.49 +2001-10-02,15.43,15.83,14.88,15.05,8424400,7.53 +2001-10-01,15.49,15.99,15.23,15.54,7436000,7.77 +2001-09-28,15.71,15.91,15.39,15.51,13039600,7.76 +2001-09-27,15.25,15.75,15.20,15.51,11508600,7.76 +2001-09-26,15.81,15.89,14.93,15.15,17635600,7.57 +2001-09-25,16.14,16.22,15.35,15.54,13371600,7.77 +2001-09-24,16.11,16.84,15.95,16.45,10519200,8.23 +2001-09-21,14.80,16.25,14.68,15.73,20375600,7.86 +2001-09-20,16.29,16.95,15.50,15.68,14684800,7.84 +2001-09-19,16.50,17.10,15.60,17.02,13332800,8.51 +2001-09-18,16.90,17.72,16.17,16.28,11682200,8.14 +2001-09-17,16.00,17.07,15.73,16.99,16357400,8.49 +2001-09-10,17.00,17.50,16.92,17.37,11030200,8.69 +2001-09-07,17.50,18.10,17.20,17.28,8636800,8.64 +2001-09-06,18.40,18.93,17.65,17.72,10084600,8.86 +2001-09-05,18.24,18.95,18.12,18.55,12859200,9.27 +2001-09-04,18.50,19.08,18.18,18.25,12436200,9.12 +2001-08-31,17.73,18.60,17.65,18.55,7746600,9.27 +2001-08-30,17.74,18.18,17.28,17.83,13167600,8.91 +2001-08-29,18.44,18.83,17.83,17.83,8570400,8.91 +2001-08-28,18.90,19.14,18.40,18.40,6133400,9.20 +2001-08-27,18.60,19.30,18.16,18.92,6273000,9.46 +2001-08-24,18.00,18.62,17.65,18.57,10369000,9.28 +2001-08-23,18.20,18.34,17.58,17.81,7752800,8.90 +2001-08-22,17.94,18.25,17.61,18.21,6213400,9.10 +2001-08-21,18.14,18.14,17.70,17.92,6632200,8.96 +2001-08-20,18.14,18.23,17.81,18.12,9010800,9.06 +2001-08-17,18.00,18.45,17.99,18.07,7443800,9.03 +2001-08-16,18.27,18.75,17.97,18.65,10289000,9.32 +2001-08-15,18.76,18.94,18.20,18.44,10331400,9.22 +2001-08-14,19.20,19.36,18.67,18.73,8176800,9.36 +2001-08-13,19.10,19.33,18.76,19.09,5285600,9.55 +2001-08-10,19.04,19.32,18.59,19.02,6677200,9.51 +2001-08-09,18.96,19.15,18.72,19.05,7166600,9.52 +2001-08-08,19.26,19.70,18.54,18.90,9863200,9.45 +2001-08-07,19.33,19.67,18.98,19.25,6019600,9.62 +2001-08-06,19.04,19.66,19.00,19.13,3559000,9.56 +2001-08-03,19.89,19.90,19.00,19.50,6644800,9.75 +2001-08-02,19.65,19.87,19.26,19.82,9003200,9.91 +2001-08-01,19.01,19.78,18.95,19.06,10862000,9.53 +2001-07-31,19.27,19.42,18.51,18.79,8393800,9.40 +2001-07-30,19.12,19.36,18.51,18.93,8691400,9.47 +2001-07-27,18.75,19.25,18.50,18.96,11933400,9.48 +2001-07-26,18.48,18.80,17.85,18.59,13183600,9.30 +2001-07-25,19.12,19.30,17.97,18.47,15852800,9.23 +2001-07-24,19.39,19.92,18.73,19.09,12442000,9.55 +2001-07-23,20.09,20.50,19.51,19.54,8620000,9.77 +2001-07-20,19.70,20.06,19.49,19.98,15878000,9.99 +2001-07-19,21.23,21.42,19.75,19.96,30755000,9.98 +2001-07-18,21.78,22.78,20.42,20.79,40607600,10.40 +2001-07-17,23.98,25.22,23.01,25.10,23136800,12.55 +2001-07-16,24.88,25.10,23.91,23.96,9952400,11.98 +2001-07-13,24.13,25.01,23.84,24.85,16240800,12.43 +2001-07-12,23.30,24.81,23.30,24.36,21957200,12.18 +2001-07-11,21.03,22.55,21.00,22.54,16803800,11.27 +2001-07-10,22.95,23.07,20.84,21.14,14116800,10.57 +2001-07-09,22.09,23.00,21.68,22.70,12052400,11.35 +2001-07-06,22.76,22.96,21.72,22.03,10818600,11.02 +2001-07-05,23.60,23.77,23.01,23.19,5439000,11.60 +2001-07-03,23.51,24.18,23.50,23.84,4019400,11.92 +2001-07-02,23.64,24.23,23.14,23.90,8216000,11.95 +2001-06-29,23.66,25.10,23.20,23.25,18406800,11.62 +2001-06-28,23.05,23.91,22.94,23.54,12443200,11.77 +2001-06-27,23.83,24.00,22.50,23.34,13361800,11.67 +2001-06-26,23.34,23.77,23.01,23.75,9742200,11.88 +2001-06-25,22.50,24.00,22.45,23.99,15698200,11.99 +2001-06-22,22.48,23.00,21.76,22.26,10215200,11.13 +2001-06-21,21.55,23.00,21.10,22.49,12190400,11.24 +2001-06-20,20.00,21.85,19.98,21.67,15415000,10.84 +2001-06-19,20.85,21.40,20.01,20.19,11467400,10.10 +2001-06-18,20.41,20.85,20.00,20.33,12354000,10.16 +2001-06-15,20.10,20.75,19.35,20.44,16236600,10.22 +2001-06-14,20.04,20.45,19.77,19.88,10619600,9.94 +2001-06-13,21.42,21.73,20.06,20.47,18267400,10.23 +2001-06-12,19.77,20.69,19.76,20.31,10849800,10.15 +2001-06-11,21.05,21.07,19.95,20.04,10500000,10.02 +2001-06-08,21.65,21.65,20.71,21.32,12236600,10.66 +2001-06-07,20.71,21.70,20.45,21.66,11613600,10.83 +2001-06-06,20.93,20.93,20.33,20.73,7970600,10.36 +2001-06-05,20.80,21.10,20.35,20.94,16849800,10.47 +2001-06-04,21.08,21.11,20.46,20.66,10068600,10.33 +2001-06-01,20.13,21.09,19.98,20.89,16288400,10.44 +2001-05-31,19.80,20.24,19.49,19.95,15817600,9.98 +2001-05-30,20.76,20.76,19.30,19.78,27752800,9.89 +2001-05-29,22.32,22.50,20.81,21.47,18428200,10.73 +2001-05-25,23.20,23.29,22.50,22.76,5669400,11.38 +2001-05-24,23.29,23.30,22.62,23.20,9705600,11.60 +2001-05-23,23.75,23.75,22.86,23.23,10037200,11.61 +2001-05-22,24.00,24.13,23.40,23.50,14747000,11.75 +2001-05-21,23.63,23.91,23.05,23.56,16464200,11.78 +2001-05-18,23.36,23.64,23.12,23.53,5680400,11.77 +2001-05-17,24.23,24.33,23.25,23.55,11861400,11.77 +2001-05-16,23.26,24.50,22.85,24.10,11511800,12.05 +2001-05-15,23.37,25.50,23.04,23.18,8465200,11.59 +2001-05-14,22.89,23.68,22.75,23.29,11043600,11.65 +2001-05-11,23.01,23.49,22.76,22.85,7251600,11.43 +2001-05-10,24.21,24.50,22.95,23.00,10320600,11.50 +2001-05-09,24.14,24.55,23.67,23.98,11603200,11.99 +2001-05-08,25.35,25.45,23.95,24.57,11265600,12.28 +2001-05-07,25.62,25.76,24.84,24.96,9876800,12.48 +2001-05-04,24.24,25.85,23.96,25.75,10037600,12.88 +2001-05-03,25.97,26.25,24.73,24.96,10769400,12.48 +2001-05-02,26.34,26.70,25.76,26.59,13161600,13.30 +2001-05-01,25.41,26.50,25.20,25.93,15259000,12.97 +2001-04-30,26.70,27.12,24.87,25.49,17670600,12.74 +2001-04-27,25.20,26.29,24.75,26.20,16179000,13.10 +2001-04-26,25.17,26.10,24.68,24.69,28560600,12.35 +2001-04-25,24.21,24.86,23.57,24.72,11813600,12.36 +2001-04-24,24.33,24.75,23.51,24.03,13469200,12.02 +2001-04-23,24.34,25.00,24.00,24.25,19340200,12.12 +2001-04-20,24.93,25.63,24.60,25.04,24764400,12.52 +2001-04-19,25.55,25.75,23.60,25.72,66916800,12.86 +2001-04-18,21.57,24.08,21.08,22.79,39315800,11.40 +2001-04-17,21.20,21.21,19.60,20.40,24471400,10.20 +2001-04-16,22.09,22.40,20.86,21.44,10186600,10.72 +2001-04-12,21.42,23.02,21.15,22.42,10676200,11.21 +2001-04-11,22.98,23.00,21.28,21.80,11932000,10.90 +2001-04-10,20.90,22.70,20.78,22.04,16334800,11.02 +2001-04-09,20.69,21.34,20.06,20.54,9520800,10.27 +2001-04-06,20.80,21.04,19.90,20.59,11603200,10.30 +2001-04-05,20.60,22.50,20.00,20.87,15955800,10.44 +2001-04-04,19.76,20.25,18.75,19.50,24481600,9.75 +2001-04-03,21.36,21.40,20.13,20.24,13167400,10.12 +2001-04-02,22.09,22.66,21.40,21.59,12175400,10.80 +2001-03-30,22.55,22.72,21.34,22.07,14298200,11.03 +2001-03-29,21.77,23.45,21.50,22.53,21895200,11.27 +2001-03-28,22.08,22.50,21.50,22.17,20880800,11.09 +2001-03-27,21.94,23.05,21.90,22.87,19422200,11.44 +2001-03-26,23.13,23.75,21.13,21.78,26230400,10.89 +2001-03-23,22.06,23.56,22.00,23.00,33749400,11.50 +2001-03-22,20.37,21.75,20.19,21.62,25839000,10.81 +2001-03-21,19.78,20.87,19.37,20.12,13265400,10.06 +2001-03-20,20.72,20.94,19.69,19.69,17833800,9.85 +2001-03-19,19.75,20.62,19.50,20.56,12722800,10.28 +2001-03-16,19.00,20.31,18.87,19.62,16806600,9.81 +2001-03-15,20.87,21.37,19.69,19.69,18906600,9.85 +2001-03-14,18.50,20.50,18.44,20.44,17065400,10.22 +2001-03-13,18.87,19.56,18.19,19.56,15840600,9.78 +2001-03-12,19.69,19.87,18.12,18.62,13967800,9.31 +2001-03-09,20.62,20.69,20.00,20.25,10685400,10.12 +2001-03-08,20.69,21.12,20.44,20.81,7325600,10.40 +2001-03-07,21.31,21.62,20.75,21.25,14985600,10.62 +2001-03-06,20.72,22.06,20.69,21.50,26144600,10.75 +2001-03-05,19.37,20.50,19.25,20.37,11587600,10.19 +2001-03-02,18.31,20.44,18.25,19.25,14511200,9.62 +2001-03-01,17.81,18.75,17.19,18.75,11803400,9.38 +2001-02-28,19.37,19.44,18.12,18.25,18157600,9.12 +2001-02-27,19.28,19.44,18.69,19.37,12451000,9.69 +2001-02-26,19.06,19.69,18.56,19.50,7380000,9.75 +2001-02-23,18.62,18.87,18.25,18.81,10503800,9.40 +2001-02-22,19.06,19.37,18.00,18.81,15431200,9.40 +2001-02-21,18.25,19.94,18.25,18.87,13947800,9.44 +2001-02-20,19.19,19.44,18.19,18.31,11249600,9.15 +2001-02-16,19.00,19.50,18.75,19.00,9428400,9.50 +2001-02-15,19.69,20.56,19.69,20.06,11123200,10.03 +2001-02-14,19.19,19.62,18.50,19.50,11040000,9.75 +2001-02-13,19.94,20.44,19.00,19.12,8470600,9.56 +2001-02-12,19.06,20.00,18.81,19.69,9795600,9.85 +2001-02-09,20.50,20.81,18.69,19.12,21082600,9.56 +2001-02-08,20.56,21.06,20.19,20.75,21585000,10.38 +2001-02-07,20.66,20.87,19.81,20.75,14071600,10.38 +2001-02-06,20.16,21.39,20.00,21.12,16528400,10.56 +2001-02-05,20.50,20.56,19.75,20.19,10228800,10.10 +2001-02-02,21.12,21.94,20.50,20.62,15263400,10.31 +2001-02-01,20.69,21.50,20.50,21.12,13205400,10.56 +2001-01-31,21.50,22.50,21.44,21.62,26106000,10.81 +2001-01-30,21.56,22.00,20.87,21.75,24734600,10.88 +2001-01-29,19.56,21.75,19.56,21.69,30562800,10.85 +2001-01-26,19.50,19.81,19.06,19.56,17245600,9.78 +2001-01-25,20.56,20.56,19.75,19.94,17495000,9.97 +2001-01-24,20.62,20.69,19.56,20.50,25616200,10.25 +2001-01-23,19.31,20.94,19.06,20.50,31418400,10.25 +2001-01-22,19.06,19.62,18.44,19.25,18551600,9.62 +2001-01-19,19.44,19.56,18.69,19.50,27748200,9.75 +2001-01-18,17.81,18.75,17.62,18.69,43822800,9.35 +2001-01-17,17.56,17.56,16.50,16.81,30037600,8.40 +2001-01-16,17.44,18.25,17.00,17.12,10940000,8.56 +2001-01-12,17.87,18.00,17.06,17.19,15121000,8.60 +2001-01-11,16.25,18.50,16.25,18.00,28707600,9.00 +2001-01-10,16.69,17.00,16.06,16.56,20743400,8.28 +2001-01-09,16.81,17.64,16.56,17.19,21040600,8.60 +2001-01-08,16.94,16.98,15.94,16.56,13350000,8.28 +2001-01-05,16.94,17.37,16.06,16.37,14731000,8.19 +2001-01-04,18.14,18.50,16.81,17.06,26411000,8.53 +2001-01-03,14.50,16.69,14.44,16.37,29181800,8.19 +2001-01-02,14.88,15.25,14.56,14.88,16161800,7.44 +2000-12-29,14.69,15.00,14.50,14.88,22518800,7.44 +2000-12-28,14.38,14.94,14.31,14.81,10910000,7.41 +2000-12-27,14.34,14.81,14.19,14.81,11626000,7.41 +2000-12-26,14.88,15.00,14.25,14.69,7745400,7.34 +2000-12-22,14.13,15.00,14.13,15.00,11369600,7.50 +2000-12-21,14.25,15.00,13.88,14.06,13102600,7.03 +2000-12-20,13.78,14.63,13.63,14.38,20196200,7.19 +2000-12-19,14.38,15.25,14.00,14.00,13367200,7.00 +2000-12-18,14.56,14.63,13.94,14.25,11645000,7.12 +2000-12-15,14.56,14.69,14.00,14.06,18363800,7.03 +2000-12-14,15.03,15.25,14.44,14.44,9406600,7.22 +2000-12-13,15.56,15.56,14.88,15.00,12327200,7.50 +2000-12-12,15.25,16.00,15.00,15.38,13803400,7.69 +2000-12-11,15.19,15.38,14.88,15.19,11884000,7.59 +2000-12-08,14.81,15.31,14.44,15.06,15568200,7.53 +2000-12-07,14.44,14.88,14.00,14.31,14606600,7.16 +2000-12-06,14.63,15.00,14.00,14.31,49092400,7.16 +2000-12-05,16.94,17.44,16.37,17.00,21932200,8.50 +2000-12-04,17.19,17.19,16.44,16.69,13273400,8.35 +2000-12-01,17.00,17.50,16.81,17.06,13783800,8.53 +2000-11-30,16.69,17.00,16.12,16.50,28922200,8.25 +2000-11-29,18.09,18.31,17.25,17.56,17586200,8.78 +2000-11-28,18.69,19.00,17.94,18.03,9618200,9.02 +2000-11-27,19.87,19.94,18.50,18.69,9244000,9.35 +2000-11-24,18.86,19.50,18.81,19.31,5751800,9.65 +2000-11-22,18.81,19.12,18.37,18.50,10029600,9.25 +2000-11-21,19.19,19.50,18.75,18.81,10786200,9.40 +2000-11-20,18.59,19.50,18.25,18.94,14581600,9.47 +2000-11-17,19.19,19.25,18.25,18.50,15943400,9.25 +2000-11-16,19.50,19.81,18.87,19.00,8554000,9.50 +2000-11-15,20.03,20.19,19.25,19.87,10086600,9.94 +2000-11-14,19.94,20.50,19.56,20.25,14611200,10.12 +2000-11-13,18.75,20.00,18.25,19.37,15423200,9.69 +2000-11-10,19.36,19.87,19.06,19.06,15080600,9.53 +2000-11-09,19.87,20.50,19.06,20.19,17035400,10.10 +2000-11-08,21.37,21.44,19.81,20.06,15082800,10.03 +2000-11-07,21.50,21.81,20.81,21.31,10786800,10.65 +2000-11-06,22.44,22.62,20.87,21.44,14060000,10.72 +2000-11-03,23.00,23.00,21.94,22.25,18423400,11.12 +2000-11-02,21.12,22.44,21.06,22.31,21105400,11.15 +2000-11-01,19.44,20.87,19.44,20.50,20553800,10.25 +2000-10-31,19.75,20.25,19.25,19.56,31649000,9.78 +2000-10-30,19.12,19.94,18.75,19.31,22832800,9.65 +2000-10-27,18.87,19.19,17.87,18.56,26594600,9.28 +2000-10-26,18.81,18.87,17.50,18.50,25780600,9.25 +2000-10-25,19.06,19.19,18.44,18.50,23720600,9.25 +2000-10-24,20.69,20.87,18.81,18.87,28736200,9.44 +2000-10-23,20.27,20.56,19.44,20.37,19694000,10.19 +2000-10-20,19.06,20.37,18.94,19.50,28270400,9.75 +2000-10-19,19.16,19.81,18.31,18.94,53818200,9.47 +2000-10-18,19.44,21.06,18.75,20.12,29803800,10.06 +2000-10-17,21.69,21.94,19.69,20.12,21495600,10.06 +2000-10-16,22.31,23.25,21.37,21.50,29298800,10.75 +2000-10-13,20.25,22.12,20.00,22.06,44564000,11.03 +2000-10-12,20.31,20.81,19.50,20.00,42548200,10.00 +2000-10-11,20.12,21.00,19.12,19.62,42801200,9.81 +2000-10-10,21.62,22.44,20.50,20.87,24683400,10.44 +2000-10-09,22.62,22.87,21.12,21.75,21342600,10.88 +2000-10-06,22.69,22.94,21.00,22.19,21881000,11.10 +2000-10-05,23.50,24.50,22.00,22.06,31189400,11.03 +2000-10-04,22.37,23.75,21.87,23.62,52368200,11.81 +2000-10-03,24.94,25.00,22.19,22.31,72795600,11.15 +2000-10-02,26.69,26.75,23.50,24.25,86610600,12.12 +2000-09-29,28.19,29.00,25.37,25.75,265069000,12.88 +2000-09-28,49.31,53.81,48.13,53.50,34988200,26.75 +2000-09-27,51.75,52.75,48.25,48.94,14370000,24.47 +2000-09-26,53.31,54.75,51.38,51.44,10396600,25.72 +2000-09-25,52.75,55.50,52.06,53.50,15564000,26.75 +2000-09-22,50.31,52.44,50.00,52.19,25961200,26.09 +2000-09-21,58.50,59.63,55.25,56.69,18238400,28.34 +2000-09-20,59.41,61.44,58.56,61.05,8121600,30.52 +2000-09-19,59.75,60.50,58.56,59.94,9706200,29.97 +2000-09-18,55.25,60.75,55.06,60.66,15163200,30.33 +2000-09-15,57.75,58.19,54.25,55.23,14095400,27.61 +2000-09-14,58.56,59.63,56.81,56.86,15241800,28.43 +2000-09-13,56.75,59.50,56.75,58.00,10932600,29.00 +2000-09-12,57.34,60.06,57.00,57.75,6722200,28.88 +2000-09-11,58.69,60.38,58.13,58.44,6699000,29.22 +2000-09-08,61.63,61.63,58.50,58.88,6984400,29.44 +2000-09-07,59.13,62.56,58.25,62.00,7770400,31.00 +2000-09-06,61.38,62.38,57.75,58.44,12700400,29.22 +2000-09-05,62.66,64.12,62.25,62.44,10669000,31.22 +2000-09-01,61.31,63.63,61.13,63.44,9181800,31.72 +2000-08-31,58.97,61.50,58.94,60.94,14988800,30.47 +2000-08-30,59.00,60.00,58.70,59.50,10199600,29.75 +2000-08-29,57.88,59.44,57.69,59.19,9546200,29.59 +2000-08-28,57.25,59.00,57.06,58.06,12822600,29.03 +2000-08-25,56.50,57.50,56.38,56.81,11947800,28.41 +2000-08-24,54.67,56.63,53.38,56.11,11109400,28.06 +2000-08-23,51.47,54.75,51.06,54.31,8470400,27.16 +2000-08-22,50.63,52.81,50.38,51.69,9889000,25.84 +2000-08-21,50.25,51.56,49.63,50.50,4803800,25.25 +2000-08-18,51.38,51.81,49.88,50.00,6798800,25.00 +2000-08-17,48.38,52.44,48.31,51.44,9683400,25.72 +2000-08-16,46.88,49.00,46.81,48.50,5137600,24.25 +2000-08-15,47.25,47.94,46.50,46.69,4089000,23.34 +2000-08-14,47.59,47.69,46.31,47.06,5603400,23.53 +2000-08-11,46.84,48.00,45.56,47.69,8503200,23.84 +2000-08-10,48.00,48.44,47.38,47.56,8995400,23.78 +2000-08-09,48.13,48.44,47.25,47.50,13569000,23.75 +2000-08-08,47.94,48.00,46.31,46.75,6315400,23.38 +2000-08-07,47.88,49.06,47.19,47.94,6697200,23.97 +2000-08-04,49.47,51.25,46.31,47.38,9406800,23.69 +2000-08-03,45.56,48.06,44.25,48.00,12150000,24.00 +2000-08-02,49.00,49.94,47.19,47.25,5808800,23.62 +2000-08-01,50.31,51.16,49.25,49.31,4904600,24.66 +2000-07-31,49.16,51.63,48.75,50.81,5550000,25.41 +2000-07-28,52.28,52.50,46.88,48.31,8505400,24.16 +2000-07-27,50.00,53.25,49.88,52.00,10543800,26.00 +2000-07-26,49.84,51.25,49.25,50.06,7526200,25.03 +2000-07-25,50.31,50.63,49.06,50.06,7567200,25.03 +2000-07-24,52.56,52.88,47.50,48.69,14720600,24.34 +2000-07-21,54.36,55.63,52.94,53.56,7013200,26.78 +2000-07-20,55.00,57.06,54.13,55.13,16631800,27.57 +2000-07-19,55.19,56.81,51.75,52.69,16359600,26.34 +2000-07-18,58.50,58.88,56.88,57.25,11378200,28.62 +2000-07-17,58.25,58.81,57.13,58.31,9289000,29.16 +2000-07-14,57.13,59.00,56.88,57.69,6804400,28.84 +2000-07-13,58.50,60.63,54.75,56.50,15925600,28.25 +2000-07-12,58.13,58.94,56.38,58.88,8057600,29.44 +2000-07-11,57.00,59.25,55.44,56.94,12783200,28.47 +2000-07-10,54.09,58.25,53.75,57.13,14211000,28.57 +2000-07-07,52.59,54.81,52.13,54.44,9422600,27.22 +2000-07-06,52.50,52.94,49.63,51.81,11063800,25.91 +2000-07-05,53.25,55.19,50.75,51.63,9478800,25.82 +2000-07-03,52.13,54.31,52.13,53.31,2535000,26.66 +2000-06-30,52.81,54.94,51.69,52.38,11550000,26.19 +2000-06-29,53.06,53.94,51.06,51.25,7281200,25.62 +2000-06-28,53.31,55.38,51.50,54.44,10235000,27.22 +2000-06-27,53.78,55.50,51.63,51.75,7270600,25.88 +2000-06-26,52.50,54.75,52.13,54.13,6631000,27.07 +2000-06-23,53.78,54.63,50.81,51.69,7320400,25.84 +2000-06-22,55.75,57.63,53.56,53.75,16706200,26.88 +2000-06-21,50.50,56.94,50.31,55.63,17500000,27.82 +2000-06-20,98.50,103.94,98.37,101.25,17922000,25.31 +2000-06-19,90.56,97.87,89.81,96.62,14089200,24.16 +2000-06-16,93.50,93.75,89.06,91.19,10842400,22.80 +2000-06-15,91.25,93.37,89.00,92.37,8898800,23.09 +2000-06-14,94.69,96.25,90.12,90.44,9925200,22.61 +2000-06-13,91.19,94.69,88.19,94.50,12570000,23.62 +2000-06-12,96.37,96.44,90.87,91.19,10374400,22.80 +2000-06-09,96.75,97.94,94.37,95.75,9020000,23.94 +2000-06-08,97.62,98.50,93.12,94.81,8540800,23.70 +2000-06-07,93.62,97.00,91.62,96.56,12056800,24.14 +2000-06-06,91.97,96.75,90.31,92.87,18771200,23.22 +2000-06-05,93.31,95.25,89.69,91.31,11582000,22.83 +2000-06-02,93.75,99.75,89.00,92.56,28336400,23.14 +2000-06-01,81.75,89.56,80.37,89.12,32280000,22.28 +2000-05-31,86.87,91.25,83.81,84.00,15483600,21.00 +2000-05-30,87.62,88.12,81.75,87.56,25481200,21.89 +2000-05-26,88.00,89.87,85.25,86.37,6486400,21.59 +2000-05-25,88.50,92.66,86.00,87.27,14530800,21.82 +2000-05-24,86.19,89.75,83.00,87.69,24248000,21.92 +2000-05-23,90.50,93.37,85.62,85.81,18488000,21.45 +2000-05-22,93.75,93.75,86.00,89.94,26995200,22.49 +2000-05-19,99.25,99.25,93.37,94.00,26459200,23.50 +2000-05-18,103.00,104.94,100.62,100.75,13365600,25.19 +2000-05-17,103.62,103.69,100.37,101.37,14227600,25.34 +2000-05-16,104.52,109.06,102.75,105.69,15736400,26.42 +2000-05-15,108.06,108.06,100.12,101.00,24252000,25.25 +2000-05-12,106.00,110.50,104.77,107.62,10962000,26.91 +2000-05-11,101.37,104.25,99.00,102.81,17852400,25.70 +2000-05-10,104.06,105.00,98.75,99.31,19127600,24.83 +2000-05-09,110.31,111.25,104.87,105.44,11685600,26.36 +2000-05-08,112.09,113.69,110.00,110.12,6605600,27.53 +2000-05-05,110.81,114.75,110.72,113.12,10160000,28.28 +2000-05-04,115.12,115.25,110.56,110.69,14284400,27.67 +2000-05-03,118.94,121.25,111.62,115.06,17500000,28.76 +2000-05-02,123.25,126.25,117.50,117.87,8446400,29.47 +2000-05-01,124.87,125.12,121.87,124.31,8100000,31.08 +2000-04-28,127.12,127.50,121.31,124.06,8932400,31.01 +2000-04-27,117.19,127.00,116.58,126.75,11678000,31.69 +2000-04-26,126.62,128.00,120.00,121.31,13117600,30.33 +2000-04-25,122.12,128.75,122.06,128.31,14002400,32.08 +2000-04-24,115.00,120.50,114.75,120.50,15845600,30.12 +2000-04-20,123.69,124.75,117.06,118.87,25806800,29.72 +2000-04-19,126.19,130.25,119.75,121.12,18586400,30.28 +2000-04-18,123.50,126.87,119.37,126.87,13962400,31.72 +2000-04-17,109.50,123.94,109.06,123.87,14642400,30.97 +2000-04-14,109.31,118.00,109.00,111.87,23845600,27.97 +2000-04-13,111.50,120.00,108.50,113.81,18923600,28.45 +2000-04-12,119.00,119.00,104.87,109.25,33618800,27.31 +2000-04-11,123.50,124.87,118.06,119.44,19368000,29.86 +2000-04-10,131.69,132.75,124.75,125.00,7592400,31.25 +2000-04-07,127.25,131.88,125.50,131.75,8668800,32.94 +2000-04-06,130.63,134.50,123.25,125.19,9290800,31.30 +2000-04-05,126.47,132.88,124.00,130.38,16359200,32.60 +2000-04-04,132.63,133.00,116.75,127.31,23596400,31.83 +2000-04-03,135.50,139.50,129.44,133.31,11742400,33.33 +2000-03-31,127.44,137.25,126.00,135.81,14457600,33.95 +2000-03-30,133.56,137.69,125.44,125.75,14800000,31.44 +2000-03-29,139.38,139.44,133.83,135.94,8568800,33.99 +2000-03-28,137.25,142.00,137.13,139.13,7253600,34.78 +2000-03-27,137.63,144.75,136.88,139.56,9976800,34.89 +2000-03-24,142.44,143.94,135.50,138.69,15962000,34.67 +2000-03-23,142.00,150.38,140.00,141.31,20098000,35.33 +2000-03-22,132.78,144.38,131.56,144.19,20288800,36.05 +2000-03-21,122.56,136.75,121.62,134.94,18729200,33.74 +2000-03-20,123.50,126.25,122.37,123.00,7316400,30.75 +2000-03-17,120.12,125.00,119.62,125.00,10902400,31.25 +2000-03-16,117.31,122.00,114.50,121.56,13516800,30.39 +2000-03-15,115.62,120.25,114.12,116.25,15845200,29.06 +2000-03-14,121.22,124.25,114.00,114.25,15321200,28.56 +2000-03-13,122.12,126.50,119.50,121.31,10864400,30.33 +2000-03-10,121.69,127.94,121.00,125.75,8900800,31.44 +2000-03-09,120.87,125.00,118.25,122.25,9884400,30.56 +2000-03-08,122.87,123.94,118.56,122.00,9690800,30.50 +2000-03-07,126.44,127.44,121.12,122.87,9767600,30.72 +2000-03-06,126.00,129.13,125.00,125.69,7520000,31.42 +2000-03-03,124.87,128.23,120.00,128.00,11565200,32.00 +2000-03-02,127.00,127.94,120.69,122.00,11136800,30.50 +2000-03-01,118.56,132.06,118.50,130.31,38478000,32.58 +2000-02-29,113.56,117.25,112.56,114.62,13186800,28.66 +2000-02-28,110.12,115.00,108.37,113.25,11729200,28.31 +2000-02-25,114.81,117.00,110.12,110.37,8908000,27.59 +2000-02-24,117.31,119.12,111.75,115.20,13446400,28.80 +2000-02-23,113.23,119.00,111.00,116.25,16905600,29.06 +2000-02-22,110.12,116.94,106.69,113.81,15083200,28.45 +2000-02-18,114.62,115.37,110.87,111.25,8346800,27.81 +2000-02-17,115.19,115.50,113.12,114.87,10350000,28.72 +2000-02-16,117.75,118.12,112.12,114.12,13525200,28.53 +2000-02-15,115.25,119.94,115.19,119.00,17363600,29.75 +2000-02-14,109.31,115.87,108.62,115.81,13130000,28.95 +2000-02-11,113.62,114.12,108.25,108.75,7592000,27.19 +2000-02-10,112.87,113.87,110.00,113.50,10832400,28.38 +2000-02-09,114.12,117.12,112.44,112.62,10698000,28.16 +2000-02-08,114.00,116.12,111.25,114.87,14613600,28.72 +2000-02-07,108.00,114.25,105.94,114.06,15770800,28.51 +2000-02-04,103.94,110.00,103.62,108.00,15206800,27.00 +2000-02-03,100.31,104.25,100.25,103.31,16977600,25.83 +2000-02-02,100.75,102.12,97.00,98.81,16588800,24.70 +2000-02-01,104.00,105.00,100.00,100.25,11380000,25.06 +2000-01-31,101.00,103.87,94.50,103.75,25071200,25.94 +2000-01-28,108.19,110.87,100.62,101.62,15142000,25.41 +2000-01-27,108.81,113.00,107.00,110.00,12163600,27.50 +2000-01-26,110.00,114.19,109.75,110.19,13131200,27.55 +2000-01-25,105.00,113.12,102.37,112.25,17775200,28.06 +2000-01-24,108.44,112.75,105.12,106.25,15760000,26.56 +2000-01-21,114.25,114.25,110.19,111.31,17729200,27.83 +2000-01-20,115.50,121.50,113.50,113.50,65418800,28.38 +2000-01-19,105.62,108.75,103.37,106.56,21358000,26.64 +2000-01-18,101.00,106.00,100.44,103.94,16421200,25.99 +2000-01-14,100.00,102.25,99.37,100.44,13954400,25.11 +2000-01-13,94.48,98.75,92.50,96.75,36882400,24.19 +2000-01-12,95.00,95.50,86.50,87.19,34870800,21.80 +2000-01-11,95.94,99.37,90.50,92.75,15775200,23.19 +2000-01-10,102.00,102.25,94.75,97.75,18059200,24.44 +2000-01-07,96.50,101.00,95.50,99.50,16463200,24.88 +2000-01-06,106.12,107.00,95.00,95.00,27443200,23.75 +2000-01-05,103.75,110.56,103.00,104.00,27818000,26.00 +2000-01-04,108.25,110.62,101.19,102.50,18310000,25.62 +2000-01-03,104.87,112.50,101.69,111.94,19144400,27.99 +1999-12-31,100.94,102.87,99.50,102.81,5856400,25.70 +1999-12-30,102.19,104.12,99.62,100.31,7419200,25.08 +1999-12-29,96.81,102.19,95.50,100.69,10161200,25.17 +1999-12-28,99.12,99.62,95.00,98.19,8843200,24.55 +1999-12-27,104.37,104.44,99.25,99.31,6022000,24.83 +1999-12-23,101.81,104.25,101.06,103.50,8218800,25.88 +1999-12-22,102.87,104.56,98.75,99.94,11682000,24.99 +1999-12-21,98.19,103.06,97.94,102.50,11000000,25.62 +1999-12-20,99.56,99.62,96.62,98.00,10155200,24.50 +1999-12-17,100.87,102.00,98.50,100.00,17700800,25.00 +1999-12-16,98.00,98.37,94.00,98.31,16568000,24.58 +1999-12-15,93.25,97.25,91.06,97.00,22254400,24.25 +1999-12-14,98.37,99.75,94.75,94.87,15570800,23.72 +1999-12-13,102.39,102.50,98.94,99.00,18931200,24.75 +1999-12-10,105.31,109.25,99.00,103.00,22786800,25.75 +1999-12-09,111.00,111.00,100.87,105.25,30555600,26.31 +1999-12-08,116.25,117.87,109.50,110.06,14730800,27.51 +1999-12-07,116.56,118.00,114.00,117.81,15901200,29.45 +1999-12-06,114.56,117.31,111.44,116.00,16688000,29.00 +1999-12-03,112.19,115.56,111.87,115.00,23151200,28.75 +1999-12-02,103.12,110.62,101.75,110.19,20275600,27.55 +1999-12-01,101.00,104.50,100.06,103.06,22098000,25.76 +1999-11-30,98.12,103.75,97.37,97.87,30132400,24.47 +1999-11-29,94.25,99.75,93.25,94.56,16586800,23.64 +1999-11-26,94.75,95.50,94.12,95.06,4737600,23.76 +1999-11-24,93.00,95.00,91.69,94.69,7683600,23.67 +1999-11-23,91.75,95.25,88.50,92.81,19406400,23.20 +1999-11-22,91.75,91.75,89.25,90.62,7242400,22.66 +1999-11-19,89.50,92.87,88.06,92.44,11162000,23.11 +1999-11-18,91.06,91.12,88.44,89.62,13043600,22.41 +1999-11-17,90.69,94.75,90.00,90.25,13032000,22.56 +1999-11-16,90.00,91.75,88.50,91.19,8370000,22.80 +1999-11-15,89.62,92.87,88.50,89.44,9283600,22.36 +1999-11-12,91.94,92.00,87.37,90.62,9970000,22.66 +1999-11-11,91.59,92.62,89.87,92.25,9660000,23.06 +1999-11-10,88.25,93.25,88.12,91.44,20661200,22.86 +1999-11-09,94.37,94.50,88.00,89.62,28910000,22.41 +1999-11-08,87.75,97.73,86.75,96.37,33962400,24.09 +1999-11-05,84.62,88.37,84.00,88.31,14889200,22.08 +1999-11-04,82.06,85.37,80.62,83.62,13549200,20.91 +1999-11-03,81.62,83.25,81.00,81.50,11736800,20.38 +1999-11-02,78.00,81.69,77.31,80.25,14268800,20.06 +1999-11-01,80.00,80.69,77.37,77.62,9965600,19.41 +1999-10-29,78.81,81.06,78.81,80.12,18680800,20.03 +1999-10-28,77.06,79.00,76.06,77.87,18005200,19.47 +1999-10-27,74.37,76.62,73.44,76.37,15837600,19.09 +1999-10-26,74.94,75.50,73.31,75.06,12924400,18.76 +1999-10-25,74.25,76.12,73.75,74.50,11677600,18.62 +1999-10-22,77.12,77.25,73.37,73.94,14995200,18.49 +1999-10-21,72.56,77.06,72.37,76.12,28347600,19.03 +1999-10-20,70.00,75.25,70.00,75.12,38633600,18.78 +1999-10-19,71.62,75.00,68.44,68.50,36521200,17.12 +1999-10-18,73.87,74.25,71.12,73.25,27733600,18.31 +1999-10-15,71.12,75.81,70.19,74.56,41910000,18.64 +1999-10-14,69.25,73.31,69.00,73.19,67822400,18.30 +1999-10-13,66.62,69.50,63.75,64.03,22752000,16.01 +1999-10-12,67.87,69.62,67.00,67.69,20142000,16.92 +1999-10-11,66.00,68.25,66.00,66.69,9418000,16.67 +1999-10-08,66.19,66.31,63.50,65.56,13689200,16.39 +1999-10-07,68.44,68.62,64.87,66.37,21660800,16.59 +1999-10-06,69.37,69.62,67.00,67.19,28726400,16.80 +1999-10-05,65.62,68.12,64.75,67.94,29100800,16.99 +1999-10-04,62.38,64.87,62.38,64.56,16408800,16.14 +1999-10-01,62.13,62.44,59.50,61.72,21977600,15.43 +1999-09-30,59.56,64.19,59.25,63.31,32449200,15.83 +1999-09-29,60.25,61.25,58.00,59.06,23493600,14.77 +1999-09-28,61.50,62.00,57.44,59.63,50542400,14.91 +1999-09-27,66.37,66.75,61.19,61.31,33877600,15.33 +1999-09-24,63.38,67.02,63.00,64.94,42148800,16.24 +1999-09-23,71.12,71.25,63.00,63.31,40853200,15.83 +1999-09-22,69.75,71.62,69.02,70.31,40132000,17.58 +1999-09-21,73.19,73.25,69.00,69.25,119931200,17.31 +1999-09-20,77.00,80.12,76.87,79.06,16326400,19.76 +1999-09-17,77.31,77.75,76.25,76.94,9915600,19.24 +1999-09-16,76.06,78.06,73.87,76.81,15793600,19.20 +1999-09-15,78.87,79.12,75.25,75.37,12843200,18.84 +1999-09-14,74.72,78.50,74.69,77.81,13883200,19.45 +1999-09-13,77.06,77.06,74.81,75.00,9000000,18.75 +1999-09-10,76.00,77.69,74.69,77.44,16398000,19.36 +1999-09-09,75.50,75.94,73.87,75.56,19093600,18.89 +1999-09-08,76.19,77.69,74.50,74.50,27233600,18.62 +1999-09-07,73.75,77.94,73.50,76.37,35177600,19.09 +1999-09-03,71.94,75.25,70.50,73.50,58403600,18.38 +1999-09-02,67.62,71.44,66.87,70.56,31975200,17.64 +1999-09-01,67.00,68.81,66.00,68.62,28168000,17.16 +1999-08-31,62.59,65.87,62.06,65.25,22675200,16.31 +1999-08-30,65.00,65.00,62.00,62.06,12033200,15.52 +1999-08-27,62.75,65.00,62.69,64.75,15980000,16.19 +1999-08-26,61.13,63.13,61.13,62.13,14449200,15.53 +1999-08-25,60.69,61.50,60.13,61.38,10553600,15.35 +1999-08-24,60.38,60.75,59.94,60.38,17948000,15.10 +1999-08-23,59.38,61.38,59.31,60.75,12709200,15.19 +1999-08-20,59.25,59.38,58.19,59.19,11730800,14.80 +1999-08-19,59.81,60.50,58.56,58.75,19645600,14.69 +1999-08-18,60.06,62.00,59.63,60.13,16743200,15.03 +1999-08-17,60.31,60.38,58.94,60.31,11474400,15.08 +1999-08-16,59.81,60.69,59.50,60.50,9896400,15.12 +1999-08-13,60.63,62.00,59.88,60.06,10668800,15.02 +1999-08-12,59.06,61.38,58.63,60.00,23806400,15.00 +1999-08-11,56.00,59.75,55.94,59.69,30374400,14.92 +1999-08-10,54.00,56.00,53.63,55.38,14879200,13.85 +1999-08-09,54.34,55.19,54.25,54.44,8338000,13.61 +1999-08-06,54.06,55.31,53.50,54.13,15575600,13.53 +1999-08-05,53.50,54.88,52.13,54.75,11541200,13.69 +1999-08-04,55.19,55.88,53.25,53.81,13279200,13.45 +1999-08-03,56.75,57.44,53.63,55.25,13176800,13.81 +1999-08-02,55.63,58.00,55.50,55.75,12958000,13.94 +1999-07-30,54.50,56.13,54.50,55.69,13685600,13.92 +1999-07-29,53.38,55.25,53.13,53.88,9860000,13.47 +1999-07-28,53.88,55.38,53.00,54.38,11762000,13.60 +1999-07-27,52.63,53.94,52.50,53.69,14150800,13.42 +1999-07-26,52.88,53.00,50.88,50.94,12555200,12.73 +1999-07-23,52.81,53.75,52.69,53.31,8192000,13.33 +1999-07-22,53.63,53.88,51.13,52.38,14529200,13.10 +1999-07-21,54.06,55.44,52.88,54.06,25653600,13.52 +1999-07-20,54.56,55.50,52.75,52.88,15804400,13.22 +1999-07-19,53.94,55.81,52.31,54.44,20050000,13.61 +1999-07-16,53.63,54.50,53.00,53.06,14705600,13.27 +1999-07-15,55.88,55.94,51.31,53.25,60433600,13.31 +1999-07-14,54.50,56.63,54.50,55.94,22320000,13.98 +1999-07-13,53.50,54.19,52.88,53.69,10136800,13.42 +1999-07-12,55.50,55.63,54.19,54.50,10862000,13.62 +1999-07-09,54.50,55.63,53.00,55.63,21750000,13.91 +1999-07-08,51.13,55.06,50.88,54.50,58058000,13.62 +1999-07-07,47.38,50.75,47.00,49.88,39264400,12.47 +1999-07-06,45.94,47.63,45.81,47.38,16212000,11.85 +1999-07-02,45.53,46.88,45.19,46.31,4426800,11.58 +1999-07-01,46.31,46.56,45.25,45.31,5334400,11.33 +1999-06-30,45.69,46.94,44.94,46.31,12270800,11.58 +1999-06-29,42.72,45.56,42.63,45.38,13599200,11.35 +1999-06-28,42.44,42.94,42.38,42.56,9938800,10.64 +1999-06-25,42.50,42.69,42.06,42.19,10518800,10.55 +1999-06-24,43.63,43.63,42.25,42.31,15498000,10.58 +1999-06-23,45.06,45.09,43.56,43.69,18994400,10.92 +1999-06-22,46.31,46.94,45.38,45.38,5415600,11.35 +1999-06-21,47.00,47.25,46.00,46.50,4842000,11.62 +1999-06-18,45.38,47.25,45.19,47.13,7448000,11.78 +1999-06-17,47.63,48.00,45.75,46.38,8022400,11.60 +1999-06-16,46.38,48.06,46.38,47.94,8056800,11.98 +1999-06-15,45.19,46.75,45.13,46.06,4666400,11.52 +1999-06-14,46.50,46.63,45.13,45.44,5615600,11.36 +1999-06-11,48.13,48.50,46.25,46.44,6613600,11.61 +1999-06-10,47.88,48.25,47.31,48.13,11325200,12.03 +1999-06-09,47.44,48.50,47.44,48.44,12655200,12.11 +1999-06-08,48.75,48.81,47.56,47.69,11203200,11.92 +1999-06-07,48.13,49.00,47.50,48.94,14949200,12.23 +1999-06-04,47.63,48.19,47.25,48.13,13171200,12.03 +1999-06-03,46.88,48.00,46.81,47.44,17450800,11.86 +1999-06-02,44.50,47.94,44.00,46.56,18614400,11.64 +1999-06-01,45.00,45.31,44.38,44.81,16479200,11.20 +1999-05-28,43.31,44.31,43.13,44.06,7196400,11.02 +1999-05-27,43.19,43.75,42.69,43.50,12042400,10.88 +1999-05-26,41.75,44.38,41.25,44.06,15642000,11.02 +1999-05-25,41.56,42.44,40.94,41.50,13095200,10.38 +1999-05-24,43.63,44.31,41.88,41.94,9340800,10.48 +1999-05-21,43.00,44.31,42.56,43.94,16555200,10.98 +1999-05-20,45.44,45.75,42.50,42.50,14940000,10.62 +1999-05-19,45.50,45.75,43.50,45.19,10660000,11.30 +1999-05-18,44.81,46.00,44.38,45.25,14954400,11.31 +1999-05-17,43.75,44.69,43.00,44.38,7531200,11.10 +1999-05-14,45.13,45.81,44.38,44.38,8102000,11.10 +1999-05-13,46.44,46.81,45.50,46.19,10573600,11.55 +1999-05-12,44.88,46.50,44.13,46.50,14129200,11.62 +1999-05-11,44.88,46.19,43.56,44.75,16388800,11.19 +1999-05-10,46.75,46.94,44.63,45.25,14055600,11.31 +1999-05-07,44.63,45.88,42.75,45.88,15528800,11.47 +1999-05-06,46.56,46.88,44.00,44.50,15486400,11.12 +1999-05-05,46.31,47.00,44.63,47.00,20694400,11.75 +1999-05-04,48.25,48.63,46.19,46.50,28980000,11.62 +1999-05-03,46.06,50.00,45.75,49.56,52535600,12.39 +1999-04-30,44.00,47.13,44.00,46.00,52596400,11.50 +1999-04-29,43.25,44.38,41.78,43.00,28206400,10.75 +1999-04-28,44.63,45.69,43.63,44.06,34122000,11.02 +1999-04-27,43.00,45.81,43.00,45.75,75225200,11.44 +1999-04-26,39.50,41.25,39.25,40.94,33152000,10.23 +1999-04-23,36.25,39.44,36.25,39.19,37402400,9.80 +1999-04-22,35.06,36.63,35.06,36.38,26454400,9.10 +1999-04-21,34.00,34.38,33.50,34.38,12566800,8.60 +1999-04-20,33.88,34.75,33.50,34.06,18725600,8.52 +1999-04-19,35.69,36.00,33.50,33.88,32923200,8.47 +1999-04-16,35.88,36.06,35.25,35.44,17945600,8.86 +1999-04-15,35.38,36.19,34.31,35.75,61960000,8.94 +1999-04-14,35.25,37.06,35.00,35.53,24323600,8.88 +1999-04-13,36.31,36.81,34.50,34.63,14732400,8.66 +1999-04-12,35.00,36.88,34.88,36.25,14145600,9.06 +1999-04-09,36.25,37.25,35.94,36.75,9608000,9.19 +1999-04-08,36.88,37.06,36.00,36.88,10600800,9.22 +1999-04-07,38.06,38.25,36.38,37.13,14723200,9.28 +1999-04-06,36.81,38.31,36.81,38.00,22455200,9.50 +1999-04-05,36.00,37.88,36.00,37.06,16474400,9.27 +1999-04-01,36.06,36.69,35.75,36.06,9381200,9.02 +1999-03-31,36.38,37.13,35.88,35.94,15086400,8.98 +1999-03-30,35.00,36.38,35.00,35.88,19806800,8.97 +1999-03-29,33.50,35.44,33.44,35.38,20337600,8.85 +1999-03-26,33.75,33.81,33.00,33.25,9080000,8.31 +1999-03-25,34.38,34.88,33.38,33.81,14286800,8.45 +1999-03-24,33.25,33.75,32.50,33.69,14297600,8.42 +1999-03-23,34.44,34.44,32.75,33.00,14842000,8.25 +1999-03-22,34.00,35.19,32.94,35.06,21200800,8.77 +1999-03-19,35.94,36.00,32.88,33.50,19161200,8.38 +1999-03-18,34.38,35.63,34.25,35.50,8126800,8.88 +1999-03-17,35.94,36.06,33.94,34.06,13084400,8.52 +1999-03-16,35.00,35.56,34.94,35.50,14302000,8.88 +1999-03-15,33.31,35.00,33.25,34.06,12586800,8.52 +1999-03-12,32.31,33.50,32.31,33.19,9700000,8.30 +1999-03-11,32.25,33.88,32.00,32.19,16936800,8.05 +1999-03-10,34.19,34.19,32.44,32.56,19526800,8.14 +1999-03-09,34.31,34.38,33.50,34.13,11427600,8.53 +1999-03-08,33.25,34.69,33.19,34.38,19682000,8.60 +1999-03-05,34.31,34.31,32.38,33.19,16735600,8.30 +1999-03-04,34.50,34.50,32.38,33.44,13137600,8.36 +1999-03-03,34.75,35.13,33.50,34.19,10497600,8.55 +1999-03-02,34.13,35.31,33.75,34.63,24414400,8.66 +1999-03-01,34.81,34.81,33.63,33.75,17435200,8.44 +1999-02-26,36.50,37.00,34.50,34.81,23847600,8.70 +1999-02-25,37.31,37.69,36.50,36.94,9455600,9.23 +1999-02-24,38.81,39.00,37.38,37.44,7620000,9.36 +1999-02-23,38.56,39.56,37.94,38.44,11521200,9.61 +1999-02-22,37.38,38.88,37.25,38.44,10682000,9.61 +1999-02-19,36.25,37.69,36.19,37.19,12938800,9.30 +1999-02-18,37.56,37.88,35.56,36.00,17876400,9.00 +1999-02-17,38.13,38.69,36.94,37.00,10581200,9.25 +1999-02-16,38.88,38.88,37.88,38.31,10723600,9.58 +1999-02-12,39.13,39.13,37.00,37.69,15339200,9.42 +1999-02-11,38.75,39.75,38.56,39.63,20200000,9.91 +1999-02-10,36.88,38.69,36.00,38.31,20135200,9.58 +1999-02-09,37.94,39.06,37.06,37.19,25042000,9.30 +1999-02-08,36.69,37.94,36.25,37.75,16723600,9.44 +1999-02-05,38.25,38.38,35.50,36.31,27778000,9.08 +1999-02-04,40.19,40.25,37.75,37.88,16565600,9.47 +1999-02-03,39.00,40.56,38.75,40.19,12108000,10.05 +1999-02-02,40.38,40.75,39.00,39.19,10975600,9.80 +1999-02-01,41.69,41.94,40.31,40.94,9962000,10.23 +1999-01-29,41.19,41.56,40.00,41.19,8684400,10.30 +1999-01-28,40.88,41.25,40.31,40.88,12015600,10.22 +1999-01-27,41.00,41.38,39.94,40.13,13053200,10.03 +1999-01-26,39.94,40.88,39.63,40.50,20002400,10.12 +1999-01-25,39.25,39.56,38.81,39.38,13763200,9.85 +1999-01-22,37.69,39.50,37.06,38.75,12365200,9.69 +1999-01-21,40.44,40.56,37.50,38.81,21449200,9.70 +1999-01-20,41.06,42.00,40.50,40.56,27806800,10.14 +1999-01-19,41.94,42.31,40.38,40.88,19116400,10.22 +1999-01-15,41.81,42.13,40.00,41.31,35933600,10.33 +1999-01-14,45.50,46.00,41.06,41.38,61570000,10.35 +1999-01-13,42.88,47.31,42.25,46.50,37434400,11.62 +1999-01-12,46.31,46.63,44.13,46.13,29330000,11.53 +1999-01-11,45.75,46.06,44.88,45.88,20054400,11.47 +1999-01-08,46.56,46.88,44.00,45.00,24246400,11.25 +1999-01-07,42.25,45.06,42.13,45.00,51056800,11.25 +1999-01-06,44.13,44.13,41.00,41.75,48165200,10.44 +1999-01-05,41.94,43.94,41.50,43.31,50362000,10.83 +1999-01-04,42.13,42.25,40.00,41.25,34049200,10.31 +1998-12-31,40.50,41.38,39.50,40.94,9716400,10.23 +1998-12-30,40.13,41.13,40.00,40.06,8498000,10.02 +1998-12-29,41.13,41.50,40.25,40.81,13853200,10.20 +1998-12-28,39.00,41.13,39.00,40.88,25917600,10.22 +1998-12-24,39.88,40.00,39.19,39.25,7155200,9.81 +1998-12-23,38.63,40.50,38.38,39.81,44124400,9.95 +1998-12-22,36.38,38.13,36.00,38.00,41111200,9.50 +1998-12-21,35.38,35.63,34.25,35.06,12769200,8.77 +1998-12-18,33.38,35.38,33.25,35.19,28283200,8.80 +1998-12-17,32.94,33.75,32.75,33.44,11812000,8.36 +1998-12-16,33.75,34.19,32.63,32.81,13375200,8.20 +1998-12-15,32.75,33.63,32.75,33.56,9462000,8.39 +1998-12-14,32.88,33.31,32.25,32.50,17925200,8.12 +1998-12-11,32.25,34.00,32.00,33.75,24644400,8.44 +1998-12-10,32.69,32.94,31.87,32.00,13980800,8.00 +1998-12-09,32.69,32.88,31.62,32.00,21184400,8.00 +1998-12-08,33.94,33.94,32.00,32.06,24295200,8.02 +1998-12-07,33.38,33.75,32.75,33.75,20255600,8.44 +1998-12-04,34.31,34.44,32.00,32.75,25765200,8.19 +1998-12-03,36.31,36.50,33.63,33.69,22380800,8.42 +1998-12-02,34.13,36.88,33.50,36.00,34382400,9.00 +1998-12-01,32.00,34.81,31.62,34.13,30941200,8.53 +1998-11-30,34.56,34.81,31.75,31.94,20060800,7.99 +1998-11-27,35.06,35.13,34.75,35.06,5483600,8.77 +1998-11-25,35.88,36.06,34.94,35.13,10855600,8.78 +1998-11-24,36.13,36.75,35.75,35.94,11430800,8.98 +1998-11-23,35.56,36.81,35.19,36.25,20642000,9.06 +1998-11-20,36.44,36.75,34.75,35.31,14268000,8.83 +1998-11-19,35.50,37.19,35.44,35.75,12385200,8.94 +1998-11-18,35.19,36.00,34.88,35.44,11781200,8.86 +1998-11-17,35.75,35.81,34.75,34.81,7529200,8.70 +1998-11-16,35.94,36.75,35.44,36.00,13740800,9.00 +1998-11-13,34.94,36.06,34.69,35.69,28301200,8.92 +1998-11-12,33.13,34.44,32.88,34.00,21261200,8.50 +1998-11-11,35.75,35.81,32.75,33.56,33895200,8.39 +1998-11-10,36.19,36.25,35.00,35.13,31576800,8.78 +1998-11-09,37.69,38.13,35.50,36.63,23622000,9.16 +1998-11-06,37.88,38.25,37.25,38.06,28496800,9.52 +1998-11-05,38.38,39.38,38.06,38.19,21684400,9.55 +1998-11-04,38.56,39.13,38.13,38.69,22438000,9.67 +1998-11-03,37.38,38.25,37.31,37.81,13247600,9.45 +1998-11-02,37.50,37.75,37.25,37.63,9076400,9.41 +1998-10-30,36.81,37.50,36.25,37.13,11358000,9.28 +1998-10-29,36.44,37.44,35.81,36.44,12321200,9.11 +1998-10-28,35.25,37.00,35.13,36.81,13006400,9.20 +1998-10-27,38.00,38.94,35.06,35.25,19233200,8.81 +1998-10-26,36.06,37.75,35.50,37.44,17013600,9.36 +1998-10-23,36.75,36.88,35.13,35.50,12732400,8.88 +1998-10-22,36.88,37.63,36.25,36.75,11343200,9.19 +1998-10-21,36.75,37.44,35.75,37.13,15390000,9.28 +1998-10-20,37.94,38.19,36.00,36.06,13649200,9.02 +1998-10-19,36.69,38.06,35.88,37.50,17010000,9.38 +1998-10-16,37.13,38.06,36.50,36.69,21998000,9.17 +1998-10-15,36.25,37.25,35.50,36.63,30037600,9.16 +1998-10-14,39.75,41.31,36.81,37.38,81445600,9.35 +1998-10-13,38.06,39.19,36.00,38.75,33646400,9.69 +1998-10-12,37.50,38.44,36.56,37.44,22250000,9.36 +1998-10-09,31.75,35.25,30.75,35.13,23880000,8.78 +1998-10-08,31.00,31.19,28.50,30.81,24623200,7.70 +1998-10-07,32.38,33.31,31.87,31.94,16920000,7.99 +1998-10-06,33.69,34.31,32.50,32.56,14281200,8.14 +1998-10-05,34.00,34.56,31.50,32.19,19726800,8.05 +1998-10-02,35.50,36.25,34.13,35.06,16998800,8.77 +1998-10-01,36.75,38.00,35.38,35.69,13234400,8.92 +1998-09-30,38.75,39.25,38.00,38.13,5976800,9.53 +1998-09-29,39.06,40.00,38.13,39.50,10907600,9.88 +1998-09-28,39.75,40.19,38.00,39.06,14501200,9.77 +1998-09-25,38.19,39.19,37.63,38.75,8172000,9.69 +1998-09-24,37.88,39.56,37.75,38.50,17246800,9.62 +1998-09-23,37.25,38.38,36.56,38.31,10284400,9.58 +1998-09-22,37.13,37.63,36.38,37.00,9218800,9.25 +1998-09-21,35.69,36.94,35.31,36.94,10570800,9.23 +1998-09-18,36.06,36.75,35.56,36.75,10904400,9.19 +1998-09-17,36.06,37.13,35.88,36.00,9627600,9.00 +1998-09-16,38.63,38.75,37.00,37.31,9248800,9.33 +1998-09-15,36.75,38.56,36.50,38.19,15492000,9.55 +1998-09-14,38.25,38.81,37.13,37.19,8837600,9.30 +1998-09-11,38.50,39.63,36.88,37.63,12593600,9.41 +1998-09-10,36.25,38.25,35.75,38.13,18826800,9.53 +1998-09-09,38.06,38.13,37.00,37.38,12683200,9.35 +1998-09-08,38.00,38.25,36.75,38.25,14400000,9.56 +1998-09-04,35.50,36.44,33.75,35.13,13493200,8.78 +1998-09-03,35.00,35.13,34.00,34.63,14653200,8.66 +1998-09-02,35.50,37.38,35.25,35.56,30122400,8.89 +1998-09-01,31.37,35.38,30.62,34.13,31060000,8.53 +1998-08-31,34.75,34.88,31.00,31.19,31012400,7.80 +1998-08-28,37.13,38.50,34.13,34.19,33303200,8.55 +1998-08-27,39.25,39.25,35.63,37.50,39813600,9.38 +1998-08-26,39.88,41.13,39.50,40.38,14538000,10.10 +1998-08-25,42.38,42.38,40.31,40.81,17709200,10.20 +1998-08-24,43.44,43.50,40.13,41.19,21810000,10.30 +1998-08-21,40.00,43.56,39.00,43.00,29054400,10.75 +1998-08-20,41.00,41.13,40.25,40.63,14018000,10.16 +1998-08-19,43.50,43.75,41.00,41.00,17377600,10.25 +1998-08-18,42.44,43.38,42.25,42.56,21642000,10.64 +1998-08-17,41.00,42.81,39.88,41.94,33248800,10.48 +1998-08-14,40.69,40.75,39.50,40.50,16110000,10.12 +1998-08-13,39.94,40.75,39.38,39.44,13976800,9.86 +1998-08-12,39.75,40.94,39.48,40.06,24654400,10.02 +1998-08-11,37.75,41.00,37.38,39.00,62860000,9.75 +1998-08-10,36.31,38.06,36.25,37.94,17455600,9.48 +1998-08-07,37.19,37.38,36.00,36.50,10645600,9.12 +1998-08-06,35.06,36.88,34.88,36.88,15678800,9.22 +1998-08-05,33.75,36.00,33.50,36.00,16226800,9.00 +1998-08-04,35.50,36.00,34.00,34.19,10506800,8.55 +1998-08-03,34.25,35.56,33.25,35.13,10786800,8.78 +1998-07-31,36.63,36.75,34.50,34.63,6550800,8.66 +1998-07-30,35.81,36.75,35.50,36.50,12950000,9.12 +1998-07-29,33.75,35.88,33.69,35.13,16006800,8.78 +1998-07-28,34.06,34.63,33.00,33.63,8054400,8.41 +1998-07-27,34.25,34.88,33.25,34.44,7657600,8.61 +1998-07-24,35.38,35.50,33.81,34.69,9693600,8.67 +1998-07-23,34.81,35.63,34.75,34.94,9040800,8.73 +1998-07-22,34.94,35.63,34.25,35.00,10040800,8.75 +1998-07-21,36.13,37.00,35.56,35.63,11772400,8.91 +1998-07-20,36.56,36.63,35.50,36.25,13727600,9.06 +1998-07-17,37.25,37.25,36.19,36.88,22486400,9.22 +1998-07-16,37.88,38.13,35.75,37.50,91497600,9.38 +1998-07-15,33.69,34.69,33.50,34.44,21253600,8.61 +1998-07-14,33.94,34.00,33.13,33.44,19607600,8.36 +1998-07-13,31.94,34.13,31.87,33.94,25566400,8.48 +1998-07-10,32.19,32.63,31.75,32.06,10806800,8.02 +1998-07-09,32.94,33.63,31.44,31.69,20256400,7.92 +1998-07-08,30.75,32.94,30.69,32.56,33334400,8.14 +1998-07-07,30.37,30.87,30.00,30.50,8637600,7.62 +1998-07-06,29.50,30.37,29.12,30.37,9697600,7.59 +1998-07-02,29.69,30.06,29.00,29.00,10650800,7.25 +1998-07-01,28.87,30.00,28.50,29.94,11228800,7.49 +1998-06-30,28.62,28.81,28.12,28.69,4681200,7.17 +1998-06-29,28.25,28.81,28.06,28.69,5943600,7.17 +1998-06-26,28.50,28.62,27.75,28.19,3973200,7.05 +1998-06-25,28.56,28.81,28.31,28.56,6856400,7.14 +1998-06-24,27.75,28.62,27.31,28.25,9788800,7.06 +1998-06-23,27.44,28.12,27.25,27.81,8258800,6.95 +1998-06-22,27.00,27.56,26.75,27.37,4809200,6.84 +1998-06-19,27.37,27.44,26.75,27.06,4931200,6.76 +1998-06-18,27.75,28.06,27.19,27.31,4288800,6.83 +1998-06-17,28.00,28.56,27.94,28.12,6687600,7.03 +1998-06-16,27.69,28.12,27.31,28.00,4649200,7.00 +1998-06-15,27.25,28.25,27.25,27.50,4881200,6.88 +1998-06-12,27.62,28.25,27.37,28.12,8014400,7.03 +1998-06-11,28.19,28.62,27.81,27.81,6451200,6.95 +1998-06-10,28.00,29.00,27.62,28.06,8202000,7.01 +1998-06-09,27.37,28.50,27.37,28.25,9852400,7.06 +1998-06-08,27.00,27.69,26.81,27.25,4523600,6.81 +1998-06-05,26.87,27.25,26.37,26.87,4406800,6.72 +1998-06-04,26.62,26.87,25.81,26.81,5585600,6.70 +1998-06-03,27.12,27.25,26.19,26.31,5196800,6.58 +1998-06-02,26.44,27.31,26.00,26.87,6405600,6.72 +1998-06-01,26.50,27.62,25.62,26.25,11427600,6.56 +1998-05-29,27.50,27.56,26.44,26.62,7751200,6.66 +1998-05-28,26.75,27.87,26.75,27.44,10672000,6.86 +1998-05-27,25.69,26.81,25.62,26.75,13233200,6.69 +1998-05-26,28.06,28.25,26.62,26.69,11143200,6.67 +1998-05-22,28.75,28.75,27.31,27.87,9522000,6.97 +1998-05-21,29.56,29.69,28.62,28.87,4700000,7.22 +1998-05-20,29.62,29.87,28.75,29.56,6810000,7.39 +1998-05-19,28.94,29.44,28.81,29.37,7815200,7.34 +1998-05-18,29.37,29.56,28.37,28.50,8310800,7.12 +1998-05-15,30.06,30.37,29.25,29.56,9743600,7.39 +1998-05-14,30.37,30.44,29.75,30.06,5815600,7.51 +1998-05-13,30.06,30.81,29.62,30.44,11245600,7.61 +1998-05-12,30.56,30.75,29.94,30.12,9212000,7.53 +1998-05-11,30.87,31.62,30.75,30.94,23768000,7.74 +1998-05-08,30.06,30.50,29.94,30.44,9690000,7.61 +1998-05-07,30.56,30.62,29.87,30.19,19761200,7.55 +1998-05-06,29.87,30.44,29.25,30.31,32056400,7.58 +1998-05-05,29.25,29.87,29.12,29.69,14982400,7.42 +1998-05-04,28.87,29.50,28.87,29.06,20419200,7.26 +1998-05-01,27.50,28.25,26.87,28.00,6582000,7.00 +1998-04-30,27.37,27.62,27.06,27.37,6442000,6.84 +1998-04-29,26.94,27.44,26.75,27.00,6774400,6.75 +1998-04-28,27.87,28.00,26.25,26.94,8487600,6.74 +1998-04-27,26.75,27.75,26.75,27.75,14655600,6.94 +1998-04-24,27.75,28.25,27.50,27.94,7708000,6.99 +1998-04-23,27.44,29.00,27.19,27.69,16983200,6.92 +1998-04-22,28.75,29.00,27.50,27.50,10186400,6.88 +1998-04-21,29.06,29.12,28.50,29.00,12446400,7.25 +1998-04-20,27.62,29.50,27.56,29.00,18498800,7.25 +1998-04-17,28.56,28.62,27.69,27.94,21165200,6.99 +1998-04-16,29.25,29.62,28.19,28.62,65642000,7.16 +1998-04-15,27.19,27.50,26.62,27.44,19928800,6.86 +1998-04-14,26.37,27.25,26.37,26.94,11725200,6.74 +1998-04-13,25.62,26.69,25.00,26.44,10305600,6.61 +1998-04-09,25.06,25.87,25.00,25.62,6083600,6.41 +1998-04-08,25.25,25.37,24.69,25.00,8044400,6.25 +1998-04-07,25.81,26.00,24.87,25.50,10461200,6.38 +1998-04-06,27.00,27.00,26.19,26.25,12422000,6.56 +1998-04-03,27.12,27.25,26.81,27.06,7259200,6.76 +1998-04-02,27.31,27.44,26.94,27.31,6950800,6.83 +1998-04-01,27.44,27.81,27.06,27.50,6693600,6.88 +1998-03-31,27.44,27.81,27.25,27.50,9538800,6.88 +1998-03-30,26.75,27.50,26.75,27.44,8972400,6.86 +1998-03-27,26.62,27.31,26.37,26.94,9133200,6.74 +1998-03-26,26.75,27.00,26.44,26.56,7253600,6.64 +1998-03-25,27.62,27.75,26.37,27.16,13854400,6.79 +1998-03-24,26.37,28.00,26.25,28.00,24152000,7.00 +1998-03-23,25.94,26.25,24.62,26.12,14818800,6.53 +1998-03-20,26.69,26.87,26.00,26.37,7704400,6.59 +1998-03-19,26.87,26.94,26.56,26.75,5736800,6.69 +1998-03-18,26.00,26.94,26.00,26.94,9900000,6.74 +1998-03-17,26.50,26.69,25.87,26.34,14658800,6.59 +1998-03-16,27.12,27.25,26.19,26.69,14375600,6.67 +1998-03-13,27.25,27.25,26.25,27.12,20231200,6.78 +1998-03-12,26.12,27.00,25.56,27.00,26598000,6.75 +1998-03-11,25.12,26.19,24.56,26.12,43374400,6.53 +1998-03-10,23.00,24.50,22.94,24.06,25472400,6.01 +1998-03-09,23.75,24.31,22.50,22.75,20540800,5.69 +1998-03-06,23.87,24.50,23.37,24.44,23803600,6.11 +1998-03-05,23.25,24.25,23.12,24.06,24129200,6.01 +1998-03-04,22.87,24.75,22.87,24.44,29212400,6.11 +1998-03-03,21.87,23.19,21.62,23.12,11937600,5.78 +1998-03-02,23.56,23.56,22.25,22.75,14313600,5.69 +1998-02-27,23.31,23.87,22.56,23.62,18578000,5.91 +1998-02-26,22.31,23.56,21.87,23.50,21263200,5.88 +1998-02-25,21.31,22.75,20.94,22.31,25459200,5.58 +1998-02-24,21.31,21.37,20.75,21.31,16322000,5.33 +1998-02-23,20.12,21.62,20.00,21.25,17060800,5.31 +1998-02-20,20.50,20.56,19.81,20.00,11634400,5.00 +1998-02-19,20.87,20.94,20.00,20.44,14292400,5.11 +1998-02-18,19.56,20.75,19.56,20.56,17677600,5.14 +1998-02-17,19.50,19.75,19.50,19.62,6530800,4.91 +1998-02-13,19.19,19.87,19.00,19.50,7444400,4.88 +1998-02-12,19.12,19.44,19.06,19.37,7297600,4.84 +1998-02-11,19.50,19.50,18.87,19.00,7582000,4.75 +1998-02-10,19.12,19.56,19.06,19.44,15090000,4.86 +1998-02-09,18.37,19.50,18.37,19.19,17682000,4.80 +1998-02-06,18.37,18.69,18.25,18.50,7241200,4.62 +1998-02-05,18.25,18.50,18.00,18.31,8526400,4.58 +1998-02-04,18.06,18.50,18.00,18.25,6100000,4.56 +1998-02-03,17.69,18.62,17.69,18.31,14390000,4.58 +1998-02-02,18.50,18.50,17.37,17.69,22752400,4.42 +1998-01-30,18.31,18.87,18.25,18.31,5802400,4.58 +1998-01-29,18.94,19.12,18.50,18.50,7571200,4.62 +1998-01-28,19.19,19.37,18.62,19.19,5418000,4.80 +1998-01-27,19.19,19.69,19.00,19.12,4013200,4.78 +1998-01-26,19.44,19.56,18.81,19.44,5246800,4.86 +1998-01-23,19.37,19.69,19.25,19.50,8331200,4.88 +1998-01-22,18.69,19.75,18.62,19.25,11785200,4.81 +1998-01-21,18.75,19.06,18.56,18.91,6812000,4.73 +1998-01-20,19.06,19.31,18.62,19.06,8642400,4.76 +1998-01-16,19.44,19.44,18.69,18.81,8820000,4.70 +1998-01-15,19.19,19.75,18.62,19.19,19982000,4.80 +1998-01-14,19.87,19.94,19.25,19.75,21048000,4.94 +1998-01-13,18.62,19.62,18.50,19.50,22758800,4.88 +1998-01-12,17.44,18.62,17.12,18.25,18444400,4.56 +1998-01-09,18.12,19.37,17.50,18.19,31675200,4.55 +1998-01-08,17.44,18.62,16.94,18.19,27645600,4.55 +1998-01-07,18.81,19.00,17.31,17.50,37201200,4.38 +1998-01-06,15.94,20.00,14.75,18.94,64737600,4.74 +1998-01-05,16.50,16.56,15.19,15.88,23282000,3.97 +1998-01-02,13.63,16.25,13.50,16.25,25650800,4.06 +1997-12-31,13.13,13.63,12.94,13.13,14531200,3.28 +1997-12-30,13.00,13.44,12.75,13.19,12250800,3.30 +1997-12-29,13.31,13.44,12.88,13.13,9944400,3.28 +1997-12-26,13.06,13.38,13.00,13.31,3860000,3.33 +1997-12-24,13.00,13.25,13.00,13.13,3502000,3.28 +1997-12-23,13.13,13.31,12.94,12.94,16402000,3.23 +1997-12-22,13.88,14.00,13.19,13.31,5704400,3.33 +1997-12-19,13.56,13.88,13.25,13.69,6812000,3.42 +1997-12-18,14.00,14.00,13.75,13.81,7225200,3.45 +1997-12-17,14.31,14.56,13.94,13.94,9494400,3.48 +1997-12-16,14.00,14.38,14.00,14.31,6646400,3.58 +1997-12-15,14.13,14.25,13.75,13.94,5927600,3.48 +1997-12-12,14.75,14.88,14.00,14.13,5742400,3.53 +1997-12-11,14.44,14.56,13.88,14.56,9185600,3.64 +1997-12-10,15.06,15.06,14.50,14.75,6960000,3.69 +1997-12-09,15.50,15.69,15.00,15.25,8680800,3.81 +1997-12-08,15.56,15.75,15.38,15.56,4776800,3.89 +1997-12-05,15.56,16.00,15.56,15.81,7926400,3.95 +1997-12-04,16.00,16.00,15.63,15.63,7135600,3.91 +1997-12-03,16.06,16.12,15.69,15.75,12258800,3.94 +1997-12-02,17.37,17.50,15.88,15.88,14178800,3.97 +1997-12-01,17.69,17.94,17.25,17.75,3135600,4.44 +1997-11-28,17.62,17.87,17.44,17.75,1495600,4.44 +1997-11-26,17.37,17.69,17.25,17.50,2178800,4.38 +1997-11-25,17.69,17.87,16.87,17.37,7346400,4.34 +1997-11-24,17.56,18.00,17.50,17.62,5630800,4.41 +1997-11-21,18.62,18.69,18.00,18.19,3498800,4.55 +1997-11-20,18.19,18.62,18.12,18.50,4587600,4.62 +1997-11-19,17.87,18.31,17.87,18.25,2843600,4.56 +1997-11-18,18.50,18.50,18.06,18.06,5258000,4.51 +1997-11-17,18.87,18.94,18.33,18.50,7323600,4.62 +1997-11-14,18.25,18.50,18.00,18.44,4835600,4.61 +1997-11-13,18.00,18.06,17.50,18.00,9218000,4.50 +1997-11-12,18.06,18.50,17.56,17.62,7448000,4.41 +1997-11-11,19.00,19.00,18.12,18.37,11893600,4.59 +1997-11-10,21.00,21.50,18.50,18.69,49946800,4.67 +1997-11-07,18.87,20.00,18.75,19.75,28423200,4.94 +1997-11-06,18.87,19.50,18.87,19.00,22060800,4.75 +1997-11-05,18.25,18.62,18.06,18.37,13840000,4.59 +1997-11-04,17.75,18.12,17.50,17.94,6033200,4.49 +1997-11-03,17.56,17.75,17.06,17.37,4512000,4.34 +1997-10-31,17.37,17.37,16.62,17.03,9549200,4.26 +1997-10-30,17.06,17.56,16.50,16.50,6764400,4.12 +1997-10-29,18.44,18.50,17.25,17.50,6355200,4.38 +1997-10-28,16.00,18.50,15.88,18.12,12273200,4.53 +1997-10-27,16.75,18.12,16.75,16.75,11764400,4.19 +1997-10-24,18.12,18.37,16.50,16.56,13880000,4.14 +1997-10-23,18.00,18.19,17.75,17.75,6688000,4.44 +1997-10-22,19.06,19.25,18.50,18.56,5421200,4.64 +1997-10-21,18.87,19.31,18.69,19.06,16982000,4.76 +1997-10-20,20.12,20.19,18.62,18.69,14724400,4.67 +1997-10-17,21.12,21.12,19.87,20.12,15682000,5.03 +1997-10-16,21.12,22.06,20.87,21.50,26422000,5.38 +1997-10-15,22.12,24.75,22.12,23.81,28982000,5.95 +1997-10-14,22.69,22.75,22.19,22.69,5923200,5.67 +1997-10-13,22.75,22.87,22.19,22.69,5679200,5.67 +1997-10-10,21.50,22.75,21.50,22.69,9666800,5.67 +1997-10-09,21.25,22.50,21.19,21.75,6696400,5.44 +1997-10-08,21.75,21.81,21.31,21.50,3891200,5.38 +1997-10-07,21.87,22.00,21.81,21.81,3916400,5.45 +1997-10-06,22.19,22.25,21.69,21.94,3338800,5.49 +1997-10-03,22.00,22.25,21.69,22.12,5813200,5.53 +1997-10-02,21.44,22.00,21.37,21.94,4856400,5.49 +1997-10-01,21.69,21.75,21.37,21.53,4670800,5.38 +1997-09-30,22.00,22.31,21.69,21.69,5032000,5.42 +1997-09-29,21.69,22.25,21.56,22.06,5980000,5.51 +1997-09-26,21.50,21.94,21.12,21.31,7440000,5.33 +1997-09-25,21.31,21.75,21.00,21.12,7988000,5.28 +1997-09-24,21.69,21.75,21.37,21.50,7957600,5.38 +1997-09-23,22.25,22.25,21.69,21.75,7163200,5.44 +1997-09-22,22.12,23.06,22.00,22.81,7176400,5.70 +1997-09-19,22.19,22.19,21.75,21.94,3407600,5.49 +1997-09-18,21.50,22.50,21.50,22.31,6042400,5.58 +1997-09-17,22.00,22.00,21.69,21.81,3109200,5.45 +1997-09-16,22.06,22.14,21.75,21.94,4812400,5.49 +1997-09-15,21.87,22.12,21.50,21.50,3473200,5.38 +1997-09-12,22.19,22.25,21.44,22.06,4071200,5.51 +1997-09-11,22.87,23.00,22.06,22.37,7504400,5.59 +1997-09-10,21.75,23.12,21.69,22.94,9803600,5.74 +1997-09-09,21.31,21.87,21.25,21.81,5702000,5.45 +1997-09-08,22.25,22.25,21.44,21.50,6264400,5.38 +1997-09-05,22.62,22.87,22.00,22.19,4883600,5.55 +1997-09-04,22.56,22.87,22.25,22.50,4385600,5.62 +1997-09-03,22.37,23.25,22.31,22.50,10163200,5.62 +1997-09-02,22.00,22.56,21.94,22.37,6646800,5.59 +1997-08-29,21.81,22.00,21.50,21.75,3937600,5.44 +1997-08-28,22.12,22.50,22.00,22.00,3426400,5.50 +1997-08-27,22.37,22.75,21.87,22.69,6813200,5.67 +1997-08-26,22.62,23.00,22.12,22.25,8100800,5.56 +1997-08-25,23.62,23.69,22.94,23.06,4968800,5.76 +1997-08-22,23.44,24.00,23.37,23.62,8135200,5.91 +1997-08-21,24.50,24.69,23.87,24.00,9271200,6.00 +1997-08-20,24.44,25.12,24.19,24.62,11595200,6.16 +1997-08-19,23.69,24.50,23.31,24.44,10331200,6.11 +1997-08-18,23.31,23.75,22.75,23.62,7791200,5.91 +1997-08-15,23.12,23.44,22.81,23.25,9320000,5.81 +1997-08-14,23.62,24.25,22.69,23.00,15536400,5.75 +1997-08-13,22.25,23.87,20.44,23.62,42923600,5.91 +1997-08-12,24.06,24.25,21.87,22.06,37444400,5.51 +1997-08-11,26.31,26.44,23.50,24.56,55411200,6.14 +1997-08-08,27.81,28.37,26.12,26.81,64809200,6.70 +1997-08-07,28.75,29.56,28.37,29.19,134124400,7.30 +1997-08-06,25.25,27.75,25.00,26.31,149671200,6.58 +1997-08-05,19.94,20.00,19.48,19.75,8840800,4.94 +1997-08-04,19.19,19.81,19.19,19.75,21851200,4.94 +1997-08-01,17.62,19.19,17.56,19.19,17217600,4.80 +1997-07-31,17.37,17.75,17.25,17.50,9434400,4.38 +1997-07-30,16.94,17.69,16.75,17.37,13372400,4.34 +1997-07-29,16.44,16.62,16.37,16.50,2558000,4.12 +1997-07-28,16.44,16.50,16.25,16.44,3962000,4.11 +1997-07-25,15.88,16.56,15.75,16.25,7798000,4.06 +1997-07-24,16.12,16.12,15.63,15.81,4772000,3.95 +1997-07-23,16.75,16.87,16.00,16.12,5049200,4.03 +1997-07-22,16.37,16.69,16.31,16.56,8274400,4.14 +1997-07-21,17.56,17.69,16.00,16.16,12695600,4.04 +1997-07-18,17.87,17.94,17.06,17.34,11353600,4.34 +1997-07-17,17.00,18.12,16.44,17.50,26659200,4.38 +1997-07-16,15.81,16.50,15.63,16.44,15947600,4.11 +1997-07-15,15.75,16.00,15.63,15.94,14953200,3.98 +1997-07-14,15.25,15.63,14.88,15.63,14700800,3.91 +1997-07-11,13.38,15.50,13.31,15.19,26252400,3.80 +1997-07-10,12.88,13.38,12.75,13.25,17606400,3.31 +1997-07-09,13.81,13.88,13.63,13.69,5090000,3.42 +1997-07-08,13.88,14.00,13.69,13.75,3427600,3.44 +1997-07-07,13.94,14.25,13.75,13.81,6860000,3.45 +1997-07-03,13.13,13.88,13.00,13.69,6688000,3.42 +1997-07-02,13.25,13.38,13.00,13.06,8931200,3.27 +1997-07-01,13.94,14.00,13.13,13.19,16104400,3.30 +1997-06-30,14.75,14.75,14.00,14.25,6132400,3.56 +1997-06-27,14.69,14.81,14.63,14.69,5642000,3.67 +1997-06-26,15.13,15.13,14.63,14.69,13643600,3.67 +1997-06-25,15.31,15.38,15.00,15.13,7102000,3.78 +1997-06-24,15.44,15.56,15.25,15.31,3974800,3.83 +1997-06-23,15.50,15.63,15.38,15.38,3574800,3.85 +1997-06-20,15.69,15.75,15.50,15.56,3943600,3.89 +1997-06-19,16.00,16.00,15.69,15.75,4323600,3.94 +1997-06-18,16.12,16.25,15.75,15.94,3936400,3.98 +1997-06-17,15.56,16.50,15.50,16.34,5080800,4.09 +1997-06-16,15.88,15.88,15.38,15.50,4800800,3.88 +1997-06-13,16.06,16.12,15.75,15.81,4737600,3.95 +1997-06-12,16.37,16.37,16.00,16.06,2816400,4.01 +1997-06-11,16.31,16.44,16.25,16.31,3766800,4.08 +1997-06-10,16.75,16.75,16.06,16.25,4969200,4.06 +1997-06-09,16.69,16.94,16.62,16.62,2689200,4.16 +1997-06-06,16.62,16.75,16.50,16.75,1893200,4.19 +1997-06-05,16.62,17.12,16.56,16.69,2323200,4.17 +1997-06-04,16.62,16.75,16.50,16.62,2889200,4.16 +1997-06-03,16.75,16.94,16.62,16.69,2335600,4.17 +1997-06-02,17.00,17.00,16.75,16.94,1488000,4.24 +1997-05-30,16.50,17.00,16.37,16.62,6340800,4.16 +1997-05-29,17.12,17.12,16.62,16.62,3976800,4.16 +1997-05-28,17.37,17.50,17.00,17.00,3130000,4.25 +1997-05-27,16.75,17.37,16.75,17.25,2938000,4.31 +1997-05-23,16.62,17.00,16.62,16.87,2413200,4.22 +1997-05-22,16.75,16.87,16.50,16.62,2753600,4.16 +1997-05-21,17.12,17.12,16.50,16.87,4369200,4.22 +1997-05-20,17.00,17.44,16.75,17.25,3046400,4.31 +1997-05-19,17.50,17.62,17.00,17.00,1881200,4.25 +1997-05-16,17.50,17.62,17.25,17.25,3338800,4.31 +1997-05-15,17.75,18.00,17.50,17.75,3544800,4.44 +1997-05-14,17.87,18.00,17.50,17.69,4846800,4.42 +1997-05-13,17.50,17.87,17.00,17.56,7056800,4.39 +1997-05-12,17.25,17.62,17.00,17.56,5898800,4.39 +1997-05-09,17.00,17.50,17.00,17.06,6732000,4.26 +1997-05-08,16.62,17.12,16.50,17.00,2963200,4.25 +1997-05-07,16.87,17.00,16.37,16.50,4101200,4.12 +1997-05-06,17.00,17.12,16.75,16.87,2974800,4.22 +1997-05-05,17.00,17.12,16.75,17.00,3538800,4.25 +1997-05-02,17.00,17.12,16.75,17.00,3643600,4.25 +1997-05-01,16.87,17.12,16.75,17.00,2596800,4.25 +1997-04-30,17.00,17.25,16.75,17.00,9202000,4.25 +1997-04-29,18.00,18.00,17.50,17.69,1853200,4.42 +1997-04-28,17.75,17.87,17.50,17.62,1687600,4.41 +1997-04-25,17.62,17.87,17.37,17.50,3121200,4.38 +1997-04-24,18.50,18.50,17.75,17.87,2696800,4.47 +1997-04-23,18.37,18.50,18.12,18.12,1960800,4.53 +1997-04-22,18.12,18.50,17.87,18.50,3392000,4.62 +1997-04-21,18.62,18.62,18.00,18.00,3197600,4.50 +1997-04-18,19.12,19.12,18.37,18.37,5058000,4.59 +1997-04-17,18.25,19.12,18.12,19.00,7859200,4.75 +1997-04-16,18.62,19.00,18.37,18.56,3101200,4.64 +1997-04-15,19.12,19.25,18.12,18.44,4869200,4.61 +1997-04-14,18.37,18.87,18.00,18.75,4020000,4.69 +1997-04-11,18.87,18.87,18.12,18.25,2842400,4.56 +1997-04-10,19.00,19.12,18.50,18.87,4188000,4.72 +1997-04-09,19.25,19.25,18.87,19.00,8766400,4.75 +1997-04-08,19.62,19.62,18.62,19.12,6923600,4.78 +1997-04-07,19.75,19.87,19.25,19.50,9136800,4.88 +1997-04-04,19.12,19.62,19.00,19.25,16980800,4.81 +1997-04-03,18.50,19.12,18.25,18.87,19603200,4.72 +1997-04-02,17.87,18.06,17.62,18.00,7957600,4.50 +1997-04-01,17.62,17.81,17.37,17.50,7881200,4.38 +1997-03-31,18.62,19.37,17.25,18.25,34658000,4.56 +1997-03-27,17.50,19.25,17.25,18.62,40695200,4.66 +1997-03-26,16.37,16.87,16.25,16.75,3824400,4.19 +1997-03-25,16.62,16.62,16.08,16.50,4031200,4.12 +1997-03-24,16.50,16.62,16.25,16.50,2556800,4.12 +1997-03-21,17.50,17.50,16.37,16.62,4892400,4.16 +1997-03-20,16.00,17.50,15.88,17.25,11324400,4.31 +1997-03-19,16.37,16.37,15.88,16.12,7457600,4.03 +1997-03-18,16.37,16.50,16.12,16.25,4548800,4.06 +1997-03-17,16.25,16.50,16.00,16.50,6886400,4.12 +1997-03-14,16.37,16.75,16.25,16.56,8245600,4.14 +1997-03-13,16.37,16.37,16.12,16.37,3772000,4.09 +1997-03-12,16.25,16.75,16.12,16.25,2544400,4.06 +1997-03-11,16.62,16.62,16.00,16.37,3539200,4.09 +1997-03-10,16.62,16.75,16.44,16.62,3554800,4.16 +1997-03-07,16.75,16.75,16.37,16.50,2523200,4.12 +1997-03-06,17.00,17.00,16.50,16.62,4172000,4.16 +1997-03-05,16.62,17.00,16.50,17.00,3453600,4.25 +1997-03-04,16.25,16.50,16.00,16.50,3688800,4.12 +1997-03-03,16.50,16.50,16.00,16.12,4670000,4.03 +1997-02-28,16.87,16.87,16.25,16.25,4371200,4.06 +1997-02-27,17.00,17.12,16.75,17.00,3700000,4.25 +1997-02-26,17.00,17.12,16.75,17.12,3687600,4.28 +1997-02-25,17.00,17.37,16.87,16.87,4938000,4.22 +1997-02-24,16.25,16.87,16.25,16.62,4222000,4.16 +1997-02-21,16.87,17.00,16.00,16.37,7549200,4.09 +1997-02-20,17.62,17.62,17.00,17.00,4474800,4.25 +1997-02-19,17.87,17.87,17.12,17.62,8627600,4.41 +1997-02-18,16.62,17.87,16.25,17.87,13171200,4.47 +1997-02-14,16.25,16.37,16.00,16.31,8492000,4.08 +1997-02-13,15.75,16.12,15.50,16.12,7013200,4.03 +1997-02-12,15.75,15.88,15.50,15.75,6303600,3.94 +1997-02-11,15.88,16.00,15.50,15.69,5004400,3.92 +1997-02-10,16.12,16.12,15.63,15.63,6633600,3.91 +1997-02-07,16.50,16.50,15.75,15.81,8403600,3.95 +1997-02-06,15.25,16.12,15.25,16.00,14283600,4.00 +1997-02-05,15.25,15.63,15.25,15.25,14093600,3.81 +1997-02-04,16.25,16.37,15.13,15.38,25458000,3.85 +1997-02-03,16.87,17.00,16.25,16.31,13162000,4.08 +1997-01-31,16.62,16.62,16.50,16.62,7135200,4.16 +1997-01-30,16.75,16.75,16.50,16.75,5018800,4.19 +1997-01-29,16.62,16.75,16.50,16.62,5428000,4.16 +1997-01-28,17.00,17.00,16.50,16.62,7520000,4.16 +1997-01-27,17.12,17.25,16.62,16.62,7646800,4.16 +1997-01-24,17.25,17.25,16.87,16.87,6726800,4.22 +1997-01-23,17.25,17.37,17.12,17.25,6175200,4.31 +1997-01-22,17.37,17.50,17.00,17.19,7356800,4.30 +1997-01-21,17.00,17.25,16.87,17.25,10179200,4.31 +1997-01-20,16.87,17.12,16.75,16.94,10423600,4.24 +1997-01-17,16.75,17.12,16.62,16.75,11619200,4.19 +1997-01-16,17.12,17.12,16.62,16.75,23983600,4.19 +1997-01-15,18.00,18.00,17.12,17.25,15483200,4.31 +1997-01-14,18.37,18.37,17.75,17.87,9143200,4.47 +1997-01-13,18.50,18.50,18.12,18.12,10942000,4.53 +1997-01-10,17.62,18.25,17.62,18.25,12651200,4.56 +1997-01-09,17.75,17.87,17.50,17.75,15970000,4.44 +1997-01-08,18.25,18.37,17.37,17.62,39296400,4.41 +1997-01-07,18.12,18.25,17.50,17.50,34896400,4.38 +1997-01-06,17.62,18.34,17.25,17.87,67246400,4.47 +1997-01-03,21.12,22.25,21.00,21.75,4295600,5.44 +1997-01-02,21.12,21.25,20.75,21.00,5128800,5.25 +1996-12-31,21.37,21.50,20.75,20.87,13719200,5.22 +1996-12-30,23.12,23.25,21.75,21.75,9366800,5.44 +1996-12-27,22.87,23.75,22.87,23.12,4900000,5.78 +1996-12-26,23.25,23.25,22.87,23.00,3049200,5.75 +1996-12-24,23.25,23.37,22.87,23.12,2067600,5.78 +1996-12-23,24.00,24.25,23.25,23.25,11883600,5.81 +1996-12-20,22.50,23.62,21.37,23.50,19535600,5.88 +1996-12-19,23.00,23.25,22.25,22.25,4893600,5.56 +1996-12-18,22.75,23.12,22.62,23.12,7326400,5.78 +1996-12-17,22.37,22.50,22.25,22.50,5625200,5.62 +1996-12-16,23.50,23.50,22.50,22.62,5335600,5.66 +1996-12-13,23.75,23.87,23.25,23.25,3194400,5.81 +1996-12-12,24.12,24.25,23.87,23.87,3122400,5.97 +1996-12-11,23.75,24.25,23.75,24.00,5853600,6.00 +1996-12-10,24.87,25.00,24.25,24.50,6593600,6.12 +1996-12-09,25.25,25.37,24.81,25.00,5680800,6.25 +1996-12-06,24.37,25.37,24.00,25.12,8210800,6.28 +1996-12-05,25.00,25.25,25.00,25.00,5096800,6.25 +1996-12-04,25.12,25.37,24.87,25.00,6823600,6.25 +1996-12-03,25.25,25.50,25.00,25.12,9840800,6.28 +1996-12-02,24.12,25.12,23.87,25.12,6254400,6.28 +1996-11-29,24.50,24.62,24.00,24.12,1527600,6.03 +1996-11-27,24.12,24.62,24.12,24.50,3191200,6.12 +1996-11-26,24.87,25.00,24.00,24.25,4054800,6.06 +1996-11-25,25.37,25.50,25.00,25.00,2830800,6.25 +1996-11-22,24.50,25.25,24.50,25.25,3732400,6.31 +1996-11-21,24.87,25.00,24.37,24.50,2522400,6.12 +1996-11-20,24.87,25.37,24.87,25.00,3683200,6.25 +1996-11-19,24.87,25.12,24.62,24.87,4446400,6.22 +1996-11-18,25.00,25.12,24.50,24.75,5468800,6.19 +1996-11-15,25.87,26.00,25.00,25.00,4684400,6.25 +1996-11-14,25.50,25.75,25.37,25.62,1740800,6.41 +1996-11-13,25.37,25.87,25.00,25.56,3000800,6.39 +1996-11-12,26.12,26.25,25.12,25.25,5120000,6.31 +1996-11-11,26.37,26.37,25.87,26.00,3318800,6.50 +1996-11-08,25.87,26.25,25.75,26.25,6750800,6.56 +1996-11-07,25.37,26.00,25.25,25.87,5548800,6.47 +1996-11-06,25.62,25.75,24.87,25.50,6462000,6.38 +1996-11-05,24.50,25.87,24.50,25.50,13517600,6.38 +1996-11-04,24.37,24.50,23.75,24.37,3270800,6.09 +1996-11-01,23.37,24.25,23.12,24.25,7563200,6.06 +1996-10-31,23.25,23.37,22.25,23.00,6945600,5.75 +1996-10-30,23.50,24.00,22.87,22.87,9192000,5.72 +1996-10-29,24.62,24.75,23.12,23.25,7135200,5.81 +1996-10-28,25.12,25.12,24.50,24.50,4288800,6.12 +1996-10-25,24.87,25.00,24.50,24.50,2775600,6.12 +1996-10-24,25.00,25.00,24.50,24.75,3020800,6.19 +1996-10-23,24.75,25.25,24.37,24.75,5736800,6.19 +1996-10-22,25.62,25.62,24.25,24.87,7651200,6.22 +1996-10-21,26.50,26.62,25.50,25.62,6712000,6.41 +1996-10-18,26.50,26.62,26.00,26.56,13681200,6.64 +1996-10-17,27.50,27.75,26.37,26.37,36679200,6.59 +1996-10-16,25.25,26.12,24.62,25.75,11975200,6.44 +1996-10-15,25.75,25.87,25.00,25.25,12970000,6.31 +1996-10-14,24.50,25.37,24.25,25.25,9649200,6.31 +1996-10-11,24.37,24.62,24.00,24.25,4327600,6.06 +1996-10-10,23.87,24.50,23.75,24.19,9883200,6.05 +1996-10-09,23.37,23.62,22.87,23.00,3044800,5.75 +1996-10-08,23.50,24.25,23.25,23.25,6802000,5.81 +1996-10-07,23.00,23.37,22.87,23.12,3428800,5.78 +1996-10-04,22.87,23.12,22.12,22.81,4770000,5.70 +1996-10-03,23.62,23.75,22.37,22.37,8140000,5.59 +1996-10-02,23.62,24.62,23.12,23.62,9890000,5.91 +1996-10-01,22.00,24.75,22.00,24.62,19269200,6.16 +1996-09-30,22.12,22.37,22.12,22.19,3058000,5.55 +1996-09-27,22.25,22.37,22.12,22.31,2932000,5.58 +1996-09-26,22.37,22.50,22.25,22.37,3693600,5.59 +1996-09-25,22.50,22.62,22.00,22.37,3902400,5.59 +1996-09-24,22.37,22.87,22.37,22.50,5143600,5.62 +1996-09-23,22.87,22.87,22.37,22.37,1653600,5.59 +1996-09-20,23.37,23.50,22.75,22.87,5330800,5.72 +1996-09-19,23.62,23.62,23.37,23.37,4282000,5.84 +1996-09-18,23.00,24.12,22.87,23.50,12631200,5.88 +1996-09-17,22.87,23.12,22.50,23.00,7487600,5.75 +1996-09-16,21.50,23.00,21.37,22.37,8747600,5.59 +1996-09-13,20.37,21.25,20.37,21.00,5967600,5.25 +1996-09-12,21.00,21.12,20.25,20.37,9340000,5.09 +1996-09-11,21.50,21.75,21.00,21.12,5266800,5.28 +1996-09-10,22.12,22.12,21.50,21.50,5562000,5.38 +1996-09-09,22.62,22.75,21.87,22.00,5302400,5.50 +1996-09-06,23.12,23.25,22.62,23.00,8602000,5.75 +1996-09-05,23.50,23.75,22.87,22.87,9999200,5.72 +1996-09-04,23.87,24.62,23.87,24.12,3636400,6.03 +1996-09-03,24.12,24.37,23.87,24.12,2461200,6.03 +1996-08-30,24.75,24.75,24.25,24.25,3784800,6.06 +1996-08-29,24.87,24.87,24.37,24.50,3829200,6.12 +1996-08-28,24.87,25.00,24.50,24.87,5844400,6.22 +1996-08-27,24.12,25.00,24.00,24.86,10339200,6.22 +1996-08-26,23.87,24.12,23.50,24.12,3204400,6.03 +1996-08-23,23.00,24.00,23.00,23.87,7281200,5.97 +1996-08-22,23.00,23.25,22.87,23.25,3138000,5.81 +1996-08-21,23.50,23.62,22.87,23.00,4052400,5.75 +1996-08-20,23.87,23.87,23.37,23.50,7564400,5.88 +1996-08-19,22.37,23.62,22.37,23.62,8084400,5.91 +1996-08-16,22.62,22.62,22.12,22.50,5075600,5.62 +1996-08-15,22.62,22.75,22.25,22.25,3845600,5.56 +1996-08-14,22.62,23.00,22.62,22.75,2570000,5.69 +1996-08-13,22.87,23.12,22.37,22.50,3706400,5.62 +1996-08-12,23.37,23.62,22.37,23.00,5408000,5.75 +1996-08-09,22.25,23.37,22.12,23.12,8243600,5.78 +1996-08-08,22.37,22.37,21.87,22.12,3640000,5.53 +1996-08-07,21.75,22.62,21.62,22.37,8892400,5.59 +1996-08-06,21.00,21.50,20.75,21.50,3354800,5.38 +1996-08-05,21.62,21.87,20.87,21.00,3612000,5.25 +1996-08-02,21.62,22.00,21.25,21.62,4574800,5.41 +1996-08-01,22.00,22.00,21.12,21.25,3942400,5.31 +1996-07-31,21.25,22.00,21.25,22.00,3332400,5.50 +1996-07-30,22.62,22.75,21.25,21.37,6766800,5.34 +1996-07-29,22.00,22.50,21.75,22.25,7005600,5.56 +1996-07-26,21.50,22.00,21.12,22.00,4426800,5.50 +1996-07-25,21.12,21.37,20.75,21.00,4090800,5.25 +1996-07-24,20.00,21.00,19.87,20.81,9448800,5.20 +1996-07-23,20.50,20.62,20.25,20.50,4651200,5.12 +1996-07-22,20.87,20.87,20.00,20.25,5456400,5.06 +1996-07-19,20.87,21.00,20.75,20.75,9510000,5.19 +1996-07-18,21.50,21.75,20.36,20.87,32058800,5.22 +1996-07-17,17.37,17.50,16.62,16.87,8355600,4.22 +1996-07-16,17.37,17.37,16.00,16.87,10334400,4.22 +1996-07-15,18.12,18.12,17.12,17.19,4779200,4.30 +1996-07-12,18.37,18.37,17.25,18.06,9610800,4.51 +1996-07-11,18.75,18.87,17.37,17.87,10420000,4.47 +1996-07-10,19.12,19.50,18.75,18.75,6055200,4.69 +1996-07-09,19.50,19.62,19.00,19.00,6723600,4.75 +1996-07-08,19.62,19.87,19.00,19.12,6762000,4.78 +1996-07-05,19.37,19.75,19.25,19.50,3808800,4.88 +1996-07-03,20.37,20.37,19.37,19.37,10323200,4.84 +1996-07-02,21.37,21.50,21.00,21.00,3189200,5.25 +1996-07-01,21.12,21.50,21.00,21.50,4732400,5.38 +1996-06-28,20.87,21.00,20.62,21.00,4138000,5.25 +1996-06-27,20.00,21.00,19.75,20.62,8202400,5.16 +1996-06-26,20.62,20.75,19.62,19.87,14440800,4.97 +1996-06-25,22.12,22.25,20.37,20.62,8831200,5.16 +1996-06-24,22.62,22.62,22.12,22.25,4398000,5.56 +1996-06-21,22.87,22.87,22.37,22.62,5792000,5.66 +1996-06-20,23.37,23.37,22.50,22.75,5260800,5.69 +1996-06-19,23.12,23.37,22.62,23.12,4803600,5.78 +1996-06-18,23.62,23.75,22.62,22.75,7979200,5.69 +1996-06-17,24.12,24.12,23.62,23.62,4052000,5.91 +1996-06-14,24.75,24.75,23.87,23.94,5186800,5.99 +1996-06-13,24.37,24.92,24.00,24.62,6856800,6.16 +1996-06-12,24.50,24.50,24.00,24.25,5440000,6.06 +1996-06-11,24.25,24.25,24.00,24.00,5481200,6.00 +1996-06-10,24.37,24.50,24.00,24.12,3820800,6.03 +1996-06-07,24.00,24.37,23.50,24.37,9565200,6.09 +1996-06-06,25.00,25.25,24.12,24.25,12938800,6.06 +1996-06-05,25.37,25.50,24.25,25.12,18228000,6.28 +1996-06-04,24.00,24.37,23.87,24.19,27235600,6.05 +1996-06-03,25.87,26.00,24.75,24.75,4481200,6.19 +1996-05-31,25.62,26.62,25.50,26.12,5813600,6.53 +1996-05-30,24.87,25.75,24.75,25.50,3703600,6.38 +1996-05-29,26.25,26.25,24.75,24.87,7840000,6.22 +1996-05-28,26.75,27.25,26.37,26.37,3658800,6.59 +1996-05-24,26.25,26.87,26.12,26.75,4046800,6.69 +1996-05-23,26.12,26.62,25.75,26.25,4447600,6.56 +1996-05-22,27.37,27.37,25.75,26.06,7215600,6.51 +1996-05-21,28.00,28.12,27.12,27.12,4088000,6.78 +1996-05-20,27.87,28.12,27.62,27.94,3028800,6.99 +1996-05-17,28.37,28.37,27.50,27.62,4405600,6.91 +1996-05-16,28.25,28.62,27.87,28.37,4648800,7.09 +1996-05-15,27.87,28.87,27.75,28.50,10442400,7.12 +1996-05-14,27.75,28.00,27.50,27.50,7068000,6.88 +1996-05-13,27.12,27.62,26.62,27.06,6701200,6.76 +1996-05-10,26.25,27.37,26.00,27.25,3966400,6.81 +1996-05-09,26.37,26.50,25.75,26.12,3515600,6.53 +1996-05-08,27.25,27.25,25.62,26.75,6688800,6.69 +1996-05-07,26.37,27.37,26.25,26.87,12641200,6.72 +1996-05-06,24.87,25.87,24.75,25.62,10349200,6.41 +1996-05-03,24.12,24.12,23.50,23.87,3892400,5.97 +1996-05-02,24.50,24.50,23.50,23.75,6728000,5.94 +1996-05-01,24.37,24.75,24.12,24.37,4039200,6.09 +1996-04-30,24.87,24.87,24.12,24.37,4881200,6.09 +1996-04-29,25.00,25.00,24.50,24.75,4324800,6.19 +1996-04-26,25.00,25.12,24.62,24.75,6759200,6.19 +1996-04-25,24.37,24.87,24.12,24.87,6245200,6.22 +1996-04-24,24.62,24.75,24.19,24.25,4596800,6.06 +1996-04-23,25.12,25.25,24.62,24.75,6086400,6.19 +1996-04-22,25.25,25.50,24.87,25.12,3973200,6.28 +1996-04-19,24.62,25.12,24.62,25.06,3655600,6.26 +1996-04-18,25.37,25.39,24.25,24.75,7780800,6.19 +1996-04-17,25.87,26.00,25.12,25.25,3056400,6.31 +1996-04-16,25.87,26.00,25.62,25.87,3634400,6.47 +1996-04-15,25.50,25.75,25.00,25.75,5515600,6.44 +1996-04-12,25.87,25.87,25.37,25.50,2924400,6.38 +1996-04-11,26.12,26.25,25.50,25.75,3526400,6.44 +1996-04-10,26.12,26.50,25.87,26.00,6242400,6.50 +1996-04-09,24.87,26.50,24.37,26.00,8415600,6.50 +1996-04-08,23.87,24.50,23.75,24.37,6046400,6.09 +1996-04-04,24.62,24.62,24.00,24.12,3092000,6.03 +1996-04-03,25.12,25.12,24.33,24.56,2591200,6.14 +1996-04-02,25.62,25.62,24.87,25.00,3635600,6.25 +1996-04-01,25.12,25.87,24.52,25.50,5680000,6.38 +1996-03-29,24.25,24.75,23.75,24.56,5962400,6.14 +1996-03-28,24.75,25.62,24.12,24.19,10572000,6.05 +1996-03-27,23.25,25.25,23.00,25.25,15338800,6.31 +1996-03-26,24.00,24.50,23.62,23.87,5755600,5.97 +1996-03-25,25.50,25.75,24.00,24.00,5887600,6.00 +1996-03-22,25.25,25.37,24.87,25.37,3842400,6.34 +1996-03-21,25.50,25.50,25.00,25.12,3932400,6.28 +1996-03-20,25.75,25.75,25.12,25.25,4154800,6.31 +1996-03-19,26.37,26.50,25.62,25.75,4442400,6.44 +1996-03-18,25.94,26.12,25.75,26.12,3907600,6.53 +1996-03-15,26.00,26.00,25.50,25.87,3632400,6.47 +1996-03-14,25.87,25.87,25.50,25.62,3342400,6.41 +1996-03-13,25.87,26.12,25.62,25.75,3560000,6.44 +1996-03-12,26.00,26.37,25.62,25.81,3453200,6.45 +1996-03-11,26.25,26.37,25.75,25.87,4544800,6.47 +1996-03-08,25.75,26.25,25.00,26.00,5322400,6.50 +1996-03-07,26.25,26.37,25.37,25.81,9292400,6.45 +1996-03-06,26.75,26.87,26.12,26.19,3547600,6.55 +1996-03-05,26.50,26.75,26.25,26.62,4246800,6.66 +1996-03-04,27.25,27.37,26.25,26.25,6708800,6.56 +1996-03-01,27.62,27.62,26.62,26.87,8263200,6.72 +1996-02-29,27.50,27.75,27.25,27.50,4049200,6.88 +1996-02-28,28.87,28.87,27.62,27.75,6728800,6.94 +1996-02-27,29.87,29.87,28.50,28.62,5331200,7.16 +1996-02-26,30.00,30.12,29.50,29.50,4238000,7.38 +1996-02-23,29.87,30.25,29.62,29.87,6205200,7.47 +1996-02-22,30.00,30.12,29.62,29.87,6588000,7.47 +1996-02-21,29.37,29.75,29.12,29.62,7924400,7.41 +1996-02-20,28.00,29.50,28.00,29.00,13473200,7.25 +1996-02-16,28.12,28.37,27.50,27.50,5602400,6.88 +1996-02-15,27.62,28.12,27.37,28.00,4360000,7.00 +1996-02-14,28.25,28.25,27.44,27.62,5843600,6.91 +1996-02-13,28.00,28.87,27.87,28.12,8161200,7.03 +1996-02-12,28.12,28.50,28.00,28.37,6948800,7.09 +1996-02-09,27.87,28.50,27.62,27.75,7360800,6.94 +1996-02-08,27.50,28.12,27.50,27.87,9420800,6.97 +1996-02-07,29.75,29.75,27.75,28.25,12885200,7.06 +1996-02-06,29.25,30.00,29.25,29.62,8101200,7.41 +1996-02-05,29.69,29.75,29.00,29.25,11396400,7.31 +1996-02-02,28.87,29.62,28.75,29.25,19865600,7.31 +1996-02-01,27.50,28.37,27.50,28.37,11902400,7.09 +1996-01-31,27.75,28.00,27.37,27.62,11736800,6.91 +1996-01-30,27.00,28.12,26.86,27.31,22246800,6.83 +1996-01-29,29.00,29.75,28.75,29.12,11900000,7.28 +1996-01-26,30.37,31.25,28.62,30.62,26297600,7.66 +1996-01-25,31.75,32.00,30.12,30.25,15911200,7.56 +1996-01-24,32.13,32.25,31.75,32.25,23438800,8.06 +1996-01-23,33.75,34.00,31.00,31.62,35305200,7.91 +1996-01-22,29.75,31.00,29.25,30.50,17852400,7.62 +1996-01-19,31.00,31.75,29.37,29.87,29623600,7.47 +1996-01-18,32.88,33.38,30.37,31.94,24955200,7.99 +1996-01-17,34.38,34.38,33.75,34.00,8445200,8.50 +1996-01-16,34.38,34.75,33.63,34.56,12606400,8.64 +1996-01-15,33.75,34.50,33.38,34.13,12971200,8.53 +1996-01-12,34.75,34.75,33.25,33.88,14370000,8.47 +1996-01-11,32.63,35.00,32.38,35.00,27041200,8.75 +1996-01-10,32.50,34.75,32.25,34.25,13057600,8.56 +1996-01-09,34.63,34.63,32.75,32.75,8978800,8.19 +1996-01-08,34.50,35.50,34.00,34.63,4341200,8.66 +1996-01-05,31.62,34.25,31.37,34.25,15929200,8.56 +1996-01-04,32.38,32.38,31.37,31.56,10721200,7.89 +1996-01-03,32.00,32.88,31.87,32.13,15368800,8.03 +1996-01-02,32.25,32.25,31.75,32.13,4983200,8.03 +1995-12-29,32.00,32.38,31.62,31.87,10874400,7.97 +1995-12-28,32.13,32.75,31.87,32.00,8933200,8.00 +1995-12-27,32.13,33.38,31.87,32.38,9609200,8.10 +1995-12-26,32.50,32.50,31.75,32.06,4994800,8.02 +1995-12-22,32.63,32.88,32.13,32.25,8392400,8.06 +1995-12-21,32.75,32.75,31.62,32.50,11893200,8.12 +1995-12-20,33.50,33.63,32.50,32.63,13074400,8.16 +1995-12-19,32.75,33.25,32.25,32.75,15403600,8.19 +1995-12-18,35.13,35.25,31.87,32.25,23807600,8.06 +1995-12-15,35.50,36.63,34.38,35.25,25960000,8.81 +1995-12-14,38.88,39.38,38.00,38.25,11928000,9.56 +1995-12-13,38.25,39.00,36.75,38.38,24472400,9.60 +1995-12-12,38.63,38.63,38.00,38.00,6353200,9.50 +1995-12-11,39.50,39.63,38.38,38.63,4003200,9.66 +1995-12-08,38.75,39.38,37.88,39.38,5053200,9.85 +1995-12-07,38.75,38.75,37.88,38.56,5084800,9.64 +1995-12-06,39.75,39.88,38.38,38.75,7195200,9.69 +1995-12-05,38.50,39.88,38.25,39.50,13000000,9.88 +1995-12-04,40.13,40.13,39.00,39.50,17171200,9.88 +1995-12-01,38.00,38.25,37.13,37.63,7300800,9.41 +1995-11-30,38.88,39.00,38.00,38.13,6247600,9.53 +1995-11-29,40.13,40.13,39.00,39.25,3782000,9.81 +1995-11-28,39.38,40.13,39.25,40.00,6305200,10.00 +1995-11-27,40.63,40.63,39.38,39.38,4148800,9.85 +1995-11-24,38.88,40.38,38.75,40.19,3930800,10.05 +1995-11-22,38.63,39.25,38.50,38.63,3533600,9.66 +1995-11-21,38.75,38.75,37.88,38.63,6845200,9.66 +1995-11-20,40.25,40.25,38.50,38.63,5314400,9.63 +1995-11-17,40.00,40.38,39.75,40.13,4607600,10.00 +1995-11-16,40.88,41.50,39.50,39.94,8102000,9.95 +1995-11-15,42.00,42.00,40.13,41.00,8874400,10.22 +1995-11-14,41.00,42.50,41.00,41.50,14560000,10.34 +1995-11-13,40.25,41.25,40.00,40.88,11343200,10.19 +1995-11-10,39.38,40.25,38.88,39.75,7973200,9.91 +1995-11-09,39.75,40.00,38.88,39.38,9295200,9.81 +1995-11-08,39.75,41.00,38.75,38.88,12823600,9.69 +1995-11-07,37.75,40.50,37.50,39.63,26310800,9.88 +1995-11-06,36.50,38.75,36.38,38.13,11143200,9.50 +1995-11-03,36.75,36.88,35.88,36.50,6413200,9.10 +1995-11-02,36.88,36.88,36.25,36.63,5464400,9.13 +1995-11-01,36.63,37.13,35.50,36.63,6913200,9.13 +1995-10-31,35.25,36.63,35.13,36.31,10334400,9.05 +1995-10-30,34.88,35.25,34.63,35.25,6291200,8.79 +1995-10-27,34.88,34.88,34.13,34.75,5523200,8.66 +1995-10-26,34.88,35.00,34.50,34.88,4503600,8.69 +1995-10-25,35.25,35.38,34.75,34.75,4761200,8.66 +1995-10-24,35.50,35.50,34.88,35.13,7638800,8.76 +1995-10-23,35.13,35.13,34.75,35.13,7078000,8.76 +1995-10-20,35.25,35.25,34.63,35.13,13818800,8.76 +1995-10-19,35.88,36.13,34.75,34.75,33761200,8.66 +1995-10-18,37.00,39.56,36.75,37.38,18311200,9.32 +1995-10-17,36.50,36.88,35.88,36.63,6390000,9.13 +1995-10-16,36.25,37.00,35.88,36.13,6515200,9.00 +1995-10-13,35.75,36.88,35.50,36.00,8422000,8.97 +1995-10-12,35.00,35.38,34.75,35.31,5803200,8.80 +1995-10-11,35.25,35.63,34.13,34.88,11893200,8.69 +1995-10-10,34.38,35.00,33.63,34.69,14303600,8.65 +1995-10-09,35.38,35.75,34.38,34.81,13320800,8.68 +1995-10-06,36.75,37.00,35.63,35.69,11058000,8.89 +1995-10-05,36.25,36.63,35.88,36.50,8737600,9.10 +1995-10-04,36.63,37.00,36.00,36.38,9532000,9.07 +1995-10-03,38.13,38.50,37.13,37.63,10368000,9.38 +1995-10-02,37.75,38.50,37.50,37.63,14000000,9.38 +1995-09-29,38.00,38.25,36.88,37.25,10123200,9.28 +1995-09-28,36.50,37.88,36.50,37.75,11843600,9.41 +1995-09-27,37.50,37.50,34.75,36.25,16135600,9.03 +1995-09-26,37.75,37.88,37.13,37.38,8961200,9.32 +1995-09-25,38.25,38.27,37.38,37.52,11267600,9.35 +1995-09-22,36.88,37.25,36.38,37.06,14258000,9.24 +1995-09-21,36.50,37.50,36.38,37.00,12407600,9.22 +1995-09-20,37.25,37.38,36.50,36.63,11500800,9.13 +1995-09-19,36.75,37.13,36.13,36.75,17512400,9.16 +1995-09-18,36.38,36.81,35.88,36.69,22216400,9.14 +1995-09-15,37.38,39.88,35.50,35.88,43286800,8.94 +1995-09-14,41.38,41.63,39.75,40.00,19675600,9.97 +1995-09-13,42.88,43.38,42.00,42.38,11530800,10.56 +1995-09-12,44.50,44.88,42.63,42.94,11658800,10.70 +1995-09-11,44.88,45.50,44.25,44.25,6160800,11.03 +1995-09-08,44.75,44.88,44.50,44.75,6243200,11.15 +1995-09-07,44.00,45.31,43.75,44.75,9373600,11.15 +1995-09-06,43.88,44.17,43.50,43.75,7175600,10.90 +1995-09-05,43.50,43.50,42.75,43.50,6443200,10.84 +1995-09-01,43.00,43.50,42.88,42.94,3532400,10.70 +1995-08-31,43.38,43.50,43.00,43.00,3148000,10.72 +1995-08-30,43.25,43.75,43.13,43.38,5482000,10.81 +1995-08-29,43.00,43.25,42.50,43.13,11325600,10.75 +1995-08-28,44.88,45.00,43.00,43.00,8680000,10.72 +1995-08-25,45.88,45.88,44.63,44.75,4819200,11.15 +1995-08-24,45.63,46.25,45.50,45.75,10285200,11.40 +1995-08-23,44.88,45.88,44.63,45.50,9078000,11.34 +1995-08-22,44.38,45.13,44.13,44.75,7769200,11.15 +1995-08-21,44.88,45.38,44.13,44.13,9721200,11.00 +1995-08-18,44.88,45.13,43.75,44.88,8620000,11.19 +1995-08-17,44.63,45.50,44.13,44.63,8827600,11.12 +1995-08-16,44.00,44.50,43.63,44.50,10457600,11.09 +1995-08-15,43.88,44.13,43.13,44.06,11370800,10.95 +1995-08-14,43.00,43.75,42.88,43.38,5989200,10.78 +1995-08-11,42.88,43.13,41.88,43.06,7407600,10.70 +1995-08-10,43.13,43.25,42.63,42.75,5868000,10.63 +1995-08-09,42.63,43.75,42.50,43.13,13190000,10.72 +1995-08-08,43.63,43.75,42.38,42.50,8388800,10.56 +1995-08-07,44.13,44.63,43.13,43.38,6920000,10.78 +1995-08-04,45.00,45.13,43.75,44.25,6884400,11.00 +1995-08-03,44.13,45.63,43.88,45.00,7640800,11.18 +1995-08-02,43.88,45.00,43.75,44.38,9840800,11.03 +1995-08-01,44.88,44.88,43.50,43.50,7540000,10.81 +1995-07-31,45.50,45.63,44.75,45.00,5673600,11.18 +1995-07-28,46.75,47.25,45.00,45.50,9341200,11.31 +1995-07-27,45.50,47.50,45.50,46.81,11621200,11.63 +1995-07-26,46.25,46.25,45.38,45.38,6125200,11.28 +1995-07-25,46.00,46.38,45.63,45.75,9418000,11.37 +1995-07-24,44.00,45.50,43.75,45.38,7679200,11.28 +1995-07-21,43.00,44.88,43.00,43.75,27082400,10.87 +1995-07-20,46.00,47.38,45.00,47.06,11848800,11.70 +1995-07-19,47.00,48.00,45.00,45.50,18613200,11.31 +1995-07-18,49.00,49.56,47.75,48.13,9102000,11.96 +1995-07-17,48.88,49.75,48.63,49.00,8098000,12.18 +1995-07-14,47.38,49.00,47.00,48.75,9929200,12.12 +1995-07-13,47.38,48.75,47.13,47.63,12596400,11.84 +1995-07-12,47.25,48.00,46.13,47.00,10145200,11.68 +1995-07-11,47.75,48.63,47.06,47.13,7683200,11.71 +1995-07-10,48.63,49.88,48.13,48.63,10640800,12.09 +1995-07-07,46.88,49.25,46.75,48.63,13840000,12.09 +1995-07-06,46.50,47.00,45.75,47.00,6583200,11.68 +1995-07-05,46.88,47.88,46.50,46.50,6325600,11.56 +1995-07-03,46.50,47.13,46.25,46.94,1410800,11.67 +1995-06-30,47.25,47.88,46.13,46.44,5927600,11.54 +1995-06-29,46.38,48.13,46.00,47.25,8320000,11.74 +1995-06-28,46.00,47.50,45.38,46.63,9531200,11.59 +1995-06-27,47.38,48.25,46.38,46.38,7772400,11.53 +1995-06-26,48.25,48.50,47.63,48.13,5465600,11.96 +1995-06-23,48.75,49.00,47.75,48.75,8286800,12.12 +1995-06-22,49.00,49.63,48.63,49.13,16928800,12.21 +1995-06-21,47.63,50.13,46.75,49.38,22378800,12.27 +1995-06-20,46.00,47.75,46.00,47.38,26385200,11.78 +1995-06-19,43.88,45.25,43.50,44.38,16774400,11.03 +1995-06-16,43.88,44.00,43.50,43.88,3200800,10.91 +1995-06-15,43.63,43.75,43.38,43.63,3331200,10.84 +1995-06-14,43.88,43.88,43.38,43.63,4224800,10.84 +1995-06-13,44.50,44.63,43.88,44.00,4508000,10.94 +1995-06-12,44.00,44.50,43.88,44.17,7584400,10.98 +1995-06-09,43.63,43.75,43.13,43.50,6679200,10.81 +1995-06-08,43.38,43.38,42.13,42.94,4874400,10.67 +1995-06-07,44.13,44.13,43.13,43.13,4451200,10.72 +1995-06-06,43.63,44.38,43.50,44.00,11270800,10.94 +1995-06-05,42.38,43.50,42.13,43.50,9103200,10.81 +1995-06-02,41.88,42.38,41.50,42.13,3783200,10.47 +1995-06-01,41.88,42.50,41.75,42.19,6685200,10.49 +1995-05-31,42.13,42.13,41.00,41.56,5707600,10.33 +1995-05-30,42.63,42.88,41.50,42.00,7021200,10.44 +1995-05-26,43.00,43.13,42.25,42.69,4097600,10.61 +1995-05-25,43.25,44.00,43.00,43.38,6536800,10.75 +1995-05-24,43.75,44.25,42.88,43.50,9459200,10.78 +1995-05-23,44.13,44.38,43.50,43.88,9881200,10.88 +1995-05-22,42.50,44.13,42.25,44.13,13282400,10.94 +1995-05-19,42.88,43.75,42.63,42.75,11522000,10.60 +1995-05-18,44.13,44.13,43.25,43.38,13287600,10.75 +1995-05-17,43.75,44.38,43.50,44.00,9419200,10.91 +1995-05-16,43.13,44.38,42.50,43.75,11895600,10.84 +1995-05-15,43.13,43.75,42.50,43.63,14053200,10.81 +1995-05-12,40.88,43.69,40.50,43.63,23153200,10.81 +1995-05-11,41.63,41.63,40.38,41.00,18712400,10.16 +1995-05-10,41.50,41.88,40.75,41.44,9837600,10.27 +1995-05-09,40.63,41.38,40.00,41.25,11540800,10.22 +1995-05-08,39.88,41.00,39.75,40.50,13832000,10.04 +1995-05-05,38.75,39.13,38.13,38.88,7445200,9.64 +1995-05-04,38.25,39.88,38.00,38.50,10846800,9.54 +1995-05-03,38.25,38.63,38.00,38.13,6043600,9.45 +1995-05-02,38.25,38.38,37.50,38.13,4289200,9.45 +1995-05-01,38.25,38.75,38.00,38.25,6375600,9.48 +1995-04-28,38.00,38.38,37.50,38.25,6984400,9.48 +1995-04-27,38.50,38.50,37.75,37.88,5014800,9.39 +1995-04-26,37.63,38.75,37.38,38.25,8246800,9.48 +1995-04-25,39.13,39.38,37.25,37.75,9780000,9.36 +1995-04-24,39.00,39.63,38.50,39.00,9724400,9.67 +1995-04-21,37.25,39.50,37.13,39.13,23812400,9.70 +1995-04-20,37.13,38.50,36.63,37.63,11772400,9.33 +1995-04-19,37.50,37.50,35.63,36.38,9990800,9.02 +1995-04-18,38.50,38.63,37.50,37.50,8263200,9.29 +1995-04-17,38.13,39.38,37.88,38.38,7467600,9.51 +1995-04-13,39.25,39.25,37.88,38.25,6242400,9.48 +1995-04-12,38.25,39.63,37.38,39.00,16973200,9.67 +1995-04-11,36.75,37.88,36.63,37.75,7673200,9.36 +1995-04-10,36.88,37.00,36.13,36.63,4211200,9.08 +1995-04-07,37.00,37.13,36.25,36.75,10562400,9.11 +1995-04-06,37.25,38.00,35.53,36.75,25823600,9.11 +1995-04-05,34.13,34.75,33.75,34.75,9470000,8.61 +1995-04-04,35.75,35.88,33.63,33.88,15300000,8.40 +1995-04-03,35.50,35.75,35.13,35.50,5528000,8.80 +1995-03-31,35.13,35.63,34.75,35.25,6558000,8.74 +1995-03-30,34.63,35.50,34.50,35.38,9767600,8.77 +1995-03-29,34.00,34.88,33.88,34.38,17760000,8.52 +1995-03-28,36.25,36.34,34.13,34.38,24655600,8.52 +1995-03-27,37.63,37.63,36.63,37.19,5111200,9.22 +1995-03-24,37.38,37.88,37.25,37.75,4584400,9.36 +1995-03-23,37.88,38.00,36.98,37.13,6094400,9.20 +1995-03-22,36.25,39.50,36.25,38.06,17130800,9.43 +1995-03-21,35.50,36.75,35.25,36.25,10920800,8.98 +1995-03-20,35.13,35.63,35.00,35.25,6793600,8.74 +1995-03-17,35.50,35.50,34.88,35.13,7713600,8.71 +1995-03-16,35.25,36.00,35.00,35.25,11330000,8.74 +1995-03-15,35.50,36.25,34.88,35.00,26120800,8.67 +1995-03-14,38.25,38.25,34.50,35.00,26015200,8.67 +1995-03-13,39.63,39.63,38.00,38.13,11653200,9.45 +1995-03-10,39.63,40.38,39.38,39.50,4923200,9.79 +1995-03-09,39.88,40.38,39.38,39.75,7038000,9.85 +1995-03-08,38.75,40.13,37.75,39.56,13048800,9.81 +1995-03-07,39.88,39.88,38.25,38.31,5399200,9.50 +1995-03-06,39.75,40.00,39.50,39.75,4751200,9.85 +1995-03-03,39.75,40.69,39.50,40.25,5209200,9.98 +1995-03-02,40.13,40.75,39.75,40.00,9619200,9.91 +1995-03-01,39.75,40.13,39.42,40.00,8025200,9.91 +1995-02-28,38.50,39.88,38.00,39.50,7965200,9.79 +1995-02-27,38.25,39.00,38.11,38.25,9600800,9.48 +1995-02-24,40.13,40.38,38.50,39.00,20334400,9.67 +1995-02-23,41.13,41.88,40.00,40.19,11262000,9.96 +1995-02-22,40.63,41.00,40.13,40.81,10501200,10.12 +1995-02-21,42.63,42.75,40.88,41.00,10776800,10.16 +1995-02-17,42.88,43.00,42.50,42.50,4366400,10.53 +1995-02-16,43.13,43.25,42.63,43.19,7821200,10.70 +1995-02-15,43.25,43.50,42.50,42.56,6604400,10.55 +1995-02-14,43.75,44.13,42.63,42.94,5934400,10.64 +1995-02-13,43.50,44.50,43.25,43.75,10120800,10.84 +1995-02-10,43.63,44.19,43.38,43.75,12542400,10.81 +1995-02-09,42.13,43.88,42.13,43.63,16988800,10.78 +1995-02-08,41.00,42.38,40.88,42.31,14403600,10.46 +1995-02-07,40.38,41.00,40.00,40.81,7200000,10.09 +1995-02-06,40.75,40.75,39.50,40.50,8702000,10.01 +1995-02-03,42.00,42.13,40.38,40.50,11400800,10.01 +1995-02-02,40.13,41.88,40.13,41.63,7288000,10.29 +1995-02-01,40.75,40.75,39.88,40.13,5665200,9.92 +1995-01-31,40.50,40.88,40.00,40.38,7621200,9.98 +1995-01-30,40.13,40.50,39.88,40.13,8255200,9.92 +1995-01-27,39.88,40.38,39.00,39.88,10676400,9.86 +1995-01-26,40.88,41.50,39.25,39.50,8822000,9.76 +1995-01-25,39.50,42.00,39.50,40.98,18482000,10.13 +1995-01-24,42.25,42.38,41.38,41.63,7805600,10.29 +1995-01-23,41.88,42.63,41.00,42.25,14252400,10.44 +1995-01-20,47.00,47.00,42.50,42.63,35731200,10.54 +1995-01-19,45.50,46.00,45.00,45.88,11238800,11.34 +1995-01-18,45.00,45.63,44.75,45.63,4581200,11.28 +1995-01-17,44.50,45.50,44.13,45.00,11806400,11.12 +1995-01-16,44.88,45.25,44.25,44.50,6765600,11.00 +1995-01-13,46.13,46.13,44.38,44.88,12565600,11.09 +1995-01-12,46.13,46.38,44.75,45.38,19721200,11.22 +1995-01-11,43.75,48.06,42.69,46.75,31212400,11.56 +1995-01-10,41.25,44.00,41.25,43.69,21977600,10.80 +1995-01-09,41.63,41.88,41.00,41.20,9805200,10.18 +1995-01-06,41.63,43.13,41.13,42.00,38456800,10.38 +1995-01-05,39.25,39.38,38.75,38.88,2646800,9.61 +1995-01-04,38.63,39.63,38.63,39.38,5682400,9.73 +1995-01-03,38.88,38.88,37.88,38.38,3726400,9.49 +1994-12-30,39.38,39.88,38.75,39.00,2616400,9.64 +1994-12-29,39.25,39.88,39.13,39.50,4341200,9.76 +1994-12-28,39.13,39.25,38.25,39.13,3198000,9.67 +1994-12-27,39.25,39.75,38.88,39.13,2928800,9.67 +1994-12-23,38.50,39.38,38.50,38.88,3372000,9.61 +1994-12-22,38.50,38.88,38.25,38.63,4771200,9.55 +1994-12-21,37.88,38.50,37.50,38.38,5635600,9.49 +1994-12-20,39.13,39.25,38.38,38.50,6263600,9.52 +1994-12-19,37.25,39.38,37.25,39.13,11890000,9.67 +1994-12-16,37.25,37.75,36.75,37.25,6432400,9.21 +1994-12-15,38.00,38.38,36.88,37.13,8133200,9.18 +1994-12-14,36.50,38.13,36.50,37.88,11123600,9.36 +1994-12-13,36.63,36.94,36.25,36.38,4266800,8.99 +1994-12-12,36.38,36.75,35.50,36.50,8004400,9.02 +1994-12-09,35.88,36.38,34.75,36.25,9329200,8.96 +1994-12-08,36.88,37.00,35.75,35.88,6081200,8.87 +1994-12-07,37.50,37.81,36.06,36.63,4916800,9.05 +1994-12-06,37.00,38.38,36.88,37.56,8516400,9.28 +1994-12-05,36.50,37.38,36.13,37.19,6460000,9.19 +1994-12-02,36.50,36.75,35.63,36.56,6170000,9.04 +1994-12-01,37.00,37.63,36.00,36.19,11051200,8.95 +1994-11-30,38.38,39.38,37.00,37.25,11157600,9.21 +1994-11-29,38.00,38.50,37.75,38.25,5163200,9.45 +1994-11-28,37.63,38.25,37.31,37.81,4971200,9.35 +1994-11-25,36.88,37.75,36.75,37.75,3012400,9.33 +1994-11-23,37.00,37.88,36.38,36.88,11723200,9.12 +1994-11-22,37.75,39.13,37.25,37.38,8018800,9.24 +1994-11-21,40.00,40.25,38.00,38.13,7255600,9.42 +1994-11-18,40.00,40.50,39.63,40.00,5257600,9.89 +1994-11-17,40.88,41.00,39.88,40.00,5380000,9.86 +1994-11-16,40.75,41.56,40.63,40.94,6700000,10.09 +1994-11-15,42.50,43.00,41.25,41.38,6001200,10.20 +1994-11-14,41.25,42.75,41.25,42.50,5002000,10.47 +1994-11-11,41.25,41.50,41.00,41.13,2237600,10.14 +1994-11-10,41.75,41.88,41.00,41.31,5476800,10.18 +1994-11-09,42.75,43.00,41.00,41.63,14530000,10.26 +1994-11-08,40.63,42.63,40.25,42.25,12476400,10.41 +1994-11-07,40.38,41.25,40.13,40.75,4058000,10.04 +1994-11-04,41.50,41.63,40.00,40.38,6869200,9.95 +1994-11-03,41.75,42.00,41.00,41.50,3962400,10.23 +1994-11-02,43.13,43.25,41.38,41.38,7819200,10.20 +1994-11-01,42.88,43.48,42.38,43.13,7805600,10.63 +1994-10-31,42.00,43.38,41.50,43.19,12728000,10.64 +1994-10-28,42.38,42.88,41.75,42.13,9762400,10.38 +1994-10-27,43.25,43.75,42.50,42.75,5700800,10.54 +1994-10-26,42.63,43.27,42.63,43.25,7043200,10.66 +1994-10-25,41.63,42.63,41.50,42.63,10771200,10.51 +1994-10-24,42.75,43.13,41.88,42.25,7316800,10.41 +1994-10-21,40.75,42.75,40.75,42.63,11528000,10.51 +1994-10-20,41.25,41.81,40.50,41.00,7808000,10.10 +1994-10-19,41.00,42.13,41.00,41.25,12549200,10.17 +1994-10-18,40.63,41.63,40.50,41.25,16749200,10.17 +1994-10-17,40.88,41.50,38.88,39.75,10866400,9.80 +1994-10-14,41.50,42.00,40.88,41.13,6292000,10.14 +1994-10-13,42.63,42.88,40.63,41.13,18761200,10.14 +1994-10-12,39.63,42.63,39.13,42.13,21340000,10.38 +1994-10-11,41.38,41.88,39.38,39.63,30083600,9.77 +1994-10-10,37.13,39.63,37.00,38.88,18700800,9.58 +1994-10-07,36.13,37.06,35.50,37.00,13022000,9.12 +1994-10-06,37.38,37.48,36.00,36.25,18828800,8.93 +1994-10-05,33.63,38.13,33.38,37.88,25366800,9.33 +1994-10-04,33.25,34.00,33.00,33.75,5822000,8.32 +1994-10-03,33.63,33.75,32.50,33.13,4644400,8.16 +1994-09-30,34.13,34.50,33.63,33.69,2561200,8.30 +1994-09-29,33.75,34.38,33.38,34.13,3921200,8.41 +1994-09-28,34.00,34.38,33.63,33.88,2914800,8.35 +1994-09-27,33.75,34.13,33.38,33.88,3904800,8.35 +1994-09-26,33.88,34.50,33.63,33.94,5072400,8.36 +1994-09-23,33.88,34.50,33.88,33.94,4760000,8.36 +1994-09-22,34.25,34.25,33.63,33.88,5235600,8.35 +1994-09-21,34.50,34.63,33.75,34.13,8402400,8.41 +1994-09-20,35.13,35.38,34.38,34.56,7047600,8.52 +1994-09-19,36.38,36.75,35.50,35.50,6242000,8.75 +1994-09-16,35.88,37.25,35.50,36.38,13008000,8.97 +1994-09-15,35.13,36.13,35.13,36.00,9253200,8.87 +1994-09-14,35.63,35.75,35.00,35.13,3549200,8.66 +1994-09-13,35.75,36.25,35.63,35.81,3723600,8.82 +1994-09-12,35.63,35.75,35.38,35.75,3252400,8.81 +1994-09-09,35.75,36.00,35.38,35.75,5624400,8.81 +1994-09-08,36.00,36.25,35.63,36.13,5691200,8.90 +1994-09-07,35.63,36.63,35.38,36.13,7283200,8.90 +1994-09-06,35.25,35.63,35.00,35.56,3279200,8.76 +1994-09-02,35.25,35.50,35.00,35.38,3628000,8.72 +1994-09-01,35.38,35.75,34.63,35.00,7305200,8.63 +1994-08-31,36.00,37.38,35.75,36.19,12568800,8.92 +1994-08-30,35.25,36.38,35.13,36.25,6515600,8.93 +1994-08-29,35.75,36.13,35.25,35.38,5450800,8.72 +1994-08-26,35.25,36.13,35.25,35.75,7300000,8.81 +1994-08-25,34.25,36.38,34.25,35.06,10688800,8.64 +1994-08-24,34.75,35.00,34.38,34.88,6132400,8.60 +1994-08-23,34.88,35.88,34.75,35.00,7669200,8.63 +1994-08-22,34.75,35.00,34.63,34.88,5445600,8.60 +1994-08-19,34.75,35.00,34.25,34.88,4674800,8.60 +1994-08-18,34.75,35.25,34.50,34.63,7370000,8.53 +1994-08-17,34.88,35.38,34.63,35.00,10232400,8.63 +1994-08-16,34.38,34.75,34.00,34.75,5563200,8.56 +1994-08-15,34.75,35.00,34.25,34.63,4293200,8.53 +1994-08-12,34.38,35.13,33.88,34.75,6425200,8.53 +1994-08-11,34.25,35.13,33.88,34.31,10649200,8.43 +1994-08-10,33.63,34.88,33.25,34.63,9065200,8.50 +1994-08-09,33.50,33.88,33.13,33.63,2811200,8.26 +1994-08-08,33.13,34.00,33.00,33.75,5048800,8.29 +1994-08-05,32.88,33.38,32.88,33.25,3123200,8.17 +1994-08-04,33.13,33.75,33.13,33.25,6620000,8.17 +1994-08-03,32.75,33.25,32.13,33.13,8113600,8.14 +1994-08-02,33.50,33.63,32.38,32.56,9642400,8.00 +1994-08-01,33.63,33.75,32.75,33.38,8204400,8.20 +1994-07-29,31.87,34.00,31.87,33.69,19853600,8.27 +1994-07-28,31.00,32.13,30.87,31.87,8762000,7.83 +1994-07-27,31.25,31.37,30.62,31.06,4788000,7.63 +1994-07-26,31.75,32.00,31.12,31.37,6756400,7.70 +1994-07-25,31.12,31.87,30.75,31.69,15103200,7.78 +1994-07-22,31.62,31.97,30.00,31.00,28098800,7.61 +1994-07-21,26.62,28.50,26.50,28.00,10348800,6.88 +1994-07-20,27.37,27.62,26.37,26.62,7765200,6.54 +1994-07-19,28.62,28.75,27.37,27.69,4176400,6.80 +1994-07-18,28.12,29.00,28.00,28.37,2734800,6.97 +1994-07-15,28.23,28.62,27.50,28.25,3409200,6.94 +1994-07-14,29.62,29.75,28.25,28.62,6459200,7.03 +1994-07-13,28.50,30.25,28.50,29.69,16081200,7.29 +1994-07-12,27.00,28.44,26.37,28.37,8662000,6.97 +1994-07-11,27.12,27.37,26.62,27.00,3801200,6.63 +1994-07-08,26.50,27.62,26.50,27.06,7457600,6.65 +1994-07-07,25.87,27.00,25.50,26.81,6097600,6.58 +1994-07-06,26.25,26.50,26.00,26.12,3499200,6.41 +1994-07-05,25.62,26.75,25.62,26.50,3080800,6.51 +1994-07-01,26.37,26.50,25.37,25.75,6404400,6.32 +1994-06-30,26.25,26.87,26.25,26.50,3652000,6.51 +1994-06-29,26.75,27.12,25.87,26.12,4842400,6.41 +1994-06-28,26.25,27.12,25.62,26.75,6235200,6.57 +1994-06-27,25.25,26.25,24.62,26.25,9153200,6.45 +1994-06-24,25.12,26.12,24.75,25.61,10470000,6.29 +1994-06-23,26.25,26.25,24.87,25.12,7283200,6.17 +1994-06-22,26.25,26.75,26.00,26.25,4081200,6.45 +1994-06-21,26.87,27.25,25.75,26.00,8693200,6.39 +1994-06-20,26.25,27.25,26.00,27.12,7150000,6.66 +1994-06-17,26.00,26.75,25.87,26.50,8027600,6.51 +1994-06-16,27.75,27.75,26.12,26.37,7812400,6.48 +1994-06-15,27.00,28.00,26.87,27.81,5704400,6.83 +1994-06-14,27.25,27.37,26.62,27.06,5531200,6.65 +1994-06-13,26.37,27.19,26.37,27.00,3339200,6.63 +1994-06-10,27.12,27.37,26.37,26.50,5107600,6.51 +1994-06-09,25.62,27.00,25.50,27.00,10485200,6.63 +1994-06-08,27.50,27.62,26.00,26.12,9809200,6.41 +1994-06-07,27.25,27.75,27.25,27.50,5013600,6.75 +1994-06-06,27.50,27.75,27.00,27.37,4513200,6.72 +1994-06-03,27.12,28.00,26.75,27.62,12649200,6.78 +1994-06-02,28.37,28.50,27.12,27.37,13762400,6.72 +1994-06-01,28.50,28.62,27.87,28.25,13786800,6.94 +1994-05-31,29.50,29.50,28.50,29.25,9211200,7.18 +1994-05-27,30.25,30.75,29.50,29.94,3882400,7.35 +1994-05-26,31.50,31.50,30.25,30.50,2613200,7.46 +1994-05-25,30.25,31.75,30.00,31.25,4873200,7.64 +1994-05-24,31.00,31.25,30.25,30.75,4536400,7.52 +1994-05-23,31.00,31.25,30.00,30.50,4286400,7.46 +1994-05-20,31.75,32.25,31.00,31.06,3519200,7.60 +1994-05-19,30.75,32.50,30.50,32.13,9776800,7.86 +1994-05-18,29.75,30.75,29.25,30.62,4436800,7.49 +1994-05-17,29.75,29.75,28.75,29.37,6450800,7.18 +1994-05-16,30.00,30.50,29.50,29.50,4854800,7.22 +1994-05-13,29.75,30.50,29.25,30.00,3323200,7.34 +1994-05-12,30.50,30.75,29.50,29.69,3839200,7.26 +1994-05-11,31.00,31.50,29.75,30.25,5218000,7.40 +1994-05-10,31.75,32.00,31.00,31.00,5246800,7.58 +1994-05-09,32.25,32.50,30.75,31.25,5026400,7.64 +1994-05-06,32.25,32.75,31.25,32.31,6721200,7.90 +1994-05-05,33.25,33.75,32.25,32.88,10307600,8.04 +1994-05-04,31.00,33.25,30.50,33.00,13008800,8.07 +1994-05-03,31.00,31.25,29.50,30.25,4761200,7.40 +1994-05-02,30.00,31.25,30.00,31.00,4401200,7.58 +1994-04-29,30.00,30.50,29.75,30.00,3399200,7.34 +1994-04-28,31.00,31.25,29.75,30.25,3604400,7.40 +1994-04-26,31.50,31.50,31.00,31.25,5879200,7.64 +1994-04-25,29.75,31.00,29.50,31.00,12846800,7.58 +1994-04-22,31.25,32.00,28.50,29.75,24923600,7.28 +1994-04-21,28.50,30.50,27.00,29.62,14674400,7.25 +1994-04-20,29.25,30.00,28.00,28.25,10080800,6.91 +1994-04-19,29.75,30.00,28.50,29.00,5947600,7.09 +1994-04-18,30.50,30.50,29.25,29.62,8238800,7.25 +1994-04-15,31.25,31.50,30.00,30.25,6730800,7.40 +1994-04-14,30.50,31.75,30.00,31.50,7933200,7.71 +1994-04-13,32.25,32.50,31.25,31.75,8330000,7.77 +1994-04-12,33.38,33.38,31.75,32.00,4890800,7.83 +1994-04-11,33.50,33.50,32.50,33.50,3823600,8.19 +1994-04-08,33.75,34.00,33.25,33.50,6336400,8.19 +1994-04-07,33.50,33.75,32.75,33.38,2764800,8.17 +1994-04-06,34.00,34.00,32.75,33.50,4616400,8.19 +1994-04-05,33.75,34.25,33.50,33.50,3505600,8.19 +1994-04-04,32.25,33.25,31.75,33.25,6016800,8.13 +1994-03-31,32.50,33.50,31.50,33.25,7481200,8.13 +1994-03-30,32.50,33.25,31.75,32.50,6079200,7.95 +1994-03-29,33.25,33.75,32.25,32.75,7640000,8.01 +1994-03-28,33.00,34.00,32.75,33.25,10098800,8.13 +1994-03-25,34.75,34.75,32.75,32.75,12291200,8.01 +1994-03-24,35.13,35.25,34.00,34.63,6738800,8.47 +1994-03-23,35.25,35.50,34.25,35.13,7749200,8.59 +1994-03-22,35.25,35.50,34.50,35.00,8690800,8.56 +1994-03-21,36.38,36.50,35.25,35.50,8806400,8.68 +1994-03-18,36.75,36.75,35.75,36.38,8004400,8.90 +1994-03-17,36.75,37.00,36.25,36.50,5590800,8.93 +1994-03-16,37.50,37.75,36.50,36.75,5265200,8.99 +1994-03-15,38.25,38.25,37.25,37.63,7319200,9.20 +1994-03-14,38.50,38.50,37.75,38.13,15783600,9.33 +1994-03-11,37.00,37.75,36.75,37.25,5791200,9.11 +1994-03-10,37.25,37.63,36.75,37.25,5142400,9.11 +1994-03-09,36.63,37.50,36.00,37.50,8896800,9.17 +1994-03-08,38.00,38.00,36.75,37.00,6647600,9.05 +1994-03-07,37.00,38.13,36.75,37.88,11088800,9.27 +1994-03-04,36.00,37.50,35.75,36.75,8113600,8.99 +1994-03-03,35.75,36.25,35.50,35.75,6737600,8.75 +1994-03-02,35.25,36.25,34.75,35.63,10519200,8.72 +1994-03-01,36.75,36.75,35.75,36.25,7570800,8.87 +1994-02-28,36.25,37.00,36.00,36.50,4434800,8.93 +1994-02-25,37.00,37.25,35.50,36.00,8468000,8.81 +1994-02-24,37.00,37.25,36.25,36.63,7081200,8.96 +1994-02-23,37.25,38.25,37.00,37.25,9318800,9.11 +1994-02-22,36.25,37.50,35.75,37.25,7676400,9.11 +1994-02-18,36.50,37.00,36.25,36.25,5326400,8.87 +1994-02-17,37.25,37.88,36.25,37.00,5197600,9.05 +1994-02-16,37.50,37.50,36.75,36.75,4379200,8.99 +1994-02-15,36.75,37.50,36.25,37.13,4654400,9.08 +1994-02-14,37.00,38.00,36.75,37.00,8775200,9.05 +1994-02-11,36.25,37.50,36.25,37.00,5880800,9.05 +1994-02-10,36.25,37.50,36.00,36.50,10802000,8.93 +1994-02-09,35.75,36.50,35.25,36.25,6699200,8.87 +1994-02-08,36.00,36.50,35.25,35.75,10210800,8.75 +1994-02-07,33.50,37.13,33.50,36.50,25925200,8.93 +1994-02-04,33.50,35.00,33.25,33.50,12645200,8.17 +1994-02-03,33.00,33.63,32.50,33.50,4933200,8.17 +1994-02-02,33.25,33.25,32.50,33.00,5247600,8.04 +1994-02-01,33.00,33.50,32.25,33.25,5618000,8.10 +1994-01-31,33.50,33.75,32.75,32.75,8532400,7.98 +1994-01-28,34.25,34.75,33.75,34.00,4891200,8.29 +1994-01-27,33.50,34.25,33.00,34.13,4724800,8.32 +1994-01-26,33.75,34.00,33.25,33.50,5922400,8.17 +1994-01-25,34.75,35.00,33.25,33.88,15818800,8.26 +1994-01-24,33.25,35.25,33.25,35.00,24742000,8.53 +1994-01-21,33.25,33.50,32.25,33.38,35007600,8.14 +1994-01-20,29.50,30.75,29.50,29.87,9582400,7.28 +1994-01-19,29.25,29.75,28.75,29.25,10066400,7.13 +1994-01-18,30.25,30.25,29.00,29.37,12978000,7.16 +1994-01-17,31.00,31.50,30.00,30.37,5206400,7.40 +1994-01-14,30.75,31.75,30.50,31.00,7673200,7.56 +1994-01-13,30.00,30.75,29.75,30.62,19000000,7.46 +1994-01-12,32.25,32.25,30.50,30.50,15684400,7.43 +1994-01-11,33.50,33.75,31.75,31.87,12700000,7.77 +1994-01-10,33.00,33.88,32.75,33.63,7222000,8.20 +1994-01-07,32.00,33.25,31.25,33.13,10688800,8.08 +1994-01-06,33.75,34.00,32.50,32.75,13095200,7.98 +1994-01-05,31.75,33.88,31.75,33.75,21874400,8.23 +1994-01-04,30.25,31.50,30.00,31.50,10198800,7.68 +1994-01-03,29.50,30.00,29.00,29.87,6485200,7.28 +1993-12-31,29.75,30.25,29.25,29.25,5765200,7.13 +1993-12-30,28.50,30.25,28.50,29.75,11253200,7.25 +1993-12-29,29.25,29.25,28.50,28.50,3853200,6.95 +1993-12-28,28.75,29.50,28.50,29.12,5705600,7.10 +1993-12-27,27.75,28.75,27.25,28.50,5730000,6.95 +1993-12-23,27.25,27.25,26.50,27.25,8120000,6.64 +1993-12-22,27.25,28.50,27.00,28.00,6498800,6.82 +1993-12-21,28.50,28.75,27.25,27.50,8973600,6.70 +1993-12-20,29.25,29.75,28.25,28.50,6768800,6.95 +1993-12-17,29.50,29.75,29.12,29.50,5197600,7.19 +1993-12-16,29.50,29.75,29.00,29.37,4532000,7.16 +1993-12-15,29.00,29.75,29.00,29.75,4438000,7.25 +1993-12-14,29.25,29.75,29.00,29.12,10492400,7.10 +1993-12-13,28.25,29.50,27.75,29.50,8729200,7.19 +1993-12-10,30.25,30.50,27.75,28.25,17781200,6.89 +1993-12-09,31.75,32.00,29.75,30.00,6531200,7.31 +1993-12-08,32.00,32.25,31.50,31.87,1422000,7.77 +1993-12-07,32.00,32.25,31.50,32.25,2280800,7.86 +1993-12-06,31.50,32.50,31.25,32.25,5610000,7.86 +1993-12-03,31.75,32.00,31.00,31.50,4314800,7.68 +1993-12-02,31.75,32.00,31.00,31.75,3614400,7.74 +1993-12-01,32.00,32.25,31.25,31.50,3978800,7.68 +1993-11-30,31.75,32.63,31.50,31.50,4036800,7.68 +1993-11-29,32.25,32.50,31.50,31.75,3462000,7.74 +1993-11-26,32.75,33.00,32.25,32.63,1569200,7.95 +1993-11-24,32.75,33.50,32.63,33.00,3246800,8.04 +1993-11-23,32.50,33.00,31.25,33.00,6653600,8.04 +1993-11-22,32.75,33.00,32.25,32.50,5389200,7.92 +1993-11-19,33.00,33.50,32.50,33.00,4409200,8.04 +1993-11-18,33.50,33.75,33.00,33.50,4089200,8.14 +1993-11-17,34.00,35.00,32.75,33.50,10812400,8.14 +1993-11-16,32.00,34.25,31.75,34.00,10838000,8.26 +1993-11-15,31.50,32.75,31.50,32.00,5616800,7.77 +1993-11-12,31.50,32.00,30.50,31.75,5136800,7.71 +1993-11-11,30.75,32.00,30.50,31.37,5090800,7.62 +1993-11-10,30.25,30.75,30.00,30.75,2765600,7.47 +1993-11-09,31.00,31.25,29.75,30.12,6136400,7.32 +1993-11-08,32.00,32.13,30.50,30.75,5966400,7.47 +1993-11-05,31.87,32.25,30.75,31.87,13513200,7.74 +1993-11-04,31.50,32.25,30.75,32.25,6632000,7.83 +1993-11-03,33.00,33.00,31.00,31.62,6320000,7.68 +1993-11-02,31.25,33.00,31.00,32.75,8013600,7.95 +1993-11-01,30.75,31.50,30.25,31.50,3798800,7.65 +1993-10-29,31.00,31.75,30.50,30.75,4892400,7.47 +1993-10-28,31.75,32.25,31.00,31.00,8736800,7.53 +1993-10-27,30.00,32.25,29.75,31.75,16415200,7.71 +1993-10-26,29.75,30.00,29.00,29.75,7960000,7.23 +1993-10-25,30.25,30.50,29.62,30.00,7840800,7.29 +1993-10-22,30.50,31.50,29.75,30.25,14160000,7.35 +1993-10-21,27.50,31.25,27.25,30.25,22417600,7.35 +1993-10-20,28.00,28.25,27.25,27.75,4956400,6.74 +1993-10-19,28.25,28.50,27.25,27.75,7643200,6.74 +1993-10-18,28.00,28.75,27.75,28.37,11900000,6.89 +1993-10-15,27.75,28.50,26.75,28.25,34136400,6.86 +1993-10-14,24.00,24.50,23.50,23.75,5749200,5.77 +1993-10-13,24.25,24.25,23.50,24.00,6322400,5.83 +1993-10-12,24.00,25.00,23.75,24.00,10952400,5.83 +1993-10-11,22.75,24.00,22.75,23.75,5775200,5.77 +1993-10-08,23.25,23.25,22.25,22.62,4989200,5.49 +1993-10-07,23.50,23.75,22.75,23.00,4828000,5.59 +1993-10-06,23.75,24.00,23.37,23.62,6271200,5.74 +1993-10-05,23.00,24.00,23.00,23.50,6306400,5.71 +1993-10-04,22.62,23.00,22.00,22.75,6891200,5.53 +1993-10-01,22.75,23.00,22.50,22.75,12022000,5.53 +1993-09-30,24.00,24.00,23.00,23.37,9828000,5.68 +1993-09-29,24.25,24.87,23.75,23.87,8463600,5.80 +1993-09-28,24.75,25.00,24.25,24.75,3386400,6.01 +1993-09-27,25.00,25.25,24.25,24.75,4043200,6.01 +1993-09-24,25.00,25.25,24.50,25.00,2743200,6.07 +1993-09-23,25.50,25.50,24.50,24.75,4697600,6.01 +1993-09-22,24.25,25.50,24.25,25.50,3960800,6.19 +1993-09-21,24.75,25.25,23.87,24.50,5250000,5.95 +1993-09-20,25.25,25.50,24.75,24.87,3968800,6.04 +1993-09-17,24.37,25.50,24.25,25.25,6157600,6.13 +1993-09-16,24.25,25.00,24.25,24.75,3086800,6.01 +1993-09-15,24.50,25.00,23.50,24.50,9206800,5.95 +1993-09-14,24.25,25.00,24.00,24.25,9880000,5.89 +1993-09-13,26.25,26.50,24.75,25.25,9143600,6.13 +1993-09-10,26.25,26.25,25.37,26.25,4804800,6.38 +1993-09-09,26.75,27.00,26.00,26.00,5352000,6.31 +1993-09-08,26.25,27.00,26.00,26.75,8102000,6.50 +1993-09-07,26.00,27.00,25.75,26.25,5130000,6.38 +1993-09-03,26.00,26.00,25.25,25.75,5830000,6.25 +1993-09-02,26.00,26.25,25.25,25.75,10081200,6.25 +1993-09-01,26.50,26.75,25.75,26.12,8065200,6.34 +1993-08-31,26.50,26.75,26.00,26.50,4570800,6.44 +1993-08-30,26.50,26.50,25.87,26.00,9785600,6.31 +1993-08-27,27.00,27.00,26.25,26.50,6676400,6.44 +1993-08-26,27.25,27.25,26.50,26.87,6296800,6.53 +1993-08-25,28.00,28.25,26.75,27.25,5209200,6.62 +1993-08-24,28.25,28.75,27.75,28.00,3625600,6.80 +1993-08-23,28.00,28.75,27.50,28.37,3265600,6.89 +1993-08-20,27.75,28.00,27.00,28.00,3574400,6.80 +1993-08-19,28.75,28.75,27.50,27.50,5452000,6.68 +1993-08-18,29.00,29.75,28.25,28.50,6751200,6.92 +1993-08-17,27.75,28.50,27.25,28.37,3876800,6.89 +1993-08-16,27.50,28.00,27.25,27.50,3669200,6.68 +1993-08-13,26.50,27.75,26.25,27.37,4978800,6.62 +1993-08-12,27.50,27.75,26.00,26.50,12098800,6.41 +1993-08-11,28.50,28.50,27.00,27.50,5965200,6.65 +1993-08-10,29.50,29.75,28.25,28.50,5465600,6.89 +1993-08-09,29.25,30.25,29.00,29.75,5767600,7.19 +1993-08-06,29.25,30.25,29.25,29.25,4506800,7.07 +1993-08-05,30.75,30.75,29.00,29.50,7498800,7.13 +1993-08-04,29.25,30.50,29.00,30.25,8700000,7.31 +1993-08-03,29.00,29.25,28.75,29.00,6315600,7.01 +1993-08-02,28.25,29.25,28.00,28.50,7728000,6.89 +1993-07-30,27.50,28.25,27.00,27.75,7669200,6.71 +1993-07-29,27.00,27.50,26.75,27.25,4343200,6.59 +1993-07-28,26.25,27.00,26.25,26.87,3300000,6.50 +1993-07-27,26.75,27.50,26.25,26.50,7100800,6.41 +1993-07-26,26.75,27.50,26.00,26.87,5468000,6.50 +1993-07-23,27.00,27.50,26.00,26.25,8365600,6.35 +1993-07-22,26.00,27.00,25.75,26.50,7554400,6.41 +1993-07-21,26.00,26.75,25.50,26.25,16283600,6.35 +1993-07-20,26.25,27.75,25.75,26.87,19017600,6.50 +1993-07-19,28.00,28.75,25.50,25.62,28813200,6.20 +1993-07-16,28.50,29.62,26.50,27.50,75744400,6.65 +1993-07-15,37.25,37.75,35.25,35.75,12091200,8.64 +1993-07-14,36.75,37.50,35.75,37.25,8816800,9.01 +1993-07-13,38.75,38.75,37.00,37.25,5650800,9.01 +1993-07-12,36.75,38.13,36.25,38.00,6215600,9.19 +1993-07-09,37.00,37.25,36.50,36.75,5604400,8.89 +1993-07-08,36.50,37.50,36.25,36.50,4964800,8.83 +1993-07-07,37.50,37.88,36.25,36.50,8124400,8.83 +1993-07-06,38.25,39.00,37.50,37.75,5558800,9.13 +1993-07-02,38.25,38.75,37.75,38.50,6846400,9.31 +1993-07-01,39.00,39.75,38.00,38.00,7809200,9.19 +1993-06-30,38.75,39.75,38.50,39.50,7170000,9.55 +1993-06-29,40.25,40.25,38.50,39.00,10526400,9.43 +1993-06-28,40.50,40.50,38.75,40.13,12645600,9.70 +1993-06-25,40.38,40.75,39.50,40.00,9198000,9.67 +1993-06-24,40.50,41.75,40.00,41.75,7980000,10.10 +1993-06-23,41.75,41.75,40.00,40.50,6462400,9.79 +1993-06-22,40.88,42.00,39.75,41.38,12021200,10.01 +1993-06-21,40.50,40.50,39.50,39.63,9776800,9.58 +1993-06-18,41.63,42.13,39.75,41.00,11138800,9.91 +1993-06-17,42.50,42.50,40.50,41.25,14635600,9.97 +1993-06-16,42.25,43.25,41.50,42.25,12615600,10.22 +1993-06-15,45.25,45.25,41.88,42.00,16018000,10.16 +1993-06-14,44.00,44.75,43.50,44.63,8927600,10.79 +1993-06-11,45.00,45.25,43.38,43.75,8662400,10.58 +1993-06-10,43.50,44.75,42.75,44.50,19783600,10.76 +1993-06-09,45.00,45.63,44.00,44.25,42090000,10.70 +1993-06-08,48.75,50.00,48.00,49.50,22194400,11.97 +1993-06-07,54.50,54.75,50.38,50.75,17239200,12.27 +1993-06-04,55.75,56.25,54.50,54.88,7649200,13.27 +1993-06-03,57.00,57.25,56.00,56.38,5603200,13.63 +1993-06-02,56.75,58.25,56.00,57.00,7160000,13.78 +1993-06-01,56.50,57.75,56.50,57.00,4837600,13.78 +1993-05-28,57.00,57.50,56.25,56.63,6575200,13.69 +1993-05-27,57.75,58.50,57.25,57.50,7049200,13.87 +1993-05-26,56.00,57.75,55.38,57.75,4353600,13.94 +1993-05-25,56.75,57.50,55.75,56.38,6462400,13.60 +1993-05-24,56.75,58.75,56.75,57.63,5373200,13.91 +1993-05-21,58.75,59.13,56.75,57.50,5300000,13.87 +1993-05-20,57.25,59.00,57.25,58.75,10385200,14.18 +1993-05-19,54.75,57.50,54.50,57.25,6176400,13.81 +1993-05-18,55.50,56.25,55.00,55.50,5860000,13.39 +1993-05-17,55.50,56.00,55.00,55.75,2491200,13.45 +1993-05-14,55.25,56.00,55.00,55.50,4212000,13.39 +1993-05-13,53.50,55.75,53.50,55.50,12940800,13.39 +1993-05-12,54.25,54.75,53.00,53.25,3779200,12.85 +1993-05-11,55.00,55.25,54.00,54.50,5665600,13.15 +1993-05-10,55.00,55.88,55.00,55.00,4929200,13.27 +1993-05-07,53.50,54.75,53.50,54.75,2927600,13.21 +1993-05-06,54.50,54.75,53.50,53.75,2536800,12.97 +1993-05-05,53.00,55.50,53.00,54.50,9059200,13.15 +1993-05-04,52.25,54.25,52.00,53.38,6112400,12.88 +1993-05-03,51.25,52.00,51.00,51.88,2332400,12.52 +1993-04-30,50.75,52.50,50.75,51.25,4730000,12.37 +1993-04-29,51.50,51.75,50.13,50.75,2958000,12.25 +1993-04-28,49.75,52.00,49.75,51.38,5846800,12.40 +1993-04-27,48.75,50.25,48.75,50.25,4648800,12.13 +1993-04-26,49.25,49.75,48.50,49.00,3689200,11.82 +1993-04-23,49.75,50.25,48.75,49.25,4808000,11.88 +1993-04-22,49.25,50.50,49.00,50.00,5648800,12.06 +1993-04-21,50.25,50.75,49.25,49.63,7337600,11.98 +1993-04-20,48.75,50.25,48.25,50.00,8580800,12.06 +1993-04-19,48.50,49.50,48.25,48.50,8148000,11.70 +1993-04-16,48.25,48.75,47.38,48.13,24533200,11.61 +1993-04-15,48.25,48.25,46.75,47.25,7816800,11.40 +1993-04-14,48.25,48.75,47.63,48.75,6092400,11.76 +1993-04-13,50.50,51.25,48.25,48.50,5893600,11.70 +1993-04-12,49.50,51.00,49.50,50.00,3324800,12.06 +1993-04-08,50.00,50.50,49.00,49.75,5857600,12.00 +1993-04-07,49.00,50.75,48.50,50.50,5825200,12.19 +1993-04-06,50.00,50.25,48.75,48.75,6020800,11.76 +1993-04-05,50.00,50.50,49.50,50.00,5332000,12.06 +1993-04-02,50.50,51.25,49.50,50.13,9077600,12.10 +1993-04-01,51.25,52.00,51.00,51.75,3878000,12.49 +1993-03-31,52.50,52.75,51.25,51.50,7968800,12.43 +1993-03-30,51.13,52.25,50.25,52.25,9447600,12.61 +1993-03-29,52.25,52.50,50.75,51.00,9362000,12.31 +1993-03-26,54.75,54.75,52.50,53.25,5431200,12.85 +1993-03-25,53.75,54.75,53.50,54.75,6125200,13.21 +1993-03-24,52.75,54.25,52.50,53.75,5126400,12.97 +1993-03-23,53.25,54.00,52.63,52.75,3674400,12.73 +1993-03-22,53.50,53.88,52.75,53.25,5911200,12.85 +1993-03-19,55.00,55.25,53.50,53.75,5516800,12.97 +1993-03-18,55.00,55.63,54.50,54.50,3810800,13.15 +1993-03-17,56.50,57.00,55.00,55.13,6301200,13.30 +1993-03-16,57.25,57.75,56.50,56.50,3626800,13.63 +1993-03-15,56.00,57.25,55.38,57.00,4868800,13.75 +1993-03-12,56.75,56.75,55.50,56.25,4527600,13.57 +1993-03-11,57.00,57.25,56.25,56.88,5167600,13.73 +1993-03-10,56.75,57.25,56.00,56.75,4738800,13.69 +1993-03-09,56.50,57.50,56.50,56.75,5535200,13.69 +1993-03-08,55.00,56.75,55.00,56.50,6322400,13.63 +1993-03-05,54.75,55.75,54.75,55.00,4001200,13.27 +1993-03-04,54.50,55.25,53.50,55.00,6730000,13.27 +1993-03-03,54.00,55.00,53.25,54.63,7261200,13.18 +1993-03-02,53.00,54.50,53.00,54.25,5294400,13.09 +1993-03-01,53.00,53.50,52.75,53.25,4272400,12.85 +1993-02-26,54.25,54.25,52.25,53.00,10538000,12.79 +1993-02-25,53.25,54.75,53.25,54.75,5979200,13.21 +1993-02-24,52.13,53.88,52.13,53.63,10253600,12.94 +1993-02-23,55.00,55.25,54.00,54.25,6937600,13.09 +1993-02-22,55.00,56.00,54.75,55.13,3531200,13.30 +1993-02-19,55.25,55.50,54.75,55.00,6366800,13.27 +1993-02-18,55.00,55.25,53.50,55.00,10006800,13.27 +1993-02-17,53.25,54.00,52.00,53.88,8932400,13.00 +1993-02-16,53.50,53.50,51.50,53.00,14563200,12.79 +1993-02-12,55.00,55.50,53.75,53.88,9855600,13.00 +1993-02-11,55.75,56.25,55.00,55.13,6015200,13.27 +1993-02-10,57.00,57.25,55.00,55.75,9593600,13.42 +1993-02-09,57.00,57.38,56.50,56.88,8525600,13.70 +1993-02-08,57.00,57.50,55.50,56.50,10060000,13.60 +1993-02-05,59.25,59.50,56.25,57.25,13134400,13.78 +1993-02-04,60.00,60.25,59.00,59.50,7453200,14.33 +1993-02-03,61.00,61.00,58.50,60.00,9455200,14.45 +1993-02-02,60.75,61.50,60.25,60.25,6530000,14.51 +1993-02-01,59.25,61.25,59.25,61.25,8608800,14.75 +1993-01-29,60.25,61.25,59.00,59.50,9516800,14.33 +1993-01-28,60.00,60.25,59.25,59.88,6580000,14.42 +1993-01-27,61.00,61.75,58.75,60.25,8101200,14.51 +1993-01-26,60.50,62.00,60.50,60.75,10201200,14.63 +1993-01-25,59.25,60.50,59.25,60.00,7237600,14.45 +1993-01-22,60.25,60.25,59.00,59.50,5252400,14.33 +1993-01-21,59.75,60.25,58.75,60.00,6601200,14.45 +1993-01-20,59.75,60.25,59.50,60.00,5685600,14.45 +1993-01-19,59.75,60.50,59.25,59.75,9802400,14.39 +1993-01-18,59.50,60.00,58.00,59.50,11935600,14.33 +1993-01-15,61.00,62.25,60.00,60.25,32257600,14.51 +1993-01-14,64.00,65.25,63.75,65.00,13145200,15.65 +1993-01-13,61.50,64.00,61.25,63.50,7135600,15.29 +1993-01-12,62.75,63.75,61.50,61.50,12364400,14.81 +1993-01-11,62.00,64.37,61.75,64.12,9785200,15.44 +1993-01-08,60.75,63.00,59.75,62.25,11474400,14.99 +1993-01-07,61.75,62.50,60.63,61.00,9741200,14.69 +1993-01-06,60.75,62.00,60.50,61.75,10055600,14.87 +1993-01-05,58.00,59.25,57.25,59.25,6658800,14.27 +1993-01-04,59.50,60.00,57.75,58.25,4618800,14.03 +1992-12-31,58.75,60.00,58.75,59.75,3302000,14.39 +1992-12-30,59.75,59.75,58.75,58.75,3610800,14.15 +1992-12-29,59.50,60.75,59.50,59.63,4171200,14.36 +1992-12-28,59.25,59.75,59.25,59.50,2536400,14.33 +1992-12-24,60.00,60.00,59.00,59.00,1642400,14.21 +1992-12-23,60.25,60.50,59.25,59.75,4018800,14.39 +1992-12-22,59.75,61.25,59.75,60.63,10009200,14.60 +1992-12-21,58.25,60.00,58.00,59.63,9159200,14.36 +1992-12-18,57.50,59.25,57.25,58.25,8414400,14.03 +1992-12-17,55.25,57.50,55.25,56.88,8370800,13.70 +1992-12-16,56.25,57.00,54.50,55.00,8085200,13.24 +1992-12-15,56.75,57.00,55.50,56.38,6541200,13.57 +1992-12-14,57.50,57.75,56.75,57.25,3962000,13.78 +1992-12-11,57.25,58.25,57.25,57.50,4299200,13.84 +1992-12-10,57.25,57.63,56.50,57.25,5010800,13.78 +1992-12-09,57.75,58.00,57.25,57.63,5700800,13.88 +1992-12-08,57.75,58.75,57.75,58.13,7035600,14.00 +1992-12-07,56.75,57.75,56.75,57.75,5168000,13.90 +1992-12-04,57.25,57.50,56.50,56.88,3432400,13.70 +1992-12-03,56.50,57.63,56.13,57.50,6710800,13.84 +1992-12-02,58.25,58.50,57.00,57.25,3498800,13.78 +1992-12-01,57.25,59.00,56.75,58.25,4652400,14.03 +1992-11-30,56.25,57.50,55.63,57.50,5739200,13.84 +1992-11-27,56.50,57.25,56.25,56.50,1688800,13.57 +1992-11-25,57.00,57.25,56.00,56.50,4208000,13.57 +1992-11-24,57.00,57.50,56.50,57.50,5601200,13.82 +1992-11-23,56.50,57.00,56.25,56.75,5462400,13.63 +1992-11-20,58.50,58.75,57.00,57.50,5572000,13.82 +1992-11-19,57.75,59.50,57.75,58.25,8608000,14.00 +1992-11-18,56.00,58.25,55.50,57.75,10889200,13.88 +1992-11-17,57.25,57.50,54.88,55.25,6045200,13.27 +1992-11-16,56.25,57.75,56.00,57.38,2419200,13.79 +1992-11-13,57.00,57.25,56.00,56.25,3042000,13.51 +1992-11-12,57.00,57.50,56.38,56.88,3844400,13.67 +1992-11-11,56.50,58.25,56.25,56.75,5023600,13.63 +1992-11-10,55.00,56.50,54.75,56.25,4368000,13.51 +1992-11-09,56.00,56.00,54.75,55.25,4052000,13.27 +1992-11-06,54.75,56.50,54.75,55.75,9443200,13.39 +1992-11-05,52.50,55.00,52.50,55.00,10647600,13.21 +1992-11-04,52.00,52.75,52.00,52.50,5086800,12.61 +1992-11-03,52.50,52.50,51.50,52.00,4042000,12.49 +1992-11-02,52.50,52.75,51.75,52.25,6094400,12.55 +1992-10-30,53.50,53.50,52.00,52.50,4657600,12.61 +1992-10-29,52.25,54.00,51.50,53.25,7661200,12.79 +1992-10-28,51.25,52.75,50.75,52.25,7033200,12.55 +1992-10-27,51.50,52.50,51.00,51.50,7575600,12.37 +1992-10-26,48.75,51.50,48.50,51.50,8972000,12.37 +1992-10-23,49.25,49.50,48.25,48.75,3279200,11.71 +1992-10-22,48.50,49.25,48.25,48.75,3026400,11.71 +1992-10-21,49.25,49.50,48.00,48.50,4080800,11.65 +1992-10-20,49.00,50.00,48.50,49.13,10269200,11.80 +1992-10-19,49.00,49.25,48.50,49.00,7002400,11.77 +1992-10-16,46.75,49.50,46.50,49.00,16142000,11.77 +1992-10-15,45.75,46.00,45.25,45.50,2701200,10.93 +1992-10-14,45.25,46.25,45.00,46.00,3429200,11.05 +1992-10-13,44.75,46.00,44.00,45.38,5265600,10.90 +1992-10-12,43.25,44.25,43.25,44.00,2580000,10.57 +1992-10-09,43.50,44.00,43.00,43.38,2108000,10.42 +1992-10-08,44.00,44.25,43.00,43.50,4543200,10.45 +1992-10-07,45.00,45.25,43.50,43.75,4050800,10.51 +1992-10-06,43.75,45.00,42.75,44.75,4058000,10.75 +1992-10-05,43.25,43.75,41.50,43.50,9475600,10.45 +1992-10-02,44.50,44.75,43.00,43.75,4063600,10.51 +1992-10-01,44.75,45.13,44.25,44.25,4396400,10.63 +1992-09-30,45.00,45.50,44.50,45.13,3580800,10.84 +1992-09-29,44.50,45.50,44.00,44.88,5626400,10.78 +1992-09-28,45.00,45.00,43.75,44.75,5351200,10.75 +1992-09-25,46.25,46.50,45.25,45.50,4926400,10.93 +1992-09-24,47.25,47.75,46.25,46.25,4492000,11.11 +1992-09-23,46.00,47.50,45.50,47.50,4443200,11.41 +1992-09-22,46.75,46.75,45.25,45.75,3996800,10.99 +1992-09-21,46.75,47.75,46.25,46.50,3204400,11.17 +1992-09-18,45.75,46.88,45.25,46.50,4133600,11.17 +1992-09-17,47.25,47.25,45.38,46.00,6180000,11.05 +1992-09-16,47.75,48.25,46.50,47.00,6395600,11.29 +1992-09-15,49.25,49.25,47.75,48.25,7806800,11.59 +1992-09-14,49.00,50.00,48.50,49.50,7682400,11.89 +1992-09-11,49.00,49.25,47.50,47.63,6438000,11.44 +1992-09-10,48.00,49.50,47.50,49.25,8165600,11.83 +1992-09-09,48.00,49.25,47.75,49.00,5622400,11.77 +1992-09-08,46.75,48.00,46.50,47.75,2511200,11.47 +1992-09-04,48.25,48.25,46.75,47.25,2268800,11.35 +1992-09-03,49.00,49.25,47.75,47.75,7570000,11.47 +1992-09-02,46.50,48.75,46.50,48.50,6794400,11.65 +1992-09-01,46.25,46.50,45.75,46.50,2172000,11.17 +1992-08-31,45.00,46.25,44.75,46.00,4328800,11.05 +1992-08-28,44.25,45.25,44.00,45.00,2202400,10.81 +1992-08-27,44.75,45.13,44.25,44.50,2974800,10.69 +1992-08-26,44.25,44.50,43.25,44.25,4325600,10.63 +1992-08-25,43.25,44.50,43.25,44.38,4731200,10.66 +1992-08-24,44.25,44.75,43.25,43.25,5454400,10.39 +1992-08-21,44.75,45.25,44.00,44.63,3926400,10.72 +1992-08-20,44.75,45.00,44.25,44.75,3894800,10.75 +1992-08-19,44.63,45.25,44.50,44.50,6096800,10.69 +1992-08-18,44.50,45.25,44.50,44.75,4017600,10.75 +1992-08-17,44.25,44.75,43.75,44.75,4617600,10.75 +1992-08-14,45.00,45.25,44.50,44.75,4872400,10.72 +1992-08-13,44.50,45.50,44.25,44.75,6122000,10.72 +1992-08-12,43.75,44.25,43.25,44.13,4343600,10.57 +1992-08-11,44.50,44.50,43.00,43.50,4339200,10.42 +1992-08-10,43.25,44.50,43.00,44.13,3280800,10.57 +1992-08-07,42.00,43.75,41.50,43.38,7842400,10.39 +1992-08-06,44.25,44.50,42.75,44.00,9220800,10.54 +1992-08-05,45.50,45.50,44.50,44.75,4981200,10.72 +1992-08-04,45.00,45.75,44.75,45.50,4295600,10.90 +1992-08-03,46.75,47.25,45.50,45.75,2452400,10.96 +1992-07-31,47.25,47.50,46.75,46.75,3262000,11.20 +1992-07-30,47.25,47.50,46.75,47.25,4927600,11.32 +1992-07-29,46.63,47.75,46.50,47.25,8976400,11.32 +1992-07-28,45.50,46.50,45.25,46.50,4813600,11.14 +1992-07-27,45.75,46.50,45.25,45.25,88800,10.84 +1992-07-24,44.50,46.25,44.00,45.88,4832000,10.99 +1992-07-23,44.50,44.75,43.75,44.75,6128800,10.72 +1992-07-22,45.25,45.50,44.00,44.25,5798800,10.60 +1992-07-21,45.50,46.25,45.00,45.75,4730800,10.96 +1992-07-20,44.75,45.25,44.00,44.75,6873600,10.72 +1992-07-17,45.00,46.00,44.63,45.00,15135600,10.78 +1992-07-16,47.75,49.00,47.25,48.75,5011200,11.68 +1992-07-15,47.50,49.00,47.25,48.00,6248000,11.50 +1992-07-14,47.00,48.00,47.00,47.50,4510800,11.38 +1992-07-13,45.75,47.13,45.25,47.00,4486800,11.26 +1992-07-10,46.00,46.25,44.88,45.75,5144400,10.96 +1992-07-09,46.00,46.50,45.75,45.88,5922000,10.99 +1992-07-08,44.00,45.75,44.00,45.75,7020000,10.96 +1992-07-07,46.25,46.25,43.50,44.25,7416400,10.60 +1992-07-06,46.50,46.75,45.50,46.25,4378000,11.08 +1992-07-02,49.00,49.00,45.75,46.25,9169200,11.08 +1992-07-01,48.00,49.50,47.75,49.00,5129200,11.74 +1992-06-30,46.75,48.25,46.50,48.00,6919200,11.50 +1992-06-29,45.75,47.13,45.25,46.75,6735200,11.20 +1992-06-26,45.75,46.00,44.50,45.25,3953600,10.84 +1992-06-25,46.50,46.50,45.25,45.63,5745200,10.93 +1992-06-24,45.50,46.00,45.25,46.00,7548000,11.02 +1992-06-23,45.00,45.50,44.50,45.25,11130800,10.84 +1992-06-22,44.00,44.75,42.75,44.25,13930000,10.60 +1992-06-19,46.00,46.00,43.75,44.75,15280000,10.72 +1992-06-18,47.50,49.00,44.75,45.25,15495600,10.84 +1992-06-17,49.00,49.25,47.00,47.50,10880800,11.38 +1992-06-16,51.75,52.00,48.75,49.25,13053200,11.80 +1992-06-15,54.00,54.00,52.50,52.63,6777600,12.61 +1992-06-12,54.50,55.00,54.25,54.63,3450800,13.09 +1992-06-11,53.75,54.25,53.50,53.88,5028800,12.91 +1992-06-10,54.00,54.75,53.50,53.75,4522400,12.88 +1992-06-09,54.25,54.25,53.50,54.00,3626800,12.94 +1992-06-08,55.00,55.00,54.00,54.25,3730000,13.00 +1992-06-05,54.75,55.25,54.25,54.88,4040800,13.15 +1992-06-04,54.25,54.75,53.50,54.50,6453200,13.06 +1992-06-03,56.50,56.50,54.00,54.13,10743200,12.97 +1992-06-02,57.50,57.50,56.25,56.50,5560000,13.54 +1992-06-01,57.25,59.50,56.00,57.50,8869200,13.78 +1992-05-29,59.75,60.63,59.50,59.75,6369200,14.29 +1992-05-28,60.00,60.25,59.00,59.50,4558000,14.23 +1992-05-27,59.25,60.25,59.00,60.25,5516400,14.41 +1992-05-26,59.50,59.75,58.75,59.25,3423200,14.17 +1992-05-22,59.00,59.75,59.00,59.50,1670800,14.23 +1992-05-21,60.25,60.25,58.75,59.13,4938800,14.14 +1992-05-20,59.75,60.25,59.25,60.00,6200800,14.35 +1992-05-19,60.75,60.75,59.00,59.38,4715600,14.20 +1992-05-18,61.50,61.50,60.00,60.38,4616400,14.44 +1992-05-15,61.00,61.25,60.50,60.63,4339200,14.50 +1992-05-14,62.75,63.00,60.25,61.38,5606800,14.68 +1992-05-13,62.50,63.25,62.25,62.75,3482000,15.01 +1992-05-12,62.25,63.00,61.75,62.25,2769200,14.89 +1992-05-11,62.00,62.75,61.50,62.25,3250000,14.89 +1992-05-08,61.50,62.88,61.00,62.00,7105600,14.83 +1992-05-07,61.50,62.25,60.50,60.75,6175600,14.53 +1992-05-06,60.75,62.13,60.50,61.75,6377600,14.77 +1992-05-05,60.50,60.63,59.50,60.50,6449200,14.47 +1992-05-04,59.50,61.25,59.25,60.50,4402000,14.47 +1992-05-01,60.00,60.75,58.25,59.25,4821200,14.17 +1992-04-30,57.25,60.25,56.50,60.13,9303600,14.38 +1992-04-29,54.25,57.00,54.25,57.00,7116800,13.63 +1992-04-28,55.25,55.75,53.00,54.25,6229200,12.97 +1992-04-27,56.00,56.25,55.00,55.75,5014800,13.33 +1992-04-24,57.00,58.25,56.00,56.50,3526800,13.51 +1992-04-23,57.50,58.25,56.00,57.00,6534400,13.63 +1992-04-22,56.25,58.00,56.25,57.63,6129200,13.78 +1992-04-21,57.00,57.25,56.00,56.25,6442400,13.45 +1992-04-20,59.00,59.00,56.00,56.75,7380800,13.57 +1992-04-16,60.25,60.75,58.50,59.00,9260800,14.11 +1992-04-15,58.00,60.88,57.50,60.50,7764400,14.47 +1992-04-14,57.75,59.25,57.25,58.75,5178000,14.05 +1992-04-13,55.50,56.75,55.25,56.50,4402000,13.51 +1992-04-10,57.25,57.50,55.00,55.50,9803600,13.27 +1992-04-09,56.00,58.25,55.25,57.25,6874400,13.69 +1992-04-08,57.00,57.00,54.75,55.88,13123600,13.36 +1992-04-07,61.00,61.25,57.25,57.25,8234400,13.69 +1992-04-06,59.00,61.00,59.00,60.75,3643600,14.53 +1992-04-03,58.75,59.25,58.50,59.00,4181200,14.11 +1992-04-02,59.00,59.50,58.38,58.75,4798800,14.05 +1992-04-01,57.25,59.25,57.25,59.00,5714400,14.11 +1992-03-31,58.25,59.75,58.00,58.25,7613200,13.93 +1992-03-30,61.25,61.25,57.75,58.13,12124400,13.90 +1992-03-27,63.88,64.00,60.50,61.00,9452000,14.59 +1992-03-26,64.75,65.25,63.75,64.00,4412400,15.30 +1992-03-25,65.00,65.00,64.25,64.50,4353200,15.42 +1992-03-24,63.50,65.00,63.25,65.00,7501200,15.54 +1992-03-23,63.00,63.75,63.00,63.00,1804400,15.07 +1992-03-20,63.00,63.25,63.00,63.25,1942400,15.13 +1992-03-19,63.75,63.75,62.75,63.00,4251200,15.07 +1992-03-18,63.25,64.00,63.00,63.75,2902000,15.25 +1992-03-17,63.50,63.75,62.75,62.88,3061200,15.04 +1992-03-16,62.75,63.50,61.75,63.38,2016400,15.16 +1992-03-13,63.25,63.75,62.00,63.13,2843600,15.10 +1992-03-12,63.25,63.75,61.50,62.75,5472400,15.01 +1992-03-11,63.75,64.25,63.00,63.25,4714400,15.13 +1992-03-10,64.00,64.75,63.75,63.75,4394400,15.25 +1992-03-09,63.75,64.25,63.50,63.75,3896800,15.25 +1992-03-06,63.50,64.00,63.00,64.00,4816400,15.30 +1992-03-05,64.50,65.50,63.00,63.50,8462400,15.19 +1992-03-04,66.25,66.75,64.75,65.00,4120800,15.54 +1992-03-03,67.75,68.00,66.25,66.37,3560000,15.87 +1992-03-02,67.75,68.50,67.25,67.25,3203200,16.08 +1992-02-28,68.50,69.00,67.00,67.50,3244400,16.14 +1992-02-27,70.00,70.00,68.00,68.50,4364800,16.38 +1992-02-26,68.25,70.00,68.25,69.87,8193600,16.71 +1992-02-25,66.25,68.50,65.25,68.50,8134400,16.38 +1992-02-24,66.25,66.50,65.75,66.12,6122400,15.81 +1992-02-21,64.75,65.50,64.50,65.00,5421200,15.54 +1992-02-20,62.50,64.75,62.25,64.62,4692400,15.45 +1992-02-19,62.75,63.00,61.75,62.00,3426400,14.83 +1992-02-18,64.25,64.50,62.75,62.75,2442000,15.01 +1992-02-14,63.75,64.25,63.25,64.12,2610800,15.33 +1992-02-13,65.25,65.25,63.75,64.25,2734400,15.34 +1992-02-12,63.75,65.50,63.00,65.25,4931200,15.57 +1992-02-11,63.00,63.75,62.25,62.88,4378800,15.01 +1992-02-10,64.00,64.25,63.00,63.13,3091200,15.07 +1992-02-07,64.25,64.75,62.75,64.00,5285600,15.28 +1992-02-06,65.75,66.00,64.00,64.12,3330000,15.30 +1992-02-05,66.25,66.75,65.12,66.12,5772400,15.78 +1992-02-04,65.75,66.25,65.00,65.75,6896400,15.69 +1992-02-03,64.75,66.25,64.50,65.75,5652000,15.69 +1992-01-31,64.00,65.25,63.50,64.75,5164400,15.46 +1992-01-30,63.50,63.75,62.75,63.75,3128800,15.22 +1992-01-29,64.75,65.75,63.25,63.25,5164400,15.10 +1992-01-28,64.75,65.37,63.00,65.25,6206800,15.57 +1992-01-27,64.75,65.25,64.25,64.50,2992000,15.40 +1992-01-24,64.50,65.75,64.00,64.62,6356400,15.42 +1992-01-23,64.25,64.75,63.00,64.50,4953200,15.40 +1992-01-22,61.50,63.75,61.25,63.50,6560000,15.16 +1992-01-21,64.25,64.25,61.00,61.13,6938000,14.59 +1992-01-20,64.50,65.25,64.00,64.00,7492400,15.28 +1992-01-17,67.75,69.00,64.75,64.75,30308800,15.46 +1992-01-16,63.75,64.25,62.50,62.75,10485200,14.98 +1992-01-15,64.50,65.00,63.00,63.50,11652400,15.16 +1992-01-14,62.25,64.75,62.25,64.50,9789200,15.40 +1992-01-13,62.25,62.75,61.50,62.00,3858800,14.80 +1992-01-10,61.50,62.50,61.00,62.25,7012400,14.86 +1992-01-09,60.50,62.25,60.25,62.25,7450800,14.86 +1992-01-08,58.50,61.25,58.50,60.50,8330800,14.44 +1992-01-07,57.50,59.50,57.50,59.13,5059200,14.11 +1992-01-06,58.75,59.00,57.75,58.00,4080000,13.84 +1992-01-03,60.00,60.25,58.25,59.00,6814400,14.08 +1992-01-02,55.75,59.75,55.50,59.50,8357600,14.20 +1991-12-31,57.38,58.00,56.00,56.38,4802000,13.46 +1991-12-30,55.00,57.25,55.00,56.75,6580800,13.55 +1991-12-27,54.75,55.75,54.50,55.00,6008000,13.13 +1991-12-26,52.75,55.00,52.25,54.88,4805600,13.10 +1991-12-24,52.00,53.75,51.75,52.25,6742400,12.47 +1991-12-23,50.50,51.75,50.00,51.50,3686800,12.29 +1991-12-20,51.25,51.50,50.25,50.25,4588000,11.99 +1991-12-19,51.25,51.75,50.75,50.75,4140800,12.11 +1991-12-18,50.25,52.00,50.00,51.75,6678000,12.35 +1991-12-17,50.50,51.00,50.25,50.50,3502400,12.05 +1991-12-16,50.38,50.75,50.00,50.50,2777600,12.05 +1991-12-13,49.75,50.75,49.75,50.38,3418000,12.03 +1991-12-12,49.38,49.75,49.00,49.38,3297600,11.79 +1991-12-11,49.25,49.75,48.50,49.00,3031200,11.70 +1991-12-10,49.00,49.50,48.50,49.13,4390000,11.73 +1991-12-09,49.00,50.00,48.75,49.13,3502000,11.73 +1991-12-06,49.50,49.75,48.50,48.75,7055200,11.64 +1991-12-05,50.50,51.00,49.25,50.00,3555600,11.93 +1991-12-04,50.75,50.75,50.00,50.50,2897600,12.05 +1991-12-03,52.00,52.00,50.25,50.50,3692400,12.05 +1991-12-02,50.75,52.00,50.00,51.75,4250000,12.35 +1991-11-29,50.50,51.50,50.50,50.75,1227600,12.11 +1991-11-27,51.25,51.50,50.50,51.00,2268800,12.17 +1991-11-26,51.50,52.00,50.00,51.50,4982000,12.29 +1991-11-25,51.00,52.25,51.00,51.25,2802000,12.23 +1991-11-22,51.00,51.75,50.25,51.25,3502400,12.23 +1991-11-21,50.50,51.75,50.50,51.00,3823200,12.17 +1991-11-20,51.25,52.00,50.25,50.50,6005600,12.05 +1991-11-19,51.75,51.75,49.75,51.25,10216400,12.23 +1991-11-18,50.00,52.50,50.00,52.13,8530000,12.44 +1991-11-15,54.50,54.75,49.75,50.00,9186400,11.91 +1991-11-14,54.25,55.25,54.00,54.75,6733600,13.04 +1991-11-13,54.00,54.50,53.50,54.13,6640000,12.89 +1991-11-12,54.25,54.75,53.75,54.50,5972000,12.98 +1991-11-11,53.50,54.50,53.25,53.75,5896800,12.80 +1991-11-08,51.25,53.75,51.00,53.25,13435200,12.68 +1991-11-07,48.50,50.50,48.25,49.75,10618800,11.85 +1991-11-06,49.00,49.25,47.50,48.00,8466400,11.43 +1991-11-05,49.75,50.50,48.75,48.75,7711200,11.61 +1991-11-04,50.75,50.75,48.50,49.75,6983200,11.85 +1991-11-01,51.25,52.00,50.50,51.00,7203600,12.14 +1991-10-31,50.75,51.75,50.00,51.50,8300800,12.26 +1991-10-30,52.00,52.75,49.50,49.75,5302400,11.85 +1991-10-29,51.50,52.00,50.75,51.75,3624400,12.32 +1991-10-28,51.50,51.75,50.75,51.50,2792400,12.26 +1991-10-25,51.75,52.25,50.75,51.25,3832000,12.20 +1991-10-24,53.00,53.25,51.50,52.13,6372400,12.41 +1991-10-23,55.00,55.25,52.75,53.13,6046400,12.65 +1991-10-22,55.50,56.25,54.50,54.50,7456400,12.98 +1991-10-21,55.25,55.88,54.25,54.75,4172000,13.04 +1991-10-18,55.13,55.50,54.50,55.00,15964400,13.10 +1991-10-17,53.00,53.25,51.50,52.38,5423200,12.47 +1991-10-16,52.50,54.00,52.25,53.50,7182000,12.74 +1991-10-15,50.50,52.50,50.00,52.50,10300800,12.50 +1991-10-14,49.00,50.25,48.75,49.88,4015600,11.88 +1991-10-11,48.13,48.88,46.50,48.50,4292000,11.55 +1991-10-10,48.75,49.00,46.75,47.75,5623200,11.37 +1991-10-09,48.25,48.75,47.75,48.00,4752400,11.43 +1991-10-08,48.13,48.50,46.50,48.25,6170000,11.49 +1991-10-07,48.00,48.75,47.50,48.13,2328000,11.46 +1991-10-04,48.00,48.75,47.50,48.25,2854400,11.49 +1991-10-03,50.00,50.00,47.50,47.75,6478000,11.37 +1991-10-02,51.75,51.75,49.50,49.75,643600,11.85 +1991-10-01,49.25,51.25,49.00,50.75,4698800,12.08 +1991-09-30,49.25,49.75,49.00,49.50,2266800,11.79 +1991-09-27,50.00,50.75,48.75,49.00,2245200,11.67 +1991-09-26,50.25,50.25,49.00,50.00,2556800,11.91 +1991-09-25,50.25,50.50,49.25,50.50,1959200,12.02 +1991-09-24,49.50,50.38,48.25,50.25,3805600,11.97 +1991-09-23,50.00,50.75,49.25,49.50,3136800,11.79 +1991-09-20,49.75,51.00,49.50,50.63,6742000,12.06 +1991-09-19,50.25,50.50,49.50,49.75,6374400,11.85 +1991-09-18,48.75,50.50,48.50,50.13,4342000,11.94 +1991-09-17,47.00,49.00,46.75,49.00,4856400,11.67 +1991-09-16,49.25,49.25,46.50,47.25,7365600,11.25 +1991-09-13,50.00,50.25,48.50,48.63,5974400,11.58 +1991-09-12,51.25,51.25,49.75,50.63,4267600,12.06 +1991-09-11,50.75,51.00,49.50,50.50,6378000,12.02 +1991-09-10,52.75,53.38,49.75,50.13,6535600,11.94 +1991-09-09,51.75,53.50,51.50,53.25,4538000,12.68 +1991-09-06,51.00,51.75,50.50,51.50,2848800,12.26 +1991-09-05,51.50,51.75,50.75,51.00,2793600,12.14 +1991-09-04,52.75,52.75,51.38,51.50,4299200,12.26 +1991-09-03,52.75,53.25,52.00,52.50,2443200,12.50 +1991-08-30,53.00,53.25,52.25,53.00,2363200,12.62 +1991-08-29,53.25,53.88,52.50,53.00,4053200,12.62 +1991-08-28,54.00,54.25,53.13,53.25,3843600,12.68 +1991-08-27,53.00,54.00,52.75,54.00,3597600,12.86 +1991-08-26,53.00,53.50,52.50,53.00,3644400,12.62 +1991-08-23,54.00,55.50,52.75,53.00,8601200,12.62 +1991-08-22,54.00,54.75,53.75,54.25,5936400,12.92 +1991-08-21,52.50,54.13,52.00,53.75,7987600,12.80 +1991-08-20,51.50,51.75,50.50,51.00,7123600,12.14 +1991-08-19,49.50,51.63,48.50,50.50,11538000,12.02 +1991-08-16,52.75,54.25,52.25,53.25,5689200,12.65 +1991-08-15,55.00,55.00,53.00,53.25,5219200,12.65 +1991-08-14,54.75,55.00,53.88,54.88,7173200,13.04 +1991-08-13,52.00,54.00,52.00,53.50,10255200,12.71 +1991-08-12,50.75,52.25,50.50,51.75,5096400,12.29 +1991-08-09,50.50,51.00,49.75,50.75,5533600,12.06 +1991-08-08,50.75,51.75,50.00,50.50,6769200,12.00 +1991-08-07,49.50,51.00,49.38,50.38,7578800,11.97 +1991-08-06,48.75,50.25,47.75,49.50,7890800,11.76 +1991-08-05,49.75,49.75,48.25,48.50,3620800,11.52 +1991-08-02,49.75,50.25,49.00,50.00,9767600,11.88 +1991-08-01,46.00,49.25,45.75,49.13,16023600,11.67 +1991-07-31,46.50,46.88,45.00,46.25,3689200,10.99 +1991-07-30,45.50,46.75,45.50,46.50,3281200,11.05 +1991-07-29,45.25,45.50,44.50,45.50,1916800,10.81 +1991-07-26,45.75,45.75,44.75,44.88,2657600,10.66 +1991-07-25,45.25,45.75,45.00,45.25,2366800,10.75 +1991-07-24,45.25,45.75,44.50,45.00,4703200,10.69 +1991-07-23,46.25,46.50,44.50,45.00,4770000,10.69 +1991-07-22,45.75,46.25,45.50,46.00,3882000,10.93 +1991-07-19,45.25,46.25,45.00,46.00,4601200,10.93 +1991-07-18,44.00,45.13,43.00,44.88,14240000,10.66 +1991-07-17,43.50,44.50,42.25,42.50,7474400,10.10 +1991-07-16,45.50,45.75,43.50,43.75,7966400,10.39 +1991-07-15,46.75,46.75,45.50,45.50,4932400,10.81 +1991-07-12,47.25,47.25,46.25,46.75,4753200,11.11 +1991-07-11,47.00,47.25,46.00,46.75,5217600,11.11 +1991-07-10,47.50,48.25,46.75,47.25,5610000,11.23 +1991-07-09,47.25,48.25,46.50,46.88,8091200,11.14 +1991-07-08,45.25,47.25,45.00,46.75,10971200,11.11 +1991-07-05,43.00,46.00,42.75,45.63,11842000,10.84 +1991-07-03,42.25,43.50,41.75,43.13,11087600,10.25 +1991-07-02,42.25,42.75,41.75,42.25,4296800,10.04 +1991-07-01,42.25,43.00,41.75,42.50,6979200,10.10 +1991-06-28,42.25,42.50,40.25,41.50,8102400,9.86 +1991-06-27,42.50,42.75,41.75,42.50,5400000,10.10 +1991-06-26,42.75,43.50,42.25,43.00,8958000,10.22 +1991-06-25,42.00,43.00,41.75,42.38,8151200,10.07 +1991-06-24,41.75,42.25,41.25,41.75,7443600,9.92 +1991-06-21,42.00,42.50,41.75,42.00,7378800,9.98 +1991-06-20,41.25,42.00,40.75,42.00,5158000,9.98 +1991-06-19,41.75,42.25,41.25,41.75,6408000,9.92 +1991-06-18,42.25,43.25,41.50,42.13,8749200,10.01 +1991-06-17,41.00,42.25,41.00,42.00,5966800,9.98 +1991-06-14,42.75,42.75,40.75,41.13,8049200,9.77 +1991-06-13,42.50,43.00,41.75,42.13,7565200,10.01 +1991-06-12,44.00,44.75,41.25,42.38,15580000,10.07 +1991-06-11,45.00,45.50,44.25,44.63,6742400,10.60 +1991-06-10,46.00,47.13,45.75,46.00,5991200,10.93 +1991-06-07,46.25,47.00,45.63,46.13,5463600,10.96 +1991-06-06,48.25,48.25,46.50,46.63,6028000,11.08 +1991-06-05,49.25,49.25,47.75,48.00,4760800,11.40 +1991-06-04,49.50,49.50,48.50,49.13,6593600,11.67 +1991-06-03,47.00,49.50,46.75,49.25,7870800,11.70 +1991-05-31,47.50,47.75,46.25,47.00,7792400,11.17 +1991-05-30,47.00,47.75,46.50,47.63,5663600,11.32 +1991-05-29,46.25,47.75,45.88,47.00,13733600,11.17 +1991-05-28,46.00,46.25,45.25,46.00,6124400,10.93 +1991-05-24,45.50,46.00,45.00,45.88,3484800,10.90 +1991-05-23,46.50,46.75,44.75,45.13,7458800,10.72 +1991-05-22,45.75,46.50,45.50,46.25,8137600,10.99 +1991-05-21,45.25,46.50,44.75,45.25,12500000,10.75 +1991-05-20,47.25,47.50,44.00,44.25,9365200,10.51 +1991-05-17,48.75,48.75,46.50,47.00,16836800,11.14 +1991-05-16,51.00,51.25,48.50,49.00,13652000,11.61 +1991-05-15,51.50,52.00,49.00,50.50,18530800,11.97 +1991-05-14,52.75,53.75,52.50,53.50,7763600,12.68 +1991-05-13,52.25,53.50,51.50,52.75,8763600,12.50 +1991-05-10,51.50,53.25,50.75,51.25,8652000,12.14 +1991-05-09,50.00,51.50,49.75,50.75,8523200,12.03 +1991-05-08,50.75,50.75,49.25,49.75,6332400,11.79 +1991-05-07,51.00,51.25,50.50,50.63,9671200,12.00 +1991-05-06,48.50,50.50,48.25,50.25,7596400,11.91 +1991-05-03,49.00,49.50,48.25,49.00,8717600,11.61 +1991-05-02,47.75,49.75,47.50,49.00,28973600,11.61 +1991-05-01,48.00,49.00,47.00,47.25,66732000,11.20 +1991-04-30,57.75,58.25,54.50,55.00,25413600,13.03 +1991-04-29,58.50,60.25,58.25,58.25,7395200,13.80 +1991-04-26,58.50,59.00,57.75,58.63,4481200,13.89 +1991-04-25,59.75,59.75,58.50,58.50,11276800,13.86 +1991-04-24,61.75,62.00,60.50,60.75,3769200,14.40 +1991-04-23,62.25,63.00,60.25,61.50,8494400,14.57 +1991-04-22,59.50,62.00,58.75,61.50,9190000,14.57 +1991-04-19,61.00,61.50,59.50,59.63,10272400,14.13 +1991-04-18,62.75,63.00,60.75,61.00,8853600,14.46 +1991-04-17,65.00,65.00,62.00,63.25,11533600,14.99 +1991-04-16,63.25,64.50,62.50,64.25,22176800,15.23 +1991-04-15,61.75,64.50,60.00,62.25,60732400,14.75 +1991-04-12,71.50,73.25,69.75,71.75,13140000,17.00 +1991-04-11,67.75,71.37,67.50,71.00,12710800,16.83 +1991-04-10,68.50,69.25,66.75,66.87,7733600,15.85 +1991-04-09,69.75,70.00,68.25,68.75,4280800,16.29 +1991-04-08,69.25,70.00,68.75,70.00,2604400,16.59 +1991-04-05,71.75,71.75,68.75,69.37,5567600,16.44 +1991-04-04,70.00,72.00,69.50,71.50,6024400,16.94 +1991-04-03,72.50,72.75,70.00,70.00,8585200,16.59 +1991-04-02,69.00,72.75,68.50,72.75,10473600,17.24 +1991-04-01,68.00,69.50,67.50,68.50,4218000,16.23 +1991-03-28,69.25,70.00,67.75,68.00,2816800,16.11 +1991-03-27,70.00,70.25,68.50,69.25,6812400,16.41 +1991-03-26,64.75,70.25,64.75,70.00,11935200,16.59 +1991-03-25,63.50,65.00,63.25,64.50,4858800,15.28 +1991-03-22,64.00,64.75,62.25,63.25,12096400,14.99 +1991-03-21,68.25,68.75,63.75,64.75,10600000,15.34 +1991-03-20,69.25,69.50,66.87,67.75,12939200,16.06 +1991-03-19,66.50,70.25,65.75,69.50,15100000,16.47 +1991-03-18,65.75,68.25,65.75,67.75,7645200,16.06 +1991-03-15,65.75,66.50,65.25,66.25,7335600,15.70 +1991-03-14,66.75,67.50,64.50,65.25,8126400,15.46 +1991-03-13,62.75,66.50,62.75,66.25,6253200,15.70 +1991-03-12,63.00,63.75,62.50,62.88,8360000,14.90 +1991-03-11,64.50,64.75,62.25,63.50,6276400,15.05 +1991-03-08,67.75,68.25,65.00,65.00,11522400,15.40 +1991-03-07,63.50,67.50,63.25,67.25,11497600,15.94 +1991-03-06,64.00,65.62,62.88,63.00,18731200,14.93 +1991-03-05,59.00,63.25,59.00,63.13,15769200,14.96 +1991-03-04,58.00,58.75,57.00,58.38,3175600,13.83 +1991-03-01,57.00,59.00,57.00,57.75,4518800,13.69 +1991-02-28,58.25,58.50,56.25,57.25,8120000,13.57 +1991-02-27,58.25,58.50,57.50,58.25,6243200,13.80 +1991-02-26,57.50,58.75,56.50,58.25,8934400,13.80 +1991-02-25,60.25,60.50,57.50,58.00,12848800,13.74 +1991-02-22,59.00,61.75,58.50,59.75,8320800,14.16 +1991-02-21,61.25,62.25,58.75,59.00,6826400,13.98 +1991-02-20,59.50,61.75,59.25,61.00,7646800,14.46 +1991-02-19,57.50,60.25,57.38,60.00,8080800,14.22 +1991-02-15,57.25,58.50,57.25,57.63,13067600,13.66 +1991-02-14,60.00,60.00,56.75,57.13,13493200,13.51 +1991-02-13,60.00,60.25,58.00,60.00,9130800,14.19 +1991-02-12,61.00,61.25,59.38,60.00,8042000,14.19 +1991-02-11,60.00,61.50,59.75,61.38,11546400,14.51 +1991-02-08,57.50,60.25,57.50,59.88,11220000,14.16 +1991-02-07,57.00,58.75,55.75,57.75,18587600,13.66 +1991-02-06,57.75,58.25,56.50,56.88,7965200,13.45 +1991-02-05,55.25,58.00,54.75,57.75,12740000,13.66 +1991-02-04,55.75,56.00,55.00,55.25,9569200,13.07 +1991-02-01,55.50,57.88,55.50,55.75,15897600,13.18 +1991-01-31,55.50,56.00,54.75,55.50,8677600,13.12 +1991-01-30,53.25,55.75,53.25,55.50,12043200,13.12 +1991-01-29,54.25,54.50,52.25,53.75,7708800,12.71 +1991-01-28,53.25,55.25,53.25,54.50,9771200,12.89 +1991-01-25,52.00,53.63,52.00,53.50,8012000,12.65 +1991-01-24,51.50,52.75,51.50,52.13,8374400,12.33 +1991-01-23,51.25,52.25,51.00,51.75,8725600,12.24 +1991-01-22,51.00,52.50,50.50,51.25,15296400,12.12 +1991-01-21,49.75,51.50,49.75,50.75,11595200,12.00 +1991-01-18,48.75,50.75,48.50,50.25,33691200,11.88 +1991-01-17,52.50,52.75,49.00,51.25,21137600,12.12 +1991-01-16,47.00,50.00,46.75,49.75,13968800,11.76 +1991-01-15,46.50,46.75,46.00,46.75,6870000,11.06 +1991-01-14,46.00,46.75,46.00,46.25,7535600,10.94 +1991-01-11,47.00,47.25,46.00,47.00,11003200,11.11 +1991-01-10,45.75,47.25,45.75,47.13,15562400,11.15 +1991-01-09,44.25,46.00,43.75,45.25,16692400,10.70 +1991-01-08,43.75,43.88,42.50,43.25,7816400,10.23 +1991-01-07,43.00,45.25,43.00,43.25,11111200,10.23 +1991-01-04,43.00,44.25,43.00,43.25,5062400,10.23 +1991-01-03,43.50,44.25,43.00,43.00,5365600,10.17 +1991-01-02,42.75,44.00,42.00,43.50,5543600,10.29 +1990-12-31,43.00,43.25,42.75,43.00,1593200,10.17 +1990-12-28,43.25,43.50,42.75,43.00,2285200,10.17 +1990-12-27,43.25,44.00,43.25,43.50,3492000,10.29 +1990-12-26,44.00,44.25,43.00,43.75,3682000,10.35 +1990-12-24,44.75,45.00,44.00,44.00,2106800,10.40 +1990-12-21,44.25,45.25,43.50,45.00,12363200,10.64 +1990-12-20,41.25,44.50,41.25,44.00,14326400,10.40 +1990-12-19,42.50,42.50,41.13,41.88,5036800,9.90 +1990-12-18,41.00,42.50,40.75,42.25,7899200,9.99 +1990-12-17,39.00,40.50,39.00,40.13,4683600,9.49 +1990-12-14,40.25,40.50,39.50,39.88,3126400,9.43 +1990-12-13,39.50,41.00,39.50,40.75,5752000,9.64 +1990-12-12,39.75,40.00,39.00,39.63,8664400,9.37 +1990-12-11,41.25,41.50,40.00,40.00,12438000,9.46 +1990-12-10,42.25,42.50,41.50,41.75,8966400,9.87 +1990-12-07,41.00,42.75,41.00,42.50,11781200,10.05 +1990-12-06,41.25,41.75,40.50,41.25,19013600,9.75 +1990-12-05,38.50,40.25,37.88,40.13,7822000,9.49 +1990-12-04,37.50,38.75,37.50,38.50,5453200,9.10 +1990-12-03,37.25,38.25,37.00,38.13,5922400,9.02 +1990-11-30,36.25,37.25,36.25,36.75,4350800,8.69 +1990-11-29,37.00,37.00,36.25,36.75,4528000,8.69 +1990-11-28,37.75,38.50,36.75,36.75,6250800,8.69 +1990-11-27,37.00,38.25,36.75,37.50,5899200,8.87 +1990-11-26,36.00,37.00,36.00,36.75,2925600,8.69 +1990-11-23,36.25,37.00,36.00,36.38,1911200,8.60 +1990-11-21,35.25,36.25,34.75,36.13,4400800,8.54 +1990-11-20,36.50,36.75,35.25,35.50,5490800,8.39 +1990-11-19,35.50,36.38,35.25,36.38,8017600,8.60 +1990-11-16,35.75,36.00,34.75,35.13,6545200,8.31 +1990-11-15,36.75,37.00,35.50,36.00,5787600,8.48 +1990-11-14,35.75,37.25,35.75,37.00,6819200,8.72 +1990-11-13,36.25,36.50,35.75,36.00,5086400,8.48 +1990-11-12,35.50,36.75,35.25,36.25,5192000,8.54 +1990-11-09,35.00,35.75,34.50,35.50,7102000,8.37 +1990-11-08,33.00,35.00,33.00,34.50,7136400,8.13 +1990-11-07,33.50,33.75,32.63,33.25,7254400,7.84 +1990-11-06,33.50,34.50,33.25,33.50,6620800,7.90 +1990-11-05,32.25,33.50,32.00,33.25,6604400,7.84 +1990-11-02,30.50,32.38,30.50,31.75,5323200,7.48 +1990-11-01,30.50,31.00,29.75,30.50,3258800,7.19 +1990-10-31,30.50,31.87,30.25,30.75,5331200,7.25 +1990-10-30,29.75,30.75,28.87,30.37,3513600,7.16 +1990-10-29,30.25,30.50,29.75,29.87,4415600,7.04 +1990-10-26,29.75,31.25,29.75,30.00,4811200,7.07 +1990-10-25,30.25,31.25,29.62,30.00,5481200,7.07 +1990-10-24,30.75,31.00,30.00,30.50,5079200,7.19 +1990-10-23,31.00,31.50,30.25,31.00,5969200,7.31 +1990-10-22,31.50,31.50,30.50,31.12,9041200,7.33 +1990-10-19,31.25,31.75,30.25,31.37,33363200,7.39 +1990-10-18,26.50,28.75,26.50,28.50,11255600,6.72 +1990-10-17,25.25,26.50,25.00,26.50,11059200,6.25 +1990-10-16,27.50,27.50,24.25,25.00,10913200,5.89 +1990-10-15,28.50,28.75,26.62,27.75,7190000,6.54 +1990-10-12,28.25,28.50,27.00,28.25,8169200,6.66 +1990-10-11,26.75,27.87,25.50,27.75,7376800,6.54 +1990-10-10,27.25,28.00,26.00,26.50,5283600,6.25 +1990-10-09,28.50,29.00,27.75,28.00,4321200,6.60 +1990-10-08,28.75,29.25,28.25,29.12,2218800,6.86 +1990-10-05,27.00,28.75,27.00,28.00,3572000,6.60 +1990-10-04,26.75,28.00,26.25,28.00,7638800,6.60 +1990-10-03,29.75,29.75,26.75,27.00,9591200,6.36 +1990-10-02,31.00,32.00,29.50,29.62,9699200,6.98 +1990-10-01,29.50,31.00,29.25,30.50,5581200,7.19 +1990-09-28,28.50,29.00,27.25,29.00,6291200,6.83 +1990-09-27,30.00,30.50,28.00,28.25,5085600,6.66 +1990-09-26,30.00,30.50,29.75,29.75,3363200,7.01 +1990-09-25,30.50,30.75,29.25,30.00,5642000,7.07 +1990-09-24,31.50,31.50,29.75,30.25,4961200,7.13 +1990-09-21,32.00,32.50,31.00,31.50,5503600,7.42 +1990-09-20,32.25,32.25,31.25,31.62,3607600,7.45 +1990-09-19,33.25,33.75,32.00,32.50,6536800,7.66 +1990-09-18,33.75,33.75,33.00,33.38,4456400,7.87 +1990-09-17,34.00,35.25,33.50,33.75,2782000,7.95 +1990-09-14,33.50,34.25,33.25,34.00,4084400,8.01 +1990-09-13,34.50,34.75,33.00,33.75,3492400,7.95 +1990-09-12,34.50,34.50,33.50,34.00,3600800,8.01 +1990-09-11,36.00,36.13,33.75,34.00,6370800,8.01 +1990-09-10,37.00,37.00,35.75,35.75,2732400,8.43 +1990-09-07,35.50,36.75,35.13,36.38,2098800,8.57 +1990-09-06,35.50,36.00,35.25,35.75,3134800,8.43 +1990-09-05,37.25,37.25,35.75,36.00,2292000,8.48 +1990-09-04,36.50,37.50,36.50,37.00,2974800,8.72 +1990-08-31,36.00,37.25,36.00,37.00,3570000,8.72 +1990-08-30,37.25,37.50,36.00,36.25,4388800,8.54 +1990-08-29,38.00,38.13,36.75,37.25,5407600,8.78 +1990-08-28,37.50,38.38,37.25,38.13,2877600,8.99 +1990-08-27,36.75,38.00,36.25,37.75,4214800,8.90 +1990-08-24,35.25,36.00,34.75,35.50,2634400,8.37 +1990-08-23,34.25,35.00,33.50,34.50,5138800,8.13 +1990-08-22,37.00,37.00,34.88,35.13,4395600,8.28 +1990-08-21,35.75,36.75,35.25,36.25,5769200,8.54 +1990-08-20,36.50,37.50,36.25,36.75,2681200,8.66 +1990-08-17,38.50,38.50,35.75,36.50,8806400,8.58 +1990-08-16,39.00,39.63,38.50,38.50,4438800,9.05 +1990-08-15,40.00,40.25,39.25,39.25,3292000,9.22 +1990-08-14,40.00,40.00,39.25,39.75,3520800,9.34 +1990-08-13,38.00,40.00,37.88,39.88,5584400,9.37 +1990-08-10,38.75,39.25,38.25,38.75,3683600,9.11 +1990-08-09,40.25,40.50,39.25,39.50,3443600,9.28 +1990-08-08,39.50,40.75,39.50,40.13,3674400,9.43 +1990-08-07,40.25,40.63,38.75,39.50,7096400,9.28 +1990-08-06,39.00,40.50,38.50,39.50,6425600,9.28 +1990-08-03,43.50,43.75,39.75,41.25,9609200,9.69 +1990-08-02,41.25,43.75,41.25,43.50,7973600,10.22 +1990-08-01,42.00,42.75,41.50,42.38,3350800,9.96 +1990-07-31,42.50,42.75,41.50,42.00,3444800,9.87 +1990-07-30,40.75,42.50,40.75,42.38,3058800,9.96 +1990-07-27,41.25,41.75,40.50,41.38,2240000,9.72 +1990-07-26,42.25,42.50,41.00,41.38,2885600,9.72 +1990-07-25,42.00,43.25,41.75,42.25,3762400,9.93 +1990-07-24,42.00,42.25,41.00,42.13,6928800,9.90 +1990-07-23,41.00,41.75,40.00,41.50,9655200,9.75 +1990-07-20,42.00,42.50,40.75,41.00,6858000,9.63 +1990-07-19,40.75,42.50,40.00,41.75,20932400,9.81 +1990-07-18,44.50,45.00,43.00,44.63,10309200,10.49 +1990-07-17,45.75,46.00,44.00,44.25,4892000,10.40 +1990-07-16,46.75,47.13,45.25,45.63,6428000,10.72 +1990-07-13,47.50,47.75,46.75,46.75,8254400,10.99 +1990-07-12,46.75,47.50,46.50,47.38,6537600,11.13 +1990-07-11,46.75,47.00,45.75,47.00,8808800,11.04 +1990-07-10,47.00,47.50,46.75,47.00,12923600,11.04 +1990-07-09,45.00,47.00,44.75,46.63,11281200,10.96 +1990-07-06,43.50,45.00,43.25,44.75,7481200,10.52 +1990-07-05,43.75,44.25,43.25,43.50,3859200,10.22 +1990-07-03,43.88,44.50,43.75,44.00,3572400,10.34 +1990-07-02,44.50,44.50,43.75,44.00,4856400,10.34 +1990-06-29,43.00,44.88,42.75,44.75,11622000,10.52 +1990-06-28,42.75,43.25,41.75,43.00,8930000,10.10 +1990-06-27,40.75,42.00,40.25,41.50,3490800,9.75 +1990-06-26,41.75,42.00,40.38,40.63,4558800,9.55 +1990-06-25,41.50,41.75,40.25,41.25,4378000,9.69 +1990-06-22,42.00,42.63,41.25,41.50,10154400,9.75 +1990-06-21,40.00,42.00,40.00,41.88,7455600,9.84 +1990-06-20,39.88,40.25,39.75,40.00,5530000,9.40 +1990-06-19,39.00,39.75,38.38,39.63,5623600,9.31 +1990-06-18,39.25,39.50,39.00,39.25,3988800,9.22 +1990-06-15,39.75,40.00,39.13,39.50,5163600,9.28 +1990-06-14,40.00,40.25,39.25,39.75,5018000,9.34 +1990-06-13,40.38,40.75,39.75,39.75,4963600,9.34 +1990-06-12,39.13,40.50,38.75,40.50,5902000,9.52 +1990-06-11,37.75,39.00,37.75,39.00,5661200,9.16 +1990-06-08,38.50,38.50,37.50,38.25,11926800,8.99 +1990-06-07,39.50,39.75,38.50,39.00,6668800,9.16 +1990-06-06,39.00,39.50,38.75,39.50,7563600,9.28 +1990-06-05,41.00,41.00,39.00,39.50,10702000,9.28 +1990-06-04,40.75,41.00,39.75,40.75,6412400,9.58 +1990-06-01,41.38,42.00,40.75,40.75,5624400,9.58 +1990-05-31,41.50,41.50,41.00,41.25,3682400,9.69 +1990-05-30,41.63,41.75,41.25,41.38,9890000,9.72 +1990-05-29,40.00,41.25,39.25,41.00,8689200,9.63 +1990-05-25,39.50,40.75,39.00,40.00,11562400,9.40 +1990-05-24,42.25,42.25,41.50,42.00,5296400,9.87 +1990-05-23,41.25,42.50,41.25,42.00,7417600,9.87 +1990-05-22,40.13,41.50,40.00,41.38,10772000,9.72 +1990-05-21,39.50,40.00,38.75,39.50,9382400,9.28 +1990-05-18,41.25,41.50,39.50,39.75,9248000,9.31 +1990-05-17,41.75,42.25,41.00,41.50,5488000,9.72 +1990-05-16,41.75,41.75,41.00,41.63,3139200,9.76 +1990-05-15,41.38,42.00,41.00,41.75,5343600,9.78 +1990-05-14,42.75,42.75,41.25,41.75,8088000,9.78 +1990-05-11,41.38,42.75,40.75,42.63,7691200,9.99 +1990-05-10,41.75,41.75,40.50,41.38,6413600,9.70 +1990-05-09,41.63,42.00,41.25,41.88,3491200,9.81 +1990-05-08,41.00,42.00,41.00,41.75,4025600,9.78 +1990-05-07,39.75,41.75,39.75,41.50,4866400,9.72 +1990-05-04,40.00,40.75,39.25,40.00,6063200,9.37 +1990-05-03,39.75,40.25,39.75,40.00,5950800,9.37 +1990-05-02,39.75,40.00,39.25,39.75,4857600,9.31 +1990-05-01,39.75,40.00,39.38,39.63,5845200,9.29 +1990-04-30,39.25,39.75,39.00,39.38,4888800,9.23 +1990-04-27,39.00,39.50,38.75,39.13,4178800,9.17 +1990-04-26,39.00,39.50,38.13,38.88,5098000,9.11 +1990-04-25,38.75,39.00,38.25,38.75,4743200,9.08 +1990-04-24,40.00,40.50,38.50,38.75,10852000,9.08 +1990-04-23,40.25,40.50,39.50,39.75,4597600,9.31 +1990-04-20,40.88,41.50,39.75,40.25,11573600,9.43 +1990-04-19,41.75,43.13,40.00,40.25,17215600,9.43 +1990-04-18,43.25,43.75,42.50,43.25,6925200,10.13 +1990-04-17,43.25,43.50,42.75,43.25,4683600,10.13 +1990-04-16,43.50,44.25,43.25,43.75,8116400,10.25 +1990-04-12,43.00,44.00,42.50,43.25,7566800,10.13 +1990-04-11,41.50,43.00,41.50,42.50,7620000,9.96 +1990-04-10,41.25,42.00,41.00,41.25,4695600,9.67 +1990-04-09,39.75,41.50,39.50,41.13,3771200,9.64 +1990-04-06,40.25,41.25,39.75,39.88,4235600,9.35 +1990-04-05,41.00,41.25,40.00,40.25,3877600,9.43 +1990-04-04,41.50,42.00,40.75,41.25,5363200,9.67 +1990-04-03,40.50,41.75,40.50,41.75,5006400,9.78 +1990-04-02,40.00,40.63,39.50,40.25,5332000,9.43 +1990-03-30,40.00,41.00,40.00,40.25,7986400,9.43 +1990-03-29,41.00,41.50,40.75,41.13,3472000,9.64 +1990-03-28,42.00,42.13,41.00,41.25,3696800,9.67 +1990-03-27,42.00,42.25,41.25,42.00,3033600,9.84 +1990-03-26,42.50,43.38,42.00,42.25,4581200,9.90 +1990-03-23,41.25,43.00,41.00,42.25,8155200,9.90 +1990-03-22,41.75,42.25,40.75,40.75,8292400,9.55 +1990-03-21,41.25,42.25,41.25,41.63,5463200,9.76 +1990-03-20,42.25,43.00,40.75,41.38,13984400,9.70 +1990-03-19,40.50,42.50,40.00,42.38,15433200,9.93 +1990-03-16,40.00,40.75,39.13,40.25,23042400,9.43 +1990-03-15,36.50,38.00,36.50,36.75,4302000,8.61 +1990-03-14,36.75,37.25,36.50,37.00,3654800,8.67 +1990-03-13,36.50,37.25,36.25,36.88,5321200,8.64 +1990-03-12,37.25,37.50,36.25,36.63,5864400,8.58 +1990-03-09,36.75,37.50,36.25,36.88,8248800,8.64 +1990-03-08,35.75,37.00,35.00,36.75,8013600,8.61 +1990-03-07,35.00,36.00,35.00,35.38,7301200,8.29 +1990-03-06,35.00,35.25,34.50,35.25,5578800,8.26 +1990-03-05,33.50,34.75,33.50,34.50,6537600,8.08 +1990-03-02,33.50,34.75,33.25,33.75,3761200,7.91 +1990-03-01,33.50,34.75,33.25,34.25,7283200,8.03 +1990-02-28,33.50,34.00,33.25,34.00,3918800,7.97 +1990-02-27,34.00,34.25,33.50,33.50,2642000,7.85 +1990-02-26,33.00,34.25,33.00,34.00,2844800,7.97 +1990-02-23,32.75,33.50,32.75,33.25,5375600,7.79 +1990-02-22,34.00,34.50,33.00,33.00,6976800,7.73 +1990-02-21,32.75,34.25,32.50,34.00,6283600,7.97 +1990-02-20,33.50,33.75,33.00,33.50,4402400,7.85 +1990-02-16,34.25,34.50,33.75,33.75,4556400,7.91 +1990-02-15,33.75,34.25,33.50,34.25,3509200,8.00 +1990-02-14,34.50,34.75,33.75,34.25,3448000,8.00 +1990-02-13,34.00,35.00,33.75,34.50,3653600,8.06 +1990-02-12,34.25,34.50,33.75,34.00,2695600,7.94 +1990-02-09,33.50,34.50,33.25,34.25,6004400,8.00 +1990-02-08,33.25,33.50,32.25,33.00,6680000,7.71 +1990-02-07,33.00,34.00,32.50,33.25,11180800,7.77 +1990-02-06,34.75,35.00,34.00,34.75,2640000,8.12 +1990-02-05,34.25,35.25,34.00,35.00,3653200,8.18 +1990-02-02,33.25,34.75,33.25,34.25,4248800,8.00 +1990-02-01,34.50,34.63,33.50,33.63,4193200,7.86 +1990-01-31,34.50,34.75,33.00,34.00,5152400,7.94 +1990-01-30,33.25,34.50,33.00,34.00,4180800,7.94 +1990-01-29,33.00,33.50,32.13,33.25,4284800,7.77 +1990-01-26,34.00,34.00,32.25,32.75,6492000,7.65 +1990-01-25,34.25,34.75,34.00,34.13,3996800,7.97 +1990-01-24,32.50,34.25,32.25,34.00,6077600,7.94 +1990-01-23,33.75,34.25,33.00,33.75,5048800,7.88 +1990-01-22,34.00,34.50,33.25,33.25,5200800,7.77 +1990-01-19,33.75,34.50,33.50,34.25,9485600,8.00 +1990-01-18,33.00,33.50,32.25,32.38,9760800,7.56 +1990-01-17,34.75,34.75,33.00,33.25,7050000,7.77 +1990-01-16,33.50,35.00,32.75,34.88,7658000,8.15 +1990-01-15,34.50,35.75,34.25,34.25,5785600,8.00 +1990-01-12,34.25,34.75,33.75,34.50,6150000,8.06 +1990-01-11,36.25,36.25,34.50,34.50,7547600,8.06 +1990-01-10,37.63,37.63,35.75,36.00,7140000,8.41 +1990-01-09,38.00,38.00,37.00,37.63,3096800,8.79 +1990-01-08,37.50,38.00,37.00,38.00,3643200,8.88 +1990-01-05,37.75,38.25,37.00,37.75,4406400,8.82 +1990-01-04,38.25,38.75,37.25,37.63,7928800,8.79 +1990-01-03,38.00,38.00,37.50,37.50,7444400,8.76 +1990-01-02,35.25,37.50,35.00,37.25,6555600,8.70 +1989-12-29,34.75,35.75,34.38,35.25,5445200,8.23 +1989-12-28,35.00,35.25,34.25,34.63,5403200,8.09 +1989-12-27,35.50,35.75,35.00,35.13,9189200,8.21 +1989-12-26,36.75,36.75,35.25,35.50,4849200,8.29 +1989-12-22,36.25,37.25,36.00,36.50,6610800,8.53 +1989-12-21,35.75,36.25,35.50,36.25,10889200,8.47 +1989-12-20,35.75,36.25,35.25,35.75,6377600,8.35 +1989-12-19,34.50,35.50,34.50,35.00,8977600,8.18 +1989-12-18,33.75,35.00,33.75,34.75,10978000,8.12 +1989-12-15,34.75,35.00,32.50,33.75,18520800,7.88 +1989-12-14,35.75,36.13,34.50,34.88,10886400,8.15 +1989-12-13,36.00,36.50,35.50,36.00,13920000,8.41 +1989-12-12,39.25,39.50,35.00,36.00,36634400,8.41 +1989-12-11,41.00,41.50,38.38,39.25,23223200,9.17 +1989-12-08,42.50,43.00,41.25,41.75,9032400,9.75 +1989-12-07,42.25,43.25,42.00,42.75,6378800,9.99 +1989-12-06,45.00,45.25,41.00,42.75,11965600,9.99 +1989-12-05,45.25,45.75,44.50,45.00,4364800,10.51 +1989-12-04,43.75,45.50,43.75,45.25,3498000,10.57 +1989-12-01,44.50,45.00,43.63,44.00,5235200,10.28 +1989-11-30,43.75,44.50,43.50,44.25,2280800,10.34 +1989-11-29,43.50,44.25,42.50,44.00,5475200,10.28 +1989-11-28,43.75,44.25,42.75,44.13,4854400,10.31 +1989-11-27,44.75,45.25,43.75,44.00,3774800,10.28 +1989-11-24,44.75,45.00,44.75,44.75,1014400,10.45 +1989-11-22,45.50,45.75,44.50,44.75,3508000,10.45 +1989-11-21,45.25,46.50,45.25,45.25,5013600,10.57 +1989-11-20,45.00,45.50,44.50,45.25,3870800,10.57 +1989-11-17,44.50,45.25,44.50,44.75,3164400,10.45 +1989-11-16,44.50,44.75,43.75,44.75,3453600,10.43 +1989-11-15,45.00,45.25,44.00,44.25,3499200,10.31 +1989-11-14,46.50,46.75,44.50,44.75,3021200,10.43 +1989-11-13,46.50,47.25,46.50,46.50,2445600,10.83 +1989-11-10,45.75,47.00,45.75,46.75,2336800,10.89 +1989-11-09,45.00,46.00,44.50,46.00,3166400,10.72 +1989-11-08,44.25,45.25,44.25,45.00,5102000,10.49 +1989-11-07,43.25,44.50,43.25,44.00,5406800,10.25 +1989-11-06,43.50,44.00,43.00,43.25,4416400,10.08 +1989-11-03,44.00,44.50,43.25,43.25,6258800,10.08 +1989-11-02,45.00,45.00,43.00,44.00,16170800,10.25 +1989-11-01,46.25,46.75,45.75,46.13,2199200,10.75 +1989-10-31,45.75,46.50,45.50,46.50,3288800,10.83 +1989-10-30,45.50,46.00,45.00,45.75,3121200,10.66 +1989-10-27,45.25,45.75,44.50,45.25,4634400,10.54 +1989-10-26,45.50,46.50,45.00,45.25,6048000,10.54 +1989-10-25,47.75,47.75,46.25,46.50,4263600,10.83 +1989-10-24,46.25,48.50,45.25,47.63,7735600,11.10 +1989-10-23,48.00,48.25,46.25,46.75,4375600,10.89 +1989-10-20,47.75,49.25,47.50,48.00,9350800,11.18 +1989-10-19,48.25,49.50,48.25,48.75,4016800,11.36 +1989-10-18,46.50,48.25,46.00,48.25,5157600,11.24 +1989-10-17,46.00,48.75,45.00,47.25,8935600,11.01 +1989-10-16,44.75,46.75,42.50,46.75,15184400,10.89 +1989-10-13,48.75,49.50,45.00,45.75,7195600,10.66 +1989-10-12,49.00,49.25,48.50,48.75,2969200,11.36 +1989-10-11,48.75,49.25,48.00,48.88,5608800,11.39 +1989-10-10,49.75,50.38,48.50,49.50,10262400,11.53 +1989-10-09,48.00,49.75,47.50,49.50,6997600,11.53 +1989-10-06,46.25,48.25,46.00,48.13,12939200,11.21 +1989-10-05,44.50,46.50,44.25,45.50,8760000,10.60 +1989-10-04,43.75,44.63,43.50,44.25,5687600,10.31 +1989-10-03,44.25,44.50,43.13,43.63,6094400,10.17 +1989-10-02,44.50,44.75,43.75,44.38,4922400,10.34 +1989-09-29,45.25,45.50,44.50,44.50,2500800,10.37 +1989-09-28,45.00,45.75,45.00,45.50,2856800,10.60 +1989-09-27,44.25,45.13,44.00,44.75,3229200,10.43 +1989-09-26,45.00,45.50,44.75,45.25,2762400,10.54 +1989-09-25,44.75,45.75,44.75,45.25,4875600,10.54 +1989-09-22,44.75,45.25,44.25,44.88,2605600,10.46 +1989-09-21,45.00,46.00,44.25,44.75,7186800,10.43 +1989-09-20,44.00,45.00,43.75,44.63,4230800,10.40 +1989-09-19,44.25,44.50,43.00,43.25,2888800,10.08 +1989-09-18,44.50,45.00,44.00,44.00,2264400,10.25 +1989-09-15,45.00,45.25,44.25,45.00,4470800,10.49 +1989-09-14,45.00,45.25,44.50,44.75,4693600,10.43 +1989-09-13,46.25,46.63,45.00,45.00,4616400,10.49 +1989-09-12,45.50,46.75,45.00,46.00,3710800,10.72 +1989-09-11,44.75,46.00,44.50,45.75,3522000,10.66 +1989-09-08,44.75,45.25,44.50,45.00,2013200,10.49 +1989-09-07,44.75,45.50,44.75,44.75,4083200,10.43 +1989-09-06,44.75,44.88,44.00,44.75,3108800,10.43 +1989-09-05,44.50,45.38,44.50,44.75,4112400,10.43 +1989-09-01,44.50,44.75,44.25,44.63,2651200,10.40 +1989-08-31,44.50,45.00,44.25,44.50,2016400,10.37 +1989-08-30,44.00,44.75,44.00,44.50,4161200,10.37 +1989-08-29,44.75,45.00,43.75,44.13,6339200,10.28 +1989-08-28,44.50,45.00,44.00,44.75,2936800,10.43 +1989-08-25,44.00,45.00,44.00,44.75,5766400,10.43 +1989-08-24,43.75,44.50,43.50,44.13,5829200,10.28 +1989-08-23,43.00,44.25,42.50,43.75,6202400,10.19 +1989-08-22,42.00,43.00,42.00,42.88,4013200,9.99 +1989-08-21,42.25,43.25,42.00,42.25,4923600,9.84 +1989-08-18,41.75,42.50,41.50,42.25,3003600,9.82 +1989-08-17,40.25,41.25,40.00,41.00,5495600,9.53 +1989-08-16,41.50,41.75,40.00,40.38,4318800,9.39 +1989-08-15,40.75,41.50,40.75,41.38,5852000,9.62 +1989-08-14,41.50,42.00,40.50,40.75,3690800,9.47 +1989-08-11,44.00,44.00,41.25,41.88,8226800,9.74 +1989-08-10,44.00,44.00,42.75,43.25,5442400,10.05 +1989-08-09,44.00,45.75,43.88,44.00,6975600,10.23 +1989-08-08,43.50,44.75,43.50,44.13,7366400,10.26 +1989-08-07,43.00,44.00,42.63,43.75,6012000,10.17 +1989-08-04,41.25,42.75,41.13,42.75,6564400,9.94 +1989-08-03,40.50,41.50,40.50,41.25,6185600,9.59 +1989-08-02,39.75,40.50,39.50,40.50,3633600,9.41 +1989-08-01,39.75,40.25,39.25,39.88,4996800,9.27 +1989-07-31,39.25,40.00,39.00,39.75,4014800,9.24 +1989-07-28,39.25,39.75,39.00,39.38,4274400,9.15 +1989-07-27,38.25,39.50,38.00,39.25,6193200,9.12 +1989-07-26,38.25,38.50,37.75,38.25,8363600,8.89 +1989-07-25,39.25,39.75,38.00,38.75,7502400,9.01 +1989-07-24,39.75,39.75,39.25,39.25,4154800,9.12 +1989-07-21,39.75,40.00,39.00,40.00,4993600,9.30 +1989-07-20,40.75,41.25,39.75,40.00,8448800,9.30 +1989-07-19,39.50,40.75,39.00,40.50,8543200,9.41 +1989-07-18,40.75,40.75,38.75,39.25,17050800,9.12 +1989-07-17,40.75,41.25,39.75,40.75,4694400,9.47 +1989-07-14,40.75,41.00,39.75,40.75,9206800,9.47 +1989-07-13,40.00,41.00,39.50,40.63,8057600,9.44 +1989-07-12,39.75,40.25,39.50,40.00,4452000,9.30 +1989-07-11,40.75,41.00,39.75,39.75,8729200,9.24 +1989-07-10,41.00,41.25,40.00,40.50,7294400,9.41 +1989-07-07,41.25,42.00,40.50,41.25,3806400,9.59 +1989-07-06,40.75,41.75,40.25,41.25,6218000,9.59 +1989-07-05,40.50,40.75,40.00,40.50,4264400,9.41 +1989-07-03,41.75,41.75,40.75,40.75,1730800,9.47 +1989-06-30,40.50,41.75,39.50,41.25,5885600,9.59 +1989-06-29,41.00,41.25,40.00,40.63,8351200,9.44 +1989-06-28,42.25,42.25,41.00,41.75,9190800,9.70 +1989-06-27,43.75,44.25,42.50,42.63,3788000,9.91 +1989-06-26,44.00,44.00,43.25,43.50,6568800,10.11 +1989-06-23,43.25,44.25,43.25,43.88,4438800,10.20 +1989-06-22,42.50,43.75,42.00,43.25,4911200,10.05 +1989-06-21,43.00,43.50,42.25,42.50,4659200,9.88 +1989-06-20,44.00,44.00,42.25,43.00,4807600,10.00 +1989-06-19,44.50,44.75,43.50,44.00,6551200,10.23 +1989-06-16,44.75,45.50,43.50,44.50,19378000,10.34 +1989-06-15,49.50,49.75,47.50,47.50,5766800,11.04 +1989-06-14,49.00,50.25,48.25,49.63,8983600,11.54 +1989-06-13,47.50,48.75,47.00,48.50,8254400,11.27 +1989-06-12,46.75,47.75,46.25,47.50,2892400,11.04 +1989-06-09,47.25,47.75,46.50,47.00,3378800,10.93 +1989-06-08,48.50,49.00,47.25,47.63,6378800,11.07 +1989-06-07,46.75,48.50,46.75,48.25,6293200,11.22 +1989-06-06,46.75,47.00,46.25,46.75,5189200,10.87 +1989-06-05,48.75,49.00,46.50,47.00,4451200,10.93 +1989-06-02,48.50,49.50,48.50,49.00,4448800,11.39 +1989-06-01,47.75,49.25,47.50,48.75,6416800,11.33 +1989-05-31,47.50,48.13,47.00,47.75,4134400,11.10 +1989-05-30,48.25,49.00,47.38,47.50,4018000,11.04 +1989-05-26,48.25,49.00,48.00,48.50,4028800,11.27 +1989-05-25,47.25,49.00,47.25,48.25,8309200,11.22 +1989-05-24,45.25,47.75,45.25,47.75,10645200,11.10 +1989-05-23,46.00,46.00,45.25,45.50,4803600,10.58 +1989-05-22,45.75,46.25,45.25,46.00,6800000,10.69 +1989-05-19,44.75,46.25,44.75,45.75,11820800,10.61 +1989-05-18,45.25,45.50,44.75,44.75,7558800,10.38 +1989-05-17,45.25,45.50,45.00,45.25,8892400,10.50 +1989-05-16,46.00,46.25,45.00,45.38,8170800,10.53 +1989-05-15,44.75,46.25,44.75,46.00,11372400,10.67 +1989-05-12,44.50,45.00,44.00,45.00,16685600,10.44 +1989-05-11,43.25,44.25,43.00,43.88,10763600,10.18 +1989-05-10,43.00,43.50,42.50,43.25,8380000,10.03 +1989-05-09,42.00,43.00,42.00,42.50,12398800,9.86 +1989-05-08,41.50,42.25,41.50,42.25,7373600,9.80 +1989-05-05,42.50,42.75,41.50,41.50,16464400,9.63 +1989-05-04,40.25,41.25,40.00,41.00,6762000,9.51 +1989-05-03,39.75,40.75,39.75,40.25,7896800,9.34 +1989-05-02,39.00,40.25,39.00,39.88,7719200,9.25 +1989-05-01,38.50,39.25,38.50,39.00,2881200,9.05 +1989-04-28,39.25,39.50,38.50,39.00,3725600,9.05 +1989-04-27,39.50,40.00,39.00,39.38,4988000,9.13 +1989-04-26,40.00,40.25,39.13,39.75,6652000,9.22 +1989-04-25,40.00,40.50,39.75,40.00,4165600,9.28 +1989-04-24,40.00,40.25,39.50,40.13,3977600,9.31 +1989-04-21,40.50,40.88,39.75,40.13,4132000,9.31 +1989-04-20,40.75,41.50,40.25,40.75,6434400,9.45 +1989-04-19,40.00,41.63,39.75,40.88,15215600,9.48 +1989-04-18,39.50,40.50,39.25,40.13,20055200,9.31 +1989-04-17,38.50,39.25,38.00,39.25,5008000,9.10 +1989-04-14,39.00,39.25,38.25,38.75,4408800,8.99 +1989-04-13,38.75,39.50,38.25,38.50,6493200,8.93 +1989-04-12,38.25,39.25,37.88,38.50,13862000,8.93 +1989-04-11,37.50,38.00,37.00,37.75,5252400,8.76 +1989-04-10,37.25,38.00,36.75,37.00,4854400,8.58 +1989-04-07,36.00,37.50,36.00,37.38,12699200,8.67 +1989-04-06,34.75,36.13,34.50,36.00,5598800,8.35 +1989-04-05,34.50,35.25,34.25,35.00,4303200,8.12 +1989-04-04,34.50,34.88,33.88,34.50,4140800,8.00 +1989-04-03,35.50,36.25,34.75,35.00,5949200,8.12 +1989-03-31,35.00,35.75,34.75,35.63,6630800,8.26 +1989-03-30,34.25,35.00,34.00,34.75,3780800,8.06 +1989-03-29,34.00,34.50,34.00,34.25,2666800,7.94 +1989-03-28,34.00,34.50,34.00,34.00,5047600,7.89 +1989-03-27,34.25,34.50,33.50,33.75,5425600,7.83 +1989-03-23,34.00,34.50,33.75,34.38,4250800,7.97 +1989-03-22,34.25,34.75,33.75,33.88,5180800,7.86 +1989-03-21,35.50,35.50,34.75,34.88,4588800,8.09 +1989-03-20,35.00,35.25,34.50,34.88,6480800,8.09 +1989-03-17,34.50,35.75,34.00,34.88,8485200,8.09 +1989-03-16,35.00,35.50,34.50,35.25,6880000,8.18 +1989-03-15,35.25,35.50,34.75,35.00,3225600,8.12 +1989-03-14,35.00,35.50,34.88,35.25,5796800,8.18 +1989-03-13,35.00,35.50,34.75,35.00,4683600,8.12 +1989-03-10,34.50,35.00,34.25,35.00,3684400,8.12 +1989-03-09,35.25,35.75,34.50,34.50,4768800,8.00 +1989-03-08,35.63,36.25,35.25,35.25,7727600,8.18 +1989-03-07,35.50,36.00,35.00,35.75,9327600,8.29 +1989-03-06,35.00,35.88,34.50,35.50,6028800,8.23 +1989-03-03,35.25,35.25,34.00,34.75,13854400,8.06 +1989-03-02,35.75,36.25,34.75,35.00,13440800,8.12 +1989-03-01,36.25,36.50,35.50,36.00,6096400,8.35 +1989-02-28,36.50,36.75,36.00,36.25,6290000,8.41 +1989-02-27,36.00,36.50,35.75,36.50,4151200,8.47 +1989-02-24,37.00,37.00,36.00,36.00,5452000,8.35 +1989-02-23,36.50,37.00,36.25,36.75,3409200,8.52 +1989-02-22,37.25,37.50,36.50,36.75,8529200,8.52 +1989-02-21,36.88,37.75,36.75,37.50,6808800,8.70 +1989-02-17,36.25,37.00,36.25,36.75,4180800,8.52 +1989-02-16,36.25,37.25,36.00,36.38,9138800,8.41 +1989-02-15,35.75,36.25,35.50,36.25,11812400,8.38 +1989-02-14,36.88,37.00,35.25,35.75,31843200,8.27 +1989-02-13,36.75,37.25,36.75,37.00,8422000,8.56 +1989-02-10,38.25,38.25,37.00,37.25,12441200,8.62 +1989-02-09,38.25,39.00,38.00,38.25,5756400,8.85 +1989-02-08,39.00,39.50,38.00,38.25,5612000,8.85 +1989-02-07,38.25,39.25,38.25,39.00,5908800,9.02 +1989-02-06,39.50,39.50,38.25,38.50,4174400,8.91 +1989-02-03,40.00,40.25,39.00,39.25,6406400,9.08 +1989-02-02,39.50,40.25,39.25,39.75,16927600,9.19 +1989-02-01,37.75,39.63,37.38,39.25,17420000,9.08 +1989-01-31,37.25,37.75,36.75,37.75,16442000,8.73 +1989-01-30,37.63,38.00,37.25,37.38,20961200,8.65 +1989-01-27,38.25,39.25,36.25,37.63,75976400,8.70 +1989-01-26,40.75,42.13,40.63,41.75,10203600,9.66 +1989-01-25,41.75,42.00,41.00,41.50,3963200,9.60 +1989-01-24,41.00,41.75,40.75,41.63,7983200,9.63 +1989-01-23,40.75,41.25,40.75,41.00,6452000,9.48 +1989-01-20,40.50,41.50,40.25,41.00,6207600,9.48 +1989-01-19,40.50,41.00,40.00,40.50,9155200,9.37 +1989-01-18,40.75,41.13,39.50,39.75,17440800,9.19 +1989-01-17,43.25,43.50,40.00,40.38,27033600,9.34 +1989-01-16,43.25,44.00,43.00,43.75,6033200,10.12 +1989-01-13,42.75,43.50,42.38,43.25,6928000,10.00 +1989-01-12,42.25,43.00,42.00,42.75,5373200,9.89 +1989-01-11,42.25,42.50,41.25,42.13,5585200,9.74 +1989-01-10,42.50,42.88,41.50,42.63,3695600,9.86 +1989-01-09,43.00,43.13,42.25,43.00,2850800,9.95 +1989-01-06,42.25,43.50,42.25,42.63,7103600,9.86 +1989-01-05,42.00,43.25,41.25,42.25,10985200,9.77 +1989-01-04,40.75,42.13,40.50,42.00,8575200,9.71 +1989-01-03,40.25,40.50,40.00,40.38,3578800,9.34 +1988-12-30,40.50,41.25,40.25,40.25,2938800,9.31 +1988-12-29,40.25,40.75,40.25,40.50,4212000,9.37 +1988-12-28,40.50,40.75,39.75,40.25,1841200,9.31 +1988-12-27,41.00,41.50,40.50,40.50,2155200,9.37 +1988-12-23,41.00,41.38,41.00,41.13,1475600,9.51 +1988-12-22,41.75,42.00,40.75,41.00,3802000,9.48 +1988-12-21,41.00,42.00,41.00,41.75,8642400,9.66 +1988-12-20,41.00,41.50,40.63,41.00,9810800,9.48 +1988-12-19,40.25,41.00,40.00,40.75,8373600,9.43 +1988-12-16,39.50,40.50,39.25,40.13,6572000,9.28 +1988-12-15,40.00,40.50,39.25,39.50,4032000,9.14 +1988-12-14,38.50,40.00,38.50,39.75,6916800,9.19 +1988-12-13,38.50,38.75,38.25,38.75,4386400,8.96 +1988-12-12,39.25,39.50,38.50,38.50,4215600,8.91 +1988-12-09,39.25,39.50,38.75,39.13,1608800,9.05 +1988-12-08,39.25,39.25,38.75,39.13,2125600,9.05 +1988-12-07,39.00,39.50,38.75,39.38,3518800,9.11 +1988-12-06,39.25,39.75,39.00,39.50,3763200,9.14 +1988-12-05,39.50,40.00,38.75,39.50,5534400,9.14 +1988-12-02,38.25,39.88,38.00,39.25,11940000,9.08 +1988-12-01,37.75,39.00,37.50,38.75,7586800,8.96 +1988-11-30,36.75,38.00,36.75,37.63,6013600,8.70 +1988-11-29,36.50,36.75,36.00,36.75,3326400,8.50 +1988-11-28,36.50,36.75,36.00,36.50,4986800,8.44 +1988-11-25,36.25,36.75,36.00,36.50,1727600,8.44 +1988-11-23,35.75,37.00,35.50,36.88,6733200,8.53 +1988-11-22,36.50,36.88,36.00,36.13,5299200,8.36 +1988-11-21,37.50,37.75,36.25,36.63,7928000,8.47 +1988-11-18,38.50,38.50,38.00,38.00,2066400,8.77 +1988-11-17,38.00,38.50,38.00,38.25,2841200,8.82 +1988-11-16,39.00,39.25,37.75,38.00,5280000,8.77 +1988-11-15,39.00,39.25,38.75,39.00,2866800,9.00 +1988-11-14,38.75,39.00,38.25,38.88,3046400,8.97 +1988-11-11,39.00,39.63,38.50,38.50,3882400,8.88 +1988-11-10,39.50,39.75,39.00,39.50,3573200,9.11 +1988-11-09,38.25,39.38,38.00,39.25,7206800,9.05 +1988-11-08,37.50,38.75,37.38,38.50,5540800,8.88 +1988-11-07,37.25,37.75,37.00,37.50,6093600,8.65 +1988-11-04,36.75,38.00,36.75,37.75,5500000,8.71 +1988-11-03,37.25,37.50,36.75,37.13,8670000,8.57 +1988-11-02,38.25,38.25,36.75,37.25,7451200,8.59 +1988-11-01,38.50,38.75,37.75,38.00,5138800,8.77 +1988-10-31,38.75,38.75,37.50,38.63,8695200,8.91 +1988-10-28,39.00,39.50,38.50,38.50,3026800,8.88 +1988-10-27,38.75,39.25,38.25,39.00,5138000,9.00 +1988-10-26,40.00,40.00,38.50,39.25,6751200,9.05 +1988-10-25,40.25,40.25,39.75,39.88,3043600,9.20 +1988-10-24,41.25,41.25,39.63,40.00,4842400,9.23 +1988-10-21,41.25,41.75,40.75,41.00,4422400,9.46 +1988-10-20,40.00,41.63,40.00,41.50,6215200,9.57 +1988-10-19,39.75,40.75,39.50,40.00,9918000,9.23 +1988-10-18,39.00,39.50,38.25,39.38,5100000,9.08 +1988-10-17,38.50,39.00,38.25,38.50,3360800,8.88 +1988-10-14,39.50,39.50,38.13,38.75,5625200,8.94 +1988-10-13,38.50,39.75,38.50,39.00,5892400,9.00 +1988-10-12,38.50,39.00,38.00,38.75,4763600,8.94 +1988-10-11,38.25,39.50,38.25,39.00,6964400,9.00 +1988-10-10,39.50,39.75,37.50,38.50,11880000,8.88 +1988-10-07,39.00,39.75,38.38,39.75,16355200,9.17 +1988-10-06,40.50,40.88,39.25,39.75,6009200,9.17 +1988-10-05,41.25,41.75,40.50,40.88,4400000,9.43 +1988-10-04,42.25,42.75,41.13,41.50,1847600,9.57 +1988-10-03,43.00,43.25,42.00,42.50,3243200,9.80 +1988-09-30,44.00,44.00,43.25,43.25,3338800,9.98 +1988-09-29,43.75,44.25,43.50,44.00,3804400,10.15 +1988-09-28,43.50,44.13,43.25,43.50,3038800,10.04 +1988-09-27,42.50,43.50,42.50,43.38,5832400,10.01 +1988-09-26,43.75,44.00,42.50,42.75,3124400,9.86 +1988-09-23,43.50,44.25,43.50,43.75,3638000,10.09 +1988-09-22,43.00,44.00,42.75,44.00,5203600,10.15 +1988-09-21,41.75,43.00,41.50,42.75,3274800,9.86 +1988-09-20,41.75,42.25,41.38,41.50,3682400,9.57 +1988-09-19,42.00,42.25,41.25,41.75,3296400,9.63 +1988-09-16,41.50,42.75,41.38,42.25,4431200,9.75 +1988-09-15,42.00,42.75,41.50,41.63,5920000,9.60 +1988-09-14,41.75,42.38,41.50,42.00,8520800,9.69 +1988-09-13,40.25,41.25,40.00,41.00,4293600,9.46 +1988-09-12,41.00,41.75,40.13,41.00,5290800,9.46 +1988-09-09,38.75,41.00,37.75,40.50,8393200,9.34 +1988-09-08,38.25,39.50,37.75,38.75,7403200,8.94 +1988-09-07,39.00,39.50,37.75,38.25,6417600,8.82 +1988-09-06,40.00,40.00,38.75,38.88,5125200,8.97 +1988-09-02,39.50,40.00,39.00,39.75,6661200,9.17 +1988-09-01,39.75,39.75,38.50,38.88,8818800,8.97 +1988-08-31,41.00,41.13,39.50,39.88,8493600,9.20 +1988-08-30,40.75,41.00,40.00,40.88,1809200,9.43 +1988-08-29,40.75,41.00,40.50,40.88,2046400,9.43 +1988-08-26,40.00,40.75,40.00,40.25,1453200,9.29 +1988-08-25,40.25,40.50,39.25,40.13,4560000,9.26 +1988-08-24,39.75,40.75,39.50,40.75,4482000,9.40 +1988-08-23,39.75,40.25,39.25,39.50,5843200,9.11 +1988-08-22,40.25,40.75,39.50,39.75,6100000,9.17 +1988-08-19,42.50,42.75,40.50,40.75,8120000,9.40 +1988-08-18,42.00,43.00,41.75,42.50,2648000,9.80 +1988-08-17,42.50,42.75,41.75,42.00,4252400,9.69 +1988-08-16,41.00,43.25,40.75,42.50,4397600,9.80 +1988-08-15,42.25,42.25,40.50,41.25,5971200,9.52 +1988-08-12,43.00,43.00,42.25,42.50,2771200,9.79 +1988-08-11,42.25,43.25,42.00,43.25,3803200,9.96 +1988-08-10,43.75,43.75,41.75,41.88,5300800,9.64 +1988-08-09,44.00,44.25,43.00,43.50,6090800,10.02 +1988-08-08,44.50,44.75,44.00,44.00,1085600,10.13 +1988-08-05,44.50,45.00,44.25,44.25,1881200,10.19 +1988-08-04,44.75,45.25,44.50,44.63,2473200,10.28 +1988-08-03,44.75,44.75,44.00,44.75,3980800,10.30 +1988-08-02,45.00,45.50,44.50,44.63,4338000,10.28 +1988-08-01,44.50,45.75,44.25,45.00,3085600,10.36 +1988-07-29,43.25,44.50,43.00,44.38,5697600,10.22 +1988-07-28,42.50,43.00,42.25,42.63,3326800,9.82 +1988-07-27,42.75,43.25,42.50,42.75,4162400,9.84 +1988-07-26,42.75,43.25,42.25,42.75,3640800,9.84 +1988-07-25,42.75,43.25,42.25,42.75,3794400,9.84 +1988-07-22,43.00,43.25,42.50,42.50,3724800,9.79 +1988-07-21,43.75,44.00,42.75,43.00,5323600,9.90 +1988-07-20,44.75,45.00,44.00,44.25,4293600,10.19 +1988-07-19,45.00,45.50,43.88,44.75,4372400,10.30 +1988-07-18,45.38,46.00,45.25,45.50,4061200,10.48 +1988-07-15,45.00,45.50,44.75,45.00,2968000,10.36 +1988-07-14,44.75,45.25,44.50,45.00,2245200,10.36 +1988-07-13,44.75,45.00,44.25,44.75,4132000,10.30 +1988-07-12,45.00,45.25,44.50,44.75,3605600,10.30 +1988-07-11,45.50,45.50,44.88,45.13,2646400,10.39 +1988-07-08,45.50,46.00,45.00,45.25,3766400,10.42 +1988-07-07,46.50,46.50,45.25,45.88,3778000,10.56 +1988-07-06,47.13,47.50,46.13,46.50,5608800,10.71 +1988-07-05,46.50,47.25,46.13,47.25,3736400,10.88 +1988-07-01,46.50,46.88,46.25,46.50,3385600,10.71 +1988-06-30,46.25,46.75,46.00,46.25,4104800,10.65 +1988-06-29,46.00,46.75,45.75,46.38,5125200,10.68 +1988-06-28,44.75,46.25,44.50,46.25,5809200,10.65 +1988-06-27,44.50,45.38,44.50,44.50,3001200,10.25 +1988-06-24,45.00,45.50,44.50,45.00,2684400,10.36 +1988-06-23,45.75,45.75,45.00,45.00,2566400,10.36 +1988-06-22,45.50,45.88,45.00,45.63,6998000,10.51 +1988-06-21,44.00,45.00,43.88,44.88,4422000,10.33 +1988-06-20,44.38,44.75,44.00,44.13,2811200,10.16 +1988-06-17,44.75,44.75,44.25,44.75,3410800,10.30 +1988-06-16,45.00,45.25,44.25,44.50,3854400,10.25 +1988-06-15,45.25,45.75,45.00,45.75,4360000,10.53 +1988-06-14,45.25,46.00,45.00,45.25,10445600,10.42 +1988-06-13,45.00,45.25,44.25,45.00,5320000,10.36 +1988-06-10,43.50,44.75,43.00,44.50,6320000,10.25 +1988-06-09,45.00,45.25,43.25,43.50,9640000,10.02 +1988-06-08,44.25,45.50,44.00,45.00,9240000,10.36 +1988-06-07,43.75,45.25,43.50,44.00,11120000,10.13 +1988-06-06,42.75,44.00,42.75,44.00,5880000,10.13 +1988-06-03,41.75,43.25,41.75,43.00,6280000,9.90 +1988-06-02,42.00,42.50,41.50,41.75,4760000,9.61 +1988-06-01,41.50,42.50,41.25,42.50,8200000,9.79 +1988-05-31,40.00,41.50,39.75,41.50,4400000,9.56 +1988-05-27,39.25,40.00,39.00,39.75,3020000,9.15 +1988-05-26,38.50,39.50,38.50,39.38,3076800,9.07 +1988-05-25,39.00,39.75,38.50,38.50,4840000,8.87 +1988-05-24,38.00,39.00,37.75,38.88,5080000,8.95 +1988-05-23,38.50,38.88,37.38,38.00,6560000,8.75 +1988-05-20,39.25,39.50,38.75,38.75,2941200,8.92 +1988-05-19,39.50,39.75,38.50,39.00,8920000,8.98 +1988-05-18,40.50,40.75,39.50,39.75,6240000,9.15 +1988-05-17,41.50,42.00,40.25,40.50,6920000,9.33 +1988-05-16,40.50,41.38,40.00,41.25,2686800,9.50 +1988-05-13,40.25,40.50,40.00,40.50,2566800,9.31 +1988-05-12,39.50,40.25,39.50,39.75,2965600,9.13 +1988-05-11,40.25,40.75,39.50,39.50,6240000,9.08 +1988-05-10,40.50,41.00,40.25,40.88,3439200,9.39 +1988-05-09,41.25,41.25,40.50,40.75,2732000,9.36 +1988-05-06,41.63,41.75,41.25,41.25,3835600,9.48 +1988-05-05,42.00,42.25,41.50,41.75,2536800,9.59 +1988-05-04,41.88,43.13,41.75,42.00,8000000,9.65 +1988-05-03,41.00,42.25,40.75,41.75,4440000,9.59 +1988-05-02,40.75,41.25,40.50,41.00,2944400,9.42 +1988-04-29,41.25,41.50,40.50,41.00,3222000,9.42 +1988-04-28,41.75,42.00,41.25,41.38,3553600,9.51 +1988-04-27,41.75,42.00,41.50,41.75,4520000,9.59 +1988-04-26,41.00,41.75,40.75,41.50,6280000,9.54 +1988-04-25,40.25,41.00,40.00,40.88,5360000,9.39 +1988-04-22,39.75,40.25,39.50,40.13,3846800,9.22 +1988-04-21,40.38,40.50,39.00,39.50,6360000,9.08 +1988-04-20,40.25,40.50,39.25,39.75,7680000,9.13 +1988-04-19,40.13,41.50,40.13,40.25,7596400,9.25 +1988-04-18,39.75,40.75,39.25,40.00,6080000,9.19 +1988-04-15,39.75,40.00,38.50,39.50,8320000,9.08 +1988-04-14,40.50,41.50,39.00,39.50,6720000,9.08 +1988-04-13,41.75,42.00,41.00,41.25,5120000,9.48 +1988-04-12,41.75,42.25,41.25,41.75,6200000,9.59 +1988-04-11,41.75,42.00,41.00,41.50,5320000,9.54 +1988-04-08,40.75,41.75,39.75,41.00,7240000,9.42 +1988-04-07,41.75,42.38,40.75,40.75,5840000,9.36 +1988-04-06,39.50,41.75,39.00,41.75,6800000,9.59 +1988-04-05,39.25,39.50,38.50,39.25,5280000,9.02 +1988-04-04,39.75,40.50,38.50,38.75,6480000,8.91 +1988-03-31,39.75,40.50,39.25,40.00,7760000,9.19 +1988-03-30,40.75,41.25,38.75,39.50,13280000,9.08 +1988-03-29,41.50,42.00,40.63,41.00,7640000,9.42 +1988-03-28,40.00,41.75,39.50,41.50,6160000,9.54 +1988-03-25,40.75,41.25,40.00,40.13,4680000,9.22 +1988-03-24,41.75,42.50,40.00,40.88,11440000,9.39 +1988-03-23,44.00,44.00,41.88,42.50,7480000,9.77 +1988-03-22,44.00,44.50,43.25,44.00,4265600,10.11 +1988-03-21,44.38,44.63,43.00,43.88,8120000,10.08 +1988-03-18,45.00,45.50,44.25,44.75,9720000,10.28 +1988-03-17,46.25,46.50,44.75,45.00,9320000,10.34 +1988-03-16,44.88,46.38,44.50,46.13,4240000,10.60 +1988-03-15,46.00,46.25,44.75,45.00,6480000,10.34 +1988-03-14,45.75,46.50,45.50,46.25,3518000,10.63 +1988-03-11,45.50,45.75,44.50,45.75,5640000,10.51 +1988-03-10,47.00,47.25,45.25,45.25,6320000,10.40 +1988-03-09,46.25,47.25,46.25,46.75,4800000,10.74 +1988-03-08,46.75,47.00,46.00,46.25,5160000,10.63 +1988-03-07,46.75,47.75,46.50,46.88,7400000,10.77 +1988-03-04,46.00,47.00,45.50,46.88,7480000,10.77 +1988-03-03,44.50,47.00,44.50,46.50,16920000,10.69 +1988-03-02,43.75,45.00,43.50,44.75,10440000,10.28 +1988-03-01,43.25,43.50,42.50,43.25,6120000,9.94 +1988-02-29,41.75,43.25,41.50,43.00,4000000,9.88 +1988-02-26,42.00,42.25,41.25,41.75,2952400,9.59 +1988-02-25,42.00,43.00,41.75,41.75,6400000,9.59 +1988-02-24,42.75,43.00,42.00,42.25,5200000,9.71 +1988-02-23,43.25,43.75,42.25,42.75,7880000,9.82 +1988-02-22,41.50,43.63,41.50,43.25,7160000,9.94 +1988-02-19,41.75,42.00,41.50,41.75,3242400,9.59 +1988-02-18,41.63,42.75,41.50,41.75,5120000,9.59 +1988-02-17,41.25,42.50,41.25,41.88,9160000,9.62 +1988-02-16,41.00,41.25,40.00,41.25,5520000,9.48 +1988-02-12,40.63,41.50,40.50,41.00,4920000,9.42 +1988-02-11,41.00,41.25,40.25,40.63,5280000,9.32 +1988-02-10,39.75,41.50,39.75,41.00,8160000,9.40 +1988-02-09,39.00,39.88,38.75,39.75,4160000,9.12 +1988-02-08,38.50,39.25,37.75,38.75,7280000,8.89 +1988-02-05,40.00,40.38,38.50,38.63,4720000,8.86 +1988-02-04,39.50,40.13,39.00,39.75,7120000,9.12 +1988-02-03,41.00,41.25,39.25,39.50,8080000,9.06 +1988-02-02,41.50,41.88,40.50,41.25,6840000,9.46 +1988-02-01,41.75,42.50,41.38,41.75,7120000,9.58 +1988-01-29,41.50,41.75,40.25,41.50,9480000,9.52 +1988-01-28,40.00,41.50,39.75,41.25,8320000,9.46 +1988-01-27,40.25,40.50,38.75,39.75,9240000,9.12 +1988-01-26,40.75,41.00,39.25,39.75,5120000,9.12 +1988-01-25,39.50,41.50,39.50,40.88,7160000,9.38 +1988-01-22,40.50,40.75,38.25,39.25,15920000,9.00 +1988-01-21,40.50,40.75,39.38,40.13,17640000,9.20 +1988-01-20,43.00,43.00,38.25,39.75,24320000,9.12 +1988-01-19,42.25,43.25,41.38,42.75,9800000,9.80 +1988-01-18,43.00,43.00,42.00,42.75,4480000,9.80 +1988-01-15,43.50,45.00,42.50,42.88,12280000,9.83 +1988-01-14,42.75,42.88,42.00,42.25,4720000,9.69 +1988-01-13,42.00,43.25,41.13,42.25,7560000,9.69 +1988-01-12,43.00,43.50,39.75,42.00,14320000,9.63 +1988-01-11,40.00,42.75,39.75,42.50,14440000,9.75 +1988-01-08,44.50,45.25,39.50,40.00,17360000,9.17 +1988-01-07,43.50,44.75,42.50,44.50,7600000,10.21 +1988-01-06,45.00,45.00,43.75,43.75,9600000,10.03 +1988-01-05,46.00,46.25,44.25,44.63,11040000,10.24 +1988-01-04,42.75,44.75,42.25,44.75,11800000,10.26 +1987-12-31,42.50,43.00,41.88,42.00,4200000,9.63 +1987-12-30,42.50,43.75,42.50,43.38,5560000,9.95 +1987-12-29,40.50,42.25,40.25,42.13,4240000,9.66 +1987-12-28,42.25,42.50,39.50,40.25,8200000,9.23 +1987-12-24,42.00,43.00,41.75,42.63,2508000,9.78 +1987-12-23,41.75,42.75,41.25,42.25,6120000,9.69 +1987-12-22,41.75,41.75,40.50,41.50,4600000,9.52 +1987-12-21,40.50,41.75,40.25,41.75,6720000,9.58 +1987-12-18,39.50,41.25,39.25,40.50,10800000,9.29 +1987-12-17,40.50,40.75,39.25,39.25,11640000,9.00 +1987-12-16,37.75,39.75,37.25,39.25,11800000,9.00 +1987-12-15,37.75,38.25,37.00,37.50,10680000,8.60 +1987-12-14,34.50,37.50,34.25,37.25,12200000,8.54 +1987-12-11,34.75,34.75,33.50,34.00,4360000,7.80 +1987-12-10,33.75,36.00,33.25,34.75,9880000,7.97 +1987-12-09,34.50,36.25,33.88,35.00,6400000,8.03 +1987-12-08,33.50,34.88,33.25,34.50,9080000,7.91 +1987-12-07,31.00,33.25,31.00,33.00,7280000,7.57 +1987-12-04,30.25,31.25,29.75,30.75,8720000,7.05 +1987-12-03,33.00,33.38,29.75,30.50,11400000,7.00 +1987-12-02,33.25,33.50,32.50,32.50,5080000,7.45 +1987-12-01,33.50,34.00,32.75,33.25,6480000,7.63 +1987-11-30,33.75,34.50,30.50,33.00,14880000,7.57 +1987-11-27,36.25,36.50,34.75,35.00,2526800,8.03 +1987-11-25,37.00,37.00,36.00,36.50,3311200,8.37 +1987-11-24,36.75,37.75,36.13,37.00,7040000,8.49 +1987-11-23,35.50,36.25,34.75,36.25,3500000,8.31 +1987-11-20,34.00,36.00,33.25,35.50,8960000,8.14 +1987-11-19,36.50,36.50,34.00,34.50,6520000,7.91 +1987-11-18,35.75,36.50,34.50,36.25,9480000,8.31 +1987-11-17,36.75,37.00,35.00,35.00,9600000,8.03 +1987-11-16,37.75,38.50,36.50,36.75,6600000,8.41 +1987-11-13,39.25,39.50,37.00,37.25,5520000,8.52 +1987-11-12,38.50,40.00,38.38,38.75,8800000,8.87 +1987-11-11,37.25,38.25,36.75,37.25,6640000,8.52 +1987-11-10,36.50,37.50,36.00,36.25,8280000,8.30 +1987-11-09,37.00,37.50,36.25,37.25,7520000,8.52 +1987-11-06,38.25,39.50,37.00,37.75,6680000,8.64 +1987-11-05,36.25,38.75,36.25,38.00,9120000,8.70 +1987-11-04,35.50,37.25,34.75,36.00,8360000,8.24 +1987-11-03,38.00,38.50,34.25,36.25,11200000,8.30 +1987-11-02,38.75,39.50,37.50,38.75,6720000,8.87 +1987-10-30,40.00,43.00,38.50,38.63,15040000,8.84 +1987-10-29,34.25,40.00,32.25,39.50,11840000,9.04 +1987-10-28,30.75,33.75,29.25,33.50,14960000,7.67 +1987-10-27,29.50,32.25,29.00,30.25,16280000,6.92 +1987-10-26,34.50,35.00,27.62,28.00,11200000,6.41 +1987-10-23,35.75,36.50,34.25,35.50,7080000,8.12 +1987-10-22,39.25,40.50,36.00,36.75,13760000,8.41 +1987-10-21,38.50,42.00,38.00,40.50,19080000,9.27 +1987-10-20,38.50,42.00,32.63,34.50,20320000,7.90 +1987-10-19,48.25,48.25,35.50,36.50,17000000,8.35 +1987-10-16,52.25,53.00,47.50,48.25,15000000,11.04 +1987-10-15,53.25,54.50,51.75,52.00,12440000,11.90 +1987-10-14,53.75,54.00,52.00,53.25,9240000,12.19 +1987-10-13,54.50,54.75,53.25,54.50,5800000,12.47 +1987-10-12,54.25,54.38,51.75,53.25,7120000,12.19 +1987-10-09,54.25,55.50,54.00,54.13,5200000,12.39 +1987-10-08,55.50,56.00,53.25,54.25,5880000,12.42 +1987-10-07,55.50,55.75,54.25,55.50,8000000,12.70 +1987-10-06,59.50,59.50,55.50,55.75,7200000,12.76 +1987-10-05,58.50,59.75,57.75,59.25,4800000,13.56 +1987-10-02,58.25,58.75,57.50,58.50,3450000,13.39 +1987-10-01,56.75,58.75,56.50,58.25,4160000,13.33 +1987-09-30,54.25,57.00,54.25,56.50,4360000,12.93 +1987-09-29,56.00,56.00,54.25,54.50,6120000,12.47 +1987-09-28,57.50,58.75,55.50,55.75,7280000,12.76 +1987-09-25,56.75,58.00,56.50,57.50,3806800,13.16 +1987-09-24,55.25,57.88,55.25,56.50,6520000,12.93 +1987-09-23,54.13,56.00,53.75,55.25,9098800,12.64 +1987-09-22,50.50,54.25,50.25,54.13,5480000,12.39 +1987-09-21,51.75,52.75,50.25,50.25,4600000,11.50 +1987-09-18,52.00,52.25,51.38,51.75,2555600,11.84 +1987-09-17,52.00,52.25,51.00,52.00,2400000,11.90 +1987-09-16,51.75,52.63,51.25,51.75,6000000,11.84 +1987-09-15,53.00,53.00,51.50,51.75,3744800,11.84 +1987-09-14,54.75,55.25,52.75,53.00,2928000,12.13 +1987-09-11,54.00,55.50,52.75,54.50,4440000,12.47 +1987-09-10,53.25,54.50,53.13,53.75,5000000,12.30 +1987-09-09,50.25,53.00,49.50,52.75,5640000,12.07 +1987-09-08,50.25,50.50,48.50,49.88,6280000,11.42 +1987-09-04,51.25,51.75,50.00,50.50,3891200,11.56 +1987-09-03,52.50,52.75,50.25,51.25,6600000,11.73 +1987-09-02,52.00,53.25,50.75,52.00,8200000,11.90 +1987-09-01,54.75,55.25,52.50,52.50,4960000,12.01 +1987-08-31,52.25,54.25,51.75,54.00,5360000,12.36 +1987-08-28,52.00,52.50,51.50,52.00,3434400,11.90 +1987-08-27,52.25,52.75,51.50,52.00,4440000,11.90 +1987-08-26,53.00,53.50,52.00,52.00,7000000,11.90 +1987-08-25,52.75,53.25,52.00,52.00,4880000,11.90 +1987-08-24,53.00,53.50,52.25,52.25,4320000,11.96 +1987-08-21,51.75,53.75,51.50,53.00,5000000,12.13 +1987-08-20,50.25,52.50,49.75,51.75,6280000,11.84 +1987-08-19,49.50,50.00,49.00,50.00,2404400,11.44 +1987-08-18,49.25,49.50,48.25,48.75,8480000,11.16 +1987-08-17,49.50,50.00,48.75,49.50,5200000,11.33 +1987-08-14,48.50,50.00,48.00,49.00,3758800,11.21 +1987-08-13,48.75,50.25,48.50,49.00,7000000,11.21 +1987-08-12,49.50,49.75,48.25,48.75,5760000,11.16 +1987-08-11,49.50,50.25,48.75,49.50,9680000,11.33 +1987-08-10,48.25,48.25,45.75,48.25,2800000,11.04 +1987-08-07,46.25,47.25,46.00,46.50,5440000,10.63 +1987-08-06,43.25,46.75,42.75,46.25,9000000,10.57 +1987-08-05,42.25,43.50,42.00,43.25,4640000,9.89 +1987-08-04,40.50,42.25,40.00,42.25,4320000,9.66 +1987-08-03,41.00,41.50,40.25,40.25,2275600,9.20 +1987-07-31,41.25,42.00,41.25,41.25,2613600,9.43 +1987-07-30,41.00,41.50,40.75,41.50,3727600,9.49 +1987-07-29,42.00,42.00,40.50,41.00,3534800,9.37 +1987-07-28,42.50,42.75,41.75,41.88,2660800,9.57 +1987-07-27,42.50,43.00,42.00,42.25,2035600,9.66 +1987-07-24,41.50,42.75,41.50,42.50,4200000,9.71 +1987-07-23,43.00,43.50,40.50,41.75,2685600,9.54 +1987-07-22,41.50,42.75,41.25,42.50,2185200,9.71 +1987-07-21,42.00,42.50,41.25,41.38,3966400,9.46 +1987-07-20,43.00,43.25,41.50,41.75,4440000,9.54 +1987-07-17,44.25,44.75,42.75,43.25,3300000,9.89 +1987-07-16,44.00,44.00,43.25,44.00,3388000,10.06 +1987-07-15,43.00,44.75,42.25,44.00,9680000,10.06 +1987-07-14,41.00,43.00,41.00,43.00,9200000,9.83 +1987-07-13,39.00,40.75,38.75,40.50,9120000,9.26 +1987-07-10,38.00,39.25,37.75,38.00,5600000,8.69 +1987-07-09,37.25,38.75,37.25,37.75,8560000,8.63 +1987-07-08,39.25,39.25,36.50,37.25,12200000,8.51 +1987-07-07,40.50,41.00,38.75,39.25,7280000,8.97 +1987-07-06,40.75,41.75,40.50,40.75,3060800,9.31 +1987-07-02,40.00,41.00,39.75,40.63,2931200,9.29 +1987-07-01,40.75,40.75,39.75,40.00,3402000,9.14 +1987-06-30,40.50,41.00,39.75,40.50,5160000,9.26 +1987-06-29,40.50,40.75,40.00,40.75,3628000,9.31 +1987-06-26,40.75,41.50,40.00,40.50,4560000,9.26 +1987-06-25,42.00,42.50,40.50,40.50,4320000,9.26 +1987-06-24,41.50,43.25,40.50,42.00,4240000,9.60 +1987-06-23,42.00,42.13,40.75,41.25,2892000,9.43 +1987-06-22,41.25,42.25,40.88,42.00,6040000,9.60 +1987-06-19,41.50,41.75,40.38,41.00,4480000,9.37 +1987-06-18,40.25,41.75,39.50,41.50,8200000,9.49 +1987-06-17,41.50,42.50,40.00,40.50,10640000,9.26 +1987-06-16,41.50,41.75,38.00,41.50,12240000,9.49 +1987-06-15,79.00,79.50,77.50,78.50,9280000,8.97 +1987-06-12,79.00,79.75,78.75,79.00,3653600,9.03 +1987-06-11,78.50,80.00,78.00,79.00,4521600,9.03 +1987-06-10,78.75,80.25,78.00,78.50,5235200,8.97 +1987-06-09,77.50,79.50,77.50,78.50,4570400,8.97 +1987-06-08,77.75,78.00,76.75,77.75,7213600,8.89 +1987-06-05,78.75,78.75,77.75,77.75,4696000,8.89 +1987-06-04,78.00,78.75,77.00,78.50,5511200,8.97 +1987-06-03,77.25,79.50,77.25,77.75,6140000,8.89 +1987-06-02,77.50,78.00,77.00,77.25,4927200,8.83 +1987-06-01,79.50,79.50,77.50,77.75,2984000,8.89 +1987-05-29,80.25,80.50,79.00,79.00,3322400,9.03 +1987-05-28,79.50,80.25,78.50,80.00,5424000,9.14 +1987-05-27,78.00,80.25,77.50,79.50,6484000,9.09 +1987-05-26,74.50,78.00,74.00,78.00,5481600,8.91 +1987-05-22,75.00,75.50,73.75,74.12,3484000,8.47 +1987-05-21,74.75,75.75,74.50,74.50,6233600,8.51 +1987-05-20,73.00,75.00,72.50,74.50,10320000,8.51 +1987-05-19,75.75,75.75,72.62,73.25,8560000,8.37 +1987-05-18,78.25,78.50,75.50,75.75,8640000,8.66 +1987-05-15,79.25,79.25,78.00,78.25,5220000,8.94 +1987-05-14,78.25,79.50,78.25,79.25,5316000,9.06 +1987-05-13,75.75,78.62,75.50,78.50,11120000,8.97 +1987-05-12,76.00,76.50,75.00,75.50,9280000,8.63 +1987-05-11,77.00,79.50,76.75,77.00,7048800,8.80 +1987-05-08,80.50,81.00,79.00,79.00,6618400,9.01 +1987-05-07,79.75,81.00,79.75,80.25,6488800,9.16 +1987-05-06,80.50,82.25,79.25,80.00,10240000,9.13 +1987-05-05,80.00,80.75,78.00,80.25,8240000,9.16 +1987-05-04,79.50,80.25,79.00,79.75,5095200,9.10 +1987-05-01,79.50,80.00,78.75,80.00,4751200,9.13 +1987-04-30,78.00,80.00,77.75,79.25,9040000,9.04 +1987-04-29,77.25,79.75,77.00,77.75,10400000,8.87 +1987-04-28,75.75,77.87,75.50,77.00,11600000,8.79 +1987-04-27,74.25,75.25,73.25,75.00,13680000,8.56 +1987-04-24,75.75,76.50,74.50,74.75,9120000,8.53 +1987-04-23,74.25,77.25,74.25,76.00,10880000,8.67 +1987-04-22,76.62,77.00,74.00,74.25,14400000,8.47 +1987-04-21,70.25,75.00,69.50,74.75,15440000,8.53 +1987-04-20,71.50,72.75,70.75,71.12,5353600,8.12 +1987-04-16,71.25,73.25,71.00,71.50,12400000,8.16 +1987-04-15,69.50,71.00,68.75,71.00,12480000,8.10 +1987-04-14,66.75,69.75,66.50,68.00,14560000,7.76 +1987-04-13,70.00,70.25,67.50,67.50,5101600,7.70 +1987-04-10,71.25,71.50,69.75,70.25,7791200,8.02 +1987-04-09,68.75,71.50,67.75,71.00,8480000,8.10 +1987-04-08,67.75,70.25,67.50,69.00,8240000,7.87 +1987-04-07,69.75,70.25,67.75,67.75,9280000,7.73 +1987-04-06,71.50,72.75,69.25,70.00,10320000,7.99 +1987-04-03,71.50,71.87,70.25,71.75,19280000,8.19 +1987-04-02,68.25,71.75,67.00,71.75,27760000,8.19 +1987-04-01,63.00,67.00,62.38,66.75,7792800,7.62 +1987-03-31,62.25,64.75,62.25,64.50,9760000,7.36 +1987-03-30,63.50,64.25,62.25,62.50,9280000,7.13 +1987-03-27,67.25,67.50,64.75,65.00,4817600,7.42 +1987-03-26,66.75,67.75,66.50,67.25,5146400,7.67 +1987-03-25,66.50,67.00,65.25,66.75,9760000,7.62 +1987-03-24,67.75,68.50,66.25,66.25,9600000,7.56 +1987-03-23,68.00,68.25,66.25,67.50,8800000,7.70 +1987-03-20,68.25,69.75,68.25,68.25,12400000,7.79 +1987-03-19,65.75,68.50,65.50,68.37,7396000,7.80 +1987-03-18,67.25,67.50,64.75,66.00,10800000,7.53 +1987-03-17,65.50,68.00,65.00,67.00,8720000,7.65 +1987-03-16,63.50,65.25,62.50,65.25,8800000,7.45 +1987-03-13,65.25,66.00,63.50,63.50,7067200,7.25 +1987-03-12,66.00,66.25,63.63,65.25,10800000,7.45 +1987-03-11,67.25,68.00,66.25,66.25,7826400,7.56 +1987-03-10,64.50,66.87,64.50,66.75,8720000,7.62 +1987-03-09,66.50,66.75,64.50,64.62,9120000,7.37 +1987-03-06,67.25,68.37,66.75,67.25,6332800,7.67 +1987-03-05,67.50,69.00,67.25,68.50,12080000,7.82 +1987-03-04,65.75,68.25,65.37,67.62,16000000,7.72 +1987-03-03,67.50,68.12,64.75,65.00,15600000,7.42 +1987-03-02,70.25,70.50,67.00,67.50,14160000,7.70 +1987-02-27,69.12,71.00,67.75,70.00,14480000,7.99 +1987-02-26,69.50,71.37,68.00,69.12,17840000,7.89 +1987-02-25,65.50,69.50,64.62,69.12,16240000,7.89 +1987-02-24,63.25,66.00,63.13,65.50,12720000,7.47 +1987-02-23,60.88,64.25,59.63,63.13,12560000,7.20 +1987-02-20,62.38,62.50,60.63,61.25,6813600,6.99 +1987-02-19,63.50,63.50,61.75,62.38,11200000,7.12 +1987-02-18,66.62,67.37,63.38,63.50,16800000,7.25 +1987-02-17,62.13,66.50,61.88,66.37,14640000,7.57 +1987-02-13,58.63,62.50,58.00,62.13,18240000,7.09 +1987-02-12,57.00,59.88,57.00,58.63,25360000,6.69 +1987-02-11,53.00,56.75,52.75,56.50,12240000,6.45 +1987-02-10,52.50,52.75,51.63,52.75,5977600,6.02 +1987-02-09,52.88,53.38,52.25,52.63,5611200,6.01 +1987-02-06,54.00,54.00,52.88,54.00,10480000,6.16 +1987-02-05,55.00,55.13,53.13,53.88,12160000,6.15 +1987-02-04,55.50,55.50,54.38,55.00,7791200,6.28 +1987-02-03,56.00,56.13,54.75,55.50,6412800,6.33 +1987-02-02,55.50,56.00,54.25,55.88,8800000,6.38 +1987-01-30,54.00,55.88,52.63,55.50,14640000,6.33 +1987-01-29,55.88,57.25,53.38,54.13,19920000,6.18 +1987-01-28,53.00,55.75,52.13,55.38,14800000,6.32 +1987-01-27,50.00,53.13,49.88,52.75,13520000,6.02 +1987-01-26,50.00,50.50,49.50,49.75,12560000,5.68 +1987-01-23,52.50,53.00,50.25,50.25,16400000,5.73 +1987-01-22,48.88,52.63,48.50,52.50,16880000,5.99 +1987-01-21,50.88,51.13,49.00,49.00,19040000,5.59 +1987-01-20,55.00,55.75,51.50,51.63,27680000,5.89 +1987-01-19,48.75,53.13,47.88,53.13,12960000,6.06 +1987-01-16,50.00,50.00,47.75,48.75,14560000,5.56 +1987-01-15,48.25,51.38,48.00,49.88,19520000,5.69 +1987-01-14,44.63,48.25,44.50,48.13,18000000,5.49 +1987-01-13,45.13,45.38,44.63,44.63,7584800,5.09 +1987-01-12,45.50,45.75,44.75,45.50,8320000,5.19 +1987-01-09,44.75,45.75,44.38,45.38,8560000,5.18 +1987-01-08,44.75,45.13,44.50,44.75,10400000,5.11 +1987-01-07,43.88,44.88,43.63,44.75,15520000,5.11 +1987-01-06,43.13,44.00,42.63,43.75,11600000,4.99 +1987-01-05,41.25,43.25,41.00,43.00,8560000,4.91 +1987-01-02,40.38,41.13,40.13,40.88,4360000,4.66 +1986-12-31,41.00,41.38,40.38,40.50,4742400,4.62 +1986-12-30,40.50,41.50,40.38,41.00,5297600,4.68 +1986-12-29,41.00,41.13,40.25,40.50,4224800,4.62 +1986-12-26,41.88,41.88,41.00,41.00,3215200,4.68 +1986-12-24,42.00,42.13,41.63,41.88,3453600,4.78 +1986-12-23,42.25,42.38,41.88,42.13,8720000,4.81 +1986-12-22,42.00,42.50,41.75,42.13,5887200,4.81 +1986-12-19,41.38,42.50,41.38,42.13,7149600,4.81 +1986-12-18,41.13,41.88,40.75,41.38,6258400,4.72 +1986-12-17,42.38,42.50,40.88,41.25,5417600,4.71 +1986-12-16,41.63,42.50,41.63,42.50,5464000,4.85 +1986-12-15,41.00,41.75,40.38,41.75,7481600,4.76 +1986-12-12,42.88,43.00,41.25,41.25,6451200,4.71 +1986-12-11,43.63,43.88,42.63,42.88,8080000,4.89 +1986-12-10,42.38,43.75,42.00,43.50,8720000,4.96 +1986-12-09,42.38,42.63,41.13,42.38,10800000,4.84 +1986-12-08,43.63,43.88,42.38,42.50,12400000,4.85 +1986-12-05,42.63,43.75,42.50,43.75,9360000,4.99 +1986-12-04,42.63,42.75,42.00,42.50,9600000,4.85 +1986-12-03,41.63,43.00,41.50,42.75,12000000,4.88 +1986-12-02,40.50,41.75,40.00,41.50,13200000,4.74 +1986-12-01,40.00,40.13,39.13,40.13,12400000,4.58 +1986-11-28,40.50,40.63,39.63,40.00,7897600,4.56 +1986-11-26,40.13,41.25,40.00,40.50,18080000,4.62 +1986-11-25,38.00,40.38,38.00,40.25,30320000,4.59 +1986-11-24,36.25,38.13,36.00,38.00,13440000,4.34 +1986-11-21,35.25,36.25,35.13,36.00,10240000,4.11 +1986-11-20,34.88,35.38,34.88,35.25,10560000,4.02 +1986-11-19,35.13,35.25,34.50,35.00,10800000,3.99 +1986-11-18,36.38,36.75,35.13,35.38,6115200,4.04 +1986-11-17,35.25,37.00,35.00,36.38,5071200,4.15 +1986-11-14,35.50,35.50,34.88,35.25,4840000,4.02 +1986-11-13,36.50,36.50,35.50,35.50,4928800,4.05 +1986-11-12,35.75,36.63,35.63,36.63,4700000,4.18 +1986-11-11,35.50,35.75,35.25,35.50,1809600,4.05 +1986-11-10,35.88,35.88,35.13,35.38,3793600,4.04 +1986-11-07,36.00,36.13,34.88,35.75,5153600,4.08 +1986-11-06,36.63,36.88,35.75,36.13,11840000,4.12 +1986-11-05,35.75,37.13,35.50,37.00,22320000,4.22 +1986-11-04,34.88,35.88,33.88,35.75,8800000,4.08 +1986-11-03,34.75,35.13,34.63,35.00,5457600,3.99 +1986-10-31,34.25,34.88,34.25,34.63,4338400,3.95 +1986-10-30,33.50,34.75,33.38,34.25,10480000,3.91 +1986-10-29,33.50,33.50,33.13,33.38,3057600,3.81 +1986-10-28,34.00,34.13,33.00,33.38,5102400,3.81 +1986-10-27,33.50,34.00,33.25,34.00,5422400,3.88 +1986-10-24,33.13,33.25,32.75,33.00,2718400,3.77 +1986-10-23,32.50,33.13,32.50,33.13,4441600,3.78 +1986-10-22,32.75,32.88,32.25,32.50,3382400,3.71 +1986-10-21,33.00,33.00,32.63,32.75,4096000,3.74 +1986-10-20,33.50,33.63,32.88,32.88,5344000,3.75 +1986-10-17,33.75,34.00,33.38,33.63,5460000,3.84 +1986-10-16,33.38,33.88,33.25,33.63,4876000,3.84 +1986-10-15,33.50,33.50,32.75,33.38,7367200,3.81 +1986-10-14,34.63,35.25,33.75,34.00,7164000,3.88 +1986-10-13,33.13,34.63,33.00,34.63,3582400,3.95 +1986-10-10,32.88,33.38,32.38,33.25,2096000,3.79 +1986-10-09,32.75,33.25,32.63,33.00,2820000,3.77 +1986-10-08,32.88,33.00,32.25,32.75,4021600,3.74 +1986-10-07,34.00,34.13,32.88,33.00,4577600,3.77 +1986-10-06,33.75,34.25,33.63,34.13,3384000,3.89 +1986-10-03,34.38,34.75,33.38,33.75,4997600,3.85 +1986-10-02,33.75,34.38,33.50,34.13,3401600,3.89 +1986-10-01,33.38,34.50,33.38,34.13,4988800,3.89 +1986-09-30,32.88,33.88,32.63,33.50,6488800,3.82 +1986-09-29,33.63,33.88,31.62,32.50,7475200,3.71 +1986-09-26,34.13,34.38,33.88,34.25,2512800,3.91 +1986-09-25,35.13,35.25,33.63,34.50,6744800,3.94 +1986-09-24,36.13,36.38,34.00,35.13,6360000,4.01 +1986-09-23,35.25,36.25,35.13,36.13,12080000,4.12 +1986-09-22,33.50,35.38,33.50,35.25,8560000,4.02 +1986-09-19,33.75,33.88,33.25,33.63,4601600,3.84 +1986-09-18,34.25,34.50,33.75,34.00,3546400,3.88 +1986-09-17,34.88,35.00,34.25,34.25,4181600,3.91 +1986-09-16,33.13,35.13,32.50,34.88,8800000,3.98 +1986-09-15,32.25,33.13,32.00,33.13,7973600,3.78 +1986-09-12,32.50,32.75,31.75,31.75,8160000,3.62 +1986-09-11,34.63,34.75,32.50,32.63,4842400,3.72 +1986-09-10,35.63,35.88,34.75,35.00,2737600,3.99 +1986-09-09,34.63,36.00,34.63,35.75,5398400,4.08 +1986-09-08,35.00,35.00,33.63,34.75,4522400,3.97 +1986-09-05,35.63,35.88,35.00,35.13,3561600,4.01 +1986-09-04,35.00,35.50,34.75,35.50,7133600,4.05 +1986-09-03,34.75,34.88,34.13,34.75,4216000,3.97 +1986-09-02,37.13,37.13,34.75,34.75,8320000,3.97 +1986-08-29,37.63,38.00,36.88,37.00,4846400,4.22 +1986-08-28,37.00,38.00,36.88,37.75,7849600,4.31 +1986-08-27,36.63,37.00,36.25,37.00,5280000,4.22 +1986-08-26,36.38,36.88,36.38,36.63,4713600,4.18 +1986-08-25,36.50,36.88,36.38,36.38,4533600,4.15 +1986-08-22,35.88,36.63,35.88,36.25,4162400,4.14 +1986-08-21,36.13,36.38,35.75,35.75,6992800,4.08 +1986-08-20,35.25,36.50,35.25,36.25,6140000,4.14 +1986-08-19,35.13,35.50,34.63,35.38,4944000,4.04 +1986-08-18,35.75,35.88,35.00,35.38,5297600,4.04 +1986-08-15,36.13,36.50,35.63,35.75,4910400,4.08 +1986-08-14,36.00,37.00,36.00,36.00,8240000,4.11 +1986-08-13,34.25,36.25,34.25,36.00,16240000,4.11 +1986-08-12,33.38,34.38,33.38,34.25,8720000,3.91 +1986-08-11,31.87,33.50,31.75,33.50,6591200,3.82 +1986-08-08,31.87,32.38,31.62,31.62,3941600,3.61 +1986-08-07,31.12,32.63,31.12,31.75,6211200,3.62 +1986-08-06,32.13,32.13,31.00,31.12,6644800,3.55 +1986-08-05,31.62,32.38,31.50,32.13,4238400,3.67 +1986-08-04,31.37,31.50,30.62,31.50,4653600,3.59 +1986-08-01,31.12,31.75,31.12,31.37,5360000,3.58 +1986-07-31,30.50,31.50,30.50,31.25,10080000,3.57 +1986-07-30,31.25,31.50,30.00,30.50,9120000,3.48 +1986-07-29,32.25,32.25,30.75,31.25,21280000,3.57 +1986-07-28,33.88,34.00,32.25,32.38,8800000,3.69 +1986-07-25,33.13,34.00,33.00,34.00,7769600,3.88 +1986-07-24,34.25,34.38,33.00,33.13,5187200,3.78 +1986-07-23,34.63,34.63,34.13,34.13,6416000,3.89 +1986-07-22,33.50,34.63,33.25,34.63,8560000,3.95 +1986-07-21,33.00,33.75,32.75,33.50,8160000,3.82 +1986-07-18,32.25,32.50,31.25,31.75,11040000,3.62 +1986-07-17,33.50,33.75,32.13,32.25,8960000,3.68 +1986-07-16,35.50,35.63,32.75,33.50,19280000,3.82 +1986-07-15,35.00,35.00,34.25,34.88,10640000,3.98 +1986-07-14,37.13,37.38,36.25,36.25,8480000,4.14 +1986-07-11,35.38,37.75,35.25,37.13,8000000,4.24 +1986-07-10,34.75,35.38,34.63,35.38,7453600,4.04 +1986-07-09,34.25,34.75,34.00,34.63,13040000,3.95 +1986-07-08,35.25,35.25,34.13,34.25,9782400,3.91 +1986-07-07,37.63,37.75,35.38,35.63,6501600,4.07 +1986-07-03,36.13,37.75,35.63,37.63,6509600,4.29 +1986-07-02,35.38,36.25,35.38,36.13,5202400,4.12 +1986-07-01,35.88,36.13,34.75,35.38,3140000,4.04 +1986-06-30,35.88,36.25,35.75,35.88,2553600,4.09 +1986-06-27,36.25,36.75,35.50,35.88,1811200,4.09 +1986-06-26,35.88,36.38,35.50,36.25,4184800,4.14 +1986-06-25,35.00,36.00,35.00,35.88,4755200,4.09 +1986-06-24,34.75,35.13,34.38,34.88,5088800,3.98 +1986-06-23,36.00,36.25,34.63,34.75,4196000,3.97 +1986-06-20,35.00,36.13,35.00,36.00,5761600,4.11 +1986-06-19,34.25,35.75,33.88,35.00,12347200,3.99 +1986-06-18,34.25,34.75,32.50,34.25,15381600,3.91 +1986-06-17,35.88,36.00,34.00,34.25,7936000,3.91 +1986-06-16,36.38,36.88,35.63,35.88,6222400,4.09 +1986-06-13,36.00,36.38,35.25,36.38,5144800,4.15 +1986-06-12,36.13,36.38,36.00,36.00,4638400,4.11 +1986-06-11,36.00,36.25,35.50,36.13,6692800,4.12 +1986-06-10,36.00,36.00,35.13,36.00,8827200,4.11 +1986-06-09,37.75,37.88,35.88,36.00,8835200,4.11 +1986-06-06,38.88,38.88,37.50,37.75,6342400,4.31 +1986-06-05,38.75,39.13,38.50,38.88,5282400,4.44 +1986-06-04,37.88,38.88,37.75,38.75,10747200,4.42 +1986-06-03,37.13,38.13,37.13,37.88,11661600,4.32 +1986-06-02,37.00,37.38,36.75,37.13,7158400,4.24 +1986-05-30,37.00,37.25,36.50,37.00,4591200,4.22 +1986-05-29,37.25,37.25,36.50,37.00,3635200,4.22 +1986-05-28,36.88,37.50,36.75,37.25,7418400,4.25 +1986-05-27,37.00,37.00,36.38,36.88,3058400,4.21 +1986-05-23,36.75,37.13,36.38,37.00,5013600,4.22 +1986-05-22,37.00,37.50,35.75,36.75,7895200,4.19 +1986-05-21,35.38,37.25,35.00,37.00,12418400,4.22 +1986-05-20,35.63,35.63,34.25,35.38,8811200,4.04 +1986-05-19,36.00,36.50,35.50,35.63,7506400,4.07 +1986-05-16,36.00,36.25,35.13,36.00,11424800,4.11 +1986-05-15,36.88,37.00,35.63,36.00,7964000,4.11 +1986-05-14,36.00,37.38,36.00,36.88,17277600,4.21 +1986-05-13,36.38,36.50,35.25,36.00,16876000,4.11 +1986-05-12,33.38,36.63,33.25,36.38,14335200,4.15 +1986-05-09,33.00,33.63,32.75,33.38,7961600,3.81 +1986-05-08,31.50,33.13,31.50,33.00,8342400,3.77 +1986-05-07,32.63,32.88,31.25,31.50,7133600,3.59 +1986-05-06,32.25,33.25,32.25,32.63,7829600,3.72 +1986-05-05,30.50,32.50,30.50,32.13,5364000,3.67 +1986-05-02,30.25,31.00,30.12,30.50,3377600,3.48 +1986-05-01,30.25,30.25,29.75,30.25,9218400,3.45 +1986-04-30,31.25,31.62,30.25,30.25,4944000,3.45 +1986-04-29,32.00,32.25,26.87,31.25,4750400,3.57 +1986-04-28,32.25,32.75,31.75,32.00,5241600,3.65 +1986-04-25,31.37,32.63,31.37,32.25,9348800,3.68 +1986-04-24,29.62,31.50,29.50,31.37,16398400,3.58 +1986-04-23,29.87,30.37,29.37,29.62,9371200,3.38 +1986-04-22,30.37,31.25,29.62,29.87,11726400,3.41 +1986-04-21,29.87,30.75,29.87,30.37,9775200,3.47 +1986-04-18,29.00,29.87,28.75,29.75,8871200,3.39 +1986-04-17,28.25,29.12,28.00,29.00,9672800,3.31 +1986-04-16,27.37,28.50,27.37,28.25,7535200,3.22 +1986-04-15,26.87,27.50,26.87,27.37,4722400,3.12 +1986-04-14,27.00,27.25,26.75,26.87,3076000,3.07 +1986-04-11,27.25,27.50,27.00,27.00,2737600,3.08 +1986-04-10,27.12,27.37,26.87,27.25,3932800,3.11 +1986-04-09,27.62,27.75,26.87,27.12,4851200,3.09 +1986-04-08,27.25,27.75,27.25,27.62,6912800,3.15 +1986-04-07,26.75,27.50,26.25,27.25,4318400,3.11 +1986-04-04,27.00,27.00,26.62,26.75,4508800,3.05 +1986-04-03,27.25,27.62,26.87,27.00,7548800,3.08 +1986-04-02,27.25,27.37,26.25,27.25,11627200,3.11 +1986-04-01,28.25,28.25,27.00,27.25,7973600,3.11 +1986-03-31,28.25,28.50,28.00,28.25,6744800,3.22 +1986-03-27,28.25,29.00,28.25,28.25,7856000,3.22 +1986-03-26,27.87,28.75,27.87,28.25,7941600,3.22 +1986-03-25,26.75,27.87,26.75,27.87,10060000,3.18 +1986-03-24,27.62,27.62,26.37,26.75,10528800,3.05 +1986-03-21,28.25,28.75,27.50,27.62,9309600,3.15 +1986-03-20,28.00,29.62,28.00,28.25,32318400,3.22 +1986-03-19,26.87,27.25,26.37,26.50,6816000,3.02 +1986-03-18,26.00,27.25,25.87,26.87,8920000,3.07 +1986-03-17,26.00,26.00,25.37,26.00,4240000,2.97 +1986-03-14,24.75,26.25,24.75,26.12,13781600,2.98 +1986-03-13,24.75,25.00,24.37,24.75,4176000,2.82 +1986-03-12,24.87,25.12,24.75,24.75,3071200,2.82 +1986-03-11,24.62,24.87,24.50,24.87,3681600,2.84 +1986-03-10,24.75,24.87,24.62,24.62,2727200,2.81 +1986-03-07,25.37,25.37,24.75,24.75,3477600,2.82 +1986-03-06,25.25,25.75,25.12,25.37,3630400,2.89 +1986-03-05,24.62,25.50,24.25,25.25,6324000,2.88 +1986-03-04,24.62,25.00,24.50,24.62,3217600,2.81 +1986-03-03,25.00,25.12,24.50,24.62,3912800,2.81 +1986-02-28,25.62,25.87,24.87,25.00,4507200,2.85 +1986-02-27,26.00,26.12,25.50,25.62,3873600,2.92 +1986-02-26,26.37,26.75,26.00,26.00,5907200,2.97 +1986-02-25,25.75,26.37,25.12,26.37,8041600,3.01 +1986-02-24,25.25,25.75,25.00,25.75,8840000,2.94 +1986-02-21,25.12,25.75,25.12,25.25,6771200,2.88 +1986-02-20,25.00,25.37,24.87,25.12,4951200,2.87 +1986-02-19,23.87,25.50,23.87,25.00,12871200,2.85 +1986-02-18,23.75,24.00,23.25,23.87,5295200,2.72 +1986-02-14,23.87,24.12,23.75,23.75,4928800,2.71 +1986-02-13,24.00,24.00,23.75,23.87,3944000,2.72 +1986-02-12,23.87,24.00,23.75,24.00,4770400,2.74 +1986-02-11,23.87,24.00,23.50,23.87,5504000,2.72 +1986-02-10,24.00,24.50,23.75,23.87,4036000,2.72 +1986-02-07,24.12,24.12,23.50,24.00,4656000,2.74 +1986-02-06,23.75,24.25,23.62,24.12,4835200,2.75 +1986-02-05,23.75,23.87,23.50,23.75,7042400,2.71 +1986-02-04,23.87,24.37,23.75,23.75,9298400,2.71 +1986-02-03,23.12,24.00,22.87,23.87,12512800,2.72 +1986-01-31,23.00,23.25,22.87,23.12,5317600,2.64 +1986-01-30,23.50,23.50,22.87,23.00,8493600,2.62 +1986-01-29,22.25,24.37,22.00,23.62,21064800,2.70 +1986-01-28,22.12,22.37,22.00,22.25,7949600,2.54 +1986-01-27,22.62,22.75,22.00,22.12,13955200,2.52 +1986-01-24,23.00,23.37,22.62,22.62,4044000,2.58 +1986-01-23,23.37,23.50,22.75,23.00,5624000,2.62 +1986-01-22,24.00,24.12,22.37,23.37,5144800,2.67 +1986-01-21,23.87,24.12,23.75,24.00,5464800,2.74 +1986-01-20,24.00,24.00,23.37,23.87,4590400,2.72 +1986-01-17,24.50,24.75,23.87,24.00,12344000,2.74 +1986-01-16,23.87,24.75,23.87,24.50,19132800,2.80 +1986-01-15,23.25,24.00,23.12,23.87,15126400,2.72 +1986-01-14,23.00,23.75,22.50,23.25,9772800,2.65 +1986-01-13,22.75,23.12,22.50,23.00,7701600,2.62 +1986-01-10,22.62,23.12,22.62,22.75,5491200,2.60 +1986-01-09,22.87,23.00,21.87,22.62,16002400,2.58 +1986-01-08,23.00,23.50,22.75,22.87,21711200,2.61 +1986-01-07,22.25,23.00,22.12,23.00,16807200,2.62 +1986-01-06,22.37,22.37,21.87,22.25,6636000,2.54 +1986-01-03,22.25,22.37,22.12,22.37,8653600,2.55 +1986-01-02,22.00,22.25,21.75,22.25,4212800,2.54 +1985-12-31,22.25,22.37,22.00,22.00,3158400,2.51 +1985-12-30,22.37,22.62,22.12,22.25,3848800,2.54 +1985-12-27,21.75,22.62,21.75,22.37,4427200,2.55 +1985-12-26,21.75,22.00,21.62,21.75,1658400,2.48 +1985-12-24,21.87,22.00,21.62,21.75,2344800,2.48 +1985-12-23,22.37,22.50,21.62,21.87,5157600,2.50 +1985-12-20,22.50,22.75,22.25,22.37,7402400,2.55 +1985-12-19,22.25,22.75,22.12,22.50,9673600,2.57 +1985-12-18,21.37,22.87,21.37,22.25,20033600,2.54 +1985-12-17,20.87,21.00,20.37,20.62,3926400,2.35 +1985-12-16,20.00,21.25,20.00,20.87,10362400,2.38 +1985-12-13,20.00,20.25,19.75,20.00,8975200,2.28 +1985-12-12,19.87,20.25,19.87,20.00,4515200,2.28 +1985-12-11,19.50,20.12,19.50,19.75,8489600,2.25 +1985-12-10,19.37,19.62,19.25,19.50,7206400,2.23 +1985-12-09,19.75,20.00,19.25,19.37,5015200,2.21 +1985-12-06,20.12,20.12,19.62,19.75,2347200,2.25 +1985-12-05,20.50,20.75,20.00,20.12,4508800,2.30 +1985-12-04,20.12,20.62,20.12,20.50,5928800,2.34 +1985-12-03,20.25,20.37,20.00,20.12,5548800,2.30 +1985-12-02,20.12,20.25,20.00,20.25,3611200,2.31 +1985-11-29,20.00,20.12,19.87,20.12,3546400,2.30 +1985-11-27,19.37,20.12,19.25,20.00,6873600,2.28 +1985-11-26,19.12,19.50,19.00,19.37,5892800,2.21 +1985-11-25,19.00,19.25,19.00,19.12,3488800,2.18 +1985-11-22,19.00,19.25,18.87,19.00,4620000,2.17 +1985-11-21,19.00,19.25,19.00,19.00,3720000,2.17 +1985-11-20,19.25,19.37,19.00,19.00,3548800,2.17 +1985-11-19,19.87,20.00,19.25,19.25,3373600,2.20 +1985-11-18,19.87,20.00,19.87,19.87,2342400,2.27 +1985-11-15,20.00,20.25,19.87,19.87,2932800,2.27 +1985-11-14,20.00,20.12,20.00,20.00,4995200,2.28 +1985-11-13,19.87,19.87,19.37,19.37,3642400,2.21 +1985-11-12,20.00,20.25,19.87,19.87,6224800,2.27 +1985-11-11,20.50,20.75,20.00,20.00,6421600,2.28 +1985-11-08,20.50,20.75,20.50,20.50,10517600,2.34 +1985-11-07,19.62,19.87,19.62,19.62,11352800,2.24 +1985-11-06,19.25,19.37,19.25,19.25,7181600,2.20 +1985-11-05,18.75,19.12,18.62,18.62,3841600,2.12 +1985-11-04,18.75,19.12,18.75,18.75,5584800,2.14 +1985-11-01,18.62,19.00,18.62,18.62,3320000,2.12 +1985-10-31,19.00,19.25,18.62,18.62,5548800,2.12 +1985-10-30,19.00,19.00,19.00,19.00,8098400,2.17 +1985-10-29,18.00,18.00,17.87,17.87,4693600,2.04 +1985-10-28,18.00,18.12,18.00,18.00,2148800,2.05 +1985-10-25,18.37,18.37,18.00,18.00,2271200,2.05 +1985-10-24,18.37,18.87,18.37,18.37,9768800,2.10 +1985-10-23,18.00,18.50,18.00,18.00,5309600,2.05 +1985-10-22,18.00,18.25,18.00,18.00,15186400,2.05 +1985-10-21,17.75,17.75,17.25,17.25,4248800,1.97 +1985-10-18,18.25,18.37,17.75,17.75,8268800,2.03 +1985-10-17,18.25,19.12,18.25,18.25,12455200,2.08 +1985-10-16,18.00,18.12,18.00,18.00,10336000,2.05 +1985-10-15,17.00,17.12,17.00,17.00,10504800,1.94 +1985-10-14,16.62,16.62,16.62,16.62,5555200,1.90 +1985-10-11,16.00,16.25,16.00,16.00,4261600,1.83 +1985-10-10,15.88,16.00,15.88,15.88,9386400,1.81 +1985-10-09,15.13,15.25,15.00,15.00,3001600,1.71 +1985-10-08,15.13,15.13,15.13,15.13,3144000,1.73 +1985-10-07,15.00,15.25,15.00,15.00,3284800,1.71 +1985-10-04,15.50,15.50,15.00,15.00,2484800,1.71 +1985-10-03,15.63,15.63,15.50,15.50,1784800,1.77 +1985-10-02,15.75,15.88,15.63,15.63,795200,1.78 +1985-10-01,15.75,15.88,15.75,15.75,3175200,1.80 +1985-09-30,15.88,16.00,15.75,15.75,1324800,1.80 +1985-09-27,15.88,16.00,15.88,15.88,250400,1.81 +1985-09-26,15.88,16.00,15.88,15.88,1949600,1.81 +1985-09-25,16.50,16.50,15.88,15.88,3761600,1.81 +1985-09-24,16.87,17.25,16.50,16.50,3161600,1.88 +1985-09-23,16.87,17.12,16.87,16.87,4277600,1.92 +1985-09-20,17.00,17.12,16.75,16.75,4846400,1.91 +1985-09-19,17.00,17.00,17.00,17.00,6662400,1.94 +1985-09-18,16.25,16.25,16.25,16.25,4316000,1.85 +1985-09-17,15.25,15.25,15.25,15.25,6564000,1.74 +1985-09-16,15.75,15.75,15.25,15.25,1344000,1.74 +1985-09-13,16.12,16.12,15.75,15.75,2541600,1.80 +1985-09-12,16.12,16.12,16.12,16.12,3998400,1.84 +1985-09-11,15.50,15.63,15.50,15.50,3150400,1.77 +1985-09-10,15.38,15.63,15.38,15.38,4364800,1.75 +1985-09-09,15.25,15.38,15.25,15.25,4728800,1.74 +1985-09-06,15.00,15.00,15.00,15.00,3333600,1.71 +1985-09-05,14.88,15.00,14.88,14.88,1201600,1.70 +1985-09-04,14.88,15.13,14.88,14.88,1708800,1.70 +1985-09-03,15.00,15.00,14.75,14.75,1369600,1.68 +1985-08-30,15.00,15.00,15.00,15.00,1537600,1.71 +1985-08-29,15.25,15.25,14.88,14.88,2006400,1.70 +1985-08-28,15.25,15.38,15.25,15.25,1475200,1.74 +1985-08-27,15.25,15.25,15.25,15.25,1540000,1.74 +1985-08-26,15.13,15.13,15.13,15.13,1315200,1.73 +1985-08-23,14.88,15.00,14.75,14.75,1601600,1.68 +1985-08-22,15.25,15.25,14.88,14.88,4406400,1.70 +1985-08-21,15.25,15.25,15.25,15.25,2767200,1.74 +1985-08-20,15.25,15.25,15.25,15.25,2431200,1.74 +1985-08-19,15.00,15.25,15.00,15.00,1726400,1.71 +1985-08-16,14.63,14.88,14.63,14.63,3008800,1.67 +1985-08-15,14.63,14.75,14.50,14.50,3800000,1.65 +1985-08-14,15.25,15.25,14.63,14.63,10372800,1.67 +1985-08-13,15.25,15.50,15.25,15.25,1555200,1.74 +1985-08-12,15.25,15.25,15.00,15.00,1988800,1.71 +1985-08-09,15.25,15.25,15.25,15.25,2186400,1.74 +1985-08-08,15.13,15.25,15.13,15.13,5321600,1.73 +1985-08-07,15.25,16.00,14.88,14.88,5452800,1.70 +1985-08-06,15.38,15.75,15.25,15.25,2260000,1.74 +1985-08-05,15.75,15.88,15.38,15.38,3307200,1.75 +1985-08-02,15.88,15.88,15.75,15.75,3501600,1.80 +1985-08-01,15.88,16.12,15.88,15.88,1842400,1.81 +1985-07-31,16.25,16.37,15.88,15.88,2917600,1.81 +1985-07-30,16.25,16.37,16.25,16.25,3237600,1.85 +1985-07-29,16.62,16.62,16.00,16.00,2808800,1.83 +1985-07-26,16.62,16.75,16.62,16.62,4673600,1.90 +1985-07-25,16.62,16.75,16.62,16.62,11282400,1.90 +1985-07-24,16.50,16.75,16.25,16.25,6040000,1.85 +1985-07-23,16.87,17.12,16.50,16.50,6038400,1.88 +1985-07-22,17.37,17.37,16.87,16.87,6906400,1.92 +1985-07-19,17.37,17.37,17.37,17.37,4117600,1.98 +1985-07-18,17.62,17.62,17.25,17.25,6437600,1.97 +1985-07-17,17.62,17.87,17.62,17.62,4255200,2.01 +1985-07-16,17.75,17.87,17.50,17.50,5120000,2.00 +1985-07-15,17.87,18.25,17.75,17.75,2804800,2.03 +1985-07-12,18.00,18.00,17.87,17.87,1680000,2.04 +1985-07-11,18.00,18.12,18.00,18.00,2361600,2.05 +1985-07-10,18.00,18.00,18.00,18.00,3802400,2.05 +1985-07-09,17.62,17.75,17.62,17.62,5284000,2.01 +1985-07-08,17.62,17.75,17.62,17.62,3301600,2.01 +1985-07-05,17.62,17.75,17.62,17.62,1321600,2.01 +1985-07-03,17.50,17.50,17.50,17.50,2472800,2.00 +1985-07-02,18.12,18.25,17.25,17.25,2807200,1.97 +1985-07-01,18.12,18.25,18.12,18.12,3702400,2.07 +1985-06-28,18.37,18.50,18.00,18.00,4875200,2.05 +1985-06-27,18.37,18.50,18.37,18.37,6915200,2.10 +1985-06-26,18.12,18.12,18.12,18.12,4722400,2.07 +1985-06-25,17.50,17.87,17.50,17.50,10506400,2.00 +1985-06-24,17.25,17.50,17.25,17.25,7387200,1.97 +1985-06-21,16.12,16.50,16.12,16.12,5941600,1.84 +1985-06-20,15.75,15.75,15.75,15.75,6822400,1.80 +1985-06-19,15.63,15.88,15.63,15.63,6177600,1.78 +1985-06-18,15.25,15.50,15.25,15.25,9489600,1.74 +1985-06-17,14.88,15.00,14.88,14.88,8464000,1.70 +1985-06-14,14.88,15.75,14.75,14.75,20226400,1.68 +1985-06-13,15.75,15.88,14.88,14.88,13573600,1.70 +1985-06-12,16.12,16.25,15.75,15.75,8888800,1.80 +1985-06-11,16.12,16.50,16.12,16.12,10751200,1.84 +1985-06-10,16.37,16.50,16.12,16.12,11296000,1.84 +1985-06-07,17.00,17.00,16.37,16.37,16980000,1.87 +1985-06-06,17.00,17.00,17.00,17.00,9688800,1.94 +1985-06-05,17.25,17.75,16.87,16.87,10267200,1.92 +1985-06-04,17.25,17.37,17.25,17.25,14373600,1.97 +1985-06-03,17.00,17.00,16.00,16.00,20578400,1.83 +1985-05-31,17.62,18.00,17.37,17.37,13235200,1.98 +1985-05-30,17.62,17.87,17.62,17.62,11273600,2.01 +1985-05-29,17.12,17.25,17.12,17.12,8808800,1.95 +1985-05-28,17.87,17.87,16.87,16.87,18253600,1.92 +1985-05-24,19.75,19.75,18.12,18.12,21060000,2.07 +1985-05-23,20.50,20.50,19.75,19.75,8576000,2.25 +1985-05-22,20.75,20.87,20.62,20.62,4342400,2.35 +1985-05-21,21.25,21.25,20.75,20.75,5452800,2.37 +1985-05-20,21.75,22.25,21.37,21.37,7044000,2.44 +1985-05-17,21.37,22.12,21.25,21.75,7592800,2.48 +1985-05-16,21.37,22.00,21.37,21.37,8275200,2.44 +1985-05-15,20.00,20.37,20.00,20.00,4668800,2.28 +1985-05-14,20.00,20.12,19.75,19.75,4364000,2.25 +1985-05-13,20.25,20.37,20.00,20.00,3157600,2.28 +1985-05-10,20.00,20.50,20.00,20.25,4893600,2.31 +1985-05-09,20.00,20.12,20.00,20.00,4571200,2.28 +1985-05-08,19.87,19.87,19.87,19.87,5177600,2.27 +1985-05-07,20.00,20.00,20.00,20.00,3844800,2.28 +1985-05-06,20.00,20.25,19.75,19.75,2007200,2.25 +1985-05-03,19.25,20.12,19.25,20.00,5673600,2.28 +1985-05-02,20.62,20.62,19.25,19.25,11787200,2.20 +1985-05-01,21.25,21.37,20.87,20.87,2075200,2.38 +1985-04-30,21.25,21.37,21.25,21.25,3396000,2.42 +1985-04-29,21.87,22.00,21.12,21.12,2256000,2.41 +1985-04-26,22.00,22.62,21.87,21.87,4295200,2.50 +1985-04-25,22.00,22.12,22.00,22.00,3135200,2.51 +1985-04-24,22.12,22.50,22.00,22.00,2830400,2.51 +1985-04-23,22.12,22.25,22.12,22.12,4261600,2.52 +1985-04-22,22.50,22.50,21.62,21.62,3700000,2.47 +1985-04-19,22.87,22.87,22.37,22.50,3468800,2.57 +1985-04-18,22.87,23.00,22.87,22.87,7246400,2.61 +1985-04-17,22.62,22.87,22.62,22.62,4402400,2.58 +1985-04-16,21.62,21.75,21.62,21.62,2424800,2.47 +1985-04-15,21.37,21.62,21.37,21.37,2168800,2.44 +1985-04-12,21.37,21.37,20.75,20.87,2607200,2.38 +1985-04-11,21.37,22.00,21.37,21.37,5260000,2.44 +1985-04-10,21.00,21.25,21.00,21.00,8117600,2.40 +1985-04-09,19.62,19.75,19.62,19.62,9461600,2.24 +1985-04-08,20.87,21.00,19.62,19.62,7129600,2.24 +1985-04-04,21.00,21.12,20.62,20.87,5792800,2.38 +1985-04-03,21.00,21.12,21.00,21.00,8681600,2.40 +1985-04-02,21.62,21.75,21.00,21.00,8146400,2.40 +1985-04-01,22.12,22.62,21.62,21.62,4115200,2.47 +1985-03-29,21.87,22.25,21.87,22.12,3155200,2.52 +1985-03-28,21.87,22.25,21.87,21.87,4667200,2.50 +1985-03-27,22.50,22.75,21.87,21.87,4008800,2.50 +1985-03-26,22.50,22.50,22.50,22.50,4346400,2.57 +1985-03-25,22.25,22.25,21.62,21.62,3931200,2.47 +1985-03-22,22.62,23.00,22.25,22.25,2910400,2.54 +1985-03-21,22.62,23.00,22.62,22.62,5826400,2.58 +1985-03-20,22.25,22.62,22.25,22.25,14498400,2.54 +1985-03-19,22.87,23.12,22.00,22.00,6147200,2.51 +1985-03-18,22.87,23.12,22.87,22.87,4487200,2.61 +1985-03-15,21.75,23.12,21.62,22.62,6524000,2.58 +1985-03-14,21.75,21.87,21.75,21.75,8667200,2.48 +1985-03-13,23.00,23.00,21.75,21.75,8973600,2.48 +1985-03-12,23.00,23.25,23.00,23.00,7880000,2.62 +1985-03-11,22.25,22.37,22.25,22.25,10244800,2.54 +1985-03-08,22.12,22.12,20.75,21.50,16931200,2.45 +1985-03-07,24.62,24.75,22.12,22.12,26244000,2.52 +1985-03-06,25.87,25.87,24.62,24.62,6933600,2.81 +1985-03-05,25.87,25.87,25.87,25.87,4687200,2.95 +1985-03-04,25.25,26.00,25.25,25.25,5484000,2.88 +1985-03-01,24.75,24.87,24.00,24.87,8857600,2.84 +1985-02-28,25.12,25.12,24.75,24.75,11415200,2.82 +1985-02-27,26.75,26.75,25.12,25.12,14421600,2.87 +1985-02-26,27.25,27.37,26.75,26.75,6764800,3.05 +1985-02-25,27.62,27.75,27.25,27.25,3564000,3.11 +1985-02-22,26.87,27.87,26.87,27.62,8096000,3.15 +1985-02-21,26.87,27.00,26.87,26.87,11035200,3.07 +1985-02-20,27.62,27.75,26.37,26.37,7864800,3.01 +1985-02-19,27.87,27.87,27.62,27.62,5391200,3.15 +1985-02-15,27.62,28.12,27.37,28.00,6224000,3.19 +1985-02-14,28.37,28.62,27.62,27.62,15268800,3.15 +1985-02-13,29.75,29.75,28.37,28.37,18835200,3.24 +1985-02-12,30.50,30.62,29.75,29.75,8095200,3.39 +1985-02-11,30.50,30.75,30.50,30.50,12431200,3.48 +1985-02-08,29.87,30.00,29.50,29.87,4757600,3.41 +1985-02-07,30.00,30.37,29.87,29.87,8793600,3.41 +1985-02-06,30.00,30.00,30.00,30.00,6980000,3.42 +1985-02-05,29.50,30.00,29.50,29.50,6824800,3.37 +1985-02-04,29.25,29.37,29.25,29.25,7801600,3.34 +1985-02-01,29.00,29.12,28.37,28.62,4941600,3.27 +1985-01-31,29.87,30.00,29.00,29.00,9880000,3.31 +1985-01-30,29.87,30.50,29.87,29.87,17624800,3.41 +1985-01-29,30.25,30.50,29.87,29.87,8029600,3.41 +1985-01-28,30.25,30.62,30.25,30.25,14721600,3.45 +1985-01-25,29.00,29.62,28.37,29.62,11381600,3.38 +1985-01-24,29.62,29.62,29.00,29.00,14192800,3.31 +1985-01-23,30.12,30.25,29.62,29.62,15384000,3.38 +1985-01-22,30.12,30.25,30.12,30.12,15202400,3.44 +1985-01-21,29.25,29.50,29.25,29.25,11635200,3.34 +1985-01-18,28.12,29.25,28.00,28.62,12615200,3.27 +1985-01-17,30.25,30.75,28.12,28.12,19573600,3.21 +1985-01-16,30.25,30.75,30.25,30.25,6816000,3.45 +1985-01-15,30.62,31.12,30.00,30.00,9476000,3.42 +1985-01-14,30.62,30.87,30.62,30.62,9691200,3.49 +1985-01-11,30.00,30.25,29.50,29.75,7347200,3.39 +1985-01-10,30.00,30.12,30.00,30.00,9926400,3.42 +1985-01-09,28.75,29.12,28.75,28.75,5973600,3.28 +1985-01-08,28.25,28.50,28.00,28.00,5040000,3.19 +1985-01-07,28.37,28.50,28.25,28.25,6117600,3.22 +1985-01-04,28.37,28.50,28.00,28.37,4915200,3.24 +1985-01-03,28.37,29.12,28.37,28.37,5967200,3.24 +1985-01-02,29.12,29.12,27.87,27.87,6272800,3.18 +1984-12-31,29.12,29.25,29.12,29.12,7453600,3.32 +1984-12-28,27.75,28.87,27.62,28.75,5941600,3.28 +1984-12-27,27.75,27.87,27.75,27.75,3531200,3.17 +1984-12-26,27.62,27.87,27.62,27.62,2444000,3.15 +1984-12-24,27.50,27.62,27.50,27.50,2418400,3.14 +1984-12-21,27.37,27.50,26.75,27.00,4438400,3.08 +1984-12-20,27.50,28.00,27.37,27.37,5013600,3.12 +1984-12-19,28.62,28.75,27.50,27.50,11372800,3.14 +1984-12-18,28.62,28.75,28.62,28.62,12164800,3.27 +1984-12-17,27.00,27.25,27.00,27.00,4513600,3.08 +1984-12-14,25.75,26.62,25.75,26.37,3475200,3.01 +1984-12-13,25.75,26.25,25.75,25.75,2424800,2.94 +1984-12-12,26.37,26.37,25.50,25.50,3937600,2.91 +1984-12-11,26.75,27.12,26.37,26.37,4432800,3.01 +1984-12-10,27.25,27.25,26.75,26.75,4016000,3.05 +1984-12-07,27.37,28.37,27.12,27.25,17696000,3.11 +1984-12-06,27.37,27.50,27.37,27.37,11360000,3.12 +1984-12-05,26.12,26.12,26.12,26.12,9406400,2.98 +1984-12-04,24.87,25.37,24.87,24.87,4332800,2.84 +1984-12-03,24.75,24.87,24.37,24.37,3533600,2.78 +1984-11-30,25.37,25.62,24.62,24.75,3906400,2.82 +1984-11-29,25.87,25.87,25.37,25.37,6248800,2.89 +1984-11-28,25.87,26.50,25.87,25.87,14673600,2.95 +1984-11-27,24.62,24.87,24.62,24.62,4590400,2.81 +1984-11-26,24.00,24.00,24.00,24.00,3636000,2.74 +1984-11-23,23.37,24.12,23.37,23.75,4904800,2.71 +1984-11-21,23.12,23.25,23.12,23.12,6418400,2.64 +1984-11-20,22.62,22.75,22.62,22.62,9424800,2.58 +1984-11-19,23.25,23.37,21.87,21.87,8321600,2.50 +1984-11-16,23.75,24.12,23.12,23.25,5920000,2.65 +1984-11-15,23.75,24.00,23.75,23.75,3833600,2.71 +1984-11-14,23.75,24.00,23.75,23.75,3752800,2.71 +1984-11-13,24.12,24.62,23.50,23.50,4548800,2.68 +1984-11-12,24.12,24.25,24.12,24.12,4070400,2.75 +1984-11-09,24.75,24.87,23.00,23.25,10518400,2.65 +1984-11-08,25.75,25.75,24.75,24.75,3162400,2.82 +1984-11-07,26.25,26.37,25.75,25.75,8286400,2.94 +1984-11-06,26.25,26.37,26.25,26.25,8073600,3.00 +1984-11-05,24.87,25.37,24.75,24.75,3764800,2.82 +1984-11-02,25.00,25.12,24.75,24.87,1004800,2.84 +1984-11-01,25.00,25.25,25.00,25.00,1680000,2.85 +1984-10-31,25.00,25.25,24.87,24.87,2191200,2.84 +1984-10-30,25.00,25.25,25.00,25.00,2677600,2.85 +1984-10-29,24.75,24.87,24.75,24.75,1836000,2.82 +1984-10-26,25.25,25.25,24.50,24.62,4113600,2.81 +1984-10-25,26.25,26.25,25.25,25.25,5676000,2.88 +1984-10-24,26.25,26.50,26.25,26.25,5989600,3.00 +1984-10-23,26.00,26.25,26.00,26.00,6668800,2.97 +1984-10-22,25.62,26.00,25.37,25.37,4108800,2.89 +1984-10-19,25.62,27.37,25.50,25.62,11673600,2.92 +1984-10-18,25.62,25.75,25.62,25.62,8842400,2.92 +1984-10-17,24.87,25.00,24.87,24.87,5636000,2.84 +1984-10-16,24.00,24.12,23.87,23.87,4246400,2.72 +1984-10-15,24.00,24.25,24.00,24.00,8715200,2.74 +1984-10-12,23.75,23.87,22.50,22.75,9522400,2.60 +1984-10-11,23.87,24.50,23.75,23.75,6553600,2.71 +1984-10-10,24.62,24.62,23.87,23.87,13070400,2.72 +1984-10-09,24.87,25.00,24.62,24.62,4515200,2.81 +1984-10-08,24.87,25.00,24.87,24.87,1721600,2.84 +1984-10-05,25.37,25.37,24.75,24.87,3510400,2.84 +1984-10-04,25.37,25.62,25.37,25.37,4482400,2.89 +1984-10-03,25.12,25.50,25.12,25.12,4335200,2.87 +1984-10-02,24.75,25.62,24.75,24.75,4258400,2.82 +1984-10-01,25.00,25.00,24.50,24.50,3521600,2.80 +1984-09-28,25.75,25.75,24.62,25.12,8344800,2.87 +1984-09-27,25.75,25.87,25.75,25.75,3796000,2.94 +1984-09-26,26.12,27.25,25.75,25.75,3987200,2.94 +1984-09-25,26.50,26.50,26.12,26.12,5977600,2.98 +1984-09-24,26.87,27.00,26.62,26.62,2833600,3.04 +1984-09-21,27.12,27.87,26.50,26.87,3591200,3.07 +1984-09-20,27.12,27.37,27.12,27.12,2387200,3.09 +1984-09-19,27.62,27.87,27.00,27.00,3816000,3.08 +1984-09-18,28.62,28.87,27.62,27.62,3495200,3.15 +1984-09-17,28.62,29.00,28.62,28.62,6886400,3.27 +1984-09-14,27.62,28.50,27.62,27.87,8826400,3.18 +1984-09-13,27.50,27.62,27.50,27.50,7429600,3.14 +1984-09-12,26.87,27.00,26.12,26.12,4773600,2.98 +1984-09-11,26.62,27.37,26.62,26.87,5444000,3.07 +1984-09-10,26.50,26.62,25.87,26.37,2346400,3.01 +1984-09-07,26.50,26.87,26.25,26.50,2981600,3.02 Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/aapl.npy.gz and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/aapl.npy.gz differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/axes_grid/bivariate_normal.npy and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/axes_grid/bivariate_normal.npy differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/ct.raw.gz and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/ct.raw.gz differ diff -Nru matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/data_x_x2_x3.csv matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/data_x_x2_x3.csv --- matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/data_x_x2_x3.csv 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/data_x_x2_x3.csv 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,11 @@ + 0 0 0 + 1 1 1 + 2 4 8 + 3 9 27 + 4 16 64 + 5 25 125 + 6 36 216 + 7 49 343 + 8 64 512 + 9 81 729 +10 100 1000 diff -Nru matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/demodata.csv matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/demodata.csv --- matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/demodata.csv 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/demodata.csv 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,11 @@ +clientid,date,weekdays,gains,prices,up +0,2008-04-30,Wed,-0.52458192906686452,7791404.0091921333,False +1,2008-05-01,Thu,0.076191536201738269,3167180.7366340165,True +2,2008-05-02,Fri,-0.86850970062880861,9589766.9613829032,False +3,2008-05-03,Sat,-0.42701083852713395,8949415.1867596991,False +4,2008-05-04,Sun,0.2532553652693274,937163.44375252665,True +5,2008-05-05,Mon,-0.68151636911081892,949579.88022264629,False +6,2008-05-06,Tue,0.0071911579626532168,7268426.906552773,True +7,2008-05-07,Wed,0.67449747200412147,7517014.782897247,True +8,2008-05-08,Thu,-1.1841008656818983,1920959.5423492221,False +9,2008-05-09,Fri,-1.5803692595811152,8456240.6198725495,False Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/eeg.dat and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/eeg.dat differ diff -Nru matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/embedding_in_wx3.xrc matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/embedding_in_wx3.xrc --- matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/embedding_in_wx3.xrc 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/embedding_in_wx3.xrc 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,65 @@ + + + + embedding_in_wx3 + + + wxVERTICAL + + + + + + + wxALL|wxEXPAND + 5 + + + + wxHORIZONTAL + + + + + + wxALL|wxEXPAND + 2 + + + + + + + wxALL|wxEXPAND + 2 + + + + + + + + wxALL|wxEXPAND + 2 + + + + 0 + + + wxEXPAND + + + + wxLEFT|wxRIGHT|wxEXPAND + 5 + + + + + wxEXPAND + + + + + \ No newline at end of file Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/goog.npy and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/goog.npy differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/lena.jpg and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/lena.jpg differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/lena.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/lena.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/logo2.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/logo2.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/membrane.dat matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/membrane.dat --- matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/membrane.dat 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/membrane.dat 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,64 @@ +**+**:,:,:,*++*+*Z***Z*Z**:,:,)Z*Z****+:,:,*+*++++++**+++**+Z***++*+++***Z*Z**+Z*++Z***++++:,:,+++Z*)+**:,++Z*:,:,Z******:,+***+++**+:,:,*+++**+**++++***Z*Z*+++++Z*++***:,**:,,,+:,:,+*:,+++Z*Z**++Z***Z*Z*Z**+Z*Z*Z*+++:,**+*+++)**:,*****Z*Z*Z*Z***Z*Z*++++++Z***:,*:,:,,*Z*Z*Z*++*****))++**+**Z*++****+++++***++)Z*Z*:,*****Z*Z**Z*Z*++++***,,+**:,*+++Z*Z*Z****+***Z*Z*Z*+*Z*Z*++++:,:,++++:,:,+Z*+++)***)),*****Z*Z**:,:,+++:,+***,+++++Z***+Z*Z****Z**)Z*Z*Z*Z*Z*:,**+++*++**:,**,**+**Z*********+*+Z*+:,++*++:,**++++**:,)Z**+Z*Z*Z*Z***Z*******:,:,*+:,***Z*Z****++++Z****Z***Z*Z*Z*+:,:,Z*Z*Z*Z*Z*+**+++:,++++:,+*+:,:,Z*Z*Z****+**Z*Z*Z*+++*++Z*Z*++++:,:,******:,***Z**Z*Z**))*+++++*+****+++++Z*++**Z*++Z****))*Z*Z**Z*Z*++Z***:,***:,:,***Z*:,+*:,*Z*Z*+++****))+Z*Z**++Z***+++++*++Z*++***+Z*)*+Z*Z*Z*+**+***++*:,:,*Z**+++*****Z***+**:,*Z*Z*Z*Z*))*++*++)**+++*Z*Z*++Z*++*))+**Z*Z*Z*Z***Z*Z*Z*+*:,Z***:,:,Z***+Z*Z*+++***Z***Z**+Z*Z*)++Z*Z*Z*+**++++++:,++Z*Z**++***)***Z*Z****+***Z*+***Z*Z*:,:,Z**:,+++:,:,:,Z******Z*Z*Z**Z*Z*:,:,)Z*Z*:,Z*Z*+++*+++***++**Z*++Z*Z*Z*+Z*Z**:,:,***+++Z*Z*+++*++*Z*Z*******Z**Z*Z**Z*Z*Z*Z***+***++)**:,**+++***++*Z*Z**Z*)Z*:,Z*))*++*+++**Z*++*********)))*****Z*Z**Z********Z*++)**+Z****:,***++*))+++Z*:,*))*++Z*++***Z*:,:,*Z**:,:,+**Z*))+*Z*++***Z*Z*Z**)):,**+++`%VZ%8z#$:"z\\*   8 vXvX:&X/[[ nnモ.C.C.ݾ˭ܾ˭ܾgm־+ҾmѾmѾξwlǾwlǾwlǾ'l¾,,뫾뿾뿾kkk뫾뫾뫾뫾,,,'l¾c,ƾwlǾwlǾwlǾɾɾ,˾l̾l̾mѾ-о-о+Ҿ?Ӿ?ӾS-վgm־gm־{׾{׾{׾ؾ-ھ˭ܾm۾m۾ݾݾݾ˭ܾ-߾-߾n-߾ݾn/WnWn///C.////C.C.-߾nnn/nn-߾nnnn˭ܾ˭ܾݾn˭ܾ˭ܾݾݾ-ھ-ھ-ھ{׾{׾ؾS-վS-վgm־ؾؾ+Ҿ+Ҿ+Ҿ+ҾmѾmѾξ-о۬;۬;۬;-оl̾l̾l̾,˾,˾ɾ,˾,˾ɾɾɾȾȾȾc,ƾc,ƾwlǾwlǾwlǾOľOľOľc,ƾOľOľOľOľOľOľwlǾOľwlǾɾwlǾwlǾwlǾ,˾ɾɾ,˾,˾,˾ɾl̾l̾ɾɾl̾,˾,˾۬;۬;۬;۬;-о-оmѾ-о-о+Ҿ-о-о+ҾS-վS-վS-վgm־gm־gm־S-վ{׾ؾؾ{׾{׾{׾{׾˭ܾ˭ܾm۾m۾m۾-ھؾؾm۾m۾ؾm۾m۾m۾-ھm۾˭ܾm۾m۾m۾m۾m۾˭ܾ˭ܾ˭ܾ-ھm۾m۾-ھؾ-ھ˭ܾؾؾؾؾgm־gm־gm־gm־gm־gm־gm־?Ӿ?Ӿ?ӾmѾmѾξmѾmѾ۬;۬;۬;-оl̾l̾,˾,˾wlǾɾɾc,ƾwlǾwlǾc,ƾ'l¾'l¾;þ,뿾,,kkkkkk뺾뺾뺾kks+_뵾_뵾_뵾s+_뵾_뵾#+_뵾_뵾7k7k7kkKKs+_뵾s+7k7k_뵾kkk뺾뺾k뺾뺾k뫾뫾뫾,;þwlǾwlǾc,ƾwlǾwlǾȾȾȾ,˾l̾l̾l̾,˾,˾-о-оξ-о-о+Ҿ-о-о?Ӿ?Ӿ?ӾS-վS-վS-վS-վgm־gm־gm־ؾؾ{׾{׾-ھؾؾؾ-ھ-ھ-ھ{׾{׾-ھ-ھ-ھ-ھ{׾{׾gm־ؾ{׾gm־gm־gm־gm־gm־?Ӿ?Ӿ?Ӿ+Ҿ+ҾmѾξξ-о+Ҿ+Ҿ۬;ξξl̾ɾɾȾ,˾,˾wlǾOľOľc,ƾ'l¾'l¾뿾뿾뿾++kkks+s+7k#+#+7k7k7kjjj*꫾꫾j[[Gj[꡾꡾i霾霾闾WiWighM]M]9ii]U]U*c,ƾ-ھk3//bvXvX8 8  x +x +x +x + 8 x +x +llvXllNbbXxXxN:::&X&X&X&Xxxo//o//o[3/ nn 𾻮羓.龓.龓.C.C.knnݾݾm۾-ھ-ھؾgm־gm־S-վ+Ҿ+Ҿ-оmѾξ,˾ɾɾɾc,ƾc,ƾc,ƾc,ƾ'l¾,,뿾kk뺾K7k7k7k**꫾*[[3*꡾꡾霾ikWi/钾((_ɊɊmFgh*;þ;þWn../NNNvXvXvXbbllllbllNNND8D8D8::x&X/oooGooo[GoGoGo...n꾻뾻뾻kkk-߾n˭ܾm۾m۾-ھ-ھ-ھ?ӾS-վS-վmѾmѾmѾξξξl̾,˾ɾwlǾwlǾ;þc,ƾc,ƾ,뫾뫾뫾++kkk7k7k#+#+#+j**j**3*[ iiC){}} +)))HH荾*;þS-վS-վn[[:D8D80NNN::D8::00&X&Xxxo///o[[oGoGoGoGo3/3/ .쾧n꾧n꾧nkkC.C.C.n-߾˭ܾ˭ܾm۾-ھ-ھ-ھgm־gm־{׾gm־gm־+Ҿ?ӾmѾξξ۬;,˾,˾ȾɾɾwlǾc,ƾc,ƾ,뿾뿾+뺾s+_뵾_뵾_뵾#+밾밾jjj[ 霾霾霾闾闾/钾/钾+NlNl q +Wq +W + +Wi7k7k˭ܾknGoo&X&X&X&Xxxxo/oo[ooGoGo3/3/3/n n..n꾓.龓.龧nkkkWnWnnC./nn-߾-߾-߾˭ܾm۾m۾ؾؾؾS-վgm־gm־S-վ-о-о-оmѾmѾ,˾۬;,˾,˾ɾɾc,ƾc,ƾOľ'l¾'l¾k,,뺾뺾kKK7k밾jjoꦾ[[꡾))霾(˨?胾=sMX   OqOqkl̾l̾knnᆱ/xoooooo///oo[oo3/3/3/3/ n .nnᄏ쾧n꾓.龓.龓.羓.龓.龓.C.C.Wn-߾-߾ݾ-߾-߾ݾ˭ܾ˭ܾ˭ܾ-ھ-ھ-ھ{׾{׾{׾gm־+Ҿ+Ҿ+Ҿ?ӾmѾmѾmѾξξ,˾l̾l̾ɾwlǾwlǾOľ;þ'l¾;þ,뫾뫾뫾뺾뺾뺾k7k7k_뵾#+#+밾꫾꫾꫾*GjGj[ii霾C)iiS(hnELD)a + +-2-2oꦾ뿾+Ҿnྒྷ.GoGo/o//ooo/oooooGo3/3/ [..n 𾻮쾓.龧n꾧n꾧nkkWnkk/ݾݾnݾݾݾݾ˭ܾm۾m۾m۾-ھ-ھ{׾ؾؾ{׾gm־gm־?Ӿ?Ӿ?ӾmѾ-о-оmѾ-о۬;ξξ۬;,˾,˾wlǾȾȾc,ƾc,ƾc,ƾ;þ;þ;þ뿾뿾k++뺾뺾_뵾s+s+#+밾밾밾*oꦾ**iii)闾闾C)((gh}}<޽ 9a qK0K0oꦾ뿾뿾ݾkk [[ooooo[[[oGoGoGon .쾻뾻뾻뾧nkkWnWnWnWn//C.nnnྷm۾˭ܾ˭ܾ˭ܾ˭ܾ˭ܾ-ھm۾-ھgm־ؾ{׾{׾{׾{׾gm־gm־S-վ+Ҿ+Ҿ+Ҿ?Ӿ?Ӿξξξξξ۬;۬;۬;,˾,˾,˾wlǾwlǾwlǾwlǾOľOľ'l¾Oľ뿾,,k뿾뿾kkK7k7k7k밾밾j꫾꫾j3*Gj[[i))iC)C)荾荾}eOveOv%Iىى!k5HZ/钾7kɾɾᾓ.龓.Go[[oooo///GoGoGoGo3/nnnᄏ뾓.龓.龓.龓.龓.WnWnC.Wn///n-߾-߾-߾ݾݾ˭ܾ˭ܾ˭ܾ-ھ-ھ-ھ-ھ-ھؾ{׾{׾ؾ{׾{׾?Ӿgm־S-վ?Ӿ?ӾmѾS-վS-վmѾmѾmѾξ۬;۬;l̾l̾l̾l̾ɾɾɾɾwlǾc,ƾc,ƾc,ƾOľOľ'l¾c,ƾc,ƾ뿾뫾뫾뺾뺾뺾+뺾kk_뵾_뵾#+밾밾*꫾꫾꫾jGjGj꡾3*iiiiC)/钾/钾(S(S(uNgK? M M +ɊɊeOviil̾ؾؾn..Goo[//[GoGoo3/3/Go3/ 񾻮뾻뾧n꾻뾻뾓.龓.龓.WnWnC.nC.-߾-߾ᾷm۾ݾݾ˭ܾؾؾm۾m۾m۾-ھؾؾؾgm־ؾS-վS-վgm־S-վS-վS-վgm־gm־-оmѾmѾ-о-о-оξ۬;۬;l̾l̾,˾ɾɾɾc,ƾc,ƾȾwlǾwlǾwlǾȾȾ;þ;þOľ뫾'l¾'l¾,,뫾뫾뫾뺾뺾뺾k_뵾_뵾_뵾#+#+#+밾꫾꫾꫾꫾jjoꦾ[[꡾ )闾/钾荾舾舾eOv__) qϽAhh,mѾmѾC.侧n꾧n3/3//[[/o3/3/3/[n 쾻뾻뾧n꾧n꾧nk澓.///WnWn-߾ݾݾݾݾm۾ݾ-ھؾ-ھ-ھؾؾؾ{׾{׾{׾{׾{׾{׾mѾmѾmѾ+Ҿ-о-оmѾmѾξ۬;۬;l̾l̾l̾l̾ɾɾl̾ȾȾȾ,˾,˾c,ƾwlǾȾOľ;þ;þOľOľ뿾'l¾'l¾뫾뫾뫾kk뺾kkk#+#+#+K밾밾jj꫾jj*[꡾3* i/钾WiWi{ghgheOvMXMɊ  K:舾舾,-о-оk澧n꾧nGo3/3/3/ooo[[[ ...뾧n꾧n꾧nWnkkkC.C.C.WnC.C./ݾ-߾m۾ݾ˭ܾm۾-ھ-ھm۾m۾m۾S-վ{׾{׾?Ӿgm־gm־S-վ+Ҿ+Ҿ+Ҿ+Ҿ+Ҿ-о-о-оξξ-о۬;۬;۬;۬;۬;l̾۬;l̾ɾɾɾɾɾwlǾwlǾwlǾ;þ;þ;þ;þ;þ;þ,뿾뿾뿾kk++뺾s+s+k_뵾_뵾7k밾밾밾꫾jjoꦾoꦾGj3*3*霾C)C)(˨˨+O{O{UK5ٽ +/A 4A 4)II){׾//nn3/GoGoGo3/3/3/nnn쾻쾧n꾧n꾧nkkkC.C.C.-߾ݾݾ˭ܾm۾m۾m۾m۾m۾ؾؾ-ھgm־gm־{׾{׾{׾S-վgm־gm־S-վ?Ӿ?Ӿ+Ҿ?Ӿ?ӾmѾ۬;۬;mѾ-оξ۬;ξl̾,˾,˾ɾ,˾,˾ɾɾɾȾwlǾwlǾ;þOľOľ;þ'l¾'l¾;þ;þ뿾,,kkkk++s+s+s+K7k밾#+꫾꫾****oꦾoꦾGjii)霾霾闾/钾/钾(S(hxM]   iK0K0 +۬;-ھn.Go3/3/GoGo3/ Go 񾻮쾻뾧n꾻WnWnWn/C.C.-߾nn-߾˭ܾ˭ܾݾݾݾ-ھ-ھ-ھؾ-ھ-ھgm־gm־{׾{׾{׾S-վS-վS-վ+Ҿ+Ҿ+Ҿ?Ӿ-о-оmѾmѾmѾξ۬;۬;۬;l̾l̾,˾ɾ,˾ȾȾ,˾ȾȾwlǾwlǾwlǾ;þOľOľOľOľOľ;þ;þ'l¾,,뫾kk뺾뺾뺾s+s+KKK#+#+꫾jjjoꦾoꦾGj3*3*i霾霾i闾/钾i(hS(S(iLILIQua a 9))(**mѾm۾C.侻n3/GoGo[3/3/3/ ..뾻뾻뾻뾓.龓.龓.龓.WnWnWn/nn/nn-߾-߾-߾ݾ˭ܾ˭ܾ˭ܾ-ھ-ھ-ھ-ھؾؾ{׾gm־gm־-оS-վS-վS-վmѾ+Ҿ+Ҿ-оmѾ-о-оξξξξl̾l̾ξl̾l̾l̾l̾,˾ɾɾɾȾȾwlǾȾȾ;þOľOľ,'l¾'l¾뿾뫾뫾뿾뺾k++k_뵾_뵾_뵾KK밾밾***oꦾ[oꦾGj3* )闾闾kii˨S(S(eOvMdMdʽ +/ !INlNlKɾɾ-߾kk.nnGo3/3/3/ 쾻뾻뾻쾓.kkkWnC./C.nnnnݾݾ˭ܾؾ-ھ˭ܾ˭ܾؾ-ھ-ھ-ھ{׾{׾{׾?Ӿ?Ӿ?Ӿgm־?Ӿ+Ҿ+ҾS-վmѾmѾ+Ҿ-о-о-оmѾmѾ۬;۬;۬;ξ,˾,˾,˾,˾ɾɾɾwlǾɾɾc,ƾOľOľc,ƾ;þ;þ;þ;þ,뿾뿾,뫾뫾k++뺾s+_뵾_뵾K7k7k밾***oꦾ**oꦾ꡾iii)闾闾Wi/钾/钾(ghgheOvM]=# Q +% !!=s=ss+ȾȾ˭ܾkk 3/3/3/3/ 쾻뾻뾻뾧n꾧nkkkWnC.C.Wn/n-߾-߾nݾݾ˭ܾݾݾm۾-ھ-ھ-ھؾ-ھ{׾{׾{׾gm־gm־gm־{׾{׾S-վ?Ӿ?Ӿ?Ӿ+ҾmѾ+ҾmѾ۬;ξξ-оξξl̾l̾l̾,˾ɾȾwlǾȾwlǾc,ƾc,ƾȾc,ƾc,ƾc,ƾwlǾwlǾ'l¾;þ;þ,,,뿾뫾뫾+kkK_뵾_뵾7k밾밾#+#+꫾**[GjGj꡾iiiii(((?胾}ii5HIIp  mF((뿾۬;۬;ᾓ.龧n3/3/3/GoGoGo  nn...n꾧n羧n꾧nWnkkkC./-߾n-߾-߾-߾-߾m۾m۾ݾ˭ܾ˭ܾ-ھ-ھ-ھ{׾{׾{׾ؾ?Ӿgm־?Ӿ?Ӿ?Ӿ+Ҿ+Ҿ+ҾmѾmѾmѾξξ-о۬;۬;ξξξ۬;l̾۬;,˾,˾,˾l̾l̾wlǾwlǾwlǾwlǾc,ƾOľc,ƾ;þ'l¾'l¾'l¾뿾'l¾'l¾k뺾뺾뫾뺾뺾s+kkKKK7k밾밾**oꦾoꦾ ꡾꡾霾)闾kC)i荾荾{}}Za + +=#=#)s+,˾gm־˭ܾk澻뾻 3/3/  nnᄃn쾻뾓.龓.羓.龓.WnWnC.C.//n-߾ݾ˭ܾ˭ܾm۾ؾ-ھؾؾ{׾gm־gm־gm־S-վS-վ?Ӿ+Ҿ+ҾS-վ?Ӿ?Ӿ+Ҿ+Ҿ+ҾmѾmѾ+ҾmѾmѾ-о-о-оl̾l̾l̾,˾Ⱦɾɾɾɾc,ƾc,ƾOľOľOľ;þ;þ;þ;þ뿾뿾뫾뫾뫾++뺾_뵾_뵾K7k7k밾7k7k꫾꫾[[GjGj)iiiikii˨舾+xMdK?ََ +\ppَ +P +P*,,˭ܾᾓ.龻뾻 3/3/nGoGo .nnn.뾻쾓.龓.龧nWnWnWn/-߾-߾/ݾݾݾ˭ܾ-ھ-ھ-ھؾؾ-ھ-ھm۾-ھ-ھgm־gm־gm־gm־?Ӿ?Ӿgm־+Ҿ+Ҿ+ҾmѾ+ҾmѾmѾ-оl̾l̾ξ۬;۬;l̾l̾l̾,˾ȾȾȾwlǾȾȾc,ƾ;þwlǾwlǾ;þ,,'l¾'l¾'l¾뿾뫾뫾k++k_뵾KK7k7k꫾****oꦾoꦾGj꡾꡾꡾))))Wi荾荾˨{{=sZZ!MNl)KɾɾݾWnWn..Go3/3/GoGoGon nnnnnᄃn꾧nWnWnC.////nn-߾-߾-߾-߾ݾݾ˭ܾ˭ܾ˭ܾm۾ݾݾ{׾{׾{׾{׾gm־ؾgm־{׾?ӾS-վS-վS-վmѾmѾ+Ҿ-о-о+Ҿξξl̾ξ۬;l̾l̾ξl̾l̾,˾,˾,˾ȾȾȾwlǾOľc,ƾc,ƾc,ƾ;þ'l¾'l¾뫾뿾뿾kk뺾kks+kkK_뵾_뵾#+밾밾밾*꫾꫾**[oꦾ3* i闾C)C)˨{{(nnJ+  + aHHk#+#+?Ӿ˭ܾ˭ܾnn.3/3/3/3/3/ n.nnᄏ뾧n꾧n羧n꾓.龓.WnWnWnWnC./C.nnn˭ܾ˭ܾ˭ܾݾ-ھ-ھ-ھؾ{׾{׾{׾{׾ؾؾgm־?Ӿ?Ӿ?Ӿ?Ӿ?Ӿ?Ӿ?Ӿ+Ҿ+Ҿ+ҾmѾmѾmѾξξξl̾l̾l̾l̾l̾l̾ɾȾȾɾɾc,ƾwlǾwlǾ,'l¾'l¾;þ뿾뿾뿾뫾뫾+kk+kk_뵾K_뵾#+#+밾밾밾꫾*GjGj3*3*3*霾i闾闾/钾(({S(S(NlMXMX) +ىeJ&} s+ɾɾnWnWn... 3/[[ nnnnᄏ...龧n꾧n羓.kkWnWnWnnnnn-߾-߾nݾݾm۾m۾m۾m۾m۾ؾؾؾؾ{׾{׾{׾-ھ-ھ?Ӿgm־gm־gm־+Ҿ?Ӿ?Ӿ?ӾmѾ+Ҿ+ҾmѾξξ۬;l̾l̾۬;,˾,˾l̾ɾɾȾwlǾȾc,ƾOľwlǾwlǾOľ;þ;þ;þ,,,뫾kkkkkKK#+밾jjjjjoꦾGjGj) ))ki˨({+xx<ََ Ȼp َK荾-о-ھ-ھ. Go3/3/ nnn.n꾧n꾻뾻뾻뾧nWnkk/C.C.C.-߾//-߾ݾݾݾ-߾-߾ݾm۾m۾˭ܾ-ھ-ھ{׾{׾ؾS-վS-վgm־ؾؾgm־S-վS-վS-վmѾmѾ-о+Ҿ+Ҿ-о۬;۬;-оl̾l̾ξξl̾ɾɾ,˾ɾɾwlǾwlǾwlǾc,ƾ;þ;þ;þOľ'l¾뿾뿾뿾kk뺾뺾s+_뵾KKK#+밾밾**꫾jjoꦾ[[Gj꡾꡾霾kk/钾iigh++Md}7}71 C  IԽELD(*+l̾l̾WnWn. 3/3/ 3/3/n.뾻Wn///////nnC.nnݾnnྏؾm۾m۾-ھ{׾{׾ؾS-վS-վgm־gm־+Ҿ?ӾS-վ+Ҿ+Ҿ+Ҿ+Ҿ+Ҿ+ҾmѾ?Ӿ?Ӿ۬;-о-оξξl̾l̾l̾l̾,˾,˾ɾɾɾc,ƾOľc,ƾc,ƾc,ƾ,c,ƾc,ƾ뿾뫾뫾k++뺾kks+s+s+KKj#+**jGj3*3*꡾霾霾霾kk/钾hghgh=s_K:ٽٽA 4ppٽLILIkk-ھΆnn 3/Go.. .쾻쾻뾧n꾧n꾓.WnWnWnC.////-߾-߾nݾݾ˭ܾm۾m۾˭ܾ˭ܾ˭ܾ-ھ-ھ-ھؾ{׾-ھ-ھgm־S-վؾؾ+ҾS-վS-վS-վ+Ҿ+ҾmѾ-о-оmѾξ۬;-оξl̾,˾,˾ɾȾȾɾȾȾ;þc,ƾc,ƾOľ;þ;þ,,k,,뺾kkkkk7k7kK밾밾jj**[[Gj3*3*)ii闾kkihhS(((M]J+YŽ pp M MMX'l¾+Ҿ+Ҿn. 3/ n..nk澻뾻C./WnWn///nn-߾nnݾݾݾݾnnྣ-ھ-ھ-ھ-ھ{׾ؾ{׾ؾ{׾{׾{׾S-վS-վS-վ+ҾmѾmѾ+ҾmѾmѾξξξl̾l̾l̾l̾,˾ɾl̾,˾ɾɾɾc,ƾc,ƾc,ƾOľ'l¾'l¾'l¾'l¾'l¾뿾kk+++kkK_뵾7k#+7k7kjjj*3*3*3*i霾iiiWiWi(˨˨?胾((Zq + +q +W5HMXC)C),mѾmѾC.WnWn3/3/GoGonn ..羓.kkWnWnC.C.//nnnnnݾnnྣ-ھ˭ܾ˭ܾ˭ܾ-ھ-ھ-ھؾؾS-վؾؾgm־{׾S-վ+Ҿ+ҾS-վmѾmѾmѾ?Ӿ?Ӿ-о-о-оξξξ۬;۬;,˾ɾɾȾȾȾOľOľOľc,ƾ,,,'l¾'l¾k뫾k뺾kkkK_뵾_뵾7k밾밾jjj*jjjoꦾoꦾ3*꡾i)kWiWi(荾荾S(((%NbK?K?k  aiJ++3*,˾,˾nWnWn   ...n꾧n꾧n꾓.龧n꾧nkkkkWnkkC.nC.C.-߾nnݾݾݾ˭ܾ˭ܾ-ھm۾m۾m۾-ھ-ھgm־{׾{׾{׾S-վS-վؾS-վS-վ?Ӿ?ӾS-վ-о-о+ҾmѾmѾ-о-о-о۬;l̾l̾,˾,˾,˾ȾȾc,ƾwlǾOľ;þ;þ;þ'l¾뿾뿾,뿾뿾+kk+s+_뵾k_뵾#+#+#+꫾*oꦾoꦾ3* )ii))/钾((({{O{%Nb%Nb +IIp;!(O{is+s+S-վݾݾ羻뾻nnn  nnn.쾓.龧n꾓.kC.C.C.C.nݾݾ-߾-߾˭ܾݾݾ˭ܾؾؾm۾m۾m۾m۾ؾؾ{׾S-վgm־S-վS-վ?Ӿ+Ҿ+Ҿ+Ҿ+Ҿ+Ҿ-оmѾmѾξ۬;۬;ξ,˾,˾,˾l̾,˾ȾȾwlǾwlǾwlǾc,ƾOľOľ;þ;þ;þk뫾뫾뺾뺾_뵾_뵾_뵾밾밾밾꫾jj*oꦾoꦾGjGji霾霾)闾闾ii{?胾?胾iLNyy + Ȼ ȻH%Nb%Nbj,,˭ܾk澻뾻n  GoGo3/nnn쾧n..羧n꾧n꾓.WnWnWnC.C.WnC./WnWn-߾-߾-߾nnnݾݾݾm۾m۾m۾ؾؾؾ{׾{׾gm־{׾{׾gm־?Ӿ?Ӿ?ӾmѾmѾ+Ҿ+Ҿξ-о-о-о-о-оl̾,˾l̾l̾l̾ȾȾȾȾc,ƾc,ƾ;þ;þ,,,kkk뫾뺾뺾s+s+_뵾s+K#+#+#+jj꫾꫾*oꦾoꦾ꡾꡾ i霾k))/钾(({{{=s__ +kkp; +ɊJ+O{ s+s++Ҿݾݾ羻뾻n3/3/3/3/3/ n..n쾓.龓.龓.龧n꾧n꾧n꾧n꾓.WnWnkk/C.C.nݾ˭ܾ˭ܾ-߾˭ܾ˭ܾ-ھ-ھm۾m۾m۾-ھ-ھ-ھgm־S-վS-վ{׾S-վS-վ?ӾS-վS-վ?Ӿ?ӾmѾmѾmѾmѾ۬;۬;l̾,˾,˾Ⱦ,˾,˾c,ƾȾwlǾOľOľ;þ;þ;þ,,,뫾뫾뫾k뺾+s+_뵾_뵾_뵾#+밾밾#+꫾꫾**Gj3*3* i)闾WiWi(((S(?胾?胾iLILI) p; Ȼ ȻH%Nb%Nbj,,m۾nnྦྷnnn 3/ .....n쾧n꾻뾻WnWnWnWn/C.C.n-߾-߾-߾ݾݾm۾ݾ˭ܾ-ھ-ھ˭ܾm۾m۾-ھؾؾgm־{׾{׾S-վgm־gm־?Ӿ+Ҿ?Ӿ+Ҿ+Ҿξ-о-оξl̾l̾۬;,˾ɾɾ,˾ȾwlǾwlǾwlǾwlǾwlǾOľ'l¾'l¾'l¾,,k뫾뫾++k밾KKjj꫾꫾꫾joꦾGjGjGjiii霾kk闾WiWihhghhhuNgELDELD +\ +\ Qu%IMdMd#+;þ;þ-ھC.C.侓... 3/ . ..񾻮뾻쾻뾻뾓.龓.龓.WnkkWnC.C.//-߾nC.n-߾n-߾-߾ݾ-ھ-ھݾ˭ܾ˭ܾm۾ؾؾ{׾gm־gm־{׾ؾgm־+Ҿ?Ӿgm־?Ӿ?ӾmѾmѾmѾξ۬;۬;ξ۬;,˾l̾,˾,˾ɾɾc,ƾȾȾOľ;þ;þ;þ'l¾'l¾뫾뫾k뺾뺾뺾kKK7k7k7k*밾j꫾jGj[3*3*)霾霾霾闾闾/钾ii(S(S(}n]UJ!J!  +: +: 99ghoꦾoꦾl̾S-վS-վC....3/3/ nn. 𾻮..뾧n꾻뾓.龓.羓.龓.k澓.龓.Wn//C.///nnn-߾-߾n˭ܾ˭ܾ˭ܾؾؾm۾m۾m۾gm־-ھgm־gm־gm־?Ӿؾؾ+Ҿ?Ӿ?Ӿ?Ӿ+Ҿ+Ҿ+Ҿ-оmѾξξ,˾l̾l̾ɾɾɾɾOľOľwlǾc,ƾc,ƾ'l¾'l¾,,뿾k뫾뫾뺾k7k#+#+#+j*jj[3*꡾iiiikWiWi˨(舾++i%Nb%Nb)aa < +\ +\J+eOv霾_뵾_뵾-оm۾m۾羓.龓.n n nnn..nᄏ뾻뾻...龓.龓.龓.kC.C.C.C.//nnnݾݾ-߾ݾݾ˭ܾݾ˭ܾm۾m۾-ھm۾m۾{׾{׾{׾{׾ؾؾ{׾S-վS-վ?Ӿ+Ҿ+Ҿ?Ӿ?Ӿξ۬;۬;mѾ۬;۬;,˾۬;۬;ȾȾȾȾwlǾwlǾc,ƾ;þ;þ;þ'l¾뫾뿾뿾kkk+kkks+s+#+7k7kjjj*[[3*3*3*霾霾霾i闾闾/钾/钾/钾h{+xx]U=#=#Q +%p;p; IԽ>>49RR>>Hy\\\\\fYfYfY\pppp9999yʙ999Y99Y999ʙyyyyyyyy Z yyZ Z Z       !!   $:"!!!$:"$:"$:"$:"$:"!$:"$:"8z#$:"."."."!$:"$:"!."."8z#."."8z#8z#L$8z#8z#B$."."B$8z#8z#L$B$8z#B$B$VZ%8z#8z#B$L$L$B$L$L$B$B$L$8z#B$VZ%B$B$L$`%`%8z#VZ%VZ%VZ%VZ%VZ%`%VZ%VZ%L$L$`%VZ%VZ%`%L$L$VZ%VZ%VZ%VZ%`%`%L$VZ%VZ%VZ%`%`%`%VZ%VZ%t:'t:'`%`%`%`%j&j&t:'`%`%~'t:'t:'j&t:'t:'j&j&j&~'~'`%j&j&j&`%`%VZ%t:'t:'`%j&j&~'j&`%`%z(~'j&j&~'~'~'t:'t:'t:'`%t:'t:'`%t:'t:'j&j&~'t:'t:'j&t:'t:'j&j&j&t:'~'~'~'t:'j&t:'t:'~'t:'t:'~'~'~'z(~'~'~'t:'t:'j&~'~'~'t:'t:'~'~'~'t:'t:'j&t:'t:'~'z(z(z(z(z(t:'z()t:'t:'z(~'~'~'z(z(~'~'~'t:'t:'t:'t:'t:'~'z(t:'~'t:'t:'~'t:'t:'z())~'z(z(z(z(z(t:'~')z(z(z(z(z(~'~'~'t:'t:'t:')~'t:'~'~'z(t:'t:')z(z()~'~'z(~'~'~'z()z(z()))z())~'z(z(t:'z(z(t:'t:'t:'z(z(t:'~'~'~'t:'t:')z(z(z())z(z(z(z(z(z(z(z(z(z(z(~'))t:'z(z()~'z(z(t:'z(~'~'~')))z(z()))))z(~'~'~'z(z(~'))z(z(z(t:'z(z(~'~'~')~'~'~'~'z(~'~')~'~'z()))~'~')))~'~'~'z(z(t:'z(z(~'t:'t:')z(z(z(~'~'~'~'z(~'~')~'~')z(z(z(z(z(t:')z())~'z(z()~'~'~'~'~'~'z(~'z(z(t:')))~'~'z(~'~'~'z(~'z(~'z(~'~'z(~'~')~'~'~'z(z(~'z(z())~'t:'t:'z())~'~'~'~'t:'t:'z())~'~')~'~'z())t:'z(z(t:'z(z(t:'~'~'~'~'~'))t:'~'~'z(t:'t:')))z(z(z(z(~')t:'t:')t:'t:'~'z(z(t:'t:'t:'~'j&j&t:'z(t:'z(~'~'))z(~'~'z(~'~'z())~'z(z(t:'~'~'z(z()~'~'z(~'~'t:'~'~'z(j&t:')~'t:'z(z()~'~'z())t:'z(z()~'~'z(z(z(~'~'t:'))t:'z(z(~'~'z(z(z(~'~'~'z())z(z(z(z(z(z(z(z(~'z(z()~'~'z(t:'t:'~'~'~'~'~'z(z(z()~'~'z())t:'z(z()j&j&)z(~'~')~')))z(z()z(z(z())j&z(z(~'t:'~'z(z(~'))~'z(z()~'~')~'~')))t:'))j&j&~'~'~'t:'~'~')~'~'~'t:'z()))))~'~'~')~'~')z(z())~'z(z(t:'t:'t:')~'~'t:'z(z(j&z(z(z(t:'~'z(z()z(z(z(z(z()z(z()~'~')z(~'t:'t:')t:'t:'~'z(z(t:'~'~'j&~'~'~'t:'t:')~'z())j&)))z(z(z())t:'))~'~'~'t:'t:')z(z(j&z(z(t:'~'~'z(t:'t:'z(~'~'z(z(t:'z(z(~'~')z()z(z(z(t:'~'~'z(z(z(z(~'~'t:'~'t:'~'~'~'))z(~'~'~'~'~'j&j& \ No newline at end of file diff -Nru matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/msft.csv matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/msft.csv --- matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/msft.csv 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/msft.csv 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,66 @@ +Date,Open,High,Low,Close,Volume,Adj. Close* +19-Sep-03,29.76,29.97,29.52,29.96,92433800,29.79 +18-Sep-03,28.49,29.51,28.42,29.50,67268096,29.34 +17-Sep-03,28.76,28.95,28.47,28.50,47221600,28.34 +16-Sep-03,28.41,28.95,28.32,28.90,52060600,28.74 +15-Sep-03,28.37,28.61,28.33,28.36,41432300,28.20 +12-Sep-03,27.48,28.40,27.45,28.34,55777200,28.18 +11-Sep-03,27.66,28.11,27.59,27.84,37813300,27.68 +10-Sep-03,28.03,28.18,27.48,27.55,54763500,27.40 +9-Sep-03,28.65,28.71,28.31,28.37,44315200,28.21 +8-Sep-03,28.39,28.92,28.34,28.84,46105300,28.68 +5-Sep-03,28.23,28.75,28.17,28.38,64024500,28.22 +4-Sep-03,28.10,28.47,27.99,28.43,59840800,28.27 +3-Sep-03,27.42,28.40,27.38,28.30,109437800,28.14 +2-Sep-03,26.70,27.30,26.47,27.26,74168896,27.11 +29-Aug-03,26.46,26.55,26.35,26.52,34503000,26.37 +28-Aug-03,26.50,26.58,26.24,26.51,46211200,26.36 +27-Aug-03,26.51,26.58,26.30,26.42,30633900,26.27 +26-Aug-03,26.31,26.67,25.96,26.57,47546000,26.42 +25-Aug-03,26.31,26.54,26.23,26.50,36132900,26.35 +22-Aug-03,26.78,26.95,26.21,26.22,65846300,26.07 +21-Aug-03,26.65,26.73,26.13,26.24,63802700,26.09 +20-Aug-03,26.30,26.53,26.00,26.45,56739300,26.30 +19-Aug-03,25.85,26.65,25.77,26.62,72952896,26.47 +18-Aug-03,25.56,25.83,25.46,25.70,45817400,25.56 +15-Aug-03,25.61,25.66,25.43,25.54,27607900,25.40 +14-Aug-03,25.66,25.71,25.52,25.63,37338300,25.49 +13-Aug-03,25.79,25.89,25.50,25.60,39636900,25.46 +12-Aug-03,25.71,25.77,25.45,25.73,38208400,25.59 +11-Aug-03,25.61,25.99,25.54,25.61,36433900,25.47 +8-Aug-03,25.88,25.98,25.50,25.58,33241400,25.44 +7-Aug-03,25.72,25.81,25.45,25.71,44258500,25.57 +6-Aug-03,25.54,26.19,25.43,25.65,56294900,25.51 +5-Aug-03,26.31,26.54,25.60,25.66,58825800,25.52 +4-Aug-03,26.15,26.41,25.75,26.18,51825600,26.03 +1-Aug-03,26.33,26.51,26.12,26.17,42649700,26.02 +31-Jul-03,26.60,26.99,26.31,26.41,64504800,26.26 +30-Jul-03,26.46,26.57,26.17,26.23,41240300,26.08 +29-Jul-03,26.88,26.90,26.24,26.47,62391100,26.32 +28-Jul-03,26.94,27.00,26.49,26.61,52658300,26.46 +25-Jul-03,26.28,26.95,26.07,26.89,54173000,26.74 +24-Jul-03,26.78,26.92,25.98,26.00,53556600,25.85 +23-Jul-03,26.42,26.65,26.14,26.45,49828200,26.30 +22-Jul-03,26.28,26.56,26.13,26.38,51791000,26.23 +21-Jul-03,26.87,26.91,26.00,26.04,48480800,25.89 +18-Jul-03,27.11,27.23,26.75,26.89,63388400,26.74 +17-Jul-03,27.14,27.27,26.54,26.69,72805000,26.54 +16-Jul-03,27.56,27.62,27.20,27.52,49838900,27.37 +15-Jul-03,27.47,27.53,27.10,27.27,53567600,27.12 +14-Jul-03,27.63,27.81,27.05,27.40,60464400,27.25 +11-Jul-03,26.95,27.45,26.89,27.31,50377300,27.16 +10-Jul-03,27.25,27.42,26.59,26.91,55350800,26.76 +9-Jul-03,27.56,27.70,27.25,27.47,62300700,27.32 +8-Jul-03,27.26,27.80,27.25,27.70,61896800,27.55 +7-Jul-03,27.02,27.55,26.95,27.42,88960800,27.27 +3-Jul-03,26.69,26.95,26.41,26.50,39440900,26.35 +2-Jul-03,26.50,26.93,26.45,26.88,94069296,26.73 +1-Jul-03,25.59,26.20,25.39,26.15,60926000,26.00 +30-Jun-03,25.94,26.12,25.50,25.64,48073100,25.50 +27-Jun-03,25.95,26.34,25.53,25.63,76040304,25.49 +26-Jun-03,25.39,26.51,25.21,25.75,51758100,25.61 +25-Jun-03,25.64,25.99,25.14,25.26,60483500,25.12 +24-Jun-03,25.65,26.04,25.52,25.70,51820300,25.56 +23-Jun-03,26.14,26.24,25.49,25.78,52584500,25.64 +20-Jun-03,26.34,26.38,26.01,26.33,86048896,26.18 +19-Jun-03,26.09,26.39,26.01,26.07,63626900,25.92 \ No newline at end of file Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/mpl-data/sample_data/s1045.ima.gz and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/mpl-data/sample_data/s1045.ima.gz differ diff -Nru matplotlib-1.1.1/lib/matplotlib/nxutils.py matplotlib-1.2.0/lib/matplotlib/nxutils.py --- matplotlib-1.1.1/lib/matplotlib/nxutils.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/nxutils.py 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,50 @@ +import warnings + +from matplotlib import path + +def pnpoly(x, y, xyverts): + """ + inside = pnpoly(x, y, xyverts) + + Return 1 if x,y is inside the polygon, 0 otherwise. + + *xyverts* + a sequence of x,y vertices. + + A point on the boundary may be treated as inside or outside. + + .. deprecated:: 1.2.0 + Use :meth:`~matplotlib.path.Path.contains_point` instead. + """ + warnings.warn( + "nxutils is deprecated. Use matplotlib.path.Path.contains_point" + " instead.", + DeprecationWarning) + + p = path.Path(xyverts) + return p.contains_point(x, y) + +def points_inside_poly(xypoints, xyverts): + """ + mask = points_inside_poly(xypoints, xyverts) + + Returns a boolean ndarray, True for points inside the polygon. + + *xypoints* + a sequence of N x,y pairs. + + *xyverts* + sequence of x,y vertices of the polygon. + + A point on the boundary may be treated as inside or outside. + + .. deprecated:: 1.2.0 + Use :meth:`~matplotlib.path.Path.contains_points` instead. + """ + warnings.warn( + "nxutils is deprecated. Use matplotlib.path.Path.contains_points" + " instead.", + DeprecationWarning) + + p = path.Path(xyverts) + return p.contains_points(xypoints) diff -Nru matplotlib-1.1.1/lib/matplotlib/offsetbox.py matplotlib-1.2.0/lib/matplotlib/offsetbox.py --- matplotlib-1.1.1/lib/matplotlib/offsetbox.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/offsetbox.py 2012-10-31 00:11:14.000000000 +0000 @@ -15,6 +15,7 @@ """ +from __future__ import print_function import matplotlib.transforms as mtransforms import matplotlib.artist as martist import matplotlib.text as mtext @@ -35,7 +36,7 @@ from matplotlib.patches import bbox_artist as mbbox_artist -DEBUG=False +DEBUG = False # for debuging use def bbox_artist(*args, **kwargs): if DEBUG: @@ -63,7 +64,7 @@ # d_list is currently not used. if mode == "fixed": - offsets_ = np.add.accumulate([0]+[w + sep for w in w_list]) + offsets_ = np.add.accumulate([0] + [w + sep for w in w_list]) offsets = offsets_[:-1] if total is None: @@ -72,8 +73,8 @@ return total, offsets elif mode == "expand": - sep = (total - sum(w_list))/(len(w_list)-1.) - offsets_ = np.add.accumulate([0]+[w + sep for w in w_list]) + sep = (total - sum(w_list)) / (len(w_list) - 1.) + offsets_ = np.add.accumulate([0] + [w + sep for w in w_list]) offsets = offsets_[:-1] return total, offsets @@ -81,11 +82,11 @@ elif mode == "equal": maxh = max(w_list) if total is None: - total = (maxh+sep)*len(w_list) + total = (maxh + sep) * len(w_list) else: - sep = float(total)/(len(w_list)) - maxh + sep = float(total) / (len(w_list)) - maxh - offsets = np.array([(maxh+sep)*i for i in range(len(w_list))]) + offsets = np.array([(maxh + sep) * i for i in range(len(w_list))]) return total, offsets @@ -111,26 +112,25 @@ height = max([h for h, d in hd_list]) if align == "baseline": - height_descent = max([h-d for h, d in hd_list]) + height_descent = max([h - d for h, d in hd_list]) descent = max([d for h, d in hd_list]) height = height_descent + descent offsets = [0. for h, d in hd_list] - elif align in ["left","top"]: - descent=0. + elif align in ["left", "top"]: + descent = 0. offsets = [d for h, d in hd_list] - elif align in ["right","bottom"]: - descent=0. - offsets = [height-h+d for h, d in hd_list] + elif align in ["right", "bottom"]: + descent = 0. + offsets = [height - h + d for h, d in hd_list] elif align == "center": - descent=0. - offsets = [(height-h)*.5+d for h, d in hd_list] + descent = 0. + offsets = [(height - h) * .5 + d for h, d in hd_list] else: raise ValueError("Unknown Align mode : %s" % (align,)) return height, descent, offsets - class OffsetBox(martist.Artist): """ The OffsetBox is a simple container artist. The child artist are meant @@ -143,6 +143,24 @@ self._children = [] self._offset = (0, 0) + def __getstate__(self): + state = martist.Artist.__getstate__(self) + + # pickle cannot save instancemethods, so handle them here + from cbook import _InstanceMethodPickler + import inspect + + offset = state['_offset'] + if inspect.ismethod(offset): + state['_offset'] = _InstanceMethodPickler(offset) + return state + + def __setstate__(self, state): + self.__dict__ = state + from cbook import _InstanceMethodPickler + if isinstance(self._offset, _InstanceMethodPickler): + self._offset = self._offset.get_instancemethod() + def set_figure(self, fig): """ Set the figure @@ -223,7 +241,7 @@ ''' w, h, xd, yd, offsets = self.get_extent_offsets(renderer) px, py = self.get_offset(w, h, xd, yd, renderer) - return mtransforms.Bbox.from_bounds(px-xd, py-yd, w, h) + return mtransforms.Bbox.from_bounds(px - xd, py - yd, w, h) def draw(self, renderer): """ @@ -236,7 +254,7 @@ px, py = self.get_offset(width, height, xdescent, ydescent, renderer) for c, (ox, oy) in zip(self.get_visible_children(), offsets): - c.set_offset((px+ox, py+oy)) + c.set_offset((px + ox, py + oy)) c.draw(renderer) bbox_artist(self, renderer, fill=False, props=dict(pad=0.)) @@ -314,7 +332,7 @@ c.set_width(self.width) whd_list = [c.get_extent(renderer) for c in self.get_visible_children()] - whd_list = [(w, h, xd, (h-yd)) for w, h, xd, yd in whd_list] + whd_list = [(w, h, xd, (h - yd)) for w, h, xd, yd in whd_list] wd_list = [(w, xd) for w, h, xd, yd in whd_list] @@ -322,11 +340,11 @@ self.width, self.align) - pack_list = [(h, yd) for w,h,xd,yd in whd_list] + pack_list = [(h, yd) for w, h, xd, yd in whd_list] height, yoffsets_ = _get_packed_offsets(pack_list, self.height, sep, self.mode) - yoffsets = yoffsets_ + [yd for w,h,xd,yd in whd_list] + yoffsets = yoffsets_ + [yd for w, h, xd, yd in whd_list] ydescent = height - yoffsets[0] yoffsets = height - yoffsets @@ -334,15 +352,15 @@ yoffsets = yoffsets - ydescent - return width + 2*pad, height + 2*pad, \ - xdescent+pad, ydescent+pad, \ + return width + 2 * pad, height + 2 * pad, \ + xdescent + pad, ydescent + pad, \ zip(xoffsets, yoffsets) class HPacker(PackerBase): """ The HPacker has its children packed horizontally. It automatically - adjust the relative positions of children in the drawing time. + adjusts the relative positions of children at draw time. """ def __init__(self, pad=None, sep=None, width=None, height=None, align="baseline", mode="fixed", @@ -363,12 +381,10 @@ super(HPacker, self).__init__(pad, sep, width, height, align, mode, children) - def get_extent_offsets(self, renderer): """ update offset of children and return the extents of the box """ - dpicor = renderer.points_to_pixels(1.) pad = self.pad * dpicor sep = self.sep * dpicor @@ -376,37 +392,35 @@ whd_list = [c.get_extent(renderer) for c in self.get_visible_children()] if not whd_list: - return 2*pad, 2*pad, pad, pad, [] + return 2 * pad, 2 * pad, pad, pad, [] if self.height is None: - height_descent = max([h-yd for w,h,xd,yd in whd_list]) - ydescent = max([yd for w,h,xd,yd in whd_list]) + height_descent = max([h - yd for w, h, xd, yd in whd_list]) + ydescent = max([yd for w, h, xd, yd in whd_list]) height = height_descent + ydescent else: - height = self.height - 2*pad # width w/o pad + height = self.height - 2 * pad # width w/o pad hd_list = [(h, yd) for w, h, xd, yd in whd_list] height, ydescent, yoffsets = _get_aligned_offsets(hd_list, self.height, self.align) - - pack_list = [(w, xd) for w,h,xd,yd in whd_list] + pack_list = [(w, xd) for w, h, xd, yd in whd_list] + width, xoffsets_ = _get_packed_offsets(pack_list, self.width, sep, self.mode) - xoffsets = xoffsets_ + [xd for w,h,xd,yd in whd_list] + xoffsets = xoffsets_ + [xd for w, h, xd, yd in whd_list] - xdescent=whd_list[0][2] + xdescent = whd_list[0][2] xoffsets = xoffsets - xdescent - return width + 2*pad, height + 2*pad, \ + return width + 2 * pad, height + 2 * pad, \ xdescent + pad, ydescent + pad, \ zip(xoffsets, yoffsets) - - class PaddedBox(OffsetBox): def __init__(self, child, pad=None, draw_frame=False, patch_attrs=None): """ @@ -430,13 +444,12 @@ snap=True ) - self.patch.set_boxstyle("square",pad=0) + self.patch.set_boxstyle("square", pad=0) if patch_attrs is not None: self.patch.update(patch_attrs) - self._drawFrame = draw_frame - + self._drawFrame = draw_frame def get_extent_offsets(self, renderer): """ @@ -448,11 +461,10 @@ w, h, xd, yd = self._children[0].get_extent(renderer) - return w + 2*pad, h + 2*pad, \ - xd+pad, yd+pad, \ + return w + 2 * pad, h + 2 * pad, \ + xd + pad, yd + pad, \ [(0, 0)] - def draw(self, renderer): """ Update the location of children if necessary and draw them @@ -464,7 +476,7 @@ px, py = self.get_offset(width, height, xdescent, ydescent, renderer) for c, (ox, oy) in zip(self.get_visible_children(), offsets): - c.set_offset((px+ox, py+oy)) + c.set_offset((px + ox, py + oy)) self.draw_frame(renderer) @@ -516,8 +528,6 @@ self.dpi_transform = mtransforms.Affine2D() - - def get_transform(self): """ Return the :class:`~matplotlib.transforms.Transform` applied @@ -531,7 +541,6 @@ """ pass - def set_offset(self, xy): """ set offset of the container. @@ -543,22 +552,20 @@ self.offset_transform.clear() self.offset_transform.translate(xy[0], xy[1]) - def get_offset(self): """ return offset of the container. """ return self._offset - def get_window_extent(self, renderer): ''' get the bounding box in display space. ''' w, h, xd, yd = self.get_extent(renderer) ox, oy = self.get_offset() #w, h, xd, yd) - return mtransforms.Bbox.from_bounds(ox-xd, oy-yd, w, h) + return mtransforms.Bbox.from_bounds(ox - xd, oy - yd, w, h) def get_extent(self, renderer): """ @@ -566,10 +573,8 @@ """ dpi_cor = renderer.points_to_pixels(1.) - - return self.width*dpi_cor, self.height*dpi_cor, \ - self.xdescent*dpi_cor, self.ydescent*dpi_cor - + return self.width * dpi_cor, self.height * dpi_cor, \ + self.xdescent * dpi_cor, self.ydescent * dpi_cor def add_artist(self, a): 'Add any :class:`~matplotlib.artist.Artist` to the container box' @@ -577,7 +582,6 @@ if not a.is_transform_set(): a.set_transform(self.get_transform()) - def draw(self, renderer): """ Draw the children @@ -600,9 +604,6 @@ of the TextArea instance is the width and height of the its child text. """ - - - def __init__(self, s, textprops=None, multilinebaseline=None, @@ -619,8 +620,8 @@ if textprops is None: textprops = {} - if not textprops.has_key("va"): - textprops["va"]="baseline" + if "va" not in textprops: + textprops["va"] = "baseline" self._text = mtext.Text(0, 0, s, **textprops) @@ -633,12 +634,11 @@ self.offset_transform.clear() self.offset_transform.translate(0, 0) self._baseline_transform = mtransforms.Affine2D() - self._text.set_transform(self.offset_transform+self._baseline_transform) + self._text.set_transform(self.offset_transform + self._baseline_transform) self._multilinebaseline = multilinebaseline self._minimumdescent = minimumdescent - def set_text(self, s): "set text" self._text.set_text(s) @@ -657,14 +657,12 @@ """ self._multilinebaseline = t - def get_multilinebaseline(self): """ get multilinebaseline . """ return self._multilinebaseline - def set_minimumdescent(self, t): """ Set minimumdescent . @@ -674,48 +672,42 @@ """ self._minimumdescent = t - def get_minimumdescent(self): """ get minimumdescent. """ return self._minimumdescent - def set_transform(self, t): """ set_transform is ignored. """ pass - def set_offset(self, xy): """ set offset of the container. - Accept : tuple of x,y cooridnate in disokay units. + Accept : tuple of x,y coordinates in display units. """ self._offset = xy self.offset_transform.clear() self.offset_transform.translate(xy[0], xy[1]) - def get_offset(self): """ return offset of the container. """ return self._offset - def get_window_extent(self, renderer): ''' get the bounding box in display space. ''' w, h, xd, yd = self.get_extent(renderer) ox, oy = self.get_offset() #w, h, xd, yd) - return mtransforms.Bbox.from_bounds(ox-xd, oy-yd, w, h) - + return mtransforms.Bbox.from_bounds(ox - xd, oy - yd, w, h) def get_extent(self, renderer): clean_line, ismath = self._text.is_math_text(self._text._text) @@ -732,15 +724,14 @@ self._baseline_transform.clear() - if len(info) > 1 and self._multilinebaseline: - d_new = 0.5 * h - 0.5 * (h_ - d_) + d_new = 0.5 * h - 0.5 * (h_ - d_) self._baseline_transform.translate(0, d - d_new) d = d_new else: # single line - h_d = max(h_ - d_, h-d) + h_d = max(h_ - d_, h - d) if self.get_minimumdescent(): ## to have a minimum descent, #i.e., "l" and "p" have same @@ -753,7 +744,6 @@ return w, h, 0., d - def draw(self, renderer): """ Draw the children @@ -764,7 +754,6 @@ bbox_artist(self, renderer, fill=False, props=dict(pad=0.)) - class AuxTransformBox(OffsetBox): """ Offset Box with the aux_transform . Its children will be @@ -779,7 +768,6 @@ children. Furthermore, the extent of the children will be calculated in the transformed coordinate. """ - def __init__(self, aux_transform): self.aux_transform = aux_transform OffsetBox.__init__(self) @@ -804,7 +792,6 @@ Return the :class:`~matplotlib.transforms.Transform` applied to the children """ - return self.aux_transform + \ self.ref_offset_transform + \ self.offset_transform @@ -815,7 +802,6 @@ """ pass - def set_offset(self, xy): """ set offset of the container. @@ -827,22 +813,19 @@ self.offset_transform.clear() self.offset_transform.translate(xy[0], xy[1]) - def get_offset(self): """ return offset of the container. """ return self._offset - def get_window_extent(self, renderer): ''' get the bounding box in display space. ''' w, h, xd, yd = self.get_extent(renderer) ox, oy = self.get_offset() #w, h, xd, yd) - return mtransforms.Bbox.from_bounds(ox-xd, oy-yd, w, h) - + return mtransforms.Bbox.from_bounds(ox - xd, oy - yd, w, h) def get_extent(self, renderer): @@ -855,7 +838,6 @@ bboxes = [c.get_window_extent(renderer) for c in self._children] ub = mtransforms.Bbox.union(bboxes) - # adjust ref_offset_tansform self.ref_offset_transform.translate(-ub.x0, -ub.y0) @@ -865,7 +847,6 @@ return ub.width, ub.height, 0., 0. - def draw(self, renderer): """ Draw the children @@ -877,7 +858,6 @@ bbox_artist(self, renderer, fill=False, props=dict(pad=0.)) - class AnchoredOffsetbox(OffsetBox): """ An offset box placed according to the legend location @@ -886,7 +866,6 @@ the offset box is anchored against its parent axes. You may explicitly specify the bbox_to_anchor. """ - zorder = 5 # zorder of the legend def __init__(self, loc, @@ -926,20 +905,19 @@ bbox_transform : with which the bbox_to_anchor will be transformed. """ - super(AnchoredOffsetbox, self).__init__(**kwargs) self.set_bbox_to_anchor(bbox_to_anchor, bbox_transform) self.set_child(child) self.loc = loc - self.borderpad=borderpad + self.borderpad = borderpad self.pad = pad if prop is None: - self.prop=FontProperties(size=rcParams["legend.fontsize"]) + self.prop = FontProperties(size=rcParams["legend.fontsize"]) elif isinstance(prop, dict): - self.prop=FontProperties(**prop) + self.prop = FontProperties(**prop) if "size" not in prop: self.prop.set_size(rcParams["legend.fontsize"]) else: @@ -951,11 +929,8 @@ mutation_scale=self.prop.get_size_in_points(), snap=True ) - self.patch.set_boxstyle("square",pad=0) - self._drawFrame = frameon - - - + self.patch.set_boxstyle("square", pad=0) + self._drawFrame = frameon def set_child(self, child): "set the child to be anchored" @@ -969,18 +944,16 @@ "return the list of children" return [self._child] - def get_extent(self, renderer): """ return the extent of the artist. The extent of the child added with the pad is returned """ - w, h, xd, yd = self.get_child().get_extent(renderer) + w, h, xd, yd = self.get_child().get_extent(renderer) fontsize = renderer.points_to_pixels(self.prop.get_size_in_points()) pad = self.pad * fontsize - return w+2*pad, h+2*pad, xd+pad, yd+pad - + return w + 2 * pad, h + 2 * pad, xd + pad, yd + pad def get_bbox_to_anchor(self): """ @@ -996,9 +969,6 @@ return TransformedBbox(self._bbox_to_anchor, transform) - - - def set_bbox_to_anchor(self, bbox, transform=None): """ set the bbox that the child will be anchored. @@ -1023,7 +993,6 @@ self._bbox_to_anchor_transform = transform - def get_window_extent(self, renderer): ''' get the bounding box in display space. @@ -1031,8 +1000,7 @@ self._update_offset_func(renderer) w, h, xd, yd = self.get_extent(renderer) ox, oy = self.get_offset(w, h, xd, yd, renderer) - return Bbox.from_bounds(ox-xd, oy-yd, w, h) - + return Bbox.from_bounds(ox - xd, oy - yd, w, h) def _update_offset_func(self, renderer, fontsize=None): """ @@ -1044,18 +1012,17 @@ def _offset(w, h, xd, yd, renderer, fontsize=fontsize, self=self): bbox = Bbox.from_bounds(0, 0, w, h) - borderpad = self.borderpad*fontsize + borderpad = self.borderpad * fontsize bbox_to_anchor = self.get_bbox_to_anchor() x0, y0 = self._get_anchored_bbox(self.loc, bbox, bbox_to_anchor, borderpad) - return x0+xd, y0+yd + return x0 + xd, y0 + yd self.set_offset(_offset) - def update_frame(self, bbox, fontsize=None): self.patch.set_bounds(bbox.x0, bbox.y0, bbox.width, bbox.height) @@ -1085,18 +1052,16 @@ self.get_child().set_offset((px, py)) self.get_child().draw(renderer) - - def _get_anchored_bbox(self, loc, bbox, parentbbox, borderpad): """ return the position of the bbox anchored at the parentbbox with the loc code, with the borderpad. """ - assert loc in range(1,11) # called only internally + assert loc in range(1, 11) # called only internally BEST, UR, UL, LL, LR, R, CL, CR, LC, UC, C = range(11) - anchor_coefs={UR:"NE", + anchor_coefs = {UR:"NE", UL:"NW", LL:"SW", LR:"SE", @@ -1140,17 +1105,16 @@ **kwargs) - class OffsetImage(OffsetBox): def __init__(self, arr, zoom=1, - cmap = None, - norm = None, + cmap=None, + norm=None, interpolation=None, origin=None, filternorm=1, filterrad=4.0, - resample = False, + resample=False, dpi_cor=True, **kwargs ): @@ -1158,13 +1122,13 @@ self._dpi_cor = dpi_cor self.image = BboxImage(bbox=self.get_window_extent, - cmap = cmap, - norm = norm, + cmap=cmap, + norm=norm, interpolation=interpolation, origin=origin, filternorm=filternorm, filterrad=filterrad, - resample = resample, + resample=resample, **kwargs ) @@ -1175,7 +1139,6 @@ OffsetBox.__init__(self) - def set_data(self, arr): self._data = np.asarray(arr) self.image.set_data(self._data) @@ -1204,8 +1167,6 @@ # self.offset_transform.clear() # self.offset_transform.translate(xy[0], xy[1]) - - def get_offset(self): """ return offset of the container. @@ -1221,8 +1182,7 @@ ''' w, h, xd, yd = self.get_extent(renderer) ox, oy = self.get_offset() - return mtransforms.Bbox.from_bounds(ox-xd, oy-yd, w, h) - + return mtransforms.Bbox.from_bounds(ox - xd, oy - yd, w, h) def get_extent(self, renderer): @@ -1234,34 +1194,29 @@ zoom = self.get_zoom() data = self.get_data() ny, nx = data.shape[:2] - w, h = nx*zoom, ny*zoom + w, h = nx * zoom, ny * zoom return w, h, 0, 0 - - def draw(self, renderer): """ Draw the children """ - self.image.draw(renderer) - #bbox_artist(self, renderer, fill=False, props=dict(pad=0.)) - from matplotlib.text import _AnnotationBase + class AnnotationBbox(martist.Artist, _AnnotationBase): """ Annotation-like class, but with offsetbox instead of Text. """ - zorder = 3 def __str__(self): - return "AnnotationBbox(%g,%g)"%(self.xy[0],self.xy[1]) + return "AnnotationBbox(%g,%g)" % (self.xy[0], self.xy[1]) @docstring.dedent_interpd def __init__(self, offsetbox, xy, xybox=None, @@ -1299,7 +1254,7 @@ if arrowprops is not None: self._arrow_relpos = self.arrowprops.pop("relpos", (0.5, 0.5)) - self.arrow_patch = FancyArrowPatch((0, 0), (1,1), + self.arrow_patch = FancyArrowPatch((0, 0), (1, 1), **self.arrowprops) else: self._arrow_relpos = None @@ -1322,22 +1277,20 @@ mutation_scale=self.prop.get_size_in_points(), snap=True ) - self.patch.set_boxstyle("square",pad=pad) + self.patch.set_boxstyle("square", pad=pad) if bboxprops: self.patch.set(**bboxprops) - self._drawFrame = frameon + self._drawFrame = frameon - - def contains(self,event): - t,tinfo = self.offsetbox.contains(event) + def contains(self, event): + t, tinfo = self.offsetbox.contains(event) #if self.arrow_patch is not None: # a,ainfo=self.arrow_patch.contains(event) # t = t or a # self.arrow_patch is currently not checked as this can be a line - JJ - return t,tinfo - + return t, tinfo def get_children(self): children = [self.offsetbox, self.patch] @@ -1359,7 +1312,7 @@ if s is None: s = rcParams["legend.fontsize"] - self.prop=FontProperties(size=s) + self.prop = FontProperties(size=s) def get_fontsize(self, s=None): """ @@ -1378,7 +1331,6 @@ if self.arrow_patch: self.arrow_patch.set_mutation_scale(mutation_scale) - def _update_position_xybox(self, renderer, xy_pixel): "Update the pixel positions of the annotation text and the arrow patch." @@ -1394,7 +1346,7 @@ w, h, xd, yd = self.offsetbox.get_extent(renderer) _fw, _fh = self._box_alignment - self.offsetbox.set_offset((ox0-_fw*w+xd, oy0-_fh*h+yd)) + self.offsetbox.set_offset((ox0 - _fw * w + xd, oy0 - _fh * h + yd)) # update patch position bbox = self.offsetbox.get_window_extent(renderer) @@ -1427,7 +1379,7 @@ # (in points). If patch A is not set, self.bbox_patch # is used. - self.arrow_patch.set_positions((ox0, oy0), (ox1,oy1)) + self.arrow_patch.set_positions((ox0, oy0), (ox1, oy1)) fs = self.prop.get_size_in_points() mutation_scale = d.pop("mutation_scale", fs) mutation_scale = renderer.points_to_pixels(mutation_scale) @@ -1436,8 +1388,6 @@ patchA = d.pop("patchA", self.patch) self.arrow_patch.set_patchA(patchA) - - def draw(self, renderer): """ Draw the :class:`Annotation` object to the given *renderer*. @@ -1465,7 +1415,6 @@ self.offsetbox.draw(renderer) - class DraggableBase(object): """ helper code for a draggable artist (legend, offsetbox) @@ -1591,11 +1540,11 @@ def get_loc_in_canvas(self): - offsetbox=self.offsetbox + offsetbox = self.offsetbox renderer = offsetbox.figure._cachedRenderer w, h, xd, yd = offsetbox.get_extent(renderer) ox, oy = offsetbox._offset - loc_in_canvas = (ox-xd, oy-yd) + loc_in_canvas = (ox - xd, oy - yd) return loc_in_canvas @@ -1634,7 +1583,7 @@ if __name__ == "__main__": - + import matplotlib.pyplot as plt fig = plt.figure(1) fig.clf() ax = plt.subplot(121) @@ -1642,10 +1591,10 @@ #txt = ax.text(0.5, 0.5, "Test", size=30, ha="center", color="w") kwargs = dict() - a = np.arange(256).reshape(16,16)/256. + a = np.arange(256).reshape(16, 16) / 256. myimage = OffsetImage(a, zoom=2, - norm = None, + norm=None, origin=None, **kwargs ) @@ -1656,7 +1605,7 @@ myimage2 = OffsetImage(a, zoom=2, - norm = None, + norm=None, origin=None, **kwargs ) @@ -1664,14 +1613,13 @@ xybox=(30, 30), xycoords='data', boxcoords="offset points", - frameon=True, pad=0.4, # BboxPatch + frameon=True, pad=0.4, # BboxPatch bboxprops=dict(boxstyle="round", fc="y"), fontsize=None, arrowprops=dict(arrowstyle="->"), ) ax.add_artist(ann) - + plt.draw() plt.show() - diff -Nru matplotlib-1.1.1/lib/matplotlib/patches.py matplotlib-1.2.0/lib/matplotlib/patches.py --- matplotlib-1.1.1/lib/matplotlib/patches.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/patches.py 2012-11-06 15:42:20.000000000 +0000 @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from __future__ import division +from __future__ import division, print_function import math import matplotlib as mpl @@ -16,7 +16,7 @@ # these are not available for the object inspector until after the # class is built so we define an initial set here for the init # function and they will be overridden after object definition -docstring.interpd.update(Patch = """ +docstring.interpd.update(Patch=""" ================= ============================================== Property Description @@ -41,6 +41,7 @@ """) + class Patch(artist.Artist): """ A patch is a 2D artist with a face color and an edge color. @@ -49,6 +50,7 @@ are *None*, they default to their rc params setting. """ zorder = 1 + def __str__(self): return str(self.__class__).split('.')[-1] @@ -58,12 +60,11 @@ color=None, linewidth=None, linestyle=None, - antialiased = None, - hatch = None, + antialiased=None, + hatch=None, fill=True, - path_effects = None, - **kwargs - ): + path_effects=None, + **kwargs): """ The following kwarg properties are supported @@ -71,11 +72,14 @@ """ artist.Artist.__init__(self) - if linewidth is None: linewidth = mpl.rcParams['patch.linewidth'] - if linestyle is None: linestyle = "solid" - if antialiased is None: antialiased = mpl.rcParams['patch.antialiased'] + if linewidth is None: + linewidth = mpl.rcParams['patch.linewidth'] + if linestyle is None: + linestyle = "solid" + if antialiased is None: + antialiased = mpl.rcParams['patch.antialiased'] - self._fill = True # needed for set_facecolor call + self._fill = True # needed for set_facecolor call if color is not None: if (edgecolor is not None or facecolor is not None): @@ -95,7 +99,8 @@ self.set_path_effects(path_effects) - if len(kwargs): artist.setp(self, **kwargs) + if len(kwargs): + artist.setp(self, **kwargs) def get_verts(self): """ @@ -121,7 +126,8 @@ # patch with a path. However, patches that have a faster # algebraic solution to hit-testing should override this # method. - if callable(self._contains): return self._contains(self,mouseevent) + if callable(self._contains): + return self._contains(self, mouseevent) if radius is None: radius = self.get_linewidth() inside = self.get_path().contains_point( @@ -135,7 +141,9 @@ """ if radius is None: radius = self.get_linewidth() - return self.get_path().contains_point(point, self.get_transform(), radius) + return self.get_path().contains_point(point, + self.get_transform(), + radius) def update_from(self, other): """ @@ -167,9 +175,21 @@ return self.get_patch_transform() + artist.Artist.get_transform(self) def get_data_transform(self): + """ + Return the :class:`~matplotlib.transforms.Transform` instance which + maps data coordinates to physical coordinates. + """ return artist.Artist.get_transform(self) def get_patch_transform(self): + """ + Return the :class:`~matplotlib.transforms.Transform` instance which + takes patch coordinates to data coordinates. + + For example, one may define a patch of a circle which represents a + radius of 5 by providing coordinates for a unit circle, and a + transform which scales the coordinates (the patch coordinate) by 5. + """ return transforms.IdentityTransform() def get_antialiased(self): @@ -214,7 +234,8 @@ ACCEPTS: [True | False] or None for default """ - if aa is None: aa = mpl.rcParams['patch.antialiased'] + if aa is None: + aa = mpl.rcParams['patch.antialiased'] self._antialiased = aa def set_aa(self, aa): @@ -227,7 +248,8 @@ ACCEPTS: mpl color spec, or None for default, or 'none' for no color """ - if color is None: color = mpl.rcParams['patch.edgecolor'] + if color is None: + color = mpl.rcParams['patch.edgecolor'] self._edgecolor = colors.colorConverter.to_rgba(color, self._alpha) def set_ec(self, color): @@ -240,9 +262,10 @@ ACCEPTS: mpl color spec, or None for default, or 'none' for no color """ - if color is None: color = mpl.rcParams['patch.facecolor'] - self._original_facecolor = color # save: otherwise changing _fill - # may lose alpha information + if color is None: + color = mpl.rcParams['patch.facecolor'] + self._original_facecolor = color # save: otherwise changing _fill + # may lose alpha information self._facecolor = colors.colorConverter.to_rgba(color, self._alpha) if not self._fill: self._facecolor = list(self._facecolor) @@ -278,7 +301,8 @@ except TypeError: raise TypeError('alpha must be a float or None') artist.Artist.set_alpha(self, alpha) - self.set_facecolor(self._original_facecolor) # using self._fill and self._alpha + self.set_facecolor(self._original_facecolor) # using self._fill and + # self._alpha self._edgecolor = colors.colorConverter.to_rgba( self._edgecolor[:3], self._alpha) @@ -288,7 +312,8 @@ ACCEPTS: float or None for default """ - if w is None: w = mpl.rcParams['patch.linewidth'] + if w is None: + w = mpl.rcParams['patch.linewidth'] self._linewidth = w def set_lw(self, lw): @@ -301,7 +326,8 @@ ACCEPTS: ['solid' | 'dashed' | 'dashdot' | 'dotted'] """ - if ls is None: ls = "solid" + if ls is None: + ls = "solid" self._linestyle = ls def set_ls(self, ls): @@ -371,7 +397,8 @@ @allow_rasterization def draw(self, renderer): 'Draw the :class:`Patch` to the given *renderer*.' - if not self.get_visible(): return + if not self.get_visible(): + return renderer.open_group('patch', self.get_gid()) gc = renderer.new_gc() @@ -392,14 +419,14 @@ rgbFace = self._facecolor if rgbFace[3] == 0: - rgbFace = None # (some?) renderers expect this as no-fill signal + rgbFace = None # (some?) renderers expect this as no-fill signal gc.set_alpha(self._edgecolor[3]) if self._edgecolor[3] == 0: gc.set_alpha(self._facecolor[3]) if self._hatch: - gc.set_hatch(self._hatch ) + gc.set_hatch(self._hatch) path = self.get_path() transform = self.get_transform() @@ -424,18 +451,20 @@ def get_window_extent(self, renderer=None): return self.get_path().get_extents(self.get_transform()) + patchdoc = artist.kwdoc(Patch) for k in ('Rectangle', 'Circle', 'RegularPolygon', 'Polygon', 'Wedge', 'Arrow', 'FancyArrow', 'YAArrow', 'CirclePolygon', 'Ellipse', 'Arc', 'FancyBboxPatch', 'Patch'): - docstring.interpd.update({k:patchdoc}) + docstring.interpd.update({k: patchdoc}) # define Patch.__init__ docstring after the class has been added to interpd -docstring.dedent_interpd(Patch.__init__.im_func) +docstring.dedent_interpd(Patch.__init__) + class Shadow(Patch): def __str__(self): - return "Shadow(%s)"%(str(self.patch)) + return "Shadow(%s)" % (str(self.patch)) @docstring.dedent_interpd def __init__(self, patch, ox, oy, props=None, **kwargs): @@ -460,14 +489,15 @@ if self.props is not None: self.update(self.props) else: - r,g,b,a = colors.colorConverter.to_rgba(self.patch.get_facecolor()) + r, g, b, a = colors.colorConverter.to_rgba( + self.patch.get_facecolor()) rho = 0.3 - r = rho*r - g = rho*g - b = rho*b + r = rho * r + g = rho * g + b = rho * b - self.set_facecolor((r,g,b,0.5)) - self.set_edgecolor((r,g,b,0.5)) + self.set_facecolor((r, g, b, 0.5)) + self.set_edgecolor((r, g, b, 0.5)) self.set_alpha(0.5) def _update_transform(self, renderer): @@ -477,11 +507,13 @@ def _get_ox(self): return self._ox + def _set_ox(self, ox): self._ox = ox def _get_oy(self): return self._oy + def _set_oy(self, oy): self._oy = oy @@ -495,6 +527,7 @@ self._update_transform(renderer) Patch.draw(self, renderer) + class Rectangle(Patch): """ Draw a rectangle with lower left at *xy* = (*x*, *y*) with @@ -549,7 +582,7 @@ def contains(self, mouseevent): # special case the degenerate rectangle - if self._width==0 or self._height==0: + if self._width == 0 or self._height == 0: return False, {} x, y = self.get_transform().inverted().transform_point( @@ -622,26 +655,28 @@ ACCEPTS: (left, bottom, width, height) """ - if len(args)==0: - l,b,w,h = args[0] + if len(args) == 0: + l, b, w, h = args[0] else: - l,b,w,h = args + l, b, w, h = args self._x = l self._y = b self._width = w self._height = h def get_bbox(self): - return transforms.Bbox.from_bounds(self._x, self._y, self._width, self._height) + return transforms.Bbox.from_bounds(self._x, self._y, + self._width, self._height) xy = property(get_xy, set_xy) + class RegularPolygon(Patch): """ A regular polygon patch. """ def __str__(self): - return "Poly%d(%g,%g)"%(self._numVertices,self._xy[0],self._xy[1]) + return "Poly%d(%g,%g)" % (self._numVertices, self._xy[0], self._xy[1]) @docstring.dedent_interpd def __init__(self, xy, numVertices, radius=5, orientation=0, @@ -682,6 +717,7 @@ def _get_xy(self): return self._xy + def _set_xy(self, xy): self._xy = xy self._update_transform() @@ -689,6 +725,7 @@ def _get_orientation(self): return self._orientation + def _set_orientation(self, orientation): self._orientation = orientation self._update_transform() @@ -696,6 +733,7 @@ def _get_radius(self): return self._radius + def _set_radius(self, radius): self._radius = radius self._update_transform() @@ -703,8 +741,10 @@ def _get_numvertices(self): return self._numVertices + def _set_numvertices(self, numVertices): self._numVertices = numVertices + numvertices = property(_get_numvertices, _set_numvertices) def get_path(self): @@ -714,6 +754,7 @@ self._update_transform() return self._poly_transform + class PathPatch(Patch): """ A general polycurve path patch. @@ -741,6 +782,7 @@ def get_path(self): return self._path + class Polygon(Patch): """ A general polygon patch. @@ -766,14 +808,8 @@ """ Patch.__init__(self, **kwargs) - xy = np.asarray(xy, np.float_) - self._path = Path(xy) - self._closed = closed - if closed and len(xy): - xy = np.concatenate([xy, [xy[0]]]) - - self._set_xy(xy) + self.set_xy(xy) def get_path(self): return self._path @@ -782,24 +818,24 @@ return self._closed def set_closed(self, closed): - if self._closed == bool(closed): return + self._closed = bool(closed) + self.set_xy(self.get_xy()) - self._closed = closed - xy = self._get_xy() - if closed: + def get_xy(self): + return self._path.vertices + + def set_xy(self, xy): + xy = np.asarray(xy) + if self._closed: if len(xy) and (xy[0] != xy[-1]).any(): xy = np.concatenate([xy, [xy[0]]]) else: - if len(xy)>2 and (xy[0]==xy[-1]).all(): - xy = xy[0:-1] - self._set_xy(xy) + if len(xy) > 2 and (xy[0] == xy[-1]).all(): + xy = xy[:-1] + self._path = Path(xy, closed=self._closed) - def get_xy(self): - return self._path.vertices - def set_xy(self, vertices): - self._path = Path(vertices, closed=self._closed) _get_xy = get_xy _set_xy = set_xy xy = property( @@ -810,12 +846,13 @@ :meth:`~matplotlib.patches.Polygon.get_xy` and :meth:`~matplotlib.patches.Polygon.set_xy` instead.""") + class Wedge(Patch): """ Wedge shaped patch. """ def __str__(self): - return "Wedge(%g,%g)"%(self.theta1,self.theta2) + return "Wedge(%g,%g)" % (self.theta1, self.theta2) @docstring.dedent_interpd def __init__(self, center, r, theta1, theta2, width=None, **kwargs): @@ -831,37 +868,37 @@ """ Patch.__init__(self, **kwargs) self.center = center - self.r,self.width = r,width - self.theta1,self.theta2 = theta1,theta2 + self.r, self.width = r, width + self.theta1, self.theta2 = theta1, theta2 # Inner and outer rings are connected unless the annulus is complete - delta=theta2-theta1 - if abs((theta2-theta1) - 360) <= 1e-12: - theta1,theta2 = 0,360 + delta = theta2 - theta1 + if abs((theta2 - theta1) - 360) <= 1e-12: + theta1, theta2 = 0, 360 connector = Path.MOVETO else: connector = Path.LINETO # Form the outer ring - arc = Path.arc(theta1,theta2) + arc = Path.arc(theta1, theta2) if width is not None: # Partial annulus needs to draw the outter ring # followed by a reversed and scaled inner ring v1 = arc.vertices - v2 = arc.vertices[::-1]*float(r-width)/r - v = np.vstack([v1,v2,v1[0,:],(0,0)]) - c = np.hstack([arc.codes,arc.codes,connector,Path.CLOSEPOLY]) - c[len(arc.codes)]=connector + v2 = arc.vertices[::-1] * float(r - width) / r + v = np.vstack([v1, v2, v1[0, :], (0, 0)]) + c = np.hstack([arc.codes, arc.codes, connector, Path.CLOSEPOLY]) + c[len(arc.codes)] = connector else: # Wedge doesn't need an inner ring - v = np.vstack([arc.vertices,[(0,0),arc.vertices[0,:],(0,0)]]) - c = np.hstack([arc.codes,[connector,connector,Path.CLOSEPOLY]]) + v = np.vstack([arc.vertices, [(0, 0), arc.vertices[0, :], (0, 0)]]) + c = np.hstack([arc.codes, [connector, connector, Path.CLOSEPOLY]]) # Shift and scale the wedge to the final location. v *= r v += np.asarray(center) - self._path = Path(v,c) + self._path = Path(v, c) self._patch_transform = transforms.IdentityTransform() def get_path(self): @@ -876,15 +913,15 @@ def __str__(self): return "Arrow()" - _path = Path( [ - [ 0.0, 0.1 ], [ 0.0, -0.1], - [ 0.8, -0.1 ], [ 0.8, -0.3], - [ 1.0, 0.0 ], [ 0.8, 0.3], - [ 0.8, 0.1 ], [ 0.0, 0.1] ], + _path = Path([ + [0.0, 0.1], [0.0, -0.1], + [0.8, -0.1], [0.8, -0.3], + [1.0, 0.0], [0.8, 0.3], + [0.8, 0.1], [0.0, 0.1]], closed=True) @docstring.dedent_interpd - def __init__( self, x, y, dx, dy, width=1.0, **kwargs ): + def __init__(self, x, y, dx, dy, width=1.0, **kwargs): """ Draws an arrow, starting at (*x*, *y*), direction and length given by (*dx*, *dy*) the width of the arrow is scaled by *width*. @@ -893,9 +930,9 @@ %(Patch)s """ Patch.__init__(self, **kwargs) - L = np.sqrt(dx**2+dy**2) or 1 # account for div by zero - cx = float(dx)/L - sx = float(dy)/L + L = np.sqrt(dx ** 2 + dy ** 2) or 1 # account for div by zero + cx = float(dx) / L + sx = float(dy) / L trans1 = transforms.Affine2D().scale(L, width) trans2 = transforms.Affine2D.from_values(cx, sx, -sx, cx, 0.0, 0.0) @@ -909,6 +946,7 @@ def get_patch_transform(self): return self._patch_transform + class FancyArrow(Polygon): """ Like Arrow, but lets you set head width and head height independently. @@ -920,24 +958,33 @@ @docstring.dedent_interpd def __init__(self, x, y, dx, dy, width=0.001, length_includes_head=False, \ head_width=None, head_length=None, shape='full', overhang=0, \ - head_starts_at_zero=False,**kwargs): + head_starts_at_zero=False, **kwargs): """ Constructor arguments + *width*: float (default: 0.001) + width of full arrow tail - *length_includes_head*: - *True* if head is counted in calculating the length. + *length_includes_head*: [True | False] (default: False) + True if head is to be counted in calculating the length. - *shape*: ['full', 'left', 'right'] + *head_width*: float or None (default: 3*width) + total width of the full arrow head - *overhang*: - distance that the arrow is swept back (0 overhang means - triangular shape). - - *head_starts_at_zero*: - If *True*, the head starts being drawn at coordinate 0 - instead of ending at coordinate 0. + *head_length*: float or None (default: 1.5 * head_width) + length of arrow head - Valid kwargs are: + *shape*: ['full', 'left', 'right'] (default: 'full') + draw the left-half, right-half, or full arrow + + *overhang*: float (default: 0) + fraction that the arrow is swept back (0 overhang means + triangular shape). Can be negative or greater than one. + + *head_starts_at_zero*: [True | False] (default: False) + if True, the head starts being drawn at coordinate 0 + instead of ending at coordinate 0. + + Other valid kwargs (inherited from :class:`Patch`) are: %(Patch)s """ @@ -946,21 +993,21 @@ if head_length is None: head_length = 1.5 * head_width - distance = np.sqrt(dx**2 + dy**2) + distance = np.sqrt(dx ** 2 + dy ** 2) if length_includes_head: - length=distance + length = distance else: - length=distance+head_length + length = distance + head_length if not length: - verts = [] #display nothing if empty + verts = [] # display nothing if empty else: - #start by drawing horizontal arrow, point at (0,0) + # start by drawing horizontal arrow, point at (0,0) hw, hl, hs, lw = head_width, head_length, overhang, width left_half_arrow = np.array([ - [0.0,0.0], #tip - [-hl, -hw/2.0], #leftmost - [-hl*(1-hs), -lw/2.0], #meets stem - [-length, -lw/2.0], #bottom left + [0.0, 0.0], # tip + [-hl, -hw / 2.0], # leftmost + [-hl * (1 - hs), -lw / 2.0], # meets stem + [-length, -lw / 2.0], # bottom left [-length, 0], ]) #if we're not including the head, shift up by head length @@ -968,30 +1015,34 @@ left_half_arrow += [head_length, 0] #if the head starts at 0, shift up by another head length if head_starts_at_zero: - left_half_arrow += [head_length/2.0, 0] + left_half_arrow += [head_length / 2.0, 0] #figure out the shape, and complete accordingly if shape == 'left': coords = left_half_arrow else: - right_half_arrow = left_half_arrow*[1,-1] + right_half_arrow = left_half_arrow * [1, -1] if shape == 'right': coords = right_half_arrow elif shape == 'full': # The half-arrows contain the midpoint of the stem, # which we can omit from the full arrow. Including it # twice caused a problem with xpdf. - coords=np.concatenate([left_half_arrow[:-1], - right_half_arrow[-2::-1]]) + coords = np.concatenate([left_half_arrow[:-1], + right_half_arrow[-2::-1]]) else: - raise ValueError, "Got unknown shape: %s" % shape - cx = float(dx)/distance - sx = float(dy)/distance - M = np.array([[cx, sx],[-sx,cx]]) - verts = np.dot(coords, M) + (x+dx, y+dy) + raise ValueError("Got unknown shape: %s" % shape) + cx = float(dx) / distance + sx = float(dy) / distance + M = np.array([[cx, sx], [-sx, cx]]) + verts = np.dot(coords, M) + (x + dx, y + dy) Polygon.__init__(self, map(tuple, verts), closed=True, **kwargs) -docstring.interpd.update({"FancyArrow":FancyArrow.__init__.__doc__}) + +docstring.interpd.update({"FancyArrow": FancyArrow.__init__.__doc__}) + +docstring.interpd.update({"FancyArrow": FancyArrow.__init__.__doc__}) + class YAArrow(Patch): """ @@ -1004,7 +1055,8 @@ return "YAArrow()" @docstring.dedent_interpd - def __init__(self, figure, xytip, xybase, width=4, frac=0.1, headwidth=12, **kwargs): + def __init__(self, figure, xytip, xybase, + width=4, frac=0.1, headwidth=12, **kwargs): """ Constructor arguments: @@ -1037,7 +1089,8 @@ self.frac = frac self.headwidth = headwidth Patch.__init__(self, **kwargs) - # Set self.figure after Patch.__init__, since it sets self.figure to None + # Set self.figure after Patch.__init__, since it sets self.figure to + # None self.figure = figure def get_path(self): @@ -1047,13 +1100,13 @@ # the base vertices x1, y1 = self.xytip x2, y2 = self.xybase - k1 = self.width*self.figure.dpi/72./2. - k2 = self.headwidth*self.figure.dpi/72./2. + k1 = self.width * self.figure.dpi / 72. / 2. + k2 = self.headwidth * self.figure.dpi / 72. / 2. xb1, yb1, xb2, yb2 = self.getpoints(x1, y1, x2, y2, k1) # a point on the segment 20% of the distance from the tip to the base - theta = math.atan2(y2-y1, x2-x1) - r = math.sqrt((y2-y1)**2. + (x2-x1)**2.) + theta = math.atan2(y2 - y1, x2 - x1) + r = math.sqrt((y2 - y1) ** 2. + (x2 - x1) ** 2.) xm = x1 + self.frac * r * math.cos(theta) ym = y1 + self.frac * r * math.sin(theta) xc1, yc1, xc2, yc2 = self.getpoints(x1, y1, xm, ym, k1) @@ -1067,31 +1120,31 @@ def get_patch_transform(self): return transforms.IdentityTransform() - def getpoints(self, x1,y1,x2,y2, k): + def getpoints(self, x1, y1, x2, y2, k): """ For line segment defined by (*x1*, *y1*) and (*x2*, *y2*) return the points on the line that is perpendicular to the line and intersects (*x2*, *y2*) and the distance from (*x2*, *y2*) of the returned points is *k*. """ - x1,y1,x2,y2,k = map(float, (x1,y1,x2,y2,k)) + x1, y1, x2, y2, k = map(float, (x1, y1, x2, y2, k)) - if y2-y1 == 0: - return x2, y2+k, x2, y2-k - elif x2-x1 == 0: - return x2+k, y2, x2-k, y2 + if y2 - y1 == 0: + return x2, y2 + k, x2, y2 - k + elif x2 - x1 == 0: + return x2 + k, y2, x2 - k, y2 - m = (y2-y1)/(x2-x1) - pm = -1./m + m = (y2 - y1) / (x2 - x1) + pm = -1. / m a = 1 - b = -2*y2 - c = y2**2. - k**2.*pm**2./(1. + pm**2.) + b = -2 * y2 + c = y2 ** 2. - k ** 2. * pm ** 2. / (1. + pm ** 2.) - y3a = (-b + math.sqrt(b**2.-4*a*c))/(2.*a) - x3a = (y3a - y2)/pm + x2 + y3a = (-b + math.sqrt(b ** 2. - 4 * a * c)) / (2. * a) + x3a = (y3a - y2) / pm + x2 - y3b = (-b - math.sqrt(b**2.-4*a*c))/(2.*a) - x3b = (y3b - y2)/pm + x2 + y3b = (-b - math.sqrt(b ** 2. - 4 * a * c)) / (2. * a) + x3b = (y3b - y2) / pm + x2 return x3a, y3a, x3b, y3b @@ -1100,12 +1153,12 @@ A polygon-approximation of a circle patch. """ def __str__(self): - return "CirclePolygon(%d,%d)"%self.center + return "CirclePolygon(%d,%d)" % self.center @docstring.dedent_interpd def __init__(self, xy, radius=5, resolution=20, # the number of vertices - **kwargs): + ** kwargs): """ Create a circle at *xy* = (*x*, *y*) with given *radius*. This circle is approximated by a regular polygon with @@ -1128,7 +1181,8 @@ A scale-free ellipse. """ def __str__(self): - return "Ellipse(%s,%s;%sx%s)"%(self.center[0],self.center[1],self.width,self.height) + return "Ellipse(%s,%s;%sx%s)" % (self.center[0], self.center[1], + self.width, self.height) @docstring.dedent_interpd def __init__(self, xy, width, height, angle=0.0, **kwargs): @@ -1182,10 +1236,11 @@ self._recompute_transform() return self._patch_transform - def contains(self,ev): - if ev.x is None or ev.y is None: return False,{} + def contains(self, ev): + if ev.x is None or ev.y is None: + return False, {} x, y = self.get_transform().inverted().transform_point((ev.x, ev.y)) - return (x*x + y*y) <= 1.0, {} + return (x * x + y * y) <= 1.0, {} class Circle(Ellipse): @@ -1193,7 +1248,9 @@ A circle patch. """ def __str__(self): - return "Circle((%g,%g),r=%g)"%(self.center[0],self.center[1],self.radius) + return "Circle((%g,%g),r=%g)" % (self.center[0], + self.center[1], + self.radius) @docstring.dedent_interpd def __init__(self, xy, radius=5, **kwargs): @@ -1209,11 +1266,13 @@ """ if 'resolution' in kwargs: import warnings - warnings.warn('Circle is now scale free. Use CirclePolygon instead!', DeprecationWarning) + warnings.warn('Circle is now scale free. ' + 'Use CirclePolygon instead!', + DeprecationWarning) kwargs.pop('resolution') self.radius = radius - Ellipse.__init__(self, xy, radius*2, radius*2, **kwargs) + Ellipse.__init__(self, xy, radius * 2, radius * 2, **kwargs) def set_radius(self, radius): """ @@ -1229,6 +1288,7 @@ radius = property(get_radius, set_radius) + class Arc(Ellipse): """ An elliptical arc. Because it performs various optimizations, it @@ -1241,10 +1301,12 @@ with high resolution. """ def __str__(self): - return "Arc(%s,%s;%sx%s)"%(self.center[0],self.center[1],self.width,self.height) + return "Arc(%s,%s;%sx%s)" % (self.center[0], self.center[1], + self.width, self.height) @docstring.dedent_interpd - def __init__(self, xy, width, height, angle=0.0, theta1=0.0, theta2=360.0, **kwargs): + def __init__(self, xy, width, height, angle=0.0, + theta1=0.0, theta2=360.0, **kwargs): """ The following args are supported: @@ -1284,7 +1346,6 @@ self._path = Path.arc(self.theta1, self.theta2) - @allow_rasterization def draw(self, renderer): """ @@ -1350,15 +1411,15 @@ def iter_circle_intersect_on_line(x0, y0, x1, y1): dx = x1 - x0 dy = y1 - y0 - dr2 = dx*dx + dy*dy - D = x0*y1 - x1*y0 - D2 = D*D + dr2 = dx * dx + dy * dy + D = x0 * y1 - x1 * y0 + D2 = D * D discrim = dr2 - D2 # Single (tangential) intersection if discrim == 0.0: - x = (D*dy) / dr2 - y = (-D*dx) / dr2 + x = (D * dy) / dr2 + y = (-D * dx) / dr2 yield x, y elif discrim > 0.0: # The definition of "sign" here is different from @@ -1369,8 +1430,8 @@ sign_dy = 1.0 sqrt_discrim = np.sqrt(discrim) for sign in (1., -1.): - x = (D*dy + sign * sign_dy * dx * sqrt_discrim) / dr2 - y = (-D*dx + sign * np.abs(dy) * sqrt_discrim) / dr2 + x = (D * dy + sign * sign_dy * dx * sqrt_discrim) / dr2 + y = (-D * dx + sign * np.abs(dy) * sqrt_discrim) / dr2 yield x, y def iter_circle_intersect_on_line_seg(x0, y0, x1, y1): @@ -1425,7 +1486,8 @@ last_theta = theta1 theta1_rad = theta1 * DEG2RAD - inside = box_path.contains_point((np.cos(theta1_rad), np.sin(theta1_rad))) + inside = box_path.contains_point((np.cos(theta1_rad), + np.sin(theta1_rad))) # save original path path_original = self._path @@ -1452,23 +1514,24 @@ *props* is a dict of rectangle props with the additional property 'pad' that sets the padding around the bbox in points. """ - if props is None: props = {} - props = props.copy() # don't want to alter the pad externally + if props is None: + props = {} + props = props.copy() # don't want to alter the pad externally pad = props.pop('pad', 4) pad = renderer.points_to_pixels(pad) bbox = artist.get_window_extent(renderer) l, b, w, h = bbox.bounds - l -= pad/2. - b -= pad/2. + l -= pad / 2. + b -= pad / 2. w += pad h += pad r = Rectangle(xy=(l, b), width=w, height=h, fill=fill, - ) + ) r.set_transform(transforms.IdentityTransform()) - r.set_clip_on( False ) + r.set_clip_on(False) r.update(props) r.draw(renderer) @@ -1487,21 +1550,21 @@ height=h, edgecolor=color, fill=False, - ) - if trans is not None: r.set_transform(trans) - r.set_clip_on( False ) + ) + if trans is not None: + r.set_transform(trans) + r.set_clip_on(False) r.draw(renderer) - def _pprint_table(_table, leadingspace=2): """ Given the list of list of strings, return a string of REST table format. """ if leadingspace: - pad = ' '*leadingspace + pad = ' ' * leadingspace else: - pad = '' + pad = '' columns = [[] for cell in _table[0]] @@ -1509,8 +1572,6 @@ for column, cell in zip(columns, row): column.append(cell) - - col_len = [max([len(cell) for cell in column]) for column in columns] lines = [] @@ -1518,10 +1579,14 @@ lines.append('') lines.append(table_formatstr) - lines.append(pad + ' '.join([cell.ljust(cl) for cell, cl in zip(_table[0], col_len)])) + lines.append(pad + ' '.join([cell.ljust(cl) + for cell, cl + in zip(_table[0], col_len)])) lines.append(table_formatstr) - lines.extend([(pad + ' '.join([cell.ljust(cl) for cell, cl in zip(row, col_len)])) + lines.extend([(pad + ' '.join([cell.ljust(cl) + for cell, cl + in zip(row, col_len)])) for row in _table[1:]]) lines.append(table_formatstr) @@ -1536,9 +1601,9 @@ styles. Used to update the documentation. """ if leadingspace: - pad = ' '*leadingspace + pad = ' ' * leadingspace else: - pad = '' + pad = '' names, attrss, clss = [], [], [] @@ -1547,9 +1612,9 @@ _table = [["Class", "Name", "Attrs"]] for name, cls in sorted(_styles.items()): - args, varargs, varkw, defaults = inspect.getargspec(cls.__init__) + args, varargs, varkw, defaults = inspect.getargspec(cls.__init__) if defaults: - args = [(argname, argdefault) \ + args = [(argname, argdefault) for argname, argdefault in zip(args[1:], defaults)] else: args = None @@ -1557,15 +1622,16 @@ if args is None: argstr = 'None' else: - argstr = ",".join([("%s=%s" % (an, av)) for an, av in args]) + argstr = ",".join([("%s=%s" % (an, av)) + for an, av + in args]) #adding ``quotes`` since - and | have special meaning in reST - _table.append([cls.__name__, "``%s``"%name, argstr]) + _table.append([cls.__name__, "``%s``" % name, argstr]) return _pprint_table(_table) - class _Style(object): """ A base class for the Styles. It is meant to be a container class, @@ -1580,7 +1646,7 @@ # the "class" should have the _style_list attribute, which is # a dictionary of stylname, style class paie. - _list = stylename.replace(" ","").split(",") + _list = stylename.replace(" ", "").split(",") _name = _list[0].lower() try: _cls = self._style_list[_name] @@ -1596,7 +1662,6 @@ return _cls(**_args) - @classmethod def get_styles(klass): """ @@ -1611,7 +1676,6 @@ """ return _pprint_styles(klass._style_list) - @classmethod def register(klass, name, style): """ @@ -1619,7 +1683,8 @@ """ if not issubclass(style, klass._Base): - raise ValueError("%s must be a subclass of %s" % (style, klass._Base)) + raise ValueError("%s must be a subclass of %s" % (style, + klass._Base)) klass._style_list[name] = style @@ -1661,7 +1726,6 @@ _style_list = {} - class _Base(object): """ :class:`BBoxTransmuterBase` and its derivatives are used to make a @@ -1681,9 +1745,6 @@ """ super(BoxStyle._Base, self).__init__() - - - def transmute(self, x0, y0, width, height, mutation_size): """ The transmute method is a very core of the @@ -1695,8 +1756,6 @@ """ raise NotImplementedError('Derived must override') - - def __call__(self, x0, y0, width, height, mutation_size, aspect_ratio=1.): """ @@ -1712,17 +1771,24 @@ if aspect_ratio is not None: # Squeeze the given height by the aspect_ratio - y0, height = y0/aspect_ratio, height/aspect_ratio + y0, height = y0 / aspect_ratio, height / aspect_ratio # call transmute method with squeezed height. path = self.transmute(x0, y0, width, height, mutation_size) vertices, codes = path.vertices, path.codes # Restore the height - vertices[:,1] = vertices[:,1] * aspect_ratio + vertices[:, 1] = vertices[:, 1] * aspect_ratio return Path(vertices, codes) else: return self.transmute(x0, y0, width, height, mutation_size) - + def __reduce__(self): + # because we have decided to nest thes classes, we need to + # add some more information to allow instance pickling. + import matplotlib.cbook as cbook + return (cbook._NestedClassGetter(), + (BoxStyle, self.__class__.__name__), + self.__dict__ + ) class Square(_Base): """ @@ -1744,12 +1810,12 @@ pad = mutation_size * self.pad # width and height with padding added. - width, height = width + 2.*pad, \ - height + 2.*pad, + width, height = width + 2. * pad, \ + height + 2. * pad, # boundary of the padded box - x0, y0 = x0-pad, y0-pad, - x1, y1 = x0+width, y0 + height + x0, y0 = x0 - pad, y0 - pad, + x1, y1 = x0 + width, y0 + height cp = [(x0, y0), (x1, y0), (x1, y1), (x0, y1), (x0, y0), (x0, y0)] @@ -1767,7 +1833,6 @@ _style_list["square"] = Square - class LArrow(_Base): """ (left) Arrow Box @@ -1783,21 +1848,22 @@ pad = mutation_size * self.pad # width and height with padding added. - width, height = width + 2.*pad, \ - height + 2.*pad, + width, height = width + 2. * pad, \ + height + 2. * pad, # boundary of the padded box - x0, y0 = x0-pad, y0-pad, - x1, y1 = x0+width, y0 + height + x0, y0 = x0 - pad, y0 - pad, + x1, y1 = x0 + width, y0 + height - dx = (y1-y0)/2. - dxx = dx*.5 + dx = (y1 - y0) / 2. + dxx = dx * .5 # adjust x0. 1.4 <- sqrt(2) x0 = x0 + pad / 1.4 - cp = [(x0+dxx, y0), (x1, y0), (x1, y1), (x0+dxx, y1), - (x0+dxx, y1+dxx), (x0-dx, y0+dx), (x0+dxx, y0-dxx), # arrow - (x0+dxx, y0), (x0+dxx, y0)] + cp = [(x0 + dxx, y0), (x1, y0), (x1, y1), (x0 + dxx, y1), + (x0 + dxx, y1 + dxx), (x0 - dx, y0 + dx), + (x0 + dxx, y0 - dxx), # arrow + (x0 + dxx, y0), (x0 + dxx, y0)] com = [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO, @@ -1808,8 +1874,6 @@ return path _style_list["larrow"] = LArrow - - class RArrow(LArrow): """ (right) Arrow Box @@ -1824,14 +1888,12 @@ p = BoxStyle.LArrow.transmute(self, x0, y0, width, height, mutation_size) - p.vertices[:,0] = 2*x0 + width - p.vertices[:,0] + p.vertices[:, 0] = 2 * x0 + width - p.vertices[:, 0] return p - _style_list["rarrow"] = RArrow - class Round(_Base): """ A box with round corners. @@ -1860,25 +1922,24 @@ else: dr = pad - width, height = width + 2.*pad, \ - height + 2.*pad, - + width, height = width + 2. * pad, \ + height + 2. * pad, - x0, y0 = x0-pad, y0-pad, - x1, y1 = x0+width, y0 + height + x0, y0 = x0 - pad, y0 - pad, + x1, y1 = x0 + width, y0 + height # Round corners are implemented as quadratic bezier. eg. # [(x0, y0-dr), (x0, y0), (x0+dr, y0)] for lower left corner. - cp = [(x0+dr, y0), - (x1-dr, y0), - (x1, y0), (x1, y0+dr), - (x1, y1-dr), - (x1, y1), (x1-dr, y1), - (x0+dr, y1), - (x0, y1), (x0, y1-dr), - (x0, y0+dr), - (x0, y0), (x0+dr, y0), - (x0+dr, y0)] + cp = [(x0 + dr, y0), + (x1 - dr, y0), + (x1, y0), (x1, y0 + dr), + (x1, y1 - dr), + (x1, y1), (x1 - dr, y1), + (x0 + dr, y1), + (x0, y1), (x0, y1 - dr), + (x0, y0 + dr), + (x0, y0), (x0 + dr, y0), + (x0 + dr, y0)] com = [Path.MOVETO, Path.LINETO, @@ -1897,7 +1958,6 @@ _style_list["round"] = Round - class Round4(_Base): """ Another box with round edges. @@ -1927,19 +1987,17 @@ else: dr = pad / 2. - width, height = width + 2.*pad - 2*dr, \ - height + 2.*pad - 2*dr, - - - x0, y0 = x0-pad+dr, y0-pad+dr, - x1, y1 = x0+width, y0 + height + width, height = width + 2. * pad - 2 * dr, \ + height + 2. * pad - 2 * dr, + x0, y0 = x0 - pad + dr, y0 - pad + dr, + x1, y1 = x0 + width, y0 + height cp = [(x0, y0), - (x0+dr, y0-dr), (x1-dr, y0-dr), (x1, y0), - (x1+dr, y0+dr), (x1+dr, y1-dr), (x1, y1), - (x1-dr, y1+dr), (x0+dr, y1+dr), (x0, y1), - (x0-dr, y1-dr), (x0-dr, y0+dr), (x0, y0), + (x0 + dr, y0 - dr), (x1 - dr, y0 - dr), (x1, y0), + (x1 + dr, y0 + dr), (x1 + dr, y1 - dr), (x1, y1), + (x1 - dr, y1 + dr), (x0 + dr, y1 + dr), (x0, y1), + (x0 - dr, y1 - dr), (x0 - dr, y0 + dr), (x0, y0), (x0, y0)] com = [Path.MOVETO, @@ -1955,7 +2013,6 @@ _style_list["round4"] = Round4 - class Sawtooth(_Base): """ A sawtooth box. @@ -1975,7 +2032,6 @@ def _get_sawtooth_vertices(self, x0, y0, width, height, mutation_size): - # padding pad = mutation_size * self.pad @@ -1986,47 +2042,67 @@ tooth_size = self.tooth_size * mutation_size tooth_size2 = tooth_size / 2. - width, height = width + 2.*pad - tooth_size, \ - height + 2.*pad - tooth_size, + width, height = width + 2. * pad - tooth_size, \ + height + 2. * pad - tooth_size, # the sizes of the vertical and horizontal sawtooth are # separately adjusted to fit the given box size. - dsx_n = int(round((width - tooth_size) / (tooth_size * 2))) * 2 - dsx = (width - tooth_size) / dsx_n - dsy_n = int(round((height - tooth_size) / (tooth_size * 2))) * 2 - dsy = (height - tooth_size) / dsy_n - - - x0, y0 = x0-pad+tooth_size2, y0-pad+tooth_size2 - x1, y1 = x0+width, y0 + height + dsx_n = int(round((width - tooth_size) / (tooth_size * 2))) * 2 + dsx = (width - tooth_size) / dsx_n + dsy_n = int(round((height - tooth_size) / (tooth_size * 2))) * 2 + dsy = (height - tooth_size) / dsy_n + x0, y0 = x0 - pad + tooth_size2, y0 - pad + tooth_size2 + x1, y1 = x0 + width, y0 + height bottom_saw_x = [x0] + \ - [x0 + tooth_size2 + dsx*.5* i for i in range(dsx_n*2)] + \ + [x0 + tooth_size2 + dsx * .5 * i + for i + in range(dsx_n * 2)] + \ [x1 - tooth_size2] + bottom_saw_y = [y0] + \ - [y0 - tooth_size2, y0, y0 + tooth_size2, y0] * dsx_n + \ + [y0 - tooth_size2, y0, + y0 + tooth_size2, y0] * dsx_n + \ [y0 - tooth_size2] right_saw_x = [x1] + \ - [x1 + tooth_size2, x1, x1 - tooth_size2, x1] * dsx_n + \ + [x1 + tooth_size2, + x1, + x1 - tooth_size2, + x1] * dsx_n + \ [x1 + tooth_size2] + right_saw_y = [y0] + \ - [y0 + tooth_size2 + dsy*.5* i for i in range(dsy_n*2)] + \ + [y0 + tooth_size2 + dsy * .5 * i + for i + in range(dsy_n * 2)] + \ [y1 - tooth_size2] top_saw_x = [x1] + \ - [x1 - tooth_size2 - dsx*.5* i for i in range(dsx_n*2)] + \ + [x1 - tooth_size2 - dsx * .5 * i + for i + in range(dsx_n * 2)] + \ [x0 + tooth_size2] + top_saw_y = [y1] + \ - [y1 + tooth_size2, y1, y1 - tooth_size2, y1] * dsx_n + \ + [y1 + tooth_size2, + y1, + y1 - tooth_size2, + y1] * dsx_n + \ [y1 + tooth_size2] left_saw_x = [x0] + \ - [x0 - tooth_size2, x0, x0 + tooth_size2, x0] * dsy_n + \ + [x0 - tooth_size2, + x0, + x0 + tooth_size2, + x0] * dsy_n + \ [x0 - tooth_size2] + left_saw_y = [y1] + \ - [y1 - tooth_size2 - dsy*.5* i for i in range(dsy_n*2)] + \ + [y1 - tooth_size2 - dsy * .5 * i + for i + in range(dsy_n * 2)] + \ [y0 + tooth_size2] saw_vertices = zip(bottom_saw_x, bottom_saw_y) + \ @@ -2037,16 +2113,15 @@ return saw_vertices - def transmute(self, x0, y0, width, height, mutation_size): - saw_vertices = self._get_sawtooth_vertices(x0, y0, width, height, mutation_size) + saw_vertices = self._get_sawtooth_vertices(x0, y0, width, + height, mutation_size) path = Path(saw_vertices) return path _style_list["sawtooth"] = Sawtooth - class Roundtooth(Sawtooth): """ A roundtooth(?) box. @@ -2062,23 +2137,27 @@ """ super(BoxStyle.Roundtooth, self).__init__(pad, tooth_size) - def transmute(self, x0, y0, width, height, mutation_size): - saw_vertices = self._get_sawtooth_vertices(x0, y0, width, height, mutation_size) + saw_vertices = self._get_sawtooth_vertices(x0, y0, + width, height, + mutation_size) - cp = [Path.MOVETO] + ([Path.CURVE3, Path.CURVE3] * ((len(saw_vertices)-1)//2)) + cp = [Path.MOVETO] + ([Path.CURVE3, Path.CURVE3] \ + * ((len(saw_vertices) - 1) // 2)) path = Path(saw_vertices, cp) return path _style_list["roundtooth"] = Roundtooth - if __doc__: # __doc__ could be None if -OO optimization is enabled + if __doc__: # __doc__ could be None if -OO optimization is enabled __doc__ = cbook.dedent(__doc__) % \ {"AvailableBoxstyles": _pprint_styles(_style_list)} -docstring.interpd.update(AvailableBoxstyles=_pprint_styles(BoxStyle._style_list)) +docstring.interpd.update( + AvailableBoxstyles=_pprint_styles(BoxStyle._style_list)) + class FancyBboxPatch(Patch): """ @@ -2094,7 +2173,8 @@ def __str__(self): return self.__class__.__name__ \ - + "FancyBboxPatch(%g,%g;%gx%g)" % (self._x, self._y, self._width, self._height) + + "FancyBboxPatch(%g,%g;%gx%g)" % (self._x, self._y, + self._width, self._height) @docstring.dedent_interpd def __init__(self, xy, width, height, @@ -2135,14 +2215,14 @@ if boxstyle == "custom": if bbox_transmuter is None: - raise ValueError("bbox_transmuter argument is needed with custom boxstyle") + raise ValueError("bbox_transmuter argument is needed with " + "custom boxstyle") self._bbox_transmuter = bbox_transmuter else: self.set_boxstyle(boxstyle) - self._mutation_scale=mutation_scale - self._mutation_aspect=mutation_aspect - + self._mutation_scale = mutation_scale + self._mutation_aspect = mutation_aspect @docstring.dedent_interpd def set_boxstyle(self, boxstyle=None, **kw): @@ -2164,8 +2244,7 @@ ACCEPTS: %(AvailableBoxstyles)s """ - - if boxstyle==None: + if boxstyle == None: return BoxStyle.pprint_styles() if isinstance(boxstyle, BoxStyle._Base): @@ -2175,14 +2254,13 @@ else: self._bbox_transmuter = BoxStyle(boxstyle, **kw) - def set_mutation_scale(self, scale): """ Set the mutation scale. ACCEPTS: float """ - self._mutation_scale=scale + self._mutation_scale = scale def get_mutation_scale(self): """ @@ -2196,7 +2274,7 @@ ACCEPTS: float """ - self._mutation_aspect=aspect + self._mutation_aspect = aspect def get_mutation_aspect(self): """ @@ -2219,7 +2297,6 @@ self.get_mutation_aspect()) return _path - # Following methods are borrowed from the Rectangle class. def get_x(self): @@ -2276,21 +2353,18 @@ ACCEPTS: (left, bottom, width, height) """ - if len(args)==0: - l,b,w,h = args[0] + if len(args) == 0: + l, b, w, h = args[0] else: - l,b,w,h = args + l, b, w, h = args self._x = l self._y = b self._width = w self._height = h - def get_bbox(self): - return transforms.Bbox.from_bounds(self._x, self._y, self._width, self._height) - - - + return transforms.Bbox.from_bounds(self._x, self._y, + self._width, self._height) from matplotlib.bezier import split_bezier_intersecting_with_closedpath @@ -2327,7 +2401,9 @@ An instance of any connection style class is an callable object, whose call signature is:: - __call__(self, posA, posB, patchA=None, patchB=None, shrinkA=2., shrinkB=2.) + __call__(self, posA, posB, + patchA=None, patchB=None, + shrinkA=2., shrinkB=2.) and it returns a :class:`Path` instance. *posA* and *posB* are tuples of x,y coordinates of the two points to be @@ -2340,7 +2416,6 @@ _style_list = {} - class _Base(object): """ A base class for connectionstyle classes. The dervided needs @@ -2369,8 +2444,7 @@ if patchA: def insideA(xy_display): - #xy_display = patchA.get_data_transform().transform_point(xy_data) - xy_event = ConnectionStyle._Base.SimpleEvent(xy_display) + xy_event = ConnectionStyle._Base.SimpleEvent(xy_display) return patchA.contains(xy_event)[0] try: @@ -2382,8 +2456,7 @@ if patchB: def insideB(xy_display): - #xy_display = patchB.get_data_transform().transform_point(xy_data) - xy_event = ConnectionStyle._Base.SimpleEvent(xy_display) + xy_event = ConnectionStyle._Base.SimpleEvent(xy_display) return patchB.contains(xy_event)[0] try: @@ -2395,7 +2468,6 @@ return path - def _shrink(self, path, shrinkA, shrinkB): """ Shrink the path by fixed size (in points) with shrinkA and shrinkB @@ -2436,6 +2508,14 @@ return shrinked_path + def __reduce__(self): + # because we have decided to nest thes classes, we need to + # add some more information to allow instance pickling. + import matplotlib.cbook as cbook + return (cbook._NestedClassGetter(), + (ConnectionStyle, self.__class__.__name__), + self.__dict__ + ) class Arc3(_Base): """ @@ -2456,12 +2536,12 @@ def connect(self, posA, posB): x1, y1 = posA x2, y2 = posB - x12, y12 = (x1 + x2)/2., (y1 + y2)/2. + x12, y12 = (x1 + x2) / 2., (y1 + y2) / 2. dx, dy = x2 - x1, y2 - y1 f = self.rad - cx, cy = x12 + f*dy, y12 - f*dx + cx, cy = x12 + f * dy, y12 - f * dx vertices = [(x1, y1), (cx, cy), @@ -2474,7 +2554,6 @@ _style_list["arc3"] = Arc3 - class Angle3(_Base): """ Creates a simple quadratic bezier curve between two @@ -2483,7 +2562,6 @@ end) point and has a angle of angleA (or angleB). """ - def __init__(self, angleA=90, angleB=0): """ *angleA* @@ -2496,15 +2574,14 @@ self.angleA = angleA self.angleB = angleB - def connect(self, posA, posB): x1, y1 = posA x2, y2 = posB - cosA, sinA = math.cos(self.angleA/180.*math.pi),\ - math.sin(self.angleA/180.*math.pi), - cosB, sinB = math.cos(self.angleB/180.*math.pi),\ - math.sin(self.angleB/180.*math.pi), + cosA, sinA = math.cos(self.angleA / 180. * math.pi),\ + math.sin(self.angleA / 180. * math.pi), + cosB, sinB = math.cos(self.angleB / 180. * math.pi),\ + math.sin(self.angleB / 180. * math.pi), cx, cy = get_intersection(x1, y1, cosA, sinA, x2, y2, cosB, sinB) @@ -2516,7 +2593,6 @@ _style_list["angle3"] = Angle3 - class Angle(_Base): """ Creates a picewise continuous quadratic bezier path between @@ -2547,10 +2623,10 @@ x1, y1 = posA x2, y2 = posB - cosA, sinA = math.cos(self.angleA/180.*math.pi),\ - math.sin(self.angleA/180.*math.pi), - cosB, sinB = math.cos(self.angleB/180.*math.pi),\ - math.sin(self.angleB/180.*math.pi), + cosA, sinA = math.cos(self.angleA / 180. * math.pi),\ + math.sin(self.angleA / 180. * math.pi), + cosB, sinB = math.cos(self.angleB / 180. * math.pi),\ + math.sin(self.angleB / 180. * math.pi), cx, cy = get_intersection(x1, y1, cosA, sinA, x2, y2, cosB, sinB) @@ -2562,15 +2638,15 @@ vertices.append((cx, cy)) codes.append(Path.LINETO) else: - dx1, dy1 = x1-cx, y1-cy - d1 = (dx1**2 + dy1**2)**.5 - f1 = self.rad/d1 - dx2, dy2 = x2-cx, y2-cy - d2 = (dx2**2 + dy2**2)**.5 - f2 = self.rad/d2 - vertices.extend([(cx + dx1*f1, cy + dy1*f1), + dx1, dy1 = x1 - cx, y1 - cy + d1 = (dx1 ** 2 + dy1 ** 2) ** .5 + f1 = self.rad / d1 + dx2, dy2 = x2 - cx, y2 - cy + d2 = (dx2 ** 2 + dy2 ** 2) ** .5 + f2 = self.rad / d2 + vertices.extend([(cx + dx1 * f1, cy + dy1 * f1), (cx, cy), - (cx + dx2*f2, cy + dy2*f2)]) + (cx + dx2 * f2, cy + dy2 * f2)]) codes.extend([Path.LINETO, Path.CURVE3, Path.CURVE3]) vertices.append((x2, y2)) @@ -2580,7 +2656,6 @@ _style_list["angle"] = Angle - class Arc(_Base): """ Creates a picewise continuous quadratic bezier path between @@ -2624,25 +2699,26 @@ codes = [Path.MOVETO] if self.armA: - cosA = math.cos(self.angleA/180.*math.pi) - sinA = math.sin(self.angleA/180.*math.pi) + cosA = math.cos(self.angleA / 180. * math.pi) + sinA = math.sin(self.angleA / 180. * math.pi) #x_armA, y_armB d = self.armA - self.rad - rounded.append((x1 + d*cosA, y1 + d*sinA)) + rounded.append((x1 + d * cosA, y1 + d * sinA)) d = self.armA - rounded.append((x1 + d*cosA, y1 + d*sinA)) + rounded.append((x1 + d * cosA, y1 + d * sinA)) if self.armB: - cosB = math.cos(self.angleB/180.*math.pi) - sinB = math.sin(self.angleB/180.*math.pi) - x_armB, y_armB = x2 + self.armB*cosB, y2 + self.armB*sinB + cosB = math.cos(self.angleB / 180. * math.pi) + sinB = math.sin(self.angleB / 180. * math.pi) + x_armB, y_armB = x2 + self.armB * cosB, y2 + self.armB * sinB if rounded: xp, yp = rounded[-1] dx, dy = x_armB - xp, y_armB - yp - dd = (dx*dx + dy*dy)**.5 + dd = (dx * dx + dy * dy) ** .5 - rounded.append((xp + self.rad*dx/dd, yp + self.rad*dy/dd)) + rounded.append((xp + self.rad * dx / dd, + yp + self.rad * dy / dd)) vertices.extend(rounded) codes.extend([Path.LINETO, Path.CURVE3, @@ -2650,18 +2726,19 @@ else: xp, yp = vertices[-1] dx, dy = x_armB - xp, y_armB - yp - dd = (dx*dx + dy*dy)**.5 + dd = (dx * dx + dy * dy) ** .5 d = dd - self.rad - rounded = [(xp + d*dx/dd, yp + d*dy/dd), + rounded = [(xp + d * dx / dd, yp + d * dy / dd), (x_armB, y_armB)] if rounded: xp, yp = rounded[-1] dx, dy = x2 - xp, y2 - yp - dd = (dx*dx + dy*dy)**.5 + dd = (dx * dx + dy * dy) ** .5 - rounded.append((xp + self.rad*dx/dd, yp + self.rad*dy/dd)) + rounded.append((xp + self.rad * dx / dd, + yp + self.rad * dy / dd)) vertices.extend(rounded) codes.extend([Path.LINETO, Path.CURVE3, @@ -2674,8 +2751,6 @@ _style_list["arc"] = Arc - - class Bar(_Base): """ A line with *angle* between A and B with *armA* and @@ -2688,8 +2763,10 @@ """ *armA* : minimum length of armA *armB* : minimum length of armB - *fraction* : a fraction of the distance between two points that will be added to armA and armB. - *angle* : anlge of the connecting line (if None, parallel to A and B) + *fraction* : a fraction of the distance between two points that + will be added to armA and armB. + *angle* : angle of the connecting line (if None, parallel to A + and B) """ self.armA = armA self.armB = armB @@ -2700,12 +2777,12 @@ x1, y1 = posA x20, y20 = x2, y2 = posB - x12, y12 = (x1 + x2)/2., (y1 + y2)/2. + x12, y12 = (x1 + x2) / 2., (y1 + y2) / 2. - theta1 = math.atan2(y2-y1, x2-x1) + theta1 = math.atan2(y2 - y1, x2 - x1) dx, dy = x2 - x1, y2 - y1 - dd = (dx*dx + dy*dy)**.5 - ddx, ddy = dx/dd, dy/dd + dd = (dx * dx + dy * dy) ** .5 + ddx, ddy = dx / dd, dy / dd armA, armB = self.armA, self.armB @@ -2714,22 +2791,22 @@ #if angle < 0. or angle > 180.: # angle #theta0 = (self.angle%180.)/180.*math.pi - theta0 = self.angle/180.*math.pi + theta0 = self.angle / 180. * math.pi #theta0 = (((self.angle+90)%180.) - 90.)/180.*math.pi dtheta = theta1 - theta0 - dl = dd*math.sin(dtheta) + dl = dd * math.sin(dtheta) - dL = dd*math.cos(dtheta) + dL = dd * math.cos(dtheta) #x2, y2 = x2 + dl*ddy, y2 - dl*ddx - x2, y2 = x1 + dL*math.cos(theta0), y1 + dL*math.sin(theta0) + x2, y2 = x1 + dL * math.cos(theta0), y1 + dL * math.sin(theta0) armB = armB - dl # update dx, dy = x2 - x1, y2 - y1 - dd2 = (dx*dx + dy*dy)**.5 - ddx, ddy = dx/dd2, dy/dd2 + dd2 = (dx * dx + dy * dy) ** .5 + ddx, ddy = dx / dd2, dy / dd2 else: dl = 0. @@ -2739,13 +2816,12 @@ #else: # armA = armB - dl - arm = max(armA, armB) - f = self.fraction*dd + arm + f = self.fraction * dd + arm #fB = self.fraction*dd + armB - cx1, cy1 = x1 + f*ddy, y1 - f*ddx - cx2, cy2 = x2 + f*ddy, y2 - f*ddx + cx1, cy1 = x1 + f * ddy, y1 - f * ddx + cx2, cy2 = x2 + f * ddy, y2 - f * ddx vertices = [(x1, y1), (cx1, cy1), @@ -2765,6 +2841,17 @@ {"AvailableConnectorstyles": _pprint_styles(_style_list)} +def _point_along_a_line(x0, y0, x1, y1, d): + """ + find a point along a line connecting (x0, y0) -- (x1, y1) whose + distance from (x0, y0) is d. + """ + dx, dy = x0 - x1, y0 - y1 + ff = d/(dx*dx+dy*dy)**.5 + x2, y2 = x0 - ff*dx, y0 - ff*dy + + return x2, y2 + class ArrowStyle(_Style): """ @@ -2805,7 +2892,6 @@ .. plot:: mpl_examples/pylab_examples/fancyarrow_demo.py """ - _style_list = {} class _Base(object): @@ -2844,7 +2930,6 @@ return list(segments[0][0]) + list(segments[1][0]) - def transmute(self, path, mutation_size, linewidth): """ The transmute method is a very core of the ArrowStyle @@ -2861,8 +2946,6 @@ raise NotImplementedError('Derived must override') - - def __call__(self, path, mutation_size, linewidth, aspect_ratio=1.): """ @@ -2877,7 +2960,7 @@ vertices, codes = path.vertices[:], path.codes[:] # Squeeze the height - vertices[:,1] = vertices[:,1] / aspect_ratio + vertices[:, 1] = vertices[:, 1] / aspect_ratio path_shrinked = Path(vertices, codes) # call transmute method with squeezed height. path_mutated, fillable = self.transmute(path_shrinked, @@ -2888,7 +2971,7 @@ for p in zip(path_mutated): v, c = p.vertices, p.codes # Restore the height - v[:,1] = v[:,1] * aspect_ratio + v[:, 1] = v[:, 1] * aspect_ratio path_list.append(Path(v, c)) return path_list, fillable else: @@ -2896,7 +2979,14 @@ else: return self.transmute(path, mutation_size, linewidth) - + def __reduce__(self): + # because we have decided to nest thes classes, we need to + # add some more information to allow instance pickling. + import matplotlib.cbook as cbook + return (cbook._NestedClassGetter(), + (ArrowStyle, self.__class__.__name__), + self.__dict__ + ) class _Curve(_Base): """ @@ -2922,10 +3012,9 @@ self.fillbegin, self.fillend = fillbegin, fillend super(ArrowStyle._Curve, self).__init__() - def _get_arrow_wedge(self, x0, y0, x1, y1, head_dist, cos_t, sin_t, linewidth - ): + ): """ Return the paths for arrow heads. Since arrow lines are drawn with capstyle=projected, The arrow goes beyond the @@ -2935,42 +3024,40 @@ # arrow from x0, y0 to x1, y1 - dx, dy = x0 - x1, y0 - y1 - cp_distance = math.sqrt(dx**2 + dy**2) + cp_distance = math.sqrt(dx ** 2 + dy ** 2) # pad_projected : amount of pad to account the # overshooting of the projection of the wedge - pad_projected = (.5*linewidth / sin_t) + pad_projected = (.5 * linewidth / sin_t) # apply pad for projected edge ddx = pad_projected * dx / cp_distance ddy = pad_projected * dy / cp_distance # offset for arrow wedge - dx, dy = dx / cp_distance * head_dist, dy / cp_distance * head_dist + dx = dx / cp_distance * head_dist + dy = dy / cp_distance * head_dist dx1, dy1 = cos_t * dx + sin_t * dy, -sin_t * dx + cos_t * dy dx2, dy2 = cos_t * dx - sin_t * dy, sin_t * dx + cos_t * dy - vertices_arrow = [(x1+ddx+dx1, y1+ddy+dy1), - (x1+ddx, y1+ddy), - (x1+ddx+dx2, y1+ddy+dy2)] + vertices_arrow = [(x1 + ddx + dx1, y1 + ddy + dy1), + (x1 + ddx, y1 + ddy), + (x1 + ddx + dx2, y1 + ddy + dy2)] codes_arrow = [Path.MOVETO, Path.LINETO, Path.LINETO] return vertices_arrow, codes_arrow, ddx, ddy - def transmute(self, path, mutation_size, linewidth): head_length, head_width = self.head_length * mutation_size, \ self.head_width * mutation_size - head_dist = math.sqrt(head_length**2 + head_width**2) + head_dist = math.sqrt(head_length ** 2 + head_width ** 2) cos_t, sin_t = head_length / head_dist, head_width / head_dist - # begin arrow x0, y0 = path.vertices[0] x1, y1 = path.vertices[1] @@ -2982,8 +3069,7 @@ linewidth) else: verticesA, codesA = [], [] - #ddxA, ddyA = self._get_pad_projected(x1, y1, x0, y0, linewidth) - ddxA, ddyA = 0., 0., #self._get_pad_projected(x1, y1, x0, y0, linewidth) + ddxA, ddyA = 0., 0. # end arrow x2, y2 = path.vertices[-2] @@ -2996,20 +3082,20 @@ linewidth) else: verticesB, codesB = [], [] - ddxB, ddyB = 0., 0. #self._get_pad_projected(x2, y2, x3, y3, linewidth) - + ddxB, ddyB = 0., 0. # this simple code will not work if ddx, ddy is greater than # separation bettern vertices. - _path = [Path(np.concatenate([[(x0+ddxA, y0+ddyA)], + _path = [Path(np.concatenate([[(x0 + ddxA, y0 + ddyA)], path.vertices[1:-1], - [(x3+ddxB, y3+ddyB)]]), + [(x3 + ddxB, y3 + ddyB)]]), path.codes)] _fillable = [False] if self.beginarrow: if self.fillbegin: - p = np.concatenate([verticesA, [verticesA[0], verticesA[0]], ]) + p = np.concatenate([verticesA, [verticesA[0], + verticesA[0]], ]) c = np.concatenate([codesA, [Path.LINETO, Path.CLOSEPOLY]]) _path.append(Path(p, c)) _fillable.append(True) @@ -3020,7 +3106,8 @@ if self.endarrow: if self.fillend: _fillable.append(True) - p = np.concatenate([verticesB, [verticesB[0], verticesB[0]], ]) + p = np.concatenate([verticesB, [verticesB[0], + verticesB[0]], ]) c = np.concatenate([codesB, [Path.LINETO, Path.CLOSEPOLY]]) _path.append(Path(p, c)) else: @@ -3029,7 +3116,6 @@ return _path, _fillable - class Curve(_Curve): """ A simple curve without any arrow head. @@ -3041,8 +3127,6 @@ _style_list["-"] = Curve - - class CurveA(_Curve): """ An arrow with a head at its begin point. @@ -3057,9 +3141,9 @@ width of the arrow head """ - super(ArrowStyle.CurveA, self).__init__( \ - beginarrow=True, endarrow=False, - head_length=head_length, head_width=head_width ) + super(ArrowStyle.CurveA, self).__init__( + beginarrow=True, endarrow=False, + head_length=head_length, head_width=head_width) _style_list["<-"] = CurveA @@ -3077,14 +3161,12 @@ width of the arrow head """ - super(ArrowStyle.CurveB, self).__init__( \ + super(ArrowStyle.CurveB, self).__init__( beginarrow=False, endarrow=True, - head_length=head_length, head_width=head_width ) + head_length=head_length, head_width=head_width) - #_style_list["->"] = CurveB _style_list["->"] = CurveB - class CurveAB(_Curve): """ An arrow with heads both at the begin and the end point. @@ -3101,13 +3183,10 @@ super(ArrowStyle.CurveAB, self).__init__( \ beginarrow=True, endarrow=True, - head_length=head_length, head_width=head_width ) + head_length=head_length, head_width=head_width) - #_style_list["<->"] = CurveAB _style_list["<->"] = CurveAB - - class CurveFilledA(_Curve): """ An arrow with filled triangle head at the begin. @@ -3125,11 +3204,10 @@ super(ArrowStyle.CurveFilledA, self).__init__( \ beginarrow=True, endarrow=False, fillbegin=True, fillend=False, - head_length=head_length, head_width=head_width ) + head_length=head_length, head_width=head_width) _style_list["<|-"] = CurveFilledA - class CurveFilledB(_Curve): """ An arrow with filled triangle head at the end. @@ -3147,14 +3225,14 @@ super(ArrowStyle.CurveFilledB, self).__init__( \ beginarrow=False, endarrow=True, fillbegin=False, fillend=True, - head_length=head_length, head_width=head_width ) + head_length=head_length, head_width=head_width) _style_list["-|>"] = CurveFilledB - class CurveFilledAB(_Curve): """ - An arrow with filled triangle heads both at the begin and the end point. + An arrow with filled triangle heads both at the begin and the end + point. """ def __init__(self, head_length=.4, head_width=.2): @@ -3169,11 +3247,10 @@ super(ArrowStyle.CurveFilledAB, self).__init__( \ beginarrow=True, endarrow=True, fillbegin=True, fillend=True, - head_length=head_length, head_width=head_width ) + head_length=head_length, head_width=head_width) _style_list["<|-|>"] = CurveFilledAB - class _Bracket(_Base): def __init__(self, bracketA=None, bracketB=None, @@ -3181,16 +3258,16 @@ lengthA=0.2, lengthB=0.2, angleA=None, angleB=None, scaleA=None, scaleB=None - ): + ): self.bracketA, self.bracketB = bracketA, bracketB self.widthA, self.widthB = widthA, widthB self.lengthA, self.lengthB = lengthA, lengthB self.angleA, self.angleB = angleA, angleB - self.scaleA, self.scaleB= scaleA, scaleB + self.scaleA, self.scaleB = scaleA, scaleB def _get_bracket(self, x0, y0, cos_t, sin_t, width, length, - ): + ): # arrow from x0, y0 to x1, y1 from matplotlib.bezier import get_normal_points @@ -3198,10 +3275,10 @@ dx, dy = length * cos_t, length * sin_t - vertices_arrow = [(x1+dx, y1+dy), + vertices_arrow = [(x1 + dx, y1 + dy), (x1, y1), (x2, y2), - (x2+dx, y2+dy)] + (x2 + dx, y2 + dy)] codes_arrow = [Path.MOVETO, Path.LINETO, Path.LINETO, @@ -3209,7 +3286,6 @@ return vertices_arrow, codes_arrow - def transmute(self, path, mutation_size, linewidth): if self.scaleA is None: @@ -3229,8 +3305,8 @@ x1, y1 = path.vertices[1] cos_t, sin_t = get_cos_sin(x1, y1, x0, y0) verticesA, codesA = self._get_bracket(x0, y0, cos_t, sin_t, - self.widthA*scaleA, - self.lengthA*scaleA) + self.widthA * scaleA, + self.lengthA * scaleA) vertices_list.append(verticesA) codes_list.append(codesA) @@ -3242,12 +3318,11 @@ x1, y1 = path.vertices[-2] cos_t, sin_t = get_cos_sin(x1, y1, x0, y0) verticesB, codesB = self._get_bracket(x0, y0, cos_t, sin_t, - self.widthB*scaleB, - self.lengthB*scaleB) + self.widthB * scaleB, + self.lengthB * scaleB) vertices_list.append(verticesB) codes_list.append(codesB) - vertices = np.concatenate(vertices_list) codes = np.concatenate(codes_list) @@ -3289,7 +3364,6 @@ _style_list["]-["] = BracketAB - class BracketA(_Bracket): """ An arrow with a bracket(]) at its end. @@ -3308,11 +3382,10 @@ """ super(ArrowStyle.BracketA, self).__init__(True, None, - widthA=widthA, lengthA=lengthA, angleA=angleA ) + widthA=widthA, lengthA=lengthA, angleA=angleA) _style_list["]-"] = BracketA - class BracketB(_Bracket): """ An arrow with a bracket([) at its end. @@ -3331,11 +3404,10 @@ """ super(ArrowStyle.BracketB, self).__init__(None, True, - widthB=widthB, lengthB=lengthB, angleB=angleB ) + widthB=widthB, lengthB=lengthB, angleB=angleB) _style_list["-["] = BracketB - class BarAB(_Bracket): """ An arrow with a bar(|) at both ends. @@ -3370,7 +3442,6 @@ _style_list["|-|"] = BarAB - class Simple(_Base): """ A simple arrow. Only works with a quadratic bezier curve. @@ -3398,47 +3469,66 @@ x0, y0, x1, y1, x2, y2 = self.ensure_quadratic_bezier(path) # divide the path into a head and a tail - head_length = self.head_length * mutation_size + head_length = self.head_length * mutation_size in_f = inside_circle(x2, y2, head_length) arrow_path = [(x0, y0), (x1, y1), (x2, y2)] - arrow_out, arrow_in = \ - split_bezier_intersecting_with_closedpath(arrow_path, - in_f, - tolerence=0.01) + + from bezier import NonIntersectingPathException + + try: + arrow_out, arrow_in = \ + split_bezier_intersecting_with_closedpath(arrow_path, + in_f, + tolerence=0.01) + except NonIntersectingPathException: + # if this happens, make a straight line of the head_length long. + x0, y0 = _point_along_a_line(x2, y2, x1, y1, head_length) + x1n, y1n = 0.5*(x0+x2), 0.5*(y0+y2) + arrow_in = [(x0, y0), (x1n, y1n), (x2, y2)] + arrow_out = None # head head_width = self.head_width * mutation_size - head_l, head_r = make_wedged_bezier2(arrow_in, head_width/2., - wm=.5) - + head_left, head_right = \ + make_wedged_bezier2(arrow_in, head_width/2., + wm=.5) # tail - tail_width = self.tail_width * mutation_size - tail_left, tail_right = get_parallels(arrow_out, tail_width/2.) + if arrow_out is not None: + tail_width = self.tail_width * mutation_size + tail_left, tail_right = get_parallels(arrow_out, tail_width/2.) + + #head_right, head_left = head_r, head_l + patch_path = [(Path.MOVETO, tail_right[0]), + (Path.CURVE3, tail_right[1]), + (Path.CURVE3, tail_right[2]), + (Path.LINETO, head_right[0]), + (Path.CURVE3, head_right[1]), + (Path.CURVE3, head_right[2]), + (Path.CURVE3, head_left[1]), + (Path.CURVE3, head_left[0]), + (Path.LINETO, tail_left[2]), + (Path.CURVE3, tail_left[1]), + (Path.CURVE3, tail_left[0]), + (Path.LINETO, tail_right[0]), + (Path.CLOSEPOLY, tail_right[0]), + ] + else: + patch_path = [(Path.MOVETO, head_right[0]), + (Path.CURVE3, head_right[1]), + (Path.CURVE3, head_right[2]), + (Path.CURVE3, head_left[1]), + (Path.CURVE3, head_left[0]), + (Path.CLOSEPOLY, head_left[0]), + ] - head_right, head_left = head_r, head_l - patch_path = [(Path.MOVETO, tail_right[0]), - (Path.CURVE3, tail_right[1]), - (Path.CURVE3, tail_right[2]), - (Path.LINETO, head_right[0]), - (Path.CURVE3, head_right[1]), - (Path.CURVE3, head_right[2]), - (Path.CURVE3, head_left[1]), - (Path.CURVE3, head_left[0]), - (Path.LINETO, tail_left[2]), - (Path.CURVE3, tail_left[1]), - (Path.CURVE3, tail_left[0]), - (Path.LINETO, tail_right[0]), - (Path.CLOSEPOLY, tail_right[0]), - ] path = Path([p for c, p in patch_path], [c for c, p in patch_path]) return path, True _style_list["simple"] = Simple - class Fancy(_Base): """ A fancy arrow. Only works with a quadratic bezier curve. @@ -3466,7 +3556,7 @@ x0, y0, x1, y1, x2, y2 = self.ensure_quadratic_bezier(path) # divide the path into a head and a tail - head_length = self.head_length * mutation_size + head_length = self.head_length * mutation_size arrow_path = [(x0, y0), (x1, y1), (x2, y2)] from bezier import NonIntersectingPathException @@ -3475,45 +3565,47 @@ in_f = inside_circle(x2, y2, head_length) try: path_out, path_in = \ - split_bezier_intersecting_with_closedpath(arrow_path, - in_f, - tolerence=0.01) + split_bezier_intersecting_with_closedpath( + arrow_path, + in_f, + tolerence=0.01) except NonIntersectingPathException: # if this happens, make a straight line of the head_length long. - dx, dy = x2 - x1, y2 - y1 - ff = head_length/(dx*dx+dy*dy)**.5 - x0, y0 = x2 - ff*dx, y2 - ff*dy - arrow_path = [(x0, y0), (x1, y1), (x2, y2)] + x0, y0 = _point_along_a_line(x2, y2, x1, y1, head_length) + x1n, y1n = 0.5*(x0+x2), 0.5*(y0+y2) + arrow_path = [(x0, y0), (x1n, y1n), (x2, y2)] path_head = arrow_path else: path_head = path_in # path for head - in_f = inside_circle(x2, y2, head_length*.8) + in_f = inside_circle(x2, y2, head_length * .8) path_out, path_in = \ - split_bezier_intersecting_with_closedpath(arrow_path, - in_f, - tolerence=0.01) + split_bezier_intersecting_with_closedpath( + arrow_path, + in_f, + tolerence=0.01) path_tail = path_out - # head head_width = self.head_width * mutation_size - head_l, head_r = make_wedged_bezier2(path_head, head_width/2., + head_l, head_r = make_wedged_bezier2(path_head, + head_width / 2., wm=.6) # tail tail_width = self.tail_width * mutation_size tail_left, tail_right = make_wedged_bezier2(path_tail, - tail_width*.5, + tail_width * .5, w1=1., wm=0.6, w2=0.3) # path for head - in_f = inside_circle(x0, y0, tail_width*.3) + in_f = inside_circle(x0, y0, tail_width * .3) path_in, path_out = \ - split_bezier_intersecting_with_closedpath(arrow_path, - in_f, - tolerence=0.01) + split_bezier_intersecting_with_closedpath( + arrow_path, + in_f, + tolerence=0.01) tail_start = path_in[-1] head_right, head_left = head_r, head_l @@ -3538,7 +3630,6 @@ _style_list["fancy"] = Fancy - class Wedge(_Base): """ Wedge(?) shape. Only wokrs with a quadratic bezier curve. The @@ -3560,16 +3651,15 @@ self.shrink_factor = shrink_factor super(ArrowStyle.Wedge, self).__init__() - def transmute(self, path, mutation_size, linewidth): x0, y0, x1, y1, x2, y2 = self.ensure_quadratic_bezier(path) arrow_path = [(x0, y0), (x1, y1), (x2, y2)] - b_plus, b_minus = make_wedged_bezier2(arrow_path, - self.tail_width * mutation_size / 2., - wm=self.shrink_factor) - + b_plus, b_minus = make_wedged_bezier2( + arrow_path, + self.tail_width * mutation_size / 2., + wm=self.shrink_factor) patch_path = [(Path.MOVETO, b_plus[0]), (Path.CURVE3, b_plus[1]), @@ -3590,21 +3680,19 @@ {"AvailableArrowstyles": _pprint_styles(_style_list)} - docstring.interpd.update( - AvailableArrowstyles = _pprint_styles(ArrowStyle._style_list), - AvailableConnectorstyles = _pprint_styles(ConnectionStyle._style_list), + AvailableArrowstyles=_pprint_styles(ArrowStyle._style_list), + AvailableConnectorstyles=_pprint_styles(ConnectionStyle._style_list), ) + class FancyArrowPatch(Patch): """ A fancy arrow patch. It draws an arrow using the :class:ArrowStyle. """ - def __str__(self): - if self._posA_posB is not None: (x1, y1), (x2, y2) = self._posA_posB return self.__class__.__name__ \ @@ -3613,7 +3701,6 @@ return self.__class__.__name__ \ + "(%s)" % (str(self._path_original),) - @docstring.dedent_interpd def __init__(self, posA=None, posB=None, path=None, @@ -3691,9 +3778,8 @@ self.set_arrowstyle(arrowstyle) - - self._mutation_scale=mutation_scale - self._mutation_aspect=mutation_aspect + self._mutation_scale = mutation_scale + self._mutation_aspect = mutation_aspect self.set_dpi_cor(dpi_cor) #self._draw_in_display_coordinate = True @@ -3714,34 +3800,32 @@ return self._dpi_cor - def set_positions(self, posA, posB): """ set the begin end end positions of the connecting path. Use current vlaue if None. """ - if posA is not None: self._posA_posB[0] = posA - if posB is not None: self._posA_posB[1] = posB - + if posA is not None: + self._posA_posB[0] = posA + if posB is not None: + self._posA_posB[1] = posB def set_patchA(self, patchA): """ set the begin patch. """ self.patchA = patchA - def set_patchB(self, patchB): """ set the begin patch """ self.patchB = patchB - def set_connectionstyle(self, connectionstyle, **kw): """ Set the connection style. - *connectionstyle* can be a string with connectionstyle name with optional - comma-separated attributes. Alternatively, the attrs can - be probided as keywords. + *connectionstyle* can be a string with connectionstyle name with + optional comma-separated attributes. Alternatively, the attrs can be + probided as keywords. set_connectionstyle("arc,angleA=0,armA=30,rad=10") set_connectionstyle("arc", angleA=0,armA=30,rad=10) @@ -3752,7 +3836,7 @@ available styles as a list of strings. """ - if connectionstyle==None: + if connectionstyle == None: return ConnectionStyle.pprint_styles() if isinstance(connectionstyle, ConnectionStyle._Base): @@ -3763,14 +3847,12 @@ else: self._connector = ConnectionStyle(connectionstyle, **kw) - def get_connectionstyle(self): """ Return the ConnectionStyle instance """ return self._connector - def set_arrowstyle(self, arrowstyle=None, **kw): """ Set the arrow style. @@ -3788,7 +3870,7 @@ available box styles as a list of strings. """ - if arrowstyle==None: + if arrowstyle == None: return ArrowStyle.pprint_styles() if isinstance(arrowstyle, ConnectionStyle._Base): @@ -3802,14 +3884,13 @@ """ return self._arrow_transmuter - def set_mutation_scale(self, scale): """ Set the mutation scale. ACCEPTS: float """ - self._mutation_scale=scale + self._mutation_scale = scale def get_mutation_scale(self): """ @@ -3823,7 +3904,7 @@ ACCEPTS: float """ - self._mutation_aspect=aspect + self._mutation_aspect = aspect def get_mutation_aspect(self): """ @@ -3831,7 +3912,6 @@ """ return self._mutation_aspect - def get_path(self): """ return the path of the arrow in the data coordinate. Use @@ -3845,7 +3925,6 @@ return self.get_transform().inverted().transform_path(_path) - def get_path_in_displaycoord(self): """ Return the mutated path of the arrow in the display coord @@ -3859,29 +3938,26 @@ _path = self.get_connectionstyle()(posA, posB, patchA=self.patchA, patchB=self.patchB, - shrinkA=self.shrinkA*dpi_cor, - shrinkB=self.shrinkB*dpi_cor - ) + shrinkA=self.shrinkA * dpi_cor, + shrinkB=self.shrinkB * dpi_cor + ) else: _path = self.get_transform().transform_path(self._path_original) - - _path, fillable = self.get_arrowstyle()(_path, self.get_mutation_scale(), - self.get_linewidth()*dpi_cor, + self.get_linewidth() * dpi_cor, self.get_mutation_aspect() - ) + ) #if not fillable: # self._fill = False return _path, fillable - - def draw(self, renderer): - if not self.get_visible(): return + if not self.get_visible(): + return renderer.open_group('patch', self.get_gid()) gc = renderer.new_gc() @@ -3901,14 +3977,14 @@ rgbFace = self._facecolor if rgbFace[3] == 0: - rgbFace = None # (some?) renderers expect this as no-fill signal + rgbFace = None # (some?) renderers expect this as no-fill signal gc.set_alpha(self._edgecolor[3]) if self._edgecolor[3] == 0: gc.set_alpha(self._facecolor[3]) if self._hatch: - gc.set_hatch(self._hatch ) + gc.set_hatch(self._hatch) # FIXME : dpi_cor is for the dpi-dependecy of the # linewidth. There could be room for improvement. @@ -3921,10 +3997,8 @@ path = [path] fillable = [fillable] - affine = transforms.IdentityTransform() - if self.get_path_effects(): for path_effect in self.get_path_effects(): for p, f in zip(path, fillable): @@ -3939,7 +4013,6 @@ else: renderer.draw_path(gc, p, affine, None) - gc.restore() renderer.close_group('patch') @@ -3951,7 +4024,7 @@ """ def __str__(self): return "ConnectionPatch((%g,%g),(%g,%g))" % \ - (self.xy1[0],self.xy1[1],self.xy2[0],self.xy2[1]) + (self.xy1[0], self.xy1[1], self.xy2[0], self.xy2[1]) @docstring.dedent_interpd def __init__(self, xyA, xyB, coordsA, coordsB=None, @@ -4029,7 +4102,7 @@ self.axesB = axesB FancyArrowPatch.__init__(self, - posA=(0,0), posB=(1,1), + posA=(0, 0), posB=(1, 1), arrowstyle=arrowstyle, arrow_transmuter=arrow_transmuter, connectionstyle=connectionstyle, @@ -4047,7 +4120,6 @@ # if True, draw annotation only if self.xy is inside the axes self._annotation_clip = None - def _get_xy(self, x, y, s, axes=None): """ caculate the pixel position of given point @@ -4056,12 +4128,12 @@ if axes is None: axes = self.axes - if s=='data': + if s == 'data': trans = axes.transData x = float(self.convert_xunits(x)) y = float(self.convert_yunits(y)) return trans.transform_point((x, y)) - elif s=='offset points': + elif s == 'offset points': # convert the data point dx, dy = self.xy @@ -4073,79 +4145,79 @@ # convert the offset dpi = self.figure.get_dpi() - x *= dpi/72. - y *= dpi/72. + x *= dpi / 72. + y *= dpi / 72. # add the offset to the data point x += dx y += dy return x, y - elif s=='polar': + elif s == 'polar': theta, r = x, y - x = r*np.cos(theta) - y = r*np.sin(theta) + x = r * np.cos(theta) + y = r * np.sin(theta) trans = axes.transData - return trans.transform_point((x,y)) - elif s=='figure points': - #points from the lower left corner of the figure + return trans.transform_point((x, y)) + elif s == 'figure points': + # points from the lower left corner of the figure dpi = self.figure.dpi - l,b,w,h = self.figure.bbox.bounds - r = l+w - t = b+h - - x *= dpi/72. - y *= dpi/72. - if x<0: + l, b, w, h = self.figure.bbox.bounds + r = l + w + t = b + h + + x *= dpi / 72. + y *= dpi / 72. + if x < 0: x = r + x - if y<0: + if y < 0: y = t + y - return x,y - elif s=='figure pixels': - #pixels from the lower left corner of the figure - l,b,w,h = self.figure.bbox.bounds - r = l+w - t = b+h - if x<0: + return x, y + elif s == 'figure pixels': + # pixels from the lower left corner of the figure + l, b, w, h = self.figure.bbox.bounds + r = l + w + t = b + h + if x < 0: x = r + x - if y<0: + if y < 0: y = t + y return x, y - elif s=='figure fraction': - #(0,0) is lower left, (1,1) is upper right of figure + elif s == 'figure fraction': + # (0,0) is lower left, (1,1) is upper right of figure trans = self.figure.transFigure - return trans.transform_point((x,y)) - elif s=='axes points': - #points from the lower left corner of the axes + return trans.transform_point((x, y)) + elif s == 'axes points': + # points from the lower left corner of the axes dpi = self.figure.dpi - l,b,w,h = axes.bbox.bounds - r = l+w - t = b+h - if x<0: - x = r + x*dpi/72. + l, b, w, h = axes.bbox.bounds + r = l + w + t = b + h + if x < 0: + x = r + x * dpi / 72. else: - x = l + x*dpi/72. - if y<0: - y = t + y*dpi/72. + x = l + x * dpi / 72. + if y < 0: + y = t + y * dpi / 72. else: - y = b + y*dpi/72. + y = b + y * dpi / 72. return x, y - elif s=='axes pixels': + elif s == 'axes pixels': #pixels from the lower left corner of the axes - l,b,w,h = axes.bbox.bounds - r = l+w - t = b+h - if x<0: + l, b, w, h = axes.bbox.bounds + r = l + w + t = b + h + if x < 0: x = r + x else: x = l + x - if y<0: + if y < 0: y = t + y else: y = b + y return x, y - elif s=='axes fraction': + elif s == 'axes fraction': #(0,0) is lower left, (1,1) is upper right of axes trans = axes.transAxes return trans.transform_point((x, y)) @@ -4154,9 +4226,11 @@ """ set *annotation_clip* attribute. - * True : the annotation will only be drawn when self.xy is inside the axes. - * False : the annotation will always be drawn regardless of its position. - * None : the self.xy will be checked only if *xycoords* is "data" + * True: the annotation will only be drawn when self.xy is inside the + axes. + * False: the annotation will always be drawn regardless of its + position. + * None: the self.xy will be checked only if *xycoords* is "data" """ self._annotation_clip = b @@ -4167,7 +4241,6 @@ """ return self._annotation_clip - def get_path_in_displaycoord(self): """ Return the mutated path of the arrow in the display coord @@ -4184,22 +4257,18 @@ _path = self.get_connectionstyle()(posA, posB, patchA=self.patchA, patchB=self.patchB, - shrinkA=self.shrinkA*dpi_cor, - shrinkB=self.shrinkB*dpi_cor - ) - - + shrinkA=self.shrinkA * dpi_cor, + shrinkB=self.shrinkB * dpi_cor + ) _path, fillable = self.get_arrowstyle()(_path, self.get_mutation_scale(), - self.get_linewidth()*dpi_cor, + self.get_linewidth() * dpi_cor, self.get_mutation_aspect() - ) + ) return _path, fillable - - def _check_xy(self, renderer): """ check if the annotation need to @@ -4208,7 +4277,6 @@ b = self.get_annotation_clip() - if b or (b is None and self.coords1 == "data"): x, y = self.xy1 xy_pixel = self._get_xy(x, y, self.coords1, self.axesA) @@ -4227,7 +4295,6 @@ return True - def draw(self, renderer): """ Draw. @@ -4235,7 +4302,8 @@ if renderer is not None: self._renderer = renderer - if not self.get_visible(): return + if not self.get_visible(): + return if not self._check_xy(renderer): return diff -Nru matplotlib-1.1.1/lib/matplotlib/path.py matplotlib-1.2.0/lib/matplotlib/path.py --- matplotlib-1.1.1/lib/matplotlib/path.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/path.py 2012-10-31 00:11:14.000000000 +0000 @@ -2,6 +2,7 @@ Contains a class for managing paths (polylines). """ +from __future__ import print_function import math from weakref import WeakValueDictionary @@ -11,7 +12,7 @@ from matplotlib._path import point_in_path, get_path_extents, \ point_in_path_collection, get_path_collection_extents, \ path_in_path, path_intersects_path, convert_path_to_polygons, \ - cleanup_path + cleanup_path, points_in_path from matplotlib.cbook import simple_linear_interpolation, maxdict from matplotlib import rcParams @@ -279,12 +280,31 @@ If *transform* is not *None*, the path will be transformed before performing the test. + + *radius* allows the path to be made slightly larger or + smaller. """ if transform is not None: transform = transform.frozen() result = point_in_path(point[0], point[1], radius, self, transform) return result + def contains_points(self, points, transform=None, radius=0.0): + """ + Returns a bool array which is *True* if the path contains the + corresponding point. + + If *transform* is not *None*, the path will be transformed + before performing the test. + + *radius* allows the path to be made slightly larger or + smaller. + """ + if transform is not None: + transform = transform.frozen() + result = points_in_path(points, radius, self, transform) + return result + def contains_path(self, path, transform=None): """ Returns *True* if this path completely contains the given path. @@ -690,12 +710,53 @@ return hatch_path _get_path_collection_extents = get_path_collection_extents -def get_path_collection_extents(*args): +def get_path_collection_extents( + master_transform, paths, transforms, offsets, offset_transform): """ - Given a sequence of :class:`Path` objects, returns the bounding - box that encapsulates all of them. + Given a sequence of :class:`Path` objects, + :class:`~matplotlib.transforms.Transform` objects and offsets, as + found in a :class:`~matplotlib.collections.PathCollection`, + returns the bounding box that encapsulates all of them. + + *master_transform* is a global transformation to apply to all paths + + *paths* is a sequence of :class:`Path` instances. + + *transforms* is a sequence of + :class:`~matplotlib.transforms.Affine2D` instances. + + *offsets* is a sequence of (x, y) offsets (or an Nx2 array) + + *offset_transform* is a :class:`~matplotlib.transforms.Affine2D` + to apply to the offsets before applying the offset to the path. + + The way that *paths*, *transforms* and *offsets* are combined + follows the same method as for collections. Each is iterated over + independently, so if you have 3 paths, 2 transforms and 1 offset, + their combinations are as follows: + + (A, A, A), (B, B, A), (C, A, A) """ from transforms import Bbox - if len(args[1]) == 0: + if len(paths) == 0: + raise ValueError("No paths provided") + return Bbox.from_extents(*_get_path_collection_extents( + master_transform, paths, transforms, offsets, offset_transform)) + +def get_paths_extents(paths, transforms=[]): + """ + Given a sequence of :class:`Path` objects and optional + :class:`~matplotlib.transforms.Transform` objects, returns the + bounding box that encapsulates all of them. + + *paths* is a sequence of :class:`Path` instances. + + *transforms* is an optional sequence of + :class:`~matplotlib.transforms.Affine2D` instances to apply to + each path. + """ + from transforms import Bbox, Affine2D + if len(paths) == 0: raise ValueError("No paths provided") - return Bbox.from_extents(*_get_path_collection_extents(*args)) + return Bbox.from_extents(*_get_path_collection_extents( + Affine2D(), paths, transforms, [], Affine2D())) diff -Nru matplotlib-1.1.1/lib/matplotlib/patheffects.py matplotlib-1.2.0/lib/matplotlib/patheffects.py --- matplotlib-1.1.1/lib/matplotlib/patheffects.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/patheffects.py 2012-10-31 00:11:14.000000000 +0000 @@ -4,6 +4,7 @@ matplotlib.text.Text. """ +from __future__ import print_function from matplotlib.backend_bases import RendererBase from matplotlib.backends.backend_mixed import MixedModeRenderer import matplotlib.transforms as transforms diff -Nru matplotlib-1.1.1/lib/matplotlib/projections/__init__.py matplotlib-1.2.0/lib/matplotlib/projections/__init__.py --- matplotlib-1.1.1/lib/matplotlib/projections/__init__.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/projections/__init__.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function from geo import AitoffAxes, HammerAxes, LambertAxes, MollweideAxes from polar import PolarAxes from matplotlib import axes @@ -45,6 +46,7 @@ def register_projection(cls): projection_registry.register(cls) + def get_projection_class(projection=None): """ Get a projection class from its name. @@ -60,6 +62,7 @@ except KeyError: raise ValueError("Unknown projection '%s'" % projection) + def projection_factory(projection, figure, rect, **kwargs): """ Get a new projection instance. @@ -73,10 +76,61 @@ Any other kwargs are passed along to the specific projection constructor being used. + + .. deprecated:: 1.3 + + This routine is deprecated in favour of getting the projection + class directly with :func:`get_projection_class` and initialising it + directly. Will be removed in version 1.3. + """ return get_projection_class(projection)(figure, rect, **kwargs) + +def process_projection_requirements(figure, *args, **kwargs): + """ + Handle the args/kwargs to for add_axes/add_subplot/gca, + returning:: + + (axes_proj_class, proj_class_kwargs, proj_stack_key) + + Which can be used for new axes initialization/identification. + + .. note:: **kwargs** is modified in place. + + """ + ispolar = kwargs.pop('polar', False) + projection = kwargs.pop('projection', None) + if ispolar: + if projection is not None and projection != 'polar': + raise ValueError( + "polar=True, yet projection=%r. " + "Only one of these arguments should be supplied." % + projection) + projection = 'polar' + + # ensure that the resolution keyword is always put into the key + # for polar plots + if projection == 'polar': + kwargs.setdefault('resolution', 1) + + if isinstance(projection, basestring) or projection is None: + projection_class = get_projection_class(projection) + elif hasattr(projection, '_as_mpl_axes'): + projection_class, extra_kwargs = projection._as_mpl_axes() + kwargs.update(**extra_kwargs) + else: + raise TypeError('projection must be a string, None or implement a ' + '_as_mpl_axes method. Got %r' % projection) + + # Make the key without projection kwargs, this is used as a unique + # lookup for axes instances + key = figure._make_key(*args, **kwargs) + + return projection_class, kwargs, key + + def get_projection_names(): """ Get a list of acceptable projection names. diff -Nru matplotlib-1.1.1/lib/matplotlib/projections/geo.py matplotlib-1.2.0/lib/matplotlib/projections/geo.py --- matplotlib-1.1.1/lib/matplotlib/projections/geo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/projections/geo.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import math import numpy as np @@ -262,7 +263,7 @@ Transform.__init__(self) self._resolution = resolution - def transform(self, ll): + def transform_non_affine(self, ll): longitude = ll[:, 0:1] latitude = ll[:, 1:2] @@ -281,18 +282,12 @@ x = (cos_latitude * ma.sin(half_long)) / sinc_alpha y = (ma.sin(latitude) / sinc_alpha) return np.concatenate((x.filled(0), y.filled(0)), 1) - transform.__doc__ = Transform.transform.__doc__ - - transform_non_affine = transform transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__ - def transform_path(self, path): + def transform_path_non_affine(self, path): vertices = path.vertices ipath = path.interpolated(self._resolution) return Path(self.transform(ipath.vertices), ipath.codes) - transform_path.__doc__ = Transform.transform_path.__doc__ - - transform_path_non_affine = transform_path transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__ def inverted(self): @@ -308,10 +303,10 @@ Transform.__init__(self) self._resolution = resolution - def transform(self, xy): + def transform_non_affine(self, xy): # MGDTODO: Math is hard ;( return xy - transform.__doc__ = Transform.transform.__doc__ + transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__ def inverted(self): return AitoffAxes.AitoffTransform(self._resolution) @@ -347,7 +342,7 @@ Transform.__init__(self) self._resolution = resolution - def transform(self, ll): + def transform_non_affine(self, ll): longitude = ll[:, 0:1] latitude = ll[:, 1:2] @@ -360,18 +355,12 @@ x = (2.0 * sqrt2) * (cos_latitude * np.sin(half_long)) / alpha y = (sqrt2 * np.sin(latitude)) / alpha return np.concatenate((x, y), 1) - transform.__doc__ = Transform.transform.__doc__ - - transform_non_affine = transform transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__ - def transform_path(self, path): + def transform_path_non_affine(self, path): vertices = path.vertices ipath = path.interpolated(self._resolution) return Path(self.transform(ipath.vertices), ipath.codes) - transform_path.__doc__ = Transform.transform_path.__doc__ - - transform_path_non_affine = transform_path transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__ def inverted(self): @@ -387,7 +376,7 @@ Transform.__init__(self) self._resolution = resolution - def transform(self, xy): + def transform_non_affine(self, xy): x = xy[:, 0:1] y = xy[:, 1:2] @@ -397,7 +386,7 @@ longitude = 2 * np.arctan((z*x) / (2.0 * (2.0*z*z - 1.0))) latitude = np.arcsin(y*z) return np.concatenate((longitude, latitude), 1) - transform.__doc__ = Transform.transform.__doc__ + transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__ def inverted(self): return HammerAxes.HammerTransform(self._resolution) @@ -433,7 +422,7 @@ Transform.__init__(self) self._resolution = resolution - def transform(self, ll): + def transform_non_affine(self, ll): def d(theta): delta = -(theta + np.sin(theta) - pi_sin_l) / (1 + np.cos(theta)) return delta, np.abs(delta) > 0.001 @@ -465,18 +454,12 @@ xy[:,1] = np.sqrt(2.0) * np.sin(aux) return xy - transform.__doc__ = Transform.transform.__doc__ - - transform_non_affine = transform transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__ - def transform_path(self, path): + def transform_path_non_affine(self, path): vertices = path.vertices ipath = path.interpolated(self._resolution) return Path(self.transform(ipath.vertices), ipath.codes) - transform_path.__doc__ = Transform.transform_path.__doc__ - - transform_path_non_affine = transform_path transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__ def inverted(self): @@ -492,10 +475,10 @@ Transform.__init__(self) self._resolution = resolution - def transform(self, xy): + def transform_non_affine(self, xy): # MGDTODO: Math is hard ;( return xy - transform.__doc__ = Transform.transform.__doc__ + transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__ def inverted(self): return MollweideAxes.MollweideTransform(self._resolution) @@ -533,7 +516,7 @@ self._center_longitude = center_longitude self._center_latitude = center_latitude - def transform(self, ll): + def transform_non_affine(self, ll): longitude = ll[:, 0:1] latitude = ll[:, 1:2] clong = self._center_longitude @@ -554,18 +537,12 @@ np.sin(clat)*cos_lat*cos_diff_long) return np.concatenate((x, y), 1) - transform.__doc__ = Transform.transform.__doc__ - - transform_non_affine = transform transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__ - def transform_path(self, path): + def transform_path_non_affine(self, path): vertices = path.vertices ipath = path.interpolated(self._resolution) return Path(self.transform(ipath.vertices), ipath.codes) - transform_path.__doc__ = Transform.transform_path.__doc__ - - transform_path_non_affine = transform_path transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__ def inverted(self): @@ -586,7 +563,7 @@ self._center_longitude = center_longitude self._center_latitude = center_latitude - def transform(self, xy): + def transform_non_affine(self, xy): x = xy[:, 0:1] y = xy[:, 1:2] clong = self._center_longitude @@ -603,7 +580,7 @@ (x*sin_c) / (p*np.cos(clat)*cos_c - y*np.sin(clat)*sin_c)) return np.concatenate((long, lat), 1) - transform.__doc__ = Transform.transform.__doc__ + transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__ def inverted(self): return LambertAxes.LambertTransform( diff -Nru matplotlib-1.1.1/lib/matplotlib/projections/polar.py matplotlib-1.2.0/lib/matplotlib/projections/polar.py --- matplotlib-1.1.1/lib/matplotlib/projections/polar.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/projections/polar.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import math import warnings @@ -17,206 +18,208 @@ ScaledTranslation, blended_transform_factory, BboxTransformToMaxOnly import matplotlib.spines as mspines -class PolarAxes(Axes): - """ - A polar graph projection, where the input dimensions are *theta*, *r*. - Theta starts pointing east and goes anti-clockwise. +class PolarTransform(Transform): """ - name = 'polar' - - class PolarTransform(Transform): - """ - The base polar transform. This handles projection *theta* and - *r* into Cartesian coordinate space *x* and *y*, but does not - perform the ultimate affine transformation into the correct - position. - """ - input_dims = 2 - output_dims = 2 - is_separable = False - - def __init__(self, axis=None, use_rmin=True): - Transform.__init__(self) - self._axis = axis - self._use_rmin = use_rmin - - def transform(self, tr): - xy = np.empty(tr.shape, np.float_) - if self._axis is not None: - if self._use_rmin: - rmin = self._axis.viewLim.ymin - else: - rmin = 0 - theta_offset = self._axis.get_theta_offset() - theta_direction = self._axis.get_theta_direction() + The base polar transform. This handles projection *theta* and + *r* into Cartesian coordinate space *x* and *y*, but does not + perform the ultimate affine transformation into the correct + position. + """ + input_dims = 2 + output_dims = 2 + is_separable = False + + def __init__(self, axis=None, use_rmin=True): + Transform.__init__(self) + self._axis = axis + self._use_rmin = use_rmin + + def transform_non_affine(self, tr): + xy = np.empty(tr.shape, np.float_) + if self._axis is not None: + if self._use_rmin: + rmin = self._axis.viewLim.ymin else: rmin = 0 - theta_offset = 0 - theta_direction = 1 + theta_offset = self._axis.get_theta_offset() + theta_direction = self._axis.get_theta_direction() + else: + rmin = 0 + theta_offset = 0 + theta_direction = 1 + + t = tr[:, 0:1] + r = tr[:, 1:2] + x = xy[:, 0:1] + y = xy[:, 1:2] + + t *= theta_direction + t += theta_offset + + if rmin != 0: + r = r - rmin + mask = r < 0 + x[:] = np.where(mask, np.nan, r * np.cos(t)) + y[:] = np.where(mask, np.nan, r * np.sin(t)) + else: + x[:] = r * np.cos(t) + y[:] = r * np.sin(t) - t = tr[:, 0:1] - r = tr[:, 1:2] - x = xy[:, 0:1] - y = xy[:, 1:2] - - t *= theta_direction - t += theta_offset - - if rmin != 0: - r = r - rmin - mask = r < 0 - x[:] = np.where(mask, np.nan, r * np.cos(t)) - y[:] = np.where(mask, np.nan, r * np.sin(t)) - else: - x[:] = r * np.cos(t) - y[:] = r * np.sin(t) + return xy + transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__ - return xy - transform.__doc__ = Transform.transform.__doc__ + def transform_path_non_affine(self, path): + vertices = path.vertices + if len(vertices) == 2 and vertices[0, 0] == vertices[1, 0]: + return Path(self.transform(vertices), path.codes) + ipath = path.interpolated(path._interpolation_steps) + return Path(self.transform(ipath.vertices), ipath.codes) + transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__ + + def inverted(self): + return PolarAxes.InvertedPolarTransform(self._axis, self._use_rmin) + inverted.__doc__ = Transform.inverted.__doc__ - transform_non_affine = transform - transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__ - def transform_path(self, path): - vertices = path.vertices - if len(vertices) == 2 and vertices[0, 0] == vertices[1, 0]: - return Path(self.transform(vertices), path.codes) - ipath = path.interpolated(path._interpolation_steps) - return Path(self.transform(ipath.vertices), ipath.codes) - transform_path.__doc__ = Transform.transform_path.__doc__ - - transform_path_non_affine = transform_path - transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__ - - def inverted(self): - return PolarAxes.InvertedPolarTransform(self._axis, self._use_rmin) - inverted.__doc__ = Transform.inverted.__doc__ - - class PolarAffine(Affine2DBase): - """ - The affine part of the polar projection. Scales the output so - that maximum radius rests on the edge of the axes circle. - """ - def __init__(self, scale_transform, limits): - """ - *limits* is the view limit of the data. The only part of - its bounds that is used is ymax (for the radius maximum). - The theta range is always fixed to (0, 2pi). - """ - Affine2DBase.__init__(self) - self._scale_transform = scale_transform - self._limits = limits - self.set_children(scale_transform, limits) - self._mtx = None - - def get_matrix(self): - if self._invalid: - limits_scaled = self._limits.transformed(self._scale_transform) - yscale = limits_scaled.ymax - limits_scaled.ymin - affine = Affine2D() \ - .scale(0.5 / yscale) \ - .translate(0.5, 0.5) - self._mtx = affine.get_matrix() - self._inverted = None - self._invalid = 0 - return self._mtx - get_matrix.__doc__ = Affine2DBase.get_matrix.__doc__ - - class InvertedPolarTransform(Transform): - """ - The inverse of the polar transform, mapping Cartesian - coordinate space *x* and *y* back to *theta* and *r*. - """ - input_dims = 2 - output_dims = 2 - is_separable = False - - def __init__(self, axis=None, use_rmin=True): - Transform.__init__(self) - self._axis = axis - self._use_rmin = use_rmin - - def transform(self, xy): - if self._axis is not None: - if self._use_rmin: - rmin = self._axis.viewLim.ymin - else: - rmin = 0 - theta_offset = self._axis.get_theta_offset() - theta_direction = self._axis.get_theta_direction() +class PolarAffine(Affine2DBase): + """ + The affine part of the polar projection. Scales the output so + that maximum radius rests on the edge of the axes circle. + """ + def __init__(self, scale_transform, limits): + """ + *limits* is the view limit of the data. The only part of + its bounds that is used is ymax (for the radius maximum). + The theta range is always fixed to (0, 2pi). + """ + Affine2DBase.__init__(self) + self._scale_transform = scale_transform + self._limits = limits + self.set_children(scale_transform, limits) + self._mtx = None + + def get_matrix(self): + if self._invalid: + limits_scaled = self._limits.transformed(self._scale_transform) + yscale = limits_scaled.ymax - limits_scaled.ymin + affine = Affine2D() \ + .scale(0.5 / yscale) \ + .translate(0.5, 0.5) + self._mtx = affine.get_matrix() + self._inverted = None + self._invalid = 0 + return self._mtx + get_matrix.__doc__ = Affine2DBase.get_matrix.__doc__ + + def __getstate__(self): + return {} + + +class InvertedPolarTransform(Transform): + """ + The inverse of the polar transform, mapping Cartesian + coordinate space *x* and *y* back to *theta* and *r*. + """ + input_dims = 2 + output_dims = 2 + is_separable = False + + def __init__(self, axis=None, use_rmin=True): + Transform.__init__(self) + self._axis = axis + self._use_rmin = use_rmin + + def transform_non_affine(self, xy): + if self._axis is not None: + if self._use_rmin: + rmin = self._axis.viewLim.ymin else: rmin = 0 - theta_offset = 0 - theta_direction = 1 + theta_offset = self._axis.get_theta_offset() + theta_direction = self._axis.get_theta_direction() + else: + rmin = 0 + theta_offset = 0 + theta_direction = 1 - x = xy[:, 0:1] - y = xy[:, 1:] - r = np.sqrt(x*x + y*y) - theta = np.arccos(x / r) - theta = np.where(y < 0, 2 * np.pi - theta, theta) + x = xy[:, 0:1] + y = xy[:, 1:] + r = np.sqrt(x*x + y*y) + theta = np.arccos(x / r) + theta = np.where(y < 0, 2 * np.pi - theta, theta) - theta -= theta_offset - theta *= theta_direction + theta -= theta_offset + theta *= theta_direction - r += rmin + r += rmin - return np.concatenate((theta, r), 1) - transform.__doc__ = Transform.transform.__doc__ + return np.concatenate((theta, r), 1) + transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__ - def inverted(self): - return PolarAxes.PolarTransform(self._axis, self._use_rmin) - inverted.__doc__ = Transform.inverted.__doc__ + def inverted(self): + return PolarAxes.PolarTransform(self._axis, self._use_rmin) + inverted.__doc__ = Transform.inverted.__doc__ - class ThetaFormatter(Formatter): - """ - Used to format the *theta* tick labels. Converts the native - unit of radians into degrees and adds a degree symbol. - """ - def __call__(self, x, pos=None): - # \u00b0 : degree symbol - if rcParams['text.usetex'] and not rcParams['text.latex.unicode']: - return r"$%0.0f^\circ$" % ((x / np.pi) * 180.0) - else: - # we use unicode, rather than mathtext with \circ, so - # that it will work correctly with any arbitrary font - # (assuming it has a degree sign), whereas $5\circ$ - # will only work correctly with one of the supported - # math fonts (Computer Modern and STIX) - return u"%0.0f\u00b0" % ((x / np.pi) * 180.0) - class RadialLocator(Locator): - """ - Used to locate radius ticks. +class ThetaFormatter(Formatter): + """ + Used to format the *theta* tick labels. Converts the native + unit of radians into degrees and adds a degree symbol. + """ + def __call__(self, x, pos=None): + # \u00b0 : degree symbol + if rcParams['text.usetex'] and not rcParams['text.latex.unicode']: + return r"$%0.0f^\circ$" % ((x / np.pi) * 180.0) + else: + # we use unicode, rather than mathtext with \circ, so + # that it will work correctly with any arbitrary font + # (assuming it has a degree sign), whereas $5\circ$ + # will only work correctly with one of the supported + # math fonts (Computer Modern and STIX) + return u"%0.0f\u00b0" % ((x / np.pi) * 180.0) - Ensures that all ticks are strictly positive. For all other - tasks, it delegates to the base - :class:`~matplotlib.ticker.Locator` (which may be different - depending on the scale of the *r*-axis. - """ - def __init__(self, base): - self.base = base - def __call__(self): - ticks = self.base() - return [x for x in ticks if x > 0] +class RadialLocator(Locator): + """ + Used to locate radius ticks. + + Ensures that all ticks are strictly positive. For all other + tasks, it delegates to the base + :class:`~matplotlib.ticker.Locator` (which may be different + depending on the scale of the *r*-axis. + """ + def __init__(self, base): + self.base = base - def autoscale(self): - return self.base.autoscale() + def __call__(self): + ticks = self.base() + return [x for x in ticks if x > 0] - def pan(self, numsteps): - return self.base.pan(numsteps) + def autoscale(self): + return self.base.autoscale() - def zoom(self, direction): - return self.base.zoom(direction) + def pan(self, numsteps): + return self.base.pan(numsteps) - def refresh(self): - return self.base.refresh() + def zoom(self, direction): + return self.base.zoom(direction) - def view_limits(self, vmin, vmax): - vmin, vmax = self.base.view_limits(vmin, vmax) - return 0, vmax + def refresh(self): + return self.base.refresh() + def view_limits(self, vmin, vmax): + vmin, vmax = self.base.view_limits(vmin, vmax) + return 0, vmax + + +class PolarAxes(Axes): + """ + A polar graph projection, where the input dimensions are *theta*, *r*. + + Theta starts pointing east and goes anti-clockwise. + """ + name = 'polar' def __init__(self, *args, **kwargs): """ @@ -228,8 +231,10 @@ each pair of data points. Set to 1 to disable interpolation. """ + self.resolution = kwargs.pop('resolution', 1) + self._default_theta_offset = kwargs.pop('theta_offset', 0) + self._default_theta_direction = kwargs.pop('theta_direction', 1) - self.resolution = kwargs.pop('resolution', None) if self.resolution not in (None, 1): warnings.warn( """The resolution kwarg to Polar plots is now ignored. @@ -258,8 +263,8 @@ # Why do we need to turn on yaxis tick labels, but # xaxis tick labels are already on? - self.set_theta_offset(0) - self.set_theta_direction(1) + self.set_theta_offset(self._default_theta_offset) + self.set_theta_direction(self._default_theta_direction) def _init_axis(self): "move this out of __init__ because non-separable axes don't use it" @@ -454,8 +459,10 @@ self.yaxis.set_major_locator( self.RadialLocator(self.yaxis.get_major_locator())) - set_rscale = Axes.set_yscale - set_rticks = Axes.set_yticks + def set_rscale(self, *args, **kwargs): + return Axes.set_yscale(self, *args, **kwargs) + def set_rticks(self, *args, **kwargs): + return Axes.set_yticks(self, *args, **kwargs) @docstring.dedent_interpd def set_thetagrids(self, angles, labels=None, frac=None, fmt=None, @@ -484,6 +491,8 @@ ACCEPTS: sequence of floats """ + # Make sure we take into account unitized data + angles = self.convert_yunits(angles) angles = np.asarray(angles, np.float_) self.set_xticks(angles * (np.pi / 180.0)) if labels is not None: @@ -521,6 +530,8 @@ ACCEPTS: sequence of floats """ + # Make sure we take into account unitized data + radii = self.convert_xunits(radii) radii = np.asarray(radii) rmin = radii.min() if rmin <= 0: @@ -646,6 +657,17 @@ scale = r / startr self.set_rmax(p.rmax / scale) + +# to keep things all self contained, we can put aliases to the Polar classes +# defined above. This isn't strictly necessary, but it makes some of the +# code more readable (and provides a backwards compatible Polar API) +PolarAxes.PolarTransform = PolarTransform +PolarAxes.PolarAffine = PolarAffine +PolarAxes.InvertedPolarTransform = InvertedPolarTransform +PolarAxes.ThetaFormatter = ThetaFormatter +PolarAxes.RadialLocator = RadialLocator + + # These are a couple of aborted attempts to project a polar plot using # cubic bezier curves. diff -Nru matplotlib-1.1.1/lib/matplotlib/pylab.py matplotlib-1.2.0/lib/matplotlib/pylab.py --- matplotlib-1.1.1/lib/matplotlib/pylab.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/pylab.py 2012-11-06 18:15:05.000000000 +0000 @@ -213,6 +213,7 @@ """ +from __future__ import print_function import sys, warnings from cbook import flatten, is_string_like, exception_to_str, \ diff -Nru matplotlib-1.1.1/lib/matplotlib/pyparsing.py matplotlib-1.2.0/lib/matplotlib/pyparsing.py --- matplotlib-1.1.1/lib/matplotlib/pyparsing.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/pyparsing.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,3600 +0,0 @@ -# module pyparsing.py -# -# Copyright (c) 2003-2008 Paul T. McGuire -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -#from __future__ import generators - -__doc__ = \ -""" -pyparsing module - Classes and methods to define and execute parsing grammars - -The pyparsing module is an alternative approach to creating and executing simple grammars, -vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you -don't need to learn a new syntax for defining grammars or matching expressions - the parsing module -provides a library of classes that you use to construct the grammar directly in Python. - -Here is a program to parse "Hello, World!" (or any greeting of the form ", !"):: - - from pyparsing import Word, alphas - - # define grammar of a greeting - greet = Word( alphas ) + "," + Word( alphas ) + "!" - - hello = "Hello, World!" - print hello, "->", greet.parseString( hello ) - -The program outputs the following:: - - Hello, World! -> ['Hello', ',', 'World', '!'] - -The Python representation of the grammar is quite readable, owing to the self-explanatory -class names, and the use of '+', '|' and '^' operators. - -The parsed results returned from parseString() can be accessed as a nested list, a dictionary, or an -object with named attributes. - -The pyparsing module handles some of the problems that are typically vexing when writing text parsers: - - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello , World !", etc.) - - quoted strings - - embedded comments -""" - -__version__ = "1.5.0" -__versionTime__ = "28 May 2008 10:05" -__author__ = "Paul McGuire " - -import string -from weakref import ref as wkref -import copy,sys -import warnings -import re -import sre_constants -import xml.sax.saxutils -#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) ) - -__all__ = [ -'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty', -'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal', -'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or', -'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException', -'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException', -'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', 'Upcase', -'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore', -'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col', -'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString', -'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'getTokensEndLoc', 'hexnums', -'htmlComment', 'javaStyleComment', 'keepOriginalText', 'line', 'lineEnd', 'lineStart', 'lineno', -'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral', -'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables', -'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', -'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd', -'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute', -'indentedBlock', -] - - -""" -Detect if we are running version 3.X and make appropriate changes -Robert A. Clark -""" -if sys.version_info[0] > 2: - _PY3K = True - _MAX_INT = sys.maxsize - basestring = str -else: - _PY3K = False - _MAX_INT = sys.maxint - -if not _PY3K: - def _ustr(obj): - """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries - str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It - then < returns the unicode object | encodes it with the default encoding | ... >. - """ - try: - # If this works, then _ustr(obj) has the same behaviour as str(obj), so - # it won't break any existing code. - return str(obj) - - except UnicodeEncodeError: - # The Python docs (http://docs.python.org/ref/customization.html#l2h-182) - # state that "The return value must be a string object". However, does a - # unicode object (being a subclass of basestring) count as a "string - # object"? - # If so, then return a unicode object: - return unicode(obj) - # Else encode it... but how? There are many choices... :) - # Replace unprintables with escape codes? - #return unicode(obj).encode(sys.getdefaultencoding(), 'backslashreplace_errors') - # Replace unprintables with question marks? - #return unicode(obj).encode(sys.getdefaultencoding(), 'replace') - # ... -else: - _ustr = str - -def _str2dict(strg): - return dict( [(c,0) for c in strg] ) - #~ return set( [c for c in strg] ) - -class _Constants(object): - pass - -if not _PY3K: - alphas = string.lowercase + string.uppercase -else: - alphas = string.ascii_lowercase + string.ascii_uppercase -nums = string.digits -hexnums = nums + "ABCDEFabcdef" -alphanums = alphas + nums -_bslash = "\\" -printables = "".join( [ c for c in string.printable if c not in string.whitespace ] ) - -class ParseBaseException(Exception): - """base exception class for all parsing runtime exceptions""" - __slots__ = ( "loc","msg","pstr","parserElement" ) - # Performance tuning: we construct a *lot* of these, so keep this - # constructor as small and fast as possible - def __init__( self, pstr, loc=0, msg=None, elem=None ): - self.loc = loc - if msg is None: - self.msg = pstr - self.pstr = "" - else: - self.msg = msg - self.pstr = pstr - self.parserElement = elem - - def __getattr__( self, aname ): - """supported attributes by name are: - - lineno - returns the line number of the exception text - - col - returns the column number of the exception text - - line - returns the line containing the exception text - """ - if( aname == "lineno" ): - return lineno( self.loc, self.pstr ) - elif( aname in ("col", "column") ): - return col( self.loc, self.pstr ) - elif( aname == "line" ): - return line( self.loc, self.pstr ) - else: - raise AttributeError(aname) - - def __str__( self ): - return "%s (at char %d), (line:%d, col:%d)" % \ - ( self.msg, self.loc, self.lineno, self.column ) - def __repr__( self ): - return _ustr(self) - def markInputline( self, markerString = ">!<" ): - """Extracts the exception line from the input string, and marks - the location of the exception with a special symbol. - """ - line_str = self.line - line_column = self.column - 1 - if markerString: - line_str = "".join( [line_str[:line_column], - markerString, line_str[line_column:]]) - return line_str.strip() - -class ParseException(ParseBaseException): - """exception thrown when parse expressions don't match class; - supported attributes by name are: - - lineno - returns the line number of the exception text - - col - returns the column number of the exception text - - line - returns the line containing the exception text - """ - pass - -class ParseFatalException(ParseBaseException): - """user-throwable exception thrown when inconsistent parse content - is found; stops all parsing immediately""" - pass - -class ParseSyntaxException(ParseFatalException): - """just like ParseFatalException, but thrown internally when an - ErrorStop indicates that parsing is to stop immediately because - an unbacktrackable syntax error has been found""" - def __init__(self, pe): - ParseFatalException.__init__(self, pe.pstr, pe.loc, pe.msg, pe.parserElement) - -#~ class ReparseException(ParseBaseException): - #~ """Experimental class - parse actions can raise this exception to cause - #~ pyparsing to reparse the input string: - #~ - with a modified input string, and/or - #~ - with a modified start location - #~ Set the values of the ReparseException in the constructor, and raise the - #~ exception in a parse action to cause pyparsing to use the new string/location. - #~ Setting the values as None causes no change to be made. - #~ """ - #~ def __init_( self, newstring, restartLoc ): - #~ self.newParseText = newstring - #~ self.reparseLoc = restartLoc - -class RecursiveGrammarException(Exception): - """exception thrown by validate() if the grammar could be improperly recursive""" - def __init__( self, parseElementList ): - self.parseElementTrace = parseElementList - - def __str__( self ): - return "RecursiveGrammarException: %s" % self.parseElementTrace - -class _ParseResultsWithOffset(object): - def __init__(self,p1,p2): - self.tup = (p1,p2) - def __getitem__(self,i): - return self.tup[i] - def __repr__(self): - return repr(self.tup) - -class ParseResults(object): - """Structured parse results, to provide multiple means of access to the parsed data: - - as a list (len(results)) - - by list index (results[0], results[1], etc.) - - by attribute (results.) - """ - __slots__ = ( "__toklist", "__tokdict", "__doinit", "__name", "__parent", "__accumNames", "__weakref__" ) - def __new__(cls, toklist, name=None, asList=True, modal=True ): - if isinstance(toklist, cls): - return toklist - retobj = object.__new__(cls) - retobj.__doinit = True - return retobj - - # Performance tuning: we construct a *lot* of these, so keep this - # constructor as small and fast as possible - def __init__( self, toklist, name=None, asList=True, modal=True ): - if self.__doinit: - self.__doinit = False - self.__name = None - self.__parent = None - self.__accumNames = {} - if isinstance(toklist, list): - self.__toklist = toklist[:] - else: - self.__toklist = [toklist] - self.__tokdict = dict() - - # this line is related to debugging the asXML bug - #~ asList = False - - if name: - if not modal: - self.__accumNames[name] = 0 - if isinstance(name,int): - name = _ustr(name) # will always return a str, but use _ustr for consistency - self.__name = name - if not toklist in (None,'',[]): - if isinstance(toklist,basestring): - toklist = [ toklist ] - if asList: - if isinstance(toklist,ParseResults): - self[name] = _ParseResultsWithOffset(toklist.copy(),-1) - else: - self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),-1) - self[name].__name = name - else: - try: - self[name] = toklist[0] - except (KeyError,TypeError): - self[name] = toklist - - def __getitem__( self, i ): - if isinstance( i, (int,slice) ): - return self.__toklist[i] - else: - if i not in self.__accumNames: - return self.__tokdict[i][-1][0] - else: - return ParseResults([ v[0] for v in self.__tokdict[i] ]) - - def __setitem__( self, k, v ): - if isinstance(v,_ParseResultsWithOffset): - self.__tokdict[k] = self.__tokdict.get(k,list()) + [v] - sub = v[0] - elif isinstance(k,int): - self.__toklist[k] = v - sub = v - else: - self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)] - sub = v - if isinstance(sub,ParseResults): - sub.__parent = wkref(self) - - def __delitem__( self, i ): - if isinstance(i,(int,slice)): - mylen = len( self.__toklist ) - del self.__toklist[i] - - # convert int to slice - if isinstance(i, int): - if i < 0: - i += mylen - i = slice(i, i+1) - # get removed indices - removed = list(range(*i.indices(mylen))) - removed.reverse() - # fixup indices in token dictionary - for name in self.__tokdict: - occurrences = self.__tokdict[name] - for j in removed: - for k, (value, position) in enumerate(occurrences): - occurrences[k] = _ParseResultsWithOffset(value, position - (position > j)) - else: - del self.__tokdict[i] - - def __contains__( self, k ): - return k in self.__tokdict - - def __len__( self ): return len( self.__toklist ) - def __bool__(self): return len( self.__toklist ) > 0 - __nonzero__ = __bool__ - def __iter__( self ): return iter( self.__toklist ) - def __reversed__( self ): return iter( reversed(self.__toklist) ) - def keys( self ): - """Returns all named result keys.""" - return self.__tokdict.keys() - - def pop( self, index=-1 ): - """Removes and returns item at specified index (default=last). - Will work with either numeric indices or dict-key indicies.""" - ret = self[index] - del self[index] - return ret - - def get(self, key, defaultValue=None): - """Returns named result matching the given key, or if there is no - such name, then returns the given defaultValue or None if no - defaultValue is specified.""" - if key in self: - return self[key] - else: - return defaultValue - - def insert( self, index, insStr ): - self.__toklist.insert(index, insStr) - # fixup indices in token dictionary - for name in self.__tokdict: - occurrences = self.__tokdict[name] - for k, (value, position) in enumerate(occurrences): - occurrences[k] = _ParseResultsWithOffset(value, position + (position > j)) - - def items( self ): - """Returns all named result keys and values as a list of tuples.""" - return [(k,self[k]) for k in self.__tokdict] - - def values( self ): - """Returns all named result values.""" - return [ v[-1][0] for v in self.__tokdict.values() ] - - def __getattr__( self, name ): - if name not in self.__slots__: - if name in self.__tokdict: - if name not in self.__accumNames: - return self.__tokdict[name][-1][0] - else: - return ParseResults([ v[0] for v in self.__tokdict[name] ]) - else: - return "" - return None - - def __add__( self, other ): - ret = self.copy() - ret += other - return ret - - def __iadd__( self, other ): - if other.__tokdict: - offset = len(self.__toklist) - addoffset = ( lambda a: (a<0 and offset) or (a+offset) ) - otheritems = other.__tokdict.items() - otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) ) - for (k,vlist) in otheritems for v in vlist] - for k,v in otherdictitems: - self[k] = v - if isinstance(v[0],ParseResults): - v[0].__parent = wkref(self) - self.__toklist += other.__toklist - self.__accumNames.update( other.__accumNames ) - del other - return self - - def __repr__( self ): - return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) ) - - def __str__( self ): - out = "[" - sep = "" - for i in self.__toklist: - if isinstance(i, ParseResults): - out += sep + _ustr(i) - else: - out += sep + repr(i) - sep = ", " - out += "]" - return out - - def _asStringList( self, sep='' ): - out = [] - for item in self.__toklist: - if out and sep: - out.append(sep) - if isinstance( item, ParseResults ): - out += item._asStringList() - else: - out.append( _ustr(item) ) - return out - - def asList( self ): - """Returns the parse results as a nested list of matching tokens, all converted to strings.""" - out = [] - for res in self.__toklist: - if isinstance(res,ParseResults): - out.append( res.asList() ) - else: - out.append( res ) - return out - - def asDict( self ): - """Returns the named parse results as dictionary.""" - return dict( self.items() ) - - def copy( self ): - """Returns a new copy of a ParseResults object.""" - ret = ParseResults( self.__toklist ) - ret.__tokdict = self.__tokdict.copy() - ret.__parent = self.__parent - ret.__accumNames.update( self.__accumNames ) - ret.__name = self.__name - return ret - - def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ): - """Returns the parse results as XML. Tags are created for tokens and lists that have defined results names.""" - nl = "\n" - out = [] - namedItems = dict( [ (v[1],k) for (k,vlist) in self.__tokdict.items() - for v in vlist ] ) - nextLevelIndent = indent + " " - - # collapse out indents if formatting is not desired - if not formatted: - indent = "" - nextLevelIndent = "" - nl = "" - - selfTag = None - if doctag is not None: - selfTag = doctag - else: - if self.__name: - selfTag = self.__name - - if not selfTag: - if namedItemsOnly: - return "" - else: - selfTag = "ITEM" - - out += [ nl, indent, "<", selfTag, ">" ] - - worklist = self.__toklist - for i,res in enumerate(worklist): - if isinstance(res,ParseResults): - if i in namedItems: - out += [ res.asXML(namedItems[i], - namedItemsOnly and doctag is None, - nextLevelIndent, - formatted)] - else: - out += [ res.asXML(None, - namedItemsOnly and doctag is None, - nextLevelIndent, - formatted)] - else: - # individual token, see if there is a name for it - resTag = None - if i in namedItems: - resTag = namedItems[i] - if not resTag: - if namedItemsOnly: - continue - else: - resTag = "ITEM" - xmlBodyText = xml.sax.saxutils.escape(_ustr(res)) - out += [ nl, nextLevelIndent, "<", resTag, ">", - xmlBodyText, - "" ] - - out += [ nl, indent, "" ] - return "".join(out) - - def __lookup(self,sub): - for k,vlist in self.__tokdict.items(): - for v,loc in vlist: - if sub is v: - return k - return None - - def getName(self): - """Returns the results name for this token expression.""" - if self.__name: - return self.__name - elif self.__parent: - par = self.__parent() - if par: - return par.__lookup(self) - else: - return None - elif (len(self) == 1 and - len(self.__tokdict) == 1 and - self.__tokdict.values()[0][0][1] in (0,-1)): - return self.__tokdict.keys()[0] - else: - return None - - def dump(self,indent='',depth=0): - """Diagnostic method for listing out the contents of a ParseResults. - Accepts an optional indent argument so that this string can be embedded - in a nested display of other data.""" - out = [] - out.append( indent+_ustr(self.asList()) ) - keys = self.items() - keys.sort() - for k,v in keys: - if out: - out.append('\n') - out.append( "%s%s- %s: " % (indent,(' '*depth), k) ) - if isinstance(v,ParseResults): - if v.keys(): - #~ out.append('\n') - out.append( v.dump(indent,depth+1) ) - #~ out.append('\n') - else: - out.append(_ustr(v)) - else: - out.append(_ustr(v)) - #~ out.append('\n') - return "".join(out) - - # add support for pickle protocol - def __getstate__(self): - return ( self.__toklist, - ( self.__tokdict.copy(), - self.__parent is not None and self.__parent() or None, - self.__accumNames, - self.__name ) ) - - def __setstate__(self,state): - self.__toklist = state[0] - self.__tokdict, \ - par, \ - inAccumNames, \ - self.__name = state[1] - self.__accumNames = {} - self.__accumNames.update(inAccumNames) - if par is not None: - self.__parent = wkref(par) - else: - self.__parent = None - - -def col (loc,strg): - """Returns current column within a string, counting newlines as line separators. - The first column is number 1. - - Note: the default parsing behavior is to expand tabs in the input string - before starting the parsing process. See L{I{ParserElement.parseString}} for more information - on parsing strings containing s, and suggested methods to maintain a - consistent view of the parsed string, the parse location, and line and column - positions within the parsed string. - """ - return (loc} for more information - on parsing strings containing s, and suggested methods to maintain a - consistent view of the parsed string, the parse location, and line and column - positions within the parsed string. - """ - return strg.count("\n",0,loc) + 1 - -def line( loc, strg ): - """Returns the line of text containing loc within a string, counting newlines as line separators. - """ - lastCR = strg.rfind("\n", 0, loc) - nextCR = strg.find("\n", loc) - if nextCR > 0: - return strg[lastCR+1:nextCR] - else: - return strg[lastCR+1:] - -def _defaultStartDebugAction( instring, loc, expr ): - print ("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )) - -def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ): - print ("Matched " + _ustr(expr) + " -> " + str(toks.asList())) - -def _defaultExceptionDebugAction( instring, loc, expr, exc ): - print ("Exception raised:" + _ustr(exc)) - -def nullDebugAction(*args): - """'Do-nothing' debug action, to suppress debugging output during parsing.""" - pass - -class ParserElement(object): - """Abstract base level parser element class.""" - DEFAULT_WHITE_CHARS = " \n\t\r" - - def setDefaultWhitespaceChars( chars ): - """Overrides the default whitespace chars - """ - ParserElement.DEFAULT_WHITE_CHARS = chars - setDefaultWhitespaceChars = staticmethod(setDefaultWhitespaceChars) - - def __init__( self, savelist=False ): - self.parseAction = list() - self.failAction = None - #~ self.name = "" # don't define self.name, let subclasses try/except upcall - self.strRepr = None - self.resultsName = None - self.saveAsList = savelist - self.skipWhitespace = True - self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS - self.copyDefaultWhiteChars = True - self.mayReturnEmpty = False # used when checking for left-recursion - self.keepTabs = False - self.ignoreExprs = list() - self.debug = False - self.streamlined = False - self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index - self.errmsg = "" - self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all) - self.debugActions = ( None, None, None ) #custom debug actions - self.re = None - self.callPreparse = True # used to avoid redundant calls to preParse - self.callDuringTry = False - - def copy( self ): - """Make a copy of this ParserElement. Useful for defining different parse actions - for the same parsing pattern, using copies of the original parse element.""" - cpy = copy.copy( self ) - cpy.parseAction = self.parseAction[:] - cpy.ignoreExprs = self.ignoreExprs[:] - if self.copyDefaultWhiteChars: - cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS - return cpy - - def setName( self, name ): - """Define name for this expression, for use in debugging.""" - self.name = name - self.errmsg = "Expected " + self.name - if hasattr(self,"exception"): - self.exception.msg = self.errmsg - return self - - def setResultsName( self, name, listAllMatches=False ): - """Define name for referencing matching tokens as a nested attribute - of the returned parse results. - NOTE: this returns a *copy* of the original ParserElement object; - this is so that the client can define a basic element, such as an - integer, and reference it in multiple places with different names. - """ - newself = self.copy() - newself.resultsName = name - newself.modalResults = not listAllMatches - return newself - - def setBreak(self,breakFlag = True): - """Method to invoke the Python pdb debugger when this element is - about to be parsed. Set breakFlag to True to enable, False to - disable. - """ - if breakFlag: - _parseMethod = self._parse - def breaker(instring, loc, doActions=True, callPreParse=True): - import pdb - pdb.set_trace() - _parseMethod( instring, loc, doActions, callPreParse ) - breaker._originalParseMethod = _parseMethod - self._parse = breaker - else: - if hasattr(self._parse,"_originalParseMethod"): - self._parse = self._parse._originalParseMethod - return self - - def _normalizeParseActionArgs( f ): - """Internal method used to decorate parse actions that take fewer than 3 arguments, - so that all parse actions can be called as f(s,l,t).""" - STAR_ARGS = 4 - - try: - restore = None - if isinstance(f,type): - restore = f - f = f.__init__ - if not _PY3K: - codeObj = f.func_code - else: - codeObj = f.code - if codeObj.co_flags & STAR_ARGS: - return f - numargs = codeObj.co_argcount - if not _PY3K: - if hasattr(f,"im_self"): - numargs -= 1 - else: - if hasattr(f,"__self__"): - numargs -= 1 - if restore: - f = restore - except AttributeError: - try: - if not _PY3K: - call_im_func_code = f.__call__.im_func.func_code - else: - call_im_func_code = f.__code__ - - # not a function, must be a callable object, get info from the - # im_func binding of its bound __call__ method - if call_im_func_code.co_flags & STAR_ARGS: - return f - numargs = call_im_func_code.co_argcount - if not _PY3K: - if hasattr(f.__call__,"im_self"): - numargs -= 1 - else: - if hasattr(f.__call__,"__self__"): - numargs -= 0 - except AttributeError: - if not _PY3K: - call_func_code = f.__call__.func_code - else: - call_func_code = f.__call__.__code__ - # not a bound method, get info directly from __call__ method - if call_func_code.co_flags & STAR_ARGS: - return f - numargs = call_func_code.co_argcount - if not _PY3K: - if hasattr(f.__call__,"im_self"): - numargs -= 1 - else: - if hasattr(f.__call__,"__self__"): - numargs -= 1 - - - #~ print ("adding function %s with %d args" % (f.func_name,numargs)) - if numargs == 3: - return f - else: - if numargs > 3: - def tmp(s,l,t): - return f(f.__call__.__self__, s,l,t) - if numargs == 2: - def tmp(s,l,t): - return f(l,t) - elif numargs == 1: - def tmp(s,l,t): - return f(t) - else: #~ numargs == 0: - def tmp(s,l,t): - return f() - try: - tmp.__name__ = f.__name__ - except (AttributeError,TypeError): - # no need for special handling if attribute doesnt exist - pass - try: - tmp.__doc__ = f.__doc__ - except (AttributeError,TypeError): - # no need for special handling if attribute doesnt exist - pass - try: - tmp.__dict__.update(f.__dict__) - except (AttributeError,TypeError): - # no need for special handling if attribute doesnt exist - pass - return tmp - _normalizeParseActionArgs = staticmethod(_normalizeParseActionArgs) - - def setParseAction( self, *fns, **kwargs ): - """Define action to perform when successfully matching parse element definition. - Parse action fn is a callable method with 0-3 arguments, called as fn(s,loc,toks), - fn(loc,toks), fn(toks), or just fn(), where: - - s = the original string being parsed (see note below) - - loc = the location of the matching substring - - toks = a list of the matched tokens, packaged as a ParseResults object - If the functions in fns modify the tokens, they can return them as the return - value from fn, and the modified list of tokens will replace the original. - Otherwise, fn does not need to return any value. - - Note: the default parsing behavior is to expand tabs in the input string - before starting the parsing process. See L{I{parseString}} for more information - on parsing strings containing s, and suggested methods to maintain a - consistent view of the parsed string, the parse location, and line and column - positions within the parsed string. - """ - self.parseAction = list(map(self._normalizeParseActionArgs, list(fns))) - self.callDuringTry = ("callDuringTry" in kwargs and kwargs["callDuringTry"]) - return self - - def addParseAction( self, *fns, **kwargs ): - """Add parse action to expression's list of parse actions. See L{I{setParseAction}}.""" - self.parseAction += list(map(self._normalizeParseActionArgs, list(fns))) - self.callDuringTry = self.callDuringTry or ("callDuringTry" in kwargs and kwargs["callDuringTry"]) - return self - - def setFailAction( self, fn ): - """Define action to perform if parsing fails at this expression. - Fail acton fn is a callable function that takes the arguments - fn(s,loc,expr,err) where: - - s = string being parsed - - loc = location where expression match was attempted and failed - - expr = the parse expression that failed - - err = the exception thrown - The function returns no value. It may throw ParseFatalException - if it is desired to stop parsing immediately.""" - self.failAction = fn - return self - - def _skipIgnorables( self, instring, loc ): - exprsFound = True - while exprsFound: - exprsFound = False - for e in self.ignoreExprs: - try: - while 1: - loc,dummy = e._parse( instring, loc ) - exprsFound = True - except ParseException: - pass - return loc - - def preParse( self, instring, loc ): - if self.ignoreExprs: - loc = self._skipIgnorables( instring, loc ) - - if self.skipWhitespace: - wt = self.whiteChars - instrlen = len(instring) - while loc < instrlen and instring[loc] in wt: - loc += 1 - - return loc - - def parseImpl( self, instring, loc, doActions=True ): - return loc, [] - - def postParse( self, instring, loc, tokenlist ): - return tokenlist - - #~ @profile - def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ): - debugging = ( self.debug ) #and doActions ) - - if debugging or self.failAction: - #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )) - if (self.debugActions[0] ): - self.debugActions[0]( instring, loc, self ) - if callPreParse and self.callPreparse: - preloc = self.preParse( instring, loc ) - else: - preloc = loc - tokensStart = loc - try: - try: - loc,tokens = self.parseImpl( instring, preloc, doActions ) - except IndexError: - raise ParseException( instring, len(instring), self.errmsg, self ) - except ParseBaseException, err: - #~ print ("Exception raised:", err) - if self.debugActions[2]: - self.debugActions[2]( instring, tokensStart, self, err ) - if self.failAction: - self.failAction( instring, tokensStart, self, err ) - raise - else: - if callPreParse and self.callPreparse: - preloc = self.preParse( instring, loc ) - else: - preloc = loc - tokensStart = loc - if self.mayIndexError or loc >= len(instring): - try: - loc,tokens = self.parseImpl( instring, preloc, doActions ) - except IndexError: - raise ParseException( instring, len(instring), self.errmsg, self ) - else: - loc,tokens = self.parseImpl( instring, preloc, doActions ) - - tokens = self.postParse( instring, loc, tokens ) - - retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults ) - if self.parseAction and (doActions or self.callDuringTry): - if debugging: - try: - for fn in self.parseAction: - tokens = fn( instring, tokensStart, retTokens ) - if tokens is not None: - retTokens = ParseResults( tokens, - self.resultsName, - asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), - modal=self.modalResults ) - except ParseBaseException, err: - #~ print "Exception raised in user parse action:", err - if (self.debugActions[2] ): - self.debugActions[2]( instring, tokensStart, self, err ) - raise - else: - for fn in self.parseAction: - tokens = fn( instring, tokensStart, retTokens ) - if tokens is not None: - retTokens = ParseResults( tokens, - self.resultsName, - asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), - modal=self.modalResults ) - - if debugging: - #~ print ("Matched",self,"->",retTokens.asList()) - if (self.debugActions[1] ): - self.debugActions[1]( instring, tokensStart, loc, self, retTokens ) - - return loc, retTokens - - def tryParse( self, instring, loc ): - try: - return self._parse( instring, loc, doActions=False )[0] - except ParseFatalException: - raise ParseException( instring, loc, self.errmsg, self) - - # this method gets repeatedly called during backtracking with the same arguments - - # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression - def _parseCache( self, instring, loc, doActions=True, callPreParse=True ): - lookup = (self,instring,loc,callPreParse,doActions) - if lookup in ParserElement._exprArgCache: - value = ParserElement._exprArgCache[ lookup ] - if isinstance(value,Exception): - raise value - return value - else: - try: - value = self._parseNoCache( instring, loc, doActions, callPreParse ) - ParserElement._exprArgCache[ lookup ] = (value[0],value[1].copy()) - return value - except ParseBaseException, pe: - ParserElement._exprArgCache[ lookup ] = pe - raise - - _parse = _parseNoCache - - # argument cache for optimizing repeated calls when backtracking through recursive expressions - _exprArgCache = {} - def resetCache(): - ParserElement._exprArgCache.clear() - resetCache = staticmethod(resetCache) - - _packratEnabled = False - def enablePackrat(): - """Enables "packrat" parsing, which adds memoizing to the parsing logic. - Repeated parse attempts at the same string location (which happens - often in many complex grammars) can immediately return a cached value, - instead of re-executing parsing/validating code. Memoizing is done of - both valid results and parsing exceptions. - - This speedup may break existing programs that use parse actions that - have side-effects. For this reason, packrat parsing is disabled when - you first import pyparsing. To activate the packrat feature, your - program must call the class method ParserElement.enablePackrat(). If - your program uses psyco to "compile as you go", you must call - enablePackrat before calling psyco.full(). If you do not do this, - Python will crash. For best results, call enablePackrat() immediately - after importing pyparsing. - """ - if not ParserElement._packratEnabled: - ParserElement._packratEnabled = True - ParserElement._parse = ParserElement._parseCache - enablePackrat = staticmethod(enablePackrat) - - def parseString( self, instring, parseAll=False ): - """Execute the parse expression with the given string. - This is the main interface to the client code, once the complete - expression has been built. - - If you want the grammar to require that the entire input string be - successfully parsed, then set parseAll to True (equivalent to ending - the grammar with StringEnd()). - - Note: parseString implicitly calls expandtabs() on the input string, - in order to report proper column numbers in parse actions. - If the input string contains tabs and - the grammar uses parse actions that use the loc argument to index into the - string being parsed, you can ensure you have a consistent view of the input - string by: - - calling parseWithTabs on your grammar before calling parseString - (see L{I{parseWithTabs}}) - - define your parse action using the full (s,loc,toks) signature, and - reference the input string using the parse action's s argument - - explictly expand the tabs in your input string before calling - parseString - """ - ParserElement.resetCache() - if not self.streamlined: - self.streamline() - #~ self.saveAsList = True - for e in self.ignoreExprs: - e.streamline() - if not self.keepTabs: - instring = instring.expandtabs() - loc, tokens = self._parse( instring, 0 ) - if parseAll: - StringEnd()._parse( instring, loc ) - return tokens - - def scanString( self, instring, maxMatches=_MAX_INT ): - """Scan the input string for expression matches. Each match will return the - matching tokens, start location, and end location. May be called with optional - maxMatches argument, to clip scanning after 'n' matches are found. - - Note that the start and end locations are reported relative to the string - being parsed. See L{I{parseString}} for more information on parsing - strings with embedded tabs.""" - if not self.streamlined: - self.streamline() - for e in self.ignoreExprs: - e.streamline() - - if not self.keepTabs: - instring = _ustr(instring).expandtabs() - instrlen = len(instring) - loc = 0 - preparseFn = self.preParse - parseFn = self._parse - ParserElement.resetCache() - matches = 0 - while loc <= instrlen and matches < maxMatches: - try: - preloc = preparseFn( instring, loc ) - nextLoc,tokens = parseFn( instring, preloc, callPreParse=False ) - except ParseException: - loc = preloc+1 - else: - matches += 1 - yield tokens, preloc, nextLoc - loc = nextLoc - - def transformString( self, instring ): - """Extension to scanString, to modify matching text with modified tokens that may - be returned from a parse action. To use transformString, define a grammar and - attach a parse action to it that modifies the returned token list. - Invoking transformString() on a target string will then scan for matches, - and replace the matched text patterns according to the logic in the parse - action. transformString() returns the resulting transformed string.""" - out = [] - lastE = 0 - # force preservation of s, to minimize unwanted transformation of string, and to - # keep string locs straight between transformString and scanString - self.keepTabs = True - for t,s,e in self.scanString( instring ): - out.append( instring[lastE:s] ) - if t: - if isinstance(t,ParseResults): - out += t.asList() - elif isinstance(t,list): - out += t - else: - out.append(t) - lastE = e - out.append(instring[lastE:]) - return "".join(map(_ustr,out)) - - def searchString( self, instring, maxMatches=_MAX_INT ): - """Another extension to scanString, simplifying the access to the tokens found - to match the given parse expression. May be called with optional - maxMatches argument, to clip searching after 'n' matches are found. - """ - return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ]) - - def __add__(self, other ): - """Implementation of + operator - returns And""" - if isinstance( other, basestring ): - other = Literal( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return And( [ self, other ] ) - - def __radd__(self, other ): - """Implementation of + operator when left operand is not a ParserElement""" - if isinstance( other, basestring ): - other = Literal( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return other + self - - def __sub__(self, other): - """Implementation of - operator, returns And with error stop""" - if isinstance( other, basestring ): - other = Literal( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return And( [ self, And._ErrorStop(), other ] ) - - def __rsub__(self, other ): - """Implementation of - operator when left operand is not a ParserElement""" - if isinstance( other, basestring ): - other = Literal( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return other - self - - def __mul__(self,other): - if isinstance(other,int): - minElements, optElements = other,0 - elif isinstance(other,tuple): - if len(other)==0: - other = (None,None) - elif len(other)==1: - other = (other[0],None) - if len(other)==2: - if other[0] is None: - other = (0, other[1]) - if isinstance(other[0],int) and other[1] is None: - if other[0] == 0: - return ZeroOrMore(self) - if other[0] == 1: - return OneOrMore(self) - else: - return self*other[0] + ZeroOrMore(self) - elif isinstance(other[0],int) and isinstance(other[1],int): - minElements, optElements = other - optElements -= minElements - else: - raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1])) - else: - raise TypeError("can only multiply 'ParserElement' and int or (int,int) objects") - else: - raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other)) - - if minElements < 0: - raise ValueError("cannot multiply ParserElement by negative value") - if optElements < 0: - raise ValueError("second tuple value must be greater or equal to first tuple value") - if minElements == optElements == 0: - raise ValueError("cannot multiply ParserElement by 0 or (0,0)") - - if (optElements): - def makeOptionalList(n): - if n>1: - return Optional(self + makeOptionalList(n-1)) - else: - return Optional(self) - if minElements: - if minElements == 1: - ret = self + makeOptionalList(optElements) - else: - ret = And([self]*minElements) + makeOptionalList(optElements) - else: - ret = makeOptionalList(optElements) - else: - if minElements == 1: - ret = self - else: - ret = And([self]*minElements) - return ret - - def __rmul__(self, other): - return self.__mul__(other) - - def __or__(self, other ): - """Implementation of | operator - returns MatchFirst""" - if isinstance( other, basestring ): - other = Literal( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return MatchFirst( [ self, other ] ) - - def __ror__(self, other ): - """Implementation of | operator when left operand is not a ParserElement""" - if isinstance( other, basestring ): - other = Literal( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return other | self - - def __xor__(self, other ): - """Implementation of ^ operator - returns Or""" - if isinstance( other, basestring ): - other = Literal( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return Or( [ self, other ] ) - - def __rxor__(self, other ): - """Implementation of ^ operator when left operand is not a ParserElement""" - if isinstance( other, basestring ): - other = Literal( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return other ^ self - - def __and__(self, other ): - """Implementation of & operator - returns Each""" - if isinstance( other, basestring ): - other = Literal( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return Each( [ self, other ] ) - - def __rand__(self, other ): - """Implementation of & operator when left operand is not a ParserElement""" - if isinstance( other, basestring ): - other = Literal( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return other & self - - def __invert__( self ): - """Implementation of ~ operator - returns NotAny""" - return NotAny( self ) - - def __call__(self, name): - """Shortcut for setResultsName, with listAllMatches=default:: - userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno") - could be written as:: - userdata = Word(alphas)("name") + Word(nums+"-")("socsecno") - """ - return self.setResultsName(name) - - def suppress( self ): - """Suppresses the output of this ParserElement; useful to keep punctuation from - cluttering up returned output. - """ - return Suppress( self ) - - def leaveWhitespace( self ): - """Disables the skipping of whitespace before matching the characters in the - ParserElement's defined pattern. This is normally only used internally by - the pyparsing module, but may be needed in some whitespace-sensitive grammars. - """ - self.skipWhitespace = False - return self - - def setWhitespaceChars( self, chars ): - """Overrides the default whitespace chars - """ - self.skipWhitespace = True - self.whiteChars = chars - self.copyDefaultWhiteChars = False - return self - - def parseWithTabs( self ): - """Overrides default behavior to expand s to spaces before parsing the input string. - Must be called before parseString when the input grammar contains elements that - match characters.""" - self.keepTabs = True - return self - - def ignore( self, other ): - """Define expression to be ignored (e.g., comments) while doing pattern - matching; may be called repeatedly, to define multiple comment or other - ignorable patterns. - """ - if isinstance( other, Suppress ): - if other not in self.ignoreExprs: - self.ignoreExprs.append( other ) - else: - self.ignoreExprs.append( Suppress( other ) ) - return self - - def setDebugActions( self, startAction, successAction, exceptionAction ): - """Enable display of debugging messages while doing pattern matching.""" - self.debugActions = (startAction or _defaultStartDebugAction, - successAction or _defaultSuccessDebugAction, - exceptionAction or _defaultExceptionDebugAction) - self.debug = True - return self - - def setDebug( self, flag=True ): - """Enable display of debugging messages while doing pattern matching. - Set flag to True to enable, False to disable.""" - if flag: - self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction ) - else: - self.debug = False - return self - - def __str__( self ): - return self.name - - def __repr__( self ): - return _ustr(self) - - def streamline( self ): - self.streamlined = True - self.strRepr = None - return self - - def checkRecursion( self, parseElementList ): - pass - - def validate( self, validateTrace=[] ): - """Check defined expressions for valid structure, check for infinite recursive definitions.""" - self.checkRecursion( [] ) - - def parseFile( self, file_or_filename ): - """Execute the parse expression on the given file or filename. - If a filename is specified (instead of a file object), - the entire file is opened, read, and closed before parsing. - """ - try: - file_contents = file_or_filename.read() - except AttributeError: - f = open(file_or_filename, "rb") - file_contents = f.read() - f.close() - return self.parseString(file_contents) - - def getException(self): - return ParseException("",0,self.errmsg,self) - - def __getattr__(self,aname): - if aname == "myException": - self.myException = ret = self.getException(); - return ret; - else: - raise AttributeError("no such attribute " + aname) - - def __eq__(self,other): - if isinstance(other, basestring): - try: - (self + StringEnd()).parseString(_ustr(other)) - return True - except ParseBaseException: - return False - else: - return super(ParserElement,self)==other - - def __hash__(self): - return hash(id(self)) - - def __req__(self,other): - return self == other - - -class Token(ParserElement): - """Abstract ParserElement subclass, for defining atomic matching patterns.""" - def __init__( self ): - super(Token,self).__init__( savelist=False ) - #self.myException = ParseException("",0,"",self) - - def setName(self, name): - s = super(Token,self).setName(name) - self.errmsg = "Expected " + self.name - #s.myException.msg = self.errmsg - return s - - -class Empty(Token): - """An empty token, will always match.""" - def __init__( self ): - super(Empty,self).__init__() - self.name = "Empty" - self.mayReturnEmpty = True - self.mayIndexError = False - - -class NoMatch(Token): - """A token that will never match.""" - def __init__( self ): - super(NoMatch,self).__init__() - self.name = "NoMatch" - self.mayReturnEmpty = True - self.mayIndexError = False - self.errmsg = "Unmatchable token" - #self.myException.msg = self.errmsg - - def parseImpl( self, instring, loc, doActions=True ): - exc = self.myException - exc.loc = loc - exc.pstr = instring - raise exc - - -class Literal(Token): - """Token to exactly match a specified string.""" - def __init__( self, matchString ): - super(Literal,self).__init__() - self.match = matchString - self.matchLen = len(matchString) - try: - self.firstMatchChar = matchString[0] - except IndexError: - warnings.warn("null string passed to Literal; use Empty() instead", - SyntaxWarning, stacklevel=2) - self.__class__ = Empty - self.name = '"%s"' % _ustr(self.match) - self.errmsg = "Expected " + self.name - self.mayReturnEmpty = False - #self.myException.msg = self.errmsg - self.mayIndexError = False - - # Performance tuning: this routine gets called a *lot* - # if this is a single character match string and the first character matches, - # short-circuit as quickly as possible, and avoid calling startswith - #~ @profile - def parseImpl( self, instring, loc, doActions=True ): - if (instring[loc] == self.firstMatchChar and - (self.matchLen==1 or instring.startswith(self.match,loc)) ): - return loc+self.matchLen, self.match - #~ raise ParseException( instring, loc, self.errmsg ) - exc = self.myException - exc.loc = loc - exc.pstr = instring - raise exc -_L = Literal - -class Keyword(Token): - """Token to exactly match a specified string as a keyword, that is, it must be - immediately followed by a non-keyword character. Compare with Literal:: - Literal("if") will match the leading 'if' in 'ifAndOnlyIf'. - Keyword("if") will not; it will only match the leading 'if in 'if x=1', or 'if(y==2)' - Accepts two optional constructor arguments in addition to the keyword string: - identChars is a string of characters that would be valid identifier characters, - defaulting to all alphanumerics + "_" and "$"; caseless allows case-insensitive - matching, default is False. - """ - DEFAULT_KEYWORD_CHARS = alphanums+"_$" - - def __init__( self, matchString, identChars=DEFAULT_KEYWORD_CHARS, caseless=False ): - super(Keyword,self).__init__() - self.match = matchString - self.matchLen = len(matchString) - try: - self.firstMatchChar = matchString[0] - except IndexError: - warnings.warn("null string passed to Keyword; use Empty() instead", - SyntaxWarning, stacklevel=2) - self.name = '"%s"' % self.match - self.errmsg = "Expected " + self.name - self.mayReturnEmpty = False - #self.myException.msg = self.errmsg - self.mayIndexError = False - self.caseless = caseless - if caseless: - self.caselessmatch = matchString.upper() - identChars = identChars.upper() - self.identChars = _str2dict(identChars) - - def parseImpl( self, instring, loc, doActions=True ): - if self.caseless: - if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and - (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and - (loc == 0 or instring[loc-1].upper() not in self.identChars) ): - return loc+self.matchLen, self.match - else: - if (instring[loc] == self.firstMatchChar and - (self.matchLen==1 or instring.startswith(self.match,loc)) and - (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and - (loc == 0 or instring[loc-1] not in self.identChars) ): - return loc+self.matchLen, self.match - #~ raise ParseException( instring, loc, self.errmsg ) - exc = self.myException - exc.loc = loc - exc.pstr = instring - raise exc - - def copy(self): - c = super(Keyword,self).copy() - c.identChars = Keyword.DEFAULT_KEYWORD_CHARS - return c - - def setDefaultKeywordChars( chars ): - """Overrides the default Keyword chars - """ - Keyword.DEFAULT_KEYWORD_CHARS = chars - setDefaultKeywordChars = staticmethod(setDefaultKeywordChars) - - -class CaselessLiteral(Literal): - """Token to match a specified string, ignoring case of letters. - Note: the matched results will always be in the case of the given - match string, NOT the case of the input text. - """ - def __init__( self, matchString ): - super(CaselessLiteral,self).__init__( matchString.upper() ) - # Preserve the defining literal. - self.returnString = matchString - self.name = "'%s'" % self.returnString - self.errmsg = "Expected " + self.name - #self.myException.msg = self.errmsg - - def parseImpl( self, instring, loc, doActions=True ): - if instring[ loc:loc+self.matchLen ].upper() == self.match: - return loc+self.matchLen, self.returnString - #~ raise ParseException( instring, loc, self.errmsg ) - exc = self.myException - exc.loc = loc - exc.pstr = instring - raise exc - -class CaselessKeyword(Keyword): - def __init__( self, matchString, identChars=Keyword.DEFAULT_KEYWORD_CHARS ): - super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True ) - - def parseImpl( self, instring, loc, doActions=True ): - if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and - (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ): - return loc+self.matchLen, self.match - #~ raise ParseException( instring, loc, self.errmsg ) - exc = self.myException - exc.loc = loc - exc.pstr = instring - raise exc - -class Word(Token): - """Token for matching words composed of allowed character sets. - Defined with string containing all allowed initial characters, - an optional string containing allowed body characters (if omitted, - defaults to the initial character set), and an optional minimum, - maximum, and/or exact length. The default value for min is 1 (a - minimum value < 1 is not valid); the default values for max and exact - are 0, meaning no maximum or exact length restriction. - """ - def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False ): - super(Word,self).__init__() - self.initCharsOrig = initChars - self.initChars = _str2dict(initChars) - if bodyChars : - self.bodyCharsOrig = bodyChars - self.bodyChars = _str2dict(bodyChars) - else: - self.bodyCharsOrig = initChars - self.bodyChars = _str2dict(initChars) - - self.maxSpecified = max > 0 - - if min < 1: - raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted") - - self.minLen = min - - if max > 0: - self.maxLen = max - else: - self.maxLen = _MAX_INT - - if exact > 0: - self.maxLen = exact - self.minLen = exact - - self.name = _ustr(self) - self.errmsg = "Expected " + self.name - #self.myException.msg = self.errmsg - self.mayIndexError = False - self.asKeyword = asKeyword - - if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0): - if self.bodyCharsOrig == self.initCharsOrig: - self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig) - elif len(self.bodyCharsOrig) == 1: - self.reString = "%s[%s]*" % \ - (re.escape(self.initCharsOrig), - _escapeRegexRangeChars(self.bodyCharsOrig),) - else: - self.reString = "[%s][%s]*" % \ - (_escapeRegexRangeChars(self.initCharsOrig), - _escapeRegexRangeChars(self.bodyCharsOrig),) - if self.asKeyword: - self.reString = r"\b"+self.reString+r"\b" - try: - self.re = re.compile( self.reString ) - except: - self.re = None - - def parseImpl( self, instring, loc, doActions=True ): - if self.re: - result = self.re.match(instring,loc) - if not result: - exc = self.myException - exc.loc = loc - exc.pstr = instring - raise exc - - loc = result.end() - return loc,result.group() - - if not(instring[ loc ] in self.initChars): - #~ raise ParseException( instring, loc, self.errmsg ) - exc = self.myException - exc.loc = loc - exc.pstr = instring - raise exc - start = loc - loc += 1 - instrlen = len(instring) - bodychars = self.bodyChars - maxloc = start + self.maxLen - maxloc = min( maxloc, instrlen ) - while loc < maxloc and instring[loc] in bodychars: - loc += 1 - - throwException = False - if loc - start < self.minLen: - throwException = True - if self.maxSpecified and loc < instrlen and instring[loc] in bodychars: - throwException = True - if self.asKeyword: - if (start>0 and instring[start-1] in bodychars) or (loc4: - return s[:4]+"..." - else: - return s - - if ( self.initCharsOrig != self.bodyCharsOrig ): - self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) ) - else: - self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig) - - return self.strRepr - - -class Regex(Token): - """Token for matching strings that match a given regular expression. - Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module. - """ - def __init__( self, pattern, flags=0): - """The parameters pattern and flags are passed to the re.compile() function as-is. See the Python re module for an explanation of the acceptable patterns and flags.""" - super(Regex,self).__init__() - - if len(pattern) == 0: - warnings.warn("null string passed to Regex; use Empty() instead", - SyntaxWarning, stacklevel=2) - - self.pattern = pattern - self.flags = flags - - try: - self.re = re.compile(self.pattern, self.flags) - self.reString = self.pattern - except sre_constants.error: - warnings.warn("invalid pattern (%s) passed to Regex" % pattern, - SyntaxWarning, stacklevel=2) - raise - - self.name = _ustr(self) - self.errmsg = "Expected " + self.name - #self.myException.msg = self.errmsg - self.mayIndexError = False - self.mayReturnEmpty = True - - def parseImpl( self, instring, loc, doActions=True ): - result = self.re.match(instring,loc) - if not result: - exc = self.myException - exc.loc = loc - exc.pstr = instring - raise exc - - loc = result.end() - d = result.groupdict() - ret = ParseResults(result.group()) - if d: - for k in d: - ret[k] = d[k] - return loc,ret - - def __str__( self ): - try: - return super(Regex,self).__str__() - except: - pass - - if self.strRepr is None: - self.strRepr = "Re:(%s)" % repr(self.pattern) - - return self.strRepr - - -class QuotedString(Token): - """Token for matching strings that are delimited by quoting characters. - """ - def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None): - """ - Defined with the following parameters: - - quoteChar - string of one or more characters defining the quote delimiting string - - escChar - character to escape quotes, typically backslash (default=None) - - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=None) - - multiline - boolean indicating whether quotes can span multiple lines (default=False) - - unquoteResults - boolean indicating whether the matched text should be unquoted (default=True) - - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=None => same as quoteChar) - """ - super(QuotedString,self).__init__() - - # remove white space from quote chars - wont work anyway - quoteChar = quoteChar.strip() - if len(quoteChar) == 0: - warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) - raise SyntaxError() - - if endQuoteChar is None: - endQuoteChar = quoteChar - else: - endQuoteChar = endQuoteChar.strip() - if len(endQuoteChar) == 0: - warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) - raise SyntaxError() - - self.quoteChar = quoteChar - self.quoteCharLen = len(quoteChar) - self.firstQuoteChar = quoteChar[0] - self.endQuoteChar = endQuoteChar - self.endQuoteCharLen = len(endQuoteChar) - self.escChar = escChar - self.escQuote = escQuote - self.unquoteResults = unquoteResults - - if multiline: - self.flags = re.MULTILINE | re.DOTALL - self.pattern = r'%s(?:[^%s%s]' % \ - ( re.escape(self.quoteChar), - _escapeRegexRangeChars(self.endQuoteChar[0]), - (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) - else: - self.flags = 0 - self.pattern = r'%s(?:[^%s\n\r%s]' % \ - ( re.escape(self.quoteChar), - _escapeRegexRangeChars(self.endQuoteChar[0]), - (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) - if len(self.endQuoteChar) > 1: - self.pattern += ( - '|(?:' + ')|(?:'.join(["%s[^%s]" % (re.escape(self.endQuoteChar[:i]), - _escapeRegexRangeChars(self.endQuoteChar[i])) - for i in range(len(self.endQuoteChar)-1,0,-1)]) + ')' - ) - if escQuote: - self.pattern += (r'|(?:%s)' % re.escape(escQuote)) - if escChar: - self.pattern += (r'|(?:%s.)' % re.escape(escChar)) - self.escCharReplacePattern = re.escape(self.escChar)+"(.)" - self.pattern += (r')*%s' % re.escape(self.endQuoteChar)) - - try: - self.re = re.compile(self.pattern, self.flags) - self.reString = self.pattern - except sre_constants.error: - warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern, - SyntaxWarning, stacklevel=2) - raise - - self.name = _ustr(self) - self.errmsg = "Expected " + self.name - #self.myException.msg = self.errmsg - self.mayIndexError = False - self.mayReturnEmpty = True - - def parseImpl( self, instring, loc, doActions=True ): - result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None - if not result: - exc = self.myException - exc.loc = loc - exc.pstr = instring - raise exc - - loc = result.end() - ret = result.group() - - if self.unquoteResults: - - # strip off quotes - ret = ret[self.quoteCharLen:-self.endQuoteCharLen] - - if isinstance(ret,basestring): - # replace escaped characters - if self.escChar: - ret = re.sub(self.escCharReplacePattern,"\g<1>",ret) - - # replace escaped quotes - if self.escQuote: - ret = ret.replace(self.escQuote, self.endQuoteChar) - - return loc, ret - - def __str__( self ): - try: - return super(QuotedString,self).__str__() - except: - pass - - if self.strRepr is None: - self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar) - - return self.strRepr - - -class CharsNotIn(Token): - """Token for matching words composed of characters *not* in a given set. - Defined with string containing all disallowed characters, and an optional - minimum, maximum, and/or exact length. The default value for min is 1 (a - minimum value < 1 is not valid); the default values for max and exact - are 0, meaning no maximum or exact length restriction. - """ - def __init__( self, notChars, min=1, max=0, exact=0 ): - super(CharsNotIn,self).__init__() - self.skipWhitespace = False - self.notChars = notChars - - if min < 1: - raise ValueError("cannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permitted") - - self.minLen = min - - if max > 0: - self.maxLen = max - else: - self.maxLen = _MAX_INT - - if exact > 0: - self.maxLen = exact - self.minLen = exact - - self.name = _ustr(self) - self.errmsg = "Expected " + self.name - self.mayReturnEmpty = ( self.minLen == 0 ) - #self.myException.msg = self.errmsg - self.mayIndexError = False - - def parseImpl( self, instring, loc, doActions=True ): - if instring[loc] in self.notChars: - #~ raise ParseException( instring, loc, self.errmsg ) - exc = self.myException - exc.loc = loc - exc.pstr = instring - raise exc - - start = loc - loc += 1 - notchars = self.notChars - maxlen = min( start+self.maxLen, len(instring) ) - while loc < maxlen and \ - (instring[loc] not in notchars): - loc += 1 - - if loc - start < self.minLen: - #~ raise ParseException( instring, loc, self.errmsg ) - exc = self.myException - exc.loc = loc - exc.pstr = instring - raise exc - - return loc, instring[start:loc] - - def __str__( self ): - try: - return super(CharsNotIn, self).__str__() - except: - pass - - if self.strRepr is None: - if len(self.notChars) > 4: - self.strRepr = "!W:(%s...)" % self.notChars[:4] - else: - self.strRepr = "!W:(%s)" % self.notChars - - return self.strRepr - -class White(Token): - """Special matching class for matching whitespace. Normally, whitespace is ignored - by pyparsing grammars. This class is included when some whitespace structures - are significant. Define with a string containing the whitespace characters to be - matched; default is " \\t\\n". Also takes optional min, max, and exact arguments, - as defined for the Word class.""" - whiteStrs = { - " " : "", - "\t": "", - "\n": "", - "\r": "", - "\f": "", - } - def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0): - super(White,self).__init__() - self.matchWhite = ws - self.setWhitespaceChars( "".join([c for c in self.whiteChars if c not in self.matchWhite]) ) - #~ self.leaveWhitespace() - self.name = ("".join([White.whiteStrs[c] for c in self.matchWhite])) - self.mayReturnEmpty = True - self.errmsg = "Expected " + self.name - #self.myException.msg = self.errmsg - - self.minLen = min - - if max > 0: - self.maxLen = max - else: - self.maxLen = _MAX_INT - - if exact > 0: - self.maxLen = exact - self.minLen = exact - - def parseImpl( self, instring, loc, doActions=True ): - if not(instring[ loc ] in self.matchWhite): - #~ raise ParseException( instring, loc, self.errmsg ) - exc = self.myException - exc.loc = loc - exc.pstr = instring - raise exc - start = loc - loc += 1 - maxloc = start + self.maxLen - maxloc = min( maxloc, len(instring) ) - while loc < maxloc and instring[loc] in self.matchWhite: - loc += 1 - - if loc - start < self.minLen: - #~ raise ParseException( instring, loc, self.errmsg ) - exc = self.myException - exc.loc = loc - exc.pstr = instring - raise exc - - return loc, instring[start:loc] - - -class _PositionToken(Token): - def __init__( self ): - super(_PositionToken,self).__init__() - self.name=self.__class__.__name__ - self.mayReturnEmpty = True - self.mayIndexError = False - -class GoToColumn(_PositionToken): - """Token to advance to a specific column of input text; useful for tabular report scraping.""" - def __init__( self, colno ): - super(GoToColumn,self).__init__() - self.col = colno - - def preParse( self, instring, loc ): - if col(loc,instring) != self.col: - instrlen = len(instring) - if self.ignoreExprs: - loc = self._skipIgnorables( instring, loc ) - while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col : - loc += 1 - return loc - - def parseImpl( self, instring, loc, doActions=True ): - thiscol = col( loc, instring ) - if thiscol > self.col: - raise ParseException( instring, loc, "Text not in expected column", self ) - newloc = loc + self.col - thiscol - ret = instring[ loc: newloc ] - return newloc, ret - -class LineStart(_PositionToken): - """Matches if current position is at the beginning of a line within the parse string""" - def __init__( self ): - super(LineStart,self).__init__() - self.setWhitespaceChars( " \t" ) - self.errmsg = "Expected start of line" - #self.myException.msg = self.errmsg - - def preParse( self, instring, loc ): - preloc = super(LineStart,self).preParse(instring,loc) - if instring[preloc] == "\n": - loc += 1 - return loc - - def parseImpl( self, instring, loc, doActions=True ): - if not( loc==0 or - (loc == self.preParse( instring, 0 )) or - (instring[loc-1] == "\n") ): #col(loc, instring) != 1: - #~ raise ParseException( instring, loc, "Expected start of line" ) - exc = self.myException - exc.loc = loc - exc.pstr = instring - raise exc - return loc, [] - -class LineEnd(_PositionToken): - """Matches if current position is at the end of a line within the parse string""" - def __init__( self ): - super(LineEnd,self).__init__() - self.setWhitespaceChars( " \t" ) - self.errmsg = "Expected end of line" - #self.myException.msg = self.errmsg - - def parseImpl( self, instring, loc, doActions=True ): - if loc len(instring): - return loc, [] - else: - exc = self.myException - exc.loc = loc - exc.pstr = instring - raise exc - -class WordStart(_PositionToken): - """Matches if the current position is at the beginning of a Word, and - is not preceded by any character in a given set of wordChars - (default=printables). To emulate the \b behavior of regular expressions, - use WordStart(alphanums). WordStart will also match at the beginning of - the string being parsed, or at the beginning of a line. - """ - def __init__(self, wordChars = printables): - super(WordStart,self).__init__() - self.wordChars = _str2dict(wordChars) - self.errmsg = "Not at the start of a word" - - def parseImpl(self, instring, loc, doActions=True ): - if loc != 0: - if (instring[loc-1] in self.wordChars or - instring[loc] not in self.wordChars): - exc = self.myException - exc.loc = loc - exc.pstr = instring - raise exc - return loc, [] - -class WordEnd(_PositionToken): - """Matches if the current position is at the end of a Word, and - is not followed by any character in a given set of wordChars - (default=printables). To emulate the \b behavior of regular expressions, - use WordEnd(alphanums). WordEnd will also match at the end of - the string being parsed, or at the end of a line. - """ - def __init__(self, wordChars = printables): - super(WordEnd,self).__init__() - self.wordChars = _str2dict(wordChars) - self.skipWhitespace = False - self.errmsg = "Not at the end of a word" - - def parseImpl(self, instring, loc, doActions=True ): - instrlen = len(instring) - if instrlen>0 and loc maxExcLoc: - maxException = err - maxExcLoc = err.loc - except IndexError: - if len(instring) > maxExcLoc: - maxException = ParseException(instring,len(instring),e.errmsg,self) - maxExcLoc = len(instring) - else: - if loc2 > maxMatchLoc: - maxMatchLoc = loc2 - maxMatchExp = e - - if maxMatchLoc < 0: - if maxException is not None: - raise maxException - else: - raise ParseException(instring, loc, "no defined alternatives to match", self) - - return maxMatchExp._parse( instring, loc, doActions ) - - def __ixor__(self, other ): - if isinstance( other, basestring ): - other = Literal( other ) - return self.append( other ) #Or( [ self, other ] ) - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "{" + " ^ ".join( [ _ustr(e) for e in self.exprs ] ) + "}" - - return self.strRepr - - def checkRecursion( self, parseElementList ): - subRecCheckList = parseElementList[:] + [ self ] - for e in self.exprs: - e.checkRecursion( subRecCheckList ) - - -class MatchFirst(ParseExpression): - """Requires that at least one ParseExpression is found. - If two expressions match, the first one listed is the one that will match. - May be constructed using the '|' operator. - """ - def __init__( self, exprs, savelist = False ): - super(MatchFirst,self).__init__(exprs, savelist) - if exprs: - self.mayReturnEmpty = False - for e in self.exprs: - if e.mayReturnEmpty: - self.mayReturnEmpty = True - break - else: - self.mayReturnEmpty = True - - def parseImpl( self, instring, loc, doActions=True ): - maxExcLoc = -1 - maxException = None - for e in self.exprs: - try: - ret = e._parse( instring, loc, doActions ) - return ret - except ParseException, err: - if err.loc > maxExcLoc: - maxException = err - maxExcLoc = err.loc - except IndexError: - if len(instring) > maxExcLoc: - maxException = ParseException(instring,len(instring),e.errmsg,self) - maxExcLoc = len(instring) - - # only got here if no expression matched, raise exception for match that made it the furthest - else: - if maxException is not None: - raise maxException - else: - raise ParseException(instring, loc, "no defined alternatives to match", self) - - def __ior__(self, other ): - if isinstance( other, basestring ): - other = Literal( other ) - return self.append( other ) #MatchFirst( [ self, other ] ) - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "{" + " | ".join( [ _ustr(e) for e in self.exprs ] ) + "}" - - return self.strRepr - - def checkRecursion( self, parseElementList ): - subRecCheckList = parseElementList[:] + [ self ] - for e in self.exprs: - e.checkRecursion( subRecCheckList ) - - -class Each(ParseExpression): - """Requires all given ParseExpressions to be found, but in any order. - Expressions may be separated by whitespace. - May be constructed using the '&' operator. - """ - def __init__( self, exprs, savelist = True ): - super(Each,self).__init__(exprs, savelist) - self.mayReturnEmpty = True - for e in self.exprs: - if not e.mayReturnEmpty: - self.mayReturnEmpty = False - break - self.skipWhitespace = True - self.initExprGroups = True - - def parseImpl( self, instring, loc, doActions=True ): - if self.initExprGroups: - self.optionals = [ e.expr for e in self.exprs if isinstance(e,Optional) ] - self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ] - self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ] - self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ] - self.required += self.multirequired - self.initExprGroups = False - tmpLoc = loc - tmpReqd = self.required[:] - tmpOpt = self.optionals[:] - matchOrder = [] - - keepMatching = True - while keepMatching: - tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired - failed = [] - for e in tmpExprs: - try: - tmpLoc = e.tryParse( instring, tmpLoc ) - except ParseException: - failed.append(e) - else: - matchOrder.append(e) - if e in tmpReqd: - tmpReqd.remove(e) - elif e in tmpOpt: - tmpOpt.remove(e) - if len(failed) == len(tmpExprs): - keepMatching = False - - if tmpReqd: - missing = ", ".join( [ _ustr(e) for e in tmpReqd ] ) - raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing ) - - # add any unmatched Optionals, in case they have default values defined - matchOrder += list(e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt) - - resultlist = [] - for e in matchOrder: - loc,results = e._parse(instring,loc,doActions) - resultlist.append(results) - - finalResults = ParseResults([]) - for r in resultlist: - dups = {} - for k in r.keys(): - if k in finalResults.keys(): - tmp = ParseResults(finalResults[k]) - tmp += ParseResults(r[k]) - dups[k] = tmp - finalResults += ParseResults(r) - for k,v in dups.items(): - finalResults[k] = v - return loc, finalResults - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "{" + " & ".join( [ _ustr(e) for e in self.exprs ] ) + "}" - - return self.strRepr - - def checkRecursion( self, parseElementList ): - subRecCheckList = parseElementList[:] + [ self ] - for e in self.exprs: - e.checkRecursion( subRecCheckList ) - - -class ParseElementEnhance(ParserElement): - """Abstract subclass of ParserElement, for combining and post-processing parsed tokens.""" - def __init__( self, expr, savelist=False ): - super(ParseElementEnhance,self).__init__(savelist) - if isinstance( expr, basestring ): - expr = Literal(expr) - self.expr = expr - self.strRepr = None - if expr is not None: - self.mayIndexError = expr.mayIndexError - self.mayReturnEmpty = expr.mayReturnEmpty - self.setWhitespaceChars( expr.whiteChars ) - self.skipWhitespace = expr.skipWhitespace - self.saveAsList = expr.saveAsList - self.callPreparse = expr.callPreparse - self.ignoreExprs.extend(expr.ignoreExprs) - - def parseImpl( self, instring, loc, doActions=True ): - if self.expr is not None: - return self.expr._parse( instring, loc, doActions, callPreParse=False ) - else: - raise ParseException("",loc,self.errmsg,self) - - def leaveWhitespace( self ): - self.skipWhitespace = False - self.expr = self.expr.copy() - if self.expr is not None: - self.expr.leaveWhitespace() - return self - - def ignore( self, other ): - if isinstance( other, Suppress ): - if other not in self.ignoreExprs: - super( ParseElementEnhance, self).ignore( other ) - if self.expr is not None: - self.expr.ignore( self.ignoreExprs[-1] ) - else: - super( ParseElementEnhance, self).ignore( other ) - if self.expr is not None: - self.expr.ignore( self.ignoreExprs[-1] ) - return self - - def streamline( self ): - super(ParseElementEnhance,self).streamline() - if self.expr is not None: - self.expr.streamline() - return self - - def checkRecursion( self, parseElementList ): - if self in parseElementList: - raise RecursiveGrammarException( parseElementList+[self] ) - subRecCheckList = parseElementList[:] + [ self ] - if self.expr is not None: - self.expr.checkRecursion( subRecCheckList ) - - def validate( self, validateTrace=[] ): - tmp = validateTrace[:]+[self] - if self.expr is not None: - self.expr.validate(tmp) - self.checkRecursion( [] ) - - def __str__( self ): - try: - return super(ParseElementEnhance,self).__str__() - except: - pass - - if self.strRepr is None and self.expr is not None: - self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) ) - return self.strRepr - - -class FollowedBy(ParseElementEnhance): - """Lookahead matching of the given parse expression. FollowedBy - does *not* advance the parsing position within the input string, it only - verifies that the specified parse expression matches at the current - position. FollowedBy always returns a null token list.""" - def __init__( self, expr ): - super(FollowedBy,self).__init__(expr) - self.mayReturnEmpty = True - - def parseImpl( self, instring, loc, doActions=True ): - self.expr.tryParse( instring, loc ) - return loc, [] - - -class NotAny(ParseElementEnhance): - """Lookahead to disallow matching with the given parse expression. NotAny - does *not* advance the parsing position within the input string, it only - verifies that the specified parse expression does *not* match at the current - position. Also, NotAny does *not* skip over leading whitespace. NotAny - always returns a null token list. May be constructed using the '~' operator.""" - def __init__( self, expr ): - super(NotAny,self).__init__(expr) - #~ self.leaveWhitespace() - self.skipWhitespace = False # do NOT use self.leaveWhitespace(), don't want to propagate to exprs - self.mayReturnEmpty = True - self.errmsg = "Found unwanted token, "+_ustr(self.expr) - #self.myException = ParseException("",0,self.errmsg,self) - - def parseImpl( self, instring, loc, doActions=True ): - try: - self.expr.tryParse( instring, loc ) - except (ParseException,IndexError): - pass - else: - #~ raise ParseException(instring, loc, self.errmsg ) - exc = self.myException - exc.loc = loc - exc.pstr = instring - raise exc - return loc, [] - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "~{" + _ustr(self.expr) + "}" - - return self.strRepr - - -class ZeroOrMore(ParseElementEnhance): - """Optional repetition of zero or more of the given expression.""" - def __init__( self, expr ): - super(ZeroOrMore,self).__init__(expr) - self.mayReturnEmpty = True - - def parseImpl( self, instring, loc, doActions=True ): - tokens = [] - try: - loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) - hasIgnoreExprs = ( len(self.ignoreExprs) > 0 ) - while 1: - if hasIgnoreExprs: - preloc = self._skipIgnorables( instring, loc ) - else: - preloc = loc - loc, tmptokens = self.expr._parse( instring, preloc, doActions ) - if tmptokens or tmptokens.keys(): - tokens += tmptokens - except (ParseException,IndexError): - pass - - return loc, tokens - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "[" + _ustr(self.expr) + "]..." - - return self.strRepr - - def setResultsName( self, name, listAllMatches=False ): - ret = super(ZeroOrMore,self).setResultsName(name,listAllMatches) - ret.saveAsList = True - return ret - - -class OneOrMore(ParseElementEnhance): - """Repetition of one or more of the given expression.""" - def parseImpl( self, instring, loc, doActions=True ): - # must be at least one - loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) - try: - hasIgnoreExprs = ( len(self.ignoreExprs) > 0 ) - while 1: - if hasIgnoreExprs: - preloc = self._skipIgnorables( instring, loc ) - else: - preloc = loc - loc, tmptokens = self.expr._parse( instring, preloc, doActions ) - if tmptokens or tmptokens.keys(): - tokens += tmptokens - except (ParseException,IndexError): - pass - - return loc, tokens - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "{" + _ustr(self.expr) + "}..." - - return self.strRepr - - def setResultsName( self, name, listAllMatches=False ): - ret = super(OneOrMore,self).setResultsName(name,listAllMatches) - ret.saveAsList = True - return ret - -class _NullToken(object): - def __bool__(self): - return False - __nonzero__ = __bool__ - def __str__(self): - return "" - -_optionalNotMatched = _NullToken() -class Optional(ParseElementEnhance): - """Optional matching of the given expression. - A default return string can also be specified, if the optional expression - is not found. - """ - def __init__( self, exprs, default=_optionalNotMatched ): - super(Optional,self).__init__( exprs, savelist=False ) - self.defaultValue = default - self.mayReturnEmpty = True - - def parseImpl( self, instring, loc, doActions=True ): - try: - loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) - except (ParseException,IndexError): - if self.defaultValue is not _optionalNotMatched: - if self.expr.resultsName: - tokens = ParseResults([ self.defaultValue ]) - tokens[self.expr.resultsName] = self.defaultValue - else: - tokens = [ self.defaultValue ] - else: - tokens = [] - return loc, tokens - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - if self.strRepr is None: - self.strRepr = "[" + _ustr(self.expr) + "]" - - return self.strRepr - - -class SkipTo(ParseElementEnhance): - """Token for skipping over all undefined text until the matched expression is found. - If include is set to true, the matched expression is also consumed. The ignore - argument is used to define grammars (typically quoted strings and comments) that - might contain false matches. - """ - def __init__( self, other, include=False, ignore=None ): - super( SkipTo, self ).__init__( other ) - if ignore is not None: - self.expr = self.expr.copy() - self.expr.ignore(ignore) - self.mayReturnEmpty = True - self.mayIndexError = False - self.includeMatch = include - self.asList = False - self.errmsg = "No match found for "+_ustr(self.expr) - #self.myException = ParseException("",0,self.errmsg,self) - - def parseImpl( self, instring, loc, doActions=True ): - startLoc = loc - instrlen = len(instring) - expr = self.expr - while loc <= instrlen: - try: - loc = expr._skipIgnorables( instring, loc ) - expr._parse( instring, loc, doActions=False, callPreParse=False ) - if self.includeMatch: - skipText = instring[startLoc:loc] - loc,mat = expr._parse(instring,loc,doActions,callPreParse=False) - if mat: - skipRes = ParseResults( skipText ) - skipRes += mat - return loc, [ skipRes ] - else: - return loc, [ skipText ] - else: - return loc, [ instring[startLoc:loc] ] - except (ParseException,IndexError): - loc += 1 - exc = self.myException - exc.loc = loc - exc.pstr = instring - raise exc - -class Forward(ParseElementEnhance): - """Forward declaration of an expression to be defined later - - used for recursive grammars, such as algebraic infix notation. - When the expression is known, it is assigned to the Forward variable using the '<<' operator. - - Note: take care when assigning to Forward not to overlook precedence of operators. - Specifically, '|' has a lower precedence than '<<', so that:: - fwdExpr << a | b | c - will actually be evaluated as:: - (fwdExpr << a) | b | c - thereby leaving b and c out as parseable alternatives. It is recommended that you - explicitly group the values inserted into the Forward:: - fwdExpr << (a | b | c) - """ - def __init__( self, other=None ): - super(Forward,self).__init__( other, savelist=False ) - - def __lshift__( self, other ): - if isinstance( other, basestring ): - other = Literal(other) - self.expr = other - self.mayReturnEmpty = other.mayReturnEmpty - self.strRepr = None - self.mayIndexError = self.expr.mayIndexError - self.mayReturnEmpty = self.expr.mayReturnEmpty - self.setWhitespaceChars( self.expr.whiteChars ) - self.skipWhitespace = self.expr.skipWhitespace - self.saveAsList = self.expr.saveAsList - self.ignoreExprs.extend(self.expr.ignoreExprs) - return None - - def leaveWhitespace( self ): - self.skipWhitespace = False - return self - - def streamline( self ): - if not self.streamlined: - self.streamlined = True - if self.expr is not None: - self.expr.streamline() - return self - - def validate( self, validateTrace=[] ): - if self not in validateTrace: - tmp = validateTrace[:]+[self] - if self.expr is not None: - self.expr.validate(tmp) - self.checkRecursion([]) - - def __str__( self ): - if hasattr(self,"name"): - return self.name - - self.__class__ = _ForwardNoRecurse - try: - if self.expr is not None: - retString = _ustr(self.expr) - else: - retString = "None" - finally: - self.__class__ = Forward - return "Forward: "+retString - - def copy(self): - if self.expr is not None: - return super(Forward,self).copy() - else: - ret = Forward() - ret << self - return ret - -class _ForwardNoRecurse(Forward): - def __str__( self ): - return "..." - -class TokenConverter(ParseElementEnhance): - """Abstract subclass of ParseExpression, for converting parsed results.""" - def __init__( self, expr, savelist=False ): - super(TokenConverter,self).__init__( expr )#, savelist ) - self.saveAsList = False - -class Upcase(TokenConverter): - """Converter to upper case all matching tokens.""" - def __init__(self, *args): - super(Upcase,self).__init__(*args) - warnings.warn("Upcase class is deprecated, use upcaseTokens parse action instead", - DeprecationWarning,stacklevel=2) - - def postParse( self, instring, loc, tokenlist ): - return list(map( string.upper, tokenlist )) - - -class Combine(TokenConverter): - """Converter to concatenate all matching tokens to a single string. - By default, the matching patterns must also be contiguous in the input string; - this can be disabled by specifying 'adjacent=False' in the constructor. - """ - def __init__( self, expr, joinString="", adjacent=True ): - super(Combine,self).__init__( expr ) - # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself - if adjacent: - self.leaveWhitespace() - self.adjacent = adjacent - self.skipWhitespace = True - self.joinString = joinString - - def ignore( self, other ): - if self.adjacent: - ParserElement.ignore(self, other) - else: - super( Combine, self).ignore( other ) - return self - - def postParse( self, instring, loc, tokenlist ): - retToks = tokenlist.copy() - del retToks[:] - retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults) - - if self.resultsName and len(retToks.keys())>0: - return [ retToks ] - else: - return retToks - -class Group(TokenConverter): - """Converter to return the matched tokens as a list - useful for returning tokens of ZeroOrMore and OneOrMore expressions.""" - def __init__( self, expr ): - super(Group,self).__init__( expr ) - self.saveAsList = True - - def postParse( self, instring, loc, tokenlist ): - return [ tokenlist ] - -class Dict(TokenConverter): - """Converter to return a repetitive expression as a list, but also as a dictionary. - Each element can also be referenced using the first token in the expression as its key. - Useful for tabular report scraping when the first column can be used as a item key. - """ - def __init__( self, exprs ): - super(Dict,self).__init__( exprs ) - self.saveAsList = True - - def postParse( self, instring, loc, tokenlist ): - for i,tok in enumerate(tokenlist): - if len(tok) == 0: - continue - ikey = tok[0] - if isinstance(ikey,int): - ikey = _ustr(tok[0]).strip() - if len(tok)==1: - tokenlist[ikey] = _ParseResultsWithOffset("",i) - elif len(tok)==2 and not isinstance(tok[1],ParseResults): - tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i) - else: - dictvalue = tok.copy() #ParseResults(i) - del dictvalue[0] - if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.keys()): - tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i) - else: - tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i) - - if self.resultsName: - return [ tokenlist ] - else: - return tokenlist - - -class Suppress(TokenConverter): - """Converter for ignoring the results of a parsed expression.""" - def postParse( self, instring, loc, tokenlist ): - return [] - - def suppress( self ): - return self - - -class OnlyOnce(object): - """Wrapper for parse actions, to ensure they are only called once.""" - def __init__(self, methodCall): - self.callable = ParserElement._normalizeParseActionArgs(methodCall) - self.called = False - def __call__(self,s,l,t): - if not self.called: - results = self.callable(s,l,t) - self.called = True - return results - raise ParseException(s,l,"") - def reset(self): - self.called = False - -def traceParseAction(f): - """Decorator for debugging parse actions.""" - f = ParserElement._normalizeParseActionArgs(f) - def z(*paArgs): - thisFunc = f.func_name - s,l,t = paArgs[-3:] - if len(paArgs)>3: - thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc - sys.stderr.write( ">>entering %s(line: '%s', %d, %s)\n" % (thisFunc,line(l,s),l,t) ) - try: - ret = f(*paArgs) - except Exception, exc: - sys.stderr.write( "<", "|".join( [ _escapeRegexChars(sym) for sym in symbols] )) - try: - if len(symbols)==len("".join(symbols)): - return Regex( "[%s]" % "".join( [ _escapeRegexRangeChars(sym) for sym in symbols] ) ) - else: - return Regex( "|".join( [ re.escape(sym) for sym in symbols] ) ) - except: - warnings.warn("Exception creating Regex for oneOf, building MatchFirst", - SyntaxWarning, stacklevel=2) - - - # last resort, just use MatchFirst - return MatchFirst( [ parseElementClass(sym) for sym in symbols ] ) - -def dictOf( key, value ): - """Helper to easily and clearly define a dictionary by specifying the respective patterns - for the key and value. Takes care of defining the Dict, ZeroOrMore, and Group tokens - in the proper order. The key pattern can include delimiting markers or punctuation, - as long as they are suppressed, thereby leaving the significant key text. The value - pattern can include named results, so that the Dict results can include named token - fields. - """ - return Dict( ZeroOrMore( Group ( key + value ) ) ) - -# convenience constants for positional expressions -empty = Empty().setName("empty") -lineStart = LineStart().setName("lineStart") -lineEnd = LineEnd().setName("lineEnd") -stringStart = StringStart().setName("stringStart") -stringEnd = StringEnd().setName("stringEnd") - -_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1]) -_printables_less_backslash = "".join([ c for c in printables if c not in r"\]" ]) -_escapedHexChar = Combine( Suppress(_bslash + "0x") + Word(hexnums) ).setParseAction(lambda s,l,t:unichr(int(t[0],16))) -_escapedOctChar = Combine( Suppress(_bslash) + Word("0","01234567") ).setParseAction(lambda s,l,t:unichr(int(t[0],8))) -_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | Word(_printables_less_backslash,exact=1) -_charRange = Group(_singleChar + Suppress("-") + _singleChar) -_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]" - -_expanded = lambda p: (isinstance(p,ParseResults) and ''.join([ unichr(c) for c in range(ord(p[0]),ord(p[1])+1) ]) or p) - -def srange(s): - r"""Helper to easily define string ranges for use in Word construction. Borrows - syntax from regexp '[]' string range definitions:: - srange("[0-9]") -> "0123456789" - srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz" - srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_" - The input string must be enclosed in []'s, and the returned string is the expanded - character set joined into a single string. - The values enclosed in the []'s may be:: - a single character - an escaped character with a leading backslash (such as \- or \]) - an escaped hex character with a leading '\0x' (\0x21, which is a '!' character) - an escaped octal character with a leading '\0' (\041, which is a '!' character) - a range of any of the above, separated by a dash ('a-z', etc.) - any combination of the above ('aeiouy', 'a-zA-Z0-9_$', etc.) - """ - try: - return "".join([_expanded(part) for part in _reBracketExpr.parseString(s).body]) - except: - return "" - -def matchOnlyAtCol(n): - """Helper method for defining parse actions that require matching at a specific - column in the input text. - """ - def verifyCol(strg,locn,toks): - if col(locn,strg) != n: - raise ParseException(strg,locn,"matched token not at column %d" % n) - return verifyCol - -def replaceWith(replStr): - """Helper method for common parse actions that simply return a literal value. Especially - useful when used with transformString(). - """ - def _replFunc(*args): - return [replStr] - return _replFunc - -def removeQuotes(s,l,t): - """Helper parse action for removing quotation marks from parsed quoted strings. - To use, add this parse action to quoted string using:: - quotedString.setParseAction( removeQuotes ) - """ - return t[0][1:-1] - -def upcaseTokens(s,l,t): - """Helper parse action to convert tokens to upper case.""" - return [ tt.upper() for tt in map(_ustr,t) ] - -def downcaseTokens(s,l,t): - """Helper parse action to convert tokens to lower case.""" - return [ tt.lower() for tt in map(_ustr,t) ] - -def keepOriginalText(s,startLoc,t): - """Helper parse action to preserve original parsed text, - overriding any nested parse actions.""" - try: - endloc = getTokensEndLoc() - except ParseException: - raise ParseFatalException("incorrect usage of keepOriginalText - may only be called as a parse action") - del t[:] - t += ParseResults(s[startLoc:endloc]) - return t - -def getTokensEndLoc(): - """Method to be called from within a parse action to determine the end - location of the parsed tokens.""" - import inspect - fstack = inspect.stack() - try: - # search up the stack (through intervening argument normalizers) for correct calling routine - for f in fstack[2:]: - if f[3] == "_parseNoCache": - endloc = f[0].f_locals["loc"] - return endloc - else: - raise ParseFatalException("incorrect usage of getTokensEndLoc - may only be called from within a parse action") - finally: - del fstack - -def _makeTags(tagStr, xml): - """Internal helper to construct opening and closing tag expressions, given a tag name""" - if isinstance(tagStr,basestring): - resname = tagStr - tagStr = Keyword(tagStr, caseless=not xml) - else: - resname = tagStr.name - - tagAttrName = Word(alphas,alphanums+"_-:") - if (xml): - tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes ) - openTag = Suppress("<") + tagStr + \ - Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \ - Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") - else: - printablesLessRAbrack = "".join( [ c for c in printables if c not in ">" ] ) - tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack) - openTag = Suppress("<") + tagStr + \ - Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \ - Optional( Suppress("=") + tagAttrValue ) ))) + \ - Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") - closeTag = Combine(_L("") - - openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % tagStr) - closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("" % tagStr) - - return openTag, closeTag - -def makeHTMLTags(tagStr): - """Helper to construct opening and closing tag expressions for HTML, given a tag name""" - return _makeTags( tagStr, False ) - -def makeXMLTags(tagStr): - """Helper to construct opening and closing tag expressions for XML, given a tag name""" - return _makeTags( tagStr, True ) - -def withAttribute(*args,**attrDict): - """Helper to create a validating parse action to be used with start tags created - with makeXMLTags or makeHTMLTags. Use withAttribute to qualify a starting tag - with a required attribute value, to avoid false matches on common tags such as - or
    . - - Call withAttribute with a series of attribute names and values. Specify the list - of filter attributes names and values as: - - keyword arguments, as in (class="Customer",align="right"), or - - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") ) - For attribute names with a namespace prefix, you must use the second form. Attribute - names are matched insensitive to upper/lower case. - - To verify that the attribute exists, but without specifying a value, pass - withAttribute.ANY_VALUE as the value. - """ - if args: - attrs = args[:] - else: - attrs = attrDict.items() - attrs = [(k,v) for k,v in attrs] - def pa(s,l,tokens): - for attrName,attrValue in attrs: - if attrName not in tokens: - raise ParseException(s,l,"no matching attribute " + attrName) - if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue: - raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" % - (attrName, tokens[attrName], attrValue)) - return pa -withAttribute.ANY_VALUE = object() - -opAssoc = _Constants() -opAssoc.LEFT = object() -opAssoc.RIGHT = object() - -def operatorPrecedence( baseExpr, opList ): - """Helper method for constructing grammars of expressions made up of - operators working in a precedence hierarchy. Operators may be unary or - binary, left- or right-associative. Parse actions can also be attached - to operator expressions. - - Parameters: - - baseExpr - expression representing the most basic element for the nested - - opList - list of tuples, one for each operator precedence level in the - expression grammar; each tuple is of the form - (opExpr, numTerms, rightLeftAssoc, parseAction), where: - - opExpr is the pyparsing expression for the operator; - may also be a string, which will be converted to a Literal; - if numTerms is 3, opExpr is a tuple of two expressions, for the - two operators separating the 3 terms - - numTerms is the number of terms for this operator (must - be 1, 2, or 3) - - rightLeftAssoc is the indicator whether the operator is - right or left associative, using the pyparsing-defined - constants opAssoc.RIGHT and opAssoc.LEFT. - - parseAction is the parse action to be associated with - expressions matching this operator expression (the - parse action tuple member may be omitted) - """ - ret = Forward() - lastExpr = baseExpr | ( Suppress('(') + ret + Suppress(')') ) - for i,operDef in enumerate(opList): - opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4] - if arity == 3: - if opExpr is None or len(opExpr) != 2: - raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions") - opExpr1, opExpr2 = opExpr - thisExpr = Forward()#.setName("expr%d" % i) - if rightLeftAssoc == opAssoc.LEFT: - if arity == 1: - matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) ) - elif arity == 2: - if opExpr is not None: - matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) ) - else: - matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) ) - elif arity == 3: - matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \ - Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr ) - else: - raise ValueError("operator must be unary (1), binary (2), or ternary (3)") - elif rightLeftAssoc == opAssoc.RIGHT: - if arity == 1: - # try to avoid LR with this extra test - if not isinstance(opExpr, Optional): - opExpr = Optional(opExpr) - matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr ) - elif arity == 2: - if opExpr is not None: - matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) ) - else: - matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) ) - elif arity == 3: - matchExpr = FollowedBy(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \ - Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr ) - else: - raise ValueError("operator must be unary (1), binary (2), or ternary (3)") - else: - raise ValueError("operator must indicate right or left associativity") - if pa: - matchExpr.setParseAction( pa ) - thisExpr << ( matchExpr | lastExpr ) - lastExpr = thisExpr - ret << lastExpr - return ret - -dblQuotedString = Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\x[0-9a-fA-F]+)|(?:\\.))*"').setName("string enclosed in double quotes") -sglQuotedString = Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\x[0-9a-fA-F]+)|(?:\\.))*'").setName("string enclosed in single quotes") -quotedString = Regex(r'''(?:"(?:[^"\n\r\\]|(?:"")|(?:\\x[0-9a-fA-F]+)|(?:\\.))*")|(?:'(?:[^'\n\r\\]|(?:'')|(?:\\x[0-9a-fA-F]+)|(?:\\.))*')''').setName("quotedString using single or double quotes") -unicodeString = Combine(_L('u') + quotedString.copy()) - -def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString): - """Helper method for defining nested lists enclosed in opening and closing - delimiters ("(" and ")" are the default). - - Parameters: - - opener - opening character for a nested list (default="("); can also be a pyparsing expression - - closer - closing character for a nested list (default=")"); can also be a pyparsing expression - - content - expression for items within the nested lists (default=None) - - ignoreExpr - expression for ignoring opening and closing delimiters (default=quotedString) - - If an expression is not provided for the content argument, the nested - expression will capture all whitespace-delimited content between delimiters - as a list of separate values. - - Use the ignoreExpr argument to define expressions that may contain - opening or closing characters that should not be treated as opening - or closing characters for nesting, such as quotedString or a comment - expression. Specify multiple expressions using an Or or MatchFirst. - The default is quotedString, but if no expressions are to be ignored, - then pass None for this argument. - """ - if opener == closer: - raise ValueError("opening and closing strings cannot be the same") - if content is None: - if isinstance(opener,basestring) and isinstance(closer,basestring): - if ignoreExpr is not None: - content = (Combine(OneOrMore(~ignoreExpr + - CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1)) - ).setParseAction(lambda t:t[0].strip())) - else: - content = (empty+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS).setParseAction(lambda t:t[0].strip())) - else: - raise ValueError("opening and closing arguments must be strings if no content expression is given") - ret = Forward() - if ignoreExpr is not None: - ret << Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) ) - else: - ret << Group( Suppress(opener) + ZeroOrMore( ret | content ) + Suppress(closer) ) - return ret - -def indentedBlock(blockStatementExpr, indentStack, indent=True): - """Helper method for defining space-delimited indentation blocks, such as - those used to define block statements in Python source code. - - Parameters: - - blockStatementExpr - expression defining syntax of statement that - is repeated within the indented block - - indentStack - list created by caller to manage indentation stack - (multiple statementWithIndentedBlock expressions within a single grammar - should share a common indentStack) - - indent - boolean indicating whether block must be indented beyond the - the current level; set to False for block of left-most statements - (default=True) - - A valid block must contain at least one blockStatement. - """ - def checkPeerIndent(s,l,t): - if l >= len(s): return - curCol = col(l,s) - if curCol != indentStack[-1]: - if curCol > indentStack[-1]: - raise ParseFatalException(s,l,"illegal nesting") - raise ParseException(s,l,"not a peer entry") - - def checkSubIndent(s,l,t): - curCol = col(l,s) - if curCol > indentStack[-1]: - indentStack.append( curCol ) - else: - raise ParseException(s,l,"not a subentry") - - def checkUnindent(s,l,t): - if l >= len(s): return - curCol = col(l,s) - if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]): - raise ParseException(s,l,"not an unindent") - indentStack.pop() - - NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress()) - INDENT = Empty() + Empty().setParseAction(checkSubIndent) - PEER = Empty().setParseAction(checkPeerIndent) - UNDENT = Empty().setParseAction(checkUnindent) - if indent: - smExpr = Group( Optional(NL) + - FollowedBy(blockStatementExpr) + - INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT) - else: - smExpr = Group( Optional(NL) + - (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) ) - blockStatementExpr.ignore("\\" + LineEnd()) - return smExpr - -alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]") -punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]") - -anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:")) -commonHTMLEntity = Combine(_L("&") + oneOf("gt lt amp nbsp quot").setResultsName("entity") +";") -_htmlEntityMap = dict(zip("gt lt amp nbsp quot".split(),"><& '")) -replaceHTMLEntity = lambda t : t.entity in _htmlEntityMap and _htmlEntityMap[t.entity] or None - -# it's easy to get these comment structures wrong - they're very common, so may as well make them available -cStyleComment = Regex(r"/\*(?:[^*]*\*+)+?/").setName("C style comment") - -htmlComment = Regex(r"") -restOfLine = Regex(r".*").leaveWhitespace() -dblSlashComment = Regex(r"\/\/(\\\n|.)*").setName("// comment") -cppStyleComment = Regex(r"/(?:\*(?:[^*]*\*+)+?/|/[^\n]*(?:\n[^\n]*)*?(?:(?" + str(tokenlist)) - print ("tokens = " + str(tokens)) - print ("tokens.columns = " + str(tokens.columns)) - print ("tokens.tables = " + str(tokens.tables)) - print (tokens.asXML("SQL",True)) - except ParseBaseException,err: - print (teststring + "->") - print (err.line) - print (" "*(err.column-1) + "^") - print (err) - print() - - selectToken = CaselessLiteral( "select" ) - fromToken = CaselessLiteral( "from" ) - - ident = Word( alphas, alphanums + "_$" ) - columnName = delimitedList( ident, ".", combine=True ).setParseAction( upcaseTokens ) - columnNameList = Group( delimitedList( columnName ) )#.setName("columns") - tableName = delimitedList( ident, ".", combine=True ).setParseAction( upcaseTokens ) - tableNameList = Group( delimitedList( tableName ) )#.setName("tables") - simpleSQL = ( selectToken + \ - ( '*' | columnNameList ).setResultsName( "columns" ) + \ - fromToken + \ - tableNameList.setResultsName( "tables" ) ) - - test( "SELECT * from XYZZY, ABC" ) - test( "select * from SYS.XYZZY" ) - test( "Select A from Sys.dual" ) - test( "Select AA,BB,CC from Sys.dual" ) - test( "Select A, B, C from Sys.dual" ) - test( "Select A, B, C from Sys.dual" ) - test( "Xelect A, B, C from Sys.dual" ) - test( "Select A, B, C frox Sys.dual" ) - test( "Select" ) - test( "Select ^^^ frox Sys.dual" ) - test( "Select A, B, C from Sys.dual, Table2 " ) diff -Nru matplotlib-1.1.1/lib/matplotlib/pyparsing_py2.py matplotlib-1.2.0/lib/matplotlib/pyparsing_py2.py --- matplotlib-1.1.1/lib/matplotlib/pyparsing_py2.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/pyparsing_py2.py 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,3791 @@ +# module pyparsing.py +# +# Copyright (c) 2003-2010 Paul T. McGuire +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +#from __future__ import generators + +__doc__ = \ +""" +pyparsing module - Classes and methods to define and execute parsing grammars + +The pyparsing module is an alternative approach to creating and executing simple grammars, +vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you +don't need to learn a new syntax for defining grammars or matching expressions - the parsing module +provides a library of classes that you use to construct the grammar directly in Python. + +Here is a program to parse "Hello, World!" (or any greeting of the form C{", !"}):: + + from pyparsing import Word, alphas + + # define grammar of a greeting + greet = Word( alphas ) + "," + Word( alphas ) + "!" + + hello = "Hello, World!" + print hello, "->", greet.parseString( hello ) + +The program outputs the following:: + + Hello, World! -> ['Hello', ',', 'World', '!'] + +The Python representation of the grammar is quite readable, owing to the self-explanatory +class names, and the use of '+', '|' and '^' operators. + +The parsed results returned from C{parseString()} can be accessed as a nested list, a dictionary, or an +object with named attributes. + +The pyparsing module handles some of the problems that are typically vexing when writing text parsers: + - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello , World !", etc.) + - quoted strings + - embedded comments +""" + +__version__ = "1.5.5" +__versionTime__ = "12 Aug 2010 03:56" +__author__ = "Paul McGuire " + +import string +from weakref import ref as wkref +import copy +import sys +import warnings +import re +import sre_constants +#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) ) + +__all__ = [ +'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty', +'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal', +'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or', +'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException', +'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException', +'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', 'Upcase', +'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore', +'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col', +'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString', +'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'getTokensEndLoc', 'hexnums', +'htmlComment', 'javaStyleComment', 'keepOriginalText', 'line', 'lineEnd', 'lineStart', 'lineno', +'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral', +'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables', +'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', +'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd', +'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute', +'indentedBlock', 'originalTextFor', +] + +""" +Detect if we are running version 3.X and make appropriate changes +Robert A. Clark +""" +_PY3K = sys.version_info[0] > 2 +if _PY3K: + _MAX_INT = sys.maxsize + basestring = str + unichr = chr + _ustr = str + _str2dict = set + alphas = string.ascii_lowercase + string.ascii_uppercase +else: + _MAX_INT = sys.maxint + range = xrange + + def _ustr(obj): + """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries + str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It + then < returns the unicode object | encodes it with the default encoding | ... >. + """ + if isinstance(obj,unicode): + return obj + + try: + # If this works, then _ustr(obj) has the same behaviour as str(obj), so + # it won't break any existing code. + return str(obj) + + except UnicodeEncodeError: + # The Python docs (http://docs.python.org/ref/customization.html#l2h-182) + # state that "The return value must be a string object". However, does a + # unicode object (being a subclass of basestring) count as a "string + # object"? + # If so, then return a unicode object: + return unicode(obj) + # Else encode it... but how? There are many choices... :) + # Replace unprintables with escape codes? + #return unicode(obj).encode(sys.getdefaultencoding(), 'backslashreplace_errors') + # Replace unprintables with question marks? + #return unicode(obj).encode(sys.getdefaultencoding(), 'replace') + # ... + + def _str2dict(strg): + return dict( [(c,0) for c in strg] ) + + alphas = string.lowercase + string.uppercase + +# build list of single arg builtins, tolerant of Python version, that can be used as parse actions +singleArgBuiltins = [] +import __builtin__ +for fname in "sum len enumerate sorted reversed list tuple set any all".split(): + try: + singleArgBuiltins.append(getattr(__builtin__,fname)) + except AttributeError: + continue + +def _xml_escape(data): + """Escape &, <, >, ", ', etc. in a string of data.""" + + # ampersand must be replaced first + from_symbols = '&><"\'' + to_symbols = ['&'+s+';' for s in "amp gt lt quot apos".split()] + for from_,to_ in zip(from_symbols, to_symbols): + data = data.replace(from_, to_) + return data + +class _Constants(object): + pass + +nums = string.digits +hexnums = nums + "ABCDEFabcdef" +alphanums = alphas + nums +_bslash = chr(92) +printables = "".join( [ c for c in string.printable if c not in string.whitespace ] ) + +class ParseBaseException(Exception): + """base exception class for all parsing runtime exceptions""" + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( self, pstr, loc=0, msg=None, elem=None ): + self.loc = loc + if msg is None: + self.msg = pstr + self.pstr = "" + else: + self.msg = msg + self.pstr = pstr + self.parserElement = elem + + def __getattr__( self, aname ): + """supported attributes by name are: + - lineno - returns the line number of the exception text + - col - returns the column number of the exception text + - line - returns the line containing the exception text + """ + if( aname == "lineno" ): + return lineno( self.loc, self.pstr ) + elif( aname in ("col", "column") ): + return col( self.loc, self.pstr ) + elif( aname == "line" ): + return line( self.loc, self.pstr ) + else: + raise AttributeError(aname) + + def __str__( self ): + return "%s (at char %d), (line:%d, col:%d)" % \ + ( self.msg, self.loc, self.lineno, self.column ) + def __repr__( self ): + return _ustr(self) + def markInputline( self, markerString = ">!<" ): + """Extracts the exception line from the input string, and marks + the location of the exception with a special symbol. + """ + line_str = self.line + line_column = self.column - 1 + if markerString: + line_str = "".join( [line_str[:line_column], + markerString, line_str[line_column:]]) + return line_str.strip() + def __dir__(self): + return "loc msg pstr parserElement lineno col line " \ + "markInputLine __str__ __repr__".split() + +class ParseException(ParseBaseException): + """exception thrown when parse expressions don't match class; + supported attributes by name are: + - lineno - returns the line number of the exception text + - col - returns the column number of the exception text + - line - returns the line containing the exception text + """ + pass + +class ParseFatalException(ParseBaseException): + """user-throwable exception thrown when inconsistent parse content + is found; stops all parsing immediately""" + pass + +class ParseSyntaxException(ParseFatalException): + """just like C{ParseFatalException}, but thrown internally when an + C{ErrorStop} ('-' operator) indicates that parsing is to stop immediately because + an unbacktrackable syntax error has been found""" + def __init__(self, pe): + super(ParseSyntaxException, self).__init__( + pe.pstr, pe.loc, pe.msg, pe.parserElement) + +#~ class ReparseException(ParseBaseException): + #~ """Experimental class - parse actions can raise this exception to cause + #~ pyparsing to reparse the input string: + #~ - with a modified input string, and/or + #~ - with a modified start location + #~ Set the values of the ReparseException in the constructor, and raise the + #~ exception in a parse action to cause pyparsing to use the new string/location. + #~ Setting the values as None causes no change to be made. + #~ """ + #~ def __init_( self, newstring, restartLoc ): + #~ self.newParseText = newstring + #~ self.reparseLoc = restartLoc + +class RecursiveGrammarException(Exception): + """exception thrown by C{validate()} if the grammar could be improperly recursive""" + def __init__( self, parseElementList ): + self.parseElementTrace = parseElementList + + def __str__( self ): + return "RecursiveGrammarException: %s" % self.parseElementTrace + +class _ParseResultsWithOffset(object): + def __init__(self,p1,p2): + self.tup = (p1,p2) + def __getitem__(self,i): + return self.tup[i] + def __repr__(self): + return repr(self.tup) + def setOffset(self,i): + self.tup = (self.tup[0],i) + +class ParseResults(object): + """Structured parse results, to provide multiple means of access to the parsed data: + - as a list (C{len(results)}) + - by list index (C{results[0], results[1]}, etc.) + - by attribute (C{results.}) + """ + #~ __slots__ = ( "__toklist", "__tokdict", "__doinit", "__name", "__parent", "__accumNames", "__weakref__" ) + def __new__(cls, toklist, name=None, asList=True, modal=True ): + if isinstance(toklist, cls): + return toklist + retobj = object.__new__(cls) + retobj.__doinit = True + return retobj + + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( self, toklist, name=None, asList=True, modal=True, isinstance=isinstance ): + if self.__doinit: + self.__doinit = False + self.__name = None + self.__parent = None + self.__accumNames = {} + if isinstance(toklist, list): + self.__toklist = toklist[:] + else: + self.__toklist = [toklist] + self.__tokdict = dict() + + if name is not None and name: + if not modal: + self.__accumNames[name] = 0 + if isinstance(name,int): + name = _ustr(name) # will always return a str, but use _ustr for consistency + self.__name = name + if not toklist in (None,'',[]): + if isinstance(toklist,basestring): + toklist = [ toklist ] + if asList: + if isinstance(toklist,ParseResults): + self[name] = _ParseResultsWithOffset(toklist.copy(),0) + else: + self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0) + self[name].__name = name + else: + try: + self[name] = toklist[0] + except (KeyError,TypeError,IndexError): + self[name] = toklist + + def __getitem__( self, i ): + if isinstance( i, (int,slice) ): + return self.__toklist[i] + else: + if i not in self.__accumNames: + return self.__tokdict[i][-1][0] + else: + return ParseResults([ v[0] for v in self.__tokdict[i] ]) + + def __setitem__( self, k, v, isinstance=isinstance ): + if isinstance(v,_ParseResultsWithOffset): + self.__tokdict[k] = self.__tokdict.get(k,list()) + [v] + sub = v[0] + elif isinstance(k,int): + self.__toklist[k] = v + sub = v + else: + self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)] + sub = v + if isinstance(sub,ParseResults): + sub.__parent = wkref(self) + + def __delitem__( self, i ): + if isinstance(i,(int,slice)): + mylen = len( self.__toklist ) + del self.__toklist[i] + + # convert int to slice + if isinstance(i, int): + if i < 0: + i += mylen + i = slice(i, i+1) + # get removed indices + removed = list(range(*i.indices(mylen))) + removed.reverse() + # fixup indices in token dictionary + for name in self.__tokdict: + occurrences = self.__tokdict[name] + for j in removed: + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset(value, position - (position > j)) + else: + del self.__tokdict[i] + + def __contains__( self, k ): + return k in self.__tokdict + + def __len__( self ): return len( self.__toklist ) + def __bool__(self): return len( self.__toklist ) > 0 + __nonzero__ = __bool__ + def __iter__( self ): return iter( self.__toklist ) + def __reversed__( self ): return iter( self.__toklist[::-1] ) + def keys( self ): + """Returns all named result keys.""" + return self.__tokdict.keys() + + def pop( self, index=-1 ): + """Removes and returns item at specified index (default=last). + Will work with either numeric indices or dict-key indicies.""" + ret = self[index] + del self[index] + return ret + + def get(self, key, defaultValue=None): + """Returns named result matching the given key, or if there is no + such name, then returns the given C{defaultValue} or C{None} if no + C{defaultValue} is specified.""" + if key in self: + return self[key] + else: + return defaultValue + + def insert( self, index, insStr ): + """Inserts new element at location index in the list of parsed tokens.""" + self.__toklist.insert(index, insStr) + # fixup indices in token dictionary + for name in self.__tokdict: + occurrences = self.__tokdict[name] + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset(value, position + (position > index)) + + def items( self ): + """Returns all named result keys and values as a list of tuples.""" + return [(k,self[k]) for k in self.__tokdict] + + def values( self ): + """Returns all named result values.""" + return [ v[-1][0] for v in self.__tokdict.values() ] + + def __getattr__( self, name ): + if True: #name not in self.__slots__: + if name in self.__tokdict: + if name not in self.__accumNames: + return self.__tokdict[name][-1][0] + else: + return ParseResults([ v[0] for v in self.__tokdict[name] ]) + else: + return "" + return None + + def __add__( self, other ): + ret = self.copy() + ret += other + return ret + + def __iadd__( self, other ): + if other.__tokdict: + offset = len(self.__toklist) + addoffset = ( lambda a: (a<0 and offset) or (a+offset) ) + otheritems = other.__tokdict.items() + otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) ) + for (k,vlist) in otheritems for v in vlist] + for k,v in otherdictitems: + self[k] = v + if isinstance(v[0],ParseResults): + v[0].__parent = wkref(self) + + self.__toklist += other.__toklist + self.__accumNames.update( other.__accumNames ) + return self + + def __radd__(self, other): + if isinstance(other,int) and other == 0: + return self.copy() + + def __repr__( self ): + return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) ) + + def __str__( self ): + out = "[" + sep = "" + for i in self.__toklist: + if isinstance(i, ParseResults): + out += sep + _ustr(i) + else: + out += sep + repr(i) + sep = ", " + out += "]" + return out + + def _asStringList( self, sep='' ): + out = [] + for item in self.__toklist: + if out and sep: + out.append(sep) + if isinstance( item, ParseResults ): + out += item._asStringList() + else: + out.append( _ustr(item) ) + return out + + def asList( self ): + """Returns the parse results as a nested list of matching tokens, all converted to strings.""" + out = [] + for res in self.__toklist: + if isinstance(res,ParseResults): + out.append( res.asList() ) + else: + out.append( res ) + return out + + def asDict( self ): + """Returns the named parse results as dictionary.""" + return dict( self.items() ) + + def copy( self ): + """Returns a new copy of a C{ParseResults} object.""" + ret = ParseResults( self.__toklist ) + ret.__tokdict = self.__tokdict.copy() + ret.__parent = self.__parent + ret.__accumNames.update( self.__accumNames ) + ret.__name = self.__name + return ret + + def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ): + """Returns the parse results as XML. Tags are created for tokens and lists that have defined results names.""" + nl = "\n" + out = [] + namedItems = dict( [ (v[1],k) for (k,vlist) in self.__tokdict.items() + for v in vlist ] ) + nextLevelIndent = indent + " " + + # collapse out indents if formatting is not desired + if not formatted: + indent = "" + nextLevelIndent = "" + nl = "" + + selfTag = None + if doctag is not None: + selfTag = doctag + else: + if self.__name: + selfTag = self.__name + + if not selfTag: + if namedItemsOnly: + return "" + else: + selfTag = "ITEM" + + out += [ nl, indent, "<", selfTag, ">" ] + + worklist = self.__toklist + for i,res in enumerate(worklist): + if isinstance(res,ParseResults): + if i in namedItems: + out += [ res.asXML(namedItems[i], + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + out += [ res.asXML(None, + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + # individual token, see if there is a name for it + resTag = None + if i in namedItems: + resTag = namedItems[i] + if not resTag: + if namedItemsOnly: + continue + else: + resTag = "ITEM" + xmlBodyText = _xml_escape(_ustr(res)) + out += [ nl, nextLevelIndent, "<", resTag, ">", + xmlBodyText, + "" ] + + out += [ nl, indent, "" ] + return "".join(out) + + def __lookup(self,sub): + for k,vlist in self.__tokdict.items(): + for v,loc in vlist: + if sub is v: + return k + return None + + def getName(self): + """Returns the results name for this token expression.""" + if self.__name: + return self.__name + elif self.__parent: + par = self.__parent() + if par: + return par.__lookup(self) + else: + return None + elif (len(self) == 1 and + len(self.__tokdict) == 1 and + self.__tokdict.values()[0][0][1] in (0,-1)): + return self.__tokdict.keys()[0] + else: + return None + + def dump(self,indent='',depth=0): + """Diagnostic method for listing out the contents of a C{ParseResults}. + Accepts an optional C{indent} argument so that this string can be embedded + in a nested display of other data.""" + out = [] + out.append( indent+_ustr(self.asList()) ) + keys = self.items() + keys.sort() + for k,v in keys: + if out: + out.append('\n') + out.append( "%s%s- %s: " % (indent,(' '*depth), k) ) + if isinstance(v,ParseResults): + if v.keys(): + out.append( v.dump(indent,depth+1) ) + else: + out.append(_ustr(v)) + else: + out.append(_ustr(v)) + return "".join(out) + + # add support for pickle protocol + def __getstate__(self): + return ( self.__toklist, + ( self.__tokdict.copy(), + self.__parent is not None and self.__parent() or None, + self.__accumNames, + self.__name ) ) + + def __setstate__(self,state): + self.__toklist = state[0] + self.__tokdict, \ + par, \ + inAccumNames, \ + self.__name = state[1] + self.__accumNames = {} + self.__accumNames.update(inAccumNames) + if par is not None: + self.__parent = wkref(par) + else: + self.__parent = None + + def __dir__(self): + return dir(super(ParseResults,self)) + self.keys() + +def col (loc,strg): + """Returns current column within a string, counting newlines as line separators. + The first column is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{ParserElement.parseString}} for more information + on parsing strings containing s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + """ + return (loc} for more information + on parsing strings containing s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + """ + return strg.count("\n",0,loc) + 1 + +def line( loc, strg ): + """Returns the line of text containing loc within a string, counting newlines as line separators. + """ + lastCR = strg.rfind("\n", 0, loc) + nextCR = strg.find("\n", loc) + if nextCR >= 0: + return strg[lastCR+1:nextCR] + else: + return strg[lastCR+1:] + +def _defaultStartDebugAction( instring, loc, expr ): + print ("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )) + +def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ): + print ("Matched " + _ustr(expr) + " -> " + str(toks.asList())) + +def _defaultExceptionDebugAction( instring, loc, expr, exc ): + print ("Exception raised:" + _ustr(exc)) + +def nullDebugAction(*args): + """'Do-nothing' debug action, to suppress debugging output during parsing.""" + pass + +class ParserElement(object): + """Abstract base level parser element class.""" + DEFAULT_WHITE_CHARS = " \n\t\r" + verbose_stacktrace = False + + def setDefaultWhitespaceChars( chars ): + """Overrides the default whitespace chars + """ + ParserElement.DEFAULT_WHITE_CHARS = chars + setDefaultWhitespaceChars = staticmethod(setDefaultWhitespaceChars) + + def __init__( self, savelist=False ): + self.parseAction = list() + self.failAction = None + #~ self.name = "" # don't define self.name, let subclasses try/except upcall + self.strRepr = None + self.resultsName = None + self.saveAsList = savelist + self.skipWhitespace = True + self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + self.copyDefaultWhiteChars = True + self.mayReturnEmpty = False # used when checking for left-recursion + self.keepTabs = False + self.ignoreExprs = list() + self.debug = False + self.streamlined = False + self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index + self.errmsg = "" + self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all) + self.debugActions = ( None, None, None ) #custom debug actions + self.re = None + self.callPreparse = True # used to avoid redundant calls to preParse + self.callDuringTry = False + + def copy( self ): + """Make a copy of this C{ParserElement}. Useful for defining different parse actions + for the same parsing pattern, using copies of the original parse element.""" + cpy = copy.copy( self ) + cpy.parseAction = self.parseAction[:] + cpy.ignoreExprs = self.ignoreExprs[:] + if self.copyDefaultWhiteChars: + cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + return cpy + + def setName( self, name ): + """Define name for this expression, for use in debugging.""" + self.name = name + self.errmsg = "Expected " + self.name + if hasattr(self,"exception"): + self.exception.msg = self.errmsg + return self + + def setResultsName( self, name, listAllMatches=False ): + """Define name for referencing matching tokens as a nested attribute + of the returned parse results. + NOTE: this returns a *copy* of the original C{ParserElement} object; + this is so that the client can define a basic element, such as an + integer, and reference it in multiple places with different names. + + You can also set results names using the abbreviated syntax, + C{expr("name")} in place of C{expr.setResultsName("name")} - + see L{I{__call__}<__call__>}. + """ + newself = self.copy() + newself.resultsName = name + newself.modalResults = not listAllMatches + return newself + + def setBreak(self,breakFlag = True): + """Method to invoke the Python pdb debugger when this element is + about to be parsed. Set C{breakFlag} to True to enable, False to + disable. + """ + if breakFlag: + _parseMethod = self._parse + def breaker(instring, loc, doActions=True, callPreParse=True): + import pdb + pdb.set_trace() + return _parseMethod( instring, loc, doActions, callPreParse ) + breaker._originalParseMethod = _parseMethod + self._parse = breaker + else: + if hasattr(self._parse,"_originalParseMethod"): + self._parse = self._parse._originalParseMethod + return self + + def _normalizeParseActionArgs( f ): + """Internal method used to decorate parse actions that take fewer than 3 arguments, + so that all parse actions can be called as C{f(s,l,t)}.""" + STAR_ARGS = 4 + + # special handling for single-argument builtins + if (f in singleArgBuiltins): + numargs = 1 + else: + try: + restore = None + if isinstance(f,type): + restore = f + f = f.__init__ + if not _PY3K: + codeObj = f.func_code + else: + codeObj = f.code + if codeObj.co_flags & STAR_ARGS: + return f + numargs = codeObj.co_argcount + if not _PY3K: + if hasattr(f,"im_self"): + numargs -= 1 + else: + if hasattr(f,"__self__"): + numargs -= 1 + if restore: + f = restore + except AttributeError: + try: + if not _PY3K: + call_im_func_code = f.__call__.im_func.func_code + else: + call_im_func_code = f.__code__ + + # not a function, must be a callable object, get info from the + # im_func binding of its bound __call__ method + if call_im_func_code.co_flags & STAR_ARGS: + return f + numargs = call_im_func_code.co_argcount + if not _PY3K: + if hasattr(f.__call__,"im_self"): + numargs -= 1 + else: + if hasattr(f.__call__,"__self__"): + numargs -= 0 + except AttributeError: + if not _PY3K: + call_func_code = f.__call__.func_code + else: + call_func_code = f.__call__.__code__ + # not a bound method, get info directly from __call__ method + if call_func_code.co_flags & STAR_ARGS: + return f + numargs = call_func_code.co_argcount + if not _PY3K: + if hasattr(f.__call__,"im_self"): + numargs -= 1 + else: + if hasattr(f.__call__,"__self__"): + numargs -= 1 + + + #~ print ("adding function %s with %d args" % (f.func_name,numargs)) + if numargs == 3: + return f + else: + if numargs > 3: + def tmp(s,l,t): + return f(f.__call__.__self__, s,l,t) + if numargs == 2: + def tmp(s,l,t): + return f(l,t) + elif numargs == 1: + def tmp(s,l,t): + return f(t) + else: #~ numargs == 0: + def tmp(s,l,t): + return f() + try: + tmp.__name__ = f.__name__ + except (AttributeError,TypeError): + # no need for special handling if attribute doesnt exist + pass + try: + tmp.__doc__ = f.__doc__ + except (AttributeError,TypeError): + # no need for special handling if attribute doesnt exist + pass + try: + tmp.__dict__.update(f.__dict__) + except (AttributeError,TypeError): + # no need for special handling if attribute doesnt exist + pass + return tmp + _normalizeParseActionArgs = staticmethod(_normalizeParseActionArgs) + + def setParseAction( self, *fns, **kwargs ): + """Define action to perform when successfully matching parse element definition. + Parse action fn is a callable method with 0-3 arguments, called as C{fn(s,loc,toks)}, + C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where: + - s = the original string being parsed (see note below) + - loc = the location of the matching substring + - toks = a list of the matched tokens, packaged as a ParseResults object + If the functions in fns modify the tokens, they can return them as the return + value from fn, and the modified list of tokens will replace the original. + Otherwise, fn does not need to return any value. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{parseString}} for more information + on parsing strings containing s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + """ + self.parseAction = list(map(self._normalizeParseActionArgs, list(fns))) + self.callDuringTry = ("callDuringTry" in kwargs and kwargs["callDuringTry"]) + return self + + def addParseAction( self, *fns, **kwargs ): + """Add parse action to expression's list of parse actions. See L{I{setParseAction}}.""" + self.parseAction += list(map(self._normalizeParseActionArgs, list(fns))) + self.callDuringTry = self.callDuringTry or ("callDuringTry" in kwargs and kwargs["callDuringTry"]) + return self + + def setFailAction( self, fn ): + """Define action to perform if parsing fails at this expression. + Fail acton fn is a callable function that takes the arguments + C{fn(s,loc,expr,err)} where: + - s = string being parsed + - loc = location where expression match was attempted and failed + - expr = the parse expression that failed + - err = the exception thrown + The function returns no value. It may throw C{ParseFatalException} + if it is desired to stop parsing immediately.""" + self.failAction = fn + return self + + def _skipIgnorables( self, instring, loc ): + exprsFound = True + while exprsFound: + exprsFound = False + for e in self.ignoreExprs: + try: + while 1: + loc,dummy = e._parse( instring, loc ) + exprsFound = True + except ParseException: + pass + return loc + + def preParse( self, instring, loc ): + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + + if self.skipWhitespace: + wt = self.whiteChars + instrlen = len(instring) + while loc < instrlen and instring[loc] in wt: + loc += 1 + + return loc + + def parseImpl( self, instring, loc, doActions=True ): + return loc, [] + + def postParse( self, instring, loc, tokenlist ): + return tokenlist + + #~ @profile + def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ): + debugging = ( self.debug ) #and doActions ) + + if debugging or self.failAction: + #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )) + if (self.debugActions[0] ): + self.debugActions[0]( instring, loc, self ) + if callPreParse and self.callPreparse: + preloc = self.preParse( instring, loc ) + else: + preloc = loc + tokensStart = preloc + try: + try: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + except IndexError: + raise ParseException( instring, len(instring), self.errmsg, self ) + except ParseBaseException: + #~ print ("Exception raised:", err) + err = None + if self.debugActions[2]: + err = sys.exc_info()[1] + self.debugActions[2]( instring, tokensStart, self, err ) + if self.failAction: + if err is None: + err = sys.exc_info()[1] + self.failAction( instring, tokensStart, self, err ) + raise + else: + if callPreParse and self.callPreparse: + preloc = self.preParse( instring, loc ) + else: + preloc = loc + tokensStart = preloc + if self.mayIndexError or loc >= len(instring): + try: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + except IndexError: + raise ParseException( instring, len(instring), self.errmsg, self ) + else: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + + tokens = self.postParse( instring, loc, tokens ) + + retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults ) + if self.parseAction and (doActions or self.callDuringTry): + if debugging: + try: + for fn in self.parseAction: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + retTokens = ParseResults( tokens, + self.resultsName, + asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), + modal=self.modalResults ) + except ParseBaseException: + #~ print "Exception raised in user parse action:", err + if (self.debugActions[2] ): + err = sys.exc_info()[1] + self.debugActions[2]( instring, tokensStart, self, err ) + raise + else: + for fn in self.parseAction: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + retTokens = ParseResults( tokens, + self.resultsName, + asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), + modal=self.modalResults ) + + if debugging: + #~ print ("Matched",self,"->",retTokens.asList()) + if (self.debugActions[1] ): + self.debugActions[1]( instring, tokensStart, loc, self, retTokens ) + + return loc, retTokens + + def tryParse( self, instring, loc ): + try: + return self._parse( instring, loc, doActions=False )[0] + except ParseFatalException: + raise ParseException( instring, loc, self.errmsg, self) + + # this method gets repeatedly called during backtracking with the same arguments - + # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression + def _parseCache( self, instring, loc, doActions=True, callPreParse=True ): + lookup = (self,instring,loc,callPreParse,doActions) + if lookup in ParserElement._exprArgCache: + value = ParserElement._exprArgCache[ lookup ] + if isinstance(value,Exception): + raise value + return value + else: + try: + value = self._parseNoCache( instring, loc, doActions, callPreParse ) + ParserElement._exprArgCache[ lookup ] = (value[0],value[1].copy()) + return value + except ParseBaseException: + pe = sys.exc_info()[1] + ParserElement._exprArgCache[ lookup ] = pe + raise + + _parse = _parseNoCache + + # argument cache for optimizing repeated calls when backtracking through recursive expressions + _exprArgCache = {} + def resetCache(): + ParserElement._exprArgCache.clear() + resetCache = staticmethod(resetCache) + + _packratEnabled = False + def enablePackrat(): + """Enables "packrat" parsing, which adds memoizing to the parsing logic. + Repeated parse attempts at the same string location (which happens + often in many complex grammars) can immediately return a cached value, + instead of re-executing parsing/validating code. Memoizing is done of + both valid results and parsing exceptions. + + This speedup may break existing programs that use parse actions that + have side-effects. For this reason, packrat parsing is disabled when + you first import pyparsing. To activate the packrat feature, your + program must call the class method C{ParserElement.enablePackrat()}. If + your program uses C{psyco} to "compile as you go", you must call + C{enablePackrat} before calling C{psyco.full()}. If you do not do this, + Python will crash. For best results, call C{enablePackrat()} immediately + after importing pyparsing. + """ + if not ParserElement._packratEnabled: + ParserElement._packratEnabled = True + ParserElement._parse = ParserElement._parseCache + enablePackrat = staticmethod(enablePackrat) + + def parseString( self, instring, parseAll=False ): + """Execute the parse expression with the given string. + This is the main interface to the client code, once the complete + expression has been built. + + If you want the grammar to require that the entire input string be + successfully parsed, then set C{parseAll} to True (equivalent to ending + the grammar with C{StringEnd()}). + + Note: C{parseString} implicitly calls C{expandtabs()} on the input string, + in order to report proper column numbers in parse actions. + If the input string contains tabs and + the grammar uses parse actions that use the C{loc} argument to index into the + string being parsed, you can ensure you have a consistent view of the input + string by: + - calling C{parseWithTabs} on your grammar before calling C{parseString} + (see L{I{parseWithTabs}}) + - define your parse action using the full C{(s,loc,toks)} signature, and + reference the input string using the parse action's C{s} argument + - explictly expand the tabs in your input string before calling + C{parseString} + """ + ParserElement.resetCache() + if not self.streamlined: + self.streamline() + #~ self.saveAsList = True + for e in self.ignoreExprs: + e.streamline() + if not self.keepTabs: + instring = instring.expandtabs() + try: + loc, tokens = self._parse( instring, 0 ) + if parseAll: + #loc = self.preParse( instring, loc ) + se = StringEnd() + se._parse( instring, loc ) + except ParseBaseException: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + exc = sys.exc_info()[1] + raise exc + else: + return tokens + + def scanString( self, instring, maxMatches=_MAX_INT ): + """Scan the input string for expression matches. Each match will return the + matching tokens, start location, and end location. May be called with optional + C{maxMatches} argument, to clip scanning after 'n' matches are found. + + Note that the start and end locations are reported relative to the string + being parsed. See L{I{parseString}} for more information on parsing + strings with embedded tabs.""" + if not self.streamlined: + self.streamline() + for e in self.ignoreExprs: + e.streamline() + + if not self.keepTabs: + instring = _ustr(instring).expandtabs() + instrlen = len(instring) + loc = 0 + preparseFn = self.preParse + parseFn = self._parse + ParserElement.resetCache() + matches = 0 + try: + while loc <= instrlen and matches < maxMatches: + try: + preloc = preparseFn( instring, loc ) + nextLoc,tokens = parseFn( instring, preloc, callPreParse=False ) + except ParseException: + loc = preloc+1 + else: + if nextLoc > loc: + matches += 1 + yield tokens, preloc, nextLoc + loc = nextLoc + else: + loc = preloc+1 + except ParseBaseException: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + exc = sys.exc_info()[1] + raise exc + + def transformString( self, instring ): + """Extension to C{scanString}, to modify matching text with modified tokens that may + be returned from a parse action. To use C{transformString}, define a grammar and + attach a parse action to it that modifies the returned token list. + Invoking C{transformString()} on a target string will then scan for matches, + and replace the matched text patterns according to the logic in the parse + action. C{transformString()} returns the resulting transformed string.""" + out = [] + lastE = 0 + # force preservation of s, to minimize unwanted transformation of string, and to + # keep string locs straight between transformString and scanString + self.keepTabs = True + try: + for t,s,e in self.scanString( instring ): + out.append( instring[lastE:s] ) + if t: + if isinstance(t,ParseResults): + out += t.asList() + elif isinstance(t,list): + out += t + else: + out.append(t) + lastE = e + out.append(instring[lastE:]) + return "".join(map(_ustr,_flatten(out))) + except ParseBaseException: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + exc = sys.exc_info()[1] + raise exc + + def searchString( self, instring, maxMatches=_MAX_INT ): + """Another extension to C{scanString}, simplifying the access to the tokens found + to match the given parse expression. May be called with optional + C{maxMatches} argument, to clip searching after 'n' matches are found. + """ + try: + return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ]) + except ParseBaseException: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + exc = sys.exc_info()[1] + raise exc + + def __add__(self, other ): + """Implementation of + operator - returns And""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return And( [ self, other ] ) + + def __radd__(self, other ): + """Implementation of + operator when left operand is not a C{ParserElement}""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other + self + + def __sub__(self, other): + """Implementation of - operator, returns C{And} with error stop""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return And( [ self, And._ErrorStop(), other ] ) + + def __rsub__(self, other ): + """Implementation of - operator when left operand is not a C{ParserElement}""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other - self + + def __mul__(self,other): + """Implementation of * operator, allows use of C{expr * 3} in place of + C{expr + expr + expr}. Expressions may also me multiplied by a 2-integer + tuple, similar to C{{min,max}} multipliers in regular expressions. Tuples + may also include C{None} as in: + - C{expr*(n,None)} or C{expr*(n,)} is equivalent + to C{expr*n + ZeroOrMore(expr)} + (read as "at least n instances of C{expr}") + - C{expr*(None,n)} is equivalent to C{expr*(0,n)} + (read as "0 to n instances of C{expr}") + - C{expr*(None,None)} is equivalent to C{ZeroOrMore(expr)} + - C{expr*(1,None)} is equivalent to C{OneOrMore(expr)} + + Note that C{expr*(None,n)} does not raise an exception if + more than n exprs exist in the input stream; that is, + C{expr*(None,n)} does not enforce a maximum number of expr + occurrences. If this behavior is desired, then write + C{expr*(None,n) + ~expr} + + """ + if isinstance(other,int): + minElements, optElements = other,0 + elif isinstance(other,tuple): + other = (other + (None, None))[:2] + if other[0] is None: + other = (0, other[1]) + if isinstance(other[0],int) and other[1] is None: + if other[0] == 0: + return ZeroOrMore(self) + if other[0] == 1: + return OneOrMore(self) + else: + return self*other[0] + ZeroOrMore(self) + elif isinstance(other[0],int) and isinstance(other[1],int): + minElements, optElements = other + optElements -= minElements + else: + raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1])) + else: + raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other)) + + if minElements < 0: + raise ValueError("cannot multiply ParserElement by negative value") + if optElements < 0: + raise ValueError("second tuple value must be greater or equal to first tuple value") + if minElements == optElements == 0: + raise ValueError("cannot multiply ParserElement by 0 or (0,0)") + + if (optElements): + def makeOptionalList(n): + if n>1: + return Optional(self + makeOptionalList(n-1)) + else: + return Optional(self) + if minElements: + if minElements == 1: + ret = self + makeOptionalList(optElements) + else: + ret = And([self]*minElements) + makeOptionalList(optElements) + else: + ret = makeOptionalList(optElements) + else: + if minElements == 1: + ret = self + else: + ret = And([self]*minElements) + return ret + + def __rmul__(self, other): + return self.__mul__(other) + + def __or__(self, other ): + """Implementation of | operator - returns C{MatchFirst}""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return MatchFirst( [ self, other ] ) + + def __ror__(self, other ): + """Implementation of | operator when left operand is not a C{ParserElement}""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other | self + + def __xor__(self, other ): + """Implementation of ^ operator - returns C{Or}""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return Or( [ self, other ] ) + + def __rxor__(self, other ): + """Implementation of ^ operator when left operand is not a C{ParserElement}""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other ^ self + + def __and__(self, other ): + """Implementation of & operator - returns C{Each}""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return Each( [ self, other ] ) + + def __rand__(self, other ): + """Implementation of & operator when left operand is not a C{ParserElement}""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other & self + + def __invert__( self ): + """Implementation of ~ operator - returns C{NotAny}""" + return NotAny( self ) + + def __call__(self, name): + """Shortcut for C{setResultsName}, with C{listAllMatches=default}:: + userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno") + could be written as:: + userdata = Word(alphas)("name") + Word(nums+"-")("socsecno") + """ + return self.setResultsName(name) + + def suppress( self ): + """Suppresses the output of this C{ParserElement}; useful to keep punctuation from + cluttering up returned output. + """ + return Suppress( self ) + + def leaveWhitespace( self ): + """Disables the skipping of whitespace before matching the characters in the + C{ParserElement}'s defined pattern. This is normally only used internally by + the pyparsing module, but may be needed in some whitespace-sensitive grammars. + """ + self.skipWhitespace = False + return self + + def setWhitespaceChars( self, chars ): + """Overrides the default whitespace chars + """ + self.skipWhitespace = True + self.whiteChars = chars + self.copyDefaultWhiteChars = False + return self + + def parseWithTabs( self ): + """Overrides default behavior to expand s to spaces before parsing the input string. + Must be called before C{parseString} when the input grammar contains elements that + match characters.""" + self.keepTabs = True + return self + + def ignore( self, other ): + """Define expression to be ignored (e.g., comments) while doing pattern + matching; may be called repeatedly, to define multiple comment or other + ignorable patterns. + """ + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + self.ignoreExprs.append( other.copy() ) + else: + self.ignoreExprs.append( Suppress( other.copy() ) ) + return self + + def setDebugActions( self, startAction, successAction, exceptionAction ): + """Enable display of debugging messages while doing pattern matching.""" + self.debugActions = (startAction or _defaultStartDebugAction, + successAction or _defaultSuccessDebugAction, + exceptionAction or _defaultExceptionDebugAction) + self.debug = True + return self + + def setDebug( self, flag=True ): + """Enable display of debugging messages while doing pattern matching. + Set C{flag} to True to enable, False to disable.""" + if flag: + self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction ) + else: + self.debug = False + return self + + def __str__( self ): + return self.name + + def __repr__( self ): + return _ustr(self) + + def streamline( self ): + self.streamlined = True + self.strRepr = None + return self + + def checkRecursion( self, parseElementList ): + pass + + def validate( self, validateTrace=[] ): + """Check defined expressions for valid structure, check for infinite recursive definitions.""" + self.checkRecursion( [] ) + + def parseFile( self, file_or_filename, parseAll=False ): + """Execute the parse expression on the given file or filename. + If a filename is specified (instead of a file object), + the entire file is opened, read, and closed before parsing. + """ + try: + file_contents = file_or_filename.read() + except AttributeError: + f = open(file_or_filename, "rb") + file_contents = f.read() + f.close() + try: + return self.parseString(file_contents, parseAll) + except ParseBaseException: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + exc = sys.exc_info()[1] + raise exc + + def getException(self): + return ParseException("",0,self.errmsg,self) + + def __getattr__(self,aname): + if aname == "myException": + self.myException = ret = self.getException(); + return ret; + else: + raise AttributeError("no such attribute " + aname) + + def __eq__(self,other): + if isinstance(other, ParserElement): + return self is other or self.__dict__ == other.__dict__ + elif isinstance(other, basestring): + try: + self.parseString(_ustr(other), parseAll=True) + return True + except ParseBaseException: + return False + else: + return super(ParserElement,self)==other + + def __ne__(self,other): + return not (self == other) + + def __hash__(self): + return hash(id(self)) + + def __req__(self,other): + return self == other + + def __rne__(self,other): + return not (self == other) + + +class Token(ParserElement): + """Abstract C{ParserElement} subclass, for defining atomic matching patterns.""" + def __init__( self ): + super(Token,self).__init__( savelist=False ) + #self.myException = ParseException("",0,"",self) + + def setName(self, name): + s = super(Token,self).setName(name) + self.errmsg = "Expected " + self.name + #s.myException.msg = self.errmsg + return s + + +class Empty(Token): + """An empty token, will always match.""" + def __init__( self ): + super(Empty,self).__init__() + self.name = "Empty" + self.mayReturnEmpty = True + self.mayIndexError = False + + +class NoMatch(Token): + """A token that will never match.""" + def __init__( self ): + super(NoMatch,self).__init__() + self.name = "NoMatch" + self.mayReturnEmpty = True + self.mayIndexError = False + self.errmsg = "Unmatchable token" + #self.myException.msg = self.errmsg + + def parseImpl( self, instring, loc, doActions=True ): + exc = self.myException + exc.loc = loc + exc.pstr = instring + raise exc + + +class Literal(Token): + """Token to exactly match a specified string.""" + def __init__( self, matchString ): + super(Literal,self).__init__() + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Literal; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.__class__ = Empty + self.name = '"%s"' % _ustr(self.match) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + #self.myException.msg = self.errmsg + self.mayIndexError = False + + # Performance tuning: this routine gets called a *lot* + # if this is a single character match string and the first character matches, + # short-circuit as quickly as possible, and avoid calling startswith + #~ @profile + def parseImpl( self, instring, loc, doActions=True ): + if (instring[loc] == self.firstMatchChar and + (self.matchLen==1 or instring.startswith(self.match,loc)) ): + return loc+self.matchLen, self.match + #~ raise ParseException( instring, loc, self.errmsg ) + exc = self.myException + exc.loc = loc + exc.pstr = instring + raise exc +_L = Literal + +class Keyword(Token): + """Token to exactly match a specified string as a keyword, that is, it must be + immediately followed by a non-keyword character. Compare with C{Literal}:: + Literal("if") will match the leading 'if' in 'ifAndOnlyIf'. + Keyword("if") will not; it will only match the leading 'if in 'if x=1', or 'if(y==2)' + Accepts two optional constructor arguments in addition to the keyword string: + C{identChars} is a string of characters that would be valid identifier characters, + defaulting to all alphanumerics + "_" and "$"; C{caseless} allows case-insensitive + matching, default is False. + """ + DEFAULT_KEYWORD_CHARS = alphanums+"_$" + + def __init__( self, matchString, identChars=DEFAULT_KEYWORD_CHARS, caseless=False ): + super(Keyword,self).__init__() + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Keyword; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.name = '"%s"' % self.match + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + #self.myException.msg = self.errmsg + self.mayIndexError = False + self.caseless = caseless + if caseless: + self.caselessmatch = matchString.upper() + identChars = identChars.upper() + self.identChars = _str2dict(identChars) + + def parseImpl( self, instring, loc, doActions=True ): + if self.caseless: + if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and + (loc == 0 or instring[loc-1].upper() not in self.identChars) ): + return loc+self.matchLen, self.match + else: + if (instring[loc] == self.firstMatchChar and + (self.matchLen==1 or instring.startswith(self.match,loc)) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and + (loc == 0 or instring[loc-1] not in self.identChars) ): + return loc+self.matchLen, self.match + #~ raise ParseException( instring, loc, self.errmsg ) + exc = self.myException + exc.loc = loc + exc.pstr = instring + raise exc + + def copy(self): + c = super(Keyword,self).copy() + c.identChars = Keyword.DEFAULT_KEYWORD_CHARS + return c + + def setDefaultKeywordChars( chars ): + """Overrides the default Keyword chars + """ + Keyword.DEFAULT_KEYWORD_CHARS = chars + setDefaultKeywordChars = staticmethod(setDefaultKeywordChars) + +class CaselessLiteral(Literal): + """Token to match a specified string, ignoring case of letters. + Note: the matched results will always be in the case of the given + match string, NOT the case of the input text. + """ + def __init__( self, matchString ): + super(CaselessLiteral,self).__init__( matchString.upper() ) + # Preserve the defining literal. + self.returnString = matchString + self.name = "'%s'" % self.returnString + self.errmsg = "Expected " + self.name + #self.myException.msg = self.errmsg + + def parseImpl( self, instring, loc, doActions=True ): + if instring[ loc:loc+self.matchLen ].upper() == self.match: + return loc+self.matchLen, self.returnString + #~ raise ParseException( instring, loc, self.errmsg ) + exc = self.myException + exc.loc = loc + exc.pstr = instring + raise exc + +class CaselessKeyword(Keyword): + def __init__( self, matchString, identChars=Keyword.DEFAULT_KEYWORD_CHARS ): + super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True ) + + def parseImpl( self, instring, loc, doActions=True ): + if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ): + return loc+self.matchLen, self.match + #~ raise ParseException( instring, loc, self.errmsg ) + exc = self.myException + exc.loc = loc + exc.pstr = instring + raise exc + +class Word(Token): + """Token for matching words composed of allowed character sets. + Defined with string containing all allowed initial characters, + an optional string containing allowed body characters (if omitted, + defaults to the initial character set), and an optional minimum, + maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. + """ + def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False ): + super(Word,self).__init__() + self.initCharsOrig = initChars + self.initChars = _str2dict(initChars) + if bodyChars : + self.bodyCharsOrig = bodyChars + self.bodyChars = _str2dict(bodyChars) + else: + self.bodyCharsOrig = initChars + self.bodyChars = _str2dict(initChars) + + self.maxSpecified = max > 0 + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + #self.myException.msg = self.errmsg + self.mayIndexError = False + self.asKeyword = asKeyword + + if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0): + if self.bodyCharsOrig == self.initCharsOrig: + self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig) + elif len(self.bodyCharsOrig) == 1: + self.reString = "%s[%s]*" % \ + (re.escape(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + else: + self.reString = "[%s][%s]*" % \ + (_escapeRegexRangeChars(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + if self.asKeyword: + self.reString = r"\b"+self.reString+r"\b" + try: + self.re = re.compile( self.reString ) + except: + self.re = None + + def parseImpl( self, instring, loc, doActions=True ): + if self.re: + result = self.re.match(instring,loc) + if not result: + exc = self.myException + exc.loc = loc + exc.pstr = instring + raise exc + + loc = result.end() + return loc,result.group() + + if not(instring[ loc ] in self.initChars): + #~ raise ParseException( instring, loc, self.errmsg ) + exc = self.myException + exc.loc = loc + exc.pstr = instring + raise exc + start = loc + loc += 1 + instrlen = len(instring) + bodychars = self.bodyChars + maxloc = start + self.maxLen + maxloc = min( maxloc, instrlen ) + while loc < maxloc and instring[loc] in bodychars: + loc += 1 + + throwException = False + if loc - start < self.minLen: + throwException = True + if self.maxSpecified and loc < instrlen and instring[loc] in bodychars: + throwException = True + if self.asKeyword: + if (start>0 and instring[start-1] in bodychars) or (loc4: + return s[:4]+"..." + else: + return s + + if ( self.initCharsOrig != self.bodyCharsOrig ): + self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) ) + else: + self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig) + + return self.strRepr + + +class Regex(Token): + """Token for matching strings that match a given regular expression. + Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module. + """ + compiledREtype = type(re.compile("[A-Z]")) + def __init__( self, pattern, flags=0): + """The parameters pattern and flags are passed to the re.compile() function as-is. See the Python re module for an explanation of the acceptable patterns and flags.""" + super(Regex,self).__init__() + + if isinstance(pattern, basestring): + if len(pattern) == 0: + warnings.warn("null string passed to Regex; use Empty() instead", + SyntaxWarning, stacklevel=2) + + self.pattern = pattern + self.flags = flags + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % pattern, + SyntaxWarning, stacklevel=2) + raise + + elif isinstance(pattern, Regex.compiledREtype): + self.re = pattern + self.pattern = \ + self.reString = str(pattern) + self.flags = flags + + else: + raise ValueError("Regex may only be constructed with a string or a compiled RE object") + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + #self.myException.msg = self.errmsg + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = self.re.match(instring,loc) + if not result: + exc = self.myException + exc.loc = loc + exc.pstr = instring + raise exc + + loc = result.end() + d = result.groupdict() + ret = ParseResults(result.group()) + if d: + for k in d: + ret[k] = d[k] + return loc,ret + + def __str__( self ): + try: + return super(Regex,self).__str__() + except: + pass + + if self.strRepr is None: + self.strRepr = "Re:(%s)" % repr(self.pattern) + + return self.strRepr + + +class QuotedString(Token): + """Token for matching strings that are delimited by quoting characters. + """ + def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None): + """ + Defined with the following parameters: + - quoteChar - string of one or more characters defining the quote delimiting string + - escChar - character to escape quotes, typically backslash (default=None) + - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=None) + - multiline - boolean indicating whether quotes can span multiple lines (default=False) + - unquoteResults - boolean indicating whether the matched text should be unquoted (default=True) + - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=None => same as quoteChar) + """ + super(QuotedString,self).__init__() + + # remove white space from quote chars - wont work anyway + quoteChar = quoteChar.strip() + if len(quoteChar) == 0: + warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + if endQuoteChar is None: + endQuoteChar = quoteChar + else: + endQuoteChar = endQuoteChar.strip() + if len(endQuoteChar) == 0: + warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + self.quoteChar = quoteChar + self.quoteCharLen = len(quoteChar) + self.firstQuoteChar = quoteChar[0] + self.endQuoteChar = endQuoteChar + self.endQuoteCharLen = len(endQuoteChar) + self.escChar = escChar + self.escQuote = escQuote + self.unquoteResults = unquoteResults + + if multiline: + self.flags = re.MULTILINE | re.DOTALL + self.pattern = r'%s(?:[^%s%s]' % \ + ( re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + else: + self.flags = 0 + self.pattern = r'%s(?:[^%s\n\r%s]' % \ + ( re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + if len(self.endQuoteChar) > 1: + self.pattern += ( + '|(?:' + ')|(?:'.join(["%s[^%s]" % (re.escape(self.endQuoteChar[:i]), + _escapeRegexRangeChars(self.endQuoteChar[i])) + for i in range(len(self.endQuoteChar)-1,0,-1)]) + ')' + ) + if escQuote: + self.pattern += (r'|(?:%s)' % re.escape(escQuote)) + if escChar: + self.pattern += (r'|(?:%s.)' % re.escape(escChar)) + self.escCharReplacePattern = re.escape(self.escChar)+"(.)" + self.pattern += (r')*%s' % re.escape(self.endQuoteChar)) + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern, + SyntaxWarning, stacklevel=2) + raise + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + #self.myException.msg = self.errmsg + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None + if not result: + exc = self.myException + exc.loc = loc + exc.pstr = instring + raise exc + + loc = result.end() + ret = result.group() + + if self.unquoteResults: + + # strip off quotes + ret = ret[self.quoteCharLen:-self.endQuoteCharLen] + + if isinstance(ret,basestring): + # replace escaped characters + if self.escChar: + ret = re.sub(self.escCharReplacePattern,"\g<1>",ret) + + # replace escaped quotes + if self.escQuote: + ret = ret.replace(self.escQuote, self.endQuoteChar) + + return loc, ret + + def __str__( self ): + try: + return super(QuotedString,self).__str__() + except: + pass + + if self.strRepr is None: + self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar) + + return self.strRepr + + +class CharsNotIn(Token): + """Token for matching words composed of characters *not* in a given set. + Defined with string containing all disallowed characters, and an optional + minimum, maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. + """ + def __init__( self, notChars, min=1, max=0, exact=0 ): + super(CharsNotIn,self).__init__() + self.skipWhitespace = False + self.notChars = notChars + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = ( self.minLen == 0 ) + #self.myException.msg = self.errmsg + self.mayIndexError = False + + def parseImpl( self, instring, loc, doActions=True ): + if instring[loc] in self.notChars: + #~ raise ParseException( instring, loc, self.errmsg ) + exc = self.myException + exc.loc = loc + exc.pstr = instring + raise exc + + start = loc + loc += 1 + notchars = self.notChars + maxlen = min( start+self.maxLen, len(instring) ) + while loc < maxlen and \ + (instring[loc] not in notchars): + loc += 1 + + if loc - start < self.minLen: + #~ raise ParseException( instring, loc, self.errmsg ) + exc = self.myException + exc.loc = loc + exc.pstr = instring + raise exc + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(CharsNotIn, self).__str__() + except: + pass + + if self.strRepr is None: + if len(self.notChars) > 4: + self.strRepr = "!W:(%s...)" % self.notChars[:4] + else: + self.strRepr = "!W:(%s)" % self.notChars + + return self.strRepr + +class White(Token): + """Special matching class for matching whitespace. Normally, whitespace is ignored + by pyparsing grammars. This class is included when some whitespace structures + are significant. Define with a string containing the whitespace characters to be + matched; default is C{" \\t\\r\\n"}. Also takes optional C{min}, C{max}, and C{exact} arguments, + as defined for the C{Word} class.""" + whiteStrs = { + " " : "", + "\t": "", + "\n": "", + "\r": "", + "\f": "", + } + def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0): + super(White,self).__init__() + self.matchWhite = ws + self.setWhitespaceChars( "".join([c for c in self.whiteChars if c not in self.matchWhite]) ) + #~ self.leaveWhitespace() + self.name = ("".join([White.whiteStrs[c] for c in self.matchWhite])) + self.mayReturnEmpty = True + self.errmsg = "Expected " + self.name + #self.myException.msg = self.errmsg + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + def parseImpl( self, instring, loc, doActions=True ): + if not(instring[ loc ] in self.matchWhite): + #~ raise ParseException( instring, loc, self.errmsg ) + exc = self.myException + exc.loc = loc + exc.pstr = instring + raise exc + start = loc + loc += 1 + maxloc = start + self.maxLen + maxloc = min( maxloc, len(instring) ) + while loc < maxloc and instring[loc] in self.matchWhite: + loc += 1 + + if loc - start < self.minLen: + #~ raise ParseException( instring, loc, self.errmsg ) + exc = self.myException + exc.loc = loc + exc.pstr = instring + raise exc + + return loc, instring[start:loc] + + +class _PositionToken(Token): + def __init__( self ): + super(_PositionToken,self).__init__() + self.name=self.__class__.__name__ + self.mayReturnEmpty = True + self.mayIndexError = False + +class GoToColumn(_PositionToken): + """Token to advance to a specific column of input text; useful for tabular report scraping.""" + def __init__( self, colno ): + super(GoToColumn,self).__init__() + self.col = colno + + def preParse( self, instring, loc ): + if col(loc,instring) != self.col: + instrlen = len(instring) + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col : + loc += 1 + return loc + + def parseImpl( self, instring, loc, doActions=True ): + thiscol = col( loc, instring ) + if thiscol > self.col: + raise ParseException( instring, loc, "Text not in expected column", self ) + newloc = loc + self.col - thiscol + ret = instring[ loc: newloc ] + return newloc, ret + +class LineStart(_PositionToken): + """Matches if current position is at the beginning of a line within the parse string""" + def __init__( self ): + super(LineStart,self).__init__() + self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") ) + self.errmsg = "Expected start of line" + #self.myException.msg = self.errmsg + + def preParse( self, instring, loc ): + preloc = super(LineStart,self).preParse(instring,loc) + if instring[preloc] == "\n": + loc += 1 + return loc + + def parseImpl( self, instring, loc, doActions=True ): + if not( loc==0 or + (loc == self.preParse( instring, 0 )) or + (instring[loc-1] == "\n") ): #col(loc, instring) != 1: + #~ raise ParseException( instring, loc, "Expected start of line" ) + exc = self.myException + exc.loc = loc + exc.pstr = instring + raise exc + return loc, [] + +class LineEnd(_PositionToken): + """Matches if current position is at the end of a line within the parse string""" + def __init__( self ): + super(LineEnd,self).__init__() + self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") ) + self.errmsg = "Expected end of line" + #self.myException.msg = self.errmsg + + def parseImpl( self, instring, loc, doActions=True ): + if loc len(instring): + return loc, [] + else: + exc = self.myException + exc.loc = loc + exc.pstr = instring + raise exc + +class WordStart(_PositionToken): + """Matches if the current position is at the beginning of a Word, and + is not preceded by any character in a given set of wordChars + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of + the string being parsed, or at the beginning of a line. + """ + def __init__(self, wordChars = printables): + super(WordStart,self).__init__() + self.wordChars = _str2dict(wordChars) + self.errmsg = "Not at the start of a word" + + def parseImpl(self, instring, loc, doActions=True ): + if loc != 0: + if (instring[loc-1] in self.wordChars or + instring[loc] not in self.wordChars): + exc = self.myException + exc.loc = loc + exc.pstr = instring + raise exc + return loc, [] + +class WordEnd(_PositionToken): + """Matches if the current position is at the end of a Word, and + is not followed by any character in a given set of wordChars + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordEnd(alphanums)}. C{WordEnd} will also match at the end of + the string being parsed, or at the end of a line. + """ + def __init__(self, wordChars = printables): + super(WordEnd,self).__init__() + self.wordChars = _str2dict(wordChars) + self.skipWhitespace = False + self.errmsg = "Not at the end of a word" + + def parseImpl(self, instring, loc, doActions=True ): + instrlen = len(instring) + if instrlen>0 and loc maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException(instring,len(instring),e.errmsg,self) + maxExcLoc = len(instring) + else: + if loc2 > maxMatchLoc: + maxMatchLoc = loc2 + maxMatchExp = e + + if maxMatchLoc < 0: + if maxException is not None: + raise maxException + else: + raise ParseException(instring, loc, "no defined alternatives to match", self) + + return maxMatchExp._parse( instring, loc, doActions ) + + def __ixor__(self, other ): + if isinstance( other, basestring ): + other = Literal( other ) + return self.append( other ) #Or( [ self, other ] ) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ^ ".join( [ _ustr(e) for e in self.exprs ] ) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class MatchFirst(ParseExpression): + """Requires that at least one C{ParseExpression} is found. + If two expressions match, the first one listed is the one that will match. + May be constructed using the '|' operator. + """ + def __init__( self, exprs, savelist = False ): + super(MatchFirst,self).__init__(exprs, savelist) + if exprs: + self.mayReturnEmpty = False + for e in self.exprs: + if e.mayReturnEmpty: + self.mayReturnEmpty = True + break + else: + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + for e in self.exprs: + try: + ret = e._parse( instring, loc, doActions ) + return ret + except ParseException, err: + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException(instring,len(instring),e.errmsg,self) + maxExcLoc = len(instring) + + # only got here if no expression matched, raise exception for match that made it the furthest + else: + if maxException is not None: + raise maxException + else: + raise ParseException(instring, loc, "no defined alternatives to match", self) + + def __ior__(self, other ): + if isinstance( other, basestring ): + other = Literal( other ) + return self.append( other ) #MatchFirst( [ self, other ] ) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " | ".join( [ _ustr(e) for e in self.exprs ] ) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class Each(ParseExpression): + """Requires all given C{ParseExpressions} to be found, but in any order. + Expressions may be separated by whitespace. + May be constructed using the '&' operator. + """ + def __init__( self, exprs, savelist = True ): + super(Each,self).__init__(exprs, savelist) + self.mayReturnEmpty = True + for e in self.exprs: + if not e.mayReturnEmpty: + self.mayReturnEmpty = False + break + self.skipWhitespace = True + self.initExprGroups = True + + def parseImpl( self, instring, loc, doActions=True ): + if self.initExprGroups: + opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ] + opt2 = [ e for e in self.exprs if e.mayReturnEmpty and e not in opt1 ] + self.optionals = opt1 + opt2 + self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ] + self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ] + self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ] + self.required += self.multirequired + self.initExprGroups = False + tmpLoc = loc + tmpReqd = self.required[:] + tmpOpt = self.optionals[:] + matchOrder = [] + + keepMatching = True + while keepMatching: + tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired + failed = [] + for e in tmpExprs: + try: + tmpLoc = e.tryParse( instring, tmpLoc ) + except ParseException: + failed.append(e) + else: + matchOrder.append(e) + if e in tmpReqd: + tmpReqd.remove(e) + elif e in tmpOpt: + tmpOpt.remove(e) + if len(failed) == len(tmpExprs): + keepMatching = False + + if tmpReqd: + missing = ", ".join( [ _ustr(e) for e in tmpReqd ] ) + raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing ) + + # add any unmatched Optionals, in case they have default values defined + matchOrder += [e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt] + + resultlist = [] + for e in matchOrder: + loc,results = e._parse(instring,loc,doActions) + resultlist.append(results) + + finalResults = ParseResults([]) + for r in resultlist: + dups = {} + for k in r.keys(): + if k in finalResults.keys(): + tmp = ParseResults(finalResults[k]) + tmp += ParseResults(r[k]) + dups[k] = tmp + finalResults += ParseResults(r) + for k,v in dups.items(): + finalResults[k] = v + return loc, finalResults + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " & ".join( [ _ustr(e) for e in self.exprs ] ) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class ParseElementEnhance(ParserElement): + """Abstract subclass of C{ParserElement}, for combining and post-processing parsed tokens.""" + def __init__( self, expr, savelist=False ): + super(ParseElementEnhance,self).__init__(savelist) + if isinstance( expr, basestring ): + expr = Literal(expr) + self.expr = expr + self.strRepr = None + if expr is not None: + self.mayIndexError = expr.mayIndexError + self.mayReturnEmpty = expr.mayReturnEmpty + self.setWhitespaceChars( expr.whiteChars ) + self.skipWhitespace = expr.skipWhitespace + self.saveAsList = expr.saveAsList + self.callPreparse = expr.callPreparse + self.ignoreExprs.extend(expr.ignoreExprs) + + def parseImpl( self, instring, loc, doActions=True ): + if self.expr is not None: + return self.expr._parse( instring, loc, doActions, callPreParse=False ) + else: + raise ParseException("",loc,self.errmsg,self) + + def leaveWhitespace( self ): + self.skipWhitespace = False + self.expr = self.expr.copy() + if self.expr is not None: + self.expr.leaveWhitespace() + return self + + def ignore( self, other ): + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + else: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + return self + + def streamline( self ): + super(ParseElementEnhance,self).streamline() + if self.expr is not None: + self.expr.streamline() + return self + + def checkRecursion( self, parseElementList ): + if self in parseElementList: + raise RecursiveGrammarException( parseElementList+[self] ) + subRecCheckList = parseElementList[:] + [ self ] + if self.expr is not None: + self.expr.checkRecursion( subRecCheckList ) + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion( [] ) + + def __str__( self ): + try: + return super(ParseElementEnhance,self).__str__() + except: + pass + + if self.strRepr is None and self.expr is not None: + self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) ) + return self.strRepr + + +class FollowedBy(ParseElementEnhance): + """Lookahead matching of the given parse expression. C{FollowedBy} + does *not* advance the parsing position within the input string, it only + verifies that the specified parse expression matches at the current + position. C{FollowedBy} always returns a null token list.""" + def __init__( self, expr ): + super(FollowedBy,self).__init__(expr) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + self.expr.tryParse( instring, loc ) + return loc, [] + + +class NotAny(ParseElementEnhance): + """Lookahead to disallow matching with the given parse expression. C{NotAny} + does *not* advance the parsing position within the input string, it only + verifies that the specified parse expression does *not* match at the current + position. Also, C{NotAny} does *not* skip over leading whitespace. C{NotAny} + always returns a null token list. May be constructed using the '~' operator.""" + def __init__( self, expr ): + super(NotAny,self).__init__(expr) + #~ self.leaveWhitespace() + self.skipWhitespace = False # do NOT use self.leaveWhitespace(), don't want to propagate to exprs + self.mayReturnEmpty = True + self.errmsg = "Found unwanted token, "+_ustr(self.expr) + #self.myException = ParseException("",0,self.errmsg,self) + + def parseImpl( self, instring, loc, doActions=True ): + try: + self.expr.tryParse( instring, loc ) + except (ParseException,IndexError): + pass + else: + #~ raise ParseException(instring, loc, self.errmsg ) + exc = self.myException + exc.loc = loc + exc.pstr = instring + raise exc + return loc, [] + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "~{" + _ustr(self.expr) + "}" + + return self.strRepr + + +class ZeroOrMore(ParseElementEnhance): + """Optional repetition of zero or more of the given expression.""" + def __init__( self, expr ): + super(ZeroOrMore,self).__init__(expr) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + tokens = [] + try: + loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) + hasIgnoreExprs = ( len(self.ignoreExprs) > 0 ) + while 1: + if hasIgnoreExprs: + preloc = self._skipIgnorables( instring, loc ) + else: + preloc = loc + loc, tmptokens = self.expr._parse( instring, preloc, doActions ) + if tmptokens or tmptokens.keys(): + tokens += tmptokens + except (ParseException,IndexError): + pass + + return loc, tokens + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]..." + + return self.strRepr + + def setResultsName( self, name, listAllMatches=False ): + ret = super(ZeroOrMore,self).setResultsName(name,listAllMatches) + ret.saveAsList = True + return ret + + +class OneOrMore(ParseElementEnhance): + """Repetition of one or more of the given expression.""" + def parseImpl( self, instring, loc, doActions=True ): + # must be at least one + loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) + try: + hasIgnoreExprs = ( len(self.ignoreExprs) > 0 ) + while 1: + if hasIgnoreExprs: + preloc = self._skipIgnorables( instring, loc ) + else: + preloc = loc + loc, tmptokens = self.expr._parse( instring, preloc, doActions ) + if tmptokens or tmptokens.keys(): + tokens += tmptokens + except (ParseException,IndexError): + pass + + return loc, tokens + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + _ustr(self.expr) + "}..." + + return self.strRepr + + def setResultsName( self, name, listAllMatches=False ): + ret = super(OneOrMore,self).setResultsName(name,listAllMatches) + ret.saveAsList = True + return ret + +class _NullToken(object): + def __bool__(self): + return False + __nonzero__ = __bool__ + def __str__(self): + return "" + +_optionalNotMatched = _NullToken() +class Optional(ParseElementEnhance): + """Optional matching of the given expression. + A default return string can also be specified, if the optional expression + is not found. + """ + def __init__( self, exprs, default=_optionalNotMatched ): + super(Optional,self).__init__( exprs, savelist=False ) + self.defaultValue = default + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + try: + loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) + except (ParseException,IndexError): + if self.defaultValue is not _optionalNotMatched: + if self.expr.resultsName: + tokens = ParseResults([ self.defaultValue ]) + tokens[self.expr.resultsName] = self.defaultValue + else: + tokens = [ self.defaultValue ] + else: + tokens = [] + return loc, tokens + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]" + + return self.strRepr + + +class SkipTo(ParseElementEnhance): + """Token for skipping over all undefined text until the matched expression is found. + If C{include} is set to true, the matched expression is also parsed (the skipped text + and matched expression are returned as a 2-element list). The C{ignore} + argument is used to define grammars (typically quoted strings and comments) that + might contain false matches. + """ + def __init__( self, other, include=False, ignore=None, failOn=None ): + super( SkipTo, self ).__init__( other ) + self.ignoreExpr = ignore + self.mayReturnEmpty = True + self.mayIndexError = False + self.includeMatch = include + self.asList = False + if failOn is not None and isinstance(failOn, basestring): + self.failOn = Literal(failOn) + else: + self.failOn = failOn + self.errmsg = "No match found for "+_ustr(self.expr) + #self.myException = ParseException("",0,self.errmsg,self) + + def parseImpl( self, instring, loc, doActions=True ): + startLoc = loc + instrlen = len(instring) + expr = self.expr + failParse = False + while loc <= instrlen: + try: + if self.failOn: + try: + self.failOn.tryParse(instring, loc) + except ParseBaseException: + pass + else: + failParse = True + raise ParseException(instring, loc, "Found expression " + str(self.failOn)) + failParse = False + if self.ignoreExpr is not None: + while 1: + try: + loc = self.ignoreExpr.tryParse(instring,loc) + # print "found ignoreExpr, advance to", loc + except ParseBaseException: + break + expr._parse( instring, loc, doActions=False, callPreParse=False ) + skipText = instring[startLoc:loc] + if self.includeMatch: + loc,mat = expr._parse(instring,loc,doActions,callPreParse=False) + if mat: + skipRes = ParseResults( skipText ) + skipRes += mat + return loc, [ skipRes ] + else: + return loc, [ skipText ] + else: + return loc, [ skipText ] + except (ParseException,IndexError): + if failParse: + raise + else: + loc += 1 + exc = self.myException + exc.loc = loc + exc.pstr = instring + raise exc + +class Forward(ParseElementEnhance): + """Forward declaration of an expression to be defined later - + used for recursive grammars, such as algebraic infix notation. + When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator. + + Note: take care when assigning to C{Forward} not to overlook precedence of operators. + Specifically, '|' has a lower precedence than '<<', so that:: + fwdExpr << a | b | c + will actually be evaluated as:: + (fwdExpr << a) | b | c + thereby leaving b and c out as parseable alternatives. It is recommended that you + explicitly group the values inserted into the C{Forward}:: + fwdExpr << (a | b | c) + """ + def __init__( self, other=None ): + super(Forward,self).__init__( other, savelist=False ) + + def __lshift__( self, other ): + if isinstance( other, basestring ): + other = Literal(other) + self.expr = other + self.mayReturnEmpty = other.mayReturnEmpty + self.strRepr = None + self.mayIndexError = self.expr.mayIndexError + self.mayReturnEmpty = self.expr.mayReturnEmpty + self.setWhitespaceChars( self.expr.whiteChars ) + self.skipWhitespace = self.expr.skipWhitespace + self.saveAsList = self.expr.saveAsList + self.ignoreExprs.extend(self.expr.ignoreExprs) + return None + + def leaveWhitespace( self ): + self.skipWhitespace = False + return self + + def streamline( self ): + if not self.streamlined: + self.streamlined = True + if self.expr is not None: + self.expr.streamline() + return self + + def validate( self, validateTrace=[] ): + if self not in validateTrace: + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion([]) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + self._revertClass = self.__class__ + self.__class__ = _ForwardNoRecurse + try: + if self.expr is not None: + retString = _ustr(self.expr) + else: + retString = "None" + finally: + self.__class__ = self._revertClass + return self.__class__.__name__ + ": " + retString + + def copy(self): + if self.expr is not None: + return super(Forward,self).copy() + else: + ret = Forward() + ret << self + return ret + +class _ForwardNoRecurse(Forward): + def __str__( self ): + return "..." + +class TokenConverter(ParseElementEnhance): + """Abstract subclass of ParseExpression, for converting parsed results.""" + def __init__( self, expr, savelist=False ): + super(TokenConverter,self).__init__( expr )#, savelist ) + self.saveAsList = False + +class Upcase(TokenConverter): + """Converter to upper case all matching tokens.""" + def __init__(self, *args): + super(Upcase,self).__init__(*args) + warnings.warn("Upcase class is deprecated, use upcaseTokens parse action instead", + DeprecationWarning,stacklevel=2) + + def postParse( self, instring, loc, tokenlist ): + return list(map( string.upper, tokenlist )) + + +class Combine(TokenConverter): + """Converter to concatenate all matching tokens to a single string. + By default, the matching patterns must also be contiguous in the input string; + this can be disabled by specifying C{'adjacent=False'} in the constructor. + """ + def __init__( self, expr, joinString="", adjacent=True ): + super(Combine,self).__init__( expr ) + # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself + if adjacent: + self.leaveWhitespace() + self.adjacent = adjacent + self.skipWhitespace = True + self.joinString = joinString + self.callPreparse = True + + def ignore( self, other ): + if self.adjacent: + ParserElement.ignore(self, other) + else: + super( Combine, self).ignore( other ) + return self + + def postParse( self, instring, loc, tokenlist ): + retToks = tokenlist.copy() + del retToks[:] + retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults) + + if self.resultsName and len(retToks.keys())>0: + return [ retToks ] + else: + return retToks + +class Group(TokenConverter): + """Converter to return the matched tokens as a list - useful for returning tokens of ZeroOrMore and OneOrMore expressions.""" + def __init__( self, expr ): + super(Group,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + return [ tokenlist ] + +class Dict(TokenConverter): + """Converter to return a repetitive expression as a list, but also as a dictionary. + Each element can also be referenced using the first token in the expression as its key. + Useful for tabular report scraping when the first column can be used as a item key. + """ + def __init__( self, exprs ): + super(Dict,self).__init__( exprs ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + for i,tok in enumerate(tokenlist): + if len(tok) == 0: + continue + ikey = tok[0] + if isinstance(ikey,int): + ikey = _ustr(tok[0]).strip() + if len(tok)==1: + tokenlist[ikey] = _ParseResultsWithOffset("",i) + elif len(tok)==2 and not isinstance(tok[1],ParseResults): + tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i) + else: + dictvalue = tok.copy() #ParseResults(i) + del dictvalue[0] + if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.keys()): + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i) + else: + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i) + + if self.resultsName: + return [ tokenlist ] + else: + return tokenlist + + +class Suppress(TokenConverter): + """Converter for ignoring the results of a parsed expression.""" + def postParse( self, instring, loc, tokenlist ): + return [] + + def suppress( self ): + return self + + +class OnlyOnce(object): + """Wrapper for parse actions, to ensure they are only called once.""" + def __init__(self, methodCall): + self.callable = ParserElement._normalizeParseActionArgs(methodCall) + self.called = False + def __call__(self,s,l,t): + if not self.called: + results = self.callable(s,l,t) + self.called = True + return results + raise ParseException(s,l,"") + def reset(self): + self.called = False + +def traceParseAction(f): + """Decorator for debugging parse actions.""" + f = ParserElement._normalizeParseActionArgs(f) + def z(*paArgs): + thisFunc = f.func_name + s,l,t = paArgs[-3:] + if len(paArgs)>3: + thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc + sys.stderr.write( ">>entering %s(line: '%s', %d, %s)\n" % (thisFunc,line(l,s),l,t) ) + try: + ret = f(*paArgs) + except Exception: + exc = sys.exc_info()[1] + sys.stderr.write( "<", "|".join( [ _escapeRegexChars(sym) for sym in symbols] )) + try: + if len(symbols)==len("".join(symbols)): + return Regex( "[%s]" % "".join( [ _escapeRegexRangeChars(sym) for sym in symbols] ) ) + else: + return Regex( "|".join( [ re.escape(sym) for sym in symbols] ) ) + except: + warnings.warn("Exception creating Regex for oneOf, building MatchFirst", + SyntaxWarning, stacklevel=2) + + + # last resort, just use MatchFirst + return MatchFirst( [ parseElementClass(sym) for sym in symbols ] ) + +def dictOf( key, value ): + """Helper to easily and clearly define a dictionary by specifying the respective patterns + for the key and value. Takes care of defining the C{Dict}, C{ZeroOrMore}, and C{Group} tokens + in the proper order. The key pattern can include delimiting markers or punctuation, + as long as they are suppressed, thereby leaving the significant key text. The value + pattern can include named results, so that the C{Dict} results can include named token + fields. + """ + return Dict( ZeroOrMore( Group ( key + value ) ) ) + +def originalTextFor(expr, asString=True): + """Helper to return the original, untokenized text for a given expression. Useful to + restore the parsed fields of an HTML start tag into the raw tag text itself, or to + revert separate tokens with intervening whitespace back to the original matching + input text. Simpler to use than the parse action C{keepOriginalText}, and does not + require the inspect module to chase up the call stack. By default, returns a + string containing the original parsed text. + + If the optional C{asString} argument is passed as False, then the return value is a + C{ParseResults} containing any results names that were originally matched, and a + single token containing the original matched text from the input string. So if + the expression passed to C{originalTextFor} contains expressions with defined + results names, you must set C{asString} to False if you want to preserve those + results name values.""" + locMarker = Empty().setParseAction(lambda s,loc,t: loc) + endlocMarker = locMarker.copy() + endlocMarker.callPreparse = False + matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end") + if asString: + extractText = lambda s,l,t: s[t._original_start:t._original_end] + else: + def extractText(s,l,t): + del t[:] + t.insert(0, s[t._original_start:t._original_end]) + del t["_original_start"] + del t["_original_end"] + matchExpr.setParseAction(extractText) + return matchExpr + +# convenience constants for positional expressions +empty = Empty().setName("empty") +lineStart = LineStart().setName("lineStart") +lineEnd = LineEnd().setName("lineEnd") +stringStart = StringStart().setName("stringStart") +stringEnd = StringEnd().setName("stringEnd") + +_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1]) +_printables_less_backslash = "".join([ c for c in printables if c not in r"\]" ]) +_escapedHexChar = Combine( Suppress(_bslash + "0x") + Word(hexnums) ).setParseAction(lambda s,l,t:unichr(int(t[0],16))) +_escapedOctChar = Combine( Suppress(_bslash) + Word("0","01234567") ).setParseAction(lambda s,l,t:unichr(int(t[0],8))) +_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | Word(_printables_less_backslash,exact=1) +_charRange = Group(_singleChar + Suppress("-") + _singleChar) +_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]" + +_expanded = lambda p: (isinstance(p,ParseResults) and ''.join([ unichr(c) for c in range(ord(p[0]),ord(p[1])+1) ]) or p) + +def srange(s): + r"""Helper to easily define string ranges for use in Word construction. Borrows + syntax from regexp '[]' string range definitions:: + srange("[0-9]") -> "0123456789" + srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz" + srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_" + The input string must be enclosed in []'s, and the returned string is the expanded + character set joined into a single string. + The values enclosed in the []'s may be:: + a single character + an escaped character with a leading backslash (such as \- or \]) + an escaped hex character with a leading '\0x' (\0x21, which is a '!' character) + an escaped octal character with a leading '\0' (\041, which is a '!' character) + a range of any of the above, separated by a dash ('a-z', etc.) + any combination of the above ('aeiouy', 'a-zA-Z0-9_$', etc.) + """ + try: + return "".join([_expanded(part) for part in _reBracketExpr.parseString(s).body]) + except: + return "" + +def matchOnlyAtCol(n): + """Helper method for defining parse actions that require matching at a specific + column in the input text. + """ + def verifyCol(strg,locn,toks): + if col(locn,strg) != n: + raise ParseException(strg,locn,"matched token not at column %d" % n) + return verifyCol + +def replaceWith(replStr): + """Helper method for common parse actions that simply return a literal value. Especially + useful when used with C{transformString()}. + """ + def _replFunc(*args): + return [replStr] + return _replFunc + +def removeQuotes(s,l,t): + """Helper parse action for removing quotation marks from parsed quoted strings. + To use, add this parse action to quoted string using:: + quotedString.setParseAction( removeQuotes ) + """ + return t[0][1:-1] + +def upcaseTokens(s,l,t): + """Helper parse action to convert tokens to upper case.""" + return [ tt.upper() for tt in map(_ustr,t) ] + +def downcaseTokens(s,l,t): + """Helper parse action to convert tokens to lower case.""" + return [ tt.lower() for tt in map(_ustr,t) ] + +def keepOriginalText(s,startLoc,t): + """DEPRECATED - use new helper method C{originalTextFor}. + Helper parse action to preserve original parsed text, + overriding any nested parse actions.""" + try: + endloc = getTokensEndLoc() + except ParseException: + raise ParseFatalException("incorrect usage of keepOriginalText - may only be called as a parse action") + del t[:] + t += ParseResults(s[startLoc:endloc]) + return t + +def getTokensEndLoc(): + """Method to be called from within a parse action to determine the end + location of the parsed tokens.""" + import inspect + fstack = inspect.stack() + try: + # search up the stack (through intervening argument normalizers) for correct calling routine + for f in fstack[2:]: + if f[3] == "_parseNoCache": + endloc = f[0].f_locals["loc"] + return endloc + else: + raise ParseFatalException("incorrect usage of getTokensEndLoc - may only be called from within a parse action") + finally: + del fstack + +def _makeTags(tagStr, xml): + """Internal helper to construct opening and closing tag expressions, given a tag name""" + if isinstance(tagStr,basestring): + resname = tagStr + tagStr = Keyword(tagStr, caseless=not xml) + else: + resname = tagStr.name + + tagAttrName = Word(alphas,alphanums+"_-:") + if (xml): + tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes ) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + else: + printablesLessRAbrack = "".join( [ c for c in printables if c not in ">" ] ) + tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack) + openTag = Suppress("<") + tagStr + \ + Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \ + Optional( Suppress("=") + tagAttrValue ) ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + closeTag = Combine(_L("") + + openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % tagStr) + closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("" % tagStr) + openTag.tag = resname + closeTag.tag = resname + return openTag, closeTag + +def makeHTMLTags(tagStr): + """Helper to construct opening and closing tag expressions for HTML, given a tag name""" + return _makeTags( tagStr, False ) + +def makeXMLTags(tagStr): + """Helper to construct opening and closing tag expressions for XML, given a tag name""" + return _makeTags( tagStr, True ) + +def withAttribute(*args,**attrDict): + """Helper to create a validating parse action to be used with start tags created + with makeXMLTags or makeHTMLTags. Use withAttribute to qualify a starting tag + with a required attribute value, to avoid false matches on common tags such as + or
    . + + Call withAttribute with a series of attribute names and values. Specify the list + of filter attributes names and values as: + - keyword arguments, as in (class="Customer",align="right"), or + - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") ) + For attribute names with a namespace prefix, you must use the second form. Attribute + names are matched insensitive to upper/lower case. + + To verify that the attribute exists, but without specifying a value, pass + withAttribute.ANY_VALUE as the value. + """ + if args: + attrs = args[:] + else: + attrs = attrDict.items() + attrs = [(k,v) for k,v in attrs] + def pa(s,l,tokens): + for attrName,attrValue in attrs: + if attrName not in tokens: + raise ParseException(s,l,"no matching attribute " + attrName) + if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue: + raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" % + (attrName, tokens[attrName], attrValue)) + return pa +withAttribute.ANY_VALUE = object() + +opAssoc = _Constants() +opAssoc.LEFT = object() +opAssoc.RIGHT = object() + +def operatorPrecedence( baseExpr, opList ): + """Helper method for constructing grammars of expressions made up of + operators working in a precedence hierarchy. Operators may be unary or + binary, left- or right-associative. Parse actions can also be attached + to operator expressions. + + Parameters: + - baseExpr - expression representing the most basic element for the nested + - opList - list of tuples, one for each operator precedence level in the + expression grammar; each tuple is of the form + (opExpr, numTerms, rightLeftAssoc, parseAction), where: + - opExpr is the pyparsing expression for the operator; + may also be a string, which will be converted to a Literal; + if numTerms is 3, opExpr is a tuple of two expressions, for the + two operators separating the 3 terms + - numTerms is the number of terms for this operator (must + be 1, 2, or 3) + - rightLeftAssoc is the indicator whether the operator is + right or left associative, using the pyparsing-defined + constants opAssoc.RIGHT and opAssoc.LEFT. + - parseAction is the parse action to be associated with + expressions matching this operator expression (the + parse action tuple member may be omitted) + """ + ret = Forward() + lastExpr = baseExpr | ( Suppress('(') + ret + Suppress(')') ) + for i,operDef in enumerate(opList): + opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4] + if arity == 3: + if opExpr is None or len(opExpr) != 2: + raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions") + opExpr1, opExpr2 = opExpr + thisExpr = Forward()#.setName("expr%d" % i) + if rightLeftAssoc == opAssoc.LEFT: + if arity == 1: + matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) ) + else: + matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) ) + elif arity == 3: + matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \ + Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + elif rightLeftAssoc == opAssoc.RIGHT: + if arity == 1: + # try to avoid LR with this extra test + if not isinstance(opExpr, Optional): + opExpr = Optional(opExpr) + matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) ) + else: + matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) ) + elif arity == 3: + matchExpr = FollowedBy(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \ + Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + else: + raise ValueError("operator must indicate right or left associativity") + if pa: + matchExpr.setParseAction( pa ) + thisExpr << ( matchExpr | lastExpr ) + lastExpr = thisExpr + ret << lastExpr + return ret + +dblQuotedString = Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\x[0-9a-fA-F]+)|(?:\\.))*"').setName("string enclosed in double quotes") +sglQuotedString = Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\x[0-9a-fA-F]+)|(?:\\.))*'").setName("string enclosed in single quotes") +quotedString = Regex(r'''(?:"(?:[^"\n\r\\]|(?:"")|(?:\\x[0-9a-fA-F]+)|(?:\\.))*")|(?:'(?:[^'\n\r\\]|(?:'')|(?:\\x[0-9a-fA-F]+)|(?:\\.))*')''').setName("quotedString using single or double quotes") +unicodeString = Combine(_L('u') + quotedString.copy()) + +def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()): + """Helper method for defining nested lists enclosed in opening and closing + delimiters ("(" and ")" are the default). + + Parameters: + - opener - opening character for a nested list (default="("); can also be a pyparsing expression + - closer - closing character for a nested list (default=")"); can also be a pyparsing expression + - content - expression for items within the nested lists (default=None) + - ignoreExpr - expression for ignoring opening and closing delimiters (default=quotedString) + + If an expression is not provided for the content argument, the nested + expression will capture all whitespace-delimited content between delimiters + as a list of separate values. + + Use the ignoreExpr argument to define expressions that may contain + opening or closing characters that should not be treated as opening + or closing characters for nesting, such as quotedString or a comment + expression. Specify multiple expressions using an Or or MatchFirst. + The default is quotedString, but if no expressions are to be ignored, + then pass None for this argument. + """ + if opener == closer: + raise ValueError("opening and closing strings cannot be the same") + if content is None: + if isinstance(opener,basestring) and isinstance(closer,basestring): + if len(opener) == 1 and len(closer)==1: + if ignoreExpr is not None: + content = (Combine(OneOrMore(~ignoreExpr + + CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS + ).setParseAction(lambda t:t[0].strip())) + else: + if ignoreExpr is not None: + content = (Combine(OneOrMore(~ignoreExpr + + ~Literal(opener) + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + raise ValueError("opening and closing arguments must be strings if no content expression is given") + ret = Forward() + if ignoreExpr is not None: + ret << Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) ) + else: + ret << Group( Suppress(opener) + ZeroOrMore( ret | content ) + Suppress(closer) ) + return ret + +def indentedBlock(blockStatementExpr, indentStack, indent=True): + """Helper method for defining space-delimited indentation blocks, such as + those used to define block statements in Python source code. + + Parameters: + - blockStatementExpr - expression defining syntax of statement that + is repeated within the indented block + - indentStack - list created by caller to manage indentation stack + (multiple statementWithIndentedBlock expressions within a single grammar + should share a common indentStack) + - indent - boolean indicating whether block must be indented beyond the + the current level; set to False for block of left-most statements + (default=True) + + A valid block must contain at least one blockStatement. + """ + def checkPeerIndent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if curCol != indentStack[-1]: + if curCol > indentStack[-1]: + raise ParseFatalException(s,l,"illegal nesting") + raise ParseException(s,l,"not a peer entry") + + def checkSubIndent(s,l,t): + curCol = col(l,s) + if curCol > indentStack[-1]: + indentStack.append( curCol ) + else: + raise ParseException(s,l,"not a subentry") + + def checkUnindent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]): + raise ParseException(s,l,"not an unindent") + indentStack.pop() + + NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress()) + INDENT = Empty() + Empty().setParseAction(checkSubIndent) + PEER = Empty().setParseAction(checkPeerIndent) + UNDENT = Empty().setParseAction(checkUnindent) + if indent: + smExpr = Group( Optional(NL) + + #~ FollowedBy(blockStatementExpr) + + INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT) + else: + smExpr = Group( Optional(NL) + + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) ) + blockStatementExpr.ignore(_bslash + LineEnd()) + return smExpr + +alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]") +punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]") + +anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:")) +commonHTMLEntity = Combine(_L("&") + oneOf("gt lt amp nbsp quot").setResultsName("entity") +";").streamline() +_htmlEntityMap = dict(zip("gt lt amp nbsp quot".split(),'><& "')) +replaceHTMLEntity = lambda t : t.entity in _htmlEntityMap and _htmlEntityMap[t.entity] or None + +# it's easy to get these comment structures wrong - they're very common, so may as well make them available +cStyleComment = Regex(r"/\*(?:[^*]*\*+)+?/").setName("C style comment") + +htmlComment = Regex(r"") +restOfLine = Regex(r".*").leaveWhitespace() +dblSlashComment = Regex(r"\/\/(\\\n|.)*").setName("// comment") +cppStyleComment = Regex(r"/(?:\*(?:[^*]*\*+)+?/|/[^\n]*(?:\n[^\n]*)*?(?:(?" + str(tokenlist)) + print ("tokens = " + str(tokens)) + print ("tokens.columns = " + str(tokens.columns)) + print ("tokens.tables = " + str(tokens.tables)) + print (tokens.asXML("SQL",True)) + except ParseBaseException: + err = sys.exc_info()[1] + print (teststring + "->") + print (err.line) + print (" "*(err.column-1) + "^") + print (err) + print() + + selectToken = CaselessLiteral( "select" ) + fromToken = CaselessLiteral( "from" ) + + ident = Word( alphas, alphanums + "_$" ) + columnName = delimitedList( ident, ".", combine=True ).setParseAction( upcaseTokens ) + columnNameList = Group( delimitedList( columnName ) )#.setName("columns") + tableName = delimitedList( ident, ".", combine=True ).setParseAction( upcaseTokens ) + tableNameList = Group( delimitedList( tableName ) )#.setName("tables") + simpleSQL = ( selectToken + \ + ( '*' | columnNameList ).setResultsName( "columns" ) + \ + fromToken + \ + tableNameList.setResultsName( "tables" ) ) + + test( "SELECT * from XYZZY, ABC" ) + test( "select * from SYS.XYZZY" ) + test( "Select A from Sys.dual" ) + test( "Select AA,BB,CC from Sys.dual" ) + test( "Select A, B, C from Sys.dual" ) + test( "Select A, B, C from Sys.dual" ) + test( "Xelect A, B, C from Sys.dual" ) + test( "Select A, B, C frox Sys.dual" ) + test( "Select" ) + test( "Select ^^^ frox Sys.dual" ) + test( "Select A, B, C from Sys.dual, Table2 " ) diff -Nru matplotlib-1.1.1/lib/matplotlib/pyparsing_py3.py matplotlib-1.2.0/lib/matplotlib/pyparsing_py3.py --- matplotlib-1.1.1/lib/matplotlib/pyparsing_py3.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/pyparsing_py3.py 2012-11-06 22:31:09.000000000 +0000 @@ -0,0 +1,3682 @@ +# module pyparsing.py +# +# Copyright (c) 2003-2010 Paul T. McGuire +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +#from __future__ import generators + +__doc__ = \ +""" +pyparsing module - Classes and methods to define and execute parsing grammars + +The pyparsing module is an alternative approach to creating and executing simple grammars, +vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you +don't need to learn a new syntax for defining grammars or matching expressions - the parsing module +provides a library of classes that you use to construct the grammar directly in Python. + +Here is a program to parse "Hello, World!" (or any greeting of the form C{", !"}):: + + from pyparsing import Word, alphas + + # define grammar of a greeting + greet = Word( alphas ) + "," + Word( alphas ) + "!" + + hello = "Hello, World!" + print hello, "->", greet.parseString( hello ) + +The program outputs the following:: + + Hello, World! -> ['Hello', ',', 'World', '!'] + +The Python representation of the grammar is quite readable, owing to the self-explanatory +class names, and the use of '+', '|' and '^' operators. + +The parsed results returned from C{parseString()} can be accessed as a nested list, a dictionary, or an +object with named attributes. + +The pyparsing module handles some of the problems that are typically vexing when writing text parsers: + - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello , World !", etc.) + - quoted strings + - embedded comments +""" + +__version__ = "1.5.5" +__versionTime__ = "12 Aug 2010 03:56" +__author__ = "Paul McGuire " + +import string +from weakref import ref as wkref +import copy +import sys +import warnings +import re +import sre_constants +import collections +#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) ) + +__all__ = [ +'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty', +'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal', +'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or', +'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException', +'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException', +'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', 'Upcase', +'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore', +'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col', +'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString', +'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'getTokensEndLoc', 'hexnums', +'htmlComment', 'javaStyleComment', 'keepOriginalText', 'line', 'lineEnd', 'lineStart', 'lineno', +'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral', +'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables', +'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', +'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd', +'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute', +'indentedBlock', 'originalTextFor', +] + +""" +Detect if we are running version 3.X and make appropriate changes +Robert A. Clark +""" +_PY3K = sys.version_info[0] > 2 +if _PY3K: + _MAX_INT = sys.maxsize + basestring = str + unichr = chr + _ustr = str + alphas = string.ascii_lowercase + string.ascii_uppercase +else: + _MAX_INT = sys.maxint + range = xrange + set = lambda s : dict( [(c,0) for c in s] ) + alphas = string.lowercase + string.uppercase + + def _ustr(obj): + """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries + str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It + then < returns the unicode object | encodes it with the default encoding | ... >. + """ + if isinstance(obj,unicode): + return obj + + try: + # If this works, then _ustr(obj) has the same behaviour as str(obj), so + # it won't break any existing code. + return str(obj) + + except UnicodeEncodeError: + # The Python docs (http://docs.python.org/ref/customization.html#l2h-182) + # state that "The return value must be a string object". However, does a + # unicode object (being a subclass of basestring) count as a "string + # object"? + # If so, then return a unicode object: + return unicode(obj) + # Else encode it... but how? There are many choices... :) + # Replace unprintables with escape codes? + #return unicode(obj).encode(sys.getdefaultencoding(), 'backslashreplace_errors') + # Replace unprintables with question marks? + #return unicode(obj).encode(sys.getdefaultencoding(), 'replace') + # ... + + +# build list of single arg builtins, tolerant of Python version, that can be used as parse actions +singleArgBuiltins = [] +import builtins +for fname in "sum len enumerate sorted reversed list tuple set any all".split(): + try: + singleArgBuiltins.append(getattr(builtins,fname)) + except AttributeError: + continue + +def _xml_escape(data): + """Escape &, <, >, ", ', etc. in a string of data.""" + + # ampersand must be replaced first + for from_,to_ in zip('&><"\'', "amp gt lt quot apos".split()): + data = data.replace(from_, '&'+to_+';') + return data + +class _Constants(object): + pass + +nums = string.digits +hexnums = nums + "ABCDEFabcdef" +alphanums = alphas + nums +_bslash = chr(92) +printables = "".join( [ c for c in string.printable if c not in string.whitespace ] ) + +class ParseBaseException(Exception): + """base exception class for all parsing runtime exceptions""" + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( self, pstr, loc=0, msg=None, elem=None ): + self.loc = loc + if msg is None: + self.msg = pstr + self.pstr = "" + else: + self.msg = msg + self.pstr = pstr + self.parserElement = elem + + def __getattr__( self, aname ): + """supported attributes by name are: + - lineno - returns the line number of the exception text + - col - returns the column number of the exception text + - line - returns the line containing the exception text + """ + if( aname == "lineno" ): + return lineno( self.loc, self.pstr ) + elif( aname in ("col", "column") ): + return col( self.loc, self.pstr ) + elif( aname == "line" ): + return line( self.loc, self.pstr ) + else: + raise AttributeError(aname) + + def __str__( self ): + return "%s (at char %d), (line:%d, col:%d)" % \ + ( self.msg, self.loc, self.lineno, self.column ) + def __repr__( self ): + return _ustr(self) + def markInputline( self, markerString = ">!<" ): + """Extracts the exception line from the input string, and marks + the location of the exception with a special symbol. + """ + line_str = self.line + line_column = self.column - 1 + if markerString: + line_str = "".join( [line_str[:line_column], + markerString, line_str[line_column:]]) + return line_str.strip() + def __dir__(self): + return "loc msg pstr parserElement lineno col line " \ + "markInputLine __str__ __repr__".split() + +class ParseException(ParseBaseException): + """exception thrown when parse expressions don't match class; + supported attributes by name are: + - lineno - returns the line number of the exception text + - col - returns the column number of the exception text + - line - returns the line containing the exception text + """ + pass + +class ParseFatalException(ParseBaseException): + """user-throwable exception thrown when inconsistent parse content + is found; stops all parsing immediately""" + pass + +class ParseSyntaxException(ParseFatalException): + """just like C{ParseFatalException}, but thrown internally when an + C{ErrorStop} ('-' operator) indicates that parsing is to stop immediately because + an unbacktrackable syntax error has been found""" + def __init__(self, pe): + super(ParseSyntaxException, self).__init__( + pe.pstr, pe.loc, pe.msg, pe.parserElement) + +#~ class ReparseException(ParseBaseException): + #~ """Experimental class - parse actions can raise this exception to cause + #~ pyparsing to reparse the input string: + #~ - with a modified input string, and/or + #~ - with a modified start location + #~ Set the values of the ReparseException in the constructor, and raise the + #~ exception in a parse action to cause pyparsing to use the new string/location. + #~ Setting the values as None causes no change to be made. + #~ """ + #~ def __init_( self, newstring, restartLoc ): + #~ self.newParseText = newstring + #~ self.reparseLoc = restartLoc + +class RecursiveGrammarException(Exception): + """exception thrown by C{validate()} if the grammar could be improperly recursive""" + def __init__( self, parseElementList ): + self.parseElementTrace = parseElementList + + def __str__( self ): + return "RecursiveGrammarException: %s" % self.parseElementTrace + +class _ParseResultsWithOffset(object): + def __init__(self,p1,p2): + self.tup = (p1,p2) + def __getitem__(self,i): + return self.tup[i] + def __repr__(self): + return repr(self.tup) + def setOffset(self,i): + self.tup = (self.tup[0],i) + +class ParseResults(object): + """Structured parse results, to provide multiple means of access to the parsed data: + - as a list (C{len(results)}) + - by list index (C{results[0], results[1]}, etc.) + - by attribute (C{results.}) + """ + #~ __slots__ = ( "__toklist", "__tokdict", "__doinit", "__name", "__parent", "__accumNames", "__weakref__" ) + def __new__(cls, toklist, name=None, asList=True, modal=True ): + if isinstance(toklist, cls): + return toklist + retobj = object.__new__(cls) + retobj.__doinit = True + return retobj + + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( self, toklist, name=None, asList=True, modal=True ): + if self.__doinit: + self.__doinit = False + self.__name = None + self.__parent = None + self.__accumNames = {} + if isinstance(toklist, list): + self.__toklist = toklist[:] + else: + self.__toklist = [toklist] + self.__tokdict = dict() + + if name is not None and name: + if not modal: + self.__accumNames[name] = 0 + if isinstance(name,int): + name = _ustr(name) # will always return a str, but use _ustr for consistency + self.__name = name + if not toklist in (None,'',[]): + if isinstance(toklist,basestring): + toklist = [ toklist ] + if asList: + if isinstance(toklist,ParseResults): + self[name] = _ParseResultsWithOffset(toklist.copy(),0) + else: + self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0) + self[name].__name = name + else: + try: + self[name] = toklist[0] + except (KeyError,TypeError,IndexError): + self[name] = toklist + + def __getitem__( self, i ): + if isinstance( i, (int,slice) ): + return self.__toklist[i] + else: + if i not in self.__accumNames: + return self.__tokdict[i][-1][0] + else: + return ParseResults([ v[0] for v in self.__tokdict[i] ]) + + def __setitem__( self, k, v ): + if isinstance(v,_ParseResultsWithOffset): + self.__tokdict[k] = self.__tokdict.get(k,list()) + [v] + sub = v[0] + elif isinstance(k,int): + self.__toklist[k] = v + sub = v + else: + self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)] + sub = v + if isinstance(sub,ParseResults): + sub.__parent = wkref(self) + + def __delitem__( self, i ): + if isinstance(i,(int,slice)): + mylen = len( self.__toklist ) + del self.__toklist[i] + + # convert int to slice + if isinstance(i, int): + if i < 0: + i += mylen + i = slice(i, i+1) + # get removed indices + removed = list(range(*i.indices(mylen))) + removed.reverse() + # fixup indices in token dictionary + for name in self.__tokdict: + occurrences = self.__tokdict[name] + for j in removed: + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset(value, position - (position > j)) + else: + del self.__tokdict[i] + + def __contains__( self, k ): + return k in self.__tokdict + + def __len__( self ): return len( self.__toklist ) + def __bool__(self): return len( self.__toklist ) > 0 + __nonzero__ = __bool__ + def __iter__( self ): return iter( self.__toklist ) + def __reversed__( self ): return iter( reversed(self.__toklist) ) + def keys( self ): + """Returns all named result keys.""" + return self.__tokdict.keys() + + def pop( self, index=-1 ): + """Removes and returns item at specified index (default=last). + Will work with either numeric indices or dict-key indicies.""" + ret = self[index] + del self[index] + return ret + + def get(self, key, defaultValue=None): + """Returns named result matching the given key, or if there is no + such name, then returns the given C{defaultValue} or C{None} if no + C{defaultValue} is specified.""" + if key in self: + return self[key] + else: + return defaultValue + + def insert( self, index, insStr ): + """Inserts new element at location index in the list of parsed tokens.""" + self.__toklist.insert(index, insStr) + # fixup indices in token dictionary + for name in self.__tokdict: + occurrences = self.__tokdict[name] + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset(value, position + (position > index)) + + def items( self ): + """Returns all named result keys and values as a list of tuples.""" + return [(k,self[k]) for k in self.__tokdict] + + def values( self ): + """Returns all named result values.""" + return [ v[-1][0] for v in self.__tokdict.values() ] + + def __getattr__( self, name ): + if True: #name not in self.__slots__: + if name in self.__tokdict: + if name not in self.__accumNames: + return self.__tokdict[name][-1][0] + else: + return ParseResults([ v[0] for v in self.__tokdict[name] ]) + else: + return "" + return None + + def __add__( self, other ): + ret = self.copy() + ret += other + return ret + + def __iadd__( self, other ): + if other.__tokdict: + offset = len(self.__toklist) + addoffset = ( lambda a: (a<0 and offset) or (a+offset) ) + otheritems = other.__tokdict.items() + otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) ) + for (k,vlist) in otheritems for v in vlist] + for k,v in otherdictitems: + self[k] = v + if isinstance(v[0],ParseResults): + v[0].__parent = wkref(self) + + self.__toklist += other.__toklist + self.__accumNames.update( other.__accumNames ) + return self + + def __radd__(self, other): + if isinstance(other,int) and other == 0: + return self.copy() + + def __repr__( self ): + return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) ) + + def __str__( self ): + out = "[" + sep = "" + for i in self.__toklist: + if isinstance(i, ParseResults): + out += sep + _ustr(i) + else: + out += sep + repr(i) + sep = ", " + out += "]" + return out + + def _asStringList( self, sep='' ): + out = [] + for item in self.__toklist: + if out and sep: + out.append(sep) + if isinstance( item, ParseResults ): + out += item._asStringList() + else: + out.append( _ustr(item) ) + return out + + def asList( self ): + """Returns the parse results as a nested list of matching tokens, all converted to strings.""" + out = [] + for res in self.__toklist: + if isinstance(res,ParseResults): + out.append( res.asList() ) + else: + out.append( res ) + return out + + def asDict( self ): + """Returns the named parse results as dictionary.""" + return dict( self.items() ) + + def copy( self ): + """Returns a new copy of a C{ParseResults} object.""" + ret = ParseResults( self.__toklist ) + ret.__tokdict = self.__tokdict.copy() + ret.__parent = self.__parent + ret.__accumNames.update( self.__accumNames ) + ret.__name = self.__name + return ret + + def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ): + """Returns the parse results as XML. Tags are created for tokens and lists that have defined results names.""" + nl = "\n" + out = [] + namedItems = dict( [ (v[1],k) for (k,vlist) in self.__tokdict.items() + for v in vlist ] ) + nextLevelIndent = indent + " " + + # collapse out indents if formatting is not desired + if not formatted: + indent = "" + nextLevelIndent = "" + nl = "" + + selfTag = None + if doctag is not None: + selfTag = doctag + else: + if self.__name: + selfTag = self.__name + + if not selfTag: + if namedItemsOnly: + return "" + else: + selfTag = "ITEM" + + out += [ nl, indent, "<", selfTag, ">" ] + + worklist = self.__toklist + for i,res in enumerate(worklist): + if isinstance(res,ParseResults): + if i in namedItems: + out += [ res.asXML(namedItems[i], + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + out += [ res.asXML(None, + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + # individual token, see if there is a name for it + resTag = None + if i in namedItems: + resTag = namedItems[i] + if not resTag: + if namedItemsOnly: + continue + else: + resTag = "ITEM" + xmlBodyText = _xml_escape(_ustr(res)) + out += [ nl, nextLevelIndent, "<", resTag, ">", + xmlBodyText, + "" ] + + out += [ nl, indent, "" ] + return "".join(out) + + def __lookup(self,sub): + for k,vlist in self.__tokdict.items(): + for v,loc in vlist: + if sub is v: + return k + return None + + def getName(self): + """Returns the results name for this token expression.""" + if self.__name: + return self.__name + elif self.__parent: + par = self.__parent() + if par: + return par.__lookup(self) + else: + return None + elif (len(self) == 1 and + len(self.__tokdict) == 1 and + self.__tokdict.values()[0][0][1] in (0,-1)): + return self.__tokdict.keys()[0] + else: + return None + + def dump(self,indent='',depth=0): + """Diagnostic method for listing out the contents of a C{ParseResults}. + Accepts an optional C{indent} argument so that this string can be embedded + in a nested display of other data.""" + out = [] + out.append( indent+_ustr(self.asList()) ) + keys = self.items() + keys.sort() + for k,v in keys: + if out: + out.append('\n') + out.append( "%s%s- %s: " % (indent,(' '*depth), k) ) + if isinstance(v,ParseResults): + if v.keys(): + out.append( v.dump(indent,depth+1) ) + else: + out.append(_ustr(v)) + else: + out.append(_ustr(v)) + return "".join(out) + + # add support for pickle protocol + def __getstate__(self): + return ( self.__toklist, + ( self.__tokdict.copy(), + self.__parent is not None and self.__parent() or None, + self.__accumNames, + self.__name ) ) + + def __setstate__(self,state): + self.__toklist = state[0] + self.__tokdict, \ + par, \ + inAccumNames, \ + self.__name = state[1] + self.__accumNames = {} + self.__accumNames.update(inAccumNames) + if par is not None: + self.__parent = wkref(par) + else: + self.__parent = None + + def __dir__(self): + return dir(super(ParseResults,self)) + self.keys() + +collections.MutableMapping.register(ParseResults) + +def col (loc,strg): + """Returns current column within a string, counting newlines as line separators. + The first column is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{ParserElement.parseString}} for more information + on parsing strings containing s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + """ + return (loc} for more information + on parsing strings containing s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + """ + return strg.count("\n",0,loc) + 1 + +def line( loc, strg ): + """Returns the line of text containing loc within a string, counting newlines as line separators. + """ + lastCR = strg.rfind("\n", 0, loc) + nextCR = strg.find("\n", loc) + if nextCR >= 0: + return strg[lastCR+1:nextCR] + else: + return strg[lastCR+1:] + +def _defaultStartDebugAction( instring, loc, expr ): + print ("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )) + +def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ): + print ("Matched " + _ustr(expr) + " -> " + str(toks.asList())) + +def _defaultExceptionDebugAction( instring, loc, expr, exc ): + print ("Exception raised:" + _ustr(exc)) + +def nullDebugAction(*args): + """'Do-nothing' debug action, to suppress debugging output during parsing.""" + pass + +class ParserElement(object): + """Abstract base level parser element class.""" + DEFAULT_WHITE_CHARS = " \n\t\r" + verbose_stacktrace = False + + def setDefaultWhitespaceChars( chars ): + """Overrides the default whitespace chars + """ + ParserElement.DEFAULT_WHITE_CHARS = chars + setDefaultWhitespaceChars = staticmethod(setDefaultWhitespaceChars) + + def __init__( self, savelist=False ): + self.parseAction = list() + self.failAction = None + #~ self.name = "" # don't define self.name, let subclasses try/except upcall + self.strRepr = None + self.resultsName = None + self.saveAsList = savelist + self.skipWhitespace = True + self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + self.copyDefaultWhiteChars = True + self.mayReturnEmpty = False # used when checking for left-recursion + self.keepTabs = False + self.ignoreExprs = list() + self.debug = False + self.streamlined = False + self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index + self.errmsg = "" + self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all) + self.debugActions = ( None, None, None ) #custom debug actions + self.re = None + self.callPreparse = True # used to avoid redundant calls to preParse + self.callDuringTry = False + + def copy( self ): + """Make a copy of this C{ParserElement}. Useful for defining different parse actions + for the same parsing pattern, using copies of the original parse element.""" + cpy = copy.copy( self ) + cpy.parseAction = self.parseAction[:] + cpy.ignoreExprs = self.ignoreExprs[:] + if self.copyDefaultWhiteChars: + cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + return cpy + + def setName( self, name ): + """Define name for this expression, for use in debugging.""" + self.name = name + self.errmsg = "Expected " + self.name + if hasattr(self,"exception"): + self.exception.msg = self.errmsg + return self + + def setResultsName( self, name, listAllMatches=False ): + """Define name for referencing matching tokens as a nested attribute + of the returned parse results. + NOTE: this returns a *copy* of the original C{ParserElement} object; + this is so that the client can define a basic element, such as an + integer, and reference it in multiple places with different names. + + You can also set results names using the abbreviated syntax, + C{expr("name")} in place of C{expr.setResultsName("name")} - + see L{I{__call__}<__call__>}. + """ + newself = self.copy() + newself.resultsName = name + newself.modalResults = not listAllMatches + return newself + + def setBreak(self,breakFlag = True): + """Method to invoke the Python pdb debugger when this element is + about to be parsed. Set C{breakFlag} to True to enable, False to + disable. + """ + if breakFlag: + _parseMethod = self._parse + def breaker(instring, loc, doActions=True, callPreParse=True): + import pdb + pdb.set_trace() + return _parseMethod( instring, loc, doActions, callPreParse ) + breaker._originalParseMethod = _parseMethod + self._parse = breaker + else: + if hasattr(self._parse,"_originalParseMethod"): + self._parse = self._parse._originalParseMethod + return self + + def _normalizeParseActionArgs( f ): + """Internal method used to decorate parse actions that take fewer than 3 arguments, + so that all parse actions can be called as C{f(s,l,t)}.""" + STAR_ARGS = 4 + + # special handling for single-argument builtins + if (f in singleArgBuiltins): + numargs = 1 + else: + try: + restore = None + if isinstance(f,type): + restore = f + f = f.__init__ + if not _PY3K: + codeObj = f.func_code + else: + codeObj = f.code + if codeObj.co_flags & STAR_ARGS: + return f + numargs = codeObj.co_argcount + if not _PY3K: + if hasattr(f,"im_self"): + numargs -= 1 + else: + if hasattr(f,"__self__"): + numargs -= 1 + if restore: + f = restore + except AttributeError: + try: + if not _PY3K: + call_im_func_code = f.__call__.im_func.func_code + else: + call_im_func_code = f.__code__ + + # not a function, must be a callable object, get info from the + # im_func binding of its bound __call__ method + if call_im_func_code.co_flags & STAR_ARGS: + return f + numargs = call_im_func_code.co_argcount + if not _PY3K: + if hasattr(f.__call__,"im_self"): + numargs -= 1 + else: + if hasattr(f.__call__,"__self__"): + numargs -= 0 + except AttributeError: + if not _PY3K: + call_func_code = f.__call__.func_code + else: + call_func_code = f.__call__.__code__ + # not a bound method, get info directly from __call__ method + if call_func_code.co_flags & STAR_ARGS: + return f + numargs = call_func_code.co_argcount + if not _PY3K: + if hasattr(f.__call__,"im_self"): + numargs -= 1 + else: + if hasattr(f.__call__,"__self__"): + numargs -= 1 + + + # print ("adding function %s with %d args" % (f.func_name,numargs)) + if numargs == 3: + return f + else: + if numargs > 3: + def tmp(s,l,t): + return f(s,l,t) + elif numargs == 2: + def tmp(s,l,t): + return f(l,t) + elif numargs == 1: + def tmp(s,l,t): + return f(t) + else: #~ numargs == 0: + def tmp(s,l,t): + return f() + try: + tmp.__name__ = f.__name__ + except (AttributeError,TypeError): + # no need for special handling if attribute doesnt exist + pass + try: + tmp.__doc__ = f.__doc__ + except (AttributeError,TypeError): + # no need for special handling if attribute doesnt exist + pass + try: + tmp.__dict__.update(f.__dict__) + except (AttributeError,TypeError): + # no need for special handling if attribute doesnt exist + pass + return tmp + _normalizeParseActionArgs = staticmethod(_normalizeParseActionArgs) + + def setParseAction( self, *fns, **kwargs ): + """Define action to perform when successfully matching parse element definition. + Parse action fn is a callable method with 0-3 arguments, called as C{fn(s,loc,toks)}, + C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where: + - s = the original string being parsed (see note below) + - loc = the location of the matching substring + - toks = a list of the matched tokens, packaged as a ParseResults object + If the functions in fns modify the tokens, they can return them as the return + value from fn, and the modified list of tokens will replace the original. + Otherwise, fn does not need to return any value. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{parseString}} for more information + on parsing strings containing s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + """ + self.parseAction = list(map(self._normalizeParseActionArgs, list(fns))) + self.callDuringTry = ("callDuringTry" in kwargs and kwargs["callDuringTry"]) + return self + + def addParseAction( self, *fns, **kwargs ): + """Add parse action to expression's list of parse actions. See L{I{setParseAction}}.""" + self.parseAction += list(map(self._normalizeParseActionArgs, list(fns))) + self.callDuringTry = self.callDuringTry or ("callDuringTry" in kwargs and kwargs["callDuringTry"]) + return self + + def setFailAction( self, fn ): + """Define action to perform if parsing fails at this expression. + Fail acton fn is a callable function that takes the arguments + C{fn(s,loc,expr,err)} where: + - s = string being parsed + - loc = location where expression match was attempted and failed + - expr = the parse expression that failed + - err = the exception thrown + The function returns no value. It may throw C{ParseFatalException} + if it is desired to stop parsing immediately.""" + self.failAction = fn + return self + + def _skipIgnorables( self, instring, loc ): + exprsFound = True + while exprsFound: + exprsFound = False + for e in self.ignoreExprs: + try: + while 1: + loc,dummy = e._parse( instring, loc ) + exprsFound = True + except ParseException: + pass + return loc + + def preParse( self, instring, loc ): + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + + if self.skipWhitespace: + wt = self.whiteChars + instrlen = len(instring) + while loc < instrlen and instring[loc] in wt: + loc += 1 + + return loc + + def parseImpl( self, instring, loc, doActions=True ): + return loc, [] + + def postParse( self, instring, loc, tokenlist ): + return tokenlist + + #~ @profile + def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ): + debugging = ( self.debug ) #and doActions ) + + if debugging or self.failAction: + #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )) + if (self.debugActions[0] ): + self.debugActions[0]( instring, loc, self ) + if callPreParse and self.callPreparse: + preloc = self.preParse( instring, loc ) + else: + preloc = loc + tokensStart = preloc + try: + try: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + except IndexError: + raise ParseException( instring, len(instring), self.errmsg, self ) + except ParseBaseException as err: + #~ print ("Exception raised:", err) + if self.debugActions[2]: + self.debugActions[2]( instring, tokensStart, self, err ) + if self.failAction: + self.failAction( instring, tokensStart, self, err ) + raise + else: + if callPreParse and self.callPreparse: + preloc = self.preParse( instring, loc ) + else: + preloc = loc + tokensStart = preloc + if self.mayIndexError or loc >= len(instring): + try: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + except IndexError: + raise ParseException( instring, len(instring), self.errmsg, self ) + else: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + + tokens = self.postParse( instring, loc, tokens ) + + retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults ) + if self.parseAction and (doActions or self.callDuringTry): + if debugging: + try: + for fn in self.parseAction: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + retTokens = ParseResults( tokens, + self.resultsName, + asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), + modal=self.modalResults ) + except ParseBaseException as err: + #~ print "Exception raised in user parse action:", err + if (self.debugActions[2] ): + self.debugActions[2]( instring, tokensStart, self, err ) + raise + else: + for fn in self.parseAction: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + retTokens = ParseResults( tokens, + self.resultsName, + asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), + modal=self.modalResults ) + + if debugging: + #~ print ("Matched",self,"->",retTokens.asList()) + if (self.debugActions[1] ): + self.debugActions[1]( instring, tokensStart, loc, self, retTokens ) + + return loc, retTokens + + def tryParse( self, instring, loc ): + try: + return self._parse( instring, loc, doActions=False )[0] + except ParseFatalException: + raise ParseException( instring, loc, self.errmsg, self) + + # this method gets repeatedly called during backtracking with the same arguments - + # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression + def _parseCache( self, instring, loc, doActions=True, callPreParse=True ): + lookup = (self,instring,loc,callPreParse,doActions) + if lookup in ParserElement._exprArgCache: + value = ParserElement._exprArgCache[ lookup ] + if isinstance(value, Exception): + raise value + return value + else: + try: + value = self._parseNoCache( instring, loc, doActions, callPreParse ) + ParserElement._exprArgCache[ lookup ] = (value[0],value[1].copy()) + return value + except ParseBaseException as err: + err.__traceback__ = None + ParserElement._exprArgCache[ lookup ] = err + raise + + _parse = _parseNoCache + + # argument cache for optimizing repeated calls when backtracking through recursive expressions + _exprArgCache = {} + def resetCache(): + ParserElement._exprArgCache.clear() + resetCache = staticmethod(resetCache) + + _packratEnabled = False + def enablePackrat(): + """Enables "packrat" parsing, which adds memoizing to the parsing logic. + Repeated parse attempts at the same string location (which happens + often in many complex grammars) can immediately return a cached value, + instead of re-executing parsing/validating code. Memoizing is done of + both valid results and parsing exceptions. + + This speedup may break existing programs that use parse actions that + have side-effects. For this reason, packrat parsing is disabled when + you first import pyparsing. To activate the packrat feature, your + program must call the class method C{ParserElement.enablePackrat()}. If + your program uses C{psyco} to "compile as you go", you must call + C{enablePackrat} before calling C{psyco.full()}. If you do not do this, + Python will crash. For best results, call C{enablePackrat()} immediately + after importing pyparsing. + """ + if not ParserElement._packratEnabled: + ParserElement._packratEnabled = True + ParserElement._parse = ParserElement._parseCache + enablePackrat = staticmethod(enablePackrat) + + def parseString( self, instring, parseAll=False ): + """Execute the parse expression with the given string. + This is the main interface to the client code, once the complete + expression has been built. + + If you want the grammar to require that the entire input string be + successfully parsed, then set C{parseAll} to True (equivalent to ending + the grammar with C{StringEnd()}). + + Note: C{parseString} implicitly calls C{expandtabs()} on the input string, + in order to report proper column numbers in parse actions. + If the input string contains tabs and + the grammar uses parse actions that use the C{loc} argument to index into the + string being parsed, you can ensure you have a consistent view of the input + string by: + - calling C{parseWithTabs} on your grammar before calling C{parseString} + (see L{I{parseWithTabs}}) + - define your parse action using the full C{(s,loc,toks)} signature, and + reference the input string using the parse action's C{s} argument + - explictly expand the tabs in your input string before calling + C{parseString} + """ + ParserElement.resetCache() + if not self.streamlined: + self.streamline() + #~ self.saveAsList = True + for e in self.ignoreExprs: + e.streamline() + if not self.keepTabs: + instring = instring.expandtabs() + try: + loc, tokens = self._parse( instring, 0 ) + if parseAll: + #loc = self.preParse( instring, loc ) + se = StringEnd() + se._parse( instring, loc ) + except ParseBaseException as err: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise err + else: + return tokens + + def scanString( self, instring, maxMatches=_MAX_INT ): + """Scan the input string for expression matches. Each match will return the + matching tokens, start location, and end location. May be called with optional + C{maxMatches} argument, to clip scanning after 'n' matches are found. + + Note that the start and end locations are reported relative to the string + being parsed. See L{I{parseString}} for more information on parsing + strings with embedded tabs.""" + if not self.streamlined: + self.streamline() + for e in self.ignoreExprs: + e.streamline() + + if not self.keepTabs: + instring = _ustr(instring).expandtabs() + instrlen = len(instring) + loc = 0 + preparseFn = self.preParse + parseFn = self._parse + ParserElement.resetCache() + matches = 0 + try: + while loc <= instrlen and matches < maxMatches: + try: + preloc = preparseFn( instring, loc ) + nextLoc,tokens = parseFn( instring, preloc, callPreParse=False ) + except ParseException: + loc = preloc+1 + else: + if nextLoc > loc: + matches += 1 + yield tokens, preloc, nextLoc + loc = nextLoc + else: + loc = preloc+1 + except ParseBaseException as err: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise err + + def transformString( self, instring ): + """Extension to C{scanString}, to modify matching text with modified tokens that may + be returned from a parse action. To use C{transformString}, define a grammar and + attach a parse action to it that modifies the returned token list. + Invoking C{transformString()} on a target string will then scan for matches, + and replace the matched text patterns according to the logic in the parse + action. C{transformString()} returns the resulting transformed string.""" + out = [] + lastE = 0 + # force preservation of s, to minimize unwanted transformation of string, and to + # keep string locs straight between transformString and scanString + self.keepTabs = True + try: + for t,s,e in self.scanString( instring ): + out.append( instring[lastE:s] ) + if t: + if isinstance(t,ParseResults): + out += t.asList() + elif isinstance(t,list): + out += t + else: + out.append(t) + lastE = e + out.append(instring[lastE:]) + return "".join(map(_ustr,out)) + except ParseBaseException as err: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise err + + def searchString( self, instring, maxMatches=_MAX_INT ): + """Another extension to C{scanString}, simplifying the access to the tokens found + to match the given parse expression. May be called with optional + C{maxMatches} argument, to clip searching after 'n' matches are found. + """ + try: + return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ]) + except ParseBaseException as err: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise err + + def __add__(self, other ): + """Implementation of + operator - returns And""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return And( [ self, other ] ) + + def __radd__(self, other ): + """Implementation of + operator when left operand is not a C{ParserElement}""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other + self + + def __sub__(self, other): + """Implementation of - operator, returns C{And} with error stop""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return And( [ self, And._ErrorStop(), other ] ) + + def __rsub__(self, other ): + """Implementation of - operator when left operand is not a C{ParserElement}""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other - self + + def __mul__(self,other): + """Implementation of * operator, allows use of C{expr * 3} in place of + C{expr + expr + expr}. Expressions may also me multiplied by a 2-integer + tuple, similar to C{{min,max}} multipliers in regular expressions. Tuples + may also include C{None} as in: + - C{expr*(n,None)} or C{expr*(n,)} is equivalent + to C{expr*n + ZeroOrMore(expr)} + (read as "at least n instances of C{expr}") + - C{expr*(None,n)} is equivalent to C{expr*(0,n)} + (read as "0 to n instances of C{expr}") + - C{expr*(None,None)} is equivalent to C{ZeroOrMore(expr)} + - C{expr*(1,None)} is equivalent to C{OneOrMore(expr)} + + Note that C{expr*(None,n)} does not raise an exception if + more than n exprs exist in the input stream; that is, + C{expr*(None,n)} does not enforce a maximum number of expr + occurrences. If this behavior is desired, then write + C{expr*(None,n) + ~expr} + + """ + if isinstance(other,int): + minElements, optElements = other,0 + elif isinstance(other,tuple): + other = (other + (None, None))[:2] + if other[0] is None: + other = (0, other[1]) + if isinstance(other[0],int) and other[1] is None: + if other[0] == 0: + return ZeroOrMore(self) + if other[0] == 1: + return OneOrMore(self) + else: + return self*other[0] + ZeroOrMore(self) + elif isinstance(other[0],int) and isinstance(other[1],int): + minElements, optElements = other + optElements -= minElements + else: + raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1])) + else: + raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other)) + + if minElements < 0: + raise ValueError("cannot multiply ParserElement by negative value") + if optElements < 0: + raise ValueError("second tuple value must be greater or equal to first tuple value") + if minElements == optElements == 0: + raise ValueError("cannot multiply ParserElement by 0 or (0,0)") + + if (optElements): + def makeOptionalList(n): + if n>1: + return Optional(self + makeOptionalList(n-1)) + else: + return Optional(self) + if minElements: + if minElements == 1: + ret = self + makeOptionalList(optElements) + else: + ret = And([self]*minElements) + makeOptionalList(optElements) + else: + ret = makeOptionalList(optElements) + else: + if minElements == 1: + ret = self + else: + ret = And([self]*minElements) + return ret + + def __rmul__(self, other): + return self.__mul__(other) + + def __or__(self, other ): + """Implementation of | operator - returns C{MatchFirst}""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return MatchFirst( [ self, other ] ) + + def __ror__(self, other ): + """Implementation of | operator when left operand is not a C{ParserElement}""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other | self + + def __xor__(self, other ): + """Implementation of ^ operator - returns C{Or}""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return Or( [ self, other ] ) + + def __rxor__(self, other ): + """Implementation of ^ operator when left operand is not a C{ParserElement}""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other ^ self + + def __and__(self, other ): + """Implementation of & operator - returns C{Each}""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return Each( [ self, other ] ) + + def __rand__(self, other ): + """Implementation of & operator when left operand is not a C{ParserElement}""" + if isinstance( other, basestring ): + other = Literal( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other & self + + def __invert__( self ): + """Implementation of ~ operator - returns C{NotAny}""" + return NotAny( self ) + + def __call__(self, name): + """Shortcut for C{setResultsName}, with C{listAllMatches=default}:: + userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno") + could be written as:: + userdata = Word(alphas)("name") + Word(nums+"-")("socsecno") + """ + return self.setResultsName(name) + + def suppress( self ): + """Suppresses the output of this C{ParserElement}; useful to keep punctuation from + cluttering up returned output. + """ + return Suppress( self ) + + def leaveWhitespace( self ): + """Disables the skipping of whitespace before matching the characters in the + C{ParserElement}'s defined pattern. This is normally only used internally by + the pyparsing module, but may be needed in some whitespace-sensitive grammars. + """ + self.skipWhitespace = False + return self + + def setWhitespaceChars( self, chars ): + """Overrides the default whitespace chars + """ + self.skipWhitespace = True + self.whiteChars = chars + self.copyDefaultWhiteChars = False + return self + + def parseWithTabs( self ): + """Overrides default behavior to expand s to spaces before parsing the input string. + Must be called before C{parseString} when the input grammar contains elements that + match characters.""" + self.keepTabs = True + return self + + def ignore( self, other ): + """Define expression to be ignored (e.g., comments) while doing pattern + matching; may be called repeatedly, to define multiple comment or other + ignorable patterns. + """ + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + self.ignoreExprs.append( other.copy() ) + else: + self.ignoreExprs.append( Suppress( other.copy() ) ) + return self + + def setDebugActions( self, startAction, successAction, exceptionAction ): + """Enable display of debugging messages while doing pattern matching.""" + self.debugActions = (startAction or _defaultStartDebugAction, + successAction or _defaultSuccessDebugAction, + exceptionAction or _defaultExceptionDebugAction) + self.debug = True + return self + + def setDebug( self, flag=True ): + """Enable display of debugging messages while doing pattern matching. + Set C{flag} to True to enable, False to disable.""" + if flag: + self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction ) + else: + self.debug = False + return self + + def __str__( self ): + return self.name + + def __repr__( self ): + return _ustr(self) + + def streamline( self ): + self.streamlined = True + self.strRepr = None + return self + + def checkRecursion( self, parseElementList ): + pass + + def validate( self, validateTrace=[] ): + """Check defined expressions for valid structure, check for infinite recursive definitions.""" + self.checkRecursion( [] ) + + def parseFile( self, file_or_filename, parseAll=False ): + """Execute the parse expression on the given file or filename. + If a filename is specified (instead of a file object), + the entire file is opened, read, and closed before parsing. + """ + try: + file_contents = file_or_filename.read() + except AttributeError: + f = open(file_or_filename, "rb") + file_contents = f.read() + f.close() + try: + return self.parseString(file_contents, parseAll) + except ParseBaseException as err: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise err + + def __eq__(self,other): + if isinstance(other, ParserElement): + return self is other or self.__dict__ == other.__dict__ + elif isinstance(other, basestring): + try: + self.parseString(_ustr(other), parseAll=True) + return True + except ParseBaseException: + return False + else: + return super(ParserElement,self)==other + + def __ne__(self,other): + return not (self == other) + + def __hash__(self): + return hash(id(self)) + + def __req__(self,other): + return self == other + + def __rne__(self,other): + return not (self == other) + + +class Token(ParserElement): + """Abstract C{ParserElement} subclass, for defining atomic matching patterns.""" + def __init__( self ): + super(Token,self).__init__( savelist=False ) + #self.myException = ParseException("",0,"",self) + + def setName(self, name): + s = super(Token,self).setName(name) + self.errmsg = "Expected " + self.name + #s.myException.msg = self.errmsg + return s + + +class Empty(Token): + """An empty token, will always match.""" + def __init__( self ): + super(Empty,self).__init__() + self.name = "Empty" + self.mayReturnEmpty = True + self.mayIndexError = False + + +class NoMatch(Token): + """A token that will never match.""" + def __init__( self ): + super(NoMatch,self).__init__() + self.name = "NoMatch" + self.mayReturnEmpty = True + self.mayIndexError = False + self.errmsg = "Unmatchable token" + #self.myException.msg = self.errmsg + + def parseImpl( self, instring, loc, doActions=True ): + raise ParseException(instring, loc, self.errmsg, self) + + +class Literal(Token): + """Token to exactly match a specified string.""" + def __init__( self, matchString ): + super(Literal,self).__init__() + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Literal; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.__class__ = Empty + self.name = '"%s"' % _ustr(self.match) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + #self.myException.msg = self.errmsg + self.mayIndexError = False + + # Performance tuning: this routine gets called a *lot* + # if this is a single character match string and the first character matches, + # short-circuit as quickly as possible, and avoid calling startswith + #~ @profile + def parseImpl( self, instring, loc, doActions=True ): + if (instring[loc] == self.firstMatchChar and + (self.matchLen==1 or instring.startswith(self.match,loc)) ): + return loc+self.matchLen, self.match + raise ParseException( instring, loc, self.errmsg, self ) +_L = Literal + +class Keyword(Token): + """Token to exactly match a specified string as a keyword, that is, it must be + immediately followed by a non-keyword character. Compare with C{Literal}:: + Literal("if") will match the leading 'if' in 'ifAndOnlyIf'. + Keyword("if") will not; it will only match the leading 'if in 'if x=1', or 'if(y==2)' + Accepts two optional constructor arguments in addition to the keyword string: + C{identChars} is a string of characters that would be valid identifier characters, + defaulting to all alphanumerics + "_" and "$"; C{caseless} allows case-insensitive + matching, default is False. + """ + DEFAULT_KEYWORD_CHARS = alphanums+"_$" + + def __init__( self, matchString, identChars=DEFAULT_KEYWORD_CHARS, caseless=False ): + super(Keyword,self).__init__() + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Keyword; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.name = '"%s"' % self.match + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + #self.myException.msg = self.errmsg + self.mayIndexError = False + self.caseless = caseless + if caseless: + self.caselessmatch = matchString.upper() + identChars = identChars.upper() + self.identChars = set(identChars) + + def parseImpl( self, instring, loc, doActions=True ): + if self.caseless: + if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and + (loc == 0 or instring[loc-1].upper() not in self.identChars) ): + return loc+self.matchLen, self.match + else: + if (instring[loc] == self.firstMatchChar and + (self.matchLen==1 or instring.startswith(self.match,loc)) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and + (loc == 0 or instring[loc-1] not in self.identChars) ): + return loc+self.matchLen, self.match + raise ParseException( instring, loc, self.errmsg, self ) + + def copy(self): + c = super(Keyword,self).copy() + c.identChars = Keyword.DEFAULT_KEYWORD_CHARS + return c + + def setDefaultKeywordChars( chars ): + """Overrides the default Keyword chars + """ + Keyword.DEFAULT_KEYWORD_CHARS = chars + setDefaultKeywordChars = staticmethod(setDefaultKeywordChars) + +class CaselessLiteral(Literal): + """Token to match a specified string, ignoring case of letters. + Note: the matched results will always be in the case of the given + match string, NOT the case of the input text. + """ + def __init__( self, matchString ): + super(CaselessLiteral,self).__init__( matchString.upper() ) + # Preserve the defining literal. + self.returnString = matchString + self.name = "'%s'" % self.returnString + self.errmsg = "Expected " + self.name + #self.myException.msg = self.errmsg + + def parseImpl( self, instring, loc, doActions=True ): + if instring[ loc:loc+self.matchLen ].upper() == self.match: + return loc+self.matchLen, self.returnString + raise ParseException( instring, loc, self.errmsg, self ) + +class CaselessKeyword(Keyword): + def __init__( self, matchString, identChars=Keyword.DEFAULT_KEYWORD_CHARS ): + super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True ) + + def parseImpl( self, instring, loc, doActions=True ): + if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ): + return loc+self.matchLen, self.match + raise ParseException( instring, loc, self.errmsg, self ) + +class Word(Token): + """Token for matching words composed of allowed character sets. + Defined with string containing all allowed initial characters, + an optional string containing allowed body characters (if omitted, + defaults to the initial character set), and an optional minimum, + maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. + """ + def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False ): + super(Word,self).__init__() + self.initCharsOrig = initChars + self.initChars = set(initChars) + if bodyChars : + self.bodyCharsOrig = bodyChars + self.bodyChars = set(bodyChars) + else: + self.bodyCharsOrig = initChars + self.bodyChars = set(initChars) + + self.maxSpecified = max > 0 + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + #self.myException.msg = self.errmsg + self.mayIndexError = False + self.asKeyword = asKeyword + + if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0): + if self.bodyCharsOrig == self.initCharsOrig: + self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig) + elif len(self.bodyCharsOrig) == 1: + self.reString = "%s[%s]*" % \ + (re.escape(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + else: + self.reString = "[%s][%s]*" % \ + (_escapeRegexRangeChars(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + if self.asKeyword: + self.reString = r"\b"+self.reString+r"\b" + try: + self.re = re.compile( self.reString ) + except: + self.re = None + + def parseImpl( self, instring, loc, doActions=True ): + if self.re: + result = self.re.match(instring,loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + return loc,result.group() + + if not(instring[ loc ] in self.initChars): + raise ParseException( instring, loc, self.errmsg, self ) + start = loc + loc += 1 + instrlen = len(instring) + bodychars = self.bodyChars + maxloc = start + self.maxLen + maxloc = min( maxloc, instrlen ) + while loc < maxloc and instring[loc] in bodychars: + loc += 1 + + throwException = False + if loc - start < self.minLen: + throwException = True + if self.maxSpecified and loc < instrlen and instring[loc] in bodychars: + throwException = True + if self.asKeyword: + if (start>0 and instring[start-1] in bodychars) or (loc4: + return s[:4]+"..." + else: + return s + + if ( self.initCharsOrig != self.bodyCharsOrig ): + self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) ) + else: + self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig) + + return self.strRepr + + +class Regex(Token): + """Token for matching strings that match a given regular expression. + Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module. + """ + compiledREtype = type(re.compile("[A-Z]")) + def __init__( self, pattern, flags=0): + """The parameters pattern and flags are passed to the re.compile() function as-is. See the Python re module for an explanation of the acceptable patterns and flags.""" + super(Regex,self).__init__() + + if isinstance(pattern, basestring): + if len(pattern) == 0: + warnings.warn("null string passed to Regex; use Empty() instead", + SyntaxWarning, stacklevel=2) + + self.pattern = pattern + self.flags = flags + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % pattern, + SyntaxWarning, stacklevel=2) + raise + + elif isinstance(pattern, Regex.compiledREtype): + self.re = pattern + self.pattern = \ + self.reString = str(pattern) + self.flags = flags + + else: + raise ValueError("Regex may only be constructed with a string or a compiled RE object") + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + #self.myException.msg = self.errmsg + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = self.re.match(instring,loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + d = result.groupdict() + ret = ParseResults(result.group()) + if d: + for k in d: + ret[k] = d[k] + return loc,ret + + def __str__( self ): + try: + return super(Regex,self).__str__() + except: + pass + + if self.strRepr is None: + self.strRepr = "Re:(%s)" % repr(self.pattern) + + return self.strRepr + + +class QuotedString(Token): + """Token for matching strings that are delimited by quoting characters. + """ + def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None): + """ + Defined with the following parameters: + - quoteChar - string of one or more characters defining the quote delimiting string + - escChar - character to escape quotes, typically backslash (default=None) + - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=None) + - multiline - boolean indicating whether quotes can span multiple lines (default=False) + - unquoteResults - boolean indicating whether the matched text should be unquoted (default=True) + - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=None => same as quoteChar) + """ + super(QuotedString,self).__init__() + + # remove white space from quote chars - wont work anyway + quoteChar = quoteChar.strip() + if len(quoteChar) == 0: + warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + if endQuoteChar is None: + endQuoteChar = quoteChar + else: + endQuoteChar = endQuoteChar.strip() + if len(endQuoteChar) == 0: + warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + self.quoteChar = quoteChar + self.quoteCharLen = len(quoteChar) + self.firstQuoteChar = quoteChar[0] + self.endQuoteChar = endQuoteChar + self.endQuoteCharLen = len(endQuoteChar) + self.escChar = escChar + self.escQuote = escQuote + self.unquoteResults = unquoteResults + + if multiline: + self.flags = re.MULTILINE | re.DOTALL + self.pattern = r'%s(?:[^%s%s]' % \ + ( re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + else: + self.flags = 0 + self.pattern = r'%s(?:[^%s\n\r%s]' % \ + ( re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + if len(self.endQuoteChar) > 1: + self.pattern += ( + '|(?:' + ')|(?:'.join(["%s[^%s]" % (re.escape(self.endQuoteChar[:i]), + _escapeRegexRangeChars(self.endQuoteChar[i])) + for i in range(len(self.endQuoteChar)-1,0,-1)]) + ')' + ) + if escQuote: + self.pattern += (r'|(?:%s)' % re.escape(escQuote)) + if escChar: + self.pattern += (r'|(?:%s.)' % re.escape(escChar)) + self.escCharReplacePattern = re.escape(self.escChar)+"(.)" + self.pattern += (r')*%s' % re.escape(self.endQuoteChar)) + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern, + SyntaxWarning, stacklevel=2) + raise + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + #self.myException.msg = self.errmsg + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + ret = result.group() + + if self.unquoteResults: + + # strip off quotes + ret = ret[self.quoteCharLen:-self.endQuoteCharLen] + + if isinstance(ret,basestring): + # replace escaped characters + if self.escChar: + ret = re.sub(self.escCharReplacePattern,"\g<1>",ret) + + # replace escaped quotes + if self.escQuote: + ret = ret.replace(self.escQuote, self.endQuoteChar) + + return loc, ret + + def __str__( self ): + try: + return super(QuotedString,self).__str__() + except: + pass + + if self.strRepr is None: + self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar) + + return self.strRepr + + +class CharsNotIn(Token): + """Token for matching words composed of characters *not* in a given set. + Defined with string containing all disallowed characters, and an optional + minimum, maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. + """ + def __init__( self, notChars, min=1, max=0, exact=0 ): + super(CharsNotIn,self).__init__() + self.skipWhitespace = False + self.notChars = notChars + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = ( self.minLen == 0 ) + #self.myException.msg = self.errmsg + self.mayIndexError = False + + def parseImpl( self, instring, loc, doActions=True ): + if instring[loc] in self.notChars: + raise ParseException( instring, loc, self.errmsg, self ) + + start = loc + loc += 1 + notchars = self.notChars + maxlen = min( start+self.maxLen, len(instring) ) + while loc < maxlen and \ + (instring[loc] not in notchars): + loc += 1 + + if loc - start < self.minLen: + raise ParseException( instring, loc, self.errmsg, self ) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(CharsNotIn, self).__str__() + except: + pass + + if self.strRepr is None: + if len(self.notChars) > 4: + self.strRepr = "!W:(%s...)" % self.notChars[:4] + else: + self.strRepr = "!W:(%s)" % self.notChars + + return self.strRepr + +class White(Token): + """Special matching class for matching whitespace. Normally, whitespace is ignored + by pyparsing grammars. This class is included when some whitespace structures + are significant. Define with a string containing the whitespace characters to be + matched; default is C{" \\t\\r\\n"}. Also takes optional C{min}, C{max}, and C{exact} arguments, + as defined for the C{Word} class.""" + whiteStrs = { + " " : "", + "\t": "", + "\n": "", + "\r": "", + "\f": "", + } + def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0): + super(White,self).__init__() + self.matchWhite = ws + self.setWhitespaceChars( "".join([c for c in self.whiteChars if c not in self.matchWhite]) ) + #~ self.leaveWhitespace() + self.name = ("".join([White.whiteStrs[c] for c in self.matchWhite])) + self.mayReturnEmpty = True + self.errmsg = "Expected " + self.name + #self.myException.msg = self.errmsg + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + def parseImpl( self, instring, loc, doActions=True ): + if not(instring[ loc ] in self.matchWhite): + raise ParseException( instring, loc, self.errmsg, self ) + start = loc + loc += 1 + maxloc = start + self.maxLen + maxloc = min( maxloc, len(instring) ) + while loc < maxloc and instring[loc] in self.matchWhite: + loc += 1 + + if loc - start < self.minLen: + raise ParseException( instring, loc, self.errmsg, self ) + + return loc, instring[start:loc] + + +class _PositionToken(Token): + def __init__( self ): + super(_PositionToken,self).__init__() + self.name=self.__class__.__name__ + self.mayReturnEmpty = True + self.mayIndexError = False + +class GoToColumn(_PositionToken): + """Token to advance to a specific column of input text; useful for tabular report scraping.""" + def __init__( self, colno ): + super(GoToColumn,self).__init__() + self.col = colno + + def preParse( self, instring, loc ): + if col(loc,instring) != self.col: + instrlen = len(instring) + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col : + loc += 1 + return loc + + def parseImpl( self, instring, loc, doActions=True ): + thiscol = col( loc, instring ) + if thiscol > self.col: + raise ParseException( instring, loc, "Text not in expected column", self ) + newloc = loc + self.col - thiscol + ret = instring[ loc: newloc ] + return newloc, ret + +class LineStart(_PositionToken): + """Matches if current position is at the beginning of a line within the parse string""" + def __init__( self ): + super(LineStart,self).__init__() + self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") ) + self.errmsg = "Expected start of line" + #self.myException.msg = self.errmsg + + def preParse( self, instring, loc ): + preloc = super(LineStart,self).preParse(instring,loc) + if instring[preloc] == "\n": + loc += 1 + return loc + + def parseImpl( self, instring, loc, doActions=True ): + if not( loc==0 or + (loc == self.preParse( instring, 0 )) or + (instring[loc-1] == "\n") ): #col(loc, instring) != 1: + raise ParseException( instring, loc, self.errmsg, self ) + return loc, [] + +class LineEnd(_PositionToken): + """Matches if current position is at the end of a line within the parse string""" + def __init__( self ): + super(LineEnd,self).__init__() + self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") ) + self.errmsg = "Expected end of line" + #self.myException.msg = self.errmsg + + def parseImpl( self, instring, loc, doActions=True ): + if loc len(instring): + return loc, [] + else: + raise ParseException( instring, loc, self.errmsg, self ) + +class WordStart(_PositionToken): + """Matches if the current position is at the beginning of a Word, and + is not preceded by any character in a given set of wordChars + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of + the string being parsed, or at the beginning of a line. + """ + def __init__(self, wordChars = printables): + super(WordStart,self).__init__() + self.wordChars = set(wordChars) + self.errmsg = "Not at the start of a word" + + def parseImpl(self, instring, loc, doActions=True ): + if loc != 0: + if (instring[loc-1] in self.wordChars or + instring[loc] not in self.wordChars): + raise ParseException( instring, loc, self.errmsg, self ) + return loc, [] + +class WordEnd(_PositionToken): + """Matches if the current position is at the end of a Word, and + is not followed by any character in a given set of wordChars + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordEnd(alphanums)}. C{WordEnd} will also match at the end of + the string being parsed, or at the end of a line. + """ + def __init__(self, wordChars = printables): + super(WordEnd,self).__init__() + self.wordChars = set(wordChars) + self.skipWhitespace = False + self.errmsg = "Not at the end of a word" + + def parseImpl(self, instring, loc, doActions=True ): + instrlen = len(instring) + if instrlen>0 and loc maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException(instring,len(instring),e.errmsg,self) + maxExcLoc = len(instring) + else: + if loc2 > maxMatchLoc: + maxMatchLoc = loc2 + maxMatchExp = e + + if maxMatchLoc < 0: + if maxException is not None: + maxException.__traceback__ = None + raise maxException + else: + raise ParseException(instring, loc, "no defined alternatives to match", self) + + return maxMatchExp._parse( instring, loc, doActions ) + + def __ixor__(self, other ): + if isinstance( other, basestring ): + other = Literal( other ) + return self.append( other ) #Or( [ self, other ] ) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ^ ".join( [ _ustr(e) for e in self.exprs ] ) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class MatchFirst(ParseExpression): + """Requires that at least one C{ParseExpression} is found. + If two expressions match, the first one listed is the one that will match. + May be constructed using the '|' operator. + """ + def __init__( self, exprs, savelist = False ): + super(MatchFirst,self).__init__(exprs, savelist) + if exprs: + self.mayReturnEmpty = False + for e in self.exprs: + if e.mayReturnEmpty: + self.mayReturnEmpty = True + break + else: + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + for e in self.exprs: + try: + ret = e._parse( instring, loc, doActions ) + return ret + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException(instring,len(instring),e.errmsg,self) + maxExcLoc = len(instring) + + # only got here if no expression matched, raise exception for match that made it the furthest + else: + if maxException is not None: + maxException.__traceback__ = None + raise maxException + else: + raise ParseException(instring, loc, "no defined alternatives to match", self) + + def __ior__(self, other ): + if isinstance( other, basestring ): + other = Literal( other ) + return self.append( other ) #MatchFirst( [ self, other ] ) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " | ".join( [ _ustr(e) for e in self.exprs ] ) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class Each(ParseExpression): + """Requires all given C{ParseExpressions} to be found, but in any order. + Expressions may be separated by whitespace. + May be constructed using the '&' operator. + """ + def __init__( self, exprs, savelist = True ): + super(Each,self).__init__(exprs, savelist) + self.mayReturnEmpty = True + for e in self.exprs: + if not e.mayReturnEmpty: + self.mayReturnEmpty = False + break + self.skipWhitespace = True + self.initExprGroups = True + + def parseImpl( self, instring, loc, doActions=True ): + if self.initExprGroups: + opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ] + opt2 = [ e for e in self.exprs if e.mayReturnEmpty and e not in opt1 ] + self.optionals = opt1 + opt2 + self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ] + self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ] + self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ] + self.required += self.multirequired + self.initExprGroups = False + tmpLoc = loc + tmpReqd = self.required[:] + tmpOpt = self.optionals[:] + matchOrder = [] + + keepMatching = True + while keepMatching: + tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired + failed = [] + for e in tmpExprs: + try: + tmpLoc = e.tryParse( instring, tmpLoc ) + except ParseException: + failed.append(e) + else: + matchOrder.append(e) + if e in tmpReqd: + tmpReqd.remove(e) + elif e in tmpOpt: + tmpOpt.remove(e) + if len(failed) == len(tmpExprs): + keepMatching = False + + if tmpReqd: + missing = ", ".join( [ _ustr(e) for e in tmpReqd ] ) + raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing ) + + # add any unmatched Optionals, in case they have default values defined + matchOrder += list(e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt) + + resultlist = [] + for e in matchOrder: + loc,results = e._parse(instring,loc,doActions) + resultlist.append(results) + + finalResults = ParseResults([]) + for r in resultlist: + dups = {} + for k in r.keys(): + if k in finalResults.keys(): + tmp = ParseResults(finalResults[k]) + tmp += ParseResults(r[k]) + dups[k] = tmp + finalResults += ParseResults(r) + for k,v in dups.items(): + finalResults[k] = v + return loc, finalResults + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " & ".join( [ _ustr(e) for e in self.exprs ] ) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class ParseElementEnhance(ParserElement): + """Abstract subclass of C{ParserElement}, for combining and post-processing parsed tokens.""" + def __init__( self, expr, savelist=False ): + super(ParseElementEnhance,self).__init__(savelist) + if isinstance( expr, basestring ): + expr = Literal(expr) + self.expr = expr + self.strRepr = None + if expr is not None: + self.mayIndexError = expr.mayIndexError + self.mayReturnEmpty = expr.mayReturnEmpty + self.setWhitespaceChars( expr.whiteChars ) + self.skipWhitespace = expr.skipWhitespace + self.saveAsList = expr.saveAsList + self.callPreparse = expr.callPreparse + self.ignoreExprs.extend(expr.ignoreExprs) + + def parseImpl( self, instring, loc, doActions=True ): + if self.expr is not None: + return self.expr._parse( instring, loc, doActions, callPreParse=False ) + else: + raise ParseException("",loc,self.errmsg,self) + + def leaveWhitespace( self ): + self.skipWhitespace = False + self.expr = self.expr.copy() + if self.expr is not None: + self.expr.leaveWhitespace() + return self + + def ignore( self, other ): + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + else: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + return self + + def streamline( self ): + super(ParseElementEnhance,self).streamline() + if self.expr is not None: + self.expr.streamline() + return self + + def checkRecursion( self, parseElementList ): + if self in parseElementList: + raise RecursiveGrammarException( parseElementList+[self] ) + subRecCheckList = parseElementList[:] + [ self ] + if self.expr is not None: + self.expr.checkRecursion( subRecCheckList ) + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion( [] ) + + def __str__( self ): + try: + return super(ParseElementEnhance,self).__str__() + except: + pass + + if self.strRepr is None and self.expr is not None: + self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) ) + return self.strRepr + + +class FollowedBy(ParseElementEnhance): + """Lookahead matching of the given parse expression. C{FollowedBy} + does *not* advance the parsing position within the input string, it only + verifies that the specified parse expression matches at the current + position. C{FollowedBy} always returns a null token list.""" + def __init__( self, expr ): + super(FollowedBy,self).__init__(expr) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + self.expr.tryParse( instring, loc ) + return loc, [] + + +class NotAny(ParseElementEnhance): + """Lookahead to disallow matching with the given parse expression. C{NotAny} + does *not* advance the parsing position within the input string, it only + verifies that the specified parse expression does *not* match at the current + position. Also, C{NotAny} does *not* skip over leading whitespace. C{NotAny} + always returns a null token list. May be constructed using the '~' operator.""" + def __init__( self, expr ): + super(NotAny,self).__init__(expr) + #~ self.leaveWhitespace() + self.skipWhitespace = False # do NOT use self.leaveWhitespace(), don't want to propagate to exprs + self.mayReturnEmpty = True + self.errmsg = "Found unwanted token, "+_ustr(self.expr) + #self.myException = ParseException("",0,self.errmsg,self) + + def parseImpl( self, instring, loc, doActions=True ): + try: + self.expr.tryParse( instring, loc ) + except (ParseException,IndexError): + pass + else: + raise ParseException( instring, loc, self.errmsg, self ) + return loc, [] + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "~{" + _ustr(self.expr) + "}" + + return self.strRepr + + +class ZeroOrMore(ParseElementEnhance): + """Optional repetition of zero or more of the given expression.""" + def __init__( self, expr ): + super(ZeroOrMore,self).__init__(expr) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + tokens = [] + try: + loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) + hasIgnoreExprs = ( len(self.ignoreExprs) > 0 ) + while 1: + if hasIgnoreExprs: + preloc = self._skipIgnorables( instring, loc ) + else: + preloc = loc + loc, tmptokens = self.expr._parse( instring, preloc, doActions ) + if tmptokens or tmptokens.keys(): + tokens += tmptokens + except (ParseException,IndexError): + pass + + return loc, tokens + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]..." + + return self.strRepr + + def setResultsName( self, name, listAllMatches=False ): + ret = super(ZeroOrMore,self).setResultsName(name,listAllMatches) + ret.saveAsList = True + return ret + + +class OneOrMore(ParseElementEnhance): + """Repetition of one or more of the given expression.""" + def parseImpl( self, instring, loc, doActions=True ): + # must be at least one + loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) + try: + hasIgnoreExprs = ( len(self.ignoreExprs) > 0 ) + while 1: + if hasIgnoreExprs: + preloc = self._skipIgnorables( instring, loc ) + else: + preloc = loc + loc, tmptokens = self.expr._parse( instring, preloc, doActions ) + if tmptokens or tmptokens.keys(): + tokens += tmptokens + except (ParseException,IndexError): + pass + + return loc, tokens + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + _ustr(self.expr) + "}..." + + return self.strRepr + + def setResultsName( self, name, listAllMatches=False ): + ret = super(OneOrMore,self).setResultsName(name,listAllMatches) + ret.saveAsList = True + return ret + +class _NullToken(object): + def __bool__(self): + return False + __nonzero__ = __bool__ + def __str__(self): + return "" + +_optionalNotMatched = _NullToken() +class Optional(ParseElementEnhance): + """Optional matching of the given expression. + A default return string can also be specified, if the optional expression + is not found. + """ + def __init__( self, exprs, default=_optionalNotMatched ): + super(Optional,self).__init__( exprs, savelist=False ) + self.defaultValue = default + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + try: + loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) + except (ParseException,IndexError): + if self.defaultValue is not _optionalNotMatched: + if self.expr.resultsName: + tokens = ParseResults([ self.defaultValue ]) + tokens[self.expr.resultsName] = self.defaultValue + else: + tokens = [ self.defaultValue ] + else: + tokens = [] + return loc, tokens + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]" + + return self.strRepr + + +class SkipTo(ParseElementEnhance): + """Token for skipping over all undefined text until the matched expression is found. + If C{include} is set to true, the matched expression is also parsed (the skipped text + and matched expression are returned as a 2-element list). The C{ignore} + argument is used to define grammars (typically quoted strings and comments) that + might contain false matches. + """ + def __init__( self, other, include=False, ignore=None, failOn=None ): + super( SkipTo, self ).__init__( other ) + self.ignoreExpr = ignore + self.mayReturnEmpty = True + self.mayIndexError = False + self.includeMatch = include + self.asList = False + if failOn is not None and isinstance(failOn, basestring): + self.failOn = Literal(failOn) + else: + self.failOn = failOn + self.errmsg = "No match found for "+_ustr(self.expr) + #self.myException = ParseException("",0,self.errmsg,self) + + def parseImpl( self, instring, loc, doActions=True ): + startLoc = loc + instrlen = len(instring) + expr = self.expr + failParse = False + while loc <= instrlen: + try: + if self.failOn: + try: + self.failOn.tryParse(instring, loc) + except ParseBaseException: + pass + else: + failParse = True + raise ParseException(instring, loc, "Found expression " + str(self.failOn)) + failParse = False + if self.ignoreExpr is not None: + while 1: + try: + loc = self.ignoreExpr.tryParse(instring,loc) + # print("found ignoreExpr, advance to", loc) + except ParseBaseException: + break + expr._parse( instring, loc, doActions=False, callPreParse=False ) + skipText = instring[startLoc:loc] + if self.includeMatch: + loc,mat = expr._parse(instring,loc,doActions,callPreParse=False) + if mat: + skipRes = ParseResults( skipText ) + skipRes += mat + return loc, [ skipRes ] + else: + return loc, [ skipText ] + else: + return loc, [ skipText ] + except (ParseException,IndexError): + if failParse: + raise + else: + loc += 1 + raise ParseException( instring, loc, self.errmsg, self ) + +class Forward(ParseElementEnhance): + """Forward declaration of an expression to be defined later - + used for recursive grammars, such as algebraic infix notation. + When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator. + + Note: take care when assigning to C{Forward} not to overlook precedence of operators. + Specifically, '|' has a lower precedence than '<<', so that:: + fwdExpr << a | b | c + will actually be evaluated as:: + (fwdExpr << a) | b | c + thereby leaving b and c out as parseable alternatives. It is recommended that you + explicitly group the values inserted into the C{Forward}:: + fwdExpr << (a | b | c) + """ + def __init__( self, other=None ): + super(Forward,self).__init__( other, savelist=False ) + + def __lshift__( self, other ): + if isinstance( other, basestring ): + other = Literal(other) + self.expr = other + self.mayReturnEmpty = other.mayReturnEmpty + self.strRepr = None + self.mayIndexError = self.expr.mayIndexError + self.mayReturnEmpty = self.expr.mayReturnEmpty + self.setWhitespaceChars( self.expr.whiteChars ) + self.skipWhitespace = self.expr.skipWhitespace + self.saveAsList = self.expr.saveAsList + self.ignoreExprs.extend(self.expr.ignoreExprs) + return None + + def leaveWhitespace( self ): + self.skipWhitespace = False + return self + + def streamline( self ): + if not self.streamlined: + self.streamlined = True + if self.expr is not None: + self.expr.streamline() + return self + + def validate( self, validateTrace=[] ): + if self not in validateTrace: + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion([]) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + self._revertClass = self.__class__ + self.__class__ = _ForwardNoRecurse + try: + if self.expr is not None: + retString = _ustr(self.expr) + else: + retString = "None" + finally: + self.__class__ = self._revertClass + return self.__class__.__name__ + ": " + retString + + def copy(self): + if self.expr is not None: + return super(Forward,self).copy() + else: + ret = Forward() + ret << self + return ret + +class _ForwardNoRecurse(Forward): + def __str__( self ): + return "..." + +class TokenConverter(ParseElementEnhance): + """Abstract subclass of ParseExpression, for converting parsed results.""" + def __init__( self, expr, savelist=False ): + super(TokenConverter,self).__init__( expr )#, savelist ) + self.saveAsList = False + +class Upcase(TokenConverter): + """Converter to upper case all matching tokens.""" + def __init__(self, *args): + super(Upcase,self).__init__(*args) + warnings.warn("Upcase class is deprecated, use upcaseTokens parse action instead", + DeprecationWarning,stacklevel=2) + + def postParse( self, instring, loc, tokenlist ): + return list(map( string.upper, tokenlist )) + + +class Combine(TokenConverter): + """Converter to concatenate all matching tokens to a single string. + By default, the matching patterns must also be contiguous in the input string; + this can be disabled by specifying C{'adjacent=False'} in the constructor. + """ + def __init__( self, expr, joinString="", adjacent=True ): + super(Combine,self).__init__( expr ) + # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself + if adjacent: + self.leaveWhitespace() + self.adjacent = adjacent + self.skipWhitespace = True + self.joinString = joinString + self.callPreparse = True + + def ignore( self, other ): + if self.adjacent: + ParserElement.ignore(self, other) + else: + super( Combine, self).ignore( other ) + return self + + def postParse( self, instring, loc, tokenlist ): + retToks = tokenlist.copy() + del retToks[:] + retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults) + + if self.resultsName and len(retToks.keys())>0: + return [ retToks ] + else: + return retToks + +class Group(TokenConverter): + """Converter to return the matched tokens as a list - useful for returning tokens of ZeroOrMore and OneOrMore expressions.""" + def __init__( self, expr ): + super(Group,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + return [ tokenlist ] + +class Dict(TokenConverter): + """Converter to return a repetitive expression as a list, but also as a dictionary. + Each element can also be referenced using the first token in the expression as its key. + Useful for tabular report scraping when the first column can be used as a item key. + """ + def __init__( self, exprs ): + super(Dict,self).__init__( exprs ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + for i,tok in enumerate(tokenlist): + if len(tok) == 0: + continue + ikey = tok[0] + if isinstance(ikey,int): + ikey = _ustr(tok[0]).strip() + if len(tok)==1: + tokenlist[ikey] = _ParseResultsWithOffset("",i) + elif len(tok)==2 and not isinstance(tok[1],ParseResults): + tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i) + else: + dictvalue = tok.copy() #ParseResults(i) + del dictvalue[0] + if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.keys()): + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i) + else: + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i) + + if self.resultsName: + return [ tokenlist ] + else: + return tokenlist + + +class Suppress(TokenConverter): + """Converter for ignoring the results of a parsed expression.""" + def postParse( self, instring, loc, tokenlist ): + return [] + + def suppress( self ): + return self + + +class OnlyOnce(object): + """Wrapper for parse actions, to ensure they are only called once.""" + def __init__(self, methodCall): + self.callable = ParserElement._normalizeParseActionArgs(methodCall) + self.called = False + def __call__(self,s,l,t): + if not self.called: + results = self.callable(s,l,t) + self.called = True + return results + raise ParseException(s,l,"") + def reset(self): + self.called = False + +def traceParseAction(f): + """Decorator for debugging parse actions.""" + f = ParserElement._normalizeParseActionArgs(f) + def z(*paArgs): + thisFunc = f.func_name + s,l,t = paArgs[-3:] + if len(paArgs)>3: + thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc + sys.stderr.write( ">>entering %s(line: '%s', %d, %s)\n" % (thisFunc,line(l,s),l,t) ) + try: + ret = f(*paArgs) + except Exception as exc: + sys.stderr.write( "<", "|".join( [ _escapeRegexChars(sym) for sym in symbols] )) + try: + if len(symbols)==len("".join(symbols)): + return Regex( "[%s]" % "".join( [ _escapeRegexRangeChars(sym) for sym in symbols] ) ) + else: + return Regex( "|".join( [ re.escape(sym) for sym in symbols] ) ) + except: + warnings.warn("Exception creating Regex for oneOf, building MatchFirst", + SyntaxWarning, stacklevel=2) + + + # last resort, just use MatchFirst + return MatchFirst( [ parseElementClass(sym) for sym in symbols ] ) + +def dictOf( key, value ): + """Helper to easily and clearly define a dictionary by specifying the respective patterns + for the key and value. Takes care of defining the C{Dict}, C{ZeroOrMore}, and C{Group} tokens + in the proper order. The key pattern can include delimiting markers or punctuation, + as long as they are suppressed, thereby leaving the significant key text. The value + pattern can include named results, so that the C{Dict} results can include named token + fields. + """ + return Dict( ZeroOrMore( Group ( key + value ) ) ) + +def originalTextFor(expr, asString=True): + """Helper to return the original, untokenized text for a given expression. Useful to + restore the parsed fields of an HTML start tag into the raw tag text itself, or to + revert separate tokens with intervening whitespace back to the original matching + input text. Simpler to use than the parse action C{keepOriginalText}, and does not + require the inspect module to chase up the call stack. By default, returns a + string containing the original parsed text. + + If the optional C{asString} argument is passed as False, then the return value is a + C{ParseResults} containing any results names that were originally matched, and a + single token containing the original matched text from the input string. So if + the expression passed to C{originalTextFor} contains expressions with defined + results names, you must set C{asString} to False if you want to preserve those + results name values.""" + locMarker = Empty().setParseAction(lambda s,loc,t: loc) + endlocMarker = locMarker.copy() + endlocMarker.callPreparse = False + matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end") + if asString: + extractText = lambda s,l,t: s[t._original_start:t._original_end] + else: + def extractText(s,l,t): + del t[:] + t.insert(0, s[t._original_start:t._original_end]) + del t["_original_start"] + del t["_original_end"] + matchExpr.setParseAction(extractText) + return matchExpr + +# convenience constants for positional expressions +empty = Empty().setName("empty") +lineStart = LineStart().setName("lineStart") +lineEnd = LineEnd().setName("lineEnd") +stringStart = StringStart().setName("stringStart") +stringEnd = StringEnd().setName("stringEnd") + +_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1]) +_printables_less_backslash = "".join([ c for c in printables if c not in r"\]" ]) +_escapedHexChar = Combine( Suppress(_bslash + "0x") + Word(hexnums) ).setParseAction(lambda s,l,t:unichr(int(t[0],16))) +_escapedOctChar = Combine( Suppress(_bslash) + Word("0","01234567") ).setParseAction(lambda s,l,t:unichr(int(t[0],8))) +_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | Word(_printables_less_backslash,exact=1) +_charRange = Group(_singleChar + Suppress("-") + _singleChar) +_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]" + +_expanded = lambda p: (isinstance(p,ParseResults) and ''.join([ unichr(c) for c in range(ord(p[0]),ord(p[1])+1) ]) or p) + +def srange(s): + r"""Helper to easily define string ranges for use in Word construction. Borrows + syntax from regexp '[]' string range definitions:: + srange("[0-9]") -> "0123456789" + srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz" + srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_" + The input string must be enclosed in []'s, and the returned string is the expanded + character set joined into a single string. + The values enclosed in the []'s may be:: + a single character + an escaped character with a leading backslash (such as \- or \]) + an escaped hex character with a leading '\0x' (\0x21, which is a '!' character) + an escaped octal character with a leading '\0' (\041, which is a '!' character) + a range of any of the above, separated by a dash ('a-z', etc.) + any combination of the above ('aeiouy', 'a-zA-Z0-9_$', etc.) + """ + try: + return "".join([_expanded(part) for part in _reBracketExpr.parseString(s).body]) + except: + return "" + +def matchOnlyAtCol(n): + """Helper method for defining parse actions that require matching at a specific + column in the input text. + """ + def verifyCol(strg,locn,toks): + if col(locn,strg) != n: + raise ParseException(strg,locn,"matched token not at column %d" % n) + return verifyCol + +def replaceWith(replStr): + """Helper method for common parse actions that simply return a literal value. Especially + useful when used with C{transformString()}. + """ + def _replFunc(*args): + return [replStr] + return _replFunc + +def removeQuotes(s,l,t): + """Helper parse action for removing quotation marks from parsed quoted strings. + To use, add this parse action to quoted string using:: + quotedString.setParseAction( removeQuotes ) + """ + return t[0][1:-1] + +def upcaseTokens(s,l,t): + """Helper parse action to convert tokens to upper case.""" + return [ tt.upper() for tt in map(_ustr,t) ] + +def downcaseTokens(s,l,t): + """Helper parse action to convert tokens to lower case.""" + return [ tt.lower() for tt in map(_ustr,t) ] + +def keepOriginalText(s,startLoc,t): + """DEPRECATED - use new helper method C{originalTextFor}. + Helper parse action to preserve original parsed text, + overriding any nested parse actions.""" + try: + endloc = getTokensEndLoc() + except ParseException: + raise ParseFatalException("incorrect usage of keepOriginalText - may only be called as a parse action") + del t[:] + t += ParseResults(s[startLoc:endloc]) + return t + +def getTokensEndLoc(): + """Method to be called from within a parse action to determine the end + location of the parsed tokens.""" + import inspect + fstack = inspect.stack() + try: + # search up the stack (through intervening argument normalizers) for correct calling routine + for f in fstack[2:]: + if f[3] == "_parseNoCache": + endloc = f[0].f_locals["loc"] + return endloc + else: + raise ParseFatalException("incorrect usage of getTokensEndLoc - may only be called from within a parse action") + finally: + del fstack + +def _makeTags(tagStr, xml): + """Internal helper to construct opening and closing tag expressions, given a tag name""" + if isinstance(tagStr,basestring): + resname = tagStr + tagStr = Keyword(tagStr, caseless=not xml) + else: + resname = tagStr.name + + tagAttrName = Word(alphas,alphanums+"_-:") + if (xml): + tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes ) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + else: + printablesLessRAbrack = "".join( [ c for c in printables if c not in ">" ] ) + tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack) + openTag = Suppress("<") + tagStr + \ + Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \ + Optional( Suppress("=") + tagAttrValue ) ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + closeTag = Combine(_L("") + + openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % tagStr) + closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("" % tagStr) + openTag.tag = resname + closeTag.tag = resname + return openTag, closeTag + +def makeHTMLTags(tagStr): + """Helper to construct opening and closing tag expressions for HTML, given a tag name""" + return _makeTags( tagStr, False ) + +def makeXMLTags(tagStr): + """Helper to construct opening and closing tag expressions for XML, given a tag name""" + return _makeTags( tagStr, True ) + +def withAttribute(*args,**attrDict): + """Helper to create a validating parse action to be used with start tags created + with makeXMLTags or makeHTMLTags. Use withAttribute to qualify a starting tag + with a required attribute value, to avoid false matches on common tags such as + or
    . + + Call withAttribute with a series of attribute names and values. Specify the list + of filter attributes names and values as: + - keyword arguments, as in (class="Customer",align="right"), or + - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") ) + For attribute names with a namespace prefix, you must use the second form. Attribute + names are matched insensitive to upper/lower case. + + To verify that the attribute exists, but without specifying a value, pass + withAttribute.ANY_VALUE as the value. + """ + if args: + attrs = args[:] + else: + attrs = attrDict.items() + attrs = [(k,v) for k,v in attrs] + def pa(s,l,tokens): + for attrName,attrValue in attrs: + if attrName not in tokens: + raise ParseException(s,l,"no matching attribute " + attrName) + if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue: + raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" % + (attrName, tokens[attrName], attrValue)) + return pa +withAttribute.ANY_VALUE = object() + +opAssoc = _Constants() +opAssoc.LEFT = object() +opAssoc.RIGHT = object() + +def operatorPrecedence( baseExpr, opList ): + """Helper method for constructing grammars of expressions made up of + operators working in a precedence hierarchy. Operators may be unary or + binary, left- or right-associative. Parse actions can also be attached + to operator expressions. + + Parameters: + - baseExpr - expression representing the most basic element for the nested + - opList - list of tuples, one for each operator precedence level in the + expression grammar; each tuple is of the form + (opExpr, numTerms, rightLeftAssoc, parseAction), where: + - opExpr is the pyparsing expression for the operator; + may also be a string, which will be converted to a Literal; + if numTerms is 3, opExpr is a tuple of two expressions, for the + two operators separating the 3 terms + - numTerms is the number of terms for this operator (must + be 1, 2, or 3) + - rightLeftAssoc is the indicator whether the operator is + right or left associative, using the pyparsing-defined + constants opAssoc.RIGHT and opAssoc.LEFT. + - parseAction is the parse action to be associated with + expressions matching this operator expression (the + parse action tuple member may be omitted) + """ + ret = Forward() + lastExpr = baseExpr | ( Suppress('(') + ret + Suppress(')') ) + for i,operDef in enumerate(opList): + opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4] + if arity == 3: + if opExpr is None or len(opExpr) != 2: + raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions") + opExpr1, opExpr2 = opExpr + thisExpr = Forward()#.setName("expr%d" % i) + if rightLeftAssoc == opAssoc.LEFT: + if arity == 1: + matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) ) + else: + matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) ) + elif arity == 3: + matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \ + Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + elif rightLeftAssoc == opAssoc.RIGHT: + if arity == 1: + # try to avoid LR with this extra test + if not isinstance(opExpr, Optional): + opExpr = Optional(opExpr) + matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) ) + else: + matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) ) + elif arity == 3: + matchExpr = FollowedBy(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \ + Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + else: + raise ValueError("operator must indicate right or left associativity") + if pa: + matchExpr.setParseAction( pa ) + thisExpr << ( matchExpr | lastExpr ) + lastExpr = thisExpr + ret << lastExpr + return ret + +dblQuotedString = Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\x[0-9a-fA-F]+)|(?:\\.))*"').setName("string enclosed in double quotes") +sglQuotedString = Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\x[0-9a-fA-F]+)|(?:\\.))*'").setName("string enclosed in single quotes") +quotedString = Regex(r'''(?:"(?:[^"\n\r\\]|(?:"")|(?:\\x[0-9a-fA-F]+)|(?:\\.))*")|(?:'(?:[^'\n\r\\]|(?:'')|(?:\\x[0-9a-fA-F]+)|(?:\\.))*')''').setName("quotedString using single or double quotes") +unicodeString = Combine(_L('u') + quotedString.copy()) + +def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()): + """Helper method for defining nested lists enclosed in opening and closing + delimiters ("(" and ")" are the default). + + Parameters: + - opener - opening character for a nested list (default="("); can also be a pyparsing expression + - closer - closing character for a nested list (default=")"); can also be a pyparsing expression + - content - expression for items within the nested lists (default=None) + - ignoreExpr - expression for ignoring opening and closing delimiters (default=quotedString) + + If an expression is not provided for the content argument, the nested + expression will capture all whitespace-delimited content between delimiters + as a list of separate values. + + Use the ignoreExpr argument to define expressions that may contain + opening or closing characters that should not be treated as opening + or closing characters for nesting, such as quotedString or a comment + expression. Specify multiple expressions using an Or or MatchFirst. + The default is quotedString, but if no expressions are to be ignored, + then pass None for this argument. + """ + if opener == closer: + raise ValueError("opening and closing strings cannot be the same") + if content is None: + if isinstance(opener,basestring) and isinstance(closer,basestring): + if len(opener) == 1 and len(closer)==1: + if ignoreExpr is not None: + content = (Combine(OneOrMore(~ignoreExpr + + CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS + ).setParseAction(lambda t:t[0].strip())) + else: + if ignoreExpr is not None: + content = (Combine(OneOrMore(~ignoreExpr + + ~Literal(opener) + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + raise ValueError("opening and closing arguments must be strings if no content expression is given") + ret = Forward() + if ignoreExpr is not None: + ret << Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) ) + else: + ret << Group( Suppress(opener) + ZeroOrMore( ret | content ) + Suppress(closer) ) + return ret + +def indentedBlock(blockStatementExpr, indentStack, indent=True): + """Helper method for defining space-delimited indentation blocks, such as + those used to define block statements in Python source code. + + Parameters: + - blockStatementExpr - expression defining syntax of statement that + is repeated within the indented block + - indentStack - list created by caller to manage indentation stack + (multiple statementWithIndentedBlock expressions within a single grammar + should share a common indentStack) + - indent - boolean indicating whether block must be indented beyond the + the current level; set to False for block of left-most statements + (default=True) + + A valid block must contain at least one blockStatement. + """ + def checkPeerIndent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if curCol != indentStack[-1]: + if curCol > indentStack[-1]: + raise ParseFatalException(s,l,"illegal nesting") + raise ParseException(s,l,"not a peer entry") + + def checkSubIndent(s,l,t): + curCol = col(l,s) + if curCol > indentStack[-1]: + indentStack.append( curCol ) + else: + raise ParseException(s,l,"not a subentry") + + def checkUnindent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]): + raise ParseException(s,l,"not an unindent") + indentStack.pop() + + NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress()) + INDENT = Empty() + Empty().setParseAction(checkSubIndent) + PEER = Empty().setParseAction(checkPeerIndent) + UNDENT = Empty().setParseAction(checkUnindent) + if indent: + smExpr = Group( Optional(NL) + + #~ FollowedBy(blockStatementExpr) + + INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT) + else: + smExpr = Group( Optional(NL) + + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) ) + blockStatementExpr.ignore(_bslash + LineEnd()) + return smExpr + +alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]") +punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]") + +anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:")) +commonHTMLEntity = Combine(_L("&") + oneOf("gt lt amp nbsp quot").setResultsName("entity") +";").streamline() +_htmlEntityMap = dict(zip("gt lt amp nbsp quot".split(),'><& "')) +replaceHTMLEntity = lambda t : t.entity in _htmlEntityMap and _htmlEntityMap[t.entity] or None + +# it's easy to get these comment structures wrong - they're very common, so may as well make them available +cStyleComment = Regex(r"/\*(?:[^*]*\*+)+?/").setName("C style comment") + +htmlComment = Regex(r"") +restOfLine = Regex(r".*").leaveWhitespace() +dblSlashComment = Regex(r"\/\/(\\\n|.)*").setName("// comment") +cppStyleComment = Regex(r"/(?:\*(?:[^*]*\*+)+?/|/[^\n]*(?:\n[^\n]*)*?(?:(?" + str(tokenlist)) + print ("tokens = " + str(tokens)) + print ("tokens.columns = " + str(tokens.columns)) + print ("tokens.tables = " + str(tokens.tables)) + print (tokens.asXML("SQL",True)) + except ParseBaseException as err: + print (teststring + "->") + print (err.line) + print (" "*(err.column-1) + "^") + print (err) + print() + + selectToken = CaselessLiteral( "select" ) + fromToken = CaselessLiteral( "from" ) + + ident = Word( alphas, alphanums + "_$" ) + columnName = delimitedList( ident, ".", combine=True ).setParseAction( upcaseTokens ) + columnNameList = Group( delimitedList( columnName ) )#.setName("columns") + tableName = delimitedList( ident, ".", combine=True ).setParseAction( upcaseTokens ) + tableNameList = Group( delimitedList( tableName ) )#.setName("tables") + simpleSQL = ( selectToken + \ + ( '*' | columnNameList ).setResultsName( "columns" ) + \ + fromToken + \ + tableNameList.setResultsName( "tables" ) ) + + test( "SELECT * from XYZZY, ABC" ) + test( "select * from SYS.XYZZY" ) + test( "Select A from Sys.dual" ) + test( "Select AA,BB,CC from Sys.dual" ) + test( "Select A, B, C from Sys.dual" ) + test( "Select A, B, C from Sys.dual" ) + test( "Xelect A, B, C from Sys.dual" ) + test( "Select A, B, C frox Sys.dual" ) + test( "Select" ) + test( "Select ^^^ frox Sys.dual" ) + test( "Select A, B, C from Sys.dual, Table2 " ) diff -Nru matplotlib-1.1.1/lib/matplotlib/pyplot.py matplotlib-1.2.0/lib/matplotlib/pyplot.py --- matplotlib-1.1.1/lib/matplotlib/pyplot.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/pyplot.py 2012-11-08 13:38:03.000000000 +0000 @@ -1,3 +1,5 @@ +# 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. @@ -13,6 +15,7 @@ plt.plot(x, y) """ +from __future__ import print_function import sys, warnings @@ -52,7 +55,6 @@ LinearLocator, LogLocator, AutoLocator, MultipleLocator,\ MaxNLocator - ## Backend detection ## def _backend_selection(): """ If rcParams['backend_fallback'] is true, check to see if the @@ -92,7 +94,7 @@ ## Global ## from matplotlib.backends import pylab_setup -new_figure_manager, draw_if_interactive, _show = pylab_setup() +_backend_mod, new_figure_manager, draw_if_interactive, _show = pylab_setup() @docstring.copy_dedent(Artist.findobj) def findobj(o=None, match=None): @@ -100,28 +102,30 @@ o = gcf() return o.findobj(match) + def switch_backend(newbackend): """ - Switch the default backend to newbackend. This feature is - **experimental**, and is only expected to work switching to an - image backend. Eg, if you have a bunch of PostScript scripts that - you want to run from an interactive ipython session, you may want - to switch to the PS backend before running them to avoid having a - bunch of GUI windows popup. If you try to interactively switch - from one GUI backend to another, you will explode. + Switch the default backend. This feature is **experimental**, and + is only expected to work switching to an image backend. Eg, if + you have a bunch of PostScript scripts that you want to run from + an interactive ipython session, you may want to switch to the PS + backend before running them to avoid having a bunch of GUI windows + popup. If you try to interactively switch from one GUI backend to + another, you will explode. Calling this command will close all open windows. """ close('all') - global new_figure_manager, draw_if_interactive, _show - matplotlib.use(newbackend, warn=False) - reload(matplotlib.backends) + global _backend_mod, new_figure_manager, draw_if_interactive, _show + matplotlib.use(newbackend, warn=False, force=True) from matplotlib.backends import pylab_setup - new_figure_manager, draw_if_interactive, _show = pylab_setup() + _backend_mod, new_figure_manager, draw_if_interactive, _show = pylab_setup() def show(*args, **kw): """ + Display a figure. + When running in ipython with its pylab mode, display all figures and return to the ipython prompt. @@ -141,7 +145,7 @@ def isinteractive(): """ - Return *True* if matplotlib is in interactive mode, *False* otherwise. + Return status of interactive mode. """ return matplotlib.is_interactive() @@ -201,25 +205,25 @@ def gci(): """ - Get the current :class:`~matplotlib.cm.ScalarMappable` instance - (image or patch collection), or *None* if no images or patch - collections have been defined. The commands - :func:`~matplotlib.pyplot.imshow` and - :func:`~matplotlib.pyplot.figimage` create + Get the current colorable artist. Specifically, returns the + current :class:`~matplotlib.cm.ScalarMappable` instance (image or + patch collection), or *None* if no images or patch collections + have been defined. The commands :func:`~matplotlib.pyplot.imshow` + and :func:`~matplotlib.pyplot.figimage` create :class:`~matplotlib.image.Image` instances, and the commands :func:`~matplotlib.pyplot.pcolor` and :func:`~matplotlib.pyplot.scatter` create - :class:`~matplotlib.collections.Collection` instances. - The current image is an attribute of the current axes, or the - nearest earlier axes in the current figure that contains an - image. + :class:`~matplotlib.collections.Collection` instances. The + current image is an attribute of the current axes, or the nearest + earlier axes in the current figure that contains an image. """ return gcf()._gci() def sci(im): """ - Set the current image (target of colormap commands like - :func:`~matplotlib.pyplot.jet`, :func:`~matplotlib.pyplot.hot` or + Set the current image. This image will be the target of colormap + commands like :func:`~matplotlib.pyplot.jet`, + :func:`~matplotlib.pyplot.hot` or :func:`~matplotlib.pyplot.clim`). The current image is an attribute of the current axes. """ @@ -253,11 +257,12 @@ **kwargs ): """ + Create a new figure. + call signature:: figure(num=None, figsize=(8, 6), dpi=80, facecolor='w', edgecolor='k') - Create a new figure and return a :class:`matplotlib.figure.Figure` instance. If *num* = *None*, the figure number will be incremented and a new figure will be created. The returned figure objects have a @@ -308,22 +313,17 @@ if edgecolor is None : edgecolor = rcParams['figure.edgecolor'] allnums = get_fignums() + next_num = max(allnums) + 1 if allnums else 1 figLabel = '' if num is None: - if allnums: - num = max(allnums) + 1 - else: - num = 1 + num = next_num elif is_string_like(num): figLabel = num allLabels = get_figlabels() if figLabel not in allLabels: if figLabel == 'all': warnings.warn("close('all') closes all existing figures") - if len(allLabels): - num = max(allnums) + 1 - else: - num = 1 + num = next_num else: inum = allLabels.index(figLabel) num = allnums[inum] @@ -359,6 +359,7 @@ draw_if_interactive() return figManager.canvas.figure + def gcf(): "Return a reference to the current figure." @@ -399,7 +400,7 @@ def close(*args): """ - Close a figure window + Close a figure window. ``close()`` by itself closes the current figure @@ -438,7 +439,7 @@ def clf(): """ - Clear the current figure + Clear the current figure. """ gcf().clf() draw_if_interactive() @@ -585,13 +586,15 @@ def ishold(): """ - Return the hold status of the current axes + Return the hold status of the current axes. """ return gca().ishold() def over(func, *args, **kwargs): """ - over calls:: + Call a function with hold(True). + + Calls:: func(*args, **kwargs) @@ -608,7 +611,9 @@ def axes(*args, **kwargs): """ - Add an axes at position rect specified by: + Add an axes to the figure. + + The axes is added at position *rect* specified by: - ``axes()`` by itself creates a default full ``subplot(111)`` window axis. @@ -653,7 +658,7 @@ def delaxes(*args): """ - ``delaxes(ax)``: remove *ax* from the current figure. If *ax* + Remove an axes from the current figure. If *ax* doesn't exist, an error will be raised. ``delaxes()``: delete the current axes @@ -668,8 +673,9 @@ def sca(ax): """ - Set the current Axes instance to *ax*. The current Figure - is updated to the parent of *ax*. + Set the current Axes instance to *ax*. + + The current Figure is updated to the parent of *ax*. """ managers = _pylab_helpers.Gcf.get_all_fig_managers() for m in managers: @@ -705,7 +711,9 @@ def subplot(*args, **kwargs): """ - Create a subplot command, creating axes with:: + Create a new axes (subplot). + + Creating axes with:: subplot(numRows, numCols, plotNum) @@ -760,7 +768,15 @@ .. plot:: mpl_examples/pylab_examples/subplot_demo.py """ - + # This check was added because it is very easy to type + # subplot(1, 2, False) when subplots(1, 2, False) was intended + # (sharex=False, that is). In most cases, no error will + # ever occur, but mysterious behavior can result because what was + # intended to be the sharex argument is instead treated as a + # subplot index for subplot() + if len(args) >= 3 and isinstance(args[2], bool) : + warnings.warn("The subplot index argument to subplot() appears" + " to be a boolean. Did you intend to use subplots()?") fig = gcf() a = fig.add_subplot(*args, **kwargs) @@ -792,15 +808,27 @@ *ncols* : int Number of columns of the subplot grid. Defaults to 1. - *sharex* : bool + *sharex* : string or bool If *True*, the X axis will be shared amongst all subplots. If *True* and you have multiple rows, the x tick labels on all but the last row of plots will have visible set to *False* + If a string must be one of "row", "col", "all", or "none". + "all" has the same effect as *True*, "none" has the same effect + as *False*. + If "row", each subplot row will share a X axis. + If "col", each subplot column will share a X axis and the x tick + labels on all but the last row will have visible set to *False*. - *sharey* : bool + *sharey* : string or bool If *True*, the Y axis will be shared amongst all subplots. If *True* and you have multiple columns, the y tick labels on all but the first column of plots will have visible set to *False* + If a string must be one of "row", "col", "all", or "none". + "all" has the same effect as *True*, "none" has the same effect + as *False*. + If "row", each subplot row will share a Y axis. + If "col", each subplot column will share a Y axis and the y tick + labels on all but the last row will have visible set to *False*. *squeeze* : bool If *True*, extra dimensions are squeezed out from the @@ -836,7 +864,7 @@ - *fig* is the :class:`matplotlib.figure.Figure` object - *ax* can be either a single axis object or an array of axis - objects if more than one supblot was created. The dimensions + objects if more than one subplot was created. The dimensions of the resulting array can be controlled with the squeeze keyword, see above. @@ -858,8 +886,45 @@ # Four polar axes plt.subplots(2, 2, subplot_kw=dict(polar=True)) - """ + # Share a X axis with each column of subplots + plt.subplots(2, 2, sharex='col') + + # Share a Y axis with each row of subplots + plt.subplots(2, 2, sharey='row') + + # Share a X and Y axis with all subplots + plt.subplots(2, 2, sharex='all', sharey='all') + # same as + plt.subplots(2, 2, sharex=True, sharey=True) + """ + # for backwards compatability + if isinstance(sharex, bool): + if sharex: + sharex = "all" + else: + sharex = "none" + if isinstance(sharey, bool): + if sharey: + sharey = "all" + else: + sharey = "none" + share_values = ["all", "row", "col", "none"] + if sharex not in share_values: + # This check was added because it is very easy to type subplots(1, 2, 1) + # when subplot(1, 2, 1) was intended. In most cases, no error will + # ever occur, but mysterious behavior will result because what was + # intended to be the subplot index is instead treated as a bool for + # sharex. + if isinstance(sharex, int): + warnings.warn("sharex argument to subplots() was an integer." + " Did you intend to use subplot() (without 's')?") + + raise ValueError("sharex [%s] must be one of %s" % \ + (sharex, share_values)) + if sharey not in share_values: + raise ValueError("sharey [%s] must be one of %s" % \ + (sharey, share_values)) if subplot_kw is None: subplot_kw = {} @@ -872,36 +937,56 @@ # Create first subplot separately, so we can share it if requested ax0 = fig.add_subplot(nrows, ncols, 1, **subplot_kw) - if sharex: - subplot_kw['sharex'] = ax0 - if sharey: - subplot_kw['sharey'] = ax0 + #if sharex: + # subplot_kw['sharex'] = ax0 + #if sharey: + # subplot_kw['sharey'] = ax0 axarr[0] = ax0 + r, c = np.mgrid[:nrows, :ncols] + r = r.flatten() * ncols + c = c.flatten() + lookup = { + "none": np.arange(nplots), + "all": np.zeros(nplots, dtype=int), + "row": r, + "col": c, + } + sxs = lookup[sharex] + sys = lookup[sharey] + # Note off-by-one counting because add_subplot uses the MATLAB 1-based # convention. for i in range(1, nplots): - axarr[i] = fig.add_subplot(nrows, ncols, i+1, **subplot_kw) - - + if sxs[i] == i: + subplot_kw['sharex'] = None + else: + subplot_kw['sharex'] = axarr[sxs[i]] + if sys[i] == i: + subplot_kw['sharey'] = None + else: + subplot_kw['sharey'] = axarr[sys[i]] + axarr[i] = fig.add_subplot(nrows, ncols, i + 1, **subplot_kw) # returned axis array will be always 2-d, even if nrows=ncols=1 axarr = axarr.reshape(nrows, ncols) - # turn off redundant tick labeling - if sharex and nrows>1: + if sharex in ["col", "all"] and nrows > 1: + #if sharex and nrows>1: # turn off all but the bottom row - for ax in axarr[:-1,:].flat: + for ax in axarr[:-1, :].flat: for label in ax.get_xticklabels(): label.set_visible(False) + ax.xaxis.offsetText.set_visible(False) - - if sharey and ncols>1: + if sharey in ["row", "all"] and ncols > 1: + #if sharey and ncols>1: # turn off all but the first column - for ax in axarr[:,1:].flat: + for ax in axarr[:, 1:].flat: for label in ax.get_yticklabels(): label.set_visible(False) + ax.yaxis.offsetText.set_visible(False) if squeeze: # Reshape the array to have the final desired dimension (nrow,ncol), @@ -921,10 +1006,9 @@ from gridspec import GridSpec def subplot2grid(shape, loc, rowspan=1, colspan=1, **kwargs): """ - - It creates a subplot in a grid of *shape*, at location of *loc*, - spanning *rowspan*, *colspan* cells in each direction. - The index for loc is 0-based. :: + Create a subplot in a grid. The grid is specified by *shape*, at + location of *loc*, spanning *rowspan*, *colspan* cells in each + direction. The index for loc is 0-based. :: subplot2grid(shape, loc, rowspan=1, colspan=1) @@ -933,8 +1017,6 @@ gridspec=GridSpec(shape[0], shape[2]) subplotspec=gridspec.new_subplotspec(loc, rowspan, colspan) subplot(subplotspec) - - """ fig = gcf() @@ -957,9 +1039,10 @@ def twinx(ax=None): """ - Make a second axes overlay *ax* (or the current axes if *ax* is - *None*) sharing the xaxis. The ticks for *ax2* will be placed on - the right, and the *ax2* instance is returned. + Make a second axes that shares the *x*-axis. The new axes will + overlay *ax* (or the current axes if *ax* is *None*). The ticks + for *ax2* will be placed on the right, and the *ax2* instance is + returned. .. seealso:: @@ -975,9 +1058,10 @@ def twiny(ax=None): """ - Make a second axes overlay *ax* (or the current axes if *ax* is - *None*) sharing the yaxis. The ticks for *ax2* will be placed on - the top, and the *ax2* instance is returned. + Make a second axes that shares the *y*-axis. The new axis will + overlay *ax* (or the current axes if *ax* is *None*). The ticks + for *ax2* will be placed on the top, and the *ax2* instance is + returned. """ if ax is None: ax=gca() @@ -989,14 +1073,14 @@ def subplots_adjust(*args, **kwargs): """ + Tune the subplot layout. + call signature:: subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None) - Tune the subplot layout via the - :class:`matplotlib.figure.SubplotParams` mechanism. The parameter - meanings (and suggested defaults) are:: + The parameter meanings (and suggested defaults) are:: left = 0.125 # the left side of the subplots of the figure right = 0.9 # the right side of the subplots of the figure @@ -1014,7 +1098,7 @@ def subplot_tool(targetfig=None): """ - Launch a subplot tool window for *targetfig* (default gcf). + Launch a subplot tool window for a figure. A :class:`matplotlib.widgets.SubplotTool` instance is returned. """ @@ -1038,9 +1122,9 @@ -def tight_layout(pad=1.2, h_pad=None, w_pad=None): +def tight_layout(pad=1.08, h_pad=None, w_pad=None, rect=None): """ - Adjust subplot parameters to give specified padding. + Automatically adjust subplot parameters to give specified padding. Parameters: @@ -1049,18 +1133,22 @@ h_pad, w_pad : float padding (height/width) between edges of adjacent subplots. Defaults to `pad_inches`. + rect : if rect is given, it is interpreted as a rectangle + (left, bottom, right, top) in the normalized figure + coordinate that the whole subplots area (including + labels) will fit into. Default is (0, 0, 1, 1). """ fig = gcf() - fig.tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad) + fig.tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect) draw_if_interactive() def box(on=None): """ - Turn the axes box on or off according to *on*. - *on* may be a boolean or a string, 'on' or 'off'. + Turn the axes box on or off. *on* may be a boolean or a string, + 'on' or 'off'. If *on* is *None*, toggle state. """ @@ -1073,7 +1161,7 @@ def title(s, *args, **kwargs): """ - Set the title of the current axis to *s*. + Set the title of the current axis. Default font override is:: @@ -1097,45 +1185,45 @@ def axis(*v, **kwargs): """ - Set/Get the axis properties: + Set or get the axis properties.:: >>> axis() - returns the current axes limits ``[xmin, xmax, ymin, ymax]``. + returns the current axes limits ``[xmin, xmax, ymin, ymax]``.:: >>> axis(v) sets the min and max of the x and y axes, with - ``v = [xmin, xmax, ymin, ymax]``. + ``v = [xmin, xmax, ymin, ymax]``.:: >>> axis('off') - turns off the axis lines and labels. + turns off the axis lines and labels.:: >>> axis('equal') changes limits of *x* or *y* axis so that equal increments of *x* - and *y* have the same length; a circle is circular. + and *y* have the same length; a circle is circular.:: >>> axis('scaled') achieves the same result by changing the dimensions of the plot box instead - of the axis data limits. + of the axis data limits.:: >>> axis('tight') changes *x* and *y* axis limits such that all data is shown. If all data is already shown, it will move it to the center of the figure without modifying (*xmax* - *xmin*) or (*ymax* - - *ymin*). Note this is slightly different than in MATLAB. + *ymin*). Note this is slightly different than in MATLAB.:: >>> axis('image') - is 'scaled' with the axis limits equal to the data limits. + is 'scaled' with the axis limits equal to the data limits.:: >>> axis('auto') - and + and:: >>> axis('normal') @@ -1160,7 +1248,7 @@ def xlabel(s, *args, **kwargs): """ - Set the *x* axis label of the current axis to *s* + Set the *x* axis label of the current axis. Default override is:: @@ -1181,7 +1269,7 @@ def ylabel(s, *args, **kwargs): """ - Set the *y* axis label of the current axis to *s*. + Set the *y* axis label of the current axis. Defaults override is:: @@ -1207,7 +1295,9 @@ def xlim(*args, **kwargs): """ - Set/Get the xlimits of the current axes:: + Get or set the *x* limits of the current axes. + + :: xmin, xmax = xlim() # return the current xlim xlim( (xmin, xmax) ) # set the xlim to xmin, xmax @@ -1234,7 +1324,9 @@ def ylim(*args, **kwargs): """ - Set/Get the ylimits of the current axes:: + Get or set the *y*-limits of the current axes. + + :: ymin, ymax = ylim() # return the current ylim ylim( (ymin, ymax) ) # set the ylim to ymin, ymax @@ -1261,11 +1353,13 @@ @docstring.dedent_interpd def xscale(*args, **kwargs): """ + Set the scaling of the *x*-axis. + call signature:: xscale(scale, **kwargs) - Set the scaling for the x-axis: %(scale)s + The available scales are: %(scale)s Different keywords may be accepted, depending on the scale: @@ -1278,11 +1372,13 @@ @docstring.dedent_interpd def yscale(*args, **kwargs): """ + Set the scaling of the *y*-axis. + call signature:: yscale(scale, **kwargs) - Set the scaling for the y-axis: %(scale)s + The available scales are: %(scale)s Different keywords may be accepted, depending on the scale: @@ -1294,7 +1390,9 @@ def xticks(*args, **kwargs): """ - Set/Get the xlimits of the current ticklocs and labels:: + Get or set the *x*-limits of the current tick locations and labels. + + :: # return locs, labels where locs is an array of tick locations and # labels is an array of tick labels. @@ -1332,7 +1430,9 @@ def yticks(*args, **kwargs): """ - Set/Get the ylimits of the current ticklocs and labels:: + Get or set the *y*-limits of the current tick locations and labels. + + :: # return locs, labels where locs is an array of tick locations and # labels is an array of tick labels. @@ -1390,8 +1490,7 @@ def rgrids(*args, **kwargs): """ - Set/Get the radial locations of the gridlines and ticklabels on a - polar plot. + Get or set the radial gridlines on a polar plot. call signatures:: @@ -1435,7 +1534,7 @@ def thetagrids(*args, **kwargs): """ - Set/Get the theta locations of the gridlines and ticklabels. + Get or set the theta locations of the gridlines in a polar plot. If no arguments are passed, return a tuple (*lines*, *labels*) where *lines* is an array of radial gridlines @@ -1498,100 +1597,36 @@ ## Plotting Info ## def plotting(): - """ - Plotting commands - - =============== ========================================================= - Command Description - =============== ========================================================= - axes Create a new axes - axis Set or return the current axis limits - bar make a bar chart - boxplot make a box and whiskers chart - cla clear current axes - clabel label a contour plot - clf clear a figure window - close close a figure window - colorbar add a colorbar to the current figure - cohere make a plot of coherence - contour make a contour plot - contourf make a filled contour plot - csd make a plot of cross spectral density - draw force a redraw of the current figure - errorbar make an errorbar graph - figlegend add a legend to the figure - figimage add an image to the figure, w/o resampling - figtext add text in figure coords - figure create or change active figure - fill make filled polygons - fill_between make filled polygons between two sets of y-values - fill_betweenx make filled polygons between two sets of x-values - gca return the current axes - gcf return the current figure - gci get the current image, or None - getp get a graphics property - hist make a histogram - hold set the hold state on current axes - legend add a legend to the axes - loglog a log log plot - imread load image file into array - imsave save array as an image file - imshow plot image data - matshow display a matrix in a new figure preserving aspect - pcolor make a pseudocolor plot - plot make a line plot - plotfile plot data from a flat file - psd make a plot of power spectral density - quiver make a direction field (arrows) plot - rc control the default params - savefig save the current figure - scatter make a scatter plot - setp set a graphics property - semilogx log x axis - semilogy log y axis - show in non-interactive mode, display all figures and block - until they have been closed; in interactive mode, - show generally has no effect. - specgram a spectrogram plot - stem make a stem plot - subplot make a subplot (numrows, numcols, axesnum) - table add a table to the axes - text add some text at location x,y to the current axes - title add a title to the current axes - xlabel add an xlabel to the current axes - ylabel add a ylabel to the current axes - =============== ========================================================= - - The following commands will set the default colormap accordingly: - - * autumn - * bone - * cool - * copper - * flag - * gray - * hot - * hsv - * jet - * pink - * prism - * spring - * summer - * winter - * spectral - - """ pass -def get_plot_commands(): return ( 'axes', 'axis', 'bar', 'boxplot', 'cla', 'clf', - 'close', 'colorbar', 'cohere', 'csd', 'draw', 'errorbar', - 'figlegend', 'figtext', 'figimage', 'figure', 'fill', 'gca', - 'gcf', 'gci', 'get', 'gray', 'barh', 'jet', 'hist', 'hold', 'imread', 'imsave', - 'imshow', 'legend', 'loglog', 'quiver', 'rc', 'pcolor', 'pcolormesh', 'plot', 'psd', - 'savefig', 'scatter', 'set', 'semilogx', 'semilogy', 'show', - 'specgram', 'stem', 'subplot', 'table', 'text', 'title', 'xlabel', - 'ylabel', 'pie', 'polar') +def get_plot_commands(): + """ + Get a sorted list of all of the plotting commands. + """ + # This works by searching for all functions in this module and + # removing a few hard-coded exclusions, as well as all of the + # colormap-setting functions, and anything marked as private with + # a preceding underscore. + + import inspect + + exclude = set(['colormaps', 'colors', 'connect', 'disconnect', + 'get_plot_commands', 'get_current_fig_manager', + 'ginput', 'plotting', 'waitforbuttonpress']) + exclude |= set(colormaps()) + this_module = inspect.getmodule(get_plot_commands) + + commands = set() + for name, obj in globals().items(): + if name.startswith('_') or name in exclude: + continue + if inspect.isfunction(obj) and inspect.getmodule(obj) is this_module: + commands.add(name) + + commands = list(commands) + commands.sort() + return commands def colors(): """ @@ -1645,40 +1680,284 @@ def colormaps(): """ - matplotlib provides the following colormaps. - - * autumn - * bone - * cool - * copper - * flag - * gray - * hot - * hsv - * jet - * pink - * prism - * spring - * summer - * winter - * spectral + Matplotlib provides a number of colormaps, and others can be added using + :func:`register_cmap`. This function documents the built-in colormaps, + and will also return a list of all registered colormaps if called. You can set the colormap for an image, pcolor, scatter, etc, - either as a keyword argument:: + using a keyword argument:: imshow(X, cmap=cm.hot) - or post-hoc using the corresponding pylab interface function:: + or using the :func:`set_cmap` function:: + + imshow(X) + pyplot.set_cmap('hot') + pyplot.set_cmap('jet') + + In interactive mode, :func:`set_cmap` will update the colormap post-hoc, + allowing you to see which one works best for your data. + + All built-in colormaps can be reversed by appending ``_r``: For instance, + ``gray_r`` is the reverse of ``gray``. + + There are several common color schemes used in visualization: + + Sequential schemes + for unipolar data that progresses from low to high + Diverging schemes + for bipolar data that emphasizes positive or negative deviations from a + central value + Cyclic schemes + meant for plotting values that wrap around at the + endpoints, such as phase angle, wind direction, or time of day + Qualitative schemes + for nominal data that has no inherent ordering, where color is used + only to distinguish categories + + The base colormaps are (with the exception of `spectral`) derived from + those of the same name provided with Matlab: + + ========= ======================================================= + Colormap Description + ========= ======================================================= + autumn sequential linearly-increasing shades of red-orange-yellow + bone sequential increasing black-white color map with + a tinge of blue, to emulate X-ray film + cool linearly-decreasing shades of cyan-magenta + copper sequential increasing shades of black-copper + flag repetitive red-white-blue-black pattern (not cyclic at + endpoints) + gray sequential linearly-increasing black-to-white + grayscale + hot sequential black-red-yellow-white, to emulate blackbody + radiation from an object at increasing temperatures + hsv cyclic red-yellow-green-cyan-blue-magenta-red, formed + by changing the hue component in the HSV color space + jet a spectral map with dark endpoints, blue-cyan-yellow-red; + based on a fluid-jet simulation by NCSA [#]_ + pink sequential increasing pastel black-pink-white, meant + for sepia tone colorization of photographs + prism repetitive red-yellow-green-blue-purple-...-green pattern + (not cyclic at endpoints) + spring linearly-increasing shades of magenta-yellow + summer sequential linearly-increasing shades of green-yellow + winter linearly-increasing shades of blue-green + spectral black-purple-blue-green-yellow-red-white spectrum + ========= ======================================================= + + For the above list only, you can also set the colormap using the + corresponding pylab shortcut interface function, similar to Matlab:: imshow(X) hot() jet() - In interactive mode, this will update the colormap allowing you to - see which one works best for your data. - """ - pass + The next set of palettes are from the `Yorick scientific visualisation + package `_, an evolution of + the GIST package, both by David H. Munro: + + ============ ======================================================= + Colormap Description + ============ ======================================================= + gist_earth mapmaker's colors from dark blue deep ocean to green + lowlands to brown highlands to white mountains + gist_heat sequential increasing black-red-orange-white, to emulate + blackbody radiation from an iron bar as it grows hotter + gist_ncar pseudo-spectral black-blue-green-yellow-red-purple-white + colormap from National Center for Atmospheric + Research [#]_ + gist_rainbow runs through the colors in spectral order from red to + violet at full saturation (like *hsv* but not cyclic) + gist_stern "Stern special" color table from Interactive Data + Language software + ============ ======================================================= + + The following colormaps are based on the `ColorBrewer + `_ color specifications and designs developed by + Cynthia Brewer: + + ColorBrewer Diverging (luminance is highest at the midpoint, and + decreases towards differently-colored endpoints): + + ======== =================================== + Colormap Description + ======== =================================== + BrBG brown, white, blue-green + PiYG pink, white, yellow-green + PRGn purple, white, green + PuOr orange, white, purple + RdBu red, white, blue + RdGy red, white, gray + RdYlBu red, yellow, blue + RdYlGn red, yellow, green + Spectral red, orange, yellow, green, blue + ======== =================================== + + ColorBrewer Sequential (luminance decreases monotonically): + + ======== ==================================== + Colormap Description + ======== ==================================== + Blues white to dark blue + BuGn white, light blue, dark green + BuPu white, light blue, dark purple + GnBu white, light green, dark blue + Greens white to dark green + Greys white to black (not linear) + Oranges white, orange, dark brown + OrRd white, orange, dark red + PuBu white, light purple, dark blue + PuBuGn white, light purple, dark green + PuRd white, light purple, dark red + Purples white to dark purple + RdPu white, pink, dark purple + Reds white to dark red + YlGn light yellow, dark green + YlGnBu light yellow, light green, dark blue + YlOrBr light yellow, orange, dark brown + YlOrRd light yellow, orange, dark red + ======== ==================================== + + ColorBrewer Qualitative: + + (For plotting nominal data, :class:`ListedColormap` should be used, + not :class:`LinearSegmentedColormap`. Different sets of colors are + recommended for different numbers of categories. These continuous + versions of the qualitative schemes may be removed or converted in the + future.) + + * Accent + * Dark2 + * Paired + * Pastel1 + * Pastel2 + * Set1 + * Set2 + * Set3 + + Other miscellaneous schemes: + + ========= ======================================================= + Colormap Description + ========= ======================================================= + afmhot sequential black-orange-yellow-white blackbody + spectrum, commonly used in atomic force microscopy + brg blue-red-green + bwr diverging blue-white-red + coolwarm diverging blue-gray-red, meant to avoid issues with 3D + shading, color blindness, and ordering of colors [#]_ + CMRmap "Default colormaps on color images often reproduce to + confusing grayscale images. The proposed colormap + maintains an aesthetically pleasing color image that + automatically reproduces to a monotonic grayscale with + discrete, quantifiable saturation levels." [#]_ + cubehelix Unlike most other color schemes cubehelix was designed + by D.A. Green to be monotonically increasing in terms + of perceived brightness. Also, when printed on a black + and white postscript printer, the scheme results in a + greyscale with monotonically increasing brightness. + This color scheme is named cubehelix because the r,g,b + values produced can be visualised as a squashed helix + around the diagonal in the r,g,b color cube. + gnuplot gnuplot's traditional pm3d scheme + (black-blue-red-yellow) + gnuplot2 sequential color printable as gray + (black-blue-violet-yellow-white) + ocean green-blue-white + rainbow spectral purple-blue-green-yellow-orange-red colormap + with diverging luminance + seismic diverging blue-white-red + terrain mapmaker's colors, blue-green-yellow-brown-white, + originally from IGOR Pro + ========= ======================================================= + + The following colormaps are redundant and may be removed in future + versions. It's recommended to use *gray* or *gray_r* instead, which + produce identical output: + + ========= ======================================================= + Colormap Description + ========= ======================================================= + gist_gray identical to *gray* + gist_yarg identical to *gray_r* + binary identical to *gray_r* + ========= ======================================================= + + .. rubric:: Footnotes + + .. [#] Rainbow colormaps, ``jet`` in particular, are considered a poor + choice for scientific visualization by many researchers: `Rainbow Color + Map (Still) Considered Harmful + `_ + + .. [#] Resembles "BkBlAqGrYeOrReViWh200" from NCAR Command + Language. See `Color Table Gallery + `_ + + .. [#] See `Diverging Color Maps for Scientific Visualization + `_ by Kenneth + Moreland. + + .. [#] See `A Color Map for Effective Black-and-White Rendering of + Color-Scale Images + `_ + by Carey Rappaport + + """ + return sorted(cm.cmap_d.keys()) + + +def _setup_pyplot_info_docstrings(): + """ + Generates the plotting and docstring. + + These must be done after the entire module is imported, so it is + called from the end of this module, which is generated by + boilerplate.py. + """ + # Generate the plotting docstring + import re + + def pad(s, l): + """Pad string *s* to length *l*.""" + if l < len(s): + return s[:l] + return s + ' ' * (l - len(s)) + + commands = get_plot_commands() + + first_sentence = re.compile("(?:\s*).+?\.(?:\s+|$)", flags=re.DOTALL) + + # Collect the first sentence of the docstring for all of the + # plotting commands. + rows = [] + max_name = 0 + max_summary = 0 + for name in commands: + doc = globals()[name].__doc__ + summary = '' + if doc is not None: + match = first_sentence.match(doc) + if match is not None: + summary = match.group(0).strip().replace('\n', ' ') + name = '`%s`' % name + rows.append([name, summary]) + max_name = max(max_name, len(name)) + max_summary = max(max_summary, len(summary)) + + lines = [] + sep = '=' * max_name + ' ' + '=' * max_summary + lines.append(sep) + lines.append(' '.join([pad("Function", max_name), + pad("Description", max_summary)])) + lines.append(sep) + for name, summary in rows: + lines.append(' '.join([pad(name, max_name), + pad(summary, max_summary)])) + lines.append(sep) + plotting.__doc__ = '\n'.join(lines) ## Plotting part 1: manually generated functions and wrappers ## @@ -1687,7 +1966,10 @@ if mappable is None: mappable = gci() if mappable is None: - raise RuntimeError('You must first define an image, eg with imshow') + raise RuntimeError('No mappable was found to use for colorbar ' + 'creation. First define a mappable such as ' + 'an image (with imshow) or a contour set (' + 'with contourf).') if ax is None: ax = gca() @@ -1698,7 +1980,7 @@ def clim(vmin=None, vmax=None): """ - Set the color limits of the current image + Set the color limits of the current image. To apply clim to all axes images do:: @@ -1723,7 +2005,7 @@ def set_cmap(cmap): ''' - set the default colormap to *cmap* and apply to current image if any. + Set the default colormap. Applies to the current image if any. See help(colormaps) for more information. *cmap* must be a :class:`colors.Colormap` instance, or @@ -1795,19 +2077,17 @@ def polar(*args, **kwargs): """ + Make a polar plot. + call signature:: polar(theta, r, **kwargs) - Make a polar plot. Multiple *theta*, *r* arguments are supported, - with format strings, as in :func:`~matplotlib.pyplot.plot`. + Multiple *theta*, *r* arguments are supported, with format + strings, as in :func:`~matplotlib.pyplot.plot`. - An optional kwarg *resolution* sets the number of vertices to - interpolate between each pair of points. The default is 1, - which disables interpolation. """ - resolution = kwargs.pop('resolution', None) - ax = gca(polar=True, resolution=resolution) + ax = gca(polar=True) ret = ax.plot(*args, **kwargs) draw_if_interactive() return ret @@ -1817,7 +2097,7 @@ subplots=True, newfig=True, **kwargs): """ - Plot the data in *fname* + Plot the data in in a file. *cols* is a sequence of column identifiers to plot. An identifier is either an int or a string. If it is an int, it indicates the @@ -1936,18 +2216,16 @@ draw_if_interactive() - -def autogen_docstring(base): +def _autogen_docstring(base): """Autogenerated wrappers will get their docstring from a base function with an addendum.""" msg = "\n\nAdditional kwargs: hold = [True|False] overrides default hold state" addendum = docstring.Appender(msg, '\n\n') return lambda func: addendum(docstring.copy_dedent(base)(func)) - # This function cannot be generated by boilerplate.py because it may # return an image or a line. -@autogen_docstring(Axes.spy) +@_autogen_docstring(Axes.spy) def spy(Z, precision=0, marker=None, markersize=None, aspect='equal', hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -1965,11 +2243,12 @@ return ret -## Plotting part 2: autogenerated wrappers for axes methods ## +################# 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) +@_autogen_docstring(Axes.acorr) def acorr(x, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -1987,7 +2266,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.arrow) +@_autogen_docstring(Axes.arrow) def arrow(x, y, dx, dy, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2005,7 +2284,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.axhline) +@_autogen_docstring(Axes.axhline) 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 @@ -2014,7 +2293,7 @@ if hold is not None: ax.hold(hold) try: - ret = ax.axhline(y, xmin, xmax, **kwargs) + ret = ax.axhline(y=y, xmin=xmin, xmax=xmax, **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2023,7 +2302,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.axhspan) +@_autogen_docstring(Axes.axhspan) 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 @@ -2032,7 +2311,7 @@ if hold is not None: ax.hold(hold) try: - ret = ax.axhspan(ymin, ymax, xmin, xmax, **kwargs) + ret = ax.axhspan(ymin, ymax, xmin=xmin, xmax=xmax, **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2041,7 +2320,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.axvline) +@_autogen_docstring(Axes.axvline) 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 @@ -2050,7 +2329,7 @@ if hold is not None: ax.hold(hold) try: - ret = ax.axvline(x, ymin, ymax, **kwargs) + ret = ax.axvline(x=x, ymin=ymin, ymax=ymax, **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2059,7 +2338,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.axvspan) +@_autogen_docstring(Axes.axvspan) 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 @@ -2068,7 +2347,7 @@ if hold is not None: ax.hold(hold) try: - ret = ax.axvspan(xmin, xmax, ymin, ymax, **kwargs) + ret = ax.axvspan(xmin, xmax, ymin=ymin, ymax=ymax, **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2077,8 +2356,8 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.bar) -def bar(left, height, width=0.80000000000000004, bottom=None, hold=None, **kwargs): +@_autogen_docstring(Axes.bar) +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() @@ -2086,7 +2365,7 @@ if hold is not None: ax.hold(hold) try: - ret = ax.bar(left, height, width, bottom, **kwargs) + ret = ax.bar(left, height, width=width, bottom=bottom, **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2095,8 +2374,8 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.barh) -def barh(bottom, width, height=0.80000000000000004, left=None, hold=None, **kwargs): +@_autogen_docstring(Axes.barh) +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() @@ -2104,7 +2383,7 @@ if hold is not None: ax.hold(hold) try: - ret = ax.barh(bottom, width, height, left, **kwargs) + ret = ax.barh(bottom, width, height=height, left=left, **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2113,7 +2392,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.broken_barh) +@_autogen_docstring(Axes.broken_barh) def broken_barh(xranges, yrange, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2131,8 +2410,10 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.boxplot) -def boxplot(x, notch=0, sym='b+', vert=1, whis=1.5, positions=None, widths=None, patch_artist=False, bootstrap=None, hold=None): +@_autogen_docstring(Axes.boxplot) +def boxplot(x, notch=False, sym='b+', vert=True, whis=1.5, positions=None, + widths=None, patch_artist=False, bootstrap=None, usermedians=None, + conf_intervals=None, hold=None): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() @@ -2140,7 +2421,10 @@ if hold is not None: ax.hold(hold) try: - ret = ax.boxplot(x, notch, sym, vert, whis, positions, widths, patch_artist, bootstrap) + ret = ax.boxplot(x, notch=notch, sym=sym, vert=vert, whis=whis, + positions=positions, widths=widths, + patch_artist=patch_artist, bootstrap=bootstrap, + usermedians=usermedians, conf_intervals=conf_intervals) draw_if_interactive() finally: ax.hold(washold) @@ -2149,8 +2433,10 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.cohere) -def cohere(x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, window=mlab.window_hanning, noverlap=0, pad_to=None, sides='default', scale_by_freq=None, hold=None, **kwargs): +@_autogen_docstring(Axes.cohere) +def cohere(x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, + window=mlab.window_hanning, noverlap=0, pad_to=None, sides='default', + scale_by_freq=None, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() @@ -2158,7 +2444,9 @@ if hold is not None: ax.hold(hold) try: - ret = ax.cohere(x, y, NFFT, Fs, Fc, detrend, window, noverlap, pad_to, sides, scale_by_freq, **kwargs) + ret = ax.cohere(x, y, NFFT=NFFT, Fs=Fs, Fc=Fc, detrend=detrend, + window=window, noverlap=noverlap, pad_to=pad_to, + sides=sides, scale_by_freq=scale_by_freq, **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2167,7 +2455,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.clabel) +@_autogen_docstring(Axes.clabel) def clabel(CS, *args, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2185,7 +2473,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.contour) +@_autogen_docstring(Axes.contour) def contour(*args, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2203,7 +2491,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.contourf) +@_autogen_docstring(Axes.contourf) def contourf(*args, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2221,8 +2509,10 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.csd) -def csd(x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, window=mlab.window_hanning, noverlap=0, pad_to=None, sides='default', scale_by_freq=None, hold=None, **kwargs): +@_autogen_docstring(Axes.csd) +def csd(x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, + window=mlab.window_hanning, noverlap=0, pad_to=None, sides='default', + scale_by_freq=None, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() @@ -2230,7 +2520,9 @@ if hold is not None: ax.hold(hold) try: - ret = ax.csd(x, y, NFFT, Fs, Fc, detrend, window, noverlap, pad_to, sides, scale_by_freq, **kwargs) + ret = ax.csd(x, y, NFFT=NFFT, Fs=Fs, Fc=Fc, detrend=detrend, + window=window, noverlap=noverlap, pad_to=pad_to, + sides=sides, scale_by_freq=scale_by_freq, **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2239,8 +2531,11 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.errorbar) -def errorbar(x, y, yerr=None, xerr=None, fmt='-', ecolor=None, elinewidth=None, capsize=3, barsabove=False, lolims=False, uplims=False, xlolims=False, xuplims=False, hold=None, **kwargs): +@_autogen_docstring(Axes.errorbar) +def errorbar(x, y, yerr=None, xerr=None, fmt='-', ecolor=None, elinewidth=None, + capsize=3, barsabove=False, lolims=False, uplims=False, + xlolims=False, xuplims=False, errorevery=1, capthick=None, + hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() @@ -2248,7 +2543,11 @@ if hold is not None: ax.hold(hold) try: - ret = ax.errorbar(x, y, yerr, xerr, fmt, ecolor, elinewidth, capsize, barsabove, lolims, uplims, xlolims, xuplims, **kwargs) + ret = ax.errorbar(x, y, yerr=yerr, xerr=xerr, fmt=fmt, ecolor=ecolor, + elinewidth=elinewidth, capsize=capsize, + barsabove=barsabove, lolims=lolims, uplims=uplims, + xlolims=xlolims, xuplims=xuplims, + errorevery=errorevery, capthick=capthick, **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2257,7 +2556,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.fill) +@_autogen_docstring(Axes.fill) def fill(*args, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2275,7 +2574,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.fill_between) +@_autogen_docstring(Axes.fill_between) 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 @@ -2284,7 +2583,8 @@ if hold is not None: ax.hold(hold) try: - ret = ax.fill_between(x, y1, y2, where, interpolate, **kwargs) + ret = ax.fill_between(x, y1, y2=y2, where=where, + interpolate=interpolate, **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2293,7 +2593,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.fill_betweenx) +@_autogen_docstring(Axes.fill_betweenx) 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 @@ -2302,7 +2602,7 @@ if hold is not None: ax.hold(hold) try: - ret = ax.fill_betweenx(y, x1, x2, where, **kwargs) + ret = ax.fill_betweenx(y, x1, x2=x2, where=where, **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2311,8 +2611,12 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.hexbin) -def hexbin(x, y, C=None, gridsize=100, bins=None, xscale='linear', yscale='linear', extent=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, edgecolors='none', reduce_C_function=np.mean, mincnt=None, marginals=False, hold=None, **kwargs): +@_autogen_docstring(Axes.hexbin) +def hexbin(x, y, C=None, gridsize=100, bins=None, xscale='linear', + yscale='linear', extent=None, cmap=None, norm=None, vmin=None, + vmax=None, alpha=None, linewidths=None, edgecolors='none', + reduce_C_function=np.mean, mincnt=None, marginals=False, hold=None, + **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() @@ -2320,7 +2624,12 @@ if hold is not None: ax.hold(hold) try: - ret = ax.hexbin(x, y, C, gridsize, bins, xscale, yscale, extent, cmap, norm, vmin, vmax, alpha, linewidths, edgecolors, reduce_C_function, mincnt, marginals, **kwargs) + ret = ax.hexbin(x, y, C=C, gridsize=gridsize, bins=bins, xscale=xscale, + yscale=yscale, extent=extent, cmap=cmap, norm=norm, + vmin=vmin, vmax=vmax, alpha=alpha, + linewidths=linewidths, edgecolors=edgecolors, + reduce_C_function=reduce_C_function, mincnt=mincnt, + marginals=marginals, **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2329,8 +2638,11 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.hist) -def hist(x, bins=10, range=None, normed=False, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, color=None, label=None, hold=None, **kwargs): +@_autogen_docstring(Axes.hist) +def hist(x, bins=10, range=None, normed=False, weights=None, cumulative=False, + bottom=None, histtype='bar', align='mid', orientation='vertical', + rwidth=None, log=False, color=None, label=None, stacked=False, + hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() @@ -2338,7 +2650,11 @@ if hold is not None: ax.hold(hold) try: - ret = ax.hist(x, bins, range, normed, weights, cumulative, bottom, histtype, align, orientation, rwidth, log, color, label, **kwargs) + ret = ax.hist(x, bins=bins, range=range, normed=normed, + weights=weights, cumulative=cumulative, bottom=bottom, + histtype=histtype, align=align, orientation=orientation, + rwidth=rwidth, log=log, color=color, label=label, + stacked=stacked, **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2347,8 +2663,29 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.hlines) -def hlines(y, xmin, xmax, colors='k', linestyles='solid', label='', hold=None, **kwargs): +@_autogen_docstring(Axes.hist2d) +def hist2d(x, y, bins=10, range=None, normed=False, weights=None, cmin=None, + cmax=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: + ret = ax.hist2d(x, y, bins=bins, range=range, normed=normed, + weights=weights, cmin=cmin, cmax=cmax, **kwargs) + draw_if_interactive() + finally: + ax.hold(washold) + sci(ret[-1]) + return ret + +# This function was autogenerated by boilerplate.py. Do not edit as +# changes will be lost +@_autogen_docstring(Axes.hlines) +def hlines(y, xmin, xmax, colors='k', linestyles='solid', label='', hold=None, + **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() @@ -2356,7 +2693,8 @@ if hold is not None: ax.hold(hold) try: - ret = ax.hlines(y, xmin, xmax, colors, linestyles, label, **kwargs) + ret = ax.hlines(y, xmin, xmax, colors=colors, linestyles=linestyles, + label=label, **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2365,8 +2703,11 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.imshow) -def imshow(X, cmap=None, norm=None, aspect=None, interpolation=None, alpha=None, vmin=None, vmax=None, origin=None, extent=None, shape=None, filternorm=1, filterrad=4.0, imlim=None, resample=None, url=None, hold=None, **kwargs): +@_autogen_docstring(Axes.imshow) +def imshow(X, cmap=None, norm=None, aspect=None, interpolation=None, alpha=None, + vmin=None, vmax=None, origin=None, extent=None, shape=None, + filternorm=1, filterrad=4.0, imlim=None, resample=None, url=None, + hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() @@ -2374,7 +2715,11 @@ if hold is not None: ax.hold(hold) try: - ret = ax.imshow(X, cmap, norm, aspect, interpolation, alpha, vmin, vmax, origin, extent, shape, filternorm, filterrad, imlim, resample, url, **kwargs) + ret = ax.imshow(X, cmap=cmap, norm=norm, aspect=aspect, + interpolation=interpolation, alpha=alpha, vmin=vmin, + vmax=vmax, origin=origin, extent=extent, shape=shape, + filternorm=filternorm, filterrad=filterrad, + imlim=imlim, resample=resample, url=url, **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2383,7 +2728,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.loglog) +@_autogen_docstring(Axes.loglog) def loglog(*args, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2401,7 +2746,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.pcolor) +@_autogen_docstring(Axes.pcolor) def pcolor(*args, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2419,7 +2764,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.pcolormesh) +@_autogen_docstring(Axes.pcolormesh) def pcolormesh(*args, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2437,8 +2782,10 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.pie) -def pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.59999999999999998, shadow=False, labeldistance=1.1000000000000001, hold=None): +@_autogen_docstring(Axes.pie) +def pie(x, explode=None, labels=None, colors=None, autopct=None, + pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=None, + radius=None, hold=None): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() @@ -2446,7 +2793,10 @@ if hold is not None: ax.hold(hold) try: - ret = ax.pie(x, explode, labels, colors, autopct, pctdistance, shadow, labeldistance) + ret = ax.pie(x, explode=explode, labels=labels, colors=colors, + autopct=autopct, pctdistance=pctdistance, shadow=shadow, + labeldistance=labeldistance, startangle=startangle, + radius=radius) draw_if_interactive() finally: ax.hold(washold) @@ -2455,7 +2805,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.plot) +@_autogen_docstring(Axes.plot) def plot(*args, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2473,8 +2823,9 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.plot_date) -def plot_date(x, y, fmt='bo', tz=None, xdate=True, ydate=False, hold=None, **kwargs): +@_autogen_docstring(Axes.plot_date) +def plot_date(x, y, fmt='bo', tz=None, xdate=True, ydate=False, hold=None, + **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() @@ -2482,7 +2833,8 @@ if hold is not None: ax.hold(hold) try: - ret = ax.plot_date(x, y, fmt, tz, xdate, ydate, **kwargs) + ret = ax.plot_date(x, y, fmt=fmt, tz=tz, xdate=xdate, ydate=ydate, + **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2491,8 +2843,10 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.psd) -def psd(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, window=mlab.window_hanning, noverlap=0, pad_to=None, sides='default', scale_by_freq=None, hold=None, **kwargs): +@_autogen_docstring(Axes.psd) +def psd(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, + window=mlab.window_hanning, noverlap=0, pad_to=None, sides='default', + scale_by_freq=None, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() @@ -2500,7 +2854,9 @@ if hold is not None: ax.hold(hold) try: - ret = ax.psd(x, NFFT, Fs, Fc, detrend, window, noverlap, pad_to, sides, scale_by_freq, **kwargs) + ret = ax.psd(x, NFFT=NFFT, Fs=Fs, Fc=Fc, detrend=detrend, + window=window, noverlap=noverlap, pad_to=pad_to, + sides=sides, scale_by_freq=scale_by_freq, **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2509,7 +2865,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.quiver) +@_autogen_docstring(Axes.quiver) def quiver(*args, **kw): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2527,7 +2883,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.quiverkey) +@_autogen_docstring(Axes.quiverkey) def quiverkey(*args, **kw): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2545,8 +2901,10 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.scatter) -def scatter(x, y, s=20, c='b', marker='o', cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, faceted=True, verts=None, hold=None, **kwargs): +@_autogen_docstring(Axes.scatter) +def scatter(x, y, s=20, c='b', marker='o', cmap=None, norm=None, vmin=None, + vmax=None, alpha=None, linewidths=None, faceted=True, verts=None, + hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() @@ -2554,7 +2912,10 @@ if hold is not None: ax.hold(hold) try: - ret = ax.scatter(x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, faceted, verts, **kwargs) + ret = ax.scatter(x, y, s=s, c=c, marker=marker, cmap=cmap, norm=norm, + vmin=vmin, vmax=vmax, alpha=alpha, + linewidths=linewidths, faceted=faceted, verts=verts, + **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2563,7 +2924,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.semilogx) +@_autogen_docstring(Axes.semilogx) def semilogx(*args, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2581,7 +2942,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.semilogy) +@_autogen_docstring(Axes.semilogy) def semilogy(*args, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2599,8 +2960,11 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.specgram) -def specgram(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, window=mlab.window_hanning, noverlap=128, cmap=None, xextent=None, pad_to=None, sides='default', scale_by_freq=None, hold=None, **kwargs): +@_autogen_docstring(Axes.specgram) +def specgram(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, + window=mlab.window_hanning, noverlap=128, cmap=None, xextent=None, + pad_to=None, sides='default', scale_by_freq=None, hold=None, + **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() @@ -2608,7 +2972,10 @@ if hold is not None: ax.hold(hold) try: - ret = ax.specgram(x, NFFT, Fs, Fc, detrend, window, noverlap, cmap, xextent, pad_to, sides, scale_by_freq, **kwargs) + ret = ax.specgram(x, NFFT=NFFT, Fs=Fs, Fc=Fc, detrend=detrend, + window=window, noverlap=noverlap, cmap=cmap, + xextent=xextent, pad_to=pad_to, sides=sides, + scale_by_freq=scale_by_freq, **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2617,8 +2984,27 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.stem) -def stem(x, y, linefmt='b-', markerfmt='bo', basefmt='r-', hold=None): +@_autogen_docstring(Axes.stackplot) +def stackplot(x, *args, **kwargs): + ax = gca() + # allow callers to override the hold state by passing hold=True|False + washold = ax.ishold() + hold = kwargs.pop('hold', None) + if hold is not None: + ax.hold(hold) + try: + ret = ax.stackplot(x, *args, **kwargs) + draw_if_interactive() + finally: + ax.hold(washold) + + return ret + +# This function was autogenerated by boilerplate.py. Do not edit as +# changes will be lost +@_autogen_docstring(Axes.stem) +def stem(x, y, linefmt='b-', markerfmt='bo', basefmt='r-', bottom=None, + label=None, hold=None): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() @@ -2626,7 +3012,8 @@ if hold is not None: ax.hold(hold) try: - ret = ax.stem(x, y, linefmt, markerfmt, basefmt) + ret = ax.stem(x, y, linefmt=linefmt, markerfmt=markerfmt, + basefmt=basefmt, bottom=bottom, label=label) draw_if_interactive() finally: ax.hold(washold) @@ -2635,7 +3022,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.step) +@_autogen_docstring(Axes.step) def step(x, y, *args, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2653,7 +3040,30 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.tricontour) +@_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.1, + transform=None, 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: + ret = ax.streamplot(x, y, u, v, density=density, linewidth=linewidth, + color=color, cmap=cmap, norm=norm, + arrowsize=arrowsize, arrowstyle=arrowstyle, + minlength=minlength, transform=transform) + draw_if_interactive() + finally: + ax.hold(washold) + sci(ret.lines) + return ret + +# This function was autogenerated by boilerplate.py. Do not edit as +# changes will be lost +@_autogen_docstring(Axes.tricontour) def tricontour(*args, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2671,7 +3081,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.tricontourf) +@_autogen_docstring(Axes.tricontourf) def tricontourf(*args, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2689,7 +3099,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.tripcolor) +@_autogen_docstring(Axes.tripcolor) def tripcolor(*args, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2707,7 +3117,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.triplot) +@_autogen_docstring(Axes.triplot) def triplot(*args, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2725,8 +3135,9 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.vlines) -def vlines(x, ymin, ymax, colors='k', linestyles='solid', label='', hold=None, **kwargs): +@_autogen_docstring(Axes.vlines) +def vlines(x, ymin, ymax, colors='k', linestyles='solid', label='', hold=None, + **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() @@ -2734,7 +3145,8 @@ if hold is not None: ax.hold(hold) try: - ret = ax.vlines(x, ymin, ymax, colors, linestyles, label, **kwargs) + ret = ax.vlines(x, ymin, ymax, colors=colors, linestyles=linestyles, + label=label, **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2743,8 +3155,9 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.xcorr) -def xcorr(x, y, normed=True, detrend=mlab.detrend_none, usevlines=True, maxlags=10, hold=None, **kwargs): +@_autogen_docstring(Axes.xcorr) +def xcorr(x, y, normed=True, detrend=mlab.detrend_none, usevlines=True, + maxlags=10, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() @@ -2752,7 +3165,8 @@ if hold is not None: ax.hold(hold) try: - ret = ax.xcorr(x, y, normed, detrend, usevlines, maxlags, **kwargs) + ret = ax.xcorr(x, y, normed=normed, detrend=detrend, + usevlines=usevlines, maxlags=maxlags, **kwargs) draw_if_interactive() finally: ax.hold(washold) @@ -2761,7 +3175,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost -@autogen_docstring(Axes.barbs) +@_autogen_docstring(Axes.barbs) def barbs(*args, **kw): ax = gca() # allow callers to override the hold state by passing hold=True|False @@ -2781,7 +3195,7 @@ # changes will be lost @docstring.copy_dedent(Axes.cla) def cla(): - ret = gca().cla() + ret = gca().cla() draw_if_interactive() return ret @@ -2789,7 +3203,7 @@ # changes will be lost @docstring.copy_dedent(Axes.grid) def grid(b=None, which='major', axis='both', **kwargs): - ret = gca().grid(b, which, axis, **kwargs) + ret = gca().grid(b=b, which=which, axis=axis, **kwargs) draw_if_interactive() return ret @@ -2797,7 +3211,7 @@ # changes will be lost @docstring.copy_dedent(Axes.legend) def legend(*args, **kwargs): - ret = gca().legend(*args, **kwargs) + ret = gca().legend(*args, **kwargs) draw_if_interactive() return ret @@ -2805,7 +3219,7 @@ # changes will be lost @docstring.copy_dedent(Axes.table) def table(**kwargs): - ret = gca().table(**kwargs) + ret = gca().table(**kwargs) draw_if_interactive() return ret @@ -2813,7 +3227,7 @@ # changes will be lost @docstring.copy_dedent(Axes.text) def text(x, y, s, fontdict=None, withdash=False, **kwargs): - ret = gca().text(x, y, s, fontdict, withdash, **kwargs) + ret = gca().text(x, y, s, fontdict=fontdict, withdash=withdash, **kwargs) draw_if_interactive() return ret @@ -2821,7 +3235,7 @@ # changes will be lost @docstring.copy_dedent(Axes.annotate) def annotate(*args, **kwargs): - ret = gca().annotate(*args, **kwargs) + ret = gca().annotate(*args, **kwargs) draw_if_interactive() return ret @@ -2829,7 +3243,7 @@ # changes will be lost @docstring.copy_dedent(Axes.ticklabel_format) def ticklabel_format(**kwargs): - ret = gca().ticklabel_format(**kwargs) + ret = gca().ticklabel_format(**kwargs) draw_if_interactive() return ret @@ -2837,7 +3251,7 @@ # changes will be lost @docstring.copy_dedent(Axes.locator_params) def locator_params(axis='both', tight=None, **kwargs): - ret = gca().locator_params(axis, tight, **kwargs) + ret = gca().locator_params(axis=axis, tight=tight, **kwargs) draw_if_interactive() return ret @@ -2845,7 +3259,7 @@ # changes will be lost @docstring.copy_dedent(Axes.tick_params) def tick_params(axis='both', **kwargs): - ret = gca().tick_params(axis, **kwargs) + ret = gca().tick_params(axis=axis, **kwargs) draw_if_interactive() return ret @@ -2853,7 +3267,7 @@ # changes will be lost @docstring.copy_dedent(Axes.margins) def margins(*args, **kw): - ret = gca().margins(*args, **kw) + ret = gca().margins(*args, **kw) draw_if_interactive() return ret @@ -2861,7 +3275,7 @@ # changes will be lost @docstring.copy_dedent(Axes.autoscale) def autoscale(enable=True, axis='both', tight=None): - ret = gca().autoscale(enable, axis, tight) + ret = gca().autoscale(enable=enable, axis=axis, tight=tight) draw_if_interactive() return ret @@ -3089,4 +3503,4 @@ im.set_cmap(cm.spectral) draw_if_interactive() - +_setup_pyplot_info_docstrings() diff -Nru matplotlib-1.1.1/lib/matplotlib/quiver.py matplotlib-1.2.0/lib/matplotlib/quiver.py --- matplotlib-1.1.1/lib/matplotlib/quiver.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/quiver.py 2012-10-31 00:11:14.000000000 +0000 @@ -15,6 +15,7 @@ """ +from __future__ import print_function, division import numpy as np from numpy import ma import matplotlib.collections as collections @@ -407,10 +408,11 @@ self.width = kw.pop('width', None) self.color = kw.pop('color', 'k') self.pivot = kw.pop('pivot', 'tail') + self.transform = kw.pop('transform', ax.transData) kw.setdefault('facecolors', self.color) kw.setdefault('linewidths', (0,)) collections.PolyCollection.__init__(self, [], offsets=self.XY, - transOffset=ax.transData, + transOffset=self.transform, closed=False, **kw) self.polykw = kw @@ -528,8 +530,6 @@ lengths = np.absolute(dxy[:,0] + dxy[:,1]*1j) / eps return angles, lengths - - def _make_verts(self, U, V): uv = (U+V*1j) if self.angles == 'xy' and self.scale_units == 'xy': @@ -591,7 +591,6 @@ return XY - def _h_arrows(self, length): """ length is in arrow width units """ # It might be possible to streamline the code @@ -823,6 +822,7 @@ self.barb_increments = kw.pop('barb_increments', dict()) self.rounding = kw.pop('rounding', True) self.flip = kw.pop('flip_barb', False) + transform = kw.pop('transform', ax.transData) #Flagcolor and and barbcolor provide convenience parameters for setting #the facecolor and edgecolor, respectively, of the barb polygon. We @@ -850,7 +850,7 @@ #Make a collection barb_size = self._length**2 / 4 #Empirically determined collections.PolyCollection.__init__(self, [], (barb_size,), offsets=xy, - transOffset=ax.transData, **kw) + transOffset=transform, **kw) self.set_transform(transforms.IdentityTransform()) self.set_UVC(u, v, c) diff -Nru matplotlib-1.1.1/lib/matplotlib/rcsetup.py matplotlib-1.2.0/lib/matplotlib/rcsetup.py --- matplotlib-1.1.1/lib/matplotlib/rcsetup.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/rcsetup.py 2012-11-08 13:38:03.000000000 +0000 @@ -12,6 +12,7 @@ parameter set listed here should also be visited to the :file:`matplotlibrc.template` in matplotlib's root source directory. """ +from __future__ import print_function import os import warnings @@ -24,11 +25,12 @@ # change for later versions. interactive_bk = ['GTK', 'GTKAgg', 'GTKCairo', 'FltkAgg', 'MacOSX', - 'QtAgg', 'Qt4Agg', 'TkAgg', 'WX', 'WXAgg', 'CocoaAgg'] + 'QtAgg', 'Qt4Agg', 'TkAgg', 'WX', 'WXAgg', 'CocoaAgg', + 'GTK3Cairo', 'GTK3Agg'] non_interactive_bk = ['agg', 'cairo', 'emf', 'gdk', - 'pdf', 'ps', 'svg', 'template'] + 'pdf', 'pgf', 'ps', 'svg', 'template'] all_backends = interactive_bk + non_interactive_bk @@ -92,11 +94,11 @@ try: fonttype = validate_int(s) except ValueError: - if s.lower() in fonttypes.keys(): + if s.lower() in fonttypes.iterkeys(): return fonttypes[s.lower()] raise ValueError('Supported Postscript/PDF font types are %s' % fonttypes.keys()) else: - if fonttype not in fonttypes.values(): + if fonttype not in fonttypes.itervalues(): raise ValueError('Supported Postscript/PDF font types are %s' % fonttypes.values()) return fonttype @@ -108,13 +110,17 @@ validate_qt4 = ValidateInStrings('backend.qt4', ['PyQt4', 'PySide']) -validate_toolbar = ValidateInStrings('toolbar',[ - 'None','classic','toolbar2', - ], ignorecase=True) - -def validate_autolayout(v): - if v: - warnings.warn("figure.autolayout is not currently supported") +def validate_toolbar(s): + validator = ValidateInStrings( + 'toolbar', + ['None','classic','toolbar2'], + ignorecase=True) + s = validator(s) + if s.lower == 'classic': + warnings.warn("'classic' Navigation Toolbar " + "is deprecated in v1.2.x and will be " + "removed in v1.3") + return s def validate_maskedarray(v): # 2008/12/12: start warning; later, remove all traces of maskedarray @@ -249,9 +255,8 @@ 'silent', 'helpful', 'debug', 'debug-annoying', ]) -validate_cairo_format = ValidateInStrings('cairo_format', - ['png', 'ps', 'pdf', 'svg'], - ignorecase=True) +def deprecate_savefig_extension(value): + warnings.warn("savefig.extension is deprecated. Use savefig.format instead.") validate_ps_papersize = ValidateInStrings('ps_papersize',[ 'auto', 'letter', 'legal', 'ledger', @@ -311,6 +316,33 @@ validate_svg_fonttype = ValidateInStrings('fonttype', ['none', 'path', 'svgfont']) +def validate_hinting(s): + if s in (True, False): + return s + if s.lower() in ('auto', 'native', 'either', 'none'): + return s.lower() + raise ValueError("hinting should be 'auto', 'native', 'either' or 'none'") + +validate_pgf_texsystem = ValidateInStrings('pgf.texsystem', + ['xelatex', 'lualatex', 'pdflatex']) + +validate_movie_writer = ValidateInStrings('animation.writer', + ['ffmpeg', 'ffmpeg_file', 'mencoder', 'mencoder_file']) + +validate_movie_frame_fmt = ValidateInStrings('animation.frame_format', + ['png', 'jpeg', 'tiff', 'raw', 'rgba']) + +def validate_bbox(s): + if type(s) is str: + s = s.lower() + if s == 'tight': + return s + if s == 'standard': + return None + raise ValueError("bbox should be 'tight' or 'standard'") + + + class ValidateInterval: """ Value must be in interval @@ -405,7 +437,8 @@ 'text.latex.preamble' : [[''], validate_stringlist], 'text.latex.preview' : [False, validate_bool], 'text.dvipnghack' : [None, validate_bool_maybe_none], - 'text.hinting' : [True, validate_bool], + 'text.hinting' : [True, validate_hinting], + 'text.hinting_factor' : [8, validate_int], 'text.antialiased' : [True, validate_bool], # The following are deprecated and replaced by, e.g., 'font.style' @@ -450,7 +483,9 @@ # use scientific notation if log10 # of the axis range is smaller than the # first or larger than the second - 'axes.formatter.use_locale' : [False, validate_bool], # Use the current locale to format ticks + 'axes.formatter.use_locale' : [False, validate_bool], + # Use the current locale to format ticks + 'axes.formatter.use_mathtext' : [False, validate_bool], 'axes.unicode_minus' : [True, validate_bool], 'axes.color_cycle' : [['b','g','r','c','m','y','k'], validate_colorlist], # cycle of plot @@ -508,6 +543,7 @@ 'grid.color' : ['k', validate_color], # grid color 'grid.linestyle' : [':', str], # dotted 'grid.linewidth' : [0.5, validate_float], # in points + 'grid.alpha' : [1.0, validate_float], # figure props @@ -516,7 +552,7 @@ 'figure.dpi' : [ 80, validate_float], # DPI 'figure.facecolor' : [ '0.75', validate_color], # facecolor; scalar gray 'figure.edgecolor' : [ 'w', validate_color], # edgecolor; white - 'figure.autolayout' : [ False, validate_autolayout], + 'figure.autolayout' : [ False, validate_bool], 'figure.subplot.left' : [0.125, ValidateInterval(0, 1, closedmin=True, closedmax=True)], 'figure.subplot.right' : [0.9, ValidateInterval(0, 1, closedmin=True, closedmax=True)], @@ -529,9 +565,11 @@ 'savefig.facecolor' : ['w', validate_color], # facecolor; white 'savefig.edgecolor' : ['w', validate_color], # edgecolor; white 'savefig.orientation' : ['portrait', validate_orientation], # edgecolor; white - 'savefig.extension' : ['auto', str], # what to add to extensionless filenames + 'savefig.extension' : ['png', deprecate_savefig_extension], # what to add to extensionless filenames + 'savefig.format' : ['png', str], # value checked by backend at runtime + 'savefig.bbox' : [None, validate_bbox], # options are 'tight', or 'standard'. 'standard' validates to None. + 'savefig.pad_inches' : [0.1, validate_float], - 'cairo.format' : ['png', validate_cairo_format], 'tk.window_focus' : [False, validate_bool], # Maintain shell focus for TkAgg 'tk.pythoninspect' : [False, validate_tkpythoninspect], # obsolete 'ps.papersize' : ['letter', validate_ps_papersize], # Set the papersize/type @@ -544,6 +582,12 @@ 'pdf.use14corefonts' : [False, validate_bool], # use only the 14 PDF core fonts # embedded in every PDF viewing application 'pdf.fonttype' : [3, validate_fonttype], # 3 (Type3) or 42 (Truetype) + + 'pgf.debug' : [False, validate_bool], # output debug information + 'pgf.texsystem' : ['xelatex', validate_pgf_texsystem], # choose latex application for creating pdf files (xelatex/lualatex) + 'pgf.rcfonts' : [True, validate_bool], # use matplotlib rc settings for font configuration + 'pgf.preamble' : [[''], validate_stringlist], # provide a custom preamble for the latex process + 'svg.image_inline' : [True, validate_bool], # write raster image data directly into the svg file 'svg.image_noscale' : [False, validate_bool], # suppress scaling of raster data embedded in SVG 'svg.embed_char_paths' : [True, deprecate_svg_embed_char_paths], # True to save all characters as paths in the SVG @@ -558,23 +602,29 @@ 'agg.path.chunksize' : [0, validate_int], # 0 to disable chunking; # recommend about 20000 to # enable. Experimental. - # key-mappings - 'keymap.fullscreen' : ['f', validate_stringlist], + # key-mappings (multi-character mappings should be a list/tuple) + 'keymap.fullscreen' : [('f', 'ctrl+f'), validate_stringlist], 'keymap.home' : [['h', 'r', 'home'], validate_stringlist], 'keymap.back' : [['left', 'c', 'backspace'], validate_stringlist], 'keymap.forward' : [['right', 'v'], validate_stringlist], 'keymap.pan' : ['p', validate_stringlist], 'keymap.zoom' : ['o', validate_stringlist], - 'keymap.save' : ['s', validate_stringlist], + 'keymap.save' : [('s', 'ctrl+s'), validate_stringlist], + 'keymap.quit' : [('ctrl+w', ), validate_stringlist], 'keymap.grid' : ['g', validate_stringlist], 'keymap.yscale' : ['l', validate_stringlist], 'keymap.xscale' : [['k', 'L'], validate_stringlist], 'keymap.all_axes' : ['a', validate_stringlist], - # sample data - 'examples.download' : [True, validate_bool], - 'examples.directory' : ['', str], - + # Animation settings + 'animation.writer' : ['ffmpeg', validate_movie_writer], + 'animation.codec' : ['mpeg4', str], + 'animation.bitrate' : [-1, validate_int], + 'animation.frame_format' : ['png', validate_movie_frame_fmt], # Controls image format when frames are written to disk + 'animation.ffmpeg_path' : ['ffmpeg', str], # Path to FFMPEG binary. If just binary name, subprocess uses $PATH. + 'animation.ffmpeg_args' : ['', validate_stringlist], # Additional arguments for ffmpeg movie writer (using pipes) + 'animation.mencoder_path' : ['mencoder', str], # Path to FFMPEG binary. If just binary name, subprocess uses $PATH. + 'animation.mencoder_args' : ['', validate_stringlist], # Additional arguments for mencoder movie writer (using pipes) } if __name__ == '__main__': @@ -582,4 +632,4 @@ rc['datapath'][0] = '/' for key in rc: if not rc[key][1](rc[key][0]) == rc[key][0]: - print "%s: %s != %s"%(key, rc[key][1](rc[key][0]), rc[key][0]) + print("%s: %s != %s"%(key, rc[key][1](rc[key][0]), rc[key][0])) diff -Nru matplotlib-1.1.1/lib/matplotlib/sankey.py matplotlib-1.2.0/lib/matplotlib/sankey.py --- matplotlib-1.1.1/lib/matplotlib/sankey.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/sankey.py 2012-11-08 13:38:03.000000000 +0000 @@ -8,7 +8,7 @@ __version__ = "2011/09/16" # Original version by Yannick Copin (ycopin@ipnl.in2p3.fr) 10/2/2010, available # at: -# http://matplotlib.sourceforge.net/examples/api/sankey_demo_old.html +# http://matplotlib.org/examples/api/sankey_demo_old.html # Modifications by Kevin Davies (kld@alumni.carnegiemellon.edu) 6/3/2011: # --Used arcs for the curves (so that the widths of the paths are uniform) # --Converted the function to a class and created methods to join @@ -16,16 +16,17 @@ # --Provided handling for cases where the total of the inputs isn't 100 # Now, the default layout is based on the assumption that the inputs sum to # 1. A scaling parameter can be used in other cases. -# --The call structure was changed to be more explicit about layout, including -# the length of the trunk, length of the paths, gap between the paths, and -# the margin around the diagram. +# --The call structure was changed to be more explicit about layout, +# including the length of the trunk, length of the paths, gap between the +# paths, and the margin around the diagram. # --Allowed the lengths of paths to be adjusted individually, with an option # to automatically justify them # --The call structure was changed to make the specification of path # orientation more flexible. Flows are passed through one array, with -# inputs being positive and outputs being negative. An orientation argument -# specifies the direction of the arrows. The "main" inputs/outputs are now -# specified via an orientation of 0, and there may be several of each. +# inputs being positive and outputs being negative. An orientation +# argument specifies the direction of the arrows. The "main" +# inputs/outputs are now specified via an orientation of 0, and there may +# be several of each. # --Added assertions to catch common calling errors # -Added the physical unit as a string argument to be used in the labels, so # that the values of the flows can usually be applied automatically @@ -34,7 +35,6 @@ # --Allowed the diagram to be rotated import numpy as np -import warnings from matplotlib.cbook import iterable, Bunch from matplotlib.path import Path @@ -61,7 +61,7 @@ `Wikipedia (6/1/2011) `_ """ - def _arc(self, quadrant=0, cw=True, radius=1, center=(0,0)): + def _arc(self, quadrant=0, cw=True, radius=1, center=(0, 0)): """ Return the codes and vertices for a rotated, scaled, and translated 90 degree arc. @@ -94,23 +94,25 @@ [7.07106781e-01, 7.07106781e-01], [5.19642327e-01, 8.94571235e-01], [2.65114773e-01, 1.00000000e+00], - #[6.12303177e-17, 1.00000000e+00]]) # Insignificant + # Insignificant + #[6.12303177e-17, 1.00000000e+00]]) [0.00000000e+00, 1.00000000e+00]]) if quadrant == 0 or quadrant == 2: if cw: vertices = ARC_VERTICES else: - vertices = ARC_VERTICES[:,::-1] # Swap x and y. + vertices = ARC_VERTICES[:, ::-1] # Swap x and y. elif quadrant == 1 or quadrant == 3: # Negate x. if cw: # Swap x and y. - vertices = np.column_stack((-ARC_VERTICES[:,1], - ARC_VERTICES[:,0])) + vertices = np.column_stack((-ARC_VERTICES[:, 1], + ARC_VERTICES[:, 0])) else: - vertices = np.column_stack((-ARC_VERTICES[:,0], - ARC_VERTICES[:,1])) - if quadrant > 1: radius = -radius # Rotate 180 deg. + vertices = np.column_stack((-ARC_VERTICES[:, 0], + ARC_VERTICES[:, 1])) + if quadrant > 1: + radius = -radius # Rotate 180 deg. return zip(ARC_CODES, radius*vertices + np.tile(center, (ARC_VERTICES.shape[0], 1))) @@ -121,7 +123,7 @@ if angle is None: return [0, 0], [0, 0] else: - (x, y) = path[-1][1] # Use the last point as a reference. + x, y = path[-1][1] # Use the last point as a reference. dipdepth = (flow / 2) * self.pitch if angle == RIGHT: x -= length @@ -131,16 +133,21 @@ (Path.LINETO, [x, y + flow]), (Path.LINETO, [x+self.gap, y + flow])]) label_location = [dip[0] - self.offset, dip[1]] - else: # Vertical + else: # Vertical x -= self.gap - if angle == UP: sign = 1 - else: sign = -1 + if angle == UP: + sign = 1 + else: + sign = -1 dip = [x - flow / 2, y - sign * (length - dipdepth)] - if angle == DOWN: quadrant = 2 - else: quadrant = 1 + if angle == DOWN: + quadrant = 2 + else: + quadrant = 1 - if self.radius: # Inner arc isn't needed if inner radius is zero + # Inner arc isn't needed if inner radius is zero + if self.radius: path.extend(self._arc(quadrant=quadrant, cw=angle==UP, radius=self.radius, @@ -170,7 +177,7 @@ if angle is None: return [0, 0], [0, 0] else: - (x, y) = path[-1][1] # Use the last point as a reference. + x, y = path[-1][1] # Use the last point as a reference. tipheight = (self.shoulder - flow / 2) * self.pitch if angle == RIGHT: x += length @@ -182,17 +189,20 @@ (Path.LINETO, [x, y + flow]), (Path.LINETO, [x-self.gap, y + flow])]) label_location = [tip[0] + self.offset, tip[1]] - else: # Vertical + else: # Vertical x += self.gap - if angle == UP: sign = 1 - else: sign = -1 + if angle == UP: + sign = 1 + else: + sign = -1 tip = [x - flow / 2.0, y + sign * (length + tipheight)] if angle == UP: quadrant = 3 else: quadrant = 0 - if self.radius: # Inner arc isn't needed if inner radius is zero + # Inner arc isn't needed if inner radius is zero + if self.radius: path.extend(self._arc(quadrant=quadrant, cw=angle==UP, radius=self.radius, @@ -223,7 +233,7 @@ """ reverse_path = [] next_code = first_action - for code,position in path[::-1]: + for code, position in path[::-1]: reverse_path.append((next_code, position)) next_code = code return reverse_path @@ -235,9 +245,9 @@ #return path @docstring.dedent_interpd - def add(self, patchlabel='', flows=np.array([1.0,-1.0]), orientations=[0,0], - labels='', trunklength=1.0, pathlengths=0.25, prior=None, - connect=(0,0), rotation=0, **kwargs): + def add(self, patchlabel='', flows=None, orientations=None, labels='', + trunklength=1.0, pathlengths=0.25, prior=None, connect=(0, 0), + rotation=0, **kwargs): """ Add a simple Sankey diagram with flows at the same hierarchical level. @@ -245,44 +255,44 @@ Optional keyword arguments: - =============== ========================================================== + =============== =================================================== Keyword Description - =============== ========================================================== + =============== =================================================== *patchlabel* label to be placed at the center of the diagram Note: *label* (not *patchlabel*) will be passed to - the patch through ``**kwargs`` and can be used to create - an entry in the legend. + the patch through ``**kwargs`` and can be used to + create an entry in the legend. *flows* array of flow values By convention, inputs are positive and outputs are negative. *orientations* list of orientations of the paths - Valid values are 1 (from/to the top), 0 (from/to the - left or right), or -1 (from/to the bottom). If + Valid values are 1 (from/to the top), 0 (from/to + the left or right), or -1 (from/to the bottom). If *orientations* == 0, inputs will break in from the left and outputs will break away to the right. *labels* list of specifications of the labels for the flows Each value may be None (no labels), '' (just label the quantities), or a labeling string. If a single value is provided, it will be applied to all flows. - If an entry is a non-empty string, then the quantity - for the corresponding flow will be shown below the - string. However, if the *unit* of the main diagram - is None, then quantities are never shown, regardless - of the value of this argument. + If an entry is a non-empty string, then the + quantity for the corresponding flow will be shown + below the string. However, if the *unit* of the + main diagram is None, then quantities are never + shown, regardless of the value of this argument. *trunklength* length between the bases of the input and output groups *pathlengths* list of lengths of the arrows before break-in or after break-away If a single value is given, then it will be applied to the first (inside) paths on the top and bottom, - and the length of all other arrows will be justified - accordingly. The *pathlengths* are not applied to - the horizontal inputs and outputs. + and the length of all other arrows will be + justified accordingly. The *pathlengths* are not + applied to the horizontal inputs and outputs. *prior* index of the prior diagram to which this diagram should be connected - *connect* a (prior, this) tuple indexing the flow of the prior - diagram and the flow of this diagram which should be - connected + *connect* a (prior, this) tuple indexing the flow of the + prior diagram and the flow of this diagram which + should be connected If this is the first diagram or *prior* is None, *connect* will be ignored. *rotation* angle of rotation of the diagram [deg] @@ -292,7 +302,7 @@ will be rotated accordingly (e.g., if *rotation* == 90, an *orientations* entry of 1 means to/from the left). - =============== ========================================================== + =============== =================================================== Valid kwargs are :meth:`matplotlib.patches.PathPatch` arguments: @@ -304,10 +314,10 @@ The indexing parameters (*prior* and *connect*) are zero-based. - The flows are placed along the top of the diagram from the inside out in - order of their index within the *flows* list or array. They are placed - along the sides of the diagram from the top down and along the bottom - from the outside in. + The flows are placed along the top of the diagram from the inside out + in order of their index within the *flows* list or array. They are + placed along the sides of the diagram from the top down and along the + bottom from the outside in. If the the sum of the inputs and outputs is nonzero, the discrepancy will appear as a cubic Bezier curve along the top and bottom edges of @@ -318,69 +328,76 @@ :meth:`finish` """ # Check and preprocess the arguments. - flows = np.array(flows) - n = flows.shape[0] # Number of flows + if flows is None: + flows = np.array([1.0, -1.0]) + else: + flows = np.array(flows) + n = flows.shape[0] # Number of flows if rotation == None: rotation = 0 else: - rotation /= 90.0 # In the code below, angles are expressed in deg/90 - assert len(orientations) == n, ("orientations and flows must have the " - "same length.\norientations has length " - "%d, but flows has length %d." - % len(orientations), n) - if getattr(labels, '__iter__', False): - # iterable() isn't used because it would give True if labels is a string - assert len(labels) == n, ("If labels is a list, then labels and " - "flows must have the same length.\n" - "labels has length %d, but flows has " - "length %d." % len(labels), n) + # In the code below, angles are expressed in deg/90 + rotation /= 90.0 + if orientations is None: + orientations = [0, 0] + assert len(orientations) == n, ( + "orientations and flows must have the same length.\n" + "orientations has length %d, but flows has length %d." + % (len(orientations), n)) + if labels != '' and getattr(labels, '__iter__', False): + # iterable() isn't used because it would give True if labels is a + # string + assert len(labels) == n, ( + "If labels is a list, then labels and flows must have the " + "same length.\nlabels has length %d, but flows has length %d." + % (len(labels), n)) else: labels = [labels]*n - assert trunklength >= 0, ("trunklength is negative.\nThis isn't " - "allowed, because it would cause poor " - "layout.") + assert trunklength >= 0, ( + "trunklength is negative.\nThis isn't allowed, because it would " + "cause poor layout.") if np.absolute(np.sum(flows)) > self.tolerance: - verbose.report("The sum of the flows is nonzero (%f).\nIs the " - "system not at steady state?" % np.sum(flows), - 'helpful') + verbose.report( + "The sum of the flows is nonzero (%f).\nIs the " + "system not at steady state?" % np.sum(flows), 'helpful') scaled_flows = self.scale*flows gain = sum(max(flow, 0) for flow in scaled_flows) loss = sum(min(flow, 0) for flow in scaled_flows) if not (0.5 <= gain <= 2.0): - verbose.report("The scaled sum of the inputs is %f.\nThis may " - "cause poor layout.\nConsider changing the scale so " - "that the scaled sum is approximately 1.0." % gain, - 'helpful') + verbose.report( + "The scaled sum of the inputs is %f.\nThis may " + "cause poor layout.\nConsider changing the scale so" + " that the scaled sum is approximately 1.0." % gain, 'helpful') if not (-2.0 <= loss <= -0.5): - verbose.report("The scaled sum of the outputs is %f.\nThis may " - "cause poor layout.\nConsider changing the scale so " - "that the scaled sum is approximately 1.0." % gain, - 'helpful') + verbose.report( + "The scaled sum of the outputs is %f.\nThis may " + "cause poor layout.\nConsider changing the scale so" + " that the scaled sum is approximately 1.0." % gain, 'helpful') if prior is not None: assert prior >= 0, "The index of the prior diagram is negative." - assert min(connect) >= 0, ("At least one of the connection indices " - "is negative.") - assert prior < len(self.diagrams), ("The index of the prior " - "diagram is %d, but there are " - "only %d other diagrams.\nThe " - "index is zero-based." % prior, - len(self.diagrams)) - assert connect[0] < len(self.diagrams[prior].flows), \ - ("The connection index to the source diagram is %d, but " - "that diagram has only %d flows.\nThe index is zero-based." - % connect[0], len(self.diagrams[prior].flows)) - assert connect[1] < n, ("The connection index to this diagram is " - "%d, but this diagram has only %d flows.\n" - "The index is zero-based." % connect[1], n) - assert self.diagrams[prior].angles[connect[0]] is not None, \ - ("The connection cannot be made. Check that the magnitude " - "of flow %d of diagram %d is greater than or equal to the " - "specified tolerance." % connect[0], prior) - flow_error = self.diagrams[prior].flows[connect[0]] \ - + flows[connect[1]] - assert abs(flow_error) < self.tolerance, \ - ("The scaled sum of the connected flows is %f, which is not " - "within the tolerance (%f)." % flow_error, self.tolerance) + assert min(connect) >= 0, ( + "At least one of the connection indices is negative.") + assert prior < len(self.diagrams), ( + "The index of the prior diagram is %d, but there are " + "only %d other diagrams.\nThe index is zero-based." + % (prior, len(self.diagrams))) + assert connect[0] < len(self.diagrams[prior].flows), ( + "The connection index to the source diagram is %d, but " + "that diagram has only %d flows.\nThe index is zero-based." + % (connect[0], len(self.diagrams[prior].flows))) + assert connect[1] < n, ( + "The connection index to this diagram is %d, but this diagram" + "has only %d flows.\n The index is zero-based." + % (connect[1], n)) + assert self.diagrams[prior].angles[connect[0]] is not None, ( + "The connection cannot be made. Check that the magnitude " + "of flow %d of diagram %d is greater than or equal to the " + "specified tolerance." % (connect[0], prior)) + flow_error = (self.diagrams[prior].flows[connect[0]] + + flows[connect[1]]) + assert abs(flow_error) < self.tolerance, ( + "The scaled sum of the connected flows is %f, which is not " + "within the tolerance (%f)." % (flow_error, self.tolerance)) # Determine if the flows are inputs. are_inputs = [None]*n @@ -390,10 +407,11 @@ elif flow <= -self.tolerance: are_inputs[i] = False else: - verbose.report("The magnitude of flow %d (%f) is below the " - "tolerance (%f).\nIt will not be shown, and it " - "cannot be used in a connection." % (i, flow, - self.tolerance), 'helpful') + verbose.report( + "The magnitude of flow %d (%f) is below the " + "tolerance (%f).\nIt will not be shown, and it " + "cannot be used in a connection." + % (i, flow, self.tolerance), 'helpful') # Determine the angles of the arrows (before rotation). angles = [None]*n @@ -401,14 +419,16 @@ if orient == 1: if is_input: angles[i] = DOWN - elif is_input == False: # Be specific since is_input can be None. + elif is_input == False: + # Be specific since is_input can be None. angles[i] = UP elif orient == 0: if is_input is not None: angles[i] = RIGHT else: - assert orient == -1, ("The value of orientations[%d] is %d, " - "but it must be -1, 0, or 1." % i, orient) + assert orient == -1, ( + "The value of orientations[%d] is %d, " + "but it must be -1, 0, or 1." % (i, orient)) if is_input: angles[i] = UP elif is_input == False: @@ -416,11 +436,10 @@ # Justify the lengths of the paths. if iterable(pathlengths): - assert len(pathlengths) == n, ("If pathlengths is a list, then " - "pathlengths and flows must have " - "the same length.\npathlengths has " - "length %d, but flows has length %d." - % len(pathlengths), n) + assert len(pathlengths) == n, ( + "If pathlengths is a list, then pathlengths and flows must " + "have the same length.\npathlengths has length %d, but flows " + "has length %d." % (len(pathlengths), n)) else: # Make pathlengths into a list. urlength = pathlengths ullength = pathlengths @@ -430,18 +449,18 @@ pathlengths = [d.get(angle, 0) for angle in angles] # Determine the lengths of the top-side arrows # from the middle outwards. - for i, (angle, is_input, flow) \ - in enumerate(zip(angles, are_inputs, scaled_flows)): + for i, (angle, is_input, flow) in enumerate(zip(angles, are_inputs, + scaled_flows)): if angle == DOWN and is_input: pathlengths[i] = ullength ullength += flow elif angle == UP and not is_input: pathlengths[i] = urlength - urlength -= flow # Flow is negative for outputs. + urlength -= flow # Flow is negative for outputs. # Determine the lengths of the bottom-side arrows # from the middle outwards. - for i, (angle, is_input, flow) \ - in enumerate(zip(angles, are_inputs, scaled_flows)[::-1]): + for i, (angle, is_input, flow) in enumerate(reversed(zip( + angles, are_inputs, scaled_flows))): if angle == UP and is_input: pathlengths[n-i-1] = lllength lllength += flow @@ -451,9 +470,8 @@ # Determine the lengths of the left-side arrows # from the bottom upwards. has_left_input = False - for i, (angle, is_input, spec) \ - in enumerate(zip(angles, are_inputs, zip(scaled_flows, - pathlengths))[::-1]): + for i, (angle, is_input, spec) in enumerate(reversed(zip( + angles, are_inputs, zip(scaled_flows, pathlengths)))): if angle == RIGHT: if is_input: if has_left_input: @@ -463,9 +481,8 @@ # Determine the lengths of the right-side arrows # from the top downwards. has_right_output = False - for i, (angle, is_input, spec) \ - in enumerate(zip(angles, are_inputs, zip(scaled_flows, - pathlengths))): + for i, (angle, is_input, spec) in enumerate(zip( + angles, are_inputs, zip(scaled_flows, pathlengths))): if angle == RIGHT: if not is_input: if has_right_output: @@ -475,7 +492,7 @@ # Begin the subpaths, and smooth the transition if the sum of the flows # is nonzero. - urpath = [(Path.MOVETO, [(self.gap - trunklength / 2.0), # Upper right + urpath = [(Path.MOVETO, [(self.gap - trunklength / 2.0), # Upper right gain / 2.0]), (Path.LINETO, [(self.gap - trunklength / 2.0) / 2.0, gain / 2.0]), @@ -487,7 +504,7 @@ -loss / 2.0]), (Path.LINETO, [(trunklength / 2.0 - self.gap), -loss / 2.0])] - llpath = [(Path.LINETO, [(trunklength / 2.0 - self.gap), # Lower left + llpath = [(Path.LINETO, [(trunklength / 2.0 - self.gap), # Lower left loss / 2.0]), (Path.LINETO, [(trunklength / 2.0 - self.gap) / 2.0, loss / 2.0]), @@ -499,41 +516,36 @@ -gain / 2.0]), (Path.LINETO, [(self.gap - trunklength / 2.0), -gain / 2.0])] - lrpath = [(Path.LINETO, [(trunklength / 2.0 - self.gap), # Lower right + lrpath = [(Path.LINETO, [(trunklength / 2.0 - self.gap), # Lower right loss / 2.0])] - ulpath = [(Path.LINETO, [self.gap - trunklength / 2.0, # Upper left + ulpath = [(Path.LINETO, [self.gap - trunklength / 2.0, # Upper left gain / 2.0])] # Add the subpaths and assign the locations of the tips and labels. - tips = np.zeros((n,2)) - label_locations = np.zeros((n,2)) + tips = np.zeros((n, 2)) + label_locations = np.zeros((n, 2)) # Add the top-side inputs and outputs from the middle outwards. - for i, (angle, is_input, spec) \ - in enumerate(zip(angles, are_inputs, - zip(scaled_flows, pathlengths))): + for i, (angle, is_input, spec) in enumerate(zip( + angles, are_inputs, zip(scaled_flows, pathlengths))): if angle == DOWN and is_input: - tips[i,:], label_locations[i,:] = self._add_input(ulpath, angle, - *spec) + tips[i, :], label_locations[i, :] = self._add_input( + ulpath, angle, *spec) elif angle == UP and not is_input: - tips[i,:], label_locations[i,:] = self._add_output(urpath, - angle, *spec) + tips[i, :], label_locations[i, :] = self._add_output( + urpath, angle, *spec) # Add the bottom-side inputs and outputs from the middle outwards. - for i, (angle, is_input, spec) \ - in enumerate(zip(angles, are_inputs, - zip(scaled_flows, pathlengths))[::-1]): + for i, (angle, is_input, spec) in enumerate(reversed(zip( + angles, are_inputs, zip(scaled_flows, pathlengths)))): if angle == UP and is_input: - (tips[n-i-1,:], - label_locations[n-i-1,:]) = self._add_input(llpath, angle, - *spec) + tips[n-i-1, :], label_locations[n-i-1, :] = self._add_input( + llpath, angle, *spec) elif angle == DOWN and not is_input: - (tips[n-i-1,:], - label_locations[n-i-1,:]) = self._add_output(lrpath, angle, - *spec) + tips[n-i-1, :], label_locations[n-i-1, :] = self._add_output( + lrpath, angle, *spec) # Add the left-side inputs from the bottom upwards. has_left_input = False - for i, (angle, is_input, spec) \ - in enumerate(zip(angles, are_inputs, - zip(scaled_flows, pathlengths))[::-1]): + for i, (angle, is_input, spec) in enumerate(reversed(zip( + angles, are_inputs, zip(scaled_flows, pathlengths)))): if angle == RIGHT and is_input: if not has_left_input: # Make sure the lower path extends @@ -542,14 +554,12 @@ llpath.append((Path.LINETO, [ulpath[-1][1][0], llpath[-1][1][1]])) has_left_input = True - (tips[n-i-1,:], - label_locations[n-i-1,:]) = self._add_input(llpath, angle, - *spec) + tips[n-i-1, :], label_locations[n-i-1, :] = self._add_input( + llpath, angle, *spec) # Add the right-side outputs from the top downwards. has_right_output = False - for i, (angle, is_input, spec) \ - in enumerate(zip(angles, are_inputs, - zip(scaled_flows, pathlengths))): + for i, (angle, is_input, spec) in enumerate(zip( + angles, are_inputs, zip(scaled_flows, pathlengths))): if angle == RIGHT and not is_input: if not has_right_output: # Make sure the upper path extends @@ -558,8 +568,8 @@ urpath.append((Path.LINETO, [lrpath[-1][1][0], urpath[-1][1][1]])) has_right_output = True - (tips[i,:], - label_locations[i,:]) = self._add_output(urpath, angle, *spec) + tips[i, :], label_locations[i, :] = self._add_output( + urpath, angle, *spec) # Trim any hanging vertices. if not has_left_input: ulpath.pop() @@ -575,12 +585,15 @@ # Create a patch with the Sankey outline. codes, vertices = zip(*path) vertices = np.array(vertices) + def _get_angle(a, r): - if a is None: return None - else: return a + r + if a is None: + return None + else: + return a + r if prior is None: - if rotation != 0: # By default, none of this is needed. + if rotation != 0: # By default, none of this is needed. angles = [_get_angle(angle, rotation) for angle in angles] rotate = Affine2D().rotate_deg(rotation*90).transform_point tips = rotate(tips) @@ -600,7 +613,7 @@ vertices = translate(rotate(vertices)) kwds = dict(s=patchlabel, ha='center', va='center') text = self.ax.text(*offset, **kwds) - if False: # Debug + if False: # Debug print "llpath\n", llpath print "ulpath\n", self._revert(ulpath) print "urpath\n", urpath @@ -609,9 +622,8 @@ self.ax.plot(xs, ys, 'go-') patch = PathPatch(Path(vertices, codes), fc=kwargs.pop('fc', kwargs.pop('facecolor', - '#bfd1d4')), # Custom defaults - lw=kwargs.pop('lw', kwargs.pop('linewidth', - '0.5')), + '#bfd1d4')), # Custom defaults + lw=kwargs.pop('lw', kwargs.pop('linewidth', 0.5)), **kwargs) self.ax.add_patch(patch) @@ -626,8 +638,10 @@ labels[i] += quantity texts = [] for i, (label, location) in enumerate(zip(labels, label_locations)): - if label: s = label - else: s = '' + if label: + s = label + else: + s = '' texts.append(self.ax.text(x=location[0], y=location[1], s=s, ha='center', va='center')) @@ -636,20 +650,24 @@ # user wants to provide labels later. # Expand the size of the diagram if necessary. - self.extent = (min(np.min(vertices[:,0]), np.min(label_locations[:,0]), + self.extent = (min(np.min(vertices[:, 0]), + np.min(label_locations[:, 0]), self.extent[0]), - max(np.max(vertices[:,0]), np.max(label_locations[:,0]), + max(np.max(vertices[:, 0]), + np.max(label_locations[:, 0]), self.extent[1]), - min(np.min(vertices[:,1]), np.min(label_locations[:,1]), + min(np.min(vertices[:, 1]), + np.min(label_locations[:, 1]), self.extent[2]), - max(np.max(vertices[:,1]), np.max(label_locations[:,1]), + max(np.max(vertices[:, 1]), + np.max(label_locations[:, 1]), self.extent[3])) # Include both vertices _and_ label locations in the extents; there are # where either could determine the margins (e.g., arrow shoulders). # Add this diagram as a subdiagram. self.diagrams.append(Bunch(patch=patch, flows=flows, angles=angles, - tips=tips, text=text, texts=texts)) + tips=tips, text=text, texts=texts)) # Allow a daisy-chained call structure (see docstring for the class). return self @@ -662,32 +680,32 @@ Return value is a list of subdiagrams represented with the following fields: - =============== ===================================================== + =============== =================================================== Field Description - =============== ===================================================== + =============== =================================================== *patch* Sankey outline (an instance of :class:`~maplotlib.patches.PathPatch`) *flows* values of the flows (positive for input, negative for output) *angles* list of angles of the arrows [deg/90] - For example, if the diagram has not been rotated, an - input to the top side will have an angle of 3 - (DOWN), and an output from the top side will have an - angle of 1 (UP). If a flow has been skipped + For example, if the diagram has not been rotated, + an input to the top side will have an angle of 3 + (DOWN), and an output from the top side will have + an angle of 1 (UP). If a flow has been skipped (because its magnitude is less than *tolerance*), then its angle will be None. - *tips* array in which each row is an [x, y] pair indicating - the positions of the tips (or "dips") of the flow - paths + *tips* array in which each row is an [x, y] pair + indicating the positions of the tips (or "dips") of + the flow paths If the magnitude of a flow is less the *tolerance* for the instance of :class:`Sankey`, the flow is skipped and its tip will be at the center of the diagram. *text* :class:`~matplotlib.text.Text` instance for the label of the diagram - *texts* list of :class:`~matplotlib.text.Text` instances for - the labels of flows - =============== ===================================================== + *texts* list of :class:`~matplotlib.text.Text` instances + for the labels of flows + =============== =================================================== .. seealso:: @@ -708,19 +726,19 @@ Optional keyword arguments: - =============== ==================================================== + =============== =================================================== Field Description - =============== ==================================================== + =============== =================================================== *ax* axes onto which the data should be plotted If *ax* isn't provided, new axes will be created. *scale* scaling factor for the flows *scale* sizes the width of the paths in order to maintain proper layout. The same scale is applied - to all subdiagrams. The value should be chosen such - that the product of the scale and the sum of the - inputs is approximately 1.0 (and the product of the - scale and the sum of the outputs is approximately - -1.0). + to all subdiagrams. The value should be chosen + such that the product of the scale and the sum of + the inputs is approximately 1.0 (and the product of + the scale and the sum of the outputs is + approximately -1.0). *unit* string representing the physical unit associated with the flow quantities If *unit* is None, then none of the quantities are @@ -728,8 +746,8 @@ *format* a Python number formatting string to be used in labeling the flow as a quantity (i.e., a number times a unit, where the unit is given) - *gap* space between paths that break in/break away to/from - the top or bottom + *gap* space between paths that break in/break away + to/from the top or bottom *radius* inner radius of the vertical paths *shoulder* size of the shoulders of output arrowS *offset* text offset (from the dip or tip of the arrow) @@ -741,14 +759,14 @@ flows The magnitude of the sum of connected flows cannot be greater than *tolerance*. - =============== ==================================================== + =============== =================================================== The optional arguments listed above are applied to all subdiagrams so that there is consistent alignment and formatting. - If :class:`Sankey` is instantiated with any keyword arguments other than - those explicitly listed above (``**kwargs``), they will be passed to - :meth:`add`, which will create the first subdiagram. + If :class:`Sankey` is instantiated with any keyword arguments other + than those explicitly listed above (``**kwargs``), they will be passed + to :meth:`add`, which will create the first subdiagram. In order to draw a complex Sankey diagram, create an instance of :class:`Sankey` by calling it without any kwargs:: @@ -781,16 +799,18 @@ .. plot:: mpl_examples/api/sankey_demo_basics.py """ # Check the arguments. - assert gap >= 0, ("The gap is negative.\nThis isn't allowed because it " - "would cause the paths to overlap.") - assert radius <= gap, ("The inner radius is greater than the path " - "spacing.\nThis isn't allowed because it would " - "cause the paths to overlap.") - assert head_angle >= 0, ("The angle is negative.\nThis isn't allowed " - "because it would cause inputs to look like " - "outputs and vice versa.") - assert tolerance >= 0, ("The tolerance is negative.\nIt must be a " - "magnitude.") + assert gap >= 0, ( + "The gap is negative.\nThis isn't allowed because it " + "would cause the paths to overlap.") + assert radius <= gap, ( + "The inner radius is greater than the path spacing.\n" + "This isn't allowed because it would cause the paths to overlap.") + assert head_angle >= 0, ( + "The angle is negative.\nThis isn't allowed " + "because it would cause inputs to look like " + "outputs and vice versa.") + assert tolerance >= 0, ( + "The tolerance is negative.\nIt must be a magnitude.") # Create axes if necessary. if ax is None: diff -Nru matplotlib-1.1.1/lib/matplotlib/scale.py matplotlib-1.2.0/lib/matplotlib/scale.py --- matplotlib-1.1.1/lib/matplotlib/scale.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/scale.py 2012-11-06 15:42:20.000000000 +0000 @@ -1,15 +1,17 @@ -import textwrap +from __future__ import print_function + import numpy as np from numpy import ma -MaskedArray = ma.MaskedArray -from cbook import dedent -from ticker import NullFormatter, ScalarFormatter, LogFormatterMathtext, Formatter -from ticker import NullLocator, LogLocator, AutoLocator, SymmetricalLogLocator, FixedLocator -from ticker import is_decade -from transforms import Transform, IdentityTransform +from matplotlib.cbook import dedent +from matplotlib.ticker import (NullFormatter, ScalarFormatter, + LogFormatterMathtext) +from matplotlib.ticker import (NullLocator, LogLocator, AutoLocator, + SymmetricalLogLocator) +from matplotlib.transforms import Transform, IdentityTransform from matplotlib import docstring + class ScaleBase(object): """ The base class for all scales. @@ -30,7 +32,7 @@ Return the :class:`~matplotlib.transforms.Transform` object associated with this scale. """ - raise NotImplementedError + raise NotImplementedError() def set_default_locators_and_formatters(self, axis): """ @@ -38,7 +40,7 @@ :class:`~matplotlib.ticker.Formatter` objects on the given axis to match this scale. """ - raise NotImplementedError + raise NotImplementedError() def limit_range_for_scale(self, vmin, vmax, minpos): """ @@ -50,6 +52,7 @@ """ return vmin, vmax + class LinearScale(ScaleBase): """ The default linear scale. @@ -89,10 +92,12 @@ return ma.MaskedArray(a, mask=mask) return a + def _clip_non_positives(a): a[a <= 0.0] = 1e-300 return a + class LogScale(ScaleBase): """ A standard logarithmic scale. Care is taken so non-positive @@ -114,6 +119,7 @@ input_dims = 1 output_dims = 1 is_separable = True + has_inverse = True def __init__(self, nonpos): Transform.__init__(self) @@ -122,13 +128,12 @@ else: self._handle_nonpos = _clip_non_positives - class Log10Transform(LogTransformBase): base = 10.0 - def transform(self, a): + def transform_non_affine(self, a): a = self._handle_nonpos(a * 10.0) - if isinstance(a, MaskedArray): + if isinstance(a, ma.MaskedArray): return ma.log10(a) return np.log10(a) @@ -139,9 +144,10 @@ input_dims = 1 output_dims = 1 is_separable = True + has_inverse = True base = 10.0 - def transform(self, a): + def transform_non_affine(self, a): return ma.power(10.0, a) / 10.0 def inverted(self): @@ -150,9 +156,9 @@ class Log2Transform(LogTransformBase): base = 2.0 - def transform(self, a): + def transform_non_affine(self, a): a = self._handle_nonpos(a * 2.0) - if isinstance(a, MaskedArray): + if isinstance(a, ma.MaskedArray): return ma.log(a) / np.log(2) return np.log2(a) @@ -163,9 +169,10 @@ input_dims = 1 output_dims = 1 is_separable = True + has_inverse = True base = 2.0 - def transform(self, a): + def transform_non_affine(self, a): return ma.power(2.0, a) / 2.0 def inverted(self): @@ -174,9 +181,9 @@ class NaturalLogTransform(LogTransformBase): base = np.e - def transform(self, a): + def transform_non_affine(self, a): a = self._handle_nonpos(a * np.e) - if isinstance(a, MaskedArray): + if isinstance(a, ma.MaskedArray): return ma.log(a) return np.log(a) @@ -187,9 +194,10 @@ input_dims = 1 output_dims = 1 is_separable = True + has_inverse = True base = np.e - def transform(self, a): + def transform_non_affine(self, a): return ma.power(np.e, a) / np.e def inverted(self): @@ -199,6 +207,7 @@ input_dims = 1 output_dims = 1 is_separable = True + has_inverse = True def __init__(self, base, nonpos): Transform.__init__(self) @@ -208,9 +217,9 @@ else: self._handle_nonpos = _clip_non_positives - def transform(self, a): + def transform_non_affine(self, a): a = self._handle_nonpos(a * self.base) - if isinstance(a, MaskedArray): + if isinstance(a, ma.MaskedArray): return ma.log(a) / np.log(self.base) return np.log(a) / np.log(self.base) @@ -221,18 +230,18 @@ input_dims = 1 output_dims = 1 is_separable = True + has_inverse = True def __init__(self, base): Transform.__init__(self) self.base = base - def transform(self, a): + def transform_non_affine(self, a): return ma.power(self.base, a) / self.base def inverted(self): return LogScale.LogTransform(self.base) - def __init__(self, axis, **kwargs): """ *basex*/*basey*: @@ -312,51 +321,70 @@ name = 'symlog' class SymmetricalLogTransform(Transform): - input_dims = 1 - output_dims = 1 - is_separable = True - - def __init__(self, base, linthresh): - Transform.__init__(self) - self.base = base - self.linthresh = linthresh - self._log_base = np.log(base) - self._linadjust = (np.log(linthresh) / self._log_base) / linthresh - - def transform(self, a): - sign = np.sign(a) - masked = ma.masked_inside(a, -self.linthresh, self.linthresh, copy=False) - log = sign * self.linthresh * (1 + ma.log(np.abs(masked) / self.linthresh)) - if masked.mask.any(): - return ma.where(masked.mask, a, log) - else: - return log + input_dims = 1 + output_dims = 1 + is_separable = True + has_inverse = True - def inverted(self): - return SymmetricalLogScale.InvertedSymmetricalLogTransform(self.base, self.linthresh) + def __init__(self, base, linthresh, linscale): + Transform.__init__(self) + self.base = base + self.linthresh = linthresh + self.linscale = linscale + self._linscale_adj = (linscale / (1.0 - self.base ** -1)) + self._log_base = np.log(base) + + def transform_non_affine(self, a): + sign = np.sign(a) + masked = ma.masked_inside(a, + -self.linthresh, + self.linthresh, + copy=False) + log = sign * self.linthresh * ( + self._linscale_adj + + ma.log(np.abs(masked) / self.linthresh) / self._log_base) + if masked.mask.any(): + return ma.where(masked.mask, a * self._linscale_adj, log) + else: + return log + + def inverted(self): + return SymmetricalLogScale.InvertedSymmetricalLogTransform( + self.base, self.linthresh, self.linscale) class InvertedSymmetricalLogTransform(Transform): input_dims = 1 output_dims = 1 is_separable = True + has_inverse = True - def __init__(self, base, linthresh): + def __init__(self, base, linthresh, linscale): Transform.__init__(self) + symlog = SymmetricalLogScale.SymmetricalLogTransform(base, + linthresh, + linscale) self.base = base self.linthresh = linthresh - self._log_base = np.log(base) - self._log_linthresh = np.log(linthresh) / self._log_base - self._linadjust = linthresh / (np.log(linthresh) / self._log_base) + self.invlinthresh = symlog.transform(linthresh) + self.linscale = linscale + self._linscale_adj = (linscale / (1.0 - self.base ** -1)) - def transform(self, a): + def transform_non_affine(self, a): sign = np.sign(a) - masked = ma.masked_inside(a, -self.linthresh, self.linthresh, copy=False) - exp = sign * self.linthresh * ma.exp(sign * masked / self.linthresh - 1) + masked = ma.masked_inside(a, -self.invlinthresh, + self.invlinthresh, copy=False) + exp = sign * self.linthresh * ( + ma.power(self.base, (sign * (masked / self.linthresh)) + - self._linscale_adj)) if masked.mask.any(): - return ma.where(masked.mask, a, exp) + return ma.where(masked.mask, a / self._linscale_adj, exp) else: return exp + def inverted(self): + return SymmetricalLogScale.SymmetricalLogTransform( + self.base, self.linthresh, self.linscale) + def __init__(self, axis, **kwargs): """ *basex*/*basey*: @@ -373,23 +401,38 @@ will place 8 logarithmically spaced minor ticks between each major tick. + + *linscalex*/*linscaley*: + This allows the linear range (-*linthresh* to *linthresh*) + to be stretched relative to the logarithmic range. Its + value is the number of decades to use for each half of the + linear range. For example, when *linscale* == 1.0 (the + default), the space used for the positive and negative + halves of the linear range will be equal to one decade in + the logarithmic range. """ if axis.axis_name == 'x': base = kwargs.pop('basex', 10.0) linthresh = kwargs.pop('linthreshx', 2.0) subs = kwargs.pop('subsx', None) + linscale = kwargs.pop('linscalex', 1.0) else: base = kwargs.pop('basey', 10.0) linthresh = kwargs.pop('linthreshy', 2.0) subs = kwargs.pop('subsy', None) + linscale = kwargs.pop('linscaley', 1.0) - self._transform = self.SymmetricalLogTransform(base, linthresh) - - assert base > 0.0 + assert base > 1.0 assert linthresh > 0.0 + assert linscale >= 1.0 + + self._transform = self.SymmetricalLogTransform(base, + linthresh, + linscale) self.base = base self.linthresh = linthresh + self.linscale = linscale self.subs = subs def set_default_locators_and_formatters(self, axis): @@ -399,7 +442,8 @@ """ axis.set_major_locator(SymmetricalLogLocator(self.get_transform())) axis.set_major_formatter(LogFormatterMathtext(self.base)) - axis.set_minor_locator(SymmetricalLogLocator(self.get_transform(), self.subs)) + axis.set_minor_locator(SymmetricalLogLocator(self.get_transform(), + self.subs)) axis.set_minor_formatter(NullFormatter()) def get_transform(self): @@ -409,17 +453,19 @@ return self._transform - _scale_mapping = { - 'linear' : LinearScale, - 'log' : LogScale, - 'symlog' : SymmetricalLogScale + 'linear': LinearScale, + 'log': LogScale, + 'symlog': SymmetricalLogScale } + + def get_scale_names(): names = _scale_mapping.keys() names.sort() return names + def scale_factory(scale, axis, **kwargs): """ Return a scale class by name. @@ -437,6 +483,7 @@ scale_factory.__doc__ = dedent(scale_factory.__doc__) % \ {'names': " | ".join(get_scale_names())} + def register_scale(scale_class): """ Register a new kind of scale. @@ -445,6 +492,7 @@ """ _scale_mapping[scale_class.name] = scale_class + def get_scale_docs(): """ Helper function for generating docstrings related to scales. @@ -461,7 +509,8 @@ docs.append("") return "\n".join(docs) + docstring.interpd.update( - scale = ' | '.join([repr(x) for x in get_scale_names()]), - scale_docs = get_scale_docs().strip(), + scale=' | '.join([repr(x) for x in get_scale_names()]), + scale_docs=get_scale_docs().strip(), ) diff -Nru matplotlib-1.1.1/lib/matplotlib/sphinxext/__init__.py matplotlib-1.2.0/lib/matplotlib/sphinxext/__init__.py --- matplotlib-1.1.1/lib/matplotlib/sphinxext/__init__.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/sphinxext/__init__.py 2012-10-31 00:11:14.000000000 +0000 @@ -1 +1,2 @@ +from __future__ import print_function diff -Nru matplotlib-1.1.1/lib/matplotlib/sphinxext/ipython_console_highlighting.py matplotlib-1.2.0/lib/matplotlib/sphinxext/ipython_console_highlighting.py --- matplotlib-1.1.1/lib/matplotlib/sphinxext/ipython_console_highlighting.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/sphinxext/ipython_console_highlighting.py 2012-10-31 00:11:14.000000000 +0000 @@ -4,6 +4,7 @@ 'pycon' lexer for the python console. At the very least it will give better highlighted tracebacks. """ +from __future__ import print_function #----------------------------------------------------------------------------- # Needed modules @@ -13,7 +14,7 @@ # Third party from pygments.lexer import Lexer, do_insertions -from pygments.lexers.agile import (PythonConsoleLexer, PythonLexer, +from pygments.lexers.agile import (PythonConsoleLexer, PythonLexer, PythonTracebackLexer) from pygments.token import Comment, Generic @@ -48,7 +49,7 @@ - It assumes the default IPython prompts, not customized ones. """ - + name = 'IPython console session' aliases = ['ipython'] mimetypes = ['text/x-ipython-console'] diff -Nru matplotlib-1.1.1/lib/matplotlib/sphinxext/ipython_directive.py matplotlib-1.2.0/lib/matplotlib/sphinxext/ipython_directive.py --- matplotlib-1.1.1/lib/matplotlib/sphinxext/ipython_directive.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/sphinxext/ipython_directive.py 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,830 @@ +# -*- coding: utf-8 -*- +"""Sphinx directive to support embedded IPython code. + +This directive allows pasting of entire interactive IPython sessions, prompts +and all, and their code will actually get re-executed at doc build time, with +all prompts renumbered sequentially. It also allows you to input code as a pure +python input by giving the argument python to the directive. The output looks +like an interactive ipython section. + +To enable this directive, simply list it in your Sphinx ``conf.py`` file +(making sure the directory where you placed it is visible to sphinx, as is +needed for all Sphinx directives). + +By default this directive assumes that your prompts are unchanged IPython ones, +but this can be customized. The configurable options that can be placed in +conf.py are + +ipython_savefig_dir: + The directory in which to save the figures. This is relative to the + Sphinx source directory. The default is `html_static_path`. +ipython_rgxin: + The compiled regular expression to denote the start of IPython input + lines. The default is re.compile('In \[(\d+)\]:\s?(.*)\s*'). You + shouldn't need to change this. +ipython_rgxout: + The compiled regular expression to denote the start of IPython output + lines. The default is re.compile('Out\[(\d+)\]:\s?(.*)\s*'). You + shouldn't need to change this. +ipython_promptin: + The string to represent the IPython input prompt in the generated ReST. + The default is 'In [%d]:'. This expects that the line numbers are used + in the prompt. +ipython_promptout: + + The string to represent the IPython prompt in the generated ReST. The + default is 'Out [%d]:'. This expects that the line numbers are used + in the prompt. + +ToDo +---- + +- Turn the ad-hoc test() function into a real test suite. +- Break up ipython-specific functionality from matplotlib stuff into better + separated code. + +Authors +------- + +- John D Hunter: orignal author. +- Fernando Perez: refactoring, documentation, cleanups, port to 0.11. +- VáclavŠmilauer : Prompt generalizations. +- Skipper Seabold, refactoring, cleanups, pure python addition +""" + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +# Stdlib +import cStringIO +import os +import re +import sys +import tempfile +import ast + +# To keep compatibility with various python versions +try: + from hashlib import md5 +except ImportError: + from md5 import md5 + +# Third-party +import matplotlib +import sphinx +from docutils.parsers.rst import directives +from docutils import nodes +from sphinx.util.compat import Directive + +matplotlib.use('Agg') + +# Our own +from IPython import Config, InteractiveShell +from IPython.core.profiledir import ProfileDir +from IPython.utils import io + +#----------------------------------------------------------------------------- +# Globals +#----------------------------------------------------------------------------- +# for tokenizing blocks +COMMENT, INPUT, OUTPUT = range(3) + +#----------------------------------------------------------------------------- +# Functions and class declarations +#----------------------------------------------------------------------------- +def block_parser(part, rgxin, rgxout, fmtin, fmtout): + """ + part is a string of ipython text, comprised of at most one + input, one ouput, comments, and blank lines. The block parser + parses the text into a list of:: + + blocks = [ (TOKEN0, data0), (TOKEN1, data1), ...] + + where TOKEN is one of [COMMENT | INPUT | OUTPUT ] and + data is, depending on the type of token:: + + COMMENT : the comment string + + INPUT: the (DECORATOR, INPUT_LINE, REST) where + DECORATOR: the input decorator (or None) + INPUT_LINE: the input as string (possibly multi-line) + REST : any stdout generated by the input line (not OUTPUT) + + + OUTPUT: the output string, possibly multi-line + """ + + block = [] + lines = part.split('\n') + N = len(lines) + i = 0 + decorator = None + while 1: + + if i==N: + # nothing left to parse -- the last line + break + + line = lines[i] + i += 1 + line_stripped = line.strip() + if line_stripped.startswith('#'): + block.append((COMMENT, line)) + continue + + if line_stripped.startswith('@'): + # we're assuming at most one decorator -- may need to + # rethink + decorator = line_stripped + continue + + # does this look like an input line? + matchin = rgxin.match(line) + if matchin: + lineno, inputline = int(matchin.group(1)), matchin.group(2) + + # the ....: continuation string + continuation = ' %s:'%''.join(['.']*(len(str(lineno))+2)) + Nc = len(continuation) + # input lines can continue on for more than one line, if + # we have a '\' line continuation char or a function call + # echo line 'print'. The input line can only be + # terminated by the end of the block or an output line, so + # we parse out the rest of the input line if it is + # multiline as well as any echo text + + rest = [] + while i 1: + if input_lines[-1] != "": + input_lines.append('') # make sure there's a blank line + # so splitter buffer gets reset + + continuation = ' %s:'%''.join(['.']*(len(str(lineno))+2)) + Nc = len(continuation) + + if is_savefig: + image_file, image_directive = self.process_image(decorator) + + ret = [] + is_semicolon = False + + for i, line in enumerate(input_lines): + if line.endswith(';'): + is_semicolon = True + + if i==0: + # process the first input line + if is_verbatim: + self.process_input_line('') + self.IP.execution_count += 1 # increment it anyway + else: + # only submit the line in non-verbatim mode + self.process_input_line(line, store_history=True) + formatted_line = '%s %s'%(input_prompt, line) + else: + # process a continuation line + if not is_verbatim: + self.process_input_line(line, store_history=True) + + formatted_line = '%s %s'%(continuation, line) + + if not is_suppress: + ret.append(formatted_line) + + if not is_suppress and len(rest.strip()) and is_verbatim: + # the "rest" is the standard output of the + # input, which needs to be added in + # verbatim mode + ret.append(rest) + + self.cout.seek(0) + output = self.cout.read() + if not is_suppress and not is_semicolon: + ret.append(output) + elif is_semicolon: # get spacing right + ret.append('') + + self.cout.truncate(0) + return (ret, input_lines, output, is_doctest, image_file, + image_directive) + #print 'OUTPUT', output # dbg + + def process_output(self, data, output_prompt, + input_lines, output, is_doctest, image_file): + """Process data block for OUTPUT token.""" + if is_doctest: + submitted = data.strip() + found = output + if found is not None: + found = found.strip() + + # XXX - fperez: in 0.11, 'output' never comes with the prompt + # in it, just the actual output text. So I think all this code + # can be nuked... + + # the above comment does not appear to be accurate... (minrk) + + ind = found.find(output_prompt) + if ind<0: + e='output prompt="%s" does not match out line=%s' % \ + (output_prompt, found) + raise RuntimeError(e) + found = found[len(output_prompt):].strip() + + if found!=submitted: + e = ('doctest failure for input_lines="%s" with ' + 'found_output="%s" and submitted output="%s"' % + (input_lines, found, submitted) ) + raise RuntimeError(e) + #print 'doctest PASSED for input_lines="%s" with found_output="%s" and submitted output="%s"'%(input_lines, found, submitted) + + def process_comment(self, data): + """Process data fPblock for COMMENT token.""" + if not self.is_suppress: + return [data] + + def save_image(self, image_file): + """ + Saves the image file to disk. + """ + self.ensure_pyplot() + command = 'plt.gcf().savefig("%s")'%image_file + #print 'SAVEFIG', command # dbg + self.process_input_line('bookmark ipy_thisdir', store_history=False) + self.process_input_line('cd -b ipy_savedir', store_history=False) + self.process_input_line(command, store_history=False) + self.process_input_line('cd -b ipy_thisdir', store_history=False) + self.process_input_line('bookmark -d ipy_thisdir', store_history=False) + self.clear_cout() + + + def process_block(self, block): + """ + process block from the block_parser and return a list of processed lines + """ + ret = [] + output = None + input_lines = None + lineno = self.IP.execution_count + + input_prompt = self.promptin%lineno + output_prompt = self.promptout%lineno + image_file = None + image_directive = None + + for token, data in block: + if token==COMMENT: + out_data = self.process_comment(data) + elif token==INPUT: + (out_data, input_lines, output, is_doctest, image_file, + image_directive) = \ + self.process_input(data, input_prompt, lineno) + elif token==OUTPUT: + out_data = \ + self.process_output(data, output_prompt, + input_lines, output, is_doctest, + image_file) + if out_data: + ret.extend(out_data) + + # save the image files + if image_file is not None: + self.save_image(image_file) + + return ret, image_directive + + def ensure_pyplot(self): + if self._pyplot_imported: + return + self.process_input_line('import matplotlib.pyplot as plt', + store_history=False) + + def process_pure_python(self, content): + """ + content is a list of strings. it is unedited directive conent + + This runs it line by line in the InteractiveShell, prepends + prompts as needed capturing stderr and stdout, then returns + the content as a list as if it were ipython code + """ + output = [] + savefig = False # keep up with this to clear figure + multiline = False # to handle line continuation + multiline_start = None + fmtin = self.promptin + + ct = 0 + + for lineno, line in enumerate(content): + + line_stripped = line.strip() + if not len(line): + output.append(line) + continue + + # handle decorators + if line_stripped.startswith('@'): + output.extend([line]) + if 'savefig' in line: + savefig = True # and need to clear figure + continue + + # handle comments + if line_stripped.startswith('#'): + output.extend([line]) + continue + + # deal with lines checking for multiline + continuation = u' %s:'% ''.join(['.']*(len(str(ct))+2)) + if not multiline: + modified = u"%s %s" % (fmtin % ct, line_stripped) + output.append(modified) + ct += 1 + try: + ast.parse(line_stripped) + output.append(u'') + except Exception: # on a multiline + multiline = True + multiline_start = lineno + else: # still on a multiline + modified = u'%s %s' % (continuation, line) + output.append(modified) + try: + mod = ast.parse( + '\n'.join(content[multiline_start:lineno+1])) + if isinstance(mod.body[0], ast.FunctionDef): + # check to see if we have the whole function + for element in mod.body[0].body: + if isinstance(element, ast.Return): + multiline = False + else: + output.append(u'') + multiline = False + except Exception: + pass + + if savefig: # clear figure if plotted + self.ensure_pyplot() + self.process_input_line('plt.clf()', store_history=False) + self.clear_cout() + savefig = False + + return output + +class IpythonDirective(Directive): + + has_content = True + required_arguments = 0 + optional_arguments = 4 # python, suppress, verbatim, doctest + final_argumuent_whitespace = True + option_spec = { 'python': directives.unchanged, + 'suppress' : directives.flag, + 'verbatim' : directives.flag, + 'doctest' : directives.flag, + } + + shell = EmbeddedSphinxShell() + + def get_config_options(self): + # contains sphinx configuration variables + config = self.state.document.settings.env.config + + # get config variables to set figure output directory + confdir = self.state.document.settings.env.app.confdir + savefig_dir = config.ipython_savefig_dir + source_dir = os.path.dirname(self.state.document.current_source) + if savefig_dir is None: + savefig_dir = config.html_static_path + if isinstance(savefig_dir, list): + savefig_dir = savefig_dir[0] # safe to assume only one path? + savefig_dir = os.path.join(confdir, savefig_dir) + + # get regex and prompt stuff + rgxin = config.ipython_rgxin + rgxout = config.ipython_rgxout + promptin = config.ipython_promptin + promptout = config.ipython_promptout + + return savefig_dir, source_dir, rgxin, rgxout, promptin, promptout + + def setup(self): + # reset the execution count if we haven't processed this doc + #NOTE: this may be borked if there are multiple seen_doc tmp files + #check time stamp? + seen_docs = [i for i in os.listdir(tempfile.tempdir) + if i.startswith('seen_doc')] + if seen_docs: + fname = os.path.join(tempfile.tempdir, seen_docs[0]) + docs = open(fname).read().split('\n') + if not self.state.document.current_source in docs: + self.shell.IP.history_manager.reset() + self.shell.IP.execution_count = 1 + else: # haven't processed any docs yet + docs = [] + + + # get config values + (savefig_dir, source_dir, rgxin, + rgxout, promptin, promptout) = self.get_config_options() + + # and attach to shell so we don't have to pass them around + self.shell.rgxin = rgxin + self.shell.rgxout = rgxout + self.shell.promptin = promptin + self.shell.promptout = promptout + self.shell.savefig_dir = savefig_dir + self.shell.source_dir = source_dir + + # setup bookmark for saving figures directory + + self.shell.process_input_line('bookmark ipy_savedir %s'%savefig_dir, + store_history=False) + self.shell.clear_cout() + + # write the filename to a tempfile because it's been "seen" now + if not self.state.document.current_source in docs: + fd, fname = tempfile.mkstemp(prefix="seen_doc", text=True) + fout = open(fname, 'a') + fout.write(self.state.document.current_source+'\n') + fout.close() + + return rgxin, rgxout, promptin, promptout + + + def teardown(self): + # delete last bookmark + self.shell.process_input_line('bookmark -d ipy_savedir', + store_history=False) + self.shell.clear_cout() + + def run(self): + debug = False + + #TODO, any reason block_parser can't be a method of embeddable shell + # then we wouldn't have to carry these around + rgxin, rgxout, promptin, promptout = self.setup() + + options = self.options + self.shell.is_suppress = 'suppress' in options + self.shell.is_doctest = 'doctest' in options + self.shell.is_verbatim = 'verbatim' in options + + + # handle pure python code + if 'python' in self.arguments: + content = self.content + self.content = self.shell.process_pure_python(content) + + parts = '\n'.join(self.content).split('\n\n') + + lines = ['.. code-block:: ipython',''] + figures = [] + + for part in parts: + + block = block_parser(part, rgxin, rgxout, promptin, promptout) + + if len(block): + rows, figure = self.shell.process_block(block) + for row in rows: + lines.extend([' %s'%line for line in row.split('\n')]) + + if figure is not None: + figures.append(figure) + + #text = '\n'.join(lines) + #figs = '\n'.join(figures) + + for figure in figures: + lines.append('') + lines.extend(figure.split('\n')) + lines.append('') + + #print lines + if len(lines)>2: + if debug: + print '\n'.join(lines) + else: #NOTE: this raises some errors, what's it for? + #print 'INSERTING %d lines'%len(lines) + self.state_machine.insert_input( + lines, self.state_machine.input_lines.source(0)) + + text = '\n'.join(lines) + txtnode = nodes.literal_block(text, text) + txtnode['language'] = 'ipython' + #imgnode = nodes.image(figs) + + # cleanup + self.teardown() + + return []#, imgnode] + +# Enable as a proper Sphinx directive +def setup(app): + setup.app = app + + app.add_directive('ipython', IpythonDirective) + app.add_config_value('ipython_savefig_dir', None, True) + app.add_config_value('ipython_rgxin', + re.compile('In \[(\d+)\]:\s?(.*)\s*'), True) + app.add_config_value('ipython_rgxout', + re.compile('Out\[(\d+)\]:\s?(.*)\s*'), True) + app.add_config_value('ipython_promptin', 'In [%d]:', True) + app.add_config_value('ipython_promptout', 'Out[%d]:', True) + + +# Simple smoke test, needs to be converted to a proper automatic test. +def test(): + + examples = [ + r""" +In [9]: pwd +Out[9]: '/home/jdhunter/py4science/book' + +In [10]: cd bookdata/ +/home/jdhunter/py4science/book/bookdata + +In [2]: from pylab import * + +In [2]: ion() + +In [3]: im = imread('stinkbug.png') + +@savefig mystinkbug.png width=4in +In [4]: imshow(im) +Out[4]: + +""", + r""" + +In [1]: x = 'hello world' + +# string methods can be +# used to alter the string +@doctest +In [2]: x.upper() +Out[2]: 'HELLO WORLD' + +@verbatim +In [3]: x.st +x.startswith x.strip +""", + r""" + +In [130]: url = 'http://ichart.finance.yahoo.com/table.csv?s=CROX\ + .....: &d=9&e=22&f=2009&g=d&a=1&br=8&c=2006&ignore=.csv' + +In [131]: print url.split('&') +['http://ichart.finance.yahoo.com/table.csv?s=CROX', 'd=9', 'e=22', 'f=2009', 'g=d', 'a=1', 'b=8', 'c=2006', 'ignore=.csv'] + +In [60]: import urllib + +""", + r"""\ + +In [133]: import numpy.random + +@suppress +In [134]: numpy.random.seed(2358) + +@doctest +In [135]: numpy.random.rand(10,2) +Out[135]: +array([[ 0.64524308, 0.59943846], + [ 0.47102322, 0.8715456 ], + [ 0.29370834, 0.74776844], + [ 0.99539577, 0.1313423 ], + [ 0.16250302, 0.21103583], + [ 0.81626524, 0.1312433 ], + [ 0.67338089, 0.72302393], + [ 0.7566368 , 0.07033696], + [ 0.22591016, 0.77731835], + [ 0.0072729 , 0.34273127]]) + +""", + + r""" +In [106]: print x +jdh + +In [109]: for i in range(10): + .....: print i + .....: + .....: +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +""", + + r""" + +In [144]: from pylab import * + +In [145]: ion() + +# use a semicolon to suppress the output +@savefig test_hist.png width=4in +In [151]: hist(np.random.randn(10000), 100); + + +@savefig test_plot.png width=4in +In [151]: plot(np.random.randn(10000), 'o'); + """, + + r""" +# use a semicolon to suppress the output +In [151]: plt.clf() + +@savefig plot_simple.png width=4in +In [151]: plot([1,2,3]) + +@savefig hist_simple.png width=4in +In [151]: hist(np.random.randn(10000), 100); + +""", + r""" +# update the current fig +In [151]: ylabel('number') + +In [152]: title('normal distribution') + + +@savefig hist_with_text.png +In [153]: grid(True) + + """, + ] + # skip local-file depending first example: + examples = examples[1:] + + #ipython_directive.DEBUG = True # dbg + #options = dict(suppress=True) # dbg + options = dict() + for example in examples: + content = example.split('\n') + ipython_directive('debug', arguments=None, options=options, + content=content, lineno=0, + content_offset=None, block_text=None, + state=None, state_machine=None, + ) + +# Run test suite as a script +if __name__=='__main__': + if not os.path.isdir('_static'): + os.mkdir('_static') + test() + print 'All OK? Check figures in _static/' diff -Nru matplotlib-1.1.1/lib/matplotlib/sphinxext/mathmpl.py matplotlib-1.2.0/lib/matplotlib/sphinxext/mathmpl.py --- matplotlib-1.1.1/lib/matplotlib/sphinxext/mathmpl.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/sphinxext/mathmpl.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import os import sys try: diff -Nru matplotlib-1.1.1/lib/matplotlib/sphinxext/only_directives.py matplotlib-1.2.0/lib/matplotlib/sphinxext/only_directives.py --- matplotlib-1.1.1/lib/matplotlib/sphinxext/only_directives.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/sphinxext/only_directives.py 2012-10-31 00:11:14.000000000 +0000 @@ -3,6 +3,7 @@ # either html or latex. # +from __future__ import print_function from docutils.nodes import Body, Element from docutils.parsers.rst import directives diff -Nru matplotlib-1.1.1/lib/matplotlib/sphinxext/plot_directive.py matplotlib-1.2.0/lib/matplotlib/sphinxext/plot_directive.py --- matplotlib-1.1.1/lib/matplotlib/sphinxext/plot_directive.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/sphinxext/plot_directive.py 2012-10-31 00:11:14.000000000 +0000 @@ -105,7 +105,25 @@ A dictionary containing any non-standard rcParams that should be applied before each plot. + plot_apply_rcparams + By default, rcParams are applied when `context` option is not used in + a plot directive. This configuration option overrides this behaviour + and applies rcParams before each plot. + + plot_working_directory + By default, the working directory will be changed to the directory of + the example, so the code can get at its data files, if any. Also its + path will be added to `sys.path` so it can import any helper modules + sitting beside it. This configuration option can be used to specify + a central directory (also added to `sys.path`) where data files and + helper modules for all code are located. + + plot_template + Provide a customized template for preparing resturctured text. + + """ +from __future__ import print_function import sys, os, glob, shutil, imp, warnings, cStringIO, re, textwrap, \ traceback, exceptions @@ -283,6 +301,9 @@ app.add_config_value('plot_basedir', None, True) app.add_config_value('plot_html_show_formats', True, True) app.add_config_value('plot_rcparams', {}, True) + app.add_config_value('plot_apply_rcparams', False, True) + app.add_config_value('plot_working_directory', None, True) + app.add_config_value('plot_template', None, True) app.connect('doctree-read', mark_plot_labels) @@ -393,6 +414,16 @@ .. image:: {{ build_dir }}/{{ img.basename }}.pdf {% endfor %} +{{ only_texinfo }} + + {% for img in images %} + .. image:: {{ build_dir }}/{{ img.basename }}.png + {%- for option in options %} + {{ option }} + {% endfor %} + + {% endfor %} + """ exception_template = """ @@ -444,7 +475,19 @@ pwd = os.getcwd() old_sys_path = list(sys.path) - if code_path is not None: + if setup.config.plot_working_directory is not None: + try: + os.chdir(setup.config.plot_working_directory) + except OSError as err: + raise OSError(str(err) + '\n`plot_working_directory` option in' + 'Sphinx configuration file must be a valid ' + 'directory path') + except TypeError as err: + raise TypeError(str(err) + '\n`plot_working_directory` option in ' + 'Sphinx configuration file must be a string or ' + 'None') + sys.path.insert(0, setup.config.plot_working_directory) + elif code_path is not None: dirname = os.path.abspath(os.path.dirname(code_path)) os.chdir(dirname) sys.path.insert(0, dirname) @@ -563,7 +606,7 @@ ns = {} for i, code_piece in enumerate(code_pieces): - if not context: + if not context or config.plot_apply_rcparams: clear_state(config.plot_rcparams) run_code(code_piece, code_path, ns, function_name) @@ -587,7 +630,7 @@ results.append((code_piece, images)) - if not context: + if not context or config.plot_apply_rcparams: clear_state(config.plot_rcparams) return results @@ -624,9 +667,8 @@ else: function_name = None - fd = open(source_file_name, 'r') - code = fd.read() - fd.close() + with open(source_file_name, 'r') as fd: + code = fd.read() output_base = os.path.basename(source_file_name) else: source_file_name = rst_file @@ -726,6 +768,7 @@ only_html = ".. only:: html" only_latex = ".. only:: latex" + only_texinfo = ".. only:: texinfo" if j == 0: src_link = source_link @@ -733,13 +776,14 @@ src_link = None result = format_template( - TEMPLATE, + config.plot_template or TEMPLATE, dest_dir=dest_dir_link, build_dir=build_dir_link, source_link=src_link, multi_image=len(images) > 1, only_html=only_html, only_latex=only_latex, + only_texinfo=only_texinfo, options=opts, images=images, source_code=source_code, @@ -765,12 +809,11 @@ # copy script (if necessary) target_name = os.path.join(dest_dir, output_base + source_ext) - f = open(target_name, 'w') - if source_file_name == rst_file: - code_escaped = unescape_doctest(code) - else: - code_escaped = code - f.write(code_escaped) - f.close() + with open(target_name, 'w') as f: + if source_file_name == rst_file: + code_escaped = unescape_doctest(code) + else: + code_escaped = code + f.write(code_escaped) return errors diff -Nru matplotlib-1.1.1/lib/matplotlib/spines.py matplotlib-1.2.0/lib/matplotlib/spines.py --- matplotlib-1.1.1/lib/matplotlib/spines.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/spines.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,4 +1,4 @@ -from __future__ import division +from __future__ import division, print_function import matplotlib rcParams = matplotlib.rcParams diff -Nru matplotlib-1.1.1/lib/matplotlib/stackplot.py matplotlib-1.2.0/lib/matplotlib/stackplot.py --- matplotlib-1.1.1/lib/matplotlib/stackplot.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/stackplot.py 2012-11-06 15:42:20.000000000 +0000 @@ -0,0 +1,60 @@ +""" +Stacked area plot for 1D arrays inspired by Douglas Y'barbo's stackoverflow +answer: +http://stackoverflow.com/questions/2225995/how-can-i-create-stacked-line-graph-with-matplotlib + +(http://stackoverflow.com/users/66549/doug) + +""" +import numpy as np + +__all__ = ['stackplot'] + + +def stackplot(axes, x, *args, **kwargs): + """Draws a stacked area plot. + + *x* : 1d array of dimension N + + *y* : 2d array of dimension MxN, OR any number 1d arrays each of dimension + 1xN. The data is assumed to be unstacked. Each of the following + calls is legal:: + + stackplot(x, y) # where y is MxN + stackplot(x, y1, y2, y3, y4) # where y1, y2, y3, y4, are all 1xNm + + Keyword arguments: + + *colors* : A list or tuple of colors. These will be cycled through and + used to colour the stacked areas. + All other keyword arguments are passed to + :func:`~matplotlib.Axes.fill_between` + + Returns *r* : A list of + :class:`~matplotlib.collections.PolyCollection`, one for each + element in the stacked area plot. + """ + + if len(args) == 1: + y = np.atleast_2d(*args) + elif len(args) > 1: + y = np.row_stack(args) + + colors = kwargs.pop('colors', None) + if colors is not None: + axes.set_color_cycle(colors) + + # Assume data passed has not been 'stacked', so stack it here. + y_stack = np.cumsum(y, axis=0) + + r = [] + + # Color between x = 0 and the first array. + r.append(axes.fill_between(x, 0, y_stack[0, :], + facecolor=axes._get_lines.color_cycle.next(), **kwargs)) + + # Color between array i-1 and array i + for i in xrange(len(y) - 1): + r.append(axes.fill_between(x, y_stack[i, :], y_stack[i + 1, :], + facecolor=axes._get_lines.color_cycle.next(), **kwargs)) + return r diff -Nru matplotlib-1.1.1/lib/matplotlib/streamplot.py matplotlib-1.2.0/lib/matplotlib/streamplot.py --- matplotlib-1.1.1/lib/matplotlib/streamplot.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/streamplot.py 2012-11-06 16:32:23.000000000 +0000 @@ -0,0 +1,592 @@ +""" +Streamline plotting for 2D vector fields. + +""" +from __future__ import division +import numpy as np +import matplotlib +import matplotlib.cm as cm +import matplotlib.colors as mcolors +import matplotlib.collections as mcollections +import matplotlib.patches as patches + + +__all__ = ['streamplot'] + + +def streamplot(axes, x, y, u, v, density=1, linewidth=None, color=None, + cmap=None, norm=None, arrowsize=1, arrowstyle='-|>', + minlength=0.1, transform=None): + """Draws streamlines of a vector flow. + + *x*, *y* : 1d arrays + an *evenly spaced* grid. + *u*, *v* : 2d arrays + x and y-velocities. Number of rows should match length of y, and + the number of columns should match x. + *density* : float or 2-tuple + Controls the closeness of streamlines. When `density = 1`, the domain + is divided into a 25x25 grid---*density* linearly scales this grid. + Each cell in the grid can have, at most, one traversing streamline. + For different densities in each direction, use [density_x, density_y]. + *linewidth* : numeric or 2d array + vary linewidth when given a 2d array with the same shape as velocities. + *color* : matplotlib color code, or 2d array + Streamline color. When given an array with the same shape as + velocities, *color* values are converted to colors using *cmap*. + *cmap* : :class:`~matplotlib.colors.Colormap` + Colormap used to plot streamlines and arrows. Only necessary when using + an array input for *color*. + *norm* : :class:`~matplotlib.colors.Normalize` + Normalize object used to scale luminance data to 0, 1. If None, stretch + (min, max) to (0, 1). Only necessary when *color* is an array. + *arrowsize* : float + Factor scale arrow size. + *arrowstyle* : str + Arrow style specification. + See :class:`~matplotlib.patches.FancyArrowPatch`. + *minlength* : float + Minimum length of streamline in axes coordinates. + + Returns: + + *stream_container* : StreamplotSet + Container object with attributes + lines: `matplotlib.collections.LineCollection` of streamlines + arrows: collection of `matplotlib.patches.FancyArrowPatch` + objects representing arrows half-way along stream + lines. + This container will probably change in the future to allow changes + to the colormap, alpha, etc. for both lines and arrows, but these + changes should be backward compatible. + + """ + grid = Grid(x, y) + mask = StreamMask(density) + dmap = DomainMap(grid, mask) + + # default to data coordinates + if transform is None: + transform = axes.transData + + if color is None: + color = axes._get_lines.color_cycle.next() + + if linewidth is None: + linewidth = matplotlib.rcParams['lines.linewidth'] + + line_kw = {} + arrow_kw = dict(arrowstyle=arrowstyle, mutation_scale=10 * arrowsize) + + use_multicolor_lines = isinstance(color, np.ndarray) + if use_multicolor_lines: + assert color.shape == grid.shape + line_colors = [] + else: + line_kw['color'] = color + arrow_kw['color'] = color + + if isinstance(linewidth, np.ndarray): + assert linewidth.shape == grid.shape + line_kw['linewidth'] = [] + else: + line_kw['linewidth'] = linewidth + arrow_kw['linewidth'] = linewidth + + ## Sanity checks. + assert u.shape == grid.shape + assert v.shape == grid.shape + + if np.any(np.isnan(u)): + u = np.ma.array(u, mask=np.isnan(u)) + if np.any(np.isnan(v)): + v = np.ma.array(v, mask=np.isnan(v)) + + integrate = get_integrator(u, v, dmap, minlength) + + trajectories = [] + for xm, ym in _gen_starting_points(mask.shape): + if mask[ym, xm] == 0: + xg, yg = dmap.mask2grid(xm, ym) + t = integrate(xg, yg) + if t is not None: + trajectories.append(t) + + if use_multicolor_lines: + if norm is None: + norm = mcolors.normalize(color.min(), color.max()) + if cmap is None: + cmap = cm.get_cmap(matplotlib.rcParams['image.cmap']) + else: + cmap = cm.get_cmap(cmap) + + streamlines = [] + arrows = [] + for t in trajectories: + tgx = np.array(t[0]) + tgy = np.array(t[1]) + # Rescale from grid-coordinates to data-coordinates. + tx = np.array(t[0]) * grid.dx + grid.x_origin + ty = np.array(t[1]) * grid.dy + grid.y_origin + + points = np.transpose([tx, ty]).reshape(-1, 1, 2) + streamlines.extend(np.hstack([points[:-1], points[1:]])) + + # Add arrows half way along each trajectory. + s = np.cumsum(np.sqrt(np.diff(tx) ** 2 + np.diff(ty) ** 2)) + n = np.searchsorted(s, s[-1] / 2.) + arrow_tail = (tx[n], ty[n]) + arrow_head = (np.mean(tx[n:n + 2]), np.mean(ty[n:n + 2])) + + if isinstance(linewidth, np.ndarray): + line_widths = interpgrid(linewidth, tgx, tgy)[:-1] + line_kw['linewidth'].extend(line_widths) + arrow_kw['linewidth'] = line_widths[n] + + if use_multicolor_lines: + color_values = interpgrid(color, tgx, tgy)[:-1] + line_colors.extend(color_values) + arrow_kw['color'] = cmap(norm(color_values[n])) + + p = patches.FancyArrowPatch(arrow_tail, + arrow_head, + transform=transform, + **arrow_kw) + axes.add_patch(p) + arrows.append(p) + + lc = mcollections.LineCollection(streamlines, + transform=transform, + **line_kw) + if use_multicolor_lines: + lc.set_array(np.asarray(line_colors)) + lc.set_cmap(cmap) + lc.set_norm(norm) + axes.add_collection(lc) + + axes.update_datalim(((x.min(), y.min()), (x.max(), y.max()))) + axes.autoscale_view(tight=True) + + ac = matplotlib.collections.PatchCollection(arrows) + stream_container = StreamplotSet(lc, ac) + return stream_container + + +class StreamplotSet(object): + + def __init__(self, lines, arrows, **kwargs): + self.lines = lines + self.arrows = arrows + + +# Coordinate definitions +#======================== + +class DomainMap(object): + """Map representing different coordinate systems. + + Coordinate definitions: + + * axes-coordinates goes from 0 to 1 in the domain. + * data-coordinates are specified by the input x-y coordinates. + * grid-coordinates goes from 0 to N and 0 to M for an N x M grid, + where N and M match the shape of the input data. + * mask-coordinates goes from 0 to N and 0 to M for an N x M mask, + where N and M are user-specified to control the density of streamlines. + + This class also has methods for adding trajectories to the StreamMask. + Before adding a trajectory, run `start_trajectory` to keep track of regions + crossed by a given trajectory. Later, if you decide the trajectory is bad + (e.g. if the trajectory is very short) just call `undo_trajectory`. + """ + + def __init__(self, grid, mask): + self.grid = grid + self.mask = mask + ## Constants for conversion between grid- and mask-coordinates + self.x_grid2mask = float(mask.nx - 1) / grid.nx + self.y_grid2mask = float(mask.ny - 1) / grid.ny + + self.x_mask2grid = 1. / self.x_grid2mask + self.y_mask2grid = 1. / self.y_grid2mask + + self.x_data2grid = grid.nx / grid.width + self.y_data2grid = grid.ny / grid.height + + def grid2mask(self, xi, yi): + """Return nearest space in mask-coords from given grid-coords.""" + return int((xi * self.x_grid2mask) + 0.5), \ + int((yi * self.y_grid2mask) + 0.5) + + def mask2grid(self, xm, ym): + return xm * self.x_mask2grid, ym * self.y_mask2grid + + def data2grid(self, xd, yd): + return xd * self.x_data2grid, yd * self.y_data2grid + + def start_trajectory(self, xg, yg): + xm, ym = self.grid2mask(xg, yg) + self.mask._start_trajectory(xm, ym) + + def reset_start_point(self, xg, yg): + xm, ym = self.grid2mask(xg, yg) + self.mask._current_xy = (xm, ym) + + def update_trajectory(self, xg, yg): + if not self.grid.within_grid(xg, yg): + raise InvalidIndexError + xm, ym = self.grid2mask(xg, yg) + self.mask._update_trajectory(xm, ym) + + def undo_trajectory(self): + self.mask._undo_trajectory() + + +class Grid(object): + """Grid of data.""" + def __init__(self, x, y): + + if len(x.shape) == 2: + x_row = x[0] + assert np.allclose(x_row, x) + x = x_row + else: + assert len(x.shape) == 1 + + if len(y.shape) == 2: + y_col = y[:, 0] + assert np.allclose(y_col, y.T) + y = y_col + else: + assert len(y.shape) == 1 + + self.nx = len(x) + self.ny = len(y) + + self.dx = x[1] - x[0] + self.dy = y[1] - y[0] + + self.x_origin = x[0] + self.y_origin = y[0] + + self.width = x[-1] - x[0] + self.height = y[-1] - y[0] + + @property + def shape(self): + return self.ny, self.nx + + def within_grid(self, xi, yi): + """Return True if point is a valid index of grid.""" + # Note that xi/yi can be floats; so, for example, we can't simply check + # `xi < self.nx` since `xi` can be `self.nx - 1 < xi < self.nx` + return xi >= 0 and xi <= self.nx - 1 and yi >= 0 and yi <= self.ny - 1 + + +class StreamMask(object): + """Mask to keep track of discrete regions crossed by streamlines. + + The resolution of this grid determines the approximate spacing between + trajectories. Streamlines are only allowed to pass through zeroed cells: + When a streamline enters a cell, that cell is set to 1, and no new + streamlines are allowed to enter. + """ + + def __init__(self, density): + if np.isscalar(density): + assert density > 0 + self.nx = self.ny = int(30 * density) + else: + assert len(density) == 2 + self.nx = int(25 * density[0]) + self.ny = int(25 * density[1]) + self._mask = np.zeros((self.ny, self.nx)) + self.shape = self._mask.shape + + self._current_xy = None + + def __getitem__(self, *args): + return self._mask.__getitem__(*args) + + def _start_trajectory(self, xm, ym): + """Start recording streamline trajectory""" + self._traj = [] + self._update_trajectory(xm, ym) + + def _undo_trajectory(self): + """Remove current trajectory from mask""" + for t in self._traj: + self._mask.__setitem__(t, 0) + + def _update_trajectory(self, xm, ym): + """Update current trajectory position in mask. + + If the new position has already been filled, raise `InvalidIndexError`. + """ + if self._current_xy != (xm, ym): + if self[ym, xm] == 0: + self._traj.append((ym, xm)) + self._mask[ym, xm] = 1 + self._current_xy = (xm, ym) + else: + raise InvalidIndexError + + +class InvalidIndexError(Exception): + pass + + +class TerminateTrajectory(Exception): + pass + + +# Integrator definitions +#======================== + +def get_integrator(u, v, dmap, minlength): + + # rescale velocity onto grid-coordinates for integrations. + u, v = dmap.data2grid(u, v) + + # speed (path length) will be in axes-coordinates + u_ax = u / dmap.grid.nx + v_ax = v / dmap.grid.ny + speed = np.ma.sqrt(u_ax ** 2 + v_ax ** 2) + + def forward_time(xi, yi): + ds_dt = interpgrid(speed, xi, yi) + if ds_dt == 0: + raise TerminateTrajectory() + dt_ds = 1. / ds_dt + ui = interpgrid(u, xi, yi) + vi = interpgrid(v, xi, yi) + return ui * dt_ds, vi * dt_ds + + def backward_time(xi, yi): + dxi, dyi = forward_time(xi, yi) + return -dxi, -dyi + + def integrate(x0, y0): + """Return x, y grid-coordinates of trajectory based on starting point. + + Integrate both forward and backward in time from starting point in + grid coordinates. + + Integration is terminated when a trajectory reaches a domain boundary + or when it crosses into an already occupied cell in the StreamMask. The + resulting trajectory is None if it is shorter than `minlength`. + """ + + dmap.start_trajectory(x0, y0) + sf, xf_traj, yf_traj = _integrate_rk12(x0, y0, dmap, forward_time) + dmap.reset_start_point(x0, y0) + sb, xb_traj, yb_traj = _integrate_rk12(x0, y0, dmap, backward_time) + # combine forward and backward trajectories + stotal = sf + sb + x_traj = xb_traj[::-1] + xf_traj[1:] + y_traj = yb_traj[::-1] + yf_traj[1:] + + if stotal > minlength: + return x_traj, y_traj + else: # reject short trajectories + dmap.undo_trajectory() + return None + + return integrate + + +def _integrate_rk12(x0, y0, dmap, f): + """2nd-order Runge-Kutta algorithm with adaptive step size. + + This method is also referred to as the improved Euler's method, or Heun's + method. This method is favored over higher-order methods because: + + 1. To get decent looking trajectories and to sample every mask cell + on the trajectory we need a small timestep, so a lower order + solver doesn't hurt us unless the data is *very* high resolution. + In fact, for cases where the user inputs + data smaller or of similar grid size to the mask grid, the higher + order corrections are negligible because of the very fast linear + interpolation used in `interpgrid`. + + 2. For high resolution input data (i.e. beyond the mask + resolution), we must reduce the timestep. Therefore, an adaptive + timestep is more suited to the problem as this would be very hard + to judge automatically otherwise. + + This integrator is about 1.5 - 2x as fast as both the RK4 and RK45 + solvers in most setups on my machine. I would recommend removing the + other two to keep things simple. + """ + ## This error is below that needed to match the RK4 integrator. It + ## is set for visual reasons -- too low and corners start + ## appearing ugly and jagged. Can be tuned. + maxerror = 0.003 + + ## This limit is important (for all integrators) to avoid the + ## trajectory skipping some mask cells. We could relax this + ## condition if we use the code which is commented out below to + ## increment the location gradually. However, due to the efficient + ## nature of the interpolation, this doesn't boost speed by much + ## for quite a bit of complexity. + maxds = min(1. / dmap.mask.nx, 1. / dmap.mask.ny, 0.1) + + ds = maxds + stotal = 0 + xi = x0 + yi = y0 + xf_traj = [] + yf_traj = [] + + while dmap.grid.within_grid(xi, yi): + xf_traj.append(xi) + yf_traj.append(yi) + try: + k1x, k1y = f(xi, yi) + k2x, k2y = f(xi + ds * k1x, + yi + ds * k1y) + except IndexError: + # Out of the domain on one of the intermediate integration steps. + # Take an Euler step to the boundary to improve neatness. + ds, xf_traj, yf_traj = _euler_step(xf_traj, yf_traj, dmap, f) + stotal += ds + break + except TerminateTrajectory: + break + + dx1 = ds * k1x + dy1 = ds * k1y + dx2 = ds * 0.5 * (k1x + k2x) + dy2 = ds * 0.5 * (k1y + k2y) + + nx, ny = dmap.grid.shape + # Error is normalized to the axes coordinates + error = np.sqrt(((dx2 - dx1) / nx) ** 2 + ((dy2 - dy1) / ny) ** 2) + + # Only save step if within error tolerance + if error < maxerror: + xi += dx2 + yi += dy2 + try: + dmap.update_trajectory(xi, yi) + except InvalidIndexError: + break + if (stotal + ds) > 2: + break + stotal += ds + + # recalculate stepsize based on step error + if error == 0: + ds = maxds + else: + ds = min(maxds, 0.85 * ds * (maxerror / error) ** 0.5) + + return stotal, xf_traj, yf_traj + + +def _euler_step(xf_traj, yf_traj, dmap, f): + """Simple Euler integration step that extends streamline to boundary.""" + ny, nx = dmap.grid.shape + xi = xf_traj[-1] + yi = yf_traj[-1] + cx, cy = f(xi, yi) + if cx == 0: + dsx = np.inf + elif cx < 0: + dsx = xi / -cx + else: + dsx = (nx - 1 - xi) / cx + if cy == 0: + dsy = np.inf + elif cy < 0: + dsy = yi / -cy + else: + dsy = (ny - 1 - yi) / cy + ds = min(dsx, dsy) + xf_traj.append(xi + cx * ds) + yf_traj.append(yi + cy * ds) + return ds, xf_traj, yf_traj + + +# Utility functions +#======================== + +def interpgrid(a, xi, yi): + """Fast 2D, linear interpolation on an integer grid""" + + Ny, Nx = np.shape(a) + if isinstance(xi, np.ndarray): + x = xi.astype(np.int) + y = yi.astype(np.int) + # Check that xn, yn don't exceed max index + xn = np.clip(x + 1, 0, Nx - 1) + yn = np.clip(y + 1, 0, Ny - 1) + else: + x = np.int(xi) + y = np.int(yi) + # conditional is faster than clipping for integers + if x == (Nx - 2): + xn = x + else: + xn = x + 1 + if y == (Ny - 2): + yn = y + else: + yn = y + 1 + + a00 = a[y, x] + a01 = a[y, xn] + a10 = a[yn, x] + a11 = a[yn, xn] + xt = xi - x + yt = yi - y + a0 = a00 * (1 - xt) + a01 * xt + a1 = a10 * (1 - xt) + a11 * xt + ai = a0 * (1 - yt) + a1 * yt + + if not isinstance(xi, np.ndarray): + if np.ma.is_masked(ai): + raise TerminateTrajectory + + return ai + + +def _gen_starting_points(shape): + """Yield starting points for streamlines. + + Trying points on the boundary first gives higher quality streamlines. + This algorithm starts with a point on the mask corner and spirals inward. + This algorithm is inefficient, but fast compared to rest of streamplot. + """ + ny, nx = shape + xfirst = 0 + yfirst = 1 + xlast = nx - 1 + ylast = ny - 1 + x, y = 0, 0 + i = 0 + direction = 'right' + for i in xrange(nx * ny): + + yield x, y + + if direction == 'right': + x += 1 + if x >= xlast: + xlast -= 1 + direction = 'up' + elif direction == 'up': + y += 1 + if y >= ylast: + ylast -= 1 + direction = 'left' + elif direction == 'left': + x -= 1 + if x <= xfirst: + xfirst += 1 + direction = 'down' + elif direction == 'down': + y -= 1 + if y <= yfirst: + yfirst += 1 + direction = 'right' diff -Nru matplotlib-1.1.1/lib/matplotlib/table.py matplotlib-1.2.0/lib/matplotlib/table.py --- matplotlib-1.1.1/lib/matplotlib/table.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/table.py 2012-11-06 16:32:23.000000000 +0000 @@ -19,7 +19,7 @@ License : matplotlib license """ -from __future__ import division +from __future__ import division, print_function import warnings import artist @@ -31,7 +31,6 @@ from transforms import Bbox - class Cell(Rectangle): """ A cell is a Rectangle with some associated text. @@ -49,18 +48,17 @@ # Call base Rectangle.__init__(self, xy, width=width, height=height, - edgecolor=edgecolor, facecolor=facecolor, - ) + edgecolor=edgecolor, facecolor=facecolor) self.set_clip_on(False) # Create text object - if loc is None: loc = 'right' + if loc is None: + loc = 'right' self._loc = loc self._text = Text(x=xy[0], y=xy[1], text=text, fontproperties=fontproperties) self._text.set_clip_on(False) - def set_transform(self, trans): Rectangle.set_transform(self, trans) # the text does not get the transform! @@ -93,7 +91,8 @@ @allow_rasterization def draw(self, renderer): - if not self.get_visible(): return + if not self.get_visible(): + return # draw the rectangle Rectangle.draw(self, renderer) @@ -134,14 +133,14 @@ def get_required_width(self, renderer): """ Get width required for this cell. """ - l,b,w,h = self.get_text_bounds(renderer) + l, b, w, h = self.get_text_bounds(renderer) return w * (1.0 + (2.0 * self.PAD)) - def set_text_props(self, **kwargs): 'update the text properties with kwargs' self._text.update(kwargs) + class Table(Artist): """ Create a table of cells. @@ -155,25 +154,24 @@ Return value is a sequence of text, line and patch instances that make up the table """ - codes = {'best' : 0, - 'upper right' : 1, # default - 'upper left' : 2, - 'lower left' : 3, - 'lower right' : 4, - 'center left' : 5, - 'center right' : 6, - 'lower center' : 7, - 'upper center' : 8, - 'center' : 9, - - 'top right' : 10, - 'top left' : 11, - 'bottom left' : 12, - 'bottom right' : 13, - 'right' : 14, - 'left' : 15, - 'top' : 16, - 'bottom' : 17, + codes = {'best': 0, + 'upper right': 1, # default + 'upper left': 2, + 'lower left': 3, + 'lower right': 4, + 'center left': 5, + 'center right': 6, + 'lower center': 7, + 'upper center': 8, + 'center': 9, + 'top right': 10, + 'top left': 11, + 'bottom left': 12, + 'bottom right': 13, + 'right': 14, + 'left': 15, + 'top': 16, + 'bottom': 17, } FONTSIZE = 10 @@ -184,9 +182,12 @@ Artist.__init__(self) if is_string_like(loc) and loc not in self.codes: - warnings.warn('Unrecognized location %s. Falling back on bottom; valid locations are\n%s\t' %(loc, '\n\t'.join(self.codes.keys()))) + warnings.warn('Unrecognized location %s. Falling back on ' + 'bottom; valid locations are\n%s\t' % + (loc, '\n\t'.join(self.codes.iterkeys()))) loc = 'bottom' - if is_string_like(loc): loc = self.codes.get(loc, 1) + if is_string_like(loc): + loc = self.codes.get(loc, 1) self.set_figure(ax.figure) self._axes = ax self._loc = loc @@ -205,7 +206,7 @@ def add_cell(self, row, col, *args, **kwargs): """ Add a cell to the table. """ - xy = (0,0) + xy = (0, 0) cell = Cell(xy, *args, **kwargs) cell.set_figure(self.figure) @@ -215,18 +216,21 @@ self._cells[(row, col)] = cell def _approx_text_height(self): - return self.FONTSIZE/72.0*self.figure.dpi/self._axes.bbox.height * 1.2 + return (self.FONTSIZE / 72.0 * self.figure.dpi / + self._axes.bbox.height * 1.2) @allow_rasterization def draw(self, renderer): - # Need a renderer to do hit tests on mouseevent; assume the last one will do + # Need a renderer to do hit tests on mouseevent; assume the last one + # will do if renderer is None: renderer = self._cachedRenderer if renderer is None: raise RuntimeError('No renderer defined') self._cachedRenderer = renderer - if not self.get_visible(): return + if not self.get_visible(): + return renderer.open_group('table') self._update_positions(renderer) @@ -243,29 +247,30 @@ Only include those in the range (0,0) to (maxRow, maxCol)""" boxes = [self._cells[pos].get_window_extent(renderer) - for pos in self._cells.keys() + for pos in self._cells.iterkeys() if pos[0] >= 0 and pos[1] >= 0] bbox = Bbox.union(boxes) return bbox.inverse_transformed(self.get_transform()) - def contains(self,mouseevent): + def contains(self, mouseevent): """Test whether the mouse event occurred in the table. Returns T/F, {} """ - if callable(self._contains): return self._contains(self,mouseevent) + if callable(self._contains): + return self._contains(self, mouseevent) # TODO: Return index of the cell containing the cursor so that the user # doesn't have to bind to each one individually. if self._cachedRenderer is not None: boxes = [self._cells[pos].get_window_extent(self._cachedRenderer) - for pos in self._cells.keys() + for pos in self._cells.iterkeys() if pos[0] >= 0 and pos[1] >= 0] - bbox = bbox_all(boxes) - return bbox.contains(mouseevent.x,mouseevent.y),{} + bbox = Bbox.union(boxes) + return bbox.contains(mouseevent.x, mouseevent.y), {} else: - return False,{} + return False, {} def get_children(self): 'Return the Artists contained by the table' @@ -274,8 +279,10 @@ def get_window_extent(self, renderer): 'Return the bounding box of the table in window coords' - boxes = [c.get_window_extent(renderer) for c in self._cells] - return bbox_all(boxes) + boxes = [cell.get_window_extent(renderer) + for cell in self._cells.values()] + + return Bbox.union(boxes) def _do_cell_alignment(self): """ Calculate row heights and column widths. @@ -345,7 +352,8 @@ cells = [] for key, cell in self._cells.iteritems(): # ignore auto-sized columns - if key[1] in self._autoColumns: continue + if key[1] in self._autoColumns: + continue size = cell.auto_set_font_size(renderer) fontsize = min(fontsize, size) cells.append(cell) @@ -375,8 +383,8 @@ for c in self._cells.itervalues(): x, y = c.get_x(), c.get_y() - c.set_x(x+ox) - c.set_y(y+oy) + c.set_x(x + ox) + c.set_y(y + oy) def _update_positions(self, renderer): # called from renderer to allow more precise estimates of @@ -393,12 +401,12 @@ self._do_cell_alignment() bbox = self._get_grid_bbox(renderer) - l,b,w,h = bbox.bounds + l, b, w, h = bbox.bounds if self._bbox is not None: # Position according to bbox rl, rb, rw, rh = self._bbox - self.scale(rw/w, rh/h) + self.scale(rw / w, rh / h) ox = rl - l oy = rb - b self._do_cell_alignment() @@ -407,8 +415,8 @@ (BEST, UR, UL, LL, LR, CL, CR, LC, UC, C, TR, TL, BL, BR, R, L, T, B) = range(len(self.codes)) # defaults for center - ox = (0.5-w/2)-l - oy = (0.5-h/2)-b + ox = (0.5 - w / 2) - l + oy = (0.5 - h / 2) - b if self._loc in (UL, LL, CL): # left ox = self.AXESPAD - l if self._loc in (BEST, UR, LR, R, CR): # right @@ -418,26 +426,26 @@ if self._loc in (LL, LR, LC): # lower oy = self.AXESPAD - b if self._loc in (LC, UC, C): # center x - ox = (0.5-w/2)-l + ox = (0.5 - w / 2) - l if self._loc in (CL, CR, C): # center y - oy = (0.5-h/2)-b + oy = (0.5 - h / 2) - b if self._loc in (TL, BL, L): # out left - ox = - (l + w) + ox = - (l + w) if self._loc in (TR, BR, R): # out right ox = 1.0 - l if self._loc in (TR, TL, T): # out top oy = 1.0 - b if self._loc in (BL, BR, B): # out bottom - oy = - (b + h) + oy = - (b + h) self._offset(ox, oy) - def get_celld(self): 'return a dict of cells in the table' return self._cells + def table(ax, cellText=None, cellColours=None, cellLoc='right', colWidths=None, @@ -476,7 +484,7 @@ # Set colwidths if not given if colWidths is None: - colWidths = [1.0/cols] * cols + colWidths = [1.0 / cols] * cols # Check row and column labels rowLabelWidth = 0 @@ -513,7 +521,7 @@ # Add the cells for row in xrange(rows): for col in xrange(cols): - table.add_cell(row+offset, col, + table.add_cell(row + offset, col, width=colWidths[col], height=height, text=cellText[row][col], facecolor=cellColours[row][col], @@ -529,7 +537,7 @@ # Do row labels if rowLabels is not None: for row in xrange(rows): - table.add_cell(row+offset, -1, + table.add_cell(row + offset, -1, width=rowLabelWidth or 1e-15, height=height, text=rowLabels[row], facecolor=rowColours[row], loc=rowLoc) diff -Nru matplotlib-1.1.1/lib/matplotlib/testing/__init__.py matplotlib-1.2.0/lib/matplotlib/testing/__init__.py --- matplotlib-1.1.1/lib/matplotlib/testing/__init__.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/testing/__init__.py 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1 @@ +from __future__ import print_function diff -Nru matplotlib-1.1.1/lib/matplotlib/testing/compare.py matplotlib-1.2.0/lib/matplotlib/testing/compare.py --- matplotlib-1.1.1/lib/matplotlib/testing/compare.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/testing/compare.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,10 +1,18 @@ #======================================================================= + """ A set of utilities for comparing results. """ #======================================================================= +from __future__ import division + import matplotlib from matplotlib.testing.noseclasses import ImageComparisonFailure +from matplotlib.testing import image_util, util +from matplotlib import _png +from matplotlib import _get_configdir +from distutils import version +import hashlib import math import operator import os @@ -12,6 +20,7 @@ import shutil import subprocess import sys +from functools import reduce #======================================================================= @@ -22,6 +31,15 @@ ] #----------------------------------------------------------------------- + +def make_test_filename(fname, purpose): + """ + Make a new filename by inserting `purpose` before the file's + extension. + """ + base, ext = os.path.splitext(fname) + return '%s-%s%s' % (base, purpose, ext) + def compare_float( expected, actual, relTol = None, absTol = None ): """Fail if the floating point values are not close enough, with the givem message. @@ -32,7 +50,7 @@ exMsg = "You haven't specified a 'relTol' relative tolerance " exMsg += "or a 'absTol' absolute tolerance function argument. " exMsg += "You must specify one." - raise ValueError, exMsg + raise ValueError(exMsg) msg = "" @@ -81,35 +99,68 @@ # A dictionary that maps filename extensions to functions that map # parameters old and new to a list that can be passed to Popen to # convert files with that extension to png format. +def get_cache_dir(): + cache_dir = os.path.join(_get_configdir(), 'test_cache') + if not os.path.exists(cache_dir): + try: + os.makedirs(cache_dir) + except IOError: + return None + if not os.access(cache_dir, os.W_OK): + return None + return cache_dir + +def get_file_hash(path, block_size=2**20): + md5 = hashlib.md5() + with open(path, 'rb') as fd: + while True: + data = fd.read(block_size) + if not data: + break + md5.update(data) + return md5.hexdigest() + converter = { } def make_external_conversion_command(cmd): - def convert(*args): - cmdline = cmd(*args) - oldname, newname = args + def convert(old, new): + cmdline = cmd(old, new) pipe = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = pipe.communicate() errcode = pipe.wait() - if not os.path.exists(newname) or errcode: + if not os.path.exists(new) or errcode: msg = "Conversion command failed:\n%s\n" % ' '.join(cmdline) if stdout: msg += "Standard output:\n%s\n" % stdout if stderr: msg += "Standard error:\n%s\n" % stderr - raise IOError, msg + raise IOError(msg) + return convert if matplotlib.checkdep_ghostscript() is not None: - # FIXME: make checkdep_ghostscript return the command - if sys.platform == 'win32': - gs = 'gswin32c' - else: - gs = 'gs' - cmd = lambda old, new: \ - [gs, '-q', '-sDEVICE=png16m', '-dNOPAUSE', '-dBATCH', - '-sOutputFile=' + new, old] - converter['pdf'] = make_external_conversion_command(cmd) - converter['eps'] = make_external_conversion_command(cmd) + def make_ghostscript_conversion_command(): + # FIXME: make checkdep_ghostscript return the command + if sys.platform == 'win32': + gs = 'gswin32c' + else: + gs = 'gs' + cmd = [gs, '-q', '-sDEVICE=png16m', '-sOutputFile=-'] + + process = util.MiniExpect(cmd) + + def do_convert(old, new): + process.expect("GS>") + process.sendline("(%s) run" % old.replace('\\', '/')) + with open(new, 'wb') as fd: + process.expect(">>showpage, press to continue<<", fd) + process.sendline('') + + return do_convert + + converter['pdf'] = make_ghostscript_conversion_command() + converter['eps'] = make_ghostscript_conversion_command() + if matplotlib.checkdep_inkscape() is not None: cmd = lambda old, new: \ @@ -121,22 +172,45 @@ on this system.''' return ['png'] + converter.keys() -def convert(filename): +def convert(filename, cache): ''' - Convert the named file into a png file. - Returns the name of the created file. + Convert the named file into a png file. Returns the name of the + created file. + + If *cache* is True, the result of the conversion is cached in + `~/.matplotlib/test_cache/`. The caching is based on a hash of the + exact contents of the input file. The is no limit on the size of + the cache, so it may need to be manually cleared periodically. ''' base, extension = filename.rsplit('.', 1) if extension not in converter: - raise ImageComparisonFailure, "Don't know how to convert %s files to png" % extension + raise ImageComparisonFailure("Don't know how to convert %s files to png" % extension) newname = base + '_' + extension + '.png' if not os.path.exists(filename): - raise IOError, "'%s' does not exist" % filename + raise IOError("'%s' does not exist" % filename) + # Only convert the file if the destination doesn't already exist or # is out of date. if (not os.path.exists(newname) or os.stat(newname).st_mtime < os.stat(filename).st_mtime): + if cache: + cache_dir = get_cache_dir() + else: + cache_dir = None + + if cache_dir is not None: + hash = get_file_hash(filename) + new_ext = os.path.splitext(newname)[1] + cached_file = os.path.join(cache_dir, hash + new_ext) + if os.path.exists(cached_file): + shutil.copyfile(cached_file, newname) + return newname + converter[extension](filename, newname) + + if cache_dir is not None: + shutil.copyfile(newname, cached_file) + return newname verifiers = { } @@ -146,7 +220,7 @@ Verify the file through some sort of verification tool. """ if not os.path.exists(filename): - raise IOError, "'%s' does not exist" % filename + raise IOError("'%s' does not exist" % filename) base, extension = filename.rsplit('.', 1) verifier = verifiers.get(extension, None) if verifier is not None: @@ -160,7 +234,7 @@ msg += "Standard output:\n%s\n" % stdout if stderr: msg += "Standard error:\n%s\n" % stderr - raise IOError, msg + raise IOError(msg) # Turning this off, because it seems to cause multiprocessing issues if matplotlib.checkdep_xmllint() and False: @@ -171,11 +245,47 @@ # clip the images to the same size -- this is useful only when # comparing eps to pdf if actual_path[-7:-4] == 'eps' and expected_path[-7:-4] == 'pdf': - aw, ah = actual_image.size - ew, eh = expected_image.size - actual_image = actual_image.crop((aw/2-ew/2, ah/2-eh/2, aw/2+ew/2, ah/2+eh/2)) + aw, ah = actual_image.shape + ew, eh = expected_image.shape + actual_image = actual_image[int(aw/2-ew/2):int(aw/2+ew/2),int(ah/2-eh/2):int(ah/2+eh/2)] return actual_image, expected_image +def calculate_rms(expectedImage, actualImage): + # compare the resulting image histogram functions + expected_version = version.LooseVersion("1.6") + found_version = version.LooseVersion(np.__version__) + + # On Numpy 1.6, we can use bincount with minlength, which is much faster than + # using histogram + if found_version >= expected_version: + rms = 0 + + for i in xrange(0, 3): + h1p = expectedImage[:,:,i] + h2p = actualImage[:,:,i] + + h1h = np.bincount(h1p.ravel(), minlength=256) + h2h = np.bincount(h2p.ravel(), minlength=256) + + rms += np.sum(np.power((h1h-h2h), 2)) + else: + rms = 0 + bins = np.arange(257) + + for i in xrange(0, 3): + h1p = expectedImage[:,:,i] + h2p = actualImage[:,:,i] + + h1h = np.histogram(h1p, bins=bins)[0] + h2h = np.histogram(h2p, bins=bins)[0] + + rms += np.sum(np.power((h1h-h2h), 2)) + + rms = np.sqrt(rms / (256 * 3)) + + return rms + + def compare_images( expected, actual, tol, in_decorator=False ): '''Compare two image files - not the greatest, but fast and good enough. @@ -195,49 +305,48 @@ True. (default=False) ''' - try: - from PIL import Image, ImageOps, ImageFilter - except ImportError, e: - msg = "Image Comparison requires the Python Imaging Library to " \ - "be installed. To run tests without using PIL, then use " \ - "the '--without-tag=PIL' command-line option.\n" \ - "Importing PIL failed with the following error:\n%s" % e - if in_decorator: - raise NotImplementedError, e - else: - return msg - verify(actual) # Convert the image to png extension = expected.split('.')[-1] if extension != 'png': - actual = convert(actual) - expected = convert(expected) + actual = convert(actual, False) + expected = convert(expected, True) # open the image files and remove the alpha channel (if it exists) - expectedImage = Image.open( expected ).convert("RGB") - actualImage = Image.open( actual ).convert("RGB") + expectedImage = _png.read_png_int( expected ) + actualImage = _png.read_png_int( actual ) actualImage, expectedImage = crop_to_same(actual, actualImage, expected, expectedImage) - # normalize the images - expectedImage = ImageOps.autocontrast( expectedImage, 2 ) - actualImage = ImageOps.autocontrast( actualImage, 2 ) - # compare the resulting image histogram functions - h1 = expectedImage.histogram() - h2 = actualImage.histogram() - rms = math.sqrt( reduce(operator.add, map(lambda a,b: (a-b)**2, h1, h2)) / len(h1) ) + expected_version = version.LooseVersion("1.6") + found_version = version.LooseVersion(np.__version__) - diff_image = os.path.join(os.path.dirname(actual), - 'failed-diff-'+os.path.basename(actual)) + rms = calculate_rms(expectedImage, actualImage) + + diff_image = make_test_filename(actual, 'failed-diff') if ( (rms / 10000.0) <= tol ): if os.path.exists(diff_image): os.unlink(diff_image) return None + # For Agg-rendered images, we can retry by ignoring pixels with + # differences of only 1 + if extension == 'png': + # Remove differences of only 1 + diffImage = np.abs(np.asarray(actualImage, dtype=np.int) - + np.asarray(expectedImage, dtype=np.int)) + actualImage = np.where(diffImage <= 1, expectedImage, actualImage) + + rms = calculate_rms(expectedImage, actualImage) + + if ( (rms / 10000.0) <= tol ): + if os.path.exists(diff_image): + os.unlink(diff_image) + return None + save_diff_image( expected, actual, diff_image ) if in_decorator: @@ -259,17 +368,28 @@ return msg def save_diff_image( expected, actual, output ): - from PIL import Image - expectedImage = Image.open( expected ).convert("RGB") - actualImage = Image.open( actual ).convert("RGB") + expectedImage = _png.read_png( expected ) + actualImage = _png.read_png( actual ) actualImage, expectedImage = crop_to_same(actual, actualImage, expected, expectedImage) expectedImage = np.array(expectedImage).astype(np.float) actualImage = np.array(actualImage).astype(np.float) assert expectedImage.ndim==actualImage.ndim assert expectedImage.shape==actualImage.shape absDiffImage = abs(expectedImage-actualImage) + # expand differences in luminance domain - absDiffImage *= 10 - save_image_np = np.clip(absDiffImage,0,255).astype(np.uint8) - save_image = Image.fromarray(save_image_np) - save_image.save(output) + absDiffImage *= 255 * 10 + save_image_np = np.clip(absDiffImage, 0, 255).astype(np.uint8) + height, width, depth = save_image_np.shape + + # The PDF renderer doesn't produce an alpha channel, but the + # matplotlib PNG writer requires one, so expand the array + if depth == 3: + with_alpha = np.empty((height, width, 4), dtype=np.uint8) + with_alpha[:,:,0:3] = save_image_np + save_image_np = with_alpha + + # Hard-code the alpha channel to fully solid + save_image_np[:,:,3] = 255 + + _png.write_png(save_image_np.tostring(), width, height, output) diff -Nru matplotlib-1.1.1/lib/matplotlib/testing/decorators.py matplotlib-1.2.0/lib/matplotlib/testing/decorators.py --- matplotlib-1.1.1/lib/matplotlib/testing/decorators.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/testing/decorators.py 2012-11-08 13:38:03.000000000 +0000 @@ -1,14 +1,17 @@ +from __future__ import print_function from matplotlib.testing.noseclasses import KnownFailureTest, \ KnownFailureDidNotFailTest, ImageComparisonFailure -import os, sys, shutil, new +import os, sys, shutil import nose import matplotlib import matplotlib.tests import matplotlib.units +from matplotlib import ticker from matplotlib import pyplot as plt from matplotlib import ft2font import numpy as np -from matplotlib.testing.compare import comparable_formats, compare_images +from matplotlib.testing.compare import comparable_formats, compare_images, \ + make_test_filename import warnings def knownfailureif(fail_condition, msg=None, known_exception_class=None ): @@ -34,7 +37,7 @@ try: # Always run the test (to generate images). result = f(*args, **kwargs) - except Exception, err: + except Exception as err: if fail_condition: if known_exception_class is not None: if not isinstance(err,known_exception_class): @@ -50,7 +53,7 @@ return nose.tools.make_decorator(f)(failer) return known_fail_decorator -class CleanupTest: +class CleanupTest(object): @classmethod def setup_class(cls): cls.original_units_registry = matplotlib.units.registry.copy() @@ -72,7 +75,7 @@ name = func.__name__ func = staticmethod(func) func.__get__(1).__name__ = '_private' - new_class = new.classobj( + new_class = type( name, (CleanupTest,), {'_func': func}) @@ -97,6 +100,16 @@ cls._func() + @staticmethod + def remove_text(figure): + figure.suptitle("") + for ax in figure.get_axes(): + ax.set_title("") + ax.xaxis.set_major_formatter(ticker.NullFormatter()) + ax.xaxis.set_minor_formatter(ticker.NullFormatter()) + ax.yaxis.set_major_formatter(ticker.NullFormatter()) + ax.yaxis.set_minor_formatter(ticker.NullFormatter()) + def test(self): baseline_dir, result_dir = _image_directories(self._func) @@ -113,7 +126,8 @@ orig_expected_fname = os.path.join(baseline_dir, baseline) + '.' + extension if extension == 'eps' and not os.path.exists(orig_expected_fname): orig_expected_fname = os.path.join(baseline_dir, baseline) + '.pdf' - expected_fname = os.path.join(result_dir, 'expected-' + os.path.basename(orig_expected_fname)) + expected_fname = make_test_filename(os.path.join( + result_dir, os.path.basename(orig_expected_fname)), 'expected') actual_fname = os.path.join(result_dir, baseline) + '.' + extension if os.path.exists(orig_expected_fname): shutil.copyfile(orig_expected_fname, expected_fname) @@ -125,9 +139,13 @@ will_fail, fail_msg, known_exception_class=ImageComparisonFailure) def do_test(): + if self._remove_text: + self.remove_text(figure) + figure.savefig(actual_fname) - err = compare_images(expected_fname, actual_fname, self._tol, in_decorator=True) + err = compare_images(expected_fname, actual_fname, + self._tol, in_decorator=True) try: if not os.path.exists(expected_fname): @@ -147,7 +165,8 @@ yield (do_test,) -def image_comparison(baseline_images=None, extensions=None, tol=1e-3, freetype_version=None): +def image_comparison(baseline_images=None, extensions=None, tol=1e-3, + freetype_version=None, remove_text=False): """ call signature:: @@ -175,6 +194,11 @@ *freetype_version*: str or tuple The expected freetype version or range of versions for this test to pass. + + *remove_text*: bool + Remove the title and tick text from the figure before + comparison. This does not remove other, more deliberate, + text, such as legends and annotations. """ if baseline_images is None: @@ -190,8 +214,8 @@ # of output file. The only way to achieve this with nose # appears to be to create a test class with "setup_class" and # "teardown_class" methods. Creating a class instance doesn't - # work, so we use new.classobj to actually create a class and - # fill it with the appropriate methods. + # work, so we use type() to actually create a class and fill + # it with the appropriate methods. name = func.__name__ # For nose 1.0, we need to rename the test function to # something without the word "test", or it will be run as @@ -199,14 +223,15 @@ # generator. func = staticmethod(func) func.__get__(1).__name__ = '_private' - new_class = new.classobj( + new_class = type( name, (ImageComparisonTest,), {'_func': func, '_baseline_images': baseline_images, '_extensions': extensions, '_tol': tol, - '_freetype_version': freetype_version}) + '_freetype_version': freetype_version, + '_remove_text': remove_text}) return new_class return compare_images_decorator @@ -219,17 +244,28 @@ module_name = func.__module__ if module_name == '__main__': # FIXME: this won't work for nested packages in matplotlib.tests - import warnings warnings.warn('test module run as script. guessing baseline image locations') script_name = sys.argv[0] basedir = os.path.abspath(os.path.dirname(script_name)) subdir = os.path.splitext(os.path.split(script_name)[1])[0] else: mods = module_name.split('.') - assert mods.pop(0) == 'matplotlib' + mods.pop(0) # <- will be the name of the package being tested (in + # most cases "matplotlib") assert mods.pop(0) == 'tests' subdir = os.path.join(*mods) - basedir = os.path.dirname(matplotlib.tests.__file__) + + import imp + def find_dotted_module(module_name, path=None): + """A version of imp which can handle dots in the module name""" + res = None + for sub_mod in module_name.split('.'): + res = _, path, _ = imp.find_module(sub_mod, path) + path = [path] + return res + + mod_file = find_dotted_module(func.__module__)[1] + basedir = os.path.dirname(mod_file) baseline_dir = os.path.join(basedir, 'baseline_images', subdir) result_dir = os.path.abspath(os.path.join('result_images', subdir)) @@ -238,4 +274,3 @@ os.makedirs(result_dir) return baseline_dir, result_dir - diff -Nru matplotlib-1.1.1/lib/matplotlib/testing/image_util.py matplotlib-1.2.0/lib/matplotlib/testing/image_util.py --- matplotlib-1.1.1/lib/matplotlib/testing/image_util.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/testing/image_util.py 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,99 @@ +# This module contains some functionality from the Python Imaging +# Library, that has been ported to use Numpy arrays rather than PIL +# Image objects. + + +# The Python Imaging Library is + +# Copyright (c) 1997-2009 by Secret Labs AB +# Copyright (c) 1995-2009 by Fredrik Lundh + +# By obtaining, using, and/or copying this software and/or its +# associated documentation, you agree that you have read, understood, +# and will comply with the following terms and conditions: + +# Permission to use, copy, modify, and distribute this software and its +# associated documentation for any purpose and without fee is hereby +# granted, provided that the above copyright notice appears in all +# copies, and that both that copyright notice and this permission notice +# appear in supporting documentation, and that the name of Secret Labs +# AB or the author not be used in advertising or publicity pertaining to +# distribution of the software without specific, written prior +# permission. + +# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO +# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import print_function +import numpy as np + +# TODO: Vectorize this +def autocontrast(image, cutoff=0): + """ + Maximize image contrast, based on histogram. This completely + ignores the alpha channel. + """ + assert image.dtype == np.uint8 + + output_image = np.empty((image.shape[0], image.shape[1], 3), np.uint8) + + for i in xrange(0, 3): + plane = image[:,:,i] + output_plane = output_image[:,:,i] + h = np.histogram(plane, bins=256)[0] + if cutoff: + # cut off pixels from both ends of the histogram + # get number of pixels + n = 0 + for ix in xrange(256): + n = n + h[ix] + # remove cutoff% pixels from the low end + cut = n * cutoff / 100 + for lo in range(256): + if cut > h[lo]: + cut = cut - h[lo] + h[lo] = 0 + else: + h[lo] = h[lo] - cut + cut = 0 + if cut <= 0: + break + # remove cutoff% samples from the hi end + cut = n * cutoff / 100 + for hi in xrange(255, -1, -1): + if cut > h[hi]: + cut = cut - h[hi] + h[hi] = 0 + else: + h[hi] = h[hi] - cut + cut = 0 + if cut <= 0: + break + + # find lowest/highest samples after preprocessing + for lo in xrange(256): + if h[lo]: + break + for hi in xrange(255, -1, -1): + if h[hi]: + break + + if hi <= lo: + output_plane[:,:] = plane + else: + scale = 255.0 / (hi - lo) + offset = -lo * scale + lut = np.arange(256, dtype=np.float) + lut *= scale + lut += offset + lut = lut.clip(0, 255) + lut = lut.astype(np.uint8) + + output_plane[:,:] = lut[plane] + + return output_image diff -Nru matplotlib-1.1.1/lib/matplotlib/testing/jpl_units/Duration.py matplotlib-1.2.0/lib/matplotlib/testing/jpl_units/Duration.py --- matplotlib-1.1.1/lib/matplotlib/testing/jpl_units/Duration.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/testing/jpl_units/Duration.py 2012-10-31 00:11:14.000000000 +0000 @@ -4,11 +4,13 @@ # #=========================================================================== + """Duration module.""" #=========================================================================== # Place all imports after here. # +from __future__ import print_function # # Place all imports before here. #=========================================================================== @@ -18,11 +20,11 @@ """Class Duration in development. """ allowed = [ "ET", "UTC" ] - + #----------------------------------------------------------------------- def __init__( self, frame, seconds ): """Create a new Duration object. - + = ERROR CONDITIONS - If the input frame is not in the allowed list, an error is thrown. @@ -47,12 +49,12 @@ def __abs__( self ): """Return the absolute value of the duration.""" return Duration( self._frame, abs( self._seconds ) ) - + #----------------------------------------------------------------------- def __neg__( self ): """Return the negative value of this Duration.""" return Duration( self._frame, -self._seconds ) - + #----------------------------------------------------------------------- def seconds( self ): """Return the number of seconds in the Duration.""" @@ -69,7 +71,7 @@ - Returns -1 if self < rhs, 0 if self == rhs, +1 if self > rhs. """ return self._seconds != 0 - + #----------------------------------------------------------------------- def __cmp__( self, rhs ): """Compare two Durations. @@ -85,7 +87,7 @@ """ self.checkSameFrame( rhs, "compare" ) return cmp( self._seconds, rhs._seconds ) - + #----------------------------------------------------------------------- def __add__( self, rhs ): """Add two Durations. @@ -104,10 +106,10 @@ if isinstance( rhs, U.Epoch ): return rhs + self - + self.checkSameFrame( rhs, "add" ) return Duration( self._frame, self._seconds + rhs._seconds ) - + #----------------------------------------------------------------------- def __sub__( self, rhs ): """Subtract two Durations. @@ -123,7 +125,7 @@ """ self.checkSameFrame( rhs, "sub" ) return Duration( self._frame, self._seconds - rhs._seconds ) - + #----------------------------------------------------------------------- def __mul__( self, rhs ): """Scale a UnitDbl by a value. @@ -135,7 +137,7 @@ - Returns the scaled Duration. """ return Duration( self._frame, self._seconds * float( rhs ) ) - + #----------------------------------------------------------------------- def __rmul__( self, lhs ): """Scale a Duration by a value. @@ -147,7 +149,7 @@ - Returns the scaled Duration. """ return Duration( self._frame, self._seconds * float( lhs ) ) - + #----------------------------------------------------------------------- def __div__( self, rhs ): """Divide a Duration by a value. @@ -159,7 +161,7 @@ - Returns the scaled Duration. """ return Duration( self._frame, self._seconds / float( rhs ) ) - + #----------------------------------------------------------------------- def __rdiv__( self, rhs ): """Divide a Duration by a value. @@ -171,17 +173,17 @@ - Returns the scaled Duration. """ return Duration( self._frame, float( rhs ) / self._seconds ) - + #----------------------------------------------------------------------- def __str__( self ): """Print the Duration.""" return "%g %s" % ( self._seconds, self._frame ) - + #----------------------------------------------------------------------- def __repr__( self ): """Print the Duration.""" return "Duration( '%s', %g )" % ( self._frame, self._seconds ) - + #----------------------------------------------------------------------- def checkSameFrame( self, rhs, func ): """Check to see if frames are the same. @@ -199,5 +201,5 @@ "LHS: %s\n" \ "RHS: %s" % ( func, self._frame, rhs._frame ) raise ValueError( msg ) - + #=========================================================================== diff -Nru matplotlib-1.1.1/lib/matplotlib/testing/jpl_units/Epoch.py matplotlib-1.2.0/lib/matplotlib/testing/jpl_units/Epoch.py --- matplotlib-1.1.1/lib/matplotlib/testing/jpl_units/Epoch.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/testing/jpl_units/Epoch.py 2012-11-06 18:15:44.000000000 +0000 @@ -4,11 +4,13 @@ # #=========================================================================== + """Epoch module.""" #=========================================================================== # Place all imports after here. # +from __future__ import print_function import math import datetime as DT from matplotlib.dates import date2num @@ -40,8 +42,8 @@ or using a matplotlib day number # Epoch( 'ET', daynum=730119.5 ) - - + + = ERROR CONDITIONS - If the input units are not in the allowed list, an error is thrown. @@ -64,7 +66,7 @@ "Sec = %s\nJD = %s\ndnum= %s\ndt = %s" \ % ( str( sec ), str( jd ), str( daynum ), str( dt ) ) raise ValueError( msg ) - + if frame not in self.allowed: msg = "Input frame '%s' is not one of the supported frames of %s" \ % ( frame, str( self.allowed.keys() ) ) @@ -80,7 +82,7 @@ jd = float( daynum ) + 1721425.5 self._jd = math.floor( jd ) self._seconds = ( jd - self._jd ) * 86400.0 - + else: self._seconds = float( sec ) self._jd = float( jd ) @@ -110,13 +112,13 @@ t = self.convert( frame ) return t._jd + t._seconds / 86400.0 - + #----------------------------------------------------------------------- def secondsPast( self, frame, jd ): t = self if frame != self._frame: t = self.convert( frame ) - + delta = t._jd - jd return t._seconds + delta * 86400 @@ -138,7 +140,7 @@ return cmp( t._jd, rhs._jd ) return cmp( t._seconds, rhs._seconds ) - + #----------------------------------------------------------------------- def __add__( self, rhs ): """Add a duration to an Epoch. @@ -156,7 +158,7 @@ sec = t._seconds + rhs.seconds() return Epoch( t._frame, sec, t._jd ) - + #----------------------------------------------------------------------- def __sub__( self, rhs ): """Subtract two Epoch's or a Duration from an Epoch. @@ -178,7 +180,7 @@ # Handle Epoch - Duration if isinstance( rhs, U.Duration ): return self + -rhs - + t = self if self._frame != rhs._frame: t = self.convert( rhs._frame ) @@ -187,17 +189,17 @@ sec = t._seconds - rhs._seconds return U.Duration( rhs._frame, days*86400 + sec ) - + #----------------------------------------------------------------------- def __str__( self ): """Print the Epoch.""" return "%22.15e %s" % ( self.julianDate( self._frame ), self._frame ) - + #----------------------------------------------------------------------- def __repr__( self ): """Print the Epoch.""" return str( self ) - + #----------------------------------------------------------------------- def range( start, stop, step ): """Generate a range of Epoch objects. @@ -205,12 +207,12 @@ Similar to the Python range() method. Returns the range [ start, stop ) at the requested step. Each element will be a Epoch object. - + = INPUT VARIABLES - - start The starting value of the range. - - stop The stop value of the range. - - step Step to use. - + - start The starting value of the range. + - stop The stop value of the range. + - step Step to use. + = RETURN VALUE - Returns a list contianing the requested Epoch values. """ diff -Nru matplotlib-1.1.1/lib/matplotlib/testing/jpl_units/EpochConverter.py matplotlib-1.2.0/lib/matplotlib/testing/jpl_units/EpochConverter.py --- matplotlib-1.1.1/lib/matplotlib/testing/jpl_units/EpochConverter.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/testing/jpl_units/EpochConverter.py 2012-11-06 18:15:44.000000000 +0000 @@ -4,11 +4,13 @@ # #=========================================================================== + """EpochConverter module containing class EpochConverter.""" #=========================================================================== # Place all imports after here. # +from __future__ import print_function import matplotlib.units as units import matplotlib.dates as date_ticker from matplotlib.cbook import iterable diff -Nru matplotlib-1.1.1/lib/matplotlib/testing/jpl_units/StrConverter.py matplotlib-1.2.0/lib/matplotlib/testing/jpl_units/StrConverter.py --- matplotlib-1.1.1/lib/matplotlib/testing/jpl_units/StrConverter.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/testing/jpl_units/StrConverter.py 2012-10-31 00:11:14.000000000 +0000 @@ -4,11 +4,13 @@ # #=========================================================================== + """StrConverter module containing class StrConverter.""" #=========================================================================== # Place all imports after here. # +from __future__ import print_function import matplotlib.units as units from matplotlib.cbook import iterable @@ -81,7 +83,7 @@ labels = [ l.get_text() for l in labels if l.get_text() ] if ( not labels ): - ticks = [] + ticks = [] labels = [] diff -Nru matplotlib-1.1.1/lib/matplotlib/testing/jpl_units/UnitDbl.py matplotlib-1.2.0/lib/matplotlib/testing/jpl_units/UnitDbl.py --- matplotlib-1.1.1/lib/matplotlib/testing/jpl_units/UnitDbl.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/testing/jpl_units/UnitDbl.py 2012-10-31 00:11:14.000000000 +0000 @@ -4,12 +4,13 @@ # #=========================================================================== + """UnitDbl module.""" #=========================================================================== # Place all imports after here. # - +from __future__ import print_function # # Place all imports before here. #=========================================================================== diff -Nru matplotlib-1.1.1/lib/matplotlib/testing/jpl_units/UnitDblConverter.py matplotlib-1.2.0/lib/matplotlib/testing/jpl_units/UnitDblConverter.py --- matplotlib-1.1.1/lib/matplotlib/testing/jpl_units/UnitDblConverter.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/testing/jpl_units/UnitDblConverter.py 2012-10-31 00:11:14.000000000 +0000 @@ -4,11 +4,13 @@ # #=========================================================================== + """UnitDblConverter module containing class UnitDblConverter.""" #=========================================================================== # Place all imports after here. # +from __future__ import print_function import numpy as np import matplotlib.units as units import matplotlib.ticker as ticker diff -Nru matplotlib-1.1.1/lib/matplotlib/testing/jpl_units/UnitDblFormatter.py matplotlib-1.2.0/lib/matplotlib/testing/jpl_units/UnitDblFormatter.py --- matplotlib-1.1.1/lib/matplotlib/testing/jpl_units/UnitDblFormatter.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/testing/jpl_units/UnitDblFormatter.py 2012-10-31 00:11:14.000000000 +0000 @@ -4,11 +4,13 @@ # #=========================================================================== + """UnitDblFormatter module containing class UnitDblFormatter.""" #=========================================================================== # Place all imports after here. # +from __future__ import print_function import matplotlib.ticker as ticker # # Place all imports before here. diff -Nru matplotlib-1.1.1/lib/matplotlib/testing/jpl_units/__init__.py matplotlib-1.2.0/lib/matplotlib/testing/jpl_units/__init__.py --- matplotlib-1.1.1/lib/matplotlib/testing/jpl_units/__init__.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/testing/jpl_units/__init__.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,10 +1,11 @@ #======================================================================= + """ This is a sample set of units for use with testing unit conversion of matplotlib routines. These are used because they use very strict enforcement of unitized data which will test the entire spectrum of how unitized data might be used (it is not always meaningful to convert to -a float without specific units given). +a float without specific units given). UnitDbl is essentially a unitized floating point number. It has a minimal set of supported units (enough for testing purposes). All @@ -30,6 +31,7 @@ """ #======================================================================= +from __future__ import print_function from Duration import Duration from Epoch import Epoch from UnitDbl import UnitDbl diff -Nru matplotlib-1.1.1/lib/matplotlib/testing/noseclasses.py matplotlib-1.2.0/lib/matplotlib/testing/noseclasses.py --- matplotlib-1.1.1/lib/matplotlib/testing/noseclasses.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/testing/noseclasses.py 2012-11-06 18:15:41.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import os from nose.plugins.errorclass import ErrorClass, ErrorClassPlugin diff -Nru matplotlib-1.1.1/lib/matplotlib/testing/util.py matplotlib-1.2.0/lib/matplotlib/testing/util.py --- matplotlib-1.1.1/lib/matplotlib/testing/util.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/testing/util.py 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,76 @@ +import subprocess +import sys + + +class MiniExpect: + """ + This is a very basic version of pexpect, providing only the + functionality necessary for the testing framework, built on top of + `subprocess` rather than directly on lower-level calls. + """ + def __init__(self, args): + """ + Start the subprocess so it may start accepting commands. + + *args* is a list of commandline arguments to pass to + `subprocess.Popen`. + """ + self._name = args[0] + self._process = subprocess.Popen( + args, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + + def check_alive(self): + """ + Raises a RuntimeError if the process is no longer alive. + """ + returncode = self._process.poll() + if returncode is not None: + raise RuntimeError("%s unexpectedly quit" % self._name) + + def sendline(self, line): + """ + Send a line to the process. + """ + line = line.encode('ascii') + self.check_alive() + stdin = self._process.stdin + stdin.write(line) + stdin.write(b'\n') + stdin.flush() + + def expect(self, s, output=None): + """ + Wait for the string *s* to appear in the child process's output. + + *output* (optional) is a writable file object where all of the + content preceding *s* will be written. + """ + s = s.encode('ascii') + read = self._process.stdout.read + pos = 0 + buf = b'' + while True: + self.check_alive() + char = read(1) + if not char: + raise IOError("Unexpected end-of-file") + + if sys.version_info[0] >= 3: + match = (ord(char) == s[pos]) + else: + match = (char == s[pos]) + + if match: + buf += char + pos += 1 + if pos == len(s): + return + else: + if output is not None: + output.write(buf) + output.write(char) + buf = b'' + pos = 0 diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/__init__.py matplotlib-1.2.0/lib/matplotlib/tests/__init__.py --- matplotlib-1.1.1/lib/matplotlib/tests/__init__.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/__init__.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function from matplotlib import rcParams, rcdefaults, use _multiprocess_can_split_ = True @@ -11,4 +12,5 @@ rcdefaults() # Start with all defaults rcParams['font.family'] = 'Bitstream Vera Sans' rcParams['text.hinting'] = False + rcParams['text.hinting_factor'] = 8 rcParams['text.antialiased'] = False Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_arrow_patches/fancyarrow_test_image.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_arrow_patches/fancyarrow_test_image.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_arrow_patches/fancyarrow_test_image.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_arrow_patches/fancyarrow_test_image.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_arrow_patches/fancyarrow_test_image.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_arrow_patches/fancyarrow_test_image.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_arrow_patches/fancyarrow_test_image.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_arrow_patches/fancyarrow_test_image.svg 2012-11-06 15:42:20.000000000 +0000 @@ -0,0 +1,1577 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/arc_ellipse.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/arc_ellipse.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/arc_ellipse.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/arc_ellipse.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/arc_ellipse.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/arc_ellipse.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/arc_ellipse.svg 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/arc_ellipse.svg 2012-10-31 00:11:14.000000000 +0000 @@ -1,823 +1,1226 @@ - + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/autoscale_tiny_range.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/autoscale_tiny_range.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/autoscale_tiny_range.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/autoscale_tiny_range.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/autoscale_tiny_range.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/autoscale_tiny_range.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/autoscale_tiny_range.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/autoscale_tiny_range.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,816 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/boxplot.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/boxplot.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/boxplot.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/boxplot.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/boxplot.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/boxplot.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/boxplot.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/boxplot.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,458 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/contour_colorbar.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/contour_colorbar.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/contour_colorbar.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/contour_colorbar.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/contour_colorbar.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/contour_colorbar.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/contour_colorbar.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/contour_colorbar.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,20114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/contour_hatching.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/contour_hatching.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/contour_hatching.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/contour_hatching.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/contour_hatching.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/contour_hatching.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/contour_hatching.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/contour_hatching.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,6861 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/errorbar_basic.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/errorbar_basic.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/errorbar_basic.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/errorbar_basic.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/errorbar_basic.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/errorbar_basic.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/errorbar_basic.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/errorbar_basic.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,1257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/errorbar_mixed.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/errorbar_mixed.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/errorbar_mixed.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/errorbar_mixed.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/errorbar_mixed.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/errorbar_mixed.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/errorbar_mixed.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/errorbar_mixed.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,2437 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/fill_between_interpolate.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/fill_between_interpolate.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/fill_between_interpolate.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/fill_between_interpolate.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/fill_between_interpolate.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/fill_between_interpolate.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/fill_between_interpolate.svg 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/fill_between_interpolate.svg 2012-10-31 00:11:14.000000000 +0000 @@ -1,763 +1,1344 @@ - + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/formatter_large_small.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,636 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hexbin_extent.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hexbin_extent.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hexbin_extent.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hexbin_extent.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hexbin_extent.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hexbin_extent.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hexbin_extent.svg 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hexbin_extent.svg 2012-10-31 00:11:14.000000000 +0000 @@ -2,35 +2,35 @@ - - - + + - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - +L0 4" id="mdad270ee8e" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - + + + - - - - - - - + + + + + + - - - - - - - - + + + + - - - - + + + + - - - - +L4 0" id="mc8fcea1516" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> + + + - - - + + - - - - +L-4 0" id="m0d5b0a6425" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> + + + - - - - - - - - - - - + + + + + + - - - - - - - - + + + - - - - - - - + + + + + + - - - - - - - - + + + + - - - - - - - - + + + + + - - - - - - - + + + + - - - - - - - - - - - + + + + + + - - - - - - - - + + + - - - - - - - + + + + + + - - - - - - - - - - - + + + + - - + - - - + - - - + - - - + - - + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hist2d.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hist2d.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hist2d.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hist2d.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hist2d.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hist2d.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hist2d.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hist2d.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hist2d_transpose.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hist2d_transpose.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hist2d_transpose.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hist2d_transpose.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hist2d_transpose.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hist2d_transpose.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hist2d_transpose.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hist2d_transpose.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,503 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hist_stacked.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hist_stacked.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hist_stacked.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hist_stacked.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hist_stacked.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hist_stacked.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hist_stacked.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hist_stacked.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,558 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hist_stacked_weights.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hist_stacked_weights.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hist_stacked_weights.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hist_stacked_weights.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hist_stacked_weights.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hist_stacked_weights.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/hist_stacked_weights.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/hist_stacked_weights.svg 2012-11-06 15:42:20.000000000 +0000 @@ -0,0 +1,577 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/imshow.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/imshow.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/imshow.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/imshow.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/imshow.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/imshow.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/imshow.svg 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/imshow.svg 2012-10-31 00:11:14.000000000 +0000 @@ -1,1191 +1,206 @@ - + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/imshow_clip.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/imshow_clip.pdf differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/imshow_clip.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/imshow_clip.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/imshow_clip.svg 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/imshow_clip.svg 2012-10-31 00:11:14.000000000 +0000 @@ -1,1353 +1,878 @@ - + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/log_scales.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/log_scales.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/log_scales.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/log_scales.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/log_scales.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/log_scales.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/log_scales.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/log_scales.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,670 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/marker_edges.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/marker_edges.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/marker_edges.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/marker_edges.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/marker_edges.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/marker_edges.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/marker_edges.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/marker_edges.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,370 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/markevery.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/markevery.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/markevery.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/markevery.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/markevery.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/markevery.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/markevery.svg 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/markevery.svg 2012-10-31 00:11:14.000000000 +0000 @@ -41,114 +41,109 @@ C-3 0.795609 -2.6839 1.55874 -2.12132 2.12132 C-1.55874 2.6839 -0.795609 3 0 3 z -" id="mafc88db4ae"/> - - - - - +" id="m0f54036a79" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -159,109 +154,109 @@ L2.44249e-16 -4.24264 L-2.54558 -8.88178e-16 z -" id="m016d603646"/> +" id="m29be9c3875" style="stroke:#000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-width:0.5;"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -272,19 +267,19 @@ L3 -3 L-3 -3 z -" id="mbfa5fcfaff"/> +" id="m4f1de7e098" style="stroke:#000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-width:0.5;"/> - - - - - - - - - - + + + + + + + + + + @@ -293,14 +288,14 @@ M-3 0 L3 0 M0 3 -L0 -3" id="mba139cba6e"/> +L0 -3" id="m28bd70cc20" style="stroke:#00bfbf;stroke-linecap:butt;stroke-width:0.5;"/> - - - - - + + + + + @@ -309,318 +304,80 @@ +L0 -4" id="mcb557df647" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + +L0 4" id="mdad270ee8e" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - - - - - - - - - - + - - - - + - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - - + @@ -631,223 +388,80 @@ +L4 0" id="mc8fcea1516" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + +L-4 0" id="m0d5b0a6425" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - + @@ -883,198 +497,165 @@ z " style="fill:#ffffff;stroke:#000000;"/> - - - - - - - - - + - - - - - + + - + - + - + +L43.2188 8.29688 +Q40.1406 3.32812 35.5469 0.953125 +Q30.9531 -1.42188 24.3125 -1.42188 +Q15.9219 -1.42188 10.9531 3.29688 +Q6 8.01562 6 15.9219 +Q6 25.1406 12.1719 29.8281 +Q18.3594 34.5156 30.6094 34.5156 +L43.2188 34.5156 +L43.2188 35.4062 +Q43.2188 41.6094 39.1406 45 +Q35.0625 48.3906 27.6875 48.3906 +Q23 48.3906 18.5469 47.2656 +Q14.1094 46.1406 10.0156 43.8906 +L10.0156 52.2031 +Q14.9375 54.1094 19.5781 55.0469 +Q24.2188 56 28.6094 56 +Q40.4844 56 46.3438 49.8438 +Q52.2031 43.7031 52.2031 31.2031" id="BitstreamVeraSans-Roman-61"/> - + @@ -1084,102 +665,79 @@ - - - - - - - - - + - - - - - + + - + - + - + @@ -1190,68 +748,78 @@ - - - - - - - - - + - - - - - + + - + + + - + @@ -1267,131 +835,137 @@ - - - - - - - - - + - - - - - + + - + - + +M44.2812 53.0781 +L44.2812 44.5781 +Q40.4844 46.5312 36.375 47.5 +Q32.2812 48.4844 27.875 48.4844 +Q21.1875 48.4844 17.8438 46.4375 +Q14.5 44.3906 14.5 40.2812 +Q14.5 37.1562 16.8906 35.375 +Q19.2812 33.5938 26.5156 31.9844 +L29.5938 31.2969 +Q39.1562 29.25 43.1875 25.5156 +Q47.2188 21.7812 47.2188 15.0938 +Q47.2188 7.46875 41.1875 3.01562 +Q35.1562 -1.42188 24.6094 -1.42188 +Q20.2188 -1.42188 15.4531 -0.5625 +Q10.6875 0.296875 5.42188 2 +L5.42188 11.2812 +Q10.4062 8.6875 15.2344 7.39062 +Q20.0625 6.10938 24.8125 6.10938 +Q31.1562 6.10938 34.5625 8.28125 +Q37.9844 10.4531 37.9844 14.4062 +Q37.9844 18.0625 35.5156 20.0156 +Q33.0625 21.9688 24.7031 23.7812 +L21.5781 24.5156 +Q13.2344 26.2656 9.51562 29.9062 +Q5.8125 33.5469 5.8125 39.8906 +Q5.8125 47.6094 11.2812 51.7969 +Q16.75 56 26.8125 56 +Q31.7812 56 36.1719 55.2656 +Q40.5781 54.5469 44.2812 53.0781" id="BitstreamVeraSans-Roman-73"/> + - + @@ -1424,4 +998,9 @@ + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/markevery_line.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/markevery_line.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/markevery_line.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/markevery_line.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/markevery_line.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/markevery_line.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/markevery_line.svg 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/markevery_line.svg 2012-10-31 00:11:14.000000000 +0000 @@ -29,11 +29,6 @@ " style="fill:#ffffff;"/> - - - - - +" id="m0f54036a79" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -361,109 +356,109 @@ L2.44249e-16 -4.24264 L-2.54558 -8.88178e-16 z -" id="m53557f14a9"/> +" id="m29be9c3875" style="stroke:#000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-width:0.5;"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -575,19 +570,19 @@ L3 -3 L-3 -3 z -" id="m63986abc5f"/> +" id="m4f1de7e098" style="stroke:#000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-width:0.5;"/> - - - - - - - - - - + + + + + + + + + + @@ -697,14 +692,14 @@ M-3 0 L3 0 M0 3 -L0 -3" id="m042afd644e"/> +L0 -3" id="m28bd70cc20" style="stroke:#00bfbf;stroke-linecap:butt;stroke-width:0.5;"/> - - - - - + + + + + @@ -713,318 +708,80 @@ +L0 -4" id="mcb557df647" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + +L0 4" id="mdad270ee8e" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - - - - - - - - - - + - - - - + - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - - + @@ -1035,223 +792,80 @@ +L4 0" id="mc8fcea1516" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + +L-4 0" id="m0d5b0a6425" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - + @@ -1293,26 +907,12 @@ L292.397 62.0617" style="fill:none;stroke:#0000ff;"/> - - - - - + + - + - - - - - + + - + @@ -1575,21 +1166,12 @@ L292.397 104.335" style="fill:none;stroke:#ff0000;"/> - - - - - + + - + + + - - - - - + + - + + @@ -1785,4 +1418,9 @@ + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/offset_points.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/offset_points.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/offset_points.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/offset_points.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/offset_points.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/offset_points.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/offset_points.svg 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/offset_points.svg 2012-10-31 00:11:14.000000000 +0000 @@ -2,39 +2,34 @@ - - - + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/pcolormesh.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/pcolormesh.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/pcolormesh.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/pcolormesh.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/pcolormesh.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/pcolormesh.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/pcolormesh.svg 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/pcolormesh.svg 2012-10-31 00:11:14.000000000 +0000 @@ -3964,763 +3964,763 @@ L280.131 -382.009" id="C1_fc_eb50d2133a"/> - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -4746,45 +4746,37 @@ L229.553 43.2" style="fill:none;stroke:#000000;"/> - + +M19.1875 8.29688 +L53.6094 8.29688 +L53.6094 0 +L7.32812 0 +L7.32812 8.29688 +Q12.9375 14.1094 22.625 23.8906 +Q32.3281 33.6875 34.8125 36.5312 +Q39.5469 41.8438 41.4219 45.5312 +Q43.3125 49.2188 43.3125 52.7812 +Q43.3125 58.5938 39.2344 62.25 +Q35.1562 65.9219 28.6094 65.9219 +Q23.9688 65.9219 18.8125 64.3125 +Q13.6719 62.7031 7.8125 59.4219 +L7.8125 69.3906 +Q13.7656 71.7812 18.9375 73 +Q24.125 74.2188 28.4219 74.2188 +Q39.75 74.2188 46.4844 68.5469 +Q53.2188 62.8906 53.2188 53.4219 +Q53.2188 48.9219 51.5312 44.8906 +Q49.8594 40.875 45.4062 35.4062 +Q44.1875 33.9844 37.6406 27.2188 +Q31.1094 20.4531 19.1875 8.29688" id="BitstreamVeraSans-Roman-32"/> - + - + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/polar_coords.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/polar_coords.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/polar_coords.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/polar_coords.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/polar_coords.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/polar_coords.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/polar_coords.svg 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/polar_coords.svg 2012-10-31 00:11:14.000000000 +0000 @@ -1,347 +1,447 @@ - + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/polycollection_joinstyle.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/polycollection_joinstyle.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/polycollection_joinstyle.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/polycollection_joinstyle.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/polycollection_joinstyle.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/polycollection_joinstyle.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/polycollection_joinstyle.svg 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/polycollection_joinstyle.svg 2012-10-31 00:11:14.000000000 +0000 @@ -1,50 +1,264 @@ - + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/scatter.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/scatter.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/scatter.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/scatter.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/scatter.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/scatter.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/scatter.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/scatter.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,646 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/stackplot_test_image.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/stackplot_test_image.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/stackplot_test_image.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/stackplot_test_image.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/stackplot_test_image.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/stackplot_test_image.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/stackplot_test_image.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/stackplot_test_image.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,661 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/symlog.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/symlog.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/symlog.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/symlog.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/symlog.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/symlog.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/symlog.svg 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/symlog.svg 2012-10-31 00:11:14.000000000 +0000 @@ -30,14 +30,14 @@ +M72 84.5119 +L89.856 96.948 +L107.712 125.824 +L143.424 249.759 +L179.136 303.507 +L232.704 365.849 +L286.272 365.849 +L500.544 365.849" style="fill:none;stroke:#0000ff;"/> @@ -45,20 +45,20 @@ +L0 -4" id="mcb557df647" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + +L0 4" id="mdad270ee8e" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + @@ -92,12 +92,12 @@ - + - + @@ -137,12 +137,12 @@ - + - + @@ -172,12 +172,12 @@ - + - + @@ -191,12 +191,12 @@ - + - + @@ -235,12 +235,12 @@ - + - + @@ -258,25 +258,25 @@ +L4 0" id="mc8fcea1516" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + +L-4 0" id="m0d5b0a6425" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + - + @@ -284,17 +284,17 @@ - + - + - + @@ -304,17 +304,17 @@ - + - + - + @@ -324,17 +324,17 @@ - + - + - + @@ -344,12 +344,12 @@ - + - + @@ -387,7 +387,7 @@ Q53.9062 49.2656 50.4375 45.0938 Q46.9688 40.9219 40.5781 39.3125" id="BitstreamVeraSans-Roman-33"/> - + @@ -397,12 +397,12 @@ - + - + @@ -428,7 +428,7 @@ z " id="BitstreamVeraSans-Roman-34"/> - + @@ -438,17 +438,17 @@ - + - + - + @@ -458,12 +458,12 @@ - + - + @@ -498,7 +498,7 @@ Q40.9219 74.2188 44.7031 73.4844 Q48.4844 72.75 52.5938 71.2969" id="BitstreamVeraSans-Roman-36"/> - + @@ -508,12 +508,12 @@ - + - + @@ -542,776 +542,116 @@ +L2 0" id="m57a2c8792a" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + +L-2 0" id="m46a939d668" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/symlog2.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/symlog2.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/symlog2.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/symlog2.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/symlog2.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/symlog2.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/symlog2.svg 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/symlog2.svg 2012-10-31 00:11:14.000000000 +0000 @@ -30,24 +30,25 @@ +M109.12 97.8207 +L114.528 95.4358 +L120.175 93.1898 +L126.089 91.078 +L132.306 89.0958 +L138.867 87.2392 +L145.817 85.5052 +L153.217 83.8904 +L158.703 82.8869 +L433.182 62.8803 +L440.995 61.2919 +L448.292 59.5837 +L455.142 57.7539 +L461.604 55.7995 +L467.724 53.718 +L473.545 51.5048 +L479.1 49.1561 +L481.279 48.166 +L481.279 48.166" style="fill:none;stroke:#0000ff;"/> @@ -60,120 +61,37 @@ +L0 -4" id="mcb557df647" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + +L0 4" id="mdad270ee8e" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - - - - - - - - - - - - - - - - + +M226.695 102.786 +L226.695 43.2" style="fill:none;stroke:#000000;stroke-dasharray:1.000000,3.000000;stroke-dashoffset:0.0;stroke-linecap:butt;stroke-width:0.5;"/> - + - - - - - - - - - - + @@ -185,43 +103,29 @@ - + - - - - - - - + +M363.705 102.786 +L363.705 43.2" style="fill:none;stroke:#000000;stroke-dasharray:1.000000,3.000000;stroke-dashoffset:0.0;stroke-linecap:butt;stroke-width:0.5;"/> - + - - - - - - - - - + @@ -233,20 +137,12 @@ - + - - - - - - - - - + @@ -255,4905 +151,1958 @@ +L0 -2" id="m6f8f3139b3" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + +L0 2" id="md27378e979" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + - + - + - + - + - + - + - + - + - + + + - - - + + + + - + - - + + + - + + + - - - + - - - + - + - + - - - + - + - - - + + + - - - + - - - + - + - + - - - + - + - - - + + + - - - + - - - + - + - + - - - + - + - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + - - - + - + - - - + + + - - - + - - - + - + - + - - - + - + - - - + + + - - - + - - - + - + - + - - - + - + - - - + + + - - - + - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - + - + + + + - + + + - + + + - + - - - - - - - - - + + + - - - - + - + - - - - - - - - - + - + - + + + - + + + - + - - - - + + + - - - - + - + - - - - - - - - + - + - + + + - + + + - + - - - - - + + + - - - - + + + - - - + - + - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - + +M72 164.359 +L518.4 164.359" style="fill:none;stroke:#000000;stroke-dasharray:1.000000,3.000000;stroke-dashoffset:0.0;stroke-linecap:butt;stroke-width:0.5;"/> - + - - - - - - - - - - + - + +M72 154.428 +L518.4 154.428" style="fill:none;stroke:#000000;stroke-dasharray:1.000000,3.000000;stroke-dashoffset:0.0;stroke-linecap:butt;stroke-width:0.5;"/> - + - - - - - - - - - - + - + +M72 144.497 +L518.4 144.497" style="fill:none;stroke:#000000;stroke-dasharray:1.000000,3.000000;stroke-dashoffset:0.0;stroke-linecap:butt;stroke-width:0.5;"/> - + - - - - - - - - - - + - + +M72 134.566 +L518.4 134.566" style="fill:none;stroke:#000000;stroke-dasharray:1.000000,3.000000;stroke-dashoffset:0.0;stroke-linecap:butt;stroke-width:0.5;"/> - + - - - - - - - + - + +M72 124.634 +L518.4 124.634" style="fill:none;stroke:#000000;stroke-dasharray:1.000000,3.000000;stroke-dashoffset:0.0;stroke-linecap:butt;stroke-width:0.5;"/> - + - - - - - - - - - + - + +M72 114.703 +L518.4 114.703" style="fill:none;stroke:#000000;stroke-dasharray:1.000000,3.000000;stroke-dashoffset:0.0;stroke-linecap:butt;stroke-width:0.5;"/> - + - - - - - - - - - + - - - + + + + - +L518.4 114.703" style="fill:none;stroke:#000000;"/> + + + + + + + + + + + + + + + + + - - - + - - - - - - - - - + - - - + + + - - - + - - - + - + - + - - - + - + - - - + + + - - - + - - - + - + - + - - - + - + - - - + + + - - - + - - - + - + - + - - - + - + - - - + + + - + - - - + + + - + - - - + + + - + - - - + + + - + - - - + + + - + - - - + + + - + - - - + + + - + - - - + + + + + - - - + - - - + - + - + - - - + - + - - - + + + - - - + - - - + - + - + - - - + - + - - - + + + - - - + - - - + - + - + - - - + - + - - - + + + - - - + - - - + - + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - + - - - + - + - + - - - + - + - - - + + + - - - + - - - + - + - + - - - + - + - - - + + + - - - + - - - + - + - + - - - + - + - - - + + + - - - + - - - + - + - + - - - + - + - - - + + + - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - + - + - - + + - + - + - + - - + + - + - + - + - - + + - + - + - + - - + + - + - + - + - - + + - + - + - + - - + + - + - + - + - - + + - + - + - + - - + + - + - + - + - - + + + + + + + - + - + - + - - + + + + + - + - + - + - - + + + + + - + - + - + - - + + + + + - + - + - + - - + + + + + - + - + - + - - + + + + + - + - + - + - - + + + + + - + - + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - - + + + + + - + - + - + - - + + + + + - + - + - + - - + + + + + - + - + - + - - + + + + + - + - + - + - - + + + + + - + - + - + - - + + + + + - + - + - + - - + + + + + - + - + - + - - + + + + + - + - + - + - - + + + + + - + - + - + - - + + + + + - + - + - + - - + + - + - + - + - - + + - + - + - + - - + + - + - + - + - - + + - + - + - + - - + + - + - + - + - - + + - + - + - + - - + + - + - + - + - - + + - + - + - + - - + + - + - + - + - - + + - + - + - + - - + + - + - + - + - + - + - + - + - - - - - - - - - - - - - - + - + - + - + - + - - - - - - - - - - - - - - + - + - + - + - + - - - - - - - - - - + - + - + - + - + - - - - - - - - - - + - + - + - + - + - - - - - - - - - - + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/transparent_markers.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/transparent_markers.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/transparent_markers.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/transparent_markers.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/transparent_markers.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/transparent_markers.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/transparent_markers.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/transparent_markers.svg 2012-11-06 15:42:20.000000000 +0000 @@ -0,0 +1,289 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/twin_axis_locaters_formatters.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/twin_axis_locaters_formatters.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/twin_axis_locaters_formatters.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/twin_axis_locaters_formatters.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/twin_axis_locaters_formatters.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/twin_axis_locaters_formatters.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_axes/twin_axis_locaters_formatters.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_axes/twin_axis_locaters_formatters.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,1219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_backend_pgf/pgf_pdflatex.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_backend_pgf/pgf_pdflatex.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_backend_pgf/pgf_rcupdate1.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_backend_pgf/pgf_rcupdate1.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_backend_pgf/pgf_rcupdate2.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_backend_pgf/pgf_rcupdate2.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_backend_pgf/pgf_xelatex.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_backend_pgf/pgf_xelatex.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_colorbar/colorbar_extensions_proportional.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_colorbar/colorbar_extensions_proportional.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_colorbar/colorbar_extensions_uniform.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_colorbar/colorbar_extensions_uniform.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/cliff-lin-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/cliff-lin-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/cliff-lin-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/cliff-lin-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/cliff-nn-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/cliff-nn-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/cliff-nn-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/cliff-nn-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/cliff-ref-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/cliff-ref-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/cliff-ref-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/cliff-ref-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/cloverleaf-lin-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/cloverleaf-lin-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/cloverleaf-lin-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/cloverleaf-lin-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/cloverleaf-nn-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/cloverleaf-nn-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/cloverleaf-nn-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/cloverleaf-nn-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/cloverleaf-ref-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/cloverleaf-ref-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/cloverleaf-ref-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/cloverleaf-ref-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/cosine_peak-lin-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/cosine_peak-lin-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/cosine_peak-lin-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/cosine_peak-lin-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/cosine_peak-nn-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/cosine_peak-nn-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/cosine_peak-nn-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/cosine_peak-nn-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/cosine_peak-ref-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/cosine_peak-ref-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/cosine_peak-ref-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/cosine_peak-ref-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/exponential-lin-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/exponential-lin-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/exponential-lin-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/exponential-lin-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/exponential-nn-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/exponential-nn-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/exponential-nn-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/exponential-nn-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/exponential-ref-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/exponential-ref-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/exponential-ref-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/exponential-ref-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/gauss-lin-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/gauss-lin-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/gauss-lin-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/gauss-lin-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/gauss-nn-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/gauss-nn-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/gauss-nn-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/gauss-nn-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/gauss-ref-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/gauss-ref-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/gauss-ref-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/gauss-ref-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/gentle-lin-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/gentle-lin-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/gentle-lin-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/gentle-lin-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/gentle-nn-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/gentle-nn-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/gentle-nn-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/gentle-nn-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/gentle-ref-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/gentle-ref-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/gentle-ref-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/gentle-ref-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/saddle-lin-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/saddle-lin-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/saddle-lin-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/saddle-lin-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/saddle-nn-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/saddle-nn-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/saddle-nn-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/saddle-nn-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/saddle-ref-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/saddle-ref-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/saddle-ref-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/saddle-ref-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/sphere-lin-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/sphere-lin-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/sphere-lin-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/sphere-lin-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/sphere-nn-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/sphere-nn-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/sphere-nn-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/sphere-nn-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/sphere-ref-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/sphere-ref-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/sphere-ref-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/sphere-ref-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/steep-lin-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/steep-lin-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/steep-lin-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/steep-lin-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/steep-nn-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/steep-nn-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/steep-nn-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/steep-nn-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/steep-ref-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/steep-ref-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/steep-ref-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/steep-ref-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/trig-lin-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/trig-lin-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/trig-lin-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/trig-lin-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/trig-nn-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/trig-nn-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/trig-nn-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/trig-nn-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/trig-ref-con.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/trig-ref-con.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_delaunay/trig-ref-img.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_delaunay/trig-ref-img.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_image/image_shift.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_image/image_shift.pdf differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_image/image_shift.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_image/image_shift.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_image/image_shift.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_image/image_shift.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_image/imshow.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_image/imshow.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_image/imshow.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_image/imshow.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_image/imshow.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_image/imshow.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_image/imshow.svg 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_image/imshow.svg 2012-10-31 00:11:14.000000000 +0000 @@ -30,127 +30,7 @@ +iVBORw0KGgoAAAANSUhEUgAAAVsAAAFbCAYAAAB7zy3tAAAABHNCSVQICAgIfAhkiAAAGkVJREFUeJzt3V+W28ZygPECRrac5OFuIN6HVuJFOhvRPnw3kKck9hWRhyGA6uqqRgPklMzW9ztHJog/DXB09KkH5MjTsiwCAPhY8/e+AAD4ERBbAEhAbAEgAbEFgATEFgASEFsASEBsASABsQWABMQWABIQWwBIQGwBIAGxBYAExBYAEhBbAEhAbAEgAbEFgATEFgASEFsASEBsASABsQWABMQWABIQWwBIQGwBIAGxBYAExBYAEhBbAEhAbAEgAbEFgATEFgASEFsASEBsASABsQWABMQWABIQWwBIQGwBIAGxBYAExBYAEhBbAEhAbAEgAbEFgATEFgASEFsASEBsASABsQWABMQWABIQWwBIQGwBIAGxBYAExBYAEhBbAEhAbAEgAbEFgATEFgASEFsASEBsASABsQWABMQWABIQWwBIQGwBIAGxBYAExBYAEhBbAEhAbAEgAbEFgATEFgASEFsASEBsASABsQWABMQWABIQWwBIQGwBIAGxBYAExBYAEhBbAEhAbAEgAbEFgATEFgASEFsASEBsASABsQWABMQWABIQWwBIQGwBIAGxBYAExBYAEhBbAEhAbAEgAbEFgATEFgASEFsASEBsASABsQWABMQWABIQWwBIQGwBIAGxBYAExBYAEhBbAEhAbAEgAbEFgATEFgASEFsASEBsASABsQWABMQWABIQWwBIQGwBIAGxBYAExBYAEhBbAEhAbAEgAbEFgATEFgASEFsASPDpe18AnuePP/77169f//kl3mM68dxbPlp3Zcwz5zo6tuf43tdy9jqecc7Sly8/ff3117c/wh3wUojtQL5+/eeX3377r9/9rZOUf8Cj59Gv+eB579gSHHt27Na2K+P3vsbW6zp7ztkcX/r993/8RmzHwW0EXLR87wsAXgqxBYAExBYAEhBbAEhAbH849g0Z+ybPI/t7784fvYN/9TqiY+N394/HaD3v3Qb4+DTCUN5E5N+DbVffRb/6aQFpbJtEppPnnC5e+9nzrK8vPC54ndOZr6U3vmMm6iMhtkP5JDmxPYqQWT4KkbfdjZEdM3gN09H6C0F2x/Rem722g/MU4xp83zkUYjuUo5ltT2Bb2zpneSJOnMyjDo8Nlg1pNFZP6KaecTvCatfpcbexvG1OZN1rcjCzHQqxHUpPbPXy2eB666V+bIW2iFIQviJGZoypMZ7e3x27cZ5m9J1z6+uanGupgmquq1rnILZDIbZDeRORfwu2HQW2FVZ7vLft/mjjqM/vRbSIo1k+iltzvYmrex59PVFUOwO7PbZea+NaPLR2KMR2KEf3bB+NrbdOFaGYodlIqXVeqKL4NiNrjznxWM12zXm944pr9V7H0fnUeb2xLWa2QyG2Q+m9Z3smtkePNggmuFVo1XovVl6A7XH6GHv8pbGDx2hb8WVYzxcse9ejXwOx/WEQ26F8dGy9dY3Y2pDYYB6Fqgrs0fMTy1G83VmqWV8sO8/19YfHTfU5LD6NMBRiO5SPuI0gfctVc80KL7xRuPTpJzN+tK4ItBrHDaA3xkHEi2uMxuxZ57y+MLbRBrwiYjuU1htkR//soBdbkboER88dxbfl9hROnMIgmuUqsOZYd32wTV9n6zzR30k27tHr8K6D2P4QiO1Q3kTkP4JtrbBGPxEWjXMgavVkVpzpfnM5itmVsaMQP/qrFWPxcRthKMR2JNMs8vZztLHz11weUo3ROr+zm7cc9f1ybIPnPefpGdsb9+x5el6j9Rasx0sitiOZJ5HP0Z/cxp/06kdfg+MPNruP0bYzgZKTy70xtMdcHftKdEXtb79eK2I7FGI7kllEfj6Irf3xUG/3at0U76vXn3k8Eyg5udwbw9bxV8Z+5JeH2whDIbYjmeV4Ztv6kVR76OSsjOLcG1i93BNdu380Vmvc6Dyt46+O/czYMrMdCrEdyTzFM9vmvw+wrluX1YIbYOd5FNxoXU8MM4PYe55nB5bY/jCI7UjeRORz43vP5o+Mqu3VsrSXW7GKlnuD2zvWmbHPxPbRcVvnsestYjsUYjuS5sz2/h/96P5I67ZzHdNouTeA9nlPcKPxW+f9u8Y2GitCbIdCbEfSumfrRlYvT2UQeh63Mcxyz7qsj34dnatn7Gjc1nmiY6KviYfYDoXYjuToDbLiD7h+buJ7Nro9wYu29URXTi73xPDo2s+Obc/jHXN0PovYDoXYjuToDbLqD7kJcPjjqo11eltvMHtC+FFB/F4f/WqNT2x/CMR2JK03yJrhsNENjjkaxx375K/W7NOOf/i6Ds4THd86T1ZoRfic7WCI7UjmSeTRn9btie6zwtoT3dY5n3k9H/k6e8b2MLMdCrEdyTP/rzgfHbeHr2Xpvhb7/1t8/7XE4x+8zqeNd1+OWju96b9x8OqI7Ug+MrZ2jKtjXr6ORlylDF0dw+V4m3mt1f+z0tn/8DxixhC1n7fNmj8J09txENuRPDu2R5F9ZNxT12BmjTpWah8vftu62Ty38Zvuq7xt4oS1Ot9SR1Zd+zZ29ai2G/MboR0JsR3JR8fWjvPIuN3ntt+e6+eLmYHqmWWw36y2qeufbNAl2E+F3m7X59zGk328bUy9zqvsal4aG/FqiO1IMmP7yJg953K3rzFTs8hilmvW2wCu6+byuMlE3D4XKc81FbcSluqY4nhRz0WNJ+baHdMbsR0JsR3Jq8a2Nda2bQ/t/u37Giu7rYyu+ziLFLcCilCaMUQdtx7jrZuWIqL7Py9hbhUU2+OgTvMt3IbXQ2xH8oqfRojGMbcLqkcJ1rcCGz6+n68V3iiq1aMNsqzbguX1dTiY2Y6F2I7k1WLrjSGiollvK2a11WN562C6r5uqdfWjjq2+f1svv0dy2man++O0zWDV4/qSVFAndUthas5sie1IiO1IXumjX97xImVoi330LYI6sO/b6+Wpsbw9ioqujqV5M2yfxZbL6zFVeLeXUIa5WKffSLO/Zcxsh0JsR5IV26vjtWIr0gjt+sveWrBxLYO8z2iXe2jr5+VHu+rbBe/bVFBF73Of5W4zXj3rXW8TLNtLEX2sSLVP9VvGPduhENuRvNobZMV40U9gOZ+xrT7WtYi9jaDXTXrdvGzL2+zUBHb/Vyf1bQEb0j2863IRXHWMF9f9JTZuIzCzHQqxHcm8yPRLsM2dHbZ/Tfq4nmX76+j/KSbqesIx95movX1QRrYMrf0VbROxUZV4/Tab1bHdbwfY7ev6nkfP3NiG10NsBzLNi3z6+V/OBvWoY9p4IyqafdY/IeUcb8/h7bOtM581rUKvZqhSh7XY7oVV4tjqgIq0o1sE1wmrjueV2K4z3vel98dZvtW/l3hZxHYg89tNPn3+y99oIqc/j7qurz+/Wh6z7SPOPsUY9S2BYr0arwry9lh/CsDOZtfbADa2OpZeWJux1Y/Om15eVMNZ7oOz2zfhnu1IiO1AwpmtiJol2llj/VxER1Wk/mmoYL0Kdfjc/BjrFsxtzHW9umWg37BSM9wtvLLPcquZbPD86KNbOpzr41FYr89q/dgysx0LsR3INN/kLZjZ1h/QFzU7tMsi5Qfw93VFnOW+n73NUC3X592GcGOuny/35/oNrTXAa2z92et6vF1uflxL3Srwwhvdlz2K7bV7tsxsR0JsB9Ka2Vb/gIpdp2aSW0cnFQMb6G2deffejOeeQ+8bjLlFXUV1stHVM9xWOG2Io5Da49Wye89W2tvWcXsePdxGGAuxHcg8x/dsi893RvcobYTVcftzZ5uKcj3W/bzOvnXMdXR1VNcxluBxDfnBrFUtu9uc+HrRbd635TYCAsR2INN8k08/O7FdZ5MqekXIqqCJFFG+b9OzTZEyxFMxhj2HDbI6Ts92nQi7ES3WrYETtRzce/VuEQS3CfTzszPaZ91GYGY7FmI7kOltkU+fgzfI9AzQxFZ/e74Hb4+niEgZZanGWJ8XPz2lQ2gjrGe76/gm6PovgO26i/Op2a0Nq9Qz2nWb+6kBE019fDiTPdheXMuF2DKzHQuxHcg03+TNm9mKbKGtv2XWkdVBFimC936Qs+14rHqWWh//vmC31TNWf+xgRipSB9iNrRRjtOLqrg+Ca8+7b9/PV7x+g5ntWIjtQOY5ntmGUfBmeeJEYqrDEAbm4P7mdrwTwvpxD3gxi+0IZfQ6om/v3XhO9frWMdHYPY8WM9uxENuBhPdsJZjF2Wi53xav+x89NiLorj87bjRevU3sPd/g8Ww4r2zruYYIH/0aC7EdyDzd5OfpT3fbmVis6+1jT7jOjn0mio8GLjO4Z7+GHm4jjIXYDmSWm3yW/6vWR7PC92393wKfie2VEPWP7b+eZ4x99vWcfY1nYstthLEQ24G8yTf5Rf7X3XYmGN7+R+vOxsqOET1eieCZsVvjnnmNj34N/d9PZrYjIbYDiWa2Iu1wtZ6vy966R4LbOoe3z5Wx63FE7KcArsT8I76GHma2YyG2A3l7QmwfWe4N47q+9/GZwX3G2MexFfGi3lr28AbZWIjtQObGbQQRPwb9Ie07pidg6/PosSeKRzPOM+c4+5fEI38Ztfaz3pjZDoXYDuRoZrs+PjsUZ2eFz4rio2OfHfcjv4YeZrZjIbYDmeXbQ7HV6648PxPdo0fvEwc9416JbO+4z46tvSaLN8jGQmwH0vMG2brcu+5KbJ8V3J5r8LeJeD8OezW4Z75e5Tj7dRx9XT28QTYWYjuQ1ke/RK7E4lzwovVHM7qjGJ4Z99GYXx370a+hh5ntWIjtQI5mtkePj0Yums09K4S913N27DOvs+dr1zu+Pbb+/WRmOxJiO5DeN8js45UZ5dUYt87Zur4z56yPFzn17y4s8V8cvdccX2c9Zhzbm8jkbsILIrYD6fnoV+9jb+DO/Chwb+hlaQVr3abD2A54Fdol/gul+FfG7uPba/X+ecjqcYm/DtU5g9u286eF2A6E2A6kNbMVefw+5plt3r56XbG8xNcgImqmqUK4BDPUYv1KrVvM8/WcVbTvz5el2t9GuzqHOpcNuF6vt7m/X/MiMgcb8XKI7UB6P/rV+3gmuN56u04/F6lnf9v2xR4r9xjWsbUB28baJoV2xvm+zouvju4+czb736/lfUy9TZzQ6+Pr16G3e+afeINsJMR2II++QbY+HgX3Slyj2WwdSLOvjuq6rGehxXY905Qt2uX4IluAF+/cUkaz2mc/3j3HfXP5F8o61v3RXKseo/g9uwX3F/CSiO1ArvwEWfR45dbBmR/prbbZe5x6druUYS2+5V/Kx/sliP5W312WfZa7hc8JoI1tvbyPob+GXWPqsR1zEGG8JmI7kNYbZJm3Ec4ul2F1ZrUqTpPzKHY/kS2s+2xU1IxVihjus041y1z2QOu46n29Mauwd40bzWy5jTASYjuQqx/9so9XbiNExx4u6xnt4sf3PaRS30ZY1hmtjpmNYzmD3Z9LEb4iossS7CP7/VoT3PfrLferxm6dxzFzG2EoxHYg/f82goiY6NX7nL+N4I3hLldvgO3fbhefcd3iK/dfar2K7Lpch9GE14ntNvO9x3zbrmfGJrT72FJF2Btf1PUV11D8BfG+ST9G93LxmojtQN7k9iGfs+2Nrt7naFwRZyarP+Kl162xNeF9326De/9PEbn7F6CIsBQx3NarIG5jmJlxczy73R6vzjfZ8xvMbMdCbAfSmtmK9N860OvO3K9tjeVtC8dXEV5nmWVoxWwrn4uIClq9bp3F7jNaqUK4P/fHPX5Ux1Vj7r/sLQ9tXrhnOxJiO5BnffRrfey9ffDQ2NHsdlH3a0X2WwdOcLfo2hnluqzW2ZnvYQyjfezY3rbDkJv1Bh/9GguxHci83OSn21/utvjD9tHjGro1pjquYtYFY4Tn2Get7zM7HV11Xze4hbBGsJrhBlF01/eEsRVL6Vx3ZlyLie1QiO1Aptsin/70/6Uo/XnQfYb5vs7/UdQyrkVsF/3cH0NE3Ve151vUGCqy67Xt2+ug6tC6QTWxC0Nrn3/P0Eax5R/9GgqxHcjciK3IHr0yuPuf9DqO9ScH1v3KWwL3QZ2Qb+MtZWy3cezyot6JVzNaL7LNGet6vo+I7ZnwElvcEduBTLdF3poz2/INmUmVYf+8p57ZShHYdVv5U1XLNvY+s933Kc7j/RDCosZe1NjLfb81qiJS3S7w3rzS+5h11fMr8RVn/2j57LgWsR0KsR3IdFvk01/Bn9DFzDaruJbLVWSL7fa+rLNsx9THLSrUi15vn9dvfu3PlzCsT7tHG+0rznZvHTNbKMR2INNN5NOf0bsqSxncNV4iUv8E1B5XETPb1OEt9tmXw/Os16CPV/dvdUTD2ay3TkUuund7ObhXIntlfA9vkA2F2A6kfc92KR6Kn05ayuhu282+5T/csu9/FNpq3aLu496Dq9cV0V2HLoLrfwKhCm0rfNH6ntieCe8jsWVmOxRiO5DptshbeBtBf2uvH/W3+c6+NoI2ovanpmQpv633zm+CqeMqUt4iKIO7xHHVY18Ja88+R5G9Glpi+0MgtgNpffRrDVwRqm19ud1G0c4gy3+oZV/XPe42vvkpK/tvE+h99DXZa3SeX45pzzHV6wjWEVsoxHYgx7GVLWg2DF4I9XMbWzd01eNSra/vqe5j1bcB9mttfV626z7tsyLsfO2a6xZ5v/dKbH94xHYghx/9cuOwtENhftUzyDqoXQFaxJmxLv557XFH19q4/ocDHH4dHzy3hzfIhkJsBzIvi8yNj35FM8NToWjtI84+3rorcYyuMzq2Z8yrAW69zqvn9jCzHQqxHck3kfBfWOwNrH1+JkTeuK1zXY3cs/+SePZ1OOda7Hj21oLn2/7DKHh9xHYkV2L7jODKwXK0PTu4jwT44jVUkQ3WeSZmtkMhtiO5yXNi+6wYeeuunicaq/ccj0a39TULlnVUbWCrbY75xsx2JMR2JFdntmdC1dpPnGVv3dUQ9iw/61xXY3t/7oU2im/4f79hZjsUYjuSbyLyP8G2M1Hy1l2JorfuSuh6QnvlmlvH9a4/eG5DGz26iO1QiO1Ijma26+OVuB7tIyeXH4n41aA/I7h2nbPPYtZ5ge2J7UJsh0JsR3J0z3Z9vBrcM+HpWX4kuL1j9p7P2+/CuuatAhtaEVluYWv5nO1giO1Irs5sHwnhsyLbu/3q+D3nsuu9/RrnWZxtNrh2Vrs9dzCzHQuxHUnPG2R6+ZnRjc5x9tw9437U+L3jOeuXxvbF/HLXeYjtUIjtSHo++qWXH4nS9wju0ZiPjN37PIjpmXPZ0BLbHwOxHckjH/16VoClY/lK0MXZx1v36F8Svdd9Xx+F1gtq+Et8C/dsh0JsB7J8QGyX3v0lGDtaf2Z8bwy7rjHG4Tm8cQ+iG/4UmNq2xvTWiGxrZvuZ2A6F2I7kJnLriO1yFBCz/nA2J/tjNYYaaxHnGDuec+7FjmUeq+3R8c51VyH2xvJel3Pd7pthEodWR9jzi4j87G/CCyK2A1m+idyiH2oQcYO6BLGI9m+F064rQmafLyef23Poce26i2O3wr4Ex0Zfvyqyref6XMq3IMJ4TcR2IMu39sy2CIazXAVJLYsEobZjy7n1Vbi8axHneWtbcM3V8tEY0bWb8aKvpQ1qa9nD+2NjIbYj6YytDZ2Nh17XimoxRnSO1vkb41frzHJzexTAnrE7x42+dnq/MLLOOs+//NV4UcR2IMvBPVv9B9t7rEKltrsh88YJ1m3nD8bqejTLvUFvvebtUCey3nbv6xSdo4pr49HDzHYsxHYgrXu2OiBuJMQPxnZsI6BeSKvzRcvOdbjronN7z20YnfP1HB+ds/k6nPMvZpu3zkNsx0JsR9K4jeAFwQYjCue6jx3Hrq/ibc9z8rxuvO357bV1jtsMd2NMO779y6pnvfe18aa3vEE2FmI7kNYbZK3wRWH0ZqnhNm88c4wXHPGOM8fofbrWH7wu7/wi5T7R2M2v4cHraG33cM92LMR2IEe3EaLgNcO0LgezP3eMg3M0j12cfdW26roeHbcxpve6D19f4/zRGPprqnEbYSzEdiSNN8iiANj/72AUOjtbDMc04y/SPsepQB+sk4PXcxQ/aY0t6rVEQT14PdHXLEJsx0JsB3J4G0H8GPUGtze03edY+q7h7PnPXFcrrG5oO8a9nRw3Ci63EcZCbEfTmCp5m1ozq3W73Sc6Jto3WhfN7s5uj64j2u9MaPW61thH57kSW4xl/t4XAFj8H2UxImKLvx1mehgRscXfDjNbjIjY/kBeJWLMbDGiaYl+VhAv59sff/z619evX6Lt9s2eo3V2+ej52fGPztlzrrPX0Tt+6/lHff2s//zy5es/fv31j8YueCHEFgAScBsBABIQWwBIQGwBIAGxBYAExBYAEhBbAEhAbAEgAbEFgATEFgASEFsASEBsASABsQWABMQWABIQWwBIQGwBIAGxBYAExBYAEhBbAEhAbAEgAbEFgATEFgASEFsASEBsASABsQWABMQWABIQWwBIQGwBIAGxBYAExBYAEhBbAEhAbAEgAbEFgATEFgASEFsASEBsASABsQWABMQWABIQWwBIQGwBIAGxBYAExBYAEhBbAEhAbAEgAbEFgATEFgASEFsASEBsASABsQWABMQWABIQWwBIQGwBIAGxBYAExBYAEhBbAEhAbAEgAbEFgATEFgASEFsASEBsASABsQWABMQWABIQWwBIQGwBIAGxBYAExBYAEhBbAEhAbAEgAbEFgATEFgASEFsASEBsASABsQWABMQWABIQWwBIQGwBIAGxBYAExBYAEhBbAEhAbAEgAbEFgATEFgASEFsASEBsASABsQWABMQWABIQWwBIQGwBIAGxBYAExBYAEhBbAEhAbAEgAbEFgATEFgASEFsASEBsASABsQWABMQWABIQWwBIQGwBIAGxBYAExBYAEhBbAEhAbAEgAbEFgATEFgASEFsASEBsASABsQWABMQWABIQWwBIQGwBIAGxBYAExBYAEhBbAEjw/w0eDkzZ+eWwAAAAAElFTkSuQmCC" y="41.8"/> @@ -158,277 +38,92 @@ +L0 -4" id="mcb557df647" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + +L0 4" id="mdad270ee8e" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - - - - - - - - - - - - - + - + - - - - - - - - - - - - + - + - - - - - - - - - - - - + - + - - - - - - - - - + - + - - - - - - - - - - - - + - + - - - - - - - - - + - + - - - - - - - - - - - - + @@ -439,148 +134,92 @@ +L4 0" id="mc8fcea1516" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + +L-4 0" id="m0d5b0a6425" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - - - - - - - - - + - + - - - - - - - - - + - + - - - - - - - - - + - + - - - - - - - - - + - + - - - - - - - - - + - + - - - - - - - - - + - + - - - - - - - - - + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_image/interp_nearest_vs_none.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_image/interp_nearest_vs_none.pdf differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_image/interp_nearest_vs_none.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_image/interp_nearest_vs_none.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_image/interp_nearest_vs_none.svg 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_image/interp_nearest_vs_none.svg 2012-10-31 00:11:14.000000000 +0000 @@ -30,9 +30,7 @@ +iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAABHNCSVQICAgIfAhkiAAAABtJREFUCJljvrVU8T+v6L0GhoZ/DP//JXv8BwBPvwlIEKcPcwAAAABJRU5ErkJggg==" y="-0.5"/> @@ -40,185 +38,68 @@ +L0 -4" id="mcb557df647" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + +L0 4" id="mdad270ee8e" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - - - - - - - - - - - - - - - - + - + - - - - - - - - - + - + - - - - - - - - - + - + - - - - - - - - - - - - + - + - - - - - - - - - + @@ -229,109 +110,68 @@ +L4 0" id="mc8fcea1516" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + +L-4 0" id="m0d5b0a6425" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - - - - - - - - - - + - + - - - - - - - - - + - + - - - - - - - - - + - + - - - - - - - - - + - + - - - - - - - - - + @@ -356,207 +196,6 @@ M72 317.455 L72 114.545" style="fill:none;stroke:#000000;"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -570,119 +209,66 @@ +iVBORw0KGgoAAAANSUhEUgAAAMwAAADLCAYAAAAiJ3xKAAAABHNCSVQICAgIfAhkiAAAAldJREFUeJzt1UERwkAABMEEJXGDEXyAFD4xggAEYOYQkHzmdVDVrWA/U7t+9m0s/Jzn6z17AicuswfAPxEMBIKBQDAQCAYCwUAgGAgEA4FgIBAMBIKBQDAQCAYCwUAgGAgEA4FgIBAMBIKBQDAQCAYCwUAgGAgEA4FgIBAMBIKBQDAQCAYCwUAgGAgEA4FgIBAMBIKBQDAQCAYCwUAgGAgEA4FgIBAMBIKBQDAQCAYCwUAgGAgEA4FgIBAMBIKBQDAQCAYCwUAgGAgEA4FgIBAMBIKBQDAQCAYCwUAgGAgEA4FgIBAMBIKBQDAQCAYCwUAgGAgEA4FgIBAMBIKBQDAQCAYCwUAgGAgEA4FgIBAMBIKBQDAQCAYCwUAgGAgEA4FgIBAMBIKBQDAQCAYCwUAgGAgEA4FgIBAMBIKBQDAQCAaC9T6WMXsER4/bdfYETngYCAQDgWAgEAwEgoFAMBAIBgLBQCAYCAQDgWAgEAwEgoFAMBAIBgLBQCAYCAQDgWAgEAwEgoFAMBAIBgLBQCAYCAQDgWAgEAwEgoFAMBAIBgLBQCAYCAQDgWAgEAwEgoFAMBAIBgLBQCAYCAQDgWAgEAwEgoFAMBAIBgLBQCAYCAQDgWAgEAwEgoFAMBAIBgLBQCAYCAQDgWAgEAwEgoFAMBAIBgLBQCAYCAQDgWAgEAwEgoFAMBAIBgLBQCAYCAQDgWAgEAwEgoFAMBAIBgLBQCAYCAQDgWAgEAwEgoFAMBAIBgLBQCAYCAQDgWAgEAwEgoFAMBAIBgLBQCAYCAQDgWAgEAwEX/HUCgtErBocAAAAAElFTkSuQmCC" y="114.454545455"/> - + - - - - - - - - - - + - + - - - - - - - - - + - + - - - - - - - - - + - + - - - - - - - - - + - + - - - - - - - - - + @@ -691,101 +277,60 @@ - + - - - - - - - - - - + - + - - - - - - - - - + - + - - - - - - - - - + - + - - - - - - - - - + - + - - - - - - - - - + @@ -810,64 +355,6 @@ M315.491 317.455 L315.491 114.545" style="fill:none;stroke:#000000;"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_image/no_interpolation_origin.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_image/no_interpolation_origin.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_image/no_interpolation_origin.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_image/no_interpolation_origin.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_image/no_interpolation_origin.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_image/no_interpolation_origin.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_image/no_interpolation_origin.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_image/no_interpolation_origin.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_image/uint16.tif and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_image/uint16.tif differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_legend/fancy.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_legend/fancy.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_legend/fancy.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_legend/fancy.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_legend/fancy.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_legend/fancy.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_legend/fancy.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_legend/fancy.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,870 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_legend/legend_auto1.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_legend/legend_auto1.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_legend/legend_auto1.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_legend/legend_auto1.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_legend/legend_auto1.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_legend/legend_auto1.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_legend/legend_auto1.svg 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_legend/legend_auto1.svg 2012-10-31 00:11:14.000000000 +0000 @@ -16,7 +16,7 @@ L576 0 L0 0 z -" style="fill:#ffffff;stroke:#ffffff;"/> +" style="fill:#ffffff;"/> @@ -41,114 +41,109 @@ C-3 0.795609 -2.6839 1.55874 -2.12132 2.12132 C-1.55874 2.6839 -0.795609 3 0 3 z -" id="m1a9f33571b"/> - - - - - +" id="m0f54036a79" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -164,109 +159,109 @@ C-3 0.795609 -2.6839 1.55874 -2.12132 2.12132 C-1.55874 2.6839 -0.795609 3 0 3 z -" id="m1a9f33571b"/> +" id="m365dd9364a" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -275,323 +270,80 @@ +L0 -4" id="mcb557df647" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + +L0 4" id="mdad270ee8e" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - - - - - - - - - - + - - - - + - - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - - - + @@ -602,212 +354,92 @@ +L4 0" id="mc8fcea1516" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + +L-4 0" id="m0d5b0a6425" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - + - - - - + - - - - - - - - - - + - - - - + - - - - - - - - - - - + - - - - + - - - - - - - - - - - + - - - - + - - - - - - - - - - - + @@ -845,60 +477,60 @@ - - - - - + + - + + - + @@ -906,37 +538,23 @@ - - - - - + + - + - + @@ -946,4 +564,9 @@ + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_legend/legend_auto2.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_legend/legend_auto2.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_legend/legend_auto2.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_legend/legend_auto2.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_legend/legend_auto2.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_legend/legend_auto2.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_legend/legend_auto2.svg 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_legend/legend_auto2.svg 2012-10-31 00:11:14.000000000 +0000 @@ -16,7 +16,7 @@ L576 0 L0 0 z -" style="fill:#ffffff;stroke:#ffffff;"/> +" style="fill:#ffffff;"/> @@ -29,11 +29,6 @@ " style="fill:#ffffff;"/> - - - - - +L0 -4" id="mcb557df647" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + +L0 4" id="mdad270ee8e" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - - - - - - - - - - + - - - - + - - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - - - + @@ -2166,172 +1918,80 @@ +L4 0" id="mc8fcea1516" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - + +L-4 0" id="m0d5b0a6425" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/> - - - - - - - + - - - - + - - - - - - - - - - - + - - - - + - - - - - - - - - - - + - - - - + - - - - - - - - - - - + - - - - + - - - - - - - - - - - + - - - - + - - - - - - - - - - - - + @@ -2376,53 +2036,53 @@ z " style="fill:#bf00bf;stroke:#000000;"/> - + +L45.3125 8.40625 +Q42.0469 3.42188 37.7188 1 +Q33.4062 -1.42188 27.6875 -1.42188 +Q18.2656 -1.42188 13.375 4.4375 +Q8.5 10.2969 8.5 21.5781" id="BitstreamVeraSans-Roman-75"/> +M18.1094 8.20312 +L18.1094 -20.7969 +L9.07812 -20.7969 +L9.07812 54.6875 +L18.1094 54.6875 +L18.1094 46.3906 +Q20.9531 51.2656 25.2656 53.625 +Q29.5938 56 35.5938 56 +Q45.5625 56 51.7812 48.0938 +Q58.0156 40.1875 58.0156 27.2969 +Q58.0156 14.4062 51.7812 6.48438 +Q45.5625 -1.42188 35.5938 -1.42188 +Q29.5938 -1.42188 25.2656 0.953125 +Q20.9531 3.32812 18.1094 8.20312 +M48.6875 27.2969 +Q48.6875 37.2031 44.6094 42.8438 +Q40.5312 48.4844 33.4062 48.4844 +Q26.2656 48.4844 22.1875 42.8438 +Q18.1094 37.2031 18.1094 27.2969 +Q18.1094 17.3906 22.1875 11.75 +Q26.2656 6.10938 33.4062 6.10938 +Q40.5312 6.10938 44.6094 11.75 +Q48.6875 17.3906 48.6875 27.2969" id="BitstreamVeraSans-Roman-70"/> - + @@ -2436,88 +2096,88 @@ z " style="fill:#008000;stroke:#000000;"/> - + +L9.07812 54.6875 +L18.1094 54.6875 +L18.1094 46.1875 +Q21.3438 51.125 25.7031 53.5625 +Q30.0781 56 35.7969 56 +Q45.2188 56 50.0469 50.1719 +Q54.8906 44.3438 54.8906 33.0156" id="BitstreamVeraSans-Roman-6e"/> +L45.4062 8.20312 +Q42.5781 3.32812 38.25 0.953125 +Q33.9375 -1.42188 27.875 -1.42188 +Q17.9688 -1.42188 11.7344 6.48438 +Q5.51562 14.4062 5.51562 27.2969 +Q5.51562 40.1875 11.7344 48.0938 +Q17.9688 56 27.875 56 +Q33.9375 56 38.25 53.625 +Q42.5781 51.2656 45.4062 46.3906 +M14.7969 27.2969 +Q14.7969 17.3906 18.875 11.75 +Q22.9531 6.10938 30.0781 6.10938 +Q37.2031 6.10938 41.2969 11.75 +Q45.4062 17.3906 45.4062 27.2969 +Q45.4062 37.2031 41.2969 42.8438 +Q37.2031 48.4844 30.0781 48.4844 +Q22.9531 48.4844 18.875 42.8438 +Q14.7969 37.2031 14.7969 27.2969" id="BitstreamVeraSans-Roman-64"/> +M30.6094 48.3906 +Q23.3906 48.3906 19.1875 42.75 +Q14.9844 37.1094 14.9844 27.2969 +Q14.9844 17.4844 19.1562 11.8438 +Q23.3438 6.20312 30.6094 6.20312 +Q37.7969 6.20312 41.9844 11.8594 +Q46.1875 17.5312 46.1875 27.2969 +Q46.1875 37.0156 41.9844 42.7031 +Q37.7969 48.3906 30.6094 48.3906 +M30.6094 56 +Q42.3281 56 49.0156 48.375 +Q55.7188 40.7656 55.7188 27.2969 +Q55.7188 13.875 49.0156 6.21875 +Q42.3281 -1.42188 30.6094 -1.42188 +Q18.8438 -1.42188 12.1719 6.21875 +Q5.51562 13.875 5.51562 27.2969 +Q5.51562 40.7656 12.1719 48.375 +Q18.8438 56 30.6094 56" id="BitstreamVeraSans-Roman-6f"/> - + @@ -2527,4 +2187,9 @@ + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_legend/legend_various_labels.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_legend/legend_various_labels.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_legend/legend_various_labels.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_legend/legend_various_labels.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_legend/legend_various_labels.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_legend/legend_various_labels.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_legend/legend_various_labels.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_legend/legend_various_labels.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,611 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_66.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_66.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_66.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_66.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_66.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_66.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_66.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_66.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_67.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_67.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_67.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_67.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_67.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_67.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_67.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_67.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,459 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_66.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_66.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_66.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_66.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_66.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_66.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_66.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_66.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_67.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_67.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_67.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_67.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_67.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_67.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_67.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_67.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,321 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_66.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_66.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_66.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_66.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_66.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_66.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_66.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_66.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_67.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_67.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_67.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_67.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_67.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_67.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_67.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_67.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_pickle/multi_pickle.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_pickle/multi_pickle.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_png/pngsuite.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_png/pngsuite.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_png/uint16.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_png/uint16.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_scale/log_scales.pdf matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_scale/log_scales.pdf --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_scale/log_scales.pdf 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_scale/log_scales.pdf 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,66 @@ +%PDF-1.4 +% +1 0 obj +<< /Type /Catalog /Pages 2 0 R >> +endobj +8 0 obj +<< /XObject 7 0 R /Pattern 5 0 R +/ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /ExtGState 4 0 R +/Shading 6 0 R /Font 3 0 R >> +endobj +10 0 obj +<< /Group << /CS /DeviceRGB /S /Transparency /Type /Group >> /Parent 2 0 R +/MediaBox [ 0 0 576 432 ] /Resources 8 0 R /Type /Page /Contents 9 0 R >> +endobj +9 0 obj +<< /Filter /FlateDecode /Length 11 0 R >> +stream +xKn0D:N@G%^ p$)%5vq3RKn1-f;?d?縦,~V]4XY&7lr}cyŽbs.هhyUwSJژ|)Υc+Je8/>IƦb> r#zvM+G\]:= ֧lQ}WR}wU/]m^*TrūN2UfueVlTTZIԑ"Y5QrsG-_[vXmCߖY5QS/l[d-wPJߖY%QS=9p׉SVĚ>U{XR2uV ԋ^ Վօ/LcW bDnՋSz c&kMeXI7Ҝ3Ai茇AJ &(!xޙ4tF Bv2Ap-hdyg@ҏ+=Mlā]{ˌ1 7ҖdC~1ճCtA"J?CRD~$ֱXbz F8Fv~A,0:'83#1Gu1HDGbQf^f<Nqb^i@g3<pĬ4sb4?43"(HLˌ1 7҂Sg~ALL:'L3ONi@gD QXﬔbnqlՙt~/mG3/Qi@8iq{n:]aoM'>` +endstream +endobj +11 0 obj +911 +endobj +3 0 obj +<< >> +endobj +4 0 obj +<< >> +endobj +5 0 obj +<< >> +endobj +6 0 obj +<< >> +endobj +7 0 obj +<< >> +endobj +2 0 obj +<< /Count 1 /Kids [ 10 0 R ] /Type /Pages >> +endobj +12 0 obj +<< /CreationDate (D:20120917121216+01'00') +/Producer (matplotlib pdf backend) +/Creator (matplotlib 1.2.0rc1, http://matplotlib.sf.net) >> +endobj +xref +0 13 +0000000000 65535 f +0000000016 00000 n +0000001484 00000 n +0000001379 00000 n +0000001400 00000 n +0000001421 00000 n +0000001442 00000 n +0000001463 00000 n +0000000065 00000 n +0000000373 00000 n +0000000208 00000 n +0000001359 00000 n +0000001544 00000 n +trailer +<< /Info 12 0 R /Root 1 0 R /Size 13 >> +startxref +1698 +%%EOF Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_scale/log_scales.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_scale/log_scales.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_scale/log_scales.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_scale/log_scales.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_scale/log_scales.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_scale/log_scales.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,712 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_simplification/clipping.pdf matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_simplification/clipping.pdf --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_simplification/clipping.pdf 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_simplification/clipping.pdf 2012-10-31 00:11:14.000000000 +0000 @@ -1,31 +1,28 @@ %PDF-1.4 % 1 0 obj -<< /Type /Catalog /Pages 3 0 R >> +<< /Type /Catalog /Pages 2 0 R >> endobj -2 0 obj -<< /CreationDate (D:20090927212543+03'00') -/Producer (matplotlib pdf backend) -/Creator (matplotlib 1.0.svn, http://matplotlib.sf.net) >> -endobj -9 0 obj -<< /XObject 8 0 R /Pattern 6 0 R -/ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /ExtGState 5 0 R -/Shading 7 0 R /Font 4 0 R >> -endobj -11 0 obj -<< /Contents 10 0 R /Type /Page /Resources 9 0 R /Parent 3 0 R -/MediaBox [ 0 0 576 432 ] >> +8 0 obj +<< /XObject 7 0 R /Pattern 5 0 R +/ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /ExtGState 4 0 R +/Shading 6 0 R /Font 3 0 R >> endobj 10 0 obj -<< /Filter /FlateDecode /Length 12 0 R >> +<< /Group << /CS /DeviceRGB /S /Transparency /Type /Group >> /Parent 2 0 R +/MediaBox [ 0 0 576 432 ] /Resources 8 0 R /Type /Page /Contents 9 0 R >> +endobj +9 0 obj +<< /Filter /FlateDecode /Length 11 0 R >> stream -xmQKN0 >lTb,8  6ӣ}eO2c# .52#Jf]2J6H;ȶbK7 -2nN?o_i2'^H;z "w!JnEYenT<l4j=4c5gF~2v$d\IK~/;!OPz|cƖ*w0em +xmn\! <_ 6 lF]E iUTj75?f2+l=`,~;37Okt961r_ 亖2ƞ\FrƬ.rS]7o'Gc\|/>T3WO*}%eS5pq#AtYX7b,{$xpv߬F~G+!4\kC;@iEث[ֽYkly#1Yf$i5#{jeFF09#{jeFn2Ƚ}ogzFՂj֩nԐ5Jy֩Np4*Rť.ʤN-R4W7St5lU"LR+ŪÍҠTNV-fZOn]ݽ O`ߕ;a*:Z endstream endobj -12 0 obj -229 +11 0 obj +411 +endobj +3 0 obj +<< >> endobj 4 0 obj << >> @@ -39,29 +36,31 @@ 7 0 obj << >> endobj -8 0 obj -<< >> +2 0 obj +<< /Count 1 /Kids [ 10 0 R ] /Type /Pages >> endobj -3 0 obj -<< /Count 1 /Kids [ 11 0 R ] /Type /Pages >> +12 0 obj +<< /CreationDate (D:20120507152718-04'00') +/Producer (matplotlib pdf backend) +/Creator (matplotlib 1.2.x, http://matplotlib.sf.net) >> endobj xref 0 13 0000000000 65535 f 0000000016 00000 n +0000000984 00000 n +0000000879 00000 n +0000000900 00000 n +0000000921 00000 n +0000000942 00000 n +0000000963 00000 n 0000000065 00000 n -0000000898 00000 n -0000000793 00000 n -0000000814 00000 n -0000000835 00000 n -0000000856 00000 n -0000000877 00000 n -0000000217 00000 n -0000000468 00000 n -0000000360 00000 n -0000000773 00000 n +0000000373 00000 n +0000000208 00000 n +0000000859 00000 n +0000001044 00000 n trailer -<< /Info 2 0 R /Root 1 0 R /Size 13 >> +<< /Info 12 0 R /Root 1 0 R /Size 13 >> startxref -958 +1195 %%EOF Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_simplification/clipping.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_simplification/clipping.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_simplification/clipping.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_simplification/clipping.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_simplification/clipping.svg 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_simplification/clipping.svg 2012-10-31 00:11:14.000000000 +0000 @@ -1,49 +1,252 @@ - + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_simplification/clipping_diamond.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_simplification/clipping_diamond.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_simplification/clipping_diamond.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_simplification/clipping_diamond.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_simplification/clipping_diamond.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_simplification/clipping_diamond.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_simplification/clipping_diamond.svg 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_simplification/clipping_diamond.svg 2012-10-31 00:11:14.000000000 +0000 @@ -1,48 +1,214 @@ - + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_simplification/fft_peaks.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_simplification/fft_peaks.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_simplification/fft_peaks.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_simplification/fft_peaks.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_simplification/fft_peaks.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_simplification/fft_peaks.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_simplification/fft_peaks.svg 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_simplification/fft_peaks.svg 2012-10-31 00:11:14.000000000 +0000 @@ -51,8 +51,222 @@ L489.926 388.8 L489.926 388.8" style="fill:none;stroke:#0000ff;"/> - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_simplification/para_equal_perp.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_simplification/para_equal_perp.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_simplification/para_equal_perp.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_simplification/para_equal_perp.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_simplification/para_equal_perp.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_simplification/para_equal_perp.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_simplification/para_equal_perp.svg 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_simplification/para_equal_perp.svg 2012-10-31 00:11:14.000000000 +0000 @@ -1,296 +1,416 @@ - + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_subplots/subplots_offset_text.svg 2012-11-06 15:42:20.000000000 +0000 @@ -0,0 +1,1786 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_text/text_contains.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_text/text_contains.png differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_transforms/pre_transform_data.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_transforms/pre_transform_data.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_transforms/pre_transform_data.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_transforms/pre_transform_data.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_transforms/pre_transform_data.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_transforms/pre_transform_data.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_transforms/pre_transform_data.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_transforms/pre_transform_data.svg 2012-11-06 15:42:20.000000000 +0000 @@ -0,0 +1,7726 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_triangulation/tripcolor1.pdf and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_triangulation/tripcolor1.pdf differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_triangulation/tripcolor1.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_triangulation/tripcolor1.png differ diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_triangulation/tripcolor1.svg matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_triangulation/tripcolor1.svg --- matplotlib-1.1.1/lib/matplotlib/tests/baseline_images/test_triangulation/tripcolor1.svg 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/baseline_images/test_triangulation/tripcolor1.svg 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,1229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_agg.py matplotlib-1.2.0/lib/matplotlib/tests/test_agg.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_agg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_agg.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,9 +1,11 @@ +from __future__ import print_function + import os def report_memory(i): pid = os.getpid() a2 = os.popen('ps -p %d -o rss,sz' % pid).readlines() - print i, ' ', a2[1], + print(i, ' ', a2[1], end=' ') return int(a2[1].split()[0]) # This test is disabled -- it uses old API. -ADS 2009-09-07 diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_arrow_patches.py matplotlib-1.2.0/lib/matplotlib/tests/test_arrow_patches.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_arrow_patches.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_arrow_patches.py 2012-11-06 15:42:20.000000000 +0000 @@ -0,0 +1,28 @@ +import matplotlib.pyplot as plt +from matplotlib.testing.decorators import image_comparison + +def draw_arrow(ax, t, r): + ax.annotate('', xy=(0.5, 0.5+r), xytext=(0.5, 0.5), size=30, + arrowprops=dict(arrowstyle=t, + fc="b", ec='k')) + +@image_comparison(baseline_images=['fancyarrow_test_image']) +def test_fancyarrow(): + r = [0.4, 0.3, 0.2, 0.1] + t = ["fancy", "simple"] + + fig, axes = plt.subplots(len(t), len(r), squeeze=False, + subplot_kw=dict(aspect=True), + figsize=(8, 4.5)) + + for i_r, r1 in enumerate(r): + for i_t, t1 in enumerate(t): + ax = axes[i_t, i_r] + draw_arrow(ax, t1, r1) + ax.tick_params(labelleft=False, labelbottom=False) + + +if __name__=='__main__': + import nose + nose.runmodule(argv=['-s','--with-doctest'], exit=False) + diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_artist.py matplotlib-1.2.0/lib/matplotlib/tests/test_artist.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_artist.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_artist.py 2012-11-06 16:32:23.000000000 +0000 @@ -0,0 +1,81 @@ +from __future__ import print_function + +from matplotlib.testing.decorators import cleanup + +import matplotlib.pyplot as plt + +import matplotlib.patches as mpatches +import matplotlib.transforms as mtrans +import matplotlib.collections as mcollections + + +@cleanup +def test_patch_transform_of_none(): + # tests the behaviour of patches added to an Axes with various transform + # specifications + + ax = plt.axes() + ax.set_xlim([1, 3]) + ax.set_ylim([1, 3]) + + #draw an ellipse over data coord (2,2) by specifying device coords + xy_data = (2, 2) + xy_pix = ax.transData.transform_point(xy_data) + + # not providing a transform of None puts the ellipse in data coordinates + e = mpatches.Ellipse(xy_data, width=1, height=1, fc='yellow', alpha=0.5) + ax.add_patch(e) + assert e._transform == ax.transData + + # providing a transform of None puts the ellipse in device coordinates + e = mpatches.Ellipse(xy_pix, width=120, height=120, fc='coral', + transform=None, alpha=0.5) + ax.add_patch(e) + assert isinstance(e._transform, mtrans.IdentityTransform) + + # providing an IdentityTransform puts the ellipse in device coordinates + e = mpatches.Ellipse(xy_pix, width=100, height=100, + transform=mtrans.IdentityTransform(), alpha=0.5) + ax.add_patch(e) + assert isinstance(e._transform, mtrans.IdentityTransform) + + +@cleanup +def test_collection_transform_of_none(): + # tests the behaviour of collections added to an Axes with various + # transform specifications + + ax = plt.axes() + ax.set_xlim([1, 3]) + ax.set_ylim([1, 3]) + + #draw an ellipse over data coord (2,2) by specifying device coords + xy_data = (2, 2) + xy_pix = ax.transData.transform_point(xy_data) + + # not providing a transform of None puts the ellipse in data coordinates + e = mpatches.Ellipse(xy_data, width=1, height=1) + c = mcollections.PatchCollection([e], facecolor='yellow', alpha=0.5) + ax.add_collection(c) + # the collection should be in data coordinates + assert c.get_offset_transform() + c.get_transform() == ax.transData + + # providing a transform of None puts the ellipse in device coordinates + e = mpatches.Ellipse(xy_pix, width=120, height=120) + c = mcollections.PatchCollection([e], facecolor='coral', + alpha=0.5) + c.set_transform(None) + ax.add_collection(c) + assert isinstance(c.get_transform(), mtrans.IdentityTransform) + + # providing an IdentityTransform puts the ellipse in device coordinates + e = mpatches.Ellipse(xy_pix, width=100, height=100) + c = mcollections.PatchCollection([e], transform=mtrans.IdentityTransform(), + alpha=0.5) + ax.add_collection(c) + assert isinstance(c._transOffset, mtrans.IdentityTransform) + + +if __name__=='__main__': + import nose + nose.runmodule(argv=['-s','--with-doctest'], exit=False) diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_axes.py matplotlib-1.2.0/lib/matplotlib/tests/test_axes.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_axes.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_axes.py 2012-11-06 18:15:48.000000000 +0000 @@ -1,7 +1,7 @@ import numpy as np from numpy import ma import matplotlib -from matplotlib.testing.decorators import image_comparison, knownfailureif +from matplotlib.testing.decorators import image_comparison, cleanup import matplotlib.pyplot as plt @@ -54,7 +54,48 @@ ax.set_xlabel( "x-label 005" ) ax.autoscale_view() -@image_comparison(baseline_images=['offset_points']) +@image_comparison(baseline_images=["formatter_large_small"]) +def test_formatter_large_small(): + # github issue #617, pull #619 + fig, ax = plt.subplots(1) + x = [0.500000001, 0.500000002] + y = [500000001, 500000002] + ax.plot(x, y) + +@image_comparison(baseline_images=["twin_axis_locaters_formatters"]) +def test_twin_axis_locaters_formatters(): + vals = np.linspace(0, 1, num=5, endpoint=True) + locs = np.sin(np.pi * vals / 2.0) + + majl = plt.FixedLocator(locs) + minl = plt.FixedLocator([0.1, 0.2, 0.3]) + + fig = plt.figure() + ax1 = fig.add_subplot(1, 1, 1) + ax1.plot([0.1, 100], [0, 1]) + ax1.yaxis.set_major_locator(majl) + ax1.yaxis.set_minor_locator(minl) + ax1.yaxis.set_major_formatter(plt.FormatStrFormatter('%08.2lf')) + ax1.yaxis.set_minor_formatter(plt.FixedFormatter(['tricks', 'mind', 'jedi'])) + + ax1.xaxis.set_major_locator(plt.LinearLocator()) + ax1.xaxis.set_minor_locator(plt.FixedLocator([15, 35, 55, 75])) + ax1.xaxis.set_major_formatter(plt.FormatStrFormatter('%05.2lf')) + ax1.xaxis.set_minor_formatter(plt.FixedFormatter(['c', '3', 'p', 'o'])) + ax2 = ax1.twiny() + ax3 = ax1.twinx() + +@image_comparison(baseline_images=["autoscale_tiny_range"], remove_text=True) +def test_autoscale_tiny_range(): + # github pull #904 + fig, ax = plt.subplots(2, 2) + ax = ax.flatten() + for i in xrange(4): + y1 = 10**(-11 - i) + ax[i].plot([0, 1], [1, 1 + y1]) + +@image_comparison(baseline_images=['offset_points'], + remove_text=True) def test_basic_annotate(): # Setup some data t = np.arange( 0.0, 5.0, 0.01 ) @@ -102,7 +143,8 @@ ) #-------------------------------------------------------------------- -@image_comparison(baseline_images=['polar_coords']) +@image_comparison(baseline_images=['polar_coords'], + remove_text=True) def test_polar_coord_annotations(): # You can also use polar notation on a catesian axes. Here the # native coordinate system ('data') is cartesian, so you need to @@ -247,6 +289,7 @@ plt.subplot( 313 ) plt.plot( np.ones( (10,) ), np.ones( (10,) ), 'o' ) + @image_comparison(baseline_images=['polar_wrap_180', 'polar_wrap_360', ]) @@ -255,21 +298,21 @@ fig = plt.figure() - #NOTE: resolution=1 really should be the default - plt.subplot( 111, polar=True, resolution=1 ) + plt.subplot(111, polar=True) + plt.polar( [179*D2R, -179*D2R], [0.2, 0.1], "b.-" ) plt.polar( [179*D2R, 181*D2R], [0.2, 0.1], "g.-" ) plt.rgrids( [0.05, 0.1, 0.15, 0.2, 0.25, 0.3] ) - + assert len(fig.axes) == 1, 'More than one polar axes created.' fig = plt.figure() - #NOTE: resolution=1 really should be the default - plt.subplot( 111, polar=True, resolution=1 ) + plt.subplot( 111, polar=True) plt.polar( [2*D2R, -2*D2R], [0.2, 0.1], "b.-" ) plt.polar( [2*D2R, 358*D2R], [0.2, 0.1], "g.-" ) plt.polar( [358*D2R, 2*D2R], [0.2, 0.1], "r.-" ) plt.rgrids( [0.05, 0.1, 0.15, 0.2, 0.25, 0.3] ) + @image_comparison(baseline_images=['polar_units', 'polar_units_2'], freetype_version=('2.4.5', '2.4.9')) def test_polar_units(): @@ -363,7 +406,8 @@ ax.set_ylim( t0 - 5.0*dt, tf + 5.0*dt ) -@image_comparison(baseline_images=['hexbin_extent']) +@image_comparison(baseline_images=['hexbin_extent'], + remove_text=True) def test_hexbin_extent(): # this test exposes sf bug 2856228 fig = plt.figure() @@ -388,13 +432,14 @@ ax = fig.add_subplot(111) ax.plot(x, y) -@image_comparison(baseline_images=['imshow']) +@image_comparison(baseline_images=['imshow'], + remove_text=True) def test_imshow(): #Create a NxN image N=100 (x,y) = np.indices((N,N)) - x -= N/2 - y -= N/2 + x -= N//2 + y -= N//2 r = np.sqrt(x**2+y**2-x*y) #Create a contour plot at N/4 and extract both the clip path and transform @@ -410,8 +455,8 @@ #Create a NxN image N=100 (x,y) = np.indices((N,N)) - x -= N/2 - y -= N/2 + x -= N//2 + y -= N//2 r = np.sqrt(x**2+y**2-x*y) #Create a contour plot at N/4 and extract both the clip path and transform @@ -429,7 +474,8 @@ #Plot the image clipped by the contour ax.imshow(r, clip_path=clip_path) -@image_comparison(baseline_images=['polycollection_joinstyle']) +@image_comparison(baseline_images=['polycollection_joinstyle'], + remove_text=True) def test_polycollection_joinstyle(): # Bug #2890979 reported by Matthew West @@ -442,10 +488,9 @@ ax.add_collection(c) ax.set_xbound(0, 3) ax.set_ybound(0, 3) - ax.set_xticks([]) - ax.set_yticks([]) -@image_comparison(baseline_images=['fill_between_interpolate'], tol=1e-2) +@image_comparison(baseline_images=['fill_between_interpolate'], + tol=1e-2, remove_text=True) def test_fill_between_interpolate(): x = np.arange(0.0, 2, 0.02) y1 = np.sin(2*np.pi*x) @@ -476,7 +521,8 @@ ax.set_xscale=('linear') ax.set_ylim(-1,10000000) -@image_comparison(baseline_images=['symlog2']) +@image_comparison(baseline_images=['symlog2'], + remove_text=True) def test_symlog2(): # Numbers from -50 to 50, with 0.1 as step x = np.arange(-50,50, 0.001) @@ -513,7 +559,8 @@ ax.grid(True) ax.set_ylim(-0.1, 0.1) -@image_comparison(baseline_images=['pcolormesh'], tol=0.02) +@image_comparison(baseline_images=['pcolormesh'], tol=0.02, + remove_text=True) def test_pcolormesh(): n = 12 x = np.linspace(-1.5,1.5,n) @@ -531,21 +578,12 @@ fig = plt.figure() ax = fig.add_subplot(131) ax.pcolormesh(Qx,Qz,Z, lw=0.5, edgecolors='k') - ax.set_title('lw=0.5') - ax.set_xticks([]) - ax.set_yticks([]) ax = fig.add_subplot(132) - ax.pcolormesh(Qx,Qz,Z, lw=3, edgecolors='k') - ax.set_title('lw=3') - ax.set_xticks([]) - ax.set_yticks([]) + ax.pcolormesh(Qx,Qz,Z, lw=2, edgecolors=['b', 'w']) ax = fig.add_subplot(133) ax.pcolormesh(Qx,Qz,Z, shading="gouraud") - ax.set_title('gouraud') - ax.set_xticks([]) - ax.set_yticks([]) @image_comparison(baseline_images=['canonical']) @@ -555,7 +593,7 @@ @image_comparison(baseline_images=['arc_ellipse'], - freetype_version=('2.4.5', '2.4.9')) + remove_text=True) def test_arc_ellipse(): from matplotlib import patches xcenter, ycenter = 0.38, 0.52 @@ -602,7 +640,8 @@ ax = fig.add_subplot(111) ax.plot(Id, pout) -@image_comparison(baseline_images=['markevery']) +@image_comparison(baseline_images=['markevery'], + remove_text=True) def test_markevery(): x = np.linspace(0, 10, 100) y = np.sin(x) * np.sqrt(x/10 + 0.5) @@ -617,7 +656,7 @@ ax.legend() @image_comparison(baseline_images=['markevery_line'], - freetype_version=('2.4.5', '2.4.9')) + remove_text=True) def test_markevery_line(): x = np.linspace(0, 10, 100) y = np.sin(x) * np.sqrt(x/10 + 0.5) @@ -631,15 +670,245 @@ ax.plot(x, y, '-+', markevery=(5, 20), label='mark every 5 starting at 10') ax.legend() -@image_comparison(baseline_images=['hist_log']) +@image_comparison(baseline_images=['marker_edges'], + remove_text=True) +def test_marker_edges(): + x = np.linspace(0, 1, 10) + fig = plt.figure() + ax = fig.add_subplot(111) + ax.plot(x, np.sin(x), 'y.', ms=30.0, mew=0, mec='r') + ax.plot(x+0.1, np.sin(x), 'y.', ms=30.0, mew=1, mec='r') + ax.plot(x+0.2, np.sin(x), 'y.', ms=30.0, mew=2, mec='b') + +@image_comparison(baseline_images=['hist_log'], + remove_text=True) def test_hist_log(): data0 = np.linspace(0,1,200)**3 data = np.r_[1-data0, 1+data0] fig = plt.figure() ax = fig.add_subplot(111) ax.hist(data, fill=False, log=True) - ax.set_xticks([]) - ax.set_yticks([]) + +def contour_dat(): + x = np.linspace(-3, 5, 150) + y = np.linspace(-3, 5, 120) + z = np.cos(x) + np.sin(y[:, np.newaxis]) + return x, y, z + +@image_comparison(baseline_images=['contour_hatching']) +def test_contour_hatching(): + x, y, z = contour_dat() + + fig = plt.figure() + ax = fig.add_subplot(111) + cs = ax.contourf(x, y, z, hatches=['-', '/', '\\', '//'], + cmap=plt.get_cmap('gray'), + extend='both', alpha=0.5) + +@image_comparison(baseline_images=['contour_colorbar']) +def test_contour_colorbar(): + x, y, z = contour_dat() + + fig = plt.figure() + ax = fig.add_subplot(111) + cs = ax.contourf(x, y, z, levels=np.arange(-1.8, 1.801, 0.2), + cmap=plt.get_cmap('RdBu'), + vmin=-0.6, + vmax=0.6, + extend='both') + cs1 = ax.contour(x, y, z, levels=np.arange(-2.2, -0.599, 0.2), + colors=['y'], + linestyles='solid', + linewidths=2) + cs2 = ax.contour(x, y, z, levels=np.arange(0.6, 2.2, 0.2), + colors=['c'], + linewidths=2) + cbar = fig.colorbar(cs, ax=ax) + cbar.add_lines(cs1) + cbar.add_lines(cs2, erase=False) + + +@image_comparison(baseline_images=['hist2d']) +def test_hist2d(): + np.random.seed(0) + #make it not symetric in case we switch x and y axis + x=np.random.randn(100)*2+5 + y = np.random.randn(100)-2 + fig = plt.figure() + ax = fig.add_subplot(111) + ax.hist2d(x,y,bins=10) + + +@image_comparison(baseline_images=['hist2d_transpose']) +def test_hist2d_transpose(): + np.random.seed(0) + #make sure the the output from np.histogram is transposed before + #passing to pcolorfast + x=np.array([5]*100) + y = np.random.randn(100)-2 + fig = plt.figure() + ax = fig.add_subplot(111) + ax.hist2d(x,y,bins=10) + + +@image_comparison(baseline_images=['scatter']) +def test_scatter_plot(): + ax = plt.axes() + ax.scatter([3, 4, 2, 6], [2, 5, 2, 3], c=['r', 'y', 'b', 'lime'], s=[24, 15, 19, 29]) + +@cleanup +def test_as_mpl_axes_api(): + # tests the _as_mpl_axes api + from matplotlib.projections.polar import PolarAxes + import matplotlib.axes as maxes + + class Polar(object): + def __init__(self): + self.theta_offset = 0 + + def _as_mpl_axes(self): + # implement the matplotlib axes interface + return PolarAxes, {'theta_offset': self.theta_offset} + prj = Polar() + prj2 = Polar() + prj2.theta_offset = np.pi + prj3 = Polar() + + # testing axes creation with plt.axes + ax = plt.axes([0, 0, 1, 1], projection=prj) + assert type(ax) == PolarAxes, \ + 'Expected a PolarAxes, got %s' % type(ax) + ax_via_gca = plt.gca(projection=prj) + assert ax_via_gca is ax + plt.close() + + # testing axes creation with gca + ax = plt.gca(projection=prj) + assert type(ax) == maxes._subplot_classes[PolarAxes], \ + 'Expected a PolarAxesSubplot, got %s' % type(ax) + ax_via_gca = plt.gca(projection=prj) + assert ax_via_gca is ax + # try getting the axes given a different polar projection + ax_via_gca = plt.gca(projection=prj2) + assert ax_via_gca is not ax + assert ax.get_theta_offset() == 0, ax.get_theta_offset() + assert ax_via_gca.get_theta_offset() == np.pi, ax_via_gca.get_theta_offset() + # try getting the axes given an == (not is) polar projection + ax_via_gca = plt.gca(projection=prj3) + assert ax_via_gca is ax + plt.close() + + # testing axes creation with subplot + ax = plt.subplot(121, projection=prj) + assert type(ax) == maxes._subplot_classes[PolarAxes], \ + 'Expected a PolarAxesSubplot, got %s' % type(ax) + plt.close() + +@image_comparison(baseline_images=['log_scales']) +def test_log_scales(): + fig = plt.figure() + ax = plt.gca() + plt.plot(np.log(np.linspace(0.1, 100))) + ax.set_yscale('log', basey=5.5) + ax.set_xscale('log', basex=9.0) + + +@image_comparison(baseline_images=['stackplot_test_image']) +def test_stackplot(): + fig = plt.figure() + x = np.linspace(0, 10, 10) + y1 = 1.0 * x + y2 = 2.0 * x + 1 + y3 = 3.0 * x + 2 + ax = fig.add_subplot(1, 1, 1) + ax.stackplot(x, y1, y2, y3) + ax.set_xlim((0, 10)) + ax.set_ylim((0, 70)) + +@image_comparison(baseline_images=['boxplot']) +def test_boxplot(): + x = np.linspace(-7, 7, 140) + x = np.hstack([-25, x, 25]) + fig = plt.figure() + ax = fig.add_subplot(111) + + # show 1 boxplot with mpl medians/conf. interfals, 1 with manual values + ax.boxplot([x, x], bootstrap=10000, usermedians=[None, 1.0], + conf_intervals=[None, (-1.0, 3.5)], notch=1) + ax.set_ylim((-30, 30)) + +@image_comparison(baseline_images=['errorbar_basic', + 'errorbar_mixed']) +def test_errorbar(): + x = np.arange(0.1, 4, 0.5) + y = np.exp(-x) + + yerr = 0.1 + 0.2*np.sqrt(x) + xerr = 0.1 + yerr + + # First illustrate basic pyplot interface, using defaults where possible. + fig = plt.figure() + ax = fig.gca() + ax.errorbar(x, y, xerr=0.2, yerr=0.4) + ax.set_title("Simplest errorbars, 0.2 in x, 0.4 in y") + + # Now switch to a more OO interface to exercise more features. + fig, axs = plt.subplots(nrows=2, ncols=2, sharex=True) + ax = axs[0,0] + ax.errorbar(x, y, yerr=yerr, fmt='o') + ax.set_title('Vert. symmetric') + + # With 4 subplots, reduce the number of axis ticks to avoid crowding. + ax.locator_params(nbins=4) + + ax = axs[0,1] + ax.errorbar(x, y, xerr=xerr, fmt='o') + ax.set_title('Hor. symmetric') + + ax = axs[1,0] + ax.errorbar(x, y, yerr=[yerr, 2*yerr], xerr=[xerr, 2*xerr], fmt='--o') + ax.set_title('H, V asymmetric') + + ax = axs[1,1] + ax.set_yscale('log') + # Here we have to be careful to keep all y values positive: + ylower = np.maximum(1e-2, y - yerr) + yerr_lower = y - ylower + + ax.errorbar(x, y, yerr=[yerr_lower, 2*yerr], xerr=xerr, + fmt='o', ecolor='g', capthick=2) + ax.set_title('Mixed sym., log y') + + fig.suptitle('Variable errorbars') + +@image_comparison(baseline_images=['hist_stacked']) +def test_hist_stacked(): + # make some data + d1 = np.linspace(0, 10, 50) + d2 = np.linspace(1, 3, 20) + fig = plt.figure() + ax = fig.add_subplot(111) + ax.hist( (d1, d2), histtype="stepfilled", stacked=True) + +@image_comparison(baseline_images=['hist_stacked_weights']) +def test_hist_stacked_weighted(): + # make some data + d1 = np.linspace(0, 10, 50) + d2 = np.linspace(1, 3, 20) + w1 = np.linspace(0.01, 3.5, 50) + w2 = np.linspace(0.05, 2., 20) + fig = plt.figure() + ax = fig.add_subplot(111) + ax.hist( (d1, d2), weights=(w1,w2), histtype="stepfilled", stacked=True) + +@image_comparison(baseline_images=['transparent_markers'], remove_text=True) +def test_transparent_markers(): + np.random.seed(0) + data = np.random.random(50) + + fig = plt.figure() + ax = fig.add_subplot(111) + ax.plot(data, 'D', mfc='none', markersize=100) if __name__=='__main__': import nose diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_backend_pgf.py matplotlib-1.2.0/lib/matplotlib/tests/test_backend_pgf.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_backend_pgf.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_backend_pgf.py 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,135 @@ +# -*- encoding: utf-8 -*- + +import os +import shutil +import subprocess +import numpy as np +import nose +from nose.plugins.skip import SkipTest +import matplotlib as mpl +import matplotlib.pyplot as plt +from matplotlib.testing.compare import compare_images, ImageComparisonFailure +from matplotlib.testing.decorators import _image_directories + +baseline_dir, result_dir = _image_directories(lambda: 'dummy func') + + +def check_for(texsystem): + header = r""" + \documentclass{minimal} + \usepackage{pgf} + \begin{document} + \typeout{pgfversion=\pgfversion} + \makeatletter + \@@end + """ + try: + latex = subprocess.Popen(["xelatex", "-halt-on-error"], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE) + stdout, stderr = latex.communicate(header.encode("utf8")) + except OSError: + return False + + return latex.returncode == 0 + + +def switch_backend(backend): + + def switch_backend_decorator(func): + def backend_switcher(*args, **kwargs): + try: + prev_backend = mpl.get_backend() + mpl.rcdefaults() + plt.switch_backend(backend) + result = func(*args, **kwargs) + finally: + plt.switch_backend(prev_backend) + return result + + return nose.tools.make_decorator(func)(backend_switcher) + return switch_backend_decorator + + +def compare_figure(fname): + actual = os.path.join(result_dir, fname) + plt.savefig(actual) + + expected = os.path.join(result_dir, "expected_%s" % fname) + shutil.copyfile(os.path.join(baseline_dir, fname), expected) + err = compare_images(expected, actual, tol=5e-3) + if err: + raise ImageComparisonFailure('images not close: %s vs. %s' % (actual, expected)) + +############################################################################### + +def create_figure(): + plt.figure() + x = np.linspace(0, 1, 15) + plt.plot(x, x**2, "b-") + plt.plot(x, 1-x**2, "g>") + plt.plot([0.9], [0.5], "ro", markersize=3) + plt.text(0.9, 0.5, u'unicode (ü, °, µ) and math ($\\mu_i = x_i^2$)', ha='right', fontsize=20) + plt.ylabel(u'sans-serif with math $\\frac{\\sqrt{x}}{y^2}$..', family='sans-serif') + + +# test compiling a figure to pdf with xelatex +@switch_backend('pgf') +def test_xelatex(): + if not check_for('xelatex'): + raise SkipTest('xelatex + pgf is required') + + rc_xelatex = {'font.family': 'serif', + 'pgf.rcfonts': False,} + mpl.rcParams.update(rc_xelatex) + create_figure() + compare_figure('pgf_xelatex.pdf') + + +# test compiling a figure to pdf with pdflatex +@switch_backend('pgf') +def test_pdflatex(): + if not check_for('pdflatex'): + raise SkipTest('pdflatex + pgf is required') + + rc_pdflatex = {'font.family': 'serif', + 'pgf.rcfonts': False, + 'pgf.texsystem': 'pdflatex', + 'pgf.preamble': [r'\usepackage[utf8x]{inputenc}', + r'\usepackage[T1]{fontenc}']} + mpl.rcParams.update(rc_pdflatex) + create_figure() + compare_figure('pgf_pdflatex.pdf') + + +# test updating the rc parameters for each figure +@switch_backend('pgf') +def test_rcupdate(): + if not check_for('xelatex') or not check_for('pdflatex'): + raise SkipTest('xelatex and pdflatex + pgf required') + + rc_sets = [] + rc_sets.append({'font.family': 'sans-serif', + 'font.size': 30, + 'figure.subplot.left': .2, + 'lines.markersize': 10, + 'pgf.rcfonts': False, + 'pgf.texsystem': 'xelatex'}) + rc_sets.append({'font.family': 'monospace', + 'font.size': 10, + 'figure.subplot.left': .1, + 'lines.markersize': 20, + 'pgf.rcfonts': False, + 'pgf.texsystem': 'pdflatex', + 'pgf.preamble': [r'\usepackage[utf8x]{inputenc}', + r'\usepackage[T1]{fontenc}', + r'\usepackage{sfmath}']}) + + for i, rc_set in enumerate(rc_sets): + mpl.rcParams.update(rc_set) + create_figure() + compare_figure('pgf_rcupdate%d.pdf' % (i+1)) + +if __name__ == '__main__': + import nose + nose.runmodule(argv=['-s','--with-doctest'], exit=False) diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_backend_svg.py matplotlib-1.2.0/lib/matplotlib/tests/test_backend_svg.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_backend_svg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_backend_svg.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,6 +1,8 @@ +from __future__ import print_function import matplotlib.pyplot as plt import numpy as np -import cStringIO as StringIO +import sys +from io import BytesIO import xml.parsers.expat from matplotlib.testing.decorators import knownfailureif, cleanup @@ -19,8 +21,8 @@ for artist in b: artist.set_visible(False) - fd = StringIO.StringIO() - fig.savefig(fd, format='svg') + fd = BytesIO() + fig.savefig(fd,format='svg') fd.seek(0) buf = fd.read() diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_basic.py matplotlib-1.2.0/lib/matplotlib/tests/test_basic.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_basic.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_basic.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function from nose.tools import assert_equal from matplotlib.testing.decorators import knownfailureif import sys @@ -20,12 +21,17 @@ 'sum' ]) + if sys.version_info[0] >= 3: + builtins = sys.modules['builtins'] + else: + builtins = sys.modules['__builtin__'] + overridden = False for key in globals().keys(): - if key in dir(sys.modules["__builtin__"]): - if (globals()[key] != getattr(sys.modules["__builtin__"], key) and + if key in dir(builtins): + if (globals()[key] != getattr(builtins, key) and key not in ok_to_override): - print "'%s' was overridden in globals()." % key + print("'%s' was overridden in globals()." % key) overridden = True assert not overridden diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_cbook.py matplotlib-1.2.0/lib/matplotlib/tests/test_cbook.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_cbook.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_cbook.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import numpy as np from numpy.testing.utils import assert_array_equal import matplotlib.cbook as cbook diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_colorbar.py matplotlib-1.2.0/lib/matplotlib/tests/test_colorbar.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_colorbar.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_colorbar.py 2012-11-08 13:38:03.000000000 +0000 @@ -0,0 +1,61 @@ +from matplotlib import rcParams, rcParamsDefault +from matplotlib.testing.decorators import image_comparison +import matplotlib.pyplot as plt +from matplotlib.colors import BoundaryNorm +from matplotlib.cm import get_cmap +from matplotlib.colorbar import ColorbarBase + + +def _colorbar_extensions(spacing): + + # Create a color map and specify the levels it represents. + cmap = get_cmap("RdBu", lut=5) + clevs = [-5., -2.5, -.5, .5, 1.5, 3.5] + + # Define norms for the color maps. + norms = dict() + norms['neither'] = BoundaryNorm(clevs, len(clevs)-1) + norms['min'] = BoundaryNorm([-10]+clevs[1:], len(clevs)-1) + norms['max'] = BoundaryNorm(clevs[:-1]+[10], len(clevs)-1) + norms['both'] = BoundaryNorm([-10]+clevs[1:-1]+[10], len(clevs)-1) + + # Create a figure and adjust whitespace for subplots. + fig = plt.figure() + fig.subplots_adjust(hspace=.6) + + for i, extension_type in enumerate(('neither', 'min', 'max', 'both')): + # Get the appropriate norm and use it to get colorbar boundaries. + norm = norms[extension_type] + boundaries = values = norm.boundaries + for j, extendfrac in enumerate((None, 'auto', 0.1)): + # Create a subplot. + cax = fig.add_subplot(12, 1, i*3+j+1) + # Turn off text and ticks. + for item in cax.get_xticklabels() + cax.get_yticklabels() +\ + cax.get_xticklines() + cax.get_yticklines(): + item.set_visible(False) + # Generate the colorbar. + cb = ColorbarBase(cax, cmap=cmap, norm=norm, + boundaries=boundaries, values=values, + extend=extension_type, extendfrac=extendfrac, + orientation='horizontal', spacing=spacing) + + # Return the figure to the caller. + return fig + + +@image_comparison( + baseline_images=['colorbar_extensions_uniform', 'colorbar_extensions_proportional'], + extensions=['png']) +def test_colorbar_extensions(): + # Use default params so .matplotlibrc doesn't cause the test to fail. + rcParams.update(rcParamsDefault) + # Create figures for uniform and proportionally spaced colorbars. + fig1 = _colorbar_extensions('uniform') + fig2 = _colorbar_extensions('proportional') + + +if __name__ == '__main__': + import nose + nose.runmodule(argv=['-s', '--with-doctest'], exit=False) + diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_colors.py matplotlib-1.2.0/lib/matplotlib/tests/test_colors.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_colors.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_colors.py 2012-11-06 15:42:20.000000000 +0000 @@ -0,0 +1,48 @@ +""" +Tests for the colors module. +""" + +from __future__ import print_function +import numpy as np +from numpy.testing.utils import assert_array_equal +import matplotlib.colors as mcolors +import matplotlib.cm as cm + +def test_colormap_endian(): + """ + Github issue #1005: a bug in putmask caused erroneous + mapping of 1.0 when input from a non-native-byteorder + array. + """ + cmap = cm.get_cmap("jet") + # Test under, over, and invalid along with values 0 and 1. + a = [-0.5, 0, 0.5, 1, 1.5, np.nan] + for dt in ["f2", "f4", "f8"]: + anative = np.ma.masked_invalid(np.array(a, dtype=dt)) + aforeign = anative.byteswap().newbyteorder() + #print(anative.dtype.isnative, aforeign.dtype.isnative) + assert_array_equal(cmap(anative), cmap(aforeign)) + +def test_BoundaryNorm(): + """ + Github issue #1258: interpolation was failing with numpy + 1.7 pre-release. + """ + # TODO: expand this into a more general test of BoundaryNorm. + boundaries = [0, 1.1, 2.2] + vals = [-1, 0, 2, 2.2, 4] + expected = [-1, 0, 2, 3, 3] + # ncolors != len(boundaries) - 1 triggers interpolation + ncolors = len(boundaries) + bn = mcolors.BoundaryNorm(boundaries, ncolors) + assert_array_equal(bn(vals), expected) + +def test_LogNorm(): + """ + LogNorm igornoed clip, now it has the same + behavior as Normalize, e.g. values > vmax are bigger than 1 + without clip, with clip they are 1. + """ + ln = mcolors.LogNorm(clip=True, vmax=5) + assert_array_equal(ln([1, 6]), [0, 1.0]) + diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_dates.py matplotlib-1.2.0/lib/matplotlib/tests/test_dates.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_dates.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_dates.py 2012-11-06 18:15:49.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import datetime import numpy as np from matplotlib.testing.decorators import image_comparison, knownfailureif, cleanup diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_delaunay.py matplotlib-1.2.0/lib/matplotlib/tests/test_delaunay.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_delaunay.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_delaunay.py 2012-10-31 00:11:14.000000000 +0000 @@ -168,7 +168,8 @@ # We only generate PNGs to save disk space -- we just assume # that any backend differences are caught by other tests. @image_comparison(filenames, extensions=['png'], - freetype_version=('2.4.5', '2.4.9')) + freetype_version=('2.4.5', '2.4.9'), + remove_text=True) def reference_test(): nnt.plot(func, interp=False, plotter='imshow') nnt.plot(func, interp=True, plotter='imshow') diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_figure.py matplotlib-1.2.0/lib/matplotlib/tests/test_figure.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_figure.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_figure.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,26 +1,26 @@ -import matplotlib -from nose.tools import assert_equal -from matplotlib.testing.decorators import image_comparison, knownfailureif, cleanup +from nose.tools import assert_equal, assert_true +from matplotlib.testing.decorators import image_comparison, cleanup import matplotlib.pyplot as plt @cleanup def test_figure_label(): - # pyplot figure creation, selection and closing with figure label and number + # pyplot figure creation, selection and closing with figure label and + # number plt.close('all') plt.figure('today') plt.figure(3) - plt.figure('tomorow') + plt.figure('tomorrow') plt.figure() plt.figure(0) plt.figure(1) plt.figure(3) assert_equal(plt.get_fignums(), [0, 1, 3, 4, 5]) - assert_equal(plt.get_figlabels(), ['', 'today', '', 'tomorow', '']) + assert_equal(plt.get_figlabels(), ['', 'today', '', 'tomorrow', '']) plt.close(10) plt.close() plt.close(5) - plt.close('tomorow') + plt.close('tomorrow') assert_equal(plt.get_fignums(), [0, 1]) assert_equal(plt.get_figlabels(), ['', 'today']) @@ -33,7 +33,38 @@ ax.set_title(fig.get_label()) ax.plot(range(5)) # plot red line in a different figure. - plt.figure('tomorow') - plt.plot([0, 1], [1,0], 'r') + plt.figure('tomorrow') + plt.plot([0, 1], [1, 0], 'r') # Return to the original; make sure the red line is not there. plt.figure('today') + plt.close('tomorrow') + + +@cleanup +def test_gca(): + fig = plt.figure() + + ax1 = fig.add_axes([0, 0, 1, 1]) + assert_true(fig.gca(projection='rectilinear') is ax1) + assert_true(fig.gca() is ax1) + + ax2 = fig.add_subplot(121, projection='polar') + assert_true(fig.gca() is ax2) + assert_true(fig.gca(polar=True)is ax2) + + ax3 = fig.add_subplot(122) + assert_true(fig.gca() is ax3) + + # the final request for a polar axes will end up creating one + # with a spec of 111. + assert_true(fig.gca(polar=True) is not ax3) + assert_true(fig.gca(polar=True) is not ax2) + assert_equal(fig.gca().get_geometry(), (1, 1, 1)) + + fig.sca(ax1) + assert_true(fig.gca(projection='rectilinear') is ax1) + assert_true(fig.gca() is ax1) + +if __name__ == "__main__": + import nose + nose.runmodule(argv=['-s', '--with-doctest'], exit=False) diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_image.py matplotlib-1.2.0/lib/matplotlib/tests/test_image.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_image.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_image.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import numpy as np from matplotlib.testing.decorators import image_comparison, knownfailureif, cleanup @@ -6,9 +7,15 @@ from nose.tools import assert_raises from numpy.testing import assert_array_equal -import cStringIO +import io import os +try: + from PIL import Image + HAS_PIL = True +except ImportError: + HAS_PIL = False + @image_comparison(baseline_images=['image_interps']) def test_image_interps(): 'make the basic nearest, bilinear and bicubic interps' @@ -29,7 +36,8 @@ ax3.imshow(X, interpolation='bicubic') ax3.set_ylabel('bicubic') -@image_comparison(baseline_images=['interp_nearest_vs_none'], extensions=['pdf', 'svg']) +@image_comparison(baseline_images=['interp_nearest_vs_none'], + extensions=['pdf', 'svg'], remove_text=True) def test_interp_nearest_vs_none(): 'Test the effect of "nearest" and "none" interpolation' # Setting dpi to something really small makes the difference very @@ -70,11 +78,18 @@ fig = plt.figure() ax = fig.add_subplot(111) ax.plot([1,2,3]) - buffer = cStringIO.StringIO() + buffer = io.BytesIO() fig.savefig(buffer) buffer.seek(0) plt.imread(buffer) +@knownfailureif(not HAS_PIL) +def test_imread_pil_uint16(): + img = plt.imread(os.path.join(os.path.dirname(__file__), + 'baseline_images', 'test_image', 'uint16.tif')) + assert (img.dtype == np.uint16) + assert np.sum(img) == 134184960 + # def test_image_unicode_io(): # fig = plt.figure() # ax = fig.add_subplot(111) @@ -96,10 +111,10 @@ random.seed(1) data = random.rand(256, 128) - buff_dpi1 = cStringIO.StringIO() + buff_dpi1 = io.BytesIO() plt.imsave(buff_dpi1, data, dpi=1) - buff_dpi100 = cStringIO.StringIO() + buff_dpi100 = io.BytesIO() plt.imsave(buff_dpi100, data, dpi=100) buff_dpi1.seek(0) @@ -113,6 +128,26 @@ assert_array_equal(arr_dpi1, arr_dpi100) +def test_imsave_color_alpha(): + # The goal is to test that imsave will accept arrays with ndim=3 where + # the third dimension is color and alpha without raising any exceptions + from numpy import random + random.seed(1) + data = random.rand(256, 128, 4) + + buff = io.BytesIO() + plt.imsave(buff, data) + + buff.seek(0) + arr_buf = plt.imread(buff) + + assert arr_buf.shape == data.shape + + # Unfortunately, the AGG process "flattens" the RGBA data + # into an equivalent RGB data with no transparency. So we + # Can't directly compare the arrays like we could in some + # other imsave tests. + @image_comparison(baseline_images=['image_clip']) def test_image_clip(): from math import pi @@ -124,7 +159,7 @@ im = ax.imshow(d, extent=(-pi,pi,-pi/2,pi/2)) -@image_comparison(baseline_images=['imshow'], tol=1.5e-3) +@image_comparison(baseline_images=['imshow'], tol=1.5e-3, remove_text=True) def test_imshow(): import numpy as np import matplotlib.pyplot as plt @@ -136,6 +171,30 @@ ax.set_xlim(0,3) ax.set_ylim(0,3) +@image_comparison(baseline_images=['no_interpolation_origin'], remove_text=True) +def test_no_interpolation_origin(): + fig = plt.figure() + ax = fig.add_subplot(211) + ax.imshow(np.arange(100).reshape((2, 50)), origin="lower", interpolation='none') + + ax = fig.add_subplot(212) + ax.imshow(np.arange(100).reshape((2, 50)), interpolation='none') + +@image_comparison(baseline_images=['image_shift'], remove_text=True, + extensions=['pdf', 'svg']) +def test_image_shift(): + from matplotlib.colors import LogNorm + + imgData = [[1.0/(x) + 1.0/(y) for x in range(1,100)] for y in range(1,100)] + tMin=734717.945208 + tMax=734717.946366 + + fig = plt.figure() + ax = fig.add_subplot(111) + ax.imshow(imgData, norm=LogNorm(), interpolation='none', + extent=(tMin, tMax, 1, 100)) + ax.set_aspect('auto') + if __name__=='__main__': import nose nose.runmodule(argv=['-s','--with-doctest'], exit=False) diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_legend.py matplotlib-1.2.0/lib/matplotlib/tests/test_legend.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_legend.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_legend.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,21 +1,21 @@ import numpy as np -from matplotlib.testing.decorators import image_comparison, knownfailureif +from matplotlib.testing.decorators import image_comparison import matplotlib.pyplot as plt -from nose.tools import assert_raises -from numpy.testing import assert_array_equal -@image_comparison(baseline_images=['legend_auto1'], tol=1.5e-3) + +@image_comparison(baseline_images=['legend_auto1'], tol=1.5e-3, remove_text=True) def test_legend_auto1(): 'Test automatic legend placement' fig = plt.figure() ax = fig.add_subplot(111) x = np.arange(100) - ax.plot(x, 50-x, 'o', label='y=1') - ax.plot(x, x-50, 'o', label='y=-1') + ax.plot(x, 50 - x, 'o', label='y=1') + ax.plot(x, x - 50, 'o', label='y=-1') ax.legend(loc=0) -@image_comparison(baseline_images=['legend_auto2']) + +@image_comparison(baseline_images=['legend_auto2'], remove_text=True) def test_legend_auto2(): 'Test automatic legend placement' fig = plt.figure() @@ -25,3 +25,24 @@ b2 = ax.bar(x, x[::-1], color='g') ax.legend([b1[0], b2[0]], ['up', 'down'], loc=0) + +@image_comparison(baseline_images=['legend_various_labels'], remove_text=True) +def test_various_labels(): + # tests all sorts of label types + fig = plt.figure() + ax = fig.add_subplot(121) + ax.plot(range(4), 'o', label=1) + ax.plot(np.linspace(4, 4.1), 'o', label=u'D\xe9velopp\xe9s') + ax.plot(range(4, 1, -1), 'o', label='__nolegend__') + ax.legend(numpoints=1) + + +@image_comparison(baseline_images=['fancy'], remove_text=True) +def test_fancy(): + # using subplot triggers some offsetbox functionality untested elsewhere + plt.subplot(121) + plt.scatter(range(10), range(10, 0, -1), label='XX\nXX') + plt.plot([5] * 10, 'o--', label='XX') + plt.errorbar(range(10), range(10), xerr=0.5, yerr=0.5, label='XX') + plt.legend(loc="center left", bbox_to_anchor=[1.0, 0.5], + ncol=2, shadow=True, title="My legend", numpoints=1) diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_mathtext.py matplotlib-1.2.0/lib/matplotlib/tests/test_mathtext.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_mathtext.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_mathtext.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,7 +1,9 @@ +from __future__ import print_function import numpy as np import matplotlib from matplotlib.testing.decorators import image_comparison, knownfailureif import matplotlib.pyplot as plt +from matplotlib import mathtext math_tests = [ r'$a+b+\dots+\dot{s}+\ldots$', @@ -46,7 +48,6 @@ r'$\widehat{abc}\widetilde{def}$', r'$\Gamma \Delta \Theta \Lambda \Xi \Pi \Sigma \Upsilon \Phi \Psi \Omega$', r'$\alpha \beta \gamma \delta \epsilon \zeta \eta \theta \iota \lambda \mu \nu \xi \pi \kappa \rho \sigma \tau \upsilon \phi \chi \psi$', - # r'$\operatorname{cos} x$', # The examples prefixed by 'mmltt' are from the MathML torture test here: # http://www.mozilla.org/projects/mathml/demo/texvsmml.xhtml @@ -59,7 +60,6 @@ r'${a}_{0}+\frac{1}{{a}_{1}+\frac{1}{{a}_{2}+\frac{1}{{a}_{3}+\frac{1}{{a}_{4}}}}}$', r'$\binom{n}{k/2}$', r'$\binom{p}{2}{x}^{2}{y}^{p-2}-\frac{1}{1-x}\frac{1}{1-{x}^{2}}$', - # 'mmltt10' : r'$\sum _{\genfrac{}{}{0}{}{0\leq i\leq m}{0 1. - mlab.rec2csv(bad,fd) + try: + bad = np.recarray((99,4),[('x',np.float),('y',np.float)]) + fd = tempfile.TemporaryFile(suffix='csv') + + # the bad recarray should trigger a ValueError for having ndim > 1. + mlab.rec2csv(bad,fd) + finally: + fd.close() def test_prctile(): # test odd lengths diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_patches.py matplotlib-1.2.0/lib/matplotlib/tests/test_patches.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_patches.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_patches.py 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,42 @@ +""" +Tests specific to the patches module. +""" + +from numpy.testing import assert_array_equal +from matplotlib.patches import Polygon + +def test_Polygon_close(): + """ + Github issue #1018 identified a bug in the Polygon handling + of the closed attribute; the path was not getting closed + when set_xy was used to set the vertices. + """ + # open set of vertices: + xy = [[0,0], [0,1], [1,1]] + # closed set: + xyclosed = xy + [[0,0]] + + # start with open path and close it: + p = Polygon(xy, closed=True) + assert_array_equal(p.get_xy(), xyclosed) + p.set_xy(xy) + assert_array_equal(p.get_xy(), xyclosed) + + # start with closed path and open it: + p = Polygon(xyclosed, closed=False) + assert_array_equal(p.get_xy(), xy) + p.set_xy(xyclosed) + assert_array_equal(p.get_xy(), xy) + + # start with open path and leave it open: + p = Polygon(xy, closed=False) + assert_array_equal(p.get_xy(), xy) + p.set_xy(xy) + assert_array_equal(p.get_xy(), xy) + + # start with closed path and leave it closed: + p = Polygon(xyclosed, closed=True) + assert_array_equal(p.get_xy(), xyclosed) + p.set_xy(xyclosed) + assert_array_equal(p.get_xy(), xyclosed) + diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_pickle.py matplotlib-1.2.0/lib/matplotlib/tests/test_pickle.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_pickle.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_pickle.py 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,199 @@ +from __future__ import print_function + +import numpy as np + +from matplotlib.testing.decorators import cleanup, image_comparison +import matplotlib.pyplot as plt + +from nose.tools import assert_equal, assert_not_equal + +# cpickle is faster, pickle gives better exceptions +import cPickle as pickle +#import pickle + +from io import BytesIO + + +def depth_getter(obj, + current_depth=0, + depth_stack=None, + nest_info='top level object'): + """ + Returns a dictionary mapping: + + id(obj): (shallowest_depth, obj, nest_info) + + for the given object (and its subordinates). + + This, in conjunction with recursive_pickle, can be used to debug + pickling issues, although finding others is sometimes a case of + trial and error. + + """ + if depth_stack is None: + depth_stack = {} + + if id(obj) in depth_stack: + stack = depth_stack[id(obj)] + if stack[0] > current_depth: + del depth_stack[id(obj)] + else: + return depth_stack + + depth_stack[id(obj)] = (current_depth, obj, nest_info) + + if isinstance(obj, (list, tuple)): + for i, item in enumerate(obj): + depth_getter(item, current_depth=current_depth+1, + depth_stack=depth_stack, + nest_info='list/tuple item #%s in (%s)' % (i, nest_info)) + else: + if isinstance(obj, dict): + state = obj + elif hasattr(obj, '__getstate__'): + state = obj.__getstate__() + if not isinstance(state, dict): + state = {} + elif hasattr(obj, '__dict__'): + state = obj.__dict__ + else: + state = {} + + for key, value in state.iteritems(): + depth_getter(value, current_depth=current_depth+1, + depth_stack=depth_stack, + nest_info='attribute "%s" in (%s)' % (key, nest_info)) + + # for instancemethod picklability (and some other issues), uncommenting + # the following may be helpful +# print([(name, dobj.__class__) for name, dobj in state.iteritems()], ': ', nest_info, ';', type(obj)) + + return depth_stack + + +def recursive_pickle(top_obj): + """ + Recursively pickle all of the given objects subordinates, starting with + the deepest first. **Very** handy for debugging pickling issues, but + also very slow (as it literally pickles each object in turn). + + Handles circular object references gracefully. + + """ + objs = depth_getter(top_obj) + # sort by depth then by nest_info + objs = sorted(objs.itervalues(), key=lambda val: (-val[0], val[2])) + + for _, obj, location in objs: +# print('trying %s' % location) + try: + pickle.dump(obj, BytesIO(), pickle.HIGHEST_PROTOCOL) + except Exception, err: + print(obj) + print('Failed to pickle %s. \n Type: %s. Traceback follows:' % (location, type(obj))) + raise + + +@cleanup +def test_simple(): + fig = plt.figure() + # un-comment to debug +# recursive_pickle(fig) + pickle.dump(fig, BytesIO(), pickle.HIGHEST_PROTOCOL) + + ax = plt.subplot(121) + pickle.dump(ax, BytesIO(), pickle.HIGHEST_PROTOCOL) + + ax = plt.axes(projection='polar') + plt.plot(range(10), label='foobar') + plt.legend() + +# recursive_pickle(fig) + pickle.dump(ax, BytesIO(), pickle.HIGHEST_PROTOCOL) + +# ax = plt.subplot(121, projection='hammer') +# recursive_pickle(ax, 'figure') +# pickle.dump(ax, BytesIO(), pickle.HIGHEST_PROTOCOL) + + +@image_comparison(baseline_images=['multi_pickle'], + extensions=['png'], remove_text=True) +def test_complete(): + fig = plt.figure('Figure with a label?', figsize=(10, 6)) + + plt.suptitle('Can you fit any more in a figure?') + + # make some arbitrary data + x, y = np.arange(8), np.arange(10) + data = u = v = np.linspace(0, 10, 80).reshape(10, 8) + v = np.sin(v * -0.6) + + plt.subplot(3,3,1) + plt.plot(range(10)) + + plt.subplot(3, 3, 2) + plt.contourf(data, hatches=['//', 'ooo']) + plt.colorbar() + + plt.subplot(3, 3, 3) + plt.pcolormesh(data) + + + plt.subplot(3, 3, 4) + plt.imshow(data) + + plt.subplot(3, 3, 5) + plt.pcolor(data) + + plt.subplot(3, 3, 6) + plt.streamplot(x, y, u, v) + + plt.subplot(3, 3, 7) + plt.quiver(x, y, u, v) + + plt.subplot(3, 3, 8) + plt.scatter(x, x**2, label='$x^2$') + plt.legend(loc='upper left') + + plt.subplot(3, 3, 9) + plt.errorbar(x, x * -0.5, xerr=0.2, yerr=0.4) + + ###### plotting is done, now test its pickle-ability ######### + + # Uncomment to debug any unpicklable objects. This is slow (~200 seconds). +# recursive_pickle(fig) + + result_fh = BytesIO() + pickle.dump(fig, result_fh, pickle.HIGHEST_PROTOCOL) + + plt.close('all') + + # make doubly sure that there are no figures left + assert_equal(plt._pylab_helpers.Gcf.figs, {}) + + # wind back the fh and load in the figure + result_fh.seek(0) + fig = pickle.load(result_fh) + + # make sure there is now a figure manager + assert_not_equal(plt._pylab_helpers.Gcf.figs, {}) + + assert_equal(fig.get_label(), 'Figure with a label?') + + +def test_no_pyplot(): + # tests pickle-ability of a figure not created with pyplot + + import pickle as p + from matplotlib.backends.backend_pdf import FigureCanvasPdf as fc + from matplotlib.figure import Figure + + fig = Figure() + can = fc(fig) + ax = fig.add_subplot(1, 1, 1) + ax.plot([1, 2, 3], [1, 2, 3]) + + # Uncomment to debug any unpicklable objects. This is slow so is not + # uncommented by default. +# recursive_pickle(fig) + pickle.dump(fig, BytesIO(), pickle.HIGHEST_PROTOCOL) diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_png.py matplotlib-1.2.0/lib/matplotlib/tests/test_png.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_png.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_png.py 2012-10-31 00:11:14.000000000 +0000 @@ -3,6 +3,7 @@ import matplotlib.cm as cm import glob import os +import numpy as np @image_comparison(baseline_images=['pngsuite'], extensions=['png']) def test_pngsuite(): @@ -25,3 +26,12 @@ plt.gca().get_frame().set_facecolor("#ddffff") plt.gca().set_xlim(0, len(files)) + + +def test_imread_png_uint16(): + from matplotlib import _png + img = _png.read_png_int(os.path.join(os.path.dirname(__file__), + 'baseline_images/test_png/uint16.png')) + + assert (img.dtype == np.uint16) + assert np.sum(img.flatten()) == 134184960 diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_rcparams.py matplotlib-1.2.0/lib/matplotlib/tests/test_rcparams.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_rcparams.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_rcparams.py 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,38 @@ +import os + +import matplotlib as mpl +mpl.rc('text', usetex=False) +mpl.rc('lines', linewidth=22) + +fname = os.path.join(os.path.dirname(__file__), 'test_rcparams.rc') + +def test_rcparams(): + + usetex = mpl.rcParams['text.usetex'] + linewidth = mpl.rcParams['lines.linewidth'] + + # test context given dictionary + with mpl.rc_context(rc={'text.usetex': not usetex}): + assert mpl.rcParams['text.usetex'] == (not usetex) + assert mpl.rcParams['text.usetex'] == usetex + + # test context given filename (mpl.rc sets linewdith to 33) + with mpl.rc_context(fname=fname): + assert mpl.rcParams['lines.linewidth'] == 33 + assert mpl.rcParams['lines.linewidth'] == linewidth + + # test context given filename and dictionary + with mpl.rc_context(fname=fname, rc={'lines.linewidth': 44}): + assert mpl.rcParams['lines.linewidth'] == 44 + assert mpl.rcParams['lines.linewidth'] == linewidth + + # test rc_file + try: + mpl.rc_file(fname) + assert mpl.rcParams['lines.linewidth'] == 33 + finally: + mpl.rcParams['lines.linewidth'] = linewidth + + +if __name__ == '__main__': + test_rcparams() diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_rcparams.rc matplotlib-1.2.0/lib/matplotlib/tests/test_rcparams.rc --- matplotlib-1.1.1/lib/matplotlib/tests/test_rcparams.rc 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_rcparams.rc 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,3 @@ +# this file is used by the tests in test_rcparams.py + +lines.linewidth: 33 diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_scale.py matplotlib-1.2.0/lib/matplotlib/tests/test_scale.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_scale.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_scale.py 2012-10-31 00:11:14.000000000 +0000 @@ -0,0 +1,12 @@ +from __future__ import print_function + +from matplotlib.testing.decorators import image_comparison +import matplotlib.pyplot as plt + + +@image_comparison(baseline_images=['log_scales'], remove_text=True) +def test_log_scales(): + ax = plt.subplot(122, yscale='log', xscale='symlog') + + ax.axvline(24.1) + ax.axhline(24.1) \ No newline at end of file diff -Nru matplotlib-1.1.1/lib/matplotlib/tests/test_simplification.py matplotlib-1.2.0/lib/matplotlib/tests/test_simplification.py --- matplotlib-1.1.1/lib/matplotlib/tests/test_simplification.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tests/test_simplification.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,3 +1,5 @@ +from __future__ import print_function + import numpy as np import matplotlib from matplotlib.testing.decorators import image_comparison, knownfailureif, cleanup @@ -8,7 +10,7 @@ from matplotlib import patches, path, transforms from nose.tools import raises -import cStringIO +import io nan = np.nan Path = path.Path @@ -16,7 +18,7 @@ # NOTE: All of these tests assume that path.simplify is set to True # (the default) -@image_comparison(baseline_images=['clipping']) +@image_comparison(baseline_images=['clipping'], remove_text=True) def test_clipping(): t = np.arange(0.0, 2.0, 0.01) s = np.sin(2*pi*t) @@ -25,10 +27,8 @@ ax = fig.add_subplot(111) ax.plot(t, s, linewidth=1.0) ax.set_ylim((-0.20, -0.28)) - ax.set_xticks([]) - ax.set_yticks([]) -@image_comparison(baseline_images=['overflow'], tol=1e-2) +@image_comparison(baseline_images=['overflow'], tol=1e-2, remove_text=True) def test_overflow(): x = np.array([1.0,2.0,3.0,2.0e5]) y = np.arange(len(x)) @@ -37,10 +37,8 @@ ax = fig.add_subplot(111) ax.plot(x,y) ax.set_xlim(xmin=2,xmax=6) - ax.set_xticks([]) - ax.set_yticks([]) -@image_comparison(baseline_images=['clipping_diamond']) +@image_comparison(baseline_images=['clipping_diamond'], remove_text=True) def test_diamond(): x = np.array([0.0, 1.0, 0.0, -1.0, 0.0]) y = np.array([1.0, 0.0, -1.0, 0.0, 1.0]) @@ -50,8 +48,6 @@ ax.plot(x, y) ax.set_xlim(xmin=-0.6, xmax=0.6) ax.set_ylim(ymin=-0.6, ymax=0.6) - ax.set_xticks([]) - ax.set_yticks([]) @cleanup def test_noise(): @@ -61,16 +57,12 @@ fig = plt.figure() ax = fig.add_subplot(111) p1 = ax.plot(x, solid_joinstyle='round', linewidth=2.0) - ax.set_xticks([]) - ax.set_yticks([]) path = p1[0].get_path() transform = p1[0].get_transform() path = transform.transform_path(path) simplified = list(path.iter_segments(simplify=(800, 600))) - print len(simplified) - assert len(simplified) == 3884 @cleanup @@ -81,19 +73,15 @@ fig = plt.figure() ax = fig.add_subplot(111) p1 = ax.plot(x, solid_joinstyle='round', linewidth=2.0) - ax.set_xticks([]) - ax.set_yticks([]) path = p1[0].get_path() transform = p1[0].get_transform() path = transform.transform_path(path) simplified = list(path.iter_segments(simplify=(800, 600))) - print len(simplified) - assert len(simplified) == 876 -@image_comparison(baseline_images=['simplify_curve']) +@image_comparison(baseline_images=['simplify_curve'], remove_text=True) def test_simplify_curve(): pp1 = patches.PathPatch( Path([(0, 0), (1, 0), (1, 1), (nan, 1), (0, 0), (2, 0), (2, 2), (0, 0)], @@ -103,12 +91,10 @@ fig = plt.figure() ax = fig.add_subplot(111) ax.add_patch(pp1) - ax.set_xticks([]) - ax.set_yticks([]) ax.set_xlim((0, 2)) ax.set_ylim((0, 2)) -@image_comparison(baseline_images=['hatch_simplify']) +@image_comparison(baseline_images=['hatch_simplify'], remove_text=True) def test_hatch(): fig = plt.figure() ax = fig.add_subplot(111) @@ -116,28 +102,24 @@ ax.set_xlim((0.45, 0.55)) ax.set_ylim((0.45, 0.55)) -@image_comparison(baseline_images=['fft_peaks']) +@image_comparison(baseline_images=['fft_peaks'], remove_text=True) def test_fft_peaks(): fig = plt.figure() t = arange(65536) ax = fig.add_subplot(111) p1 = ax.plot(abs(fft(sin(2*pi*.01*t)*blackman(len(t))))) - ax.set_xticks([]) - ax.set_yticks([]) path = p1[0].get_path() transform = p1[0].get_transform() path = transform.transform_path(path) simplified = list(path.iter_segments(simplify=(800, 600))) - print len(simplified) - assert len(simplified) == 20 @cleanup def test_start_with_moveto(): # Should be entirely clipped away to a single MOVETO - data = """ + data = b""" ZwAAAAku+v9UAQAA+Tj6/z8CAADpQ/r/KAMAANlO+v8QBAAAyVn6//UEAAC6ZPr/2gUAAKpv+v+8 BgAAm3r6/50HAACLhfr/ewgAAHyQ+v9ZCQAAbZv6/zQKAABepvr/DgsAAE+x+v/lCwAAQLz6/7wM AAAxx/r/kA0AACPS+v9jDgAAFN36/zQPAAAF6Pr/AxAAAPfy+v/QEAAA6f36/5wRAADbCPv/ZhIA @@ -159,7 +141,15 @@ AABHqP//ej8AAD6z//+FPwAANb7//48/AAAsyf//lz8AACPU//+ePwAAGt///6M/AAAR6v//pj8A AAj1//+nPwAA/////w==""" - verts = np.fromstring(data.decode('base64'), dtype='> sys.stderr, """\ + print("""\ WARNING: found a TeX cache dir in the deprecated location "%s". - Moving it to the new default location "%s"."""%(oldcache, texcache) + Moving it to the new default location "%s"."""%(oldcache, texcache), file=sys.stderr) shutil.move(oldcache, texcache) - if not os.path.exists(texcache): - os.mkdir(texcache) + mkdirs(texcache) _dvipng_hack_alpha = None #_dvipng_hack_alpha = dvipng_hack_alpha() @@ -130,8 +133,7 @@ def __init__(self): - if not os.path.isdir(self.texcache): - os.mkdir(self.texcache) + mkdirs(self.texcache) ff = rcParams['font.family'].lower() if ff in self.font_families: self.font_family = ff @@ -148,11 +150,11 @@ setattr(self, font_family_attr, self.font_info[font.lower()]) if DEBUG: - print 'family: %s, font: %s, info: %s'%(font_family, - font, self.font_info[font.lower()]) + print('family: %s, font: %s, info: %s'%(font_family, + font, self.font_info[font.lower()])) break else: - if DEBUG: print '$s font is not compatible with usetex' + if DEBUG: print('$s font is not compatible with usetex') else: mpl.verbose.report('No LaTeX-compatible font found for the %s font family in rcParams. Using default.' % ff, 'helpful') setattr(self, font_family_attr, self.font_info[font_family]) @@ -186,16 +188,16 @@ changed = [par for par in self._rc_cache_keys if rcParams[par] != \ self._rc_cache[par]] if changed: - if DEBUG: print 'DEBUG following keys changed:', changed + if DEBUG: print('DEBUG following keys changed:', changed) for k in changed: if DEBUG: - print 'DEBUG %-20s: %-10s -> %-10s' % \ - (k, self._rc_cache[k], rcParams[k]) + print('DEBUG %-20s: %-10s -> %-10s' % \ + (k, self._rc_cache[k], rcParams[k])) # deepcopy may not be necessary, but feels more future-proof self._rc_cache[k] = copy.deepcopy(rcParams[k]) - if DEBUG: print 'DEBUG RE-INIT\nold fontconfig:', self._fontconfig + if DEBUG: print('DEBUG RE-INIT\nold fontconfig:', self._fontconfig) self.__init__() - if DEBUG: print 'DEBUG fontconfig:', self._fontconfig + if DEBUG: print('DEBUG fontconfig:', self._fontconfig) return self._fontconfig def get_font_preamble(self): @@ -228,7 +230,6 @@ """ basefile = self.get_basefile(tex, fontsize) texfile = '%s.tex'%basefile - fh = file(texfile, 'w') custom_preamble = self.get_custom_preamble() fontcmd = {'sans-serif' : r'{\sffamily %s}', 'monospace' : r'{\ttfamily %s}'}.get(self.font_family, @@ -236,7 +237,7 @@ tex = fontcmd % tex if rcParams['text.latex.unicode']: - unicode_preamble = """\usepackage{ucs} + unicode_preamble = r"""\usepackage{ucs} \usepackage[utf8x]{inputenc}""" else: unicode_preamble = '' @@ -252,18 +253,17 @@ \end{document} """ % (self._font_preamble, unicode_preamble, custom_preamble, fontsize, fontsize*1.25, tex) - if rcParams['text.latex.unicode']: - fh.write(s.encode('utf8')) - else: - try: - fh.write(s) - except UnicodeEncodeError, err: - mpl.verbose.report("You are using unicode and latex, but have " - "not enabled the matplotlib 'text.latex.unicode' " - "rcParam.", 'helpful') - raise - - fh.close() + with open(texfile, 'wb') as fh: + if rcParams['text.latex.unicode']: + fh.write(s.encode('utf8')) + else: + try: + fh.write(s.encode('ascii')) + except UnicodeEncodeError as err: + mpl.verbose.report("You are using unicode and latex, but have " + "not enabled the matplotlib 'text.latex.unicode' " + "rcParam.", 'helpful') + raise return texfile @@ -280,7 +280,6 @@ """ basefile = self.get_basefile(tex, fontsize) texfile = '%s.tex'%basefile - fh = file(texfile, 'w') custom_preamble = self.get_custom_preamble() fontcmd = {'sans-serif' : r'{\sffamily %s}', 'monospace' : r'{\ttfamily %s}'}.get(self.font_family, @@ -288,7 +287,7 @@ tex = fontcmd % tex if rcParams['text.latex.unicode']: - unicode_preamble = """\usepackage{ucs} + unicode_preamble = r"""\usepackage{ucs} \usepackage[utf8x]{inputenc}""" else: unicode_preamble = '' @@ -317,18 +316,17 @@ \end{document} """ % (self._font_preamble, unicode_preamble, custom_preamble, fontsize, fontsize*1.25, tex) - if rcParams['text.latex.unicode']: - fh.write(s.encode('utf8')) - else: - try: - fh.write(s) - except UnicodeEncodeError, err: - mpl.verbose.report("You are using unicode and latex, but have " - "not enabled the matplotlib 'text.latex.unicode' " - "rcParam.", 'helpful') - raise - - fh.close() + with open(texfile, 'wb') as fh: + if rcParams['text.latex.unicode']: + fh.write(s.encode('utf8')) + else: + try: + fh.write(s.encode('ascii')) + except UnicodeEncodeError as err: + mpl.verbose.report("You are using unicode and latex, but have " + "not enabled the matplotlib 'text.latex.unicode' " + "rcParam.", 'helpful') + raise return texfile @@ -356,9 +354,8 @@ mpl.verbose.report(command, 'debug') exit_status = os.system(command) try: - fh = file(outfile) - report = fh.read() - fh.close() + with open(outfile) as fh: + report = fh.read() except IOError: report = 'No latex error report available.' try: @@ -402,9 +399,8 @@ mpl.verbose.report(command, 'debug') exit_status = os.system(command) try: - fh = file(outfile) - report = fh.read() - fh.close() + with open(outfile) as fh: + report = fh.read() except IOError: report = 'No latex error report available.' @@ -416,7 +412,8 @@ # find the box extent information in the latex output # file and store them in ".baseline" file m = TexManager._re_vbox.search(report) - open(basefile+'.baseline',"w").write(" ".join(m.groups())) + with open(basefile+'.baseline',"w") as fh: + fh.write(" ".join(m.groups())) for fname in glob.glob(basefile+'*'): if fname.endswith('dvi'): pass @@ -448,9 +445,8 @@ mpl.verbose.report(command, 'debug') exit_status = os.system(command) try: - fh = file(outfile) - report = fh.read() - fh.close() + with open(outfile) as fh: + report = fh.read() except IOError: report = 'No dvipng error report available.' if exit_status: @@ -481,13 +477,13 @@ os.path.split(dvifile)[-1], outfile)) mpl.verbose.report(command, 'debug') exit_status = os.system(command) - fh = file(outfile) - if exit_status: - raise RuntimeError('dvipng was not able to \ -process the flowing file:\n%s\nHere is the full report generated by dvipng: \ -\n\n'% dvifile + fh.read()) - else: mpl.verbose.report(fh.read(), 'debug') - fh.close() + with open(outfile) as fh: + if exit_status: + raise RuntimeError('dvipng was not able to \ + process the flowing file:\n%s\nHere is the full report generated by dvipng: \ + \n\n'% dvifile + fh.read()) + else: + mpl.verbose.report(fh.read(), 'debug') os.remove(outfile) return psfile @@ -498,10 +494,10 @@ rendering of the tex string """ psfile = self.make_ps(tex, fontsize) - ps = file(psfile) - for line in ps: - if line.startswith('%%BoundingBox:'): - return [int(val) for val in line.split()[1:]] + with open(psfile) as ps: + for line in ps: + if line.startswith('%%BoundingBox:'): + return [int(val) for val in line.split()[1:]] raise RuntimeError('Could not parse %s'%psfile) def get_grey(self, tex, fontsize=None, dpi=None): @@ -597,7 +593,8 @@ if DEBUG or not os.path.exists(baselinefile): dvifile = self.make_dvi_preview(tex, fontsize) - l = open(baselinefile).read().split() + with open(baselinefile) as fh: + l = fh.read().split() height, depth, width = [float(l1)*dpi_fraction for l1 in l] return width, height+depth, depth @@ -605,7 +602,9 @@ # use dviread. It sometimes returns a wrong descent. dvifile = self.make_dvi(tex, fontsize) dvi = dviread.Dvi(dvifile, 72*dpi_fraction) - page = iter(dvi).next() - dvi.close() + try: + page = next(iter(dvi)) + finally: + dvi.close() # A total height (including the descent) needs to be returned. return page.width, page.height+page.descent, page.descent diff -Nru matplotlib-1.1.1/lib/matplotlib/text.py matplotlib-1.2.0/lib/matplotlib/text.py --- matplotlib-1.1.1/lib/matplotlib/text.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/text.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,7 +1,7 @@ """ Classes for including text in a figure. """ -from __future__ import division +from __future__ import division, print_function import math import numpy as np @@ -22,8 +22,6 @@ from matplotlib.artist import allow_rasterization -import matplotlib.nxutils as nxutils - from matplotlib.path import Path import matplotlib.font_manager as font_manager from matplotlib.ft2font import FT2Font @@ -209,14 +207,20 @@ return False,{} l,b,w,h = self.get_window_extent().bounds - - r = l+w - t = b+h - xyverts = (l,b), (l, t), (r, t), (r, b) + r, t = l+w, b+h + x, y = mouseevent.x, mouseevent.y - inside = nxutils.pnpoly(x, y, xyverts) + inside = (l <= x <= r and b <= y <= t) + cattr = {} + + # if the text has a surrounding patch, also check containment for it, + # and merge the results with the results for the text. + if self._bbox_patch: + patch_inside, patch_cattr = self._bbox_patch.contains(mouseevent) + inside = inside or patch_inside + cattr["bbox_patch"] = patch_cattr - return inside,{} + return inside, cattr def _get_xy_display(self): 'get the (possibly unit converted) transformed x, y in display coords' @@ -365,7 +369,8 @@ width = xmax - xmin height = ymax - ymin - # Now move the box to the targe position offset the display bbox by alignment + # Now move the box to the target position offset the display + # bbox by alignment halign = self._horizontalalignment valign = self._verticalalignment @@ -1007,7 +1012,7 @@ self.set_fontproperties(fp) docstring.interpd.update(Text = artist.kwdoc(Text)) -docstring.dedent_interpd(Text.__init__.im_func) +docstring.dedent_interpd(Text.__init__) class TextWithDash(Text): @@ -1801,7 +1806,7 @@ self.arrow = None - if arrowprops and arrowprops.has_key("arrowstyle"): + if arrowprops and "arrowstyle" in arrowprops: arrowprops = self.arrowprops.copy() self._arrow_relpos = arrowprops.pop("relpos", (0.5, 0.5)) self.arrow_patch = FancyArrowPatch((0, 0), (1,1), @@ -1809,17 +1814,14 @@ else: self.arrow_patch = None - def contains(self,event): - t,tinfo = Text.contains(self,event) + contains, tinfo = Text.contains(self,event) if self.arrow is not None: - a,ainfo=self.arrow.contains(event) - t = t or a - + in_arrow, _ = self.arrow.contains(event) + contains = contains or in_arrow # self.arrow_patch is currently not checked as this can be a line - JJ - return t,tinfo - + return contains, tinfo def set_figure(self, fig): @@ -1920,11 +1922,11 @@ # pick the x,y corner of the text bbox closest to point # annotated - dsu = [(abs(val-x0), val) for val in l, r, xc] + dsu = [(abs(val-x0), val) for val in (l, r, xc)] dsu.sort() _, x = dsu[0] - dsu = [(abs(val-y0), val) for val in b, t, yc] + dsu = [(abs(val-y0), val) for val in (b, t, yc)] dsu.sort() _, y = dsu[0] diff -Nru matplotlib-1.1.1/lib/matplotlib/textpath.py matplotlib-1.2.0/lib/matplotlib/textpath.py --- matplotlib-1.1.1/lib/matplotlib/textpath.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/textpath.py 2012-11-08 13:38:03.000000000 +0000 @@ -1,5 +1,7 @@ # -*- coding: utf-8 -*- +from __future__ import print_function + import urllib from matplotlib.path import Path import matplotlib.font_manager as font_manager @@ -297,8 +299,10 @@ else: dvifile = texmanager.make_dvi(s, self.FONT_SCALE) dvi = dviread.Dvi(dvifile, self.DPI) - page = iter(dvi).next() - dvi.close() + try: + page = next(iter(dvi)) + finally: + dvi.close() if glyph_map is None: @@ -355,7 +359,7 @@ if enc: charcode = enc.get(glyph, None) else: charcode = glyph - if charcode: + if charcode is not None: glyph0 = font.load_char(charcode, flags=ft2font_flag) else: warnings.warn("The glyph (%d) of font (%s) cannot be converted with the encoding. Glyph may be wrong" % (glyph, font_bunch.filename)) diff -Nru matplotlib-1.1.1/lib/matplotlib/ticker.py matplotlib-1.2.0/lib/matplotlib/ticker.py --- matplotlib-1.1.1/lib/matplotlib/ticker.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/ticker.py 2012-11-06 22:31:09.000000000 +0000 @@ -2,22 +2,21 @@ Tick locating and formatting ============================ -This module contains classes to support completely configurable tick -locating and formatting. Although the locators know nothing about -major or minor ticks, they are used by the Axis class to support major -and minor tick locating and formatting. Generic tick locators and -formatters are provided, as well as domain specific custom ones.. +This module contains classes to support completely configurable tick locating +and formatting. Although the locators know nothing about major or minor +ticks, they are used by the Axis class to support major and minor tick +locating and formatting. Generic tick locators and formatters are provided, +as well as domain specific custom ones.. Tick locating ------------- -The Locator class is the base class for all tick locators. The -locators handle autoscaling of the view limits based on the data -limits, and the choosing of tick locations. A useful semi-automatic -tick locator is MultipleLocator. You initialize this with a base, eg -10, and it picks axis limits and ticks that are multiples of your -base. +The Locator class is the base class for all tick locators. The locators +handle autoscaling of the view limits based on the data limits, and the +choosing of tick locations. A useful semi-automatic tick locator is +MultipleLocator. You initialize this with a base, eg 10, and it picks axis +limits and ticks that are multiples of your base. The Locator subclasses defined here are @@ -123,8 +122,7 @@ more information and examples of using date locators and formatters. """ - -from __future__ import division +from __future__ import division, print_function import decimal import locale import math @@ -134,33 +132,37 @@ from matplotlib import transforms as mtransforms +class _DummyAxis(object): + def __init__(self, minpos=0): + self.dataLim = mtransforms.Bbox.unit() + self.viewLim = mtransforms.Bbox.unit() + self._minpos = minpos -class TickHelper: - axis = None - class DummyAxis: - def __init__(self): - self.dataLim = mtransforms.Bbox.unit() - self.viewLim = mtransforms.Bbox.unit() - - def get_view_interval(self): - return self.viewLim.intervalx + def get_view_interval(self): + return self.viewLim.intervalx + + def set_view_interval(self, vmin, vmax): + self.viewLim.intervalx = vmin, vmax + + def get_minpos(self): + return self._minpos - def set_view_interval(self, vmin, vmax): - self.viewLim.intervalx = vmin, vmax + def get_data_interval(self): + return self.dataLim.intervalx - def get_data_interval(self): - return self.dataLim.intervalx + def set_data_interval(self, vmin, vmax): + self.dataLim.intervalx = vmin, vmax - def set_data_interval(self, vmin, vmax): - self.dataLim.intervalx = vmin, vmax +class TickHelper(object): + axis = None def set_axis(self, axis): self.axis = axis - def create_dummy_axis(self): + def create_dummy_axis(self, **kwargs): if self.axis is None: - self.axis = self.DummyAxis() + self.axis = _DummyAxis(**kwargs) def set_view_interval(self, vmin, vmax): self.axis.set_view_interval(vmin, vmax) @@ -177,19 +179,20 @@ """ Convert the tick location to a string """ - # some classes want to see all the locs to help format # individual ones locs = [] + def __call__(self, x, pos=None): - 'Return the format for tick val x at position pos; pos=None indicated unspecified' - raise NotImplementedError('Derived must overide') + """Return the format for tick val x at position pos; pos=None + indicated unspecified""" + raise NotImplementedError('Derived must override') - def format_data(self,value): + def format_data(self, value): return self.__call__(value) - def format_data_short(self,value): - 'return a short string version' + def format_data_short(self, value): + """return a short string version""" return self.format_data(value) def get_offset(self): @@ -215,6 +218,7 @@ """ return s + class IndexFormatter(Formatter): """ format the position x to the nearest i-th label where i=int(x+0.5) @@ -224,11 +228,12 @@ self.n = len(labels) def __call__(self, x, pos=None): - 'Return the format for tick val x at position pos; pos=None indicated unspecified' - i = int(x+0.5) - if i<0: + """Return the format for tick val x at position pos; pos=None + indicated unspecified""" + i = int(x + 0.5) + if i < 0: return '' - elif i>=self.n: + elif i >= self.n: return '' else: return self.labels[i] @@ -236,10 +241,12 @@ class NullFormatter(Formatter): 'Always return the empty string' + def __call__(self, x, pos=None): 'Return the format for tick val *x* at position *pos*' return '' + class FixedFormatter(Formatter): 'Return fixed strings for tick labels' def __init__(self, seq): @@ -252,8 +259,10 @@ def __call__(self, x, pos=None): 'Return the format for tick val *x* at position *pos*' - if pos is None or pos>=len(self.seq): return '' - else: return self.seq[pos] + if pos is None or pos >= len(self.seq): + return '' + else: + return self.seq[pos] def get_offset(self): return self.offset_string @@ -261,6 +270,7 @@ def set_offset_string(self, ofs): self.offset_string = ofs + class FuncFormatter(Formatter): """ User defined function for formatting @@ -284,6 +294,7 @@ 'Return the format for tick val *x* at position *pos*' return self.fmt % x + class OldScalarFormatter(Formatter): """ Tick location is a plain old number. @@ -294,27 +305,34 @@ xmin, xmax = self.axis.get_view_interval() d = abs(xmax - xmin) - return self.pprint_val(x,d) + return self.pprint_val(x, d) def pprint_val(self, x, d): #if the number is not too big and it's an int, format it as an #int - if abs(x)<1e4 and x==int(x): return '%d' % x + if abs(x) < 1e4 and x == int(x): + return '%d' % x - if d < 1e-2: fmt = '%1.3e' - elif d < 1e-1: fmt = '%1.3f' - elif d > 1e5: fmt = '%1.1e' - elif d > 10 : fmt = '%1.1f' - elif d > 1 : fmt = '%1.2f' - else: fmt = '%1.3f' - s = fmt % x + if d < 1e-2: + fmt = '%1.3e' + elif d < 1e-1: + fmt = '%1.3f' + elif d > 1e5: + fmt = '%1.1e' + elif d > 10: + fmt = '%1.1f' + elif d > 1: + fmt = '%1.2f' + else: + fmt = '%1.3f' + s = fmt % x #print d, x, fmt, s tup = s.split('e') - if len(tup)==2: + if len(tup) == 2: mantissa = tup[0].rstrip('0').rstrip('.') sign = tup[1][0].replace('+', '') exponent = tup[1][1:].lstrip('0') - s = '%se%s%s' %(mantissa, sign, exponent) + s = '%se%s%s' % (mantissa, sign, exponent) else: s = s.rstrip('0').rstrip('.') return s @@ -331,21 +349,23 @@ """ - def __init__(self, useOffset=True, useMathText=False, useLocale=None): - # useOffset allows plotting small data ranges with large offsets: - # for example: [1+1e-9,1+2e-9,1+3e-9] - # useMathText will render the offset and scientific notation in mathtext + def __init__(self, useOffset=True, useMathText=None, useLocale=None): + # useOffset allows plotting small data ranges with large offsets: for + # example: [1+1e-9,1+2e-9,1+3e-9] useMathText will render the offset + # and scientific notation in mathtext + self.set_useOffset(useOffset) self._usetex = rcParams['text.usetex'] + if useMathText is None: + useMathText = rcParams['axes.formatter.use_mathtext'] self._useMathText = useMathText self.orderOfMagnitude = 0 self.format = '' self._scientific = True self._powerlimits = rcParams['axes.formatter.limits'] if useLocale is None: - self._useLocale = rcParams['axes.formatter.use_locale'] - else: - self._useLocale = useLocale + useLocale = rcParams['axes.formatter.use_locale'] + self._useLocale = useLocale def get_useOffset(self): return self._useOffset @@ -370,15 +390,17 @@ self._useLocale = val useLocale = property(fget=get_useLocale, fset=set_useLocale) - + def fix_minus(self, s): - 'use a unicode minus rather than hyphen' - if rcParams['text.usetex'] or not rcParams['axes.unicode_minus']: return s - else: return s.replace('-', u'\u2212') + """use a unicode minus rather than hyphen""" + if rcParams['text.usetex'] or not rcParams['axes.unicode_minus']: + return s + else: + return s.replace('-', u'\u2212') def __call__(self, x, pos=None): 'Return the format for tick val *x* at position *pos*' - if len(self.locs)==0: + if len(self.locs) == 0: return '' else: s = self.pprint_val(x) @@ -394,22 +416,22 @@ ''' Sets size thresholds for scientific notation. - e.g. ``formatter.set_powerlimits((-3, 4))`` sets the pre-2007 default in - which scientific notation is used for numbers less than - 1e-3 or greater than 1e4. + e.g. ``formatter.set_powerlimits((-3, 4))`` sets the pre-2007 default + in which scientific notation is used for numbers less than 1e-3 or + greater than 1e4. See also :meth:`set_scientific`. ''' assert len(lims) == 2, "argument must be a sequence of length 2" self._powerlimits = lims - def format_data_short(self,value): - 'return a short formatted string representation of a number' + def format_data_short(self, value): + """return a short formatted string representation of a number""" if self._useLocale: return locale.format_string('%-12g', (value,)) else: - return '%-12g'%value + return '%-12g' % value - def format_data(self,value): + def format_data(self, value): 'return a formatted string representation of a number' if self._useLocale: s = locale.format_string('%1.10e', (value,)) @@ -418,32 +440,34 @@ s = self._formatSciNotation(s) return self.fix_minus(s) - def get_offset(self): """Return scientific notation, plus offset""" - if len(self.locs)==0: return '' + if len(self.locs) == 0: + return '' s = '' if self.orderOfMagnitude or self.offset: offsetStr = '' sciNotStr = '' if self.offset: offsetStr = self.format_data(self.offset) - if self.offset > 0: offsetStr = '+' + offsetStr + if self.offset > 0: + offsetStr = '+' + offsetStr if self.orderOfMagnitude: if self._usetex or self._useMathText: - sciNotStr = self.format_data(10**self.orderOfMagnitude) + sciNotStr = self.format_data(10 ** self.orderOfMagnitude) else: - sciNotStr = '1e%d'% self.orderOfMagnitude + sciNotStr = '1e%d' % self.orderOfMagnitude if self._useMathText: if sciNotStr != '': sciNotStr = r'\times\mathdefault{%s}' % sciNotStr - s = ''.join(('$',sciNotStr,r'\mathdefault{',offsetStr,'}$')) + s = ''.join(('$', sciNotStr, + r'\mathdefault{', offsetStr, '}$')) elif self._usetex: if sciNotStr != '': sciNotStr = r'\times%s' % sciNotStr - s = ''.join(('$',sciNotStr,offsetStr,'$')) + s = ''.join(('$', sciNotStr, offsetStr, '$')) else: - s = ''.join((sciNotStr,offsetStr)) + s = ''.join((sciNotStr, offsetStr)) return self.fix_minus(s) @@ -452,11 +476,11 @@ self.locs = locs if len(self.locs) > 0: vmin, vmax = self.axis.get_view_interval() - d = abs(vmax-vmin) + d = abs(vmax - vmin) if self._useOffset: self._set_offset(d) self._set_orderOfMagnitude(d) - self._set_format() + self._set_format(vmin, vmax) def _set_offset(self, range): # offset of 20,001 is 20,000, for example @@ -466,30 +490,38 @@ self.offset = 0 return ave_loc = np.mean(locs) - if ave_loc: # dont want to take log10(0) + if ave_loc: # dont want to take log10(0) ave_oom = math.floor(math.log10(np.mean(np.absolute(locs)))) range_oom = math.floor(math.log10(range)) - if np.absolute(ave_oom-range_oom) >= 3: # four sig-figs + if np.absolute(ave_oom - range_oom) >= 3: # four sig-figs + p10 = 10 ** range_oom if ave_loc < 0: - self.offset = math.ceil(np.max(locs)/10**range_oom)*10**range_oom + self.offset = (math.ceil(np.max(locs) / p10) * p10) else: - self.offset = math.floor(np.min(locs)/10**(range_oom))*10**(range_oom) - else: self.offset = 0 + self.offset = (math.floor(np.min(locs) / p10) * p10) + else: + self.offset = 0 - def _set_orderOfMagnitude(self,range): + def _set_orderOfMagnitude(self, range): # if scientific notation is to be used, find the appropriate exponent - # if using an numerical offset, find the exponent after applying the offset + # if using an numerical offset, find the exponent after applying the + # offset if not self._scientific: self.orderOfMagnitude = 0 return locs = np.absolute(self.locs) - if self.offset: oom = math.floor(math.log10(range)) + if self.offset: + oom = math.floor(math.log10(range)) else: - if locs[0] > locs[-1]: val = locs[0] - else: val = locs[-1] - if val == 0: oom = 0 - else: oom = math.floor(math.log10(val)) + if locs[0] > locs[-1]: + val = locs[0] + else: + val = locs[-1] + if val == 0: + oom = 0 + else: + oom = math.floor(math.log10(val)) if oom <= self._powerlimits[0]: self.orderOfMagnitude = oom elif oom >= self._powerlimits[1]: @@ -497,23 +529,39 @@ else: self.orderOfMagnitude = 0 - def _set_format(self): + def _set_format(self, vmin, vmax): # set the format string to format all the ticklabels - # The floating point black magic (adding 1e-15 and formatting - # to 8 digits) may warrant review and cleanup. - locs = (np.asarray(self.locs)-self.offset) / 10**self.orderOfMagnitude+1e-15 - sigfigs = [len(str('%1.8f'% loc).split('.')[1].rstrip('0')) \ - for loc in locs] - sigfigs.sort() - self.format = '%1.' + str(sigfigs[-1]) + 'f' + if len(self.locs) < 2: + # Temporarily augment the locations with the axis end points. + _locs = list(self.locs) + [vmin, vmax] + else: + _locs = self.locs + locs = (np.asarray(_locs) - self.offset) / 10 ** self.orderOfMagnitude + loc_range = np.ptp(locs) + if len(self.locs) < 2: + # We needed the end points only for the loc_range calculation. + locs = locs[:-2] + loc_range_oom = int(math.floor(math.log10(loc_range))) + # first estimate: + sigfigs = max(0, 3 - loc_range_oom) + # refined estimate: + thresh = 1e-3 * 10 ** loc_range_oom + while sigfigs >= 0: + if np.abs(locs - np.round(locs, decimals=sigfigs)).max() < thresh: + sigfigs -= 1 + else: + break + sigfigs += 1 + self.format = '%1.' + str(sigfigs) + 'f' if self._usetex: self.format = '$%s$' % self.format elif self._useMathText: self.format = '$\mathdefault{%s}$' % self.format def pprint_val(self, x): - xp = (x-self.offset)/10**self.orderOfMagnitude - if np.absolute(xp) < 1e-8: xp = 0 + xp = (x - self.offset) / (10 ** self.orderOfMagnitude) + if np.absolute(xp) < 1e-8: + xp = 0 if self._useLocale: return locale.format_string(self.format, (xp,)) else: @@ -537,13 +585,13 @@ # reformat 1x10^y as 10^y significand = '' if exponent: - exponent = '10^{%s%s}'%(sign, exponent) + exponent = '10^{%s%s}' % (sign, exponent) if significand and exponent: - return r'%s{\times}%s'%(significand, exponent) + return r'%s{\times}%s' % (significand, exponent) else: - return r'%s%s'%(significand, exponent) + return r'%s%s' % (significand, exponent) else: - s = ('%se%s%s' %(significand, sign, exponent)).rstrip('e') + s = ('%se%s%s' % (significand, sign, exponent)).rstrip('e') return s except IndexError: return s @@ -553,29 +601,27 @@ """ Format values for log axis; - if attribute *decadeOnly* is True, only the decades will be labelled. """ - def __init__(self, base=10.0, labelOnlyBase = True): + def __init__(self, base=10.0, labelOnlyBase=True): """ *base* is used to locate the decade tick, which will be the only one to be labeled if *labelOnlyBase* is ``False`` """ - self._base = base+0.0 + self._base = base + 0.0 self.labelOnlyBase = labelOnlyBase - self.decadeOnly = True def base(self, base): - 'change the *base* for labeling - warning: should always match the base used for :class:`LogLocator`' + """change the *base* for labeling - warning: should always match the + base used for :class:`LogLocator`""" self._base = base def label_minor(self, labelOnlyBase): 'switch on/off minor ticks labeling' self.labelOnlyBase = labelOnlyBase - def __call__(self, x, pos=None): - 'Return the format for tick val *x* at position *pos*' + """Return the format for tick val *x* at position *pos*""" vmin, vmax = self.axis.get_view_interval() d = abs(vmax - vmin) b = self._base @@ -583,14 +629,18 @@ return '0' sign = np.sign(x) # only label the decades - fx = math.log(abs(x))/math.log(b) + fx = math.log(abs(x)) / math.log(b) isDecade = is_close_to_int(fx) - if not isDecade and self.labelOnlyBase: s = '' - elif x>10000: s= '%1.0e'%x - elif x<1: s = '%1.0e'%x - else : s = self.pprint_val(x, d) + if not isDecade and self.labelOnlyBase: + s = '' + elif x > 10000: + s = '%1.0e' % x + elif x < 1: + s = '%1.0e' % x + else: + s = self.pprint_val(x, d) if sign == -1: - s = '-%s' % s + s = '-%s' % s return self.fix_minus(s) @@ -601,61 +651,72 @@ self.labelOnlyBase = b return value - def format_data_short(self,value): + def format_data_short(self, value): 'return a short formatted string representation of a number' - return '%-12g'%value + return '%-12g' % value def pprint_val(self, x, d): #if the number is not too big and it's an int, format it as an #int - if abs(x) < 1e4 and x == int(x): return '%d' % x + if abs(x) < 1e4 and x == int(x): + return '%d' % x - if d < 1e-2: fmt = '%1.3e' - elif d < 1e-1: fmt = '%1.3f' - elif d > 1e5: fmt = '%1.1e' - elif d > 10 : fmt = '%1.1f' - elif d > 1 : fmt = '%1.2f' - else: fmt = '%1.3f' - s = fmt % x + if d < 1e-2: + fmt = '%1.3e' + elif d < 1e-1: + fmt = '%1.3f' + elif d > 1e5: + fmt = '%1.1e' + elif d > 10: + fmt = '%1.1f' + elif d > 1: + fmt = '%1.2f' + else: + fmt = '%1.3f' + s = fmt % x #print d, x, fmt, s tup = s.split('e') if len(tup) == 2: mantissa = tup[0].rstrip('0').rstrip('.') sign = tup[1][0].replace('+', '') exponent = tup[1][1:].lstrip('0') - s = '%se%s%s' %(mantissa, sign, exponent) + s = '%se%s%s' % (mantissa, sign, exponent) else: s = s.rstrip('0').rstrip('.') return s + class LogFormatterExponent(LogFormatter): """ Format values for log axis; using ``exponent = log_base(value)`` """ def __call__(self, x, pos=None): - 'Return the format for tick val *x* at position *pos*' - + """Return the format for tick val *x* at position *pos*""" vmin, vmax = self.axis.get_view_interval() - vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander = 0.05) - d = abs(vmax-vmin) - b=self._base + vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander=0.05) + d = abs(vmax - vmin) + b = self._base if x == 0: return '0' sign = np.sign(x) # only label the decades - fx = math.log(abs(x))/math.log(b) + fx = math.log(abs(x)) / math.log(b) isDecade = is_close_to_int(fx) - if not isDecade and self.labelOnlyBase: s = '' + if not isDecade and self.labelOnlyBase: + s = '' #if 0: pass - elif fx>10000: s= '%1.0e'%fx + elif fx > 10000: + s = '%1.0e' % fx #elif x<1: s = '$10^{%d}$'%fx #elif x<1: s = '10^%d'%fx - elif fx<1: s = '%1.0e'%fx - else : s = self.pprint_val(fx,d) + elif fx < 1: + s = '%1.0e' % fx + else: + s = self.pprint_val(fx, d) if sign == -1: - s = '-%s' % s + s = '-%s' % s return self.fix_minus(s) @@ -676,29 +737,37 @@ return '$0$' else: return '$\mathdefault{0}$' - sign = np.sign(x) - fx = math.log(abs(x))/math.log(b) - isDecade = is_close_to_int(fx) - if sign == -1: - sign_string = '-' + fx = math.log(abs(x)) / math.log(b) + is_decade = is_close_to_int(fx) + + sign_string = '-' if x < 0 else '' + + # use string formatting of the base if it is not an integer + if b % 1 == 0.0: + base = '%d' % b else: - sign_string = '' + base = '%s' % b - if not isDecade and self.labelOnlyBase: s = '' - elif not isDecade: + if not is_decade and self.labelOnlyBase: + return '' + elif not is_decade: if usetex: - s = r'$%s%d^{%.2f}$'% (sign_string, b, fx) + return (r'$%s%s^{%.2f}$') % \ + (sign_string, base, fx) else: - s = '$\mathdefault{%s%d^{%.2f}}$'% (sign_string, b, fx) + return ('$\mathdefault{%s%s^{%.2f}}$') % \ + (sign_string, base, fx) else: if usetex: - s = r'$%s%d^{%d}$'% (sign_string, b, nearest_long(fx)) + return (r'$%s%s^{%d}$') % (sign_string, + base, + nearest_long(fx)) else: - s = r'$\mathdefault{%s%d^{%d}}$'% (sign_string, b, - nearest_long(fx)) + return (r'$\mathdefault{%s%s^{%d}}$') % (sign_string, + base, + nearest_long(fx)) - return s class EngFormatter(Formatter): """ @@ -714,7 +783,7 @@ -15: "f", -12: "p", -9: "n", - -6: u"\u03bc", # Greek letter mu + -6: u"\u03bc", # Greek letter mu -3: "m", 0: "", 3: "k", @@ -764,7 +833,7 @@ dnum = -dnum if dnum != 0: - pow10 = decimal.Decimal(int(math.floor(dnum.log10()/3)*3)) + pow10 = decimal.Decimal(int(math.floor(dnum.log10() / 3) * 3)) else: pow10 = decimal.Decimal(0) @@ -773,7 +842,7 @@ prefix = self.ENG_PREFIXES[int(pow10)] - mant = sign*dnum/(10**pow10) + mant = sign * dnum / (10 ** pow10) if self.places is None: format_str = u"%g %s" @@ -786,13 +855,14 @@ return formatted.strip() + class Locator(TickHelper): """ Determine the tick locations; - Note, you should not use the same locator between different :class:`~matplotlib.axis.Axis` - because the locator stores references to the Axis data and view - limits + Note, you should not use the same locator between different + :class:`~matplotlib.axis.Axis` because the locator stores references to + the Axis data and view limits """ # some automatic tick locators can generate so many ticks they @@ -802,17 +872,38 @@ # This parameter is set to cause locators to raise an error if too # many ticks are generated MAXTICKS = 1000 + + def tick_values(self, vmin, vmax): + """ + Return the values of the located ticks given **vmin** and **vmax**. + + .. note:: + To get tick locations with the vmin and vmax values defined + automatically for the associated :attr:`axis` simply call + the Locator instance:: + + >>> print(type(loc)) + + >>> print(loc()) + [1, 2, 3, 4] + + """ + raise NotImplementedError('Derived must override') + def __call__(self): - 'Return the locations of the ticks' + """Return the locations of the ticks""" + # note: some locators return data limits, other return view limits, + # hence there is no *one* interface to call self.tick_values. raise NotImplementedError('Derived must override') def raise_if_exceeds(self, locs): - 'raise a RuntimeError if Locator attempts to create more than MAXTICKS locs' - if len(locs)>=self.MAXTICKS: + """raise a RuntimeError if Locator attempts to create more than + MAXTICKS locs""" + if len(locs) >= self.MAXTICKS: msg = ('Locator attempting to generate %d ticks from %s to %s: ' + - 'exceeds Locator.MAXTICKS') % (len(locs), locs[0], locs[-1]) - raise RuntimeError(msg) - + 'exceeds Locator.MAXTICKS') % (len(locs), locs[0], locs[-1]) + raise RuntimeError(msg) + return locs def view_limits(self, vmin, vmax): @@ -824,38 +915,37 @@ return mtransforms.nonsingular(vmin, vmax) def autoscale(self): - 'autoscale the view limits' + """autoscale the view limits""" return self.view_limits(*self.axis.get_view_interval()) def pan(self, numsteps): - 'Pan numticks (can be positive or negative)' + """Pan numticks (can be positive or negative)""" ticks = self() numticks = len(ticks) vmin, vmax = self.axis.get_view_interval() - vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander = 0.05) - if numticks>2: - step = numsteps*abs(ticks[0]-ticks[1]) + vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander=0.05) + if numticks > 2: + step = numsteps * abs(ticks[0] - ticks[1]) else: - d = abs(vmax-vmin) - step = numsteps*d/6. + d = abs(vmax - vmin) + step = numsteps * d / 6. vmin += step vmax += step self.axis.set_view_interval(vmin, vmax, ignore=True) - def zoom(self, direction): "Zoom in/out on axis; if direction is >0 zoom in, else zoom out" vmin, vmax = self.axis.get_view_interval() - vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander = 0.05) - interval = abs(vmax-vmin) - step = 0.1*interval*direction + vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander=0.05) + interval = abs(vmax - vmin) + step = 0.1 * interval * direction self.axis.set_view_interval(vmin + step, vmax - step, ignore=True) def refresh(self): - 'refresh internal information based on current lim' + """refresh internal information based on current lim""" pass @@ -872,10 +962,13 @@ self.offset = offset def __call__(self): - 'Return the locations of the ticks' + """Return the locations of the ticks""" dmin, dmax = self.axis.get_data_interval() + return self.tick_values(dmin, dmax) + + def tick_values(self, vmin, vmax): return self.raise_if_exceeds( - np.arange(dmin + self.offset, dmax+1, self._base)) + np.arange(vmin + self.offset, vmax + 1, self._base)) class FixedLocator(Locator): @@ -896,29 +989,49 @@ self.nbins = max(self.nbins, 2) def __call__(self): - 'Return the locations of the ticks' + return self.tick_values(None, None) + + def tick_values(self, vmin, vmax): + """" + Return the locations of the ticks. + + .. note:: + + Because the values are fixed, vmin and vmax are not used in this + method. + + """ if self.nbins is None: return self.locs step = max(int(0.99 + len(self.locs) / float(self.nbins)), 1) ticks = self.locs[::step] - for i in range(1,step): + for i in range(1, step): ticks1 = self.locs[i::step] if np.absolute(ticks1).min() < np.absolute(ticks).min(): ticks = ticks1 return self.raise_if_exceeds(ticks) - - class NullLocator(Locator): """ No ticks """ def __call__(self): - 'Return the locations of the ticks' + return self.tick_values(None, None) + + def tick_values(self, vmin, vmax): + """" + Return the locations of the ticks. + + .. note:: + + Because the values are Null, vmin and vmax are not used in this + method. + """ return [] + class LinearLocator(Locator): """ Determine the tick locations @@ -927,10 +1040,9 @@ number of ticks to make a nice tick partitioning. Thereafter the number of ticks will be fixed so that interactive navigation will be nice - """ - - def __init__(self, numticks = None, presets=None): + """ + def __init__(self, numticks=None, presets=None): """ Use presets to set locs based on lom. A dict mapping vmin, vmax->locs """ @@ -942,10 +1054,12 @@ def __call__(self): 'Return the locations of the ticks' - vmin, vmax = self.axis.get_view_interval() - vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander = 0.05) - if vmax0) + assert(base > 0) self._base = base def lt(self, x): 'return the largest multiple of base < x' - d,m = divmod(x, self._base) - if closeto(m,0) and not closeto(m/self._base,1): - return (d-1)*self._base - return d*self._base + d, m = divmod(x, self._base) + if closeto(m, 0) and not closeto(m / self._base, 1): + return (d - 1) * self._base + return d * self._base def le(self, x): 'return the largest multiple of base <= x' - d,m = divmod(x, self._base) - if closeto(m/self._base,1): # was closeto(m, self._base) + d, m = divmod(x, self._base) + if closeto(m / self._base, 1): # was closeto(m, self._base) #looks like floating point error - return (d+1)*self._base - return d*self._base + return (d + 1) * self._base + return d * self._base def gt(self, x): 'return the smallest multiple of base > x' - d,m = divmod(x, self._base) - if closeto(m/self._base,1): + d, m = divmod(x, self._base) + if closeto(m / self._base, 1): #looks like floating point error - return (d+2)*self._base - return (d+1)*self._base + return (d + 2) * self._base + return (d + 1) * self._base def ge(self, x): 'return the smallest multiple of base >= x' - d,m = divmod(x, self._base) - if closeto(m,0) and not closeto(m/self._base,1): - return d*self._base - return (d+1)*self._base + d, m = divmod(x, self._base) + if closeto(m, 0) and not closeto(m / self._base, 1): + return d * self._base + return (d + 1) * self._base def get_base(self): return self._base + class MultipleLocator(Locator): """ Set a tick on every integer that is multiple of base in the @@ -1041,12 +1157,15 @@ def __call__(self): 'Return the locations of the ticks' vmin, vmax = self.axis.get_view_interval() - if vmax 0: ex = divmod(math.log10(meanv), 1)[0] - offset = 10**ex + offset = 10 ** ex else: ex = divmod(math.log10(-meanv), 1)[0] - offset = -10**ex - ex = divmod(math.log10(dv/n), 1)[0] - scale = 10**ex + offset = -10 ** ex + ex = divmod(math.log10(dv / n), 1)[0] + scale = 10 ** ex return scale, offset - class MaxNLocator(Locator): """ Select no more than N intervals at nice locations. """ - default_params = dict(nbins = 10, - steps = None, - trim = True, + default_params = dict(nbins=10, + steps=None, + trim=True, integer=False, symmetric=False, prune=None) + def __init__(self, *args, **kwargs): """ Keyword args: @@ -1159,17 +1281,17 @@ if 'integer' in kwargs: self._integer = kwargs['integer'] if self._integer: - self._steps = [n for n in self._steps if divmod(n,1)[1] < 0.001] + self._steps = [n for n in self._steps if divmod(n, 1)[1] < 0.001] def bin_boundaries(self, vmin, vmax): nbins = self._nbins scale, offset = scale_range(vmin, vmax, nbins) if self._integer: scale = max(1, scale) - vmin -= offset - vmax -= offset - raw_step = (vmax-vmin)/nbins - scaled_raw_step = raw_step/scale + vmin = vmin - offset + vmax = vmax - offset + raw_step = (vmax - vmin) / nbins + scaled_raw_step = raw_step / scale best_vmax = vmax best_vmin = vmin @@ -1177,27 +1299,29 @@ if step < scaled_raw_step: continue step *= scale - best_vmin = step*divmod(vmin, step)[0] - best_vmax = best_vmin + step*nbins + best_vmin = step * divmod(vmin, step)[0] + best_vmax = best_vmin + step * nbins if (best_vmax >= vmax): break if self._trim: extra_bins = int(divmod((best_vmax - vmax), step)[0]) nbins -= extra_bins - return (np.arange(nbins+1) * step + best_vmin + offset) - + return (np.arange(nbins + 1) * step + best_vmin + offset) def __call__(self): vmin, vmax = self.axis.get_view_interval() - vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander = 0.05) + return self.tick_values(vmin, vmax) + + def tick_values(self, vmin, vmax): + vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander=1e-13, + tiny=1e-14) locs = self.bin_boundaries(vmin, vmax) - #print 'locs=', locs prune = self._prune - if prune=='lower': + if prune == 'lower': locs = locs[1:] - elif prune=='upper': + elif prune == 'upper': locs = locs[:-1] - elif prune=='both': + elif prune == 'both': locs = locs[1:-1] return self.raise_if_exceeds(locs) @@ -1206,77 +1330,87 @@ maxabs = max(abs(dmin), abs(dmax)) dmin = -maxabs dmax = maxabs - dmin, dmax = mtransforms.nonsingular(dmin, dmax, expander = 0.05) - return np.take(self.bin_boundaries(dmin, dmax), [0,-1]) + dmin, dmax = mtransforms.nonsingular(dmin, dmax, expander=1e-12, + tiny=1.e-13) + return np.take(self.bin_boundaries(dmin, dmax), [0, -1]) def decade_down(x, base=10): 'floor x to the nearest lower decade' if x == 0.0: return -base - lx = np.floor(np.log(x)/np.log(base)) - return base**lx + lx = np.floor(np.log(x) / np.log(base)) + return base ** lx + def decade_up(x, base=10): 'ceil x to the nearest higher decade' if x == 0.0: return base - lx = np.ceil(np.log(x)/np.log(base)) - return base**lx + lx = np.ceil(np.log(x) / np.log(base)) + return base ** lx + def nearest_long(x): - if x == 0: return 0L - elif x > 0: return long(x+0.5) - else: return long(x-0.5) + if x == 0: + return 0L + elif x > 0: + return long(x + 0.5) + else: + return long(x - 0.5) + def is_decade(x, base=10): if not np.isfinite(x): return False if x == 0.0: return True - lx = np.log(np.abs(x))/np.log(base) + lx = np.log(np.abs(x)) / np.log(base) return is_close_to_int(lx) + def is_close_to_int(x): if not np.isfinite(x): return False return abs(x - nearest_long(x)) < 1e-10 + class LogLocator(Locator): """ Determine the tick locations for log axes """ - def __init__(self, base=10.0, subs=[1.0], numdecs=4): + def __init__(self, base=10.0, subs=[1.0], numdecs=4, numticks=15): """ place ticks on the location= base**i*subs[j] """ self.base(base) self.subs(subs) - self.numticks = 15 + self.numticks = numticks self.numdecs = numdecs - def base(self,base): + def base(self, base): """ set the base of the log scaling (major tick every base**i, i integer) """ - self._base=base+0.0 + self._base = base + 0.0 - def subs(self,subs): + def subs(self, subs): """ set the minor ticks the log scaling every base**i*subs[j] """ if subs is None: self._subs = None # autosub else: - self._subs = np.asarray(subs)+0.0 + self._subs = np.asarray(subs) + 0.0 def __call__(self): 'Return the locations of the ticks' - b=self._base - vmin, vmax = self.axis.get_view_interval() + return self.tick_values(vmin, vmax) + def tick_values(self, vmin, vmax): + b = self._base # dummy axis has no axes attribute if hasattr(self.axis, 'axes') and self.axis.axes.name == 'polar': vmax = math.ceil(math.log(vmax) / math.log(b)) @@ -1286,32 +1420,38 @@ return ticklocs if vmin <= 0.0: - vmin = self.axis.get_minpos() + if self.axis is not None: + vmin = self.axis.get_minpos() + if vmin <= 0.0 or not np.isfinite(vmin): raise ValueError( - "Data has no positive values, and therefore can not be log-scaled.") + "Data has no positive values, and therefore can not be " + "log-scaled.") - vmin = math.log(vmin)/math.log(b) - vmax = math.log(vmax)/math.log(b) + vmin = math.log(vmin) / math.log(b) + vmax = math.log(vmax) / math.log(b) - if vmax10: subs = np.array([1.0]) - elif numdec>6: subs = np.arange(2.0, b, 2.0) - else: subs = np.arange(2.0, b) + if self._subs is None: # autosub + if numdec > 10: + subs = np.array([1.0]) + elif numdec > 6: + subs = np.arange(2.0, b, 2.0) + else: + subs = np.arange(2.0, b) else: subs = self._subs stride = 1 - while numdec/stride+1 > self.numticks: + while numdec / stride + 1 > self.numticks: stride += 1 decades = np.arange(math.floor(vmin), - math.ceil(vmax)+stride, stride) + math.ceil(vmax) + stride, stride) if hasattr(self, '_transform'): ticklocs = self._transform.inverted().transform(decades) if len(subs) > 1 or (len(subs == 1) and subs[0] != 1.0): @@ -1319,10 +1459,10 @@ else: if len(subs) > 1 or (len(subs == 1) and subs[0] != 1.0): ticklocs = [] - for decadeStart in b**decades: - ticklocs.extend( subs*decadeStart ) + for decadeStart in b ** decades: + ticklocs.extend(subs * decadeStart) else: - ticklocs = b**decades + ticklocs = b ** decades return self.raise_if_exceeds(np.asarray(ticklocs)) @@ -1330,7 +1470,7 @@ 'Try to choose the view limits intelligently' b = self._base - if vmax vmax: - vmin,vmax = vmax,vmin + vmin, vmax = vmax, vmin if len(majorlocs) > 0: t0 = majorlocs[0] tmin = np.ceil((vmin - t0) / minorstep) * minorstep tmax = np.floor((vmax - t0) / minorstep) * minorstep locs = np.arange(tmin, tmax, minorstep) + t0 - cond = np.abs((locs - t0) % majorstep) > minorstep/10.0 + cond = np.abs((locs - t0) % majorstep) > minorstep / 10.0 locs = locs.compress(cond) else: locs = [] return self.raise_if_exceeds(np.array(locs)) + def tick_values(self, vmin, vmax): + raise NotImplementedError('Cannot get tick locations for a ' + '%s type.' % type(self)) + class OldAutoLocator(Locator): """ @@ -1579,48 +1736,53 @@ self.refresh() return self.raise_if_exceeds(self._locator()) + def tick_values(self, vmin, vmax): + raise NotImplementedError('Cannot get tick locations for a ' + '%s type.' % type(self)) + def refresh(self): 'refresh internal information based on current lim' vmin, vmax = self.axis.get_view_interval() - vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander = 0.05) - d = abs(vmax-vmin) + vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander=0.05) + d = abs(vmax - vmin) self._locator = self.get_locator(d) def view_limits(self, vmin, vmax): 'Try to choose the view limits intelligently' - d = abs(vmax-vmin) + d = abs(vmax - vmin) self._locator = self.get_locator(d) return self._locator.view_limits(vmin, vmax) def get_locator(self, d): 'pick the best locator based on a distance' d = abs(d) - if d<=0: + if d <= 0: locator = MultipleLocator(0.2) else: - try: ld = math.log10(d) + try: + ld = math.log10(d) except OverflowError: raise RuntimeError('AutoLocator illegal data interval range') - fld = math.floor(ld) - base = 10**fld + base = 10 ** fld #if ld==fld: base = 10**(fld-1) #else: base = 10**fld - if d >= 5*base : ticksize = base - elif d >= 2*base : ticksize = base/2.0 - else : ticksize = base/5.0 + if d >= 5 * base: + ticksize = base + elif d >= 2 * base: + ticksize = base / 2.0 + else: + ticksize = base / 5.0 locator = MultipleLocator(ticksize) - return locator - __all__ = ('TickHelper', 'Formatter', 'FixedFormatter', 'NullFormatter', 'FuncFormatter', 'FormatStrFormatter', 'ScalarFormatter', 'LogFormatter', 'LogFormatterExponent', diff -Nru matplotlib-1.1.1/lib/matplotlib/tight_bbox.py matplotlib-1.2.0/lib/matplotlib/tight_bbox.py --- matplotlib-1.1.1/lib/matplotlib/tight_bbox.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tight_bbox.py 2012-11-06 15:42:20.000000000 +0000 @@ -2,11 +2,11 @@ This module is to support *bbox_inches* option in savefig command. """ +from __future__ import print_function import warnings from matplotlib.transforms import Bbox, TransformedBbox, Affine2D - def adjust_bbox(fig, format, bbox_inches): """ Temporarily adjust the figure so that only the specified area @@ -29,12 +29,11 @@ locator_list.append(ax.get_axes_locator()) asp_list.append(ax.get_aspect()) - def _l(a, r, pos=pos): return pos + def _l(a, r, pos=pos): + return pos ax.set_axes_locator(_l) ax.set_aspect("auto") - - def restore_bbox(): for ax, asp, loc in zip(fig.axes, asp_list, locator_list): @@ -52,7 +51,8 @@ adjust_bbox_handler(fig, bbox_inches) return restore_bbox else: - warnings.warn("bbox_inches option for %s backend is not implemented yet." % (format)) + warnings.warn("bbox_inches option for %s backend is not " + "implemented yet." % (format)) return None @@ -78,8 +78,8 @@ fig.bbox = TransformedBbox(fig.bbox_inches, tr) - fig.patch.set_bounds(x0/w1, y0/h1, - fig.bbox.width/w1, fig.bbox.height/h1) + fig.patch.set_bounds(x0 / w1, y0 / h1, + fig.bbox.width / w1, fig.bbox.height / h1) def adjust_bbox_pdf(fig, bbox_inches): @@ -87,7 +87,12 @@ adjust_bbox for pdf & eps format """ - tr = Affine2D().scale(72) + if fig._cachedRenderer.__class__.__name__ == "RendererPgf": + tr = Affine2D().scale(fig.dpi) + f = 1. + else: + tr = Affine2D().scale(72) + f = 72. / fig.dpi _bbox = TransformedBbox(bbox_inches, tr) @@ -95,21 +100,20 @@ bbox_inches.width, bbox_inches.height) x0, y0 = _bbox.x0, _bbox.y0 - f = 72. / fig.dpi - w1, h1 = fig.bbox.width*f, fig.bbox.height*f + w1, h1 = fig.bbox.width * f, fig.bbox.height * f fig.transFigure._boxout = Bbox.from_bounds(-x0, -y0, w1, h1) fig.transFigure.invalidate() fig.bbox = TransformedBbox(fig.bbox_inches, tr) - fig.patch.set_bounds(x0/w1, y0/h1, - fig.bbox.width/w1, fig.bbox.height/h1) + fig.patch.set_bounds(x0 / w1, y0 / h1, + fig.bbox.width / w1, fig.bbox.height / h1) def process_figure_for_rasterizing(figure, bbox_inches_restore, mode): - + """ This need to be called when figure dpi changes during the drawing (e.g., rasterizing). It recovers the bbox and re-adjust it with diff -Nru matplotlib-1.1.1/lib/matplotlib/tight_layout.py matplotlib-1.2.0/lib/matplotlib/tight_layout.py --- matplotlib-1.1.1/lib/matplotlib/tight_layout.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tight_layout.py 2012-11-06 15:42:20.000000000 +0000 @@ -1,15 +1,16 @@ """ -This module provides routines to adjust subplot params so that -subplots are nicely fit in the figure. In doing so, only axis labels, -tick labels and axes titles are currently considered. +This module provides routines to adjust subplot params so that subplots are +nicely fit in the figure. In doing so, only axis labels, tick labels and axes +titles are currently considered. Internally, it assumes that the margins (left_margin, etc.) which are -differences between ax.get_tightbbox and ax.bbox are independent of -axes position. This may fail if Axes.adjustable is datalim. Also, This -will fail for some cases (for example, left or right margin is affected by xlabel). - +differences between ax.get_tightbbox and ax.bbox are independent of axes +position. This may fail if Axes.adjustable is datalim. Also, This will fail +for some cases (for example, left or right margin is affected by xlabel). """ +import warnings + import matplotlib from matplotlib.transforms import TransformedBbox, Bbox @@ -17,16 +18,18 @@ rcParams = matplotlib.rcParams - def _get_left(tight_bbox, axes_bbox): return axes_bbox.xmin - tight_bbox.xmin + def _get_right(tight_bbox, axes_bbox): return tight_bbox.xmax - axes_bbox.xmax + def _get_bottom(tight_bbox, axes_bbox): return axes_bbox.ymin - tight_bbox.ymin + def _get_top(tight_bbox, axes_bbox): return tight_bbox.ymax - axes_bbox.ymax @@ -36,7 +39,7 @@ num1num2_list, subplot_list, ax_bbox_list=None, - pad=1.2, h_pad=None, w_pad=None, + pad=1.08, h_pad=None, w_pad=None, rect=None): """ Return a dictionary of subplot parameters so that spacing between @@ -44,7 +47,7 @@ information of subplot itself, but uses what is given by *nrows_ncols* and *num1num2_list* parameteres. Also, the results could be incorrect if some subplots have ``adjustable=datalim``. - + Parameters: nrows_ncols @@ -57,7 +60,8 @@ list of subplots that will be used to calcuate optimal subplot_params. pad : float - padding between the figure edge and the edges of subplots, as a fraction of the font-size. + padding between the figure edge and the edges of subplots, as a fraction + of the font-size. h_pad, w_pad : float padding (height/width) between edges of adjacent subplots. Defaults to `pad_inches`. @@ -65,22 +69,22 @@ rect [left, bottom, right, top] in normalized (0, 1) figure coordinates. """ - - rows, cols = nrows_ncols - pad_inches = pad * FontProperties(size=rcParams["font.size"]).get_size_in_points() / renderer.dpi + pad_inches = pad * FontProperties( + size=rcParams["font.size"]).get_size_in_points() / 72. if h_pad is not None: - vpad_inches = h_pad * FontProperties(size=rcParams["font.size"]).get_size_in_points() / renderer.dpi + vpad_inches = h_pad * FontProperties( + size=rcParams["font.size"]).get_size_in_points() / 72. else: vpad_inches = pad_inches if w_pad is not None: - hpad_inches = w_pad * FontProperties(size=rcParams["font.size"]).get_size_in_points() / renderer.dpi + hpad_inches = w_pad * FontProperties( + size=rcParams["font.size"]).get_size_in_points() / 72. else: hpad_inches = pad_inches - if len(subplot_list) == 0: raise RuntimeError("") @@ -89,25 +93,33 @@ raise RuntimeError("") if rect is None: - margin_left, margin_bottom, margin_right, margin_top = None, None, None, None + margin_left = None + margin_bottom = None + margin_right = None + margin_top = None else: margin_left, margin_bottom, _right, _top = rect - if _right: margin_right = 1. - _right - else: margin_right = None - if _top: margin_top = 1. - _top - else: margin_top = None - - vspaces = [[] for i in range((rows+1)*cols)] - hspaces = [[] for i in range(rows*(cols+1))] - + if _right: + margin_right = 1. - _right + else: + margin_right = None + if _top: + margin_top = 1. - _top + else: + margin_top = None + + vspaces = [[] for i in range((rows + 1) * cols)] + hspaces = [[] for i in range(rows * (cols + 1))] + union = Bbox.union if ax_bbox_list is None: ax_bbox_list = [] for subplots in subplot_list: - ax_bbox = union([ax.get_position(original=True) for ax in subplots]) + ax_bbox = union([ax.get_position(original=True) + for ax in subplots]) ax_bbox_list.append(ax_bbox) - + for subplots, ax_bbox, (num1, num2) in zip(subplot_list, ax_bbox_list, num1num2_list): @@ -115,35 +127,42 @@ #ax_bbox = union([ax.get_position(original=True) for ax in subplots]) tight_bbox_raw = union([ax.get_tightbbox(renderer) for ax in subplots]) - tight_bbox = TransformedBbox(tight_bbox_raw, fig.transFigure.inverted()) + tight_bbox = TransformedBbox(tight_bbox_raw, + fig.transFigure.inverted()) row1, col1 = divmod(num1, cols) - if num2 is None: # left - hspaces[row1 * (cols+1) + col1].append(_get_left(tight_bbox, ax_bbox)) + hspaces[row1 * (cols + 1) + col1].append( + _get_left(tight_bbox, ax_bbox)) # right - hspaces[row1 * (cols+1) + (col1+1)].append(_get_right(tight_bbox, ax_bbox)) + hspaces[row1 * (cols + 1) + (col1 + 1)].append( + _get_right(tight_bbox, ax_bbox)) # top - vspaces[row1 * cols + col1].append(_get_top(tight_bbox, ax_bbox)) + vspaces[row1 * cols + col1].append( + _get_top(tight_bbox, ax_bbox)) # bottom - vspaces[(row1+1) * cols + col1].append(_get_bottom(tight_bbox, ax_bbox)) + vspaces[(row1 + 1) * cols + col1].append( + _get_bottom(tight_bbox, ax_bbox)) else: row2, col2 = divmod(num2, cols) - - for row_i in range(row1, row2+1): + + for row_i in range(row1, row2 + 1): # left - hspaces[row_i * (cols+1) + col1].append(_get_left(tight_bbox, ax_bbox)) + hspaces[row_i * (cols + 1) + col1].append( + _get_left(tight_bbox, ax_bbox)) # right - hspaces[row_i * (cols+1) + (col2+1)].append(_get_right(tight_bbox, ax_bbox)) - for col_i in range(col1, col2+1): + hspaces[row_i * (cols + 1) + (col2 + 1)].append( + _get_right(tight_bbox, ax_bbox)) + for col_i in range(col1, col2 + 1): # top - vspaces[row1 * cols + col_i].append(_get_top(tight_bbox, ax_bbox)) + vspaces[row1 * cols + col_i].append( + _get_top(tight_bbox, ax_bbox)) # bottom - vspaces[(row2+1) * cols + col_i].append(_get_bottom(tight_bbox, ax_bbox)) - + vspaces[(row2 + 1) * cols + col_i].append( + _get_bottom(tight_bbox, ax_bbox)) fig_width_inch, fig_height_inch = fig.get_size_inches() @@ -151,43 +170,47 @@ # append + [0] to make minimum margins 0 if not margin_left: - margin_left = max([sum(s) for s in hspaces[::cols+1]] + [0]) + margin_left = max([sum(s) for s in hspaces[::cols + 1]] + [0]) margin_left += pad_inches / fig_width_inch - + if not margin_right: - margin_right = max([sum(s) for s in hspaces[cols::cols+1]] + [0]) + margin_right = max([sum(s) for s in hspaces[cols::cols + 1]] + [0]) margin_right += pad_inches / fig_width_inch if not margin_top: - margin_top = max([sum(s) for s in vspaces[:cols]] + [0]) + margin_top = max([sum(s) for s in vspaces[:cols]] + [0]) margin_top += pad_inches / fig_height_inch if not margin_bottom: - margin_bottom = max([sum(s) for s in vspaces[-cols:]] + [0]) + margin_bottom = max([sum(s) for s in vspaces[-cols:]] + [0]) margin_bottom += pad_inches / fig_height_inch - kwargs = dict(left=margin_left, - right=1-margin_right, + right=1 - margin_right, bottom=margin_bottom, - top=1-margin_top) + top=1 - margin_top) if cols > 1: - hspace = max([sum(s) for i in range(rows) for s in hspaces[i*(cols+1)+1:(i+1)*(cols+1)-1]]) + hspace = max([sum(s) + for i in range(rows) + for s + in hspaces[i * (cols + 1) + 1:(i + 1) * (cols + 1) - 1]]) hspace += hpad_inches / fig_width_inch - h_axes = ((1-margin_right-margin_left) - hspace * (cols - 1))/cols + h_axes = ((1 - margin_right - margin_left) - + hspace * (cols - 1)) / cols - kwargs["wspace"]=hspace/h_axes + kwargs["wspace"] = hspace / h_axes if rows > 1: - vspace = max([sum(s) for s in vspaces[cols:-cols]]) + vspace = max([sum(s) for s in vspaces[cols:-cols]]) vspace += vpad_inches / fig_height_inch - v_axes = ((1-margin_top-margin_bottom) - vspace * (rows - 1))/rows + v_axes = ((1 - margin_top - margin_bottom) - + vspace * (rows - 1)) / rows - kwargs["hspace"]=vspace/v_axes + kwargs["hspace"] = vspace / v_axes return kwargs - + def get_renderer(fig): if fig._cachedRenderer: @@ -199,9 +222,163 @@ renderer = canvas.get_renderer() else: # not sure if this can happen - print "tight_layout : falling back to Agg renderer" + warnings.warn("tight_layout : falling back to Agg renderer") from matplotlib.backends.backend_agg import FigureCanvasAgg canvas = FigureCanvasAgg(fig) renderer = canvas.get_renderer() return renderer + + +def get_subplotspec_list(axes_list, grid_spec=None): + """ + Return a list of subplotspec from the given list of axes. For an + instance of axes that does not support subplotspec, None is + inserted in the list. + + If grid_spec is given, None is inserted for those not from + the given grid_spec. + + """ + subplotspec_list = [] + for ax in axes_list: + axes_or_locator = ax.get_axes_locator() + if axes_or_locator is None: + axes_or_locator = ax + + if hasattr(axes_or_locator, "get_subplotspec"): + subplotspec = axes_or_locator.get_subplotspec() + subplotspec = subplotspec.get_topmost_subplotspec() + gs = subplotspec.get_gridspec() + if grid_spec is not None: + if gs != grid_spec: + subplotspec = None + elif gs.locally_modified_subplot_params(): + subplotspec = None + else: + subplotspec = None + + subplotspec_list.append(subplotspec) + + return subplotspec_list + + +def get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer, + pad=1.08, h_pad=None, w_pad=None, rect=None): + """ + Return subplot parameters for tight-layouted-figure with specified + padding. + + Parameters: + + *fig* : figure instance + + *axes_list* : a list of axes + + *subplotspec_list* : a list of subplotspec associated with each + axes in axes_list + + *renderer* : renderer instance + + *pad* : float + padding between the figure edge and the edges of subplots, + as a fraction of the font-size. + + *h_pad*, *w_pad* : float + padding (height/width) between edges of adjacent subplots. + Defaults to `pad_inches`. + + *rect* : if rect is given, it is interpreted as a rectangle + (left, bottom, right, top) in the normalized figure + coordinate that the whole subplots area (including + labels) will fit into. Default is (0, 0, 1, 1). + """ + + subplot_list = [] + nrows_list = [] + ncols_list = [] + ax_bbox_list = [] + + subplot_dict = {} # multiple axes can share + # same subplot_interface (e.g, axes_grid1). Thus + # we need to join them together. + + subplotspec_list2 = [] + + for ax, subplotspec in zip(axes_list, + subplotspec_list): + if subplotspec is None: + continue + + subplots = subplot_dict.setdefault(subplotspec, []) + + if not subplots: + myrows, mycols, _, _ = subplotspec.get_geometry() + nrows_list.append(myrows) + ncols_list.append(mycols) + subplotspec_list2.append(subplotspec) + subplot_list.append(subplots) + ax_bbox_list.append(subplotspec.get_position(fig)) + + subplots.append(ax) + + max_nrows = max(nrows_list) + max_ncols = max(ncols_list) + + num1num2_list = [] + for subplotspec in subplotspec_list2: + rows, cols, num1, num2 = subplotspec.get_geometry() + div_row, mod_row = divmod(max_nrows, rows) + div_col, mod_col = divmod(max_ncols, cols) + if (mod_row != 0) or (mod_col != 0): + raise RuntimeError("") + + rowNum1, colNum1 = divmod(num1, cols) + if num2 is None: + rowNum2, colNum2 = rowNum1, colNum1 + else: + rowNum2, colNum2 = divmod(num2, cols) + + num1num2_list.append((rowNum1 * div_row * max_ncols + + colNum1 * div_col, + ((rowNum2 + 1) * div_row - 1) * max_ncols + + (colNum2 + 1) * div_col - 1)) + + kwargs = auto_adjust_subplotpars(fig, renderer, + nrows_ncols=(max_nrows, max_ncols), + num1num2_list=num1num2_list, + subplot_list=subplot_list, + ax_bbox_list=ax_bbox_list, + pad=pad, h_pad=h_pad, w_pad=w_pad) + + if rect is not None: + # if rect is given, the whole subplots area (including + # labels) will fit into the rect instead of the + # figure. Note that the rect argument of + # *auto_adjust_subplotpars* specify the area that will be + # covered by the total area of axes.bbox. Thus we call + # auto_adjust_subplotpars twice, where the second run + # with adjusted rect parameters. + + left, bottom, right, top = rect + if left is not None: + left += kwargs["left"] + if bottom is not None: + bottom += kwargs["bottom"] + if right is not None: + right -= (1 - kwargs["right"]) + if top is not None: + top -= (1 - kwargs["top"]) + + #if h_pad is None: h_pad = pad + #if w_pad is None: w_pad = pad + + kwargs = auto_adjust_subplotpars(fig, renderer, + nrows_ncols=(max_nrows, max_ncols), + num1num2_list=num1num2_list, + subplot_list=subplot_list, + ax_bbox_list=ax_bbox_list, + pad=pad, h_pad=h_pad, w_pad=w_pad, + rect=(left, bottom, right, top)) + + return kwargs diff -Nru matplotlib-1.1.1/lib/matplotlib/transforms.py matplotlib-1.2.0/lib/matplotlib/transforms.py --- matplotlib-1.1.1/lib/matplotlib/transforms.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/transforms.py 2012-11-06 15:42:20.000000000 +0000 @@ -29,28 +29,27 @@ themselves. """ +from __future__ import print_function, division import numpy as np from numpy import ma -from matplotlib._path import affine_transform +from matplotlib._path import (affine_transform, count_bboxes_overlapping_bbox, + update_path_extents) from numpy.linalg import inv -from weakref import WeakKeyDictionary +from weakref import WeakValueDictionary import warnings try: set except NameError: from sets import Set as set -import cbook from path import Path -from _path import count_bboxes_overlapping_bbox, update_path_extents DEBUG = False -if DEBUG: - import warnings MaskedArray = ma.MaskedArray + class TransformNode(object): """ :class:`TransformNode` is the base class for anything that @@ -65,30 +64,54 @@ # invalidation was "affine-only", the _invalid member is set to # INVALID_AFFINE_ONLY INVALID_NON_AFFINE = 1 - INVALID_AFFINE = 2 - INVALID = INVALID_NON_AFFINE | INVALID_AFFINE + INVALID_AFFINE = 2 + INVALID = INVALID_NON_AFFINE | INVALID_AFFINE # Some metadata about the transform, used to determine whether an # invalidation is affine-only is_affine = False - is_bbox = False + is_bbox = False - # If pass_through is True, all ancestors will always be - # invalidated, even if 'self' is already invalid. pass_through = False + """ + If pass_through is True, all ancestors will always be + invalidated, even if 'self' is already invalid. + """ - def __init__(self): + def __init__(self, shorthand_name=None): """ Creates a new :class:`TransformNode`. + + **shorthand_name** - a string representing the "name" of this + transform. The name carries no significance + other than to improve the readability of + ``str(transform)`` when DEBUG=True. """ - # Parents are stored in a WeakKeyDictionary, so that if the + # Parents are stored in a WeakValueDictionary, so that if the # parents are deleted, references from the children won't keep # them alive. - self._parents = WeakKeyDictionary() + self._parents = WeakValueDictionary() # TransformNodes start out as invalid until their values are # computed for the first time. self._invalid = 1 + self._shorthand_name = shorthand_name or '' + + if DEBUG: + def __str__(self): + # either just return the name of this TransformNode, or it's repr + return self._shorthand_name or repr(self) + + def __getstate__(self): + d = self.__dict__.copy() + # turn the weakkey dictionary into a normal dictionary + d['_parents'] = dict(self._parents.iteritems()) + return d + + def __setstate__(self, data_dict): + self.__dict__ = data_dict + # turn the normal dictionary back into a WeakValueDictionary + self._parents = WeakValueDictionary(self._parents) def __copy__(self, *args): raise NotImplementedError( @@ -98,30 +121,38 @@ def invalidate(self): """ - Invalidate this :class:`TransformNode` and all of its - ancestors. Should be called any time the transform changes. - """ - # If we are an affine transform being changed, we can set the - # flag to INVALID_AFFINE_ONLY - value = (self.is_affine) and self.INVALID_AFFINE or self.INVALID - - # Shortcut: If self is already invalid, that means its parents - # are as well, so we don't need to do anything. - if self._invalid == value: - return + Invalidate this :class:`TransformNode` and triggers an + invalidation of its ancestors. Should be called any + time the transform changes. + """ + value = self.INVALID + if self.is_affine: + value = self.INVALID_AFFINE + return self._invalidate_internal(value, invalidating_node=self) + + def _invalidate_internal(self, value, invalidating_node): + """ + Called by :meth:`invalidate` and subsequently ascends the transform + stack calling each TransformNode's _invalidate_internal method. + """ + # determine if this call will be an extension to the invalidation + # status. If not, then a shortcut means that we needn't invoke an + # invalidation up the transform stack as it will already have been + # invalidated. + + # N.B This makes the invalidation sticky, once a transform has been + # invalidated as NON_AFFINE, then it will always be invalidated as + # NON_AFFINE even when triggered with a AFFINE_ONLY invalidation. + # In most cases this is not a problem (i.e. for interactive panning and + # zooming) and the only side effect will be on performance. + status_changed = self._invalid < value - if not len(self._parents): + if self.pass_through or status_changed: self._invalid = value - return - # Invalidate all ancestors of self using pseudo-recursion. - stack = [self] - while len(stack): - root = stack.pop() - # Stop at subtrees that have already been invalidated - if root._invalid != value or root.pass_through: - root._invalid = self.INVALID - stack.extend(root._parents.keys()) + for parent in self._parents.itervalues(): + parent._invalidate_internal(value=value, + invalidating_node=self) def set_children(self, *children): """ @@ -131,10 +162,11 @@ depend on other transforms. """ for child in children: - child._parents[self] = None + child._parents[id(self)] = self if DEBUG: _set_children = set_children + def set_children(self, *children): self._set_children(*children) self._children = children @@ -162,6 +194,12 @@ marked in yellow. *fobj*: A Python file-like object + + Once the "dot" file has been created, it can be turned into a + png easily with:: + + $> dot -Tpng -o $OUTPUT_FILE $DOT_FILE + """ seen = set() @@ -177,7 +215,9 @@ props['style'] = 'bold' props['shape'] = 'box' props['label'] = '"%s"' % label - props = ' '.join(['%s=%s' % (key, val) for key, val in props.items()]) + props = ' '.join(['%s=%s' % (key, val) + for key, val + in props.iteritems()]) fobj.write('%s [%s];\n' % (hash(root), props)) @@ -185,22 +225,19 @@ if hasattr(root, '_children'): for child in root._children: name = '?' - for key, val in root.__dict__.items(): + for key, val in root.__dict__.iteritems(): if val is child: name = key break - fobj.write('%s -> %s [label="%s", fontsize=10];\n' % ( - hash(root), - hash(child), - name)) + fobj.write('"%s" -> "%s" [label="%s", fontsize=10];\n' + % (hash(root), + hash(child), + name)) recurse(child) fobj.write("digraph G {\n") recurse(self) fobj.write("}\n") - else: - def write_graphviz(self, fobj, highlight=[]): - return class BboxBase(TransformNode): @@ -227,8 +264,8 @@ if ma.isMaskedArray(points): warnings.warn("Bbox bounds are a masked array.") points = np.asarray(points) - if (points[1,0] - points[0,0] == 0 or - points[1,1] - points[0,1] == 0): + if (points[1, 0] - points[0, 0] == 0 or + points[1, 1] - points[0, 1] == 0): warnings.warn("Singular Bbox.") _check = staticmethod(_check) @@ -263,30 +300,30 @@ def _get_x1(self): return self.get_points()[1, 0] x1 = property(_get_x1, None, None, """ - (property) :attr:`x1` is the second of the pair of *x* coordinates that - define the bounding box. :attr:`x1` is not guaranteed to be + (property) :attr:`x1` is the second of the pair of *x* coordinates + that define the bounding box. :attr:`x1` is not guaranteed to be greater than :attr:`x0`. If you require that, use :attr:`xmax`.""") def _get_y1(self): return self.get_points()[1, 1] y1 = property(_get_y1, None, None, """ - (property) :attr:`y1` is the second of the pair of *y* coordinates that - define the bounding box. :attr:`y1` is not guaranteed to be + (property) :attr:`y1` is the second of the pair of *y* coordinates + that define the bounding box. :attr:`y1` is not guaranteed to be greater than :attr:`y0`. If you require that, use :attr:`ymax`.""") def _get_p0(self): return self.get_points()[0] p0 = property(_get_p0, None, None, """ - (property) :attr:`p0` is the first pair of (*x*, *y*) coordinates that - define the bounding box. It is not guaranteed to be the bottom-left - corner. For that, use :attr:`min`.""") + (property) :attr:`p0` is the first pair of (*x*, *y*) coordinates + that define the bounding box. It is not guaranteed to be the + bottom-left corner. For that, use :attr:`min`.""") def _get_p1(self): return self.get_points()[1] p1 = property(_get_p1, None, None, """ - (property) :attr:`p1` is the second pair of (*x*, *y*) coordinates that - define the bounding box. It is not guaranteed to be the top-right - corner. For that, use :attr:`max`.""") + (property) :attr:`p1` is the second pair of (*x*, *y*) coordinates + that define the bounding box. It is not guaranteed to be the + top-right corner. For that, use :attr:`max`.""") def _get_xmin(self): return min(self.get_points()[:, 0]) @@ -366,7 +403,8 @@ def _get_extents(self): return self.get_points().flatten().copy() extents = property(_get_extents, None, None, """ - (property) Returns (:attr:`x0`, :attr:`y0`, :attr:`x1`, :attr:`y1`).""") + (property) Returns (:attr:`x0`, :attr:`y0`, :attr:`x1`, + :attr:`y1`).""") def get_points(self): return NotImplementedError() @@ -437,8 +475,8 @@ """ y0, y1 = self.intervaly return ((y0 < y1 - and (x > y0 and x < y1)) - or (x > y1 and x < y0)) + and (y > y0 and y < y1)) + or (y > y1 and y < y0)) def fully_contains(self, x, y): """ @@ -485,7 +523,7 @@ return Bbox(transform.inverted().transform(self.get_points())) coefs = {'C': (0.5, 0.5), - 'SW': (0,0), + 'SW': (0, 0), 'S': (0.5, 0), 'SE': (1.0, 0), 'E': (1.0, 0.5), @@ -493,7 +531,8 @@ 'N': (0.5, 1.0), 'NW': (0, 1.0), 'W': (0, 0.5)} - def anchored(self, c, container = None): + + def anchored(self, c, container=None): """ Return a copy of the :class:`Bbox`, shifted to position *c* within a container. @@ -517,14 +556,14 @@ if container is None: container = self l, b, w, h = container.bounds - if isinstance(c, str): + if isinstance(c, basestring): cx, cy = self.coefs[c] else: cx, cy = c L, B, W, H = self.bounds return Bbox(self._points + - [(l + cx * (w-W)) - L, - (b + cy * (h-H)) - B]) + [(l + cx * (w - W)) - L, + (b + cy * (h - H)) - B]) def shrunk(self, mx, my): """ @@ -537,7 +576,7 @@ return Bbox([self._points[0], self._points[0] + [mx * w, my * h]]) - def shrunk_to_aspect(self, box_aspect, container = None, fig_aspect = 1.0): + def shrunk_to_aspect(self, box_aspect, container=None, fig_aspect=1.0): """ Return a copy of the :class:`Bbox`, shrunk so that it is as large as it can be while having the desired aspect ratio, @@ -551,11 +590,11 @@ if container is None: container = self w, h = container.size - H = w * box_aspect/fig_aspect + H = w * box_aspect / fig_aspect if H <= h: W = w else: - W = h * fig_aspect/box_aspect + W = h * fig_aspect / box_aspect H = h return Bbox([self._points[0], self._points[0] + (W, H)]) @@ -699,7 +738,7 @@ A mutable bounding box. """ - def __init__(self, points): + def __init__(self, points, **kwargs): """ *points*: a 2x2 numpy array of the form [[x0, y0], [x1, y1]] @@ -707,7 +746,7 @@ of data, consider the static methods :meth:`unit`, :meth:`from_bounds` and :meth:`from_extents`. """ - BboxBase.__init__(self) + BboxBase.__init__(self, **kwargs) self._points = np.asarray(points, np.float_) self._minpos = np.array([0.0000001, 0.0000001]) self._ignore = True @@ -717,15 +756,17 @@ self._points_orig = self._points.copy() if DEBUG: ___init__ = __init__ - def __init__(self, points): + + def __init__(self, points, **kwargs): self._check(points) - self.___init__(points) + self.___init__(points, **kwargs) def invalidate(self): self._check(self._points) TransformNode.invalidate(self) _unit_values = np.array([[0.0, 0.0], [1.0, 1.0]], np.float_) + @staticmethod def unit(): """ @@ -756,8 +797,7 @@ return Bbox(points) def __repr__(self): - return 'Bbox(%s)' % repr(self._points) - __str__ = __repr__ + return 'Bbox(%r)' % repr(self._points) def ignore(self, value): """ @@ -791,7 +831,9 @@ - when None, use the last value passed to :meth:`ignore`. """ warnings.warn( - "update_from_data requires a memory copy -- please replace with update_from_data_xy") + "update_from_data requires a memory copy -- please replace with " + "update_from_data_xy") + xy = np.hstack((x.reshape((len(x), 1)), y.reshape((len(y), 1)))) return self.update_from_data_xy(xy, ignore) @@ -811,6 +853,7 @@ *updatex*: when True, update the x values *updatey*: when True, update the y values + """ if ignore is None: ignore = self._ignore @@ -824,13 +867,12 @@ if changed: self.invalidate() if updatex: - self._points[:,0] = points[:,0] + self._points[:, 0] = points[:, 0] self._minpos[0] = minpos[0] if updatey: - self._points[:,1] = points[:,1] + self._points[:, 1] = points[:, 1] self._minpos[1] = minpos[1] - def update_from_data_xy(self, xy, ignore=None, updatex=True, updatey=True): """ Update the bounds of the :class:`Bbox` based on the passed in @@ -897,7 +939,7 @@ def _set_bounds(self, bounds): l, b, w, h = bounds - points = np.array([[l, b], [l+w, b+h]], np.float_) + points = np.array([[l, b], [l + w, b + h]], np.float_) if np.any(self._points != points): self._points = points self.invalidate() @@ -948,14 +990,13 @@ def mutatedx(self): 'return whether the x-limits have changed since init' - return (self._points[0,0]!=self._points_orig[0,0] or - self._points[1,0]!=self._points_orig[1,0]) + return (self._points[0, 0] != self._points_orig[0, 0] or + self._points[1, 0] != self._points_orig[1, 0]) + def mutatedy(self): 'return whether the y-limits have changed since init' - return (self._points[0,1]!=self._points_orig[0,1] or - self._points[1,1]!=self._points_orig[1,1]) - - + return (self._points[0, 1] != self._points_orig[0, 1] or + self._points[1, 1] != self._points_orig[1, 1]) class TransformedBbox(BboxBase): @@ -964,7 +1005,7 @@ transform. When either the child bounding box or transform changes, the bounds of this bbox will update accordingly. """ - def __init__(self, bbox, transform): + def __init__(self, bbox, transform, **kwargs): """ *bbox*: a child :class:`Bbox` @@ -975,15 +1016,14 @@ assert transform.input_dims == 2 assert transform.output_dims == 2 - BboxBase.__init__(self) + BboxBase.__init__(self, **kwargs) self._bbox = bbox self._transform = transform self.set_children(bbox, transform) self._points = None def __repr__(self): - return "TransformedBbox(%s, %s)" % (self._bbox, self._transform) - __str__ = __repr__ + return "TransformedBbox(%r, %r)" % (self._bbox, self._transform) def get_points(self): if self._invalid: @@ -996,11 +1036,13 @@ if DEBUG: _get_points = get_points + def get_points(self): points = self._get_points() self._check(points) return points + class Transform(TransformNode): """ The base class of all :class:`TransformNode` instances that @@ -1018,7 +1060,7 @@ - :meth:`transform` - :attr:`is_separable` - :attr:`has_inverse` - - :meth:`inverted` (if :meth:`has_inverse` can return True) + - :meth:`inverted` (if :attr:`has_inverse` is True) If the transform needs to do something non-standard with :class:`matplotlib.path.Path` objects, such as adding curves @@ -1026,21 +1068,23 @@ - :meth:`transform_path` """ - # The number of input and output dimensions for this transform. - # These must be overridden (with integers) in the subclass. input_dims = None + """ + The number of input dimensions of this transform. + Must be overridden (with integers) in the subclass. + """ + output_dims = None + """ + The number of output dimensions of this transform. + Must be overridden (with integers) in the subclass. + """ - # True if this transform as a corresponding inverse transform. has_inverse = False + """True if this transform has a corresponding inverse transform.""" - # True if this transform is separable in the x- and y- dimensions. is_separable = False - - #* Redundant: Removed for performance - # - # def __init__(self): - # TransformNode.__init__(self) + """True if this transform is separable in the x- and y- dimensions.""" def __add__(self, other): """ @@ -1062,11 +1106,127 @@ raise TypeError( "Can not add Transform to object of type '%s'" % type(other)) + def __eq__(self, other): + # equality is based on transform object id. Hence: + # Transform() != Transform(). + # Some classes, such as TransformWrapper & AffineBase, will override. + return self is other + + def _iter_break_from_left_to_right(self): + """ + Returns an iterator breaking down this transform stack from left to + right recursively. If self == ((A, N), A) then the result will be an + iterator which yields I : ((A, N), A), followed by A : (N, A), + followed by (A, N) : (A), but not ((A, N), A) : I. + + This is equivalent to flattening the stack then yielding + ``flat_stack[:i], flat_stack[i:]`` where i=0..(n-1). + + """ + yield IdentityTransform(), self + + @property + def depth(self): + """ + Returns the number of transforms which have been chained + together to form this Transform instance. + + .. note:: + + For the special case of a Composite transform, the maximum depth + of the two is returned. + + """ + return 1 + + def contains_branch(self, other): + """ + Return whether the given transform is a sub-tree of this transform. + + This routine uses transform equality to identify sub-trees, therefore + in many situations it is object id which will be used. + + For the case where the given transform represents the whole + of this transform, returns True. + + """ + if self.depth < other.depth: + return False + + # check that a subtree is equal to other (starting from self) + for _, sub_tree in self._iter_break_from_left_to_right(): + if sub_tree == other: + return True + return False + + def contains_branch_seperately(self, other_transform): + """ + Returns whether the given branch is a sub-tree of this transform on + each seperate dimension. + + A common use for this method is to identify if a transform is a blended + transform containing an axes' data transform. e.g.:: + + x_isdata, y_isdata = trans.contains_branch_seperately(ax.transData) + + """ + if self.output_dims != 2: + raise ValueError('contains_branch_seperately only supports ' + 'transforms with 2 output dimensions') + # for a non-blended transform each seperate dimension is the same, so + # just return the appropriate shape. + return [self.contains_branch(other_transform)] * 2 + + def __sub__(self, other): + """ + Returns a transform stack which goes all the way down self's transform + stack, and then ascends back up other's stack. If it can, this is + optimised:: + + # normally + A - B == a + b.inverted() + + # sometimes, when A contains the tree B there is no need to + # descend all the way down to the base of A (via B), instead we + # can just stop at B. + + (A + B) - (B)^-1 == A + + # similarly, when B contains tree A, we can avoid decending A at + # all, basically: + A - (A + B) == ((B + A) - A).inverted() or B^-1 + + For clarity, the result of ``(A + B) - B + B == (A + B)``. + + """ + # we only know how to do this operation if other is a Transform. + if not isinstance(other, Transform): + return NotImplemented + + for remainder, sub_tree in self._iter_break_from_left_to_right(): + if sub_tree == other: + return remainder + + for remainder, sub_tree in other._iter_break_from_left_to_right(): + if sub_tree == self: + if not remainder.has_inverse: + raise ValueError("The shortcut cannot be computed since " + "other's transform includes a non-invertable component.") + return remainder.inverted() + + # if we have got this far, then there was no shortcut possible + if other.has_inverse: + return self + other.inverted() + else: + raise ValueError('It is not possible to compute transA - transB ' + 'since transB cannot be inverted and there is no ' + 'shortcut possible.') + def __array__(self, *args, **kwargs): """ - Used by C/C++ -based backends to get at the array matrix data. + Array interface to get at this Transform's affine matrix. """ - raise NotImplementedError + return self.get_affine().get_matrix() def transform(self, values): """ @@ -1075,7 +1235,7 @@ Accepts a numpy array of shape (N x :attr:`input_dims`) and returns a numpy array of shape (N x :attr:`output_dims`). """ - raise NotImplementedError() + return self.transform_affine(self.transform_non_affine(values)) def transform_affine(self, values): """ @@ -1092,7 +1252,7 @@ Accepts a numpy array of shape (N x :attr:`input_dims`) and returns a numpy array of shape (N x :attr:`output_dims`). """ - return values + return self.get_affine().transform(values) def transform_non_affine(self, values): """ @@ -1108,7 +1268,7 @@ Accepts a numpy array of shape (N x :attr:`input_dims`) and returns a numpy array of shape (N x :attr:`output_dims`). """ - return self.transform(values) + return values def get_affine(self): """ @@ -1116,6 +1276,14 @@ """ return IdentityTransform() + def get_matrix(self): + """ + Get the Affine transformation array for the affine part + of this transform. + + """ + return self.get_affine().get_matrix() + def transform_point(self, point): """ A convenience function that returns the transformed copy of a @@ -1130,19 +1298,18 @@ def transform_path(self, path): """ - Returns a transformed copy of path. + Returns a transformed path. *path*: a :class:`~matplotlib.path.Path` instance. In some cases, this transform may insert curves into the path that began as line segments. """ - return Path(self.transform(path.vertices), path.codes, - path._interpolation_steps) + return self.transform_path_affine(self.transform_path_non_affine(path)) def transform_path_affine(self, path): """ - Returns a copy of path, transformed only by the affine part of + Returns a path, transformed only by the affine part of this transform. *path*: a :class:`~matplotlib.path.Path` instance. @@ -1150,11 +1317,11 @@ ``transform_path(path)`` is equivalent to ``transform_path_affine(transform_path_non_affine(values))``. """ - return path + return self.get_affine().transform_path_affine(path) def transform_path_non_affine(self, path): """ - Returns a copy of path, transformed only by the non-affine + Returns a path, transformed only by the non-affine part of this transform. *path*: a :class:`~matplotlib.path.Path` instance. @@ -1191,7 +1358,7 @@ close to *pts*, to find the angle in the transformed system. """ # Must be 2D - if self.input_dims <> 2 or self.output_dims <> 2: + if self.input_dims != 2 or self.output_dims != 2: raise NotImplementedError('Only defined in 2D') # pts must be array with 2 columns for x,y @@ -1206,15 +1373,15 @@ angles = angles / 180.0 * np.pi # Move a short distance away - pts2 = pts + pushoff * np.c_[ np.cos(angles), np.sin(angles) ] + pts2 = pts + pushoff * np.c_[np.cos(angles), np.sin(angles)] # Transform both sets of points - tpts = self.transform( pts ) - tpts2 = self.transform( pts2 ) + tpts = self.transform(pts) + tpts2 = self.transform(pts2) # Calculate transformed angles d = tpts2 - tpts - a = np.arctan2( d[:,1], d[:,0] ) + a = np.arctan2(d[:, 1], d[:, 0]) # Convert back to degrees if desired if not radians: @@ -1250,7 +1417,6 @@ of the same dimensions. """ pass_through = True - is_affine = False def __init__(self, child): """ @@ -1258,16 +1424,30 @@ be replaced with :meth:`set`. """ assert isinstance(child, Transform) - Transform.__init__(self) self.input_dims = child.input_dims self.output_dims = child.output_dims self._set(child) self._invalid = 0 + def __eq__(self, other): + return self._child.__eq__(other) + + if DEBUG: + + def __str__(self): + return str(self._child) + + def __getstate__(self): + # only store the child + return {'child': self._child} + + def __setstate__(self, state): + # re-initialise the TransformWrapper with the state's child + self.__init__(state['child']) + def __repr__(self): return "TransformWrapper(%r)" % self._child - __str__ = __repr__ def frozen(self): return self._child.frozen() @@ -1277,14 +1457,19 @@ self._child = child self.set_children(child) - self.transform = child.transform - self.transform_affine = child.transform_affine - self.transform_non_affine = child.transform_non_affine - self.transform_path = child.transform_path - self.transform_path_affine = child.transform_path_affine + self.transform = child.transform + self.transform_affine = child.transform_affine + self.transform_non_affine = child.transform_non_affine + self.transform_path = child.transform_path + self.transform_path_affine = child.transform_path_affine self.transform_path_non_affine = child.transform_path_non_affine - self.get_affine = child.get_affine - self.inverted = child.inverted + self.get_affine = child.get_affine + self.inverted = child.inverted + self.get_matrix = child.get_matrix + + # note we do not wrap other properties here since the transform's + # child can be changed with WrappedTransform.set and so checking + # is_affine and other such properties may be dangerous. def set(self, child): """ @@ -1302,6 +1487,10 @@ self.invalidate() self._invalid = 0 + def _get_is_affine(self): + return self._child.is_affine + is_affine = property(_get_is_affine) + def _get_is_separable(self): return self._child.is_separable is_separable = property(_get_is_separable) @@ -1318,11 +1507,12 @@ """ is_affine = True - def __init__(self): - Transform.__init__(self) + def __init__(self, *args, **kwargs): + Transform.__init__(self, *args, **kwargs) self._inverted = None def __array__(self, *args, **kwargs): + # optimises the access of the transform matrix vs the superclass return self.get_matrix() @staticmethod @@ -1333,18 +1523,31 @@ """ return np.dot(b, a) - def get_matrix(self): - """ - Get the underlying transformation matrix as a numpy array. - """ - raise NotImplementedError() + def __eq__(self, other): + if other.is_affine: + return np.all(self.get_matrix() == other.get_matrix()) + return NotImplemented + + def transform(self, values): + return self.transform_affine(values) + transform.__doc__ = Transform.transform.__doc__ + + def transform_affine(self, values): + raise NotImplementedError('Affine subclasses should override this ' + 'method.') + transform_affine.__doc__ = Transform.transform_affine.__doc__ def transform_non_affine(self, points): return points transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__ + def transform_path(self, path): + return self.transform_path_affine(path) + transform_path.__doc__ = Transform.transform_path.__doc__ + def transform_path_affine(self, path): - return self.transform_path(path) + return Path(self.transform_affine(path.vertices), + path.codes, path._interpolation_steps) transform_path_affine.__doc__ = Transform.transform_path_affine.__doc__ def transform_path_non_affine(self, path): @@ -1372,6 +1575,7 @@ Subclasses of this class will generally only need to override a constructor and :meth:`get_matrix` that generates a custom 3x3 matrix. """ + has_inverse = True input_dims = 2 output_dims = 2 @@ -1385,9 +1589,6 @@ return mtx[0, 1] == 0.0 and mtx[1, 0] == 0.0 is_separable = property(_get_is_separable) - def __array__(self, *args, **kwargs): - return self.get_matrix() - def to_values(self): """ Return the values of the matrix as a sequence (a,b,c,d,e,f) @@ -1407,7 +1608,7 @@ """ return np.array([[a, c, e], [b, d, f], [0.0, 0.0, 1.0]], np.float_) - def transform(self, points): + def transform_affine(self, points): mtx = self.get_matrix() if isinstance(points, MaskedArray): tpoints = affine_transform(points.data, mtx) @@ -1420,8 +1621,9 @@ transform_point.__doc__ = AffineBase.transform_point.__doc__ if DEBUG: - _transform = transform - def transform(self, points): + _transform_affine = transform_affine + + def transform_affine(self, points): # The major speed trap here is just converting to the # points to an array in the first place. If we can use # more arrays upstream, that should help here. @@ -1430,17 +1632,17 @@ warnings.warn( ('A non-numpy array of type %s was passed in for ' + 'transformation. Please correct this.') - % type(values)) - return self._transform(points) - transform.__doc__ = AffineBase.transform.__doc__ - - transform_affine = transform + % type(points)) + return self._transform_affine(points) transform_affine.__doc__ = AffineBase.transform_affine.__doc__ def inverted(self): if self._inverted is None or self._invalid: mtx = self.get_matrix() - self._inverted = Affine2D(inv(mtx)) + shorthand_name = None + if self._shorthand_name: + shorthand_name = '(%s)-1' % self._shorthand_name + self._inverted = Affine2D(inv(mtx), shorthand_name=shorthand_name) self._invalid = 0 return self._inverted inverted.__doc__ = AffineBase.inverted.__doc__ @@ -1451,7 +1653,7 @@ A mutable 2D affine transformation. """ - def __init__(self, matrix = None): + def __init__(self, matrix=None, **kwargs): """ Initialize an Affine transform from a 3x3 numpy float array:: @@ -1461,7 +1663,7 @@ If *matrix* is None, initialize with the identity transform. """ - Affine2DBase.__init__(self) + Affine2DBase.__init__(self, **kwargs) if matrix is None: matrix = np.identity(3) elif DEBUG: @@ -1472,13 +1674,13 @@ def __repr__(self): return "Affine2D(%s)" % repr(self._mtx) - __str__ = __repr__ - def __cmp__(self, other): - if (isinstance(other, Affine2D) and - (self.get_matrix() == other.get_matrix()).all()): - return 0 - return -1 +# def __cmp__(self, other): +# # XXX redundant. this only tells us eq. +# if (isinstance(other, Affine2D) and +# (self.get_matrix() == other.get_matrix()).all()): +# return 0 +# return -1 @staticmethod def from_values(a, b, c, d, e, f): @@ -1494,7 +1696,7 @@ """ return Affine2D( np.array([a, c, e, b, d, f, 0.0, 0.0, 1.0], np.float_) - .reshape((3,3))) + .reshape((3, 3))) def get_matrix(self): """ @@ -1575,7 +1777,7 @@ calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate` and :meth:`scale`. """ - return self.rotate(degrees*np.pi/180.) + return self.rotate(degrees * np.pi / 180.) def rotate_around(self, x, y, theta): """ @@ -1651,7 +1853,6 @@ def __repr__(self): return "IdentityTransform()" - __str__ = __repr__ def get_matrix(self): return self._mtx @@ -1698,7 +1899,7 @@ is_separable = True pass_through = True - def __init__(self, x_transform, y_transform): + def __init__(self, x_transform, y_transform, **kwargs): """ Create a new "blended" transform using *x_transform* to transform the *x*-axis and *y_transform* to transform the @@ -1711,57 +1912,73 @@ """ # Here we ask: "Does it blend?" - Transform.__init__(self) + Transform.__init__(self, **kwargs) self._x = x_transform self._y = y_transform self.set_children(x_transform, y_transform) self._affine = None + def __eq__(self, other): + # Note, this is an exact copy of BlendedAffine2D.__eq__ + if isinstance(other, (BlendedAffine2D, BlendedGenericTransform)): + return (self._x == other._x) and (self._y == other._y) + elif self._x == self._y: + return self._x == other + else: + return NotImplemented + + def contains_branch_seperately(self, transform): + # Note, this is an exact copy of BlendedAffine2D.contains_branch_seperately + return self._x.contains_branch(transform), self._y.contains_branch(transform) + + @property + def depth(self): + return max([self._x.depth, self._y.depth]) + + def contains_branch(self, other): + # a blended transform cannot possibly contain a branch from two different transforms. + return False + def _get_is_affine(self): return self._x.is_affine and self._y.is_affine is_affine = property(_get_is_affine) + def _get_has_inverse(self): + return self._x.has_inverse and self._y.has_inverse + has_inverse = property(_get_has_inverse) + def frozen(self): return blended_transform_factory(self._x.frozen(), self._y.frozen()) frozen.__doc__ = Transform.frozen.__doc__ def __repr__(self): return "BlendedGenericTransform(%s,%s)" % (self._x, self._y) - __str__ = __repr__ - def transform(self, points): + def transform_non_affine(self, points): + if self._x.is_affine and self._y.is_affine: + return points x = self._x y = self._y - if x is y and x.input_dims == 2: - return x.transform(points) + if x == y and x.input_dims == 2: + return x.transform_non_affine(points) if x.input_dims == 2: - x_points = x.transform(points)[:, 0:1] + x_points = x.transform_non_affine(points)[:, 0:1] else: - x_points = x.transform(points[:, 0]) + x_points = x.transform_non_affine(points[:, 0]) x_points = x_points.reshape((len(x_points), 1)) if y.input_dims == 2: - y_points = y.transform(points)[:, 1:] + y_points = y.transform_non_affine(points)[:, 1:] else: - y_points = y.transform(points[:, 1]) + y_points = y.transform_non_affine(points[:, 1]) y_points = y_points.reshape((len(y_points), 1)) if isinstance(x_points, MaskedArray) or isinstance(y_points, MaskedArray): return ma.concatenate((x_points, y_points), 1) else: return np.concatenate((x_points, y_points), 1) - transform.__doc__ = Transform.transform.__doc__ - - def transform_affine(self, points): - return self.get_affine().transform(points) - transform_affine.__doc__ = Transform.transform_affine.__doc__ - - def transform_non_affine(self, points): - if self._x.is_affine and self._y.is_affine: - return points - return self.transform(points) transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__ def inverted(self): @@ -1770,19 +1987,16 @@ def get_affine(self): if self._invalid or self._affine is None: - if self._x.is_affine and self._y.is_affine: - if self._x == self._y: - self._affine = self._x.get_affine() - else: - x_mtx = self._x.get_affine().get_matrix() - y_mtx = self._y.get_affine().get_matrix() - # This works because we already know the transforms are - # separable, though normally one would want to set b and - # c to zero. - mtx = np.vstack((x_mtx[0], y_mtx[1], [0.0, 0.0, 1.0])) - self._affine = Affine2D(mtx) + if self._x == self._y: + self._affine = self._x.get_affine() else: - self._affine = IdentityTransform() + x_mtx = self._x.get_affine().get_matrix() + y_mtx = self._y.get_affine().get_matrix() + # This works because we already know the transforms are + # separable, though normally one would want to set b and + # c to zero. + mtx = np.vstack((x_mtx[0], y_mtx[1], [0.0, 0.0, 1.0])) + self._affine = Affine2D(mtx) self._invalid = 0 return self._affine get_affine.__doc__ = Transform.get_affine.__doc__ @@ -1798,7 +2012,7 @@ """ is_separable = True - def __init__(self, x_transform, y_transform): + def __init__(self, x_transform, y_transform, **kwargs): """ Create a new "blended" transform using *x_transform* to transform the *x*-axis and *y_transform* to transform the @@ -1817,7 +2031,7 @@ assert x_transform.is_separable assert y_transform.is_separable - Transform.__init__(self) + Transform.__init__(self, **kwargs) self._x = x_transform self._y = y_transform self.set_children(x_transform, y_transform) @@ -1825,9 +2039,21 @@ Affine2DBase.__init__(self) self._mtx = None + def __eq__(self, other): + # Note, this is an exact copy of BlendedGenericTransform.__eq__ + if isinstance(other, (BlendedAffine2D, BlendedGenericTransform)): + return (self._x == other._x) and (self._y == other._y) + elif self._x == self._y: + return self._x == other + else: + return NotImplemented + + def contains_branch_seperately(self, transform): + # Note, this is an exact copy of BlendedTransform.contains_branch_seperately + return self._x.contains_branch(transform), self._y.contains_branch(transform) + def __repr__(self): return "BlendedAffine2D(%s,%s)" % (self._x, self._y) - __str__ = __repr__ def get_matrix(self): if self._invalid: @@ -1870,7 +2096,7 @@ """ pass_through = True - def __init__(self, a, b): + def __init__(self, a, b, **kwargs): """ Create a new composite transform that is the result of applying transform *a* then transform *b*. @@ -1884,11 +2110,13 @@ self.input_dims = a.input_dims self.output_dims = b.output_dims - Transform.__init__(self) + Transform.__init__(self, **kwargs) self._a = a self._b = b self.set_children(a, b) + is_affine = property(lambda self: self._a.is_affine and self._b.is_affine) + def frozen(self): self._invalid = 0 frozen = composite_transform_factory(self._a.frozen(), self._b.frozen()) @@ -1897,6 +2125,37 @@ return frozen frozen.__doc__ = Transform.frozen.__doc__ + def _invalidate_internal(self, value, invalidating_node): + # In some cases for a composite transform, an invalidating call to AFFINE_ONLY needs + # to be extended to invalidate the NON_AFFINE part too. These cases are when the right + # hand transform is non-affine and either: + # (a) the left hand transform is non affine + # (b) it is the left hand node which has triggered the invalidation + if value == Transform.INVALID_AFFINE \ + and not self._b.is_affine \ + and (not self._a.is_affine or invalidating_node is self._a): + + value = Transform.INVALID + + Transform._invalidate_internal(self, value=value, + invalidating_node=invalidating_node) + + def __eq__(self, other): + if isinstance(other, (CompositeGenericTransform, CompositeAffine2D)): + return self is other or (self._a == other._a and self._b == other._b) + else: + return False + + def _iter_break_from_left_to_right(self): + for lh_compliment, rh_compliment in self._a._iter_break_from_left_to_right(): + yield lh_compliment, rh_compliment + self._b + for lh_compliment, rh_compliment in self._b._iter_break_from_left_to_right(): + yield self._a + lh_compliment, rh_compliment + + @property + def depth(self): + return self._a.depth + self._b.depth + def _get_is_affine(self): return self._a.is_affine and self._b.is_affine is_affine = property(_get_is_affine) @@ -1905,14 +2164,12 @@ return self._a.is_separable and self._b.is_separable is_separable = property(_get_is_separable) - def __repr__(self): - return "CompositeGenericTransform(%s, %s)" % (self._a, self._b) - __str__ = __repr__ + if DEBUG: + def __str__(self): + return '(%s, %s)' % (self._a, self._b) - def transform(self, points): - return self._b.transform( - self._a.transform(points)) - transform.__doc__ = Transform.transform.__doc__ + def __repr__(self): + return "CompositeGenericTransform(%r, %r)" % (self._a, self._b) def transform_affine(self, points): return self.get_affine().transform(points) @@ -1921,39 +2178,39 @@ def transform_non_affine(self, points): if self._a.is_affine and self._b.is_affine: return points - return self._b.transform_non_affine( - self._a.transform(points)) + elif not self._a.is_affine and self._b.is_affine: + return self._a.transform_non_affine(points) + else: + return self._b.transform_non_affine( + self._a.transform(points)) transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__ - def transform_path(self, path): - return self._b.transform_path( - self._a.transform_path(path)) - transform_path.__doc__ = Transform.transform_path.__doc__ - - def transform_path_affine(self, path): - return self._b.transform_path_affine( - self._a.transform_path(path)) - transform_path_affine.__doc__ = Transform.transform_path_affine.__doc__ - def transform_path_non_affine(self, path): if self._a.is_affine and self._b.is_affine: return path - return self._b.transform_path_non_affine( - self._a.transform_path(path)) + elif not self._a.is_affine and self._b.is_affine: + return self._a.transform_path_non_affine(path) + else: + return self._b.transform_path_non_affine( + self._a.transform_path(path)) transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__ def get_affine(self): - if self._a.is_affine and self._b.is_affine: - return Affine2D(np.dot(self._b.get_affine().get_matrix(), - self._a.get_affine().get_matrix())) - else: + if not self._b.is_affine: return self._b.get_affine() + else: + return Affine2D(np.dot(self._b.get_affine().get_matrix(), + self._a.get_affine().get_matrix())) get_affine.__doc__ = Transform.get_affine.__doc__ def inverted(self): return CompositeGenericTransform(self._b.inverted(), self._a.inverted()) inverted.__doc__ = Transform.inverted.__doc__ + def _get_has_inverse(self): + return self._a.has_inverse and self._b.has_inverse + has_inverse = property(_get_has_inverse) + class CompositeAffine2D(Affine2DBase): """ @@ -1962,7 +2219,7 @@ This version is an optimization that handles the case where both *a* and *b* are 2D affines. """ - def __init__(self, a, b): + def __init__(self, a, b, **kwargs): """ Create a new composite transform that is the result of applying transform *a* then transform *b*. @@ -1980,15 +2237,28 @@ assert a.is_affine assert b.is_affine - Affine2DBase.__init__(self) + Affine2DBase.__init__(self, **kwargs) self._a = a self._b = b self.set_children(a, b) self._mtx = None + if DEBUG: + def __str__(self): + return '(%s, %s)' % (self._a, self._b) + + @property + def depth(self): + return self._a.depth + self._b.depth + + def _iter_break_from_left_to_right(self): + for lh_compliment, rh_compliment in self._a._iter_break_from_left_to_right(): + yield lh_compliment, rh_compliment + self._b + for lh_compliment, rh_compliment in self._b._iter_break_from_left_to_right(): + yield self._a + lh_compliment, rh_compliment + def __repr__(self): - return "CompositeAffine2D(%s, %s)" % (self._a, self._b) - __str__ = __repr__ + return "CompositeAffine2D(%r, %r)" % (self._a, self._b) def get_matrix(self): if self._invalid: @@ -2015,11 +2285,15 @@ c = a + b """ + # check to see if any of a or b are IdentityTransforms. We use + # isinstance here to guarantee that the transforms will *always* + # be IdentityTransforms. Since TransformWrappers are mutable, + # use of equality here would be wrong. if isinstance(a, IdentityTransform): return b elif isinstance(b, IdentityTransform): return a - elif isinstance(a, AffineBase) and isinstance(b, AffineBase): + elif isinstance(a, Affine2D) and isinstance(b, Affine2D): return CompositeAffine2D(a, b) return CompositeGenericTransform(a, b) @@ -2031,7 +2305,7 @@ """ is_separable = True - def __init__(self, boxin, boxout): + def __init__(self, boxin, boxout, **kwargs): """ Create a new :class:`BboxTransform` that linearly transforms points from *boxin* to *boxout*. @@ -2039,7 +2313,7 @@ assert boxin.is_bbox assert boxout.is_bbox - Affine2DBase.__init__(self) + Affine2DBase.__init__(self, **kwargs) self._boxin = boxin self._boxout = boxout self.set_children(boxin, boxout) @@ -2047,8 +2321,7 @@ self._inverted = None def __repr__(self): - return "BboxTransform(%s, %s)" % (self._boxin, self._boxout) - __str__ = __repr__ + return "BboxTransform(%r, %r)" % (self._boxin, self._boxout) def get_matrix(self): if self._invalid: @@ -2076,22 +2349,21 @@ """ is_separable = True - def __init__(self, boxout): + def __init__(self, boxout, **kwargs): """ Create a new :class:`BboxTransformTo` that linearly transforms points from the unit bounding box to *boxout*. """ assert boxout.is_bbox - Affine2DBase.__init__(self) + Affine2DBase.__init__(self, **kwargs) self._boxout = boxout self.set_children(boxout) self._mtx = None self._inverted = None def __repr__(self): - return "BboxTransformTo(%s)" % (self._boxout) - __str__ = __repr__ + return "BboxTransformTo(%r)" % (self._boxout) def get_matrix(self): if self._invalid: @@ -2115,8 +2387,7 @@ :class:`Bbox` with a fixed upper left of (0, 0). """ def __repr__(self): - return "BboxTransformToMaxOnly(%s)" % (self._boxout) - __str__ = __repr__ + return "BboxTransformToMaxOnly(%r)" % (self._boxout) def get_matrix(self): if self._invalid: @@ -2140,18 +2411,17 @@ """ is_separable = True - def __init__(self, boxin): + def __init__(self, boxin, **kwargs): assert boxin.is_bbox - Affine2DBase.__init__(self) + Affine2DBase.__init__(self, **kwargs) self._boxin = boxin self.set_children(boxin) self._mtx = None self._inverted = None def __repr__(self): - return "BboxTransformFrom(%s)" % (self._boxin) - __str__ = __repr__ + return "BboxTransformFrom(%r)" % (self._boxin) def get_matrix(self): if self._invalid: @@ -2175,8 +2445,8 @@ A transformation that translates by *xt* and *yt*, after *xt* and *yt* have been transformad by the given transform *scale_trans*. """ - def __init__(self, xt, yt, scale_trans): - Affine2DBase.__init__(self) + def __init__(self, xt, yt, scale_trans, **kwargs): + Affine2DBase.__init__(self, **kwargs) self._t = (xt, yt) self._scale_trans = scale_trans self.set_children(scale_trans) @@ -2184,8 +2454,7 @@ self._inverted = None def __repr__(self): - return "ScaledTranslation(%s)" % (self._t,) - __str__ = __repr__ + return "ScaledTranslation(%r)" % (self._t,) def get_matrix(self): if self._invalid: @@ -2228,6 +2497,7 @@ self._transformed_points = None def _revalidate(self): + # only recompute if the invalidation includes the non_affine part of the transform if ((self._invalid & self.INVALID_NON_AFFINE == self.INVALID_NON_AFFINE) or self._transformed_path is None): self._transformed_path = \ @@ -2261,11 +2531,7 @@ """ Return a fully-transformed copy of the child path. """ - if ((self._invalid & self.INVALID_NON_AFFINE == self.INVALID_NON_AFFINE) - or self._transformed_path is None): - self._transformed_path = \ - self._transform.transform_path_non_affine(self._path) - self._invalid = 0 + self._revalidate() return self._transform.transform_path_affine(self._transformed_path) def get_affine(self): @@ -2274,16 +2540,29 @@ def nonsingular(vmin, vmax, expander=0.001, tiny=1e-15, increasing=True): ''' - Ensure the endpoints of a range are finite and not too close together. + Modify the endpoints of a range as needed to avoid singularities. + + *vmin*, *vmax* + the initial endpoints. + + *tiny* + threshold for the ratio of the interval to the maximum absolute + value of its endpoints. If the interval is smaller than + this, it will be expanded. This value should be around + 1e-15 or larger; otherwise the interval will be approaching + the double precision resolution limit. + + *expander* + fractional amount by which *vmin* and *vmax* are expanded if + the original interval is too small, based on *tiny*. - "too close" means the interval is smaller than 'tiny' times - the maximum absolute value. + *increasing*: [True | False] + If True (default), swap *vmin*, *vmax* if *vmin* > *vmax* - If they are too close, each will be moved by the 'expander'. - If 'increasing' is True and vmin > vmax, they will be swapped, - regardless of whether they are too close. + Returns *vmin*, *vmax*, expanded and/or swapped if necessary. - If either is inf or -inf or nan, return - expander, expander. + If either input is inf or NaN, or if both inputs are 0, + returns -*expander*, *expander*. ''' if (not np.isfinite(vmin)) or (not np.isfinite(vmax)): return -expander, expander @@ -2292,7 +2571,7 @@ vmin, vmax = vmax, vmin swapped = True if vmax - vmin <= max(abs(vmin), abs(vmax)) * tiny: - if vmin == 0.0: + if vmax == 0 and vmin == 0: vmin = -expander vmax = expander else: diff -Nru matplotlib-1.1.1/lib/matplotlib/tri/__init__.py matplotlib-1.2.0/lib/matplotlib/tri/__init__.py --- matplotlib-1.1.1/lib/matplotlib/tri/__init__.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tri/__init__.py 2012-10-31 00:11:14.000000000 +0000 @@ -2,6 +2,7 @@ Unstructured triangular grid functions. """ +from __future__ import print_function from triangulation import * from tricontour import * from tripcolor import * diff -Nru matplotlib-1.1.1/lib/matplotlib/tri/_tri.cpp matplotlib-1.2.0/lib/matplotlib/tri/_tri.cpp --- matplotlib-1.1.1/lib/matplotlib/tri/_tri.cpp 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tri/_tri.cpp 2012-11-08 13:38:03.000000000 +0000 @@ -980,19 +980,22 @@ - -#if defined(_MSC_VER) -DL_EXPORT(void) -#elif defined(__cplusplus) -extern "C" void +#if PY_MAJOR_VERSION >= 3 +PyMODINIT_FUNC +PyInit__tri(void) #else -void +PyMODINIT_FUNC +init_tri(void) #endif -init_tri() { + import_array(); + static TriModule* triModule = NULL; triModule = new TriModule(); - import_array(); + + #if PY_MAJOR_VERSION >= 3 + return triModule->module().ptr(); + #endif } TriModule::TriModule() diff -Nru matplotlib-1.1.1/lib/matplotlib/tri/triangulation.py matplotlib-1.2.0/lib/matplotlib/tri/triangulation.py --- matplotlib-1.1.1/lib/matplotlib/tri/triangulation.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tri/triangulation.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import matplotlib.delaunay as delaunay import matplotlib._tri as _tri import numpy as np diff -Nru matplotlib-1.1.1/lib/matplotlib/tri/tricontour.py matplotlib-1.2.0/lib/matplotlib/tri/tricontour.py --- matplotlib-1.1.1/lib/matplotlib/tri/tricontour.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tri/tricontour.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function from matplotlib.contour import ContourSet from matplotlib.tri.triangulation import Triangulation import matplotlib._tri as _tri @@ -91,10 +92,10 @@ return (tri, z) tricontour_doc = """ + Draw contours on an unstructured triangular grid. :func:`~matplotlib.pyplot.tricontour` and :func:`~matplotlib.pyplot.tricontourf` draw contour lines and - filled contours, respectively, on an unstructured triangular - grid. Except as noted, function + filled contours, respectively. Except as noted, function signatures and return values are the same for both versions. The triangulation can be specified in one of two ways; either:: diff -Nru matplotlib-1.1.1/lib/matplotlib/tri/tripcolor.py matplotlib-1.2.0/lib/matplotlib/tri/tripcolor.py --- matplotlib-1.1.1/lib/matplotlib/tri/tripcolor.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tri/tripcolor.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,12 +1,12 @@ -from matplotlib.collections import PolyCollection +from __future__ import print_function +from matplotlib.collections import PolyCollection, TriMesh from matplotlib.colors import Normalize from matplotlib.tri.triangulation import Triangulation import numpy as np def tripcolor(ax, *args, **kwargs): """ - Create a pseudocolor plot of an unstructured triangular grid to - the :class:`~matplotlib.axes.Axes`. + Create a pseudocolor plot of an unstructured triangular grid. The triangulation can be specified in one of two ways; either:: @@ -27,9 +27,20 @@ :class:`~matplotlib.tri.Triangulation` for a explanation of these possibilities. - The next argument must be *C*, the array of color values, one per - point in the triangulation. The colors used for each triangle - are from the mean C of the triangle's three points. + The next argument must be *C*, the array of color values, either + one per point in the triangulation if color values are defined at + points, or one per triangle in the triangulation if color values + are defined at triangles. If there are the same number of points + and triangles in the triangulation it is assumed that color + values are defined at points; to force the use of color values at + triangles use the kwarg *facecolors*=C instead of just *C*. + + *shading* may be 'flat' (the default) or 'gouraud'. If *shading* + is 'flat' and C values are defined at points, the color values + used for each triangle are from the mean C of the triangle's + three points. If *shading* is 'gouraud' then color values must be + defined at points. *shading* of 'faceted' is deprecated; + please use *edgecolors* instead. The remaining kwargs are the same as for :meth:`~matplotlib.axes.Axes.pcolor`. @@ -46,35 +57,79 @@ vmin = kwargs.pop('vmin', None) vmax = kwargs.pop('vmax', None) shading = kwargs.pop('shading', 'flat') + facecolors = kwargs.pop('facecolors', None) tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args, **kwargs) - x = tri.x - y = tri.y - triangles = tri.get_masked_triangles() - - # Vertices of triangles. - verts = np.concatenate((x[triangles][...,np.newaxis], - y[triangles][...,np.newaxis]), axis=2) - - C = np.asarray(args[0]) - if C.shape != x.shape: - raise ValueError('C array must have same length as triangulation x and' - ' y arrays') - - # Color values, one per triangle, mean of the 3 vertex color values. - C = C[triangles].mean(axis=1) - - if shading == 'faceted': - edgecolors = (0,0,0,1), - linewidths = (0.25,) + + # C is the colors array, defined at either points or faces (i.e. triangles). + # If facecolors is None, C are defined at points. + # If facecolors is not None, C are defined at faces. + if facecolors is not None: + C = facecolors else: - edgecolors = 'face' - linewidths = (1.0,) - kwargs.setdefault('edgecolors', edgecolors) - kwargs.setdefault('antialiaseds', (0,)) + C = np.asarray(args[0]) + + # If there are a different number of points and triangles in the + # triangulation, can omit facecolors kwarg as it is obvious from + # length of C whether it refers to points or faces. + # Do not do this for gouraud shading. + if (facecolors is None and len(C) == len(tri.triangles) and + len(C) != len(tri.x) and shading != 'gouraud'): + facecolors = C + + # Check length of C is OK. + if ( (facecolors is None and len(C) != len(tri.x)) or + (facecolors is not None and len(C) != len(tri.triangles)) ): + raise ValueError('Length of color values array must be the same ' + 'as either the number of triangulation points ' + 'or triangles') + + + # Handling of linewidths, shading, edgecolors and antialiased as + # in Axes.pcolor + linewidths = (0.25,) + if 'linewidth' in kwargs: + kwargs['linewidths'] = kwargs.pop('linewidth') kwargs.setdefault('linewidths', linewidths) - collection = PolyCollection(verts, **kwargs) + if shading == 'faceted': # Deprecated. + edgecolors = 'k' + else: + edgecolors = 'none' + if 'edgecolor' in kwargs: + kwargs['edgecolors'] = kwargs.pop('edgecolor') + ec = kwargs.setdefault('edgecolors', edgecolors) + + if 'antialiased' in kwargs: + kwargs['antialiaseds'] = kwargs.pop('antialiased') + if 'antialiaseds' not in kwargs and ec.lower() == "none": + kwargs['antialiaseds'] = False + + + if shading == 'gouraud': + if facecolors is not None: + raise ValueError('Gouraud shading does not support the use ' + 'of facecolors kwarg') + if len(C) != len(tri.x): + raise ValueError('For gouraud shading, the length of color ' + 'values array must be the same as the ' + 'number of triangulation points') + collection = TriMesh(tri, **kwargs) + else: + # Vertices of triangles. + maskedTris = tri.get_masked_triangles() + verts = np.concatenate((tri.x[maskedTris][...,np.newaxis], + tri.y[maskedTris][...,np.newaxis]), axis=2) + + # Color values. + if facecolors is None: + # One color per triangle, the mean of the 3 vertex color values. + C = C[maskedTris].mean(axis=1) + elif tri.mask is not None: + # Remove color values of masked triangles. + C = C.compress(1-tri.mask) + + collection = PolyCollection(verts, **kwargs) collection.set_alpha(alpha) collection.set_array(C) diff -Nru matplotlib-1.1.1/lib/matplotlib/tri/triplot.py matplotlib-1.2.0/lib/matplotlib/tri/triplot.py --- matplotlib-1.1.1/lib/matplotlib/tri/triplot.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/tri/triplot.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function from matplotlib.cbook import ls_mapper from matplotlib.patches import PathPatch from matplotlib.path import Path @@ -6,8 +7,7 @@ def triplot(ax, *args, **kwargs): """ - Draw a unstructured triangular grid as lines and/or markers to - the :class:`~matplotlib.axes.Axes`. + Draw a unstructured triangular grid as lines and/or markers. The triangulation to plot can be specified in one of two ways; either:: diff -Nru matplotlib-1.1.1/lib/matplotlib/type1font.py matplotlib-1.2.0/lib/matplotlib/type1font.py --- matplotlib-1.1.1/lib/matplotlib/type1font.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/type1font.py 2012-11-06 15:42:20.000000000 +0000 @@ -22,12 +22,19 @@ v1.1, 1993. ISBN 0-201-57044-0. """ +from __future__ import print_function import matplotlib.cbook as cbook -import cStringIO +import io import itertools import numpy as np import re import struct +import sys + +if sys.version_info[0] >= 3: + def ord(x): + return x + class Type1Font(object): """ @@ -52,13 +59,10 @@ if isinstance(input, tuple) and len(input) == 3: self.parts = input else: - file = open(input, 'rb') - try: + with open(input, 'rb') as file: data = self._read(file) - finally: - file.close() self.parts = self._split(data) - + self._parse() def _read(self, file): @@ -66,31 +70,30 @@ Read the font from a file, decoding into usable parts. """ rawdata = file.read() - if not rawdata.startswith(chr(128)): + if not rawdata.startswith(b'\x80'): return rawdata - data = '' + data = b'' while len(rawdata) > 0: - if not rawdata.startswith(chr(128)): - raise RuntimeError, \ - 'Broken pfb file (expected byte 128, got %d)' % \ - ord(rawdata[0]) + if not rawdata.startswith(b'\x80'): + raise RuntimeError('Broken pfb file (expected byte 128, ' + 'got %d)' % ord(rawdata[0])) type = ord(rawdata[1]) - if type in (1,2): + if type in (1, 2): length, = struct.unpack('{}/%[]+') - _comment = re.compile(r'%[^\r\n\v]*') - _instring = re.compile(r'[()\\]') + _whitespace = re.compile(br'[\0\t\r\014\n ]+') + _token = re.compile(br'/{0,2}[^]\0\t\r\v\n ()<>{}/%[]+') + _comment = re.compile(br'%[^\r\n\v]*') + _instring = re.compile(br'[()\\]') + @classmethod def _tokens(cls, text): """ @@ -144,7 +149,8 @@ """ pos = 0 while pos < len(text): - match = cls._comment.match(text[pos:]) or cls._whitespace.match(text[pos:]) + match = (cls._comment.match(text[pos:]) or + cls._whitespace.match(text[pos:])) if match: yield ('whitespace', match.group()) pos += match.end() @@ -154,17 +160,18 @@ depth = 1 while depth: match = cls._instring.search(text[pos:]) - if match is None: return + if match is None: + return pos += match.end() if match.group() == '(': depth += 1 elif match.group() == ')': depth -= 1 - else: # a backslash - skip the next character + else: # a backslash - skip the next character pos += 1 yield ('string', text[start:pos]) - elif text[pos:pos+2] in ('<<', '>>'): - yield ('delimiter', text[pos:pos+2]) + elif text[pos:pos + 2] in ('<<', '>>'): + yield ('delimiter', text[pos:pos + 2]) pos += 2 elif text[pos] == '<': start = pos @@ -190,80 +197,86 @@ Compatibility" of the Type-1 spec. """ # Start with reasonable defaults - prop = { 'weight': 'Regular', 'ItalicAngle': 0.0, 'isFixedPitch': False, - 'UnderlinePosition': -100, 'UnderlineThickness': 50 } + prop = {'weight': 'Regular', 'ItalicAngle': 0.0, 'isFixedPitch': False, + 'UnderlinePosition': -100, 'UnderlineThickness': 50} tokenizer = self._tokens(self.parts[0]) filtered = itertools.ifilter(lambda x: x[0] != 'whitespace', tokenizer) for token, value in filtered: - if token == 'name' and value.startswith('/'): + if token == b'name' and value.startswith(b'/'): key = value[1:] - token, value = filtered.next() - if token == 'name': - if value in ('true', 'false'): - value = value == 'true' + token, value = next(filtered) + if token == b'name': + if value in (b'true', b'false'): + value = value == b'true' + else: + value = value.lstrip(b'/') + elif token == b'string': + value = value.lstrip(b'(').rstrip(b')') + elif token == b'number': + if b'.' in value: + value = float(value) else: - value = value.lstrip('/') - elif token == 'string': - value = value.lstrip('(').rstrip(')') - elif token == 'number': - if '.' in value: value = float(value) - else: value = int(value) - else: # more complicated value such as an array + value = int(value) + else: # more complicated value such as an array value = None - if key != 'FontInfo' and value is not None: + if key != b'FontInfo' and value is not None: prop[key] = value # Fill in the various *Name properties - if not prop.has_key('FontName'): - prop['FontName'] = prop.get('FullName') or prop.get('FamilyName') or 'Unknown' - if not prop.has_key('FullName'): + if 'FontName' not in prop: + prop['FontName'] = (prop.get('FullName') or + prop.get('FamilyName') or + 'Unknown') + if 'FullName' not in prop: prop['FullName'] = prop['FontName'] - if not prop.has_key('FamilyName'): + if 'FamilyName' not in prop: extras = r'(?i)([ -](regular|plain|italic|oblique|(semi)?bold|(ultra)?light|extra|condensed))+$' prop['FamilyName'] = re.sub(extras, '', prop['FullName']) - + self.prop = prop - + @classmethod def _transformer(cls, tokens, slant, extend): def fontname(name): result = name - if slant: result += '_Slant_' + str(int(1000*slant)) - if extend != 1.0: result += '_Extend_' + str(int(1000*extend)) + if slant: + result += '_Slant_' + str(int(1000 * slant)) + if extend != 1.0: + result += '_Extend_' + str(int(1000 * extend)) return result def italicangle(angle): - return str(float(angle) - np.arctan(slant)/np.pi*180) + return str(float(angle) - np.arctan(slant) / np.pi * 180) def fontmatrix(array): array = array.lstrip('[').rstrip(']').strip().split() - array = [ float(x) for x in array ] - oldmatrix = np.eye(3,3) - oldmatrix[0:3,0] = array[::2] - oldmatrix[0:3,1] = array[1::2] + array = [float(x) for x in array] + oldmatrix = np.eye(3, 3) + oldmatrix[0:3, 0] = array[::2] + oldmatrix[0:3, 1] = array[1::2] modifier = np.array([[extend, 0, 0], [slant, 1, 0], [0, 0, 1]]) newmatrix = np.dot(modifier, oldmatrix) - array[::2] = newmatrix[0:3,0] - array[1::2] = newmatrix[0:3,1] + array[::2] = newmatrix[0:3, 0] + array[1::2] = newmatrix[0:3, 1] return '[' + ' '.join(str(x) for x in array) + ']' def replace(fun): def replacer(tokens): - token, value = tokens.next() # name, e.g. /FontMatrix + token, value = next(tokens) # name, e.g. /FontMatrix yield value - token, value = tokens.next() # possible whitespace + token, value = next(tokens) # possible whitespace while token == 'whitespace': yield value - token, value = tokens.next() + token, value = next(tokens) if value != '[': # name/number/etc. yield fun(value) else: # array, e.g. [1 2 3] array = [] while value != ']': array += value - token, value = tokens.next() + token, value = next(tokens) array += value yield fun(''.join(array)) return replacer @@ -272,20 +285,21 @@ for x in itertools.takewhile(lambda x: x[1] != 'def', tokens): pass yield '' - - table = { '/FontName': replace(fontname), - '/ItalicAngle': replace(italicangle), - '/FontMatrix': replace(fontmatrix), - '/UniqueID': suppress } + + table = {'/FontName': replace(fontname), + '/ItalicAngle': replace(italicangle), + '/FontMatrix': replace(fontmatrix), + '/UniqueID': suppress} while True: - token, value = tokens.next() + token, value = next(tokens) if token == 'name' and value in table: - for value in table[value](itertools.chain([(token, value)], tokens)): + for value in table[value](itertools.chain([(token, value)], + tokens)): yield value else: yield value - + def transform(self, effects): """ Transform the font by slanting or extending. *effects* should @@ -295,15 +309,17 @@ multiplier by which the font is to be extended (so values less than 1.0 condense). Returns a new :class:`Type1Font` object. """ - - buffer = cStringIO.StringIO() - tokenizer = self._tokens(self.parts[0]) - for value in self._transformer(tokenizer, - slant=effects.get('slant', 0.0), - extend=effects.get('extend', 1.0)): - buffer.write(value) - result = buffer.getvalue() - buffer.close() + buffer = io.BytesIO() + try: + tokenizer = self._tokens(self.parts[0]) + for value in self._transformer(tokenizer, + slant=effects.get('slant', 0.0), + extend=effects.get('extend', 1.0)): + if sys.version_info[0] >= 3 and isinstance(value, int): + value = chr(value).encode('latin-1') + buffer.write(value) + result = buffer.getvalue() + finally: + buffer.close() return Type1Font((result, self.parts[1], self.parts[2])) - diff -Nru matplotlib-1.1.1/lib/matplotlib/units.py matplotlib-1.2.0/lib/matplotlib/units.py --- matplotlib-1.1.1/lib/matplotlib/units.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/units.py 2012-11-08 13:38:03.000000000 +0000 @@ -42,6 +42,7 @@ units.registry[datetime.date] = DateConverter() """ +from __future__ import print_function import numpy as np from matplotlib.cbook import iterable, is_numlike, is_string_like diff -Nru matplotlib-1.1.1/lib/matplotlib/widgets.py matplotlib-1.2.0/lib/matplotlib/widgets.py --- matplotlib-1.1.1/lib/matplotlib/widgets.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/matplotlib/widgets.py 2012-10-31 00:11:14.000000000 +0000 @@ -9,6 +9,7 @@ wide and tall you want your Axes to be to accommodate your widget. """ +from __future__ import print_function import numpy as np from mlab import dist @@ -19,7 +20,7 @@ class LockDraw: """ Some widgets, like the cursor, draw onto the canvas, and this is not - desirable under all circumstaces, like when the toolbar is in + desirable under all circumstances, like when the toolbar is in zoom-to-rect mode and drawing a rectangle. The module level "lock" allows someone to grab the lock and prevent other widgets from drawing. Use ``matplotlib.widgets.lock(someobj)`` to pr @@ -54,7 +55,6 @@ return self._owner is not None - class Widget(object): """ Abstract base class for GUI neutral widgets @@ -63,13 +63,52 @@ eventson = True +class AxesWidget(Widget): + """Widget that is connected to a single :class:`~matplotlib.axes.Axes`. + Attributes: -class Button(Widget): + *ax* : :class:`~matplotlib.axes.Axes` + The parent axes for the widget + *canvas* : :class:`~matplotlib.backend_bases.FigureCanvasBase` subclass + The parent figure canvas for the widget. + *active* : bool + If False, the widget does not respond to events. + """ + def __init__(self, ax): + self.ax = ax + self.canvas = ax.figure.canvas + self.cids = [] + self.active = True + + def connect_event(self, event, callback): + """Connect callback with an event. + + This should be used in lieu of `figure.canvas.mpl_connect` since this + function stores call back ids for later clean up. + """ + cid = self.canvas.mpl_connect(event, callback) + self.cids.append(cid) + + def disconnect_events(self): + """Disconnect all events created by this widget.""" + for c in self.cids: + self.canvas.mpl_disconnect(c) + + def ignore(self, event): + """Return True if event should be ignored. + + This method (or a version of it) should be called at the beginning + of any event callback. + """ + return not self.active + + +class Button(AxesWidget): """ A GUI neutral button - The following attributes are accesible + The following attributes are accessible *ax* The :class:`matplotlib.axes.Axes` the button renders into. @@ -107,6 +146,8 @@ *hovercolor* The color of the button when the mouse is over it """ + AxesWidget.__init__(self, ax) + if image is not None: ax.imshow(image) self.label = ax.text(0.5, 0.5, label, @@ -116,12 +157,10 @@ self.cnt = 0 self.observers = {} - self.ax = ax - - ax.figure.canvas.mpl_connect('button_press_event', self._click) - ax.figure.canvas.mpl_connect('button_release_event', self._release) - ax.figure.canvas.mpl_connect('motion_notify_event', self._motion) + self.connect_event('button_press_event', self._click) + self.connect_event('button_release_event', self._release) + self.connect_event('motion_notify_event', self._motion) ax.set_navigate(False) ax.set_axis_bgcolor(color) ax.set_xticks([]) @@ -132,6 +171,8 @@ self._lastcolor = color def _click(self, event): + if self.ignore(event): + return if event.inaxes != self.ax: return if not self.eventson: @@ -140,6 +181,8 @@ event.canvas.grab_mouse(self.ax) def _release(self, event): + if self.ignore(event): + return if event.canvas.mouse_grabber != self.ax: return event.canvas.release_mouse(self.ax) @@ -147,10 +190,12 @@ return if event.inaxes != self.ax: return - for cid, func in self.observers.items(): + for cid, func in self.observers.iteritems(): func(event) def _motion(self, event): + if self.ignore(event): + return if event.inaxes==self.ax: c = self.hovercolor else: @@ -178,7 +223,7 @@ -class Slider(Widget): +class Slider(AxesWidget): """ A slider representing a floating point range @@ -231,7 +276,7 @@ Indicate whether the slider interval is closed *slidermin* and *slidermax* - Used to contrain the value of this slider to the values + Used to constrain the value of this slider to the values of other sliders. additional kwargs are passed on to ``self.poly`` which is the @@ -239,7 +284,7 @@ knob. See the :class:`matplotlib.patches.Rectangle` documentation valid property names (e.g., *facecolor*, *edgecolor*, *alpha*, ...) """ - self.ax = ax + AxesWidget.__init__(self, ax) self.valmin = valmin self.valmax = valmax @@ -256,10 +301,10 @@ ax.set_xticks([]) ax.set_navigate(False) - ax.figure.canvas.mpl_connect('button_press_event', self._update) - ax.figure.canvas.mpl_connect('button_release_event', self._update) + self.connect_event('button_press_event', self._update) + self.connect_event('button_release_event', self._update) if dragging: - ax.figure.canvas.mpl_connect('motion_notify_event', self._update) + self.connect_event('motion_notify_event', self._update) self.label = ax.text(-0.02, 0.5, label, transform=ax.transAxes, verticalalignment='center', horizontalalignment='right') @@ -280,6 +325,9 @@ def _update(self, event): 'update the slider position' + if self.ignore(event): + return + if event.button != 1: return @@ -306,11 +354,15 @@ return val = self.valmax - if self.slidermin is not None: - if val<=self.slidermin.val: return + if self.slidermin is not None and val <= self.slidermin.val: + if not self.closedmin: + return + val = self.slidermin.val - if self.slidermax is not None: - if val>=self.slidermax.val: return + if self.slidermax is not None and val >= self.slidermax.val: + if not self.closedmax: + return + val = self.slidermax.val self.set_val(val) @@ -323,7 +375,7 @@ if self.drawon: self.ax.figure.canvas.draw() self.val = val if not self.eventson: return - for cid, func in self.observers.items(): + for cid, func in self.observers.iteritems(): func(val) def on_changed(self, func): @@ -350,7 +402,7 @@ -class CheckButtons(Widget): +class CheckButtons(AxesWidget): """ A GUI neutral radio button @@ -384,6 +436,7 @@ A len(buttons) list of booleans indicating whether the button is active """ + AxesWidget.__init__(self, ax) ax.set_xticks([]) ax.set_yticks([]) @@ -431,14 +484,14 @@ ax.add_line(l2) cnt += 1 - ax.figure.canvas.mpl_connect('button_press_event', self._clicked) - self.ax = ax - + self.connect_event('button_press_event', self._clicked) self.cnt = 0 self.observers = {} def _clicked(self, event): + if self.ignore(event): + return if event.button !=1 : return if event.inaxes != self.ax: return @@ -457,7 +510,7 @@ if self.drawon: self.ax.figure.canvas.draw() if not self.eventson: return - for cid, func in self.observers.items(): + for cid, func in self.observers.iteritems(): func(thist.get_text()) @@ -478,7 +531,7 @@ except KeyError: pass -class RadioButtons(Widget): +class RadioButtons(AxesWidget): """ A GUI neutral radio button @@ -511,8 +564,9 @@ *activecolor* The color of the button when clicked """ - self.activecolor = activecolor + AxesWidget.__init__(self, ax) + self.activecolor = activecolor ax.set_xticks([]) ax.set_yticks([]) @@ -543,14 +597,14 @@ ax.add_patch(p) cnt += 1 - ax.figure.canvas.mpl_connect('button_press_event', self._clicked) - self.ax = ax - + self.connect_event('button_press_event', self._clicked) self.cnt = 0 self.observers = {} def _clicked(self, event): + if self.ignore(event): + return if event.button !=1 : return if event.inaxes != self.ax: return xy = self.ax.transAxes.inverted().transform_point((event.x, event.y)) @@ -576,7 +630,7 @@ if self.drawon: self.ax.figure.canvas.draw() if not self.eventson: return - for cid, func in self.observers.items(): + for cid, func in self.observers.iteritems(): func(thist.get_text()) @@ -733,7 +787,7 @@ if self.drawon: self.targetfig.canvas.draw() -class Cursor: +class Cursor(AxesWidget): """ A horizontal and vertical line span the axes that and move with the pointer. You can turn off the hline or vline spectively with @@ -756,12 +810,10 @@ .. plot :: mpl_examples/widgets/cursor.py """ # TODO: Is the GTKAgg limitation still true? + AxesWidget.__init__(self, ax) - self.ax = ax - self.canvas = ax.figure.canvas - - self.canvas.mpl_connect('motion_notify_event', self.onmove) - self.canvas.mpl_connect('draw_event', self.clear) + self.connect_event('motion_notify_event', self.onmove) + self.connect_event('draw_event', self.clear) self.visible = True self.horizOn = True @@ -776,9 +828,10 @@ self.background = None self.needclear = False - def clear(self, event): 'clear the cursor' + if self.ignore(event): + return if self.useblit: self.background = self.canvas.copy_from_bbox(self.ax.bbox) self.linev.set_visible(False) @@ -786,6 +839,10 @@ def onmove(self, event): 'on mouse motion draw the cursor if visible' + if self.ignore(event): + return + if not self.canvas.widgetlock.available(self): + return if event.inaxes != self.ax: self.linev.set_visible(False) self.lineh.set_visible(False) @@ -819,18 +876,18 @@ return False -class MultiCursor: +class MultiCursor(Widget): """ Provide a vertical line cursor shared between multiple axes Example usage:: from matplotlib.widgets import MultiCursor - from pylab import figure, show, nx + from pylab import figure, show, np - t = nx.arange(0.0, 2.0, 0.01) - s1 = nx.sin(2*nx.pi*t) - s2 = nx.sin(4*nx.pi*t) + t = np.arange(0.0, 2.0, 0.01) + s1 = np.sin(2*np.pi*t) + s2 = np.sin(4*np.pi*t) fig = figure() ax1 = fig.add_subplot(211) ax1.plot(t, s1) @@ -852,7 +909,8 @@ if useblit: lineprops['animated'] = True - self.lines = [ax.axvline(xmid, visible=False, **lineprops) for ax in axes] + self.lines = [ax.axvline(xmid, visible=False, **lineprops) + for ax in axes] self.visible = True self.useblit = useblit @@ -866,15 +924,20 @@ def clear(self, event): 'clear the cursor' if self.useblit: - self.background = self.canvas.copy_from_bbox(self.canvas.figure.bbox) - for line in self.lines: line.set_visible(False) + self.background = self.canvas.copy_from_bbox( + self.canvas.figure.bbox) + for line in self.lines: + line.set_visible(False) def onmove(self, event): - if event.inaxes is None: return - if not self.canvas.widgetlock.available(self): return + if event.inaxes is None: + return + if not self.canvas.widgetlock.available(self): + return self.needclear = True - if not self.visible: return + if not self.visible: + return for line in self.lines: line.set_xdata((event.xdata, event.xdata)) @@ -894,7 +957,7 @@ self.canvas.draw_idle() -class SpanSelector: +class SpanSelector(AxesWidget): """ Select a min/max range of the x or y axes for a matplotlib Axes @@ -932,16 +995,15 @@ Set the visible attribute to *False* if you want to turn off the functionality of the span selector """ + AxesWidget.__init__(self, ax) + if rectprops is None: rectprops = dict(facecolor='red', alpha=0.5) assert direction in ['horizontal', 'vertical'], 'Must choose horizontal or vertical for direction' self.direction = direction - self.ax = None - self.canvas = None self.visible = True - self.cids=[] self.rect = None self.background = None @@ -957,21 +1019,21 @@ self.buttonDown = False self.prev = (0, 0) + # Reset canvas so that `new_axes` connects events. + self.canvas = None self.new_axes(ax) - def new_axes(self,ax): self.ax = ax if self.canvas is not ax.figure.canvas: - for cid in self.cids: - self.canvas.mpl_disconnect(cid) + self.disconnect_events() self.canvas = ax.figure.canvas + self.connect_event('motion_notify_event', self.onmove) + self.connect_event('button_press_event', self.press) + self.connect_event('button_release_event', self.release) + self.connect_event('draw_event', self.update_background) - self.cids.append(self.canvas.mpl_connect('motion_notify_event', self.onmove)) - self.cids.append(self.canvas.mpl_connect('button_press_event', self.press)) - self.cids.append(self.canvas.mpl_connect('button_release_event', self.release)) - self.cids.append(self.canvas.mpl_connect('draw_event', self.update_background)) if self.direction == 'horizontal': trans = blended_transform_factory(self.ax.transData, self.ax.transAxes) w,h = 0,1 @@ -988,17 +1050,21 @@ def update_background(self, event): 'force an update of the background' + # If you add a call to `ignore` here, you'll want to check edge case: + # `release` can call a draw event even when `ignore` is True. if self.useblit: self.background = self.canvas.copy_from_bbox(self.ax.bbox) - def ignore(self, event): 'return *True* if *event* should be ignored' - return event.inaxes!=self.ax or not self.visible or event.button !=1 + widget_off = not self.visible or not self.active + non_event = event.inaxes!=self.ax or event.button !=1 + return widget_off or non_event def press(self, event): 'on button press event' - if self.ignore(event): return + if self.ignore(event): + return self.buttonDown = True self.rect.set_visible(self.visible) @@ -1008,10 +1074,12 @@ self.pressv = event.ydata return False - def release(self, event): 'on button release event' - if self.pressv is None or (self.ignore(event) and not self.buttonDown): return + if self.ignore(event) and not self.buttonDown: + return + if self.pressv is None: + return self.buttonDown = False self.rect.set_visible(False) @@ -1046,7 +1114,8 @@ def onmove(self, event): 'on motion notify event' - if self.pressv is None or self.ignore(event): return + if self.pressv is None or self.ignore(event): + return x, y = event.xdata, event.ydata self.prev = x, y if self.direction == 'horizontal': @@ -1084,7 +1153,7 @@ SpanSelector.__init__(self, ax, onselect, 'horizontal', **kwargs) -class RectangleSelector: +class RectangleSelector(AxesWidget): """ Select a min/max range of the x axes for a matplotlib Axes @@ -1164,13 +1233,13 @@ 2 = center mouse button (scroll wheel) 3 = right mouse button """ - self.ax = ax + AxesWidget.__init__(self, ax) + self.visible = True - self.canvas = ax.figure.canvas - self.canvas.mpl_connect('motion_notify_event', self.onmove) - self.canvas.mpl_connect('button_press_event', self.press) - self.canvas.mpl_connect('button_release_event', self.release) - self.canvas.mpl_connect('draw_event', self.update_background) + self.connect_event('motion_notify_event', self.onmove) + self.connect_event('button_press_event', self.press) + self.connect_event('button_release_event', self.release) + self.connect_event('draw_event', self.update_background) self.active = True # for activation / deactivation self.to_draw = None @@ -1222,7 +1291,6 @@ def ignore(self, event): 'return *True* if *event* should be ignored' - # If RectangleSelector is not active : if not self.active: return True @@ -1242,16 +1310,29 @@ return event.inaxes!= self.ax # If a button was pressed, check if the release-button is the + # same. If event is out of axis, limit the data coordinates to axes + # boundaries. + if event.button == self.eventpress.button and event.inaxes != self.ax: + (xdata, ydata) = self.ax.transData.inverted().transform_point((event.x, event.y)) + x0, x1 = self.ax.get_xbound() + y0, y1 = self.ax.get_ybound() + xdata = max(x0, xdata) + xdata = min(x1, xdata) + ydata = max(y0, ydata) + ydata = min(y1, ydata) + event.xdata = xdata + event.ydata = ydata + return False + + # If a button was pressed, check if the release-button is the # same. return (event.inaxes!=self.ax or event.button != self.eventpress.button) def press(self, event): 'on button press event' - # Is the correct button pressed within the correct axes? - if self.ignore(event): return - - + if self.ignore(event): + return # make the drawed box/line visible get the click-coordinates, # button, ... self.to_draw.set_visible(self.visible) @@ -1261,7 +1342,8 @@ def release(self, event): 'on button release event' - if self.eventpress is None or self.ignore(event): return + if self.eventpress is None or self.ignore(event): + return # make the box/line invisible again self.to_draw.set_visible(False) self.canvas.draw() @@ -1312,10 +1394,10 @@ self.canvas.draw_idle() return False - def onmove(self, event): 'on motion notify event if box/line is wanted' - if self.eventpress is None or self.ignore(event): return + if self.eventpress is None or self.ignore(event): + return x,y = event.xdata, event.ydata # actual position (with # (button still pressed) if self.drawtype == 'box': @@ -1346,37 +1428,153 @@ """ Get status of active mode (boolean variable)""" return self.active -class Lasso(Widget): + +class LassoSelector(AxesWidget): + """Selection curve of an arbitrary shape. + + The selected path can be used in conjunction with + :function:`~matplotlib.path.Path.contains_point` to select + data points from an image. + + In contrast to :class:`Lasso`, `LassoSelector` is written with an interface + similar to :class:`RectangleSelector` and :class:`SpanSelector` and will + continue to interact with the axes until disconnected. + + Parameters: + + *ax* : :class:`~matplotlib.axes.Axes` + The parent axes for the widget. + *onselect* : function + Whenever the lasso is released, the `onselect` function is called and + passed the vertices of the selected path. + + Example usage:: + + ax = subplot(111) + ax.plot(x,y) + + def onselect(verts): + print verts + lasso = LassoSelector(ax, onselect) + + """ + + def __init__(self, ax, onselect=None, useblit=True, lineprops=None): + AxesWidget.__init__(self, ax) + + self.useblit = useblit + self.onselect = onselect + self.verts = None + + if lineprops is None: + lineprops = dict() + self.line = Line2D([], [], **lineprops) + self.line.set_visible(False) + self.ax.add_line(self.line) + + self.connect_event('button_press_event', self.onpress) + self.connect_event('button_release_event', self.onrelease) + self.connect_event('motion_notify_event', self.onmove) + self.connect_event('draw_event', self.update_background) + + def ignore(self, event): + wrong_button = hasattr(event, 'button') and event.button != 1 + return not self.active or wrong_button + + def onpress(self, event): + if self.ignore(event) or event.inaxes != self.ax: + return + self.verts = [(event.xdata, event.ydata)] + self.line.set_visible(True) + + def onrelease(self, event): + if self.ignore(event): + return + if self.verts is not None: + if event.inaxes == self.ax: + self.verts.append((event.xdata, event.ydata)) + self.onselect(self.verts) + self.line.set_data([[], []]) + self.line.set_visible(False) + self.verts = None + + def onmove(self, event): + if self.ignore(event) or event.inaxes != self.ax: + return + if self.verts is None: return + if event.inaxes != self.ax: return + if event.button!=1: return + self.verts.append((event.xdata, event.ydata)) + + self.line.set_data(zip(*self.verts)) + + if self.useblit: + self.canvas.restore_region(self.background) + self.ax.draw_artist(self.line) + self.canvas.blit(self.ax.bbox) + else: + self.canvas.draw_idle() + + def update_background(self, event): + if self.ignore(event): + return + if self.useblit: + self.background = self.canvas.copy_from_bbox(self.ax.bbox) + + +class Lasso(AxesWidget): + """Selection curve of an arbitrary shape. + + The selected path can be used in conjunction with + :func:`~matplotlib.path.Path.contains_point` to select data points + from an image. + + Unlike :class:`LassoSelector`, this must be initialized with a starting + point `xy`, and the `Lasso` events are destroyed upon release. + + Parameters: + + *ax* : :class:`~matplotlib.axes.Axes` + The parent axes for the widget. + *xy* : array + Coordinates of the start of the lasso. + *callback* : function + Whenever the lasso is released, the `callback` function is called and + passed the vertices of the selected path. + + """ + def __init__(self, ax, xy, callback=None, useblit=True): - self.axes = ax - self.figure = ax.figure - self.canvas = self.figure.canvas + AxesWidget.__init__(self, ax) + self.useblit = useblit if useblit: - self.background = self.canvas.copy_from_bbox(self.axes.bbox) + self.background = self.canvas.copy_from_bbox(self.ax.bbox) x, y = xy self.verts = [(x,y)] self.line = Line2D([x], [y], linestyle='-', color='black', lw=2) - self.axes.add_line(self.line) + self.ax.add_line(self.line) self.callback = callback - self.cids = [] - self.cids.append(self.canvas.mpl_connect('button_release_event', self.onrelease)) - self.cids.append(self.canvas.mpl_connect('motion_notify_event', self.onmove)) + self.connect_event('button_release_event', self.onrelease) + self.connect_event('motion_notify_event', self.onmove) def onrelease(self, event): + if self.ignore(event): + return if self.verts is not None: self.verts.append((event.xdata, event.ydata)) if len(self.verts)>2: self.callback(self.verts) - self.axes.lines.remove(self.line) + self.ax.lines.remove(self.line) self.verts = None - for cid in self.cids: - self.canvas.mpl_disconnect(cid) + self.disconnect_events() def onmove(self, event): + if self.ignore(event): + return if self.verts is None: return - if event.inaxes != self.axes: return + if event.inaxes != self.ax: return if event.button!=1: return self.verts.append((event.xdata, event.ydata)) @@ -1384,7 +1582,7 @@ if self.useblit: self.canvas.restore_region(self.background) - self.axes.draw_artist(self.line) - self.canvas.blit(self.axes.bbox) + self.ax.draw_artist(self.line) + self.canvas.blit(self.ax.bbox) else: self.canvas.draw_idle() diff -Nru matplotlib-1.1.1/lib/mpl_examples/animation/basic_example.py matplotlib-1.2.0/lib/mpl_examples/animation/basic_example.py --- matplotlib-1.1.1/lib/mpl_examples/animation/basic_example.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/animation/basic_example.py 2012-10-31 00:11:13.000000000 +0000 @@ -29,6 +29,6 @@ im_ani = animation.ArtistAnimation(fig2, ims, interval=50, repeat_delay=3000, blit=True) -#im_ani.save('im.mp4') +#im_ani.save('im.mp4', metadata={'artist':'Guido'}) plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/animation/basic_example_writer.py matplotlib-1.2.0/lib/mpl_examples/animation/basic_example_writer.py --- matplotlib-1.1.1/lib/mpl_examples/animation/basic_example_writer.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/animation/basic_example_writer.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,42 @@ +# Same as basic_example, but writes files using a single MovieWriter instance +# without putting on screen +# -*- noplot -*- +import numpy as np +import matplotlib +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import matplotlib.animation as animation + +def update_line(num, data, line): + line.set_data(data[...,:num]) + return line, + +# Set up formatting for the movie files +Writer = animation.writers['ffmpeg'] +writer = Writer(fps=15, metadata=dict(artist='Me'), bitrate=1800) + + +fig1 = plt.figure() + +data = np.random.rand(2, 25) +l, = plt.plot([], [], 'r-') +plt.xlim(0, 1) +plt.ylim(0, 1) +plt.xlabel('x') +plt.title('test') +line_ani = animation.FuncAnimation(fig1, update_line, 25, fargs=(data, l), + interval=50, blit=True) +line_ani.save('lines.mp4', writer=writer) + +fig2 = plt.figure() + +x = np.arange(-9, 10) +y = np.arange(-9, 10).reshape(-1, 1) +base = np.hypot(x, y) +ims = [] +for add in np.arange(15): + ims.append((plt.pcolor(x, y, base + add, norm=plt.Normalize(0, 30)),)) + +im_ani = animation.ArtistAnimation(fig2, ims, interval=50, repeat_delay=3000, + blit=True) +im_ani.save('im.mp4', writer=writer) diff -Nru matplotlib-1.1.1/lib/mpl_examples/animation/dynamic_image2.py matplotlib-1.2.0/lib/mpl_examples/animation/dynamic_image2.py --- matplotlib-1.1.1/lib/mpl_examples/animation/dynamic_image2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/animation/dynamic_image2.py 2012-10-31 00:11:13.000000000 +0000 @@ -26,7 +26,7 @@ ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True, repeat_delay=1000) -ani.save('dynamic_images.mp4') +#ani.save('dynamic_images.mp4') plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/animation/moviewriter.py matplotlib-1.2.0/lib/mpl_examples/animation/moviewriter.py --- matplotlib-1.1.1/lib/mpl_examples/animation/moviewriter.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/animation/moviewriter.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,32 @@ +# This example uses a MovieWriter directly to grab individual frames and +# write them to a file. This avoids any event loop integration, but has +# the advantage of working with even the Agg backend. This is not recommended +# for use in an interactive setting. +# -*- noplot -*- + +import numpy as np +import matplotlib +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import matplotlib.animation as manimation + +FFMpegWriter = manimation.writers['ffmpeg'] +metadata = dict(title='Movie Test', artist='Matplotlib', + comment='Movie support!') +writer = FFMpegWriter(fps=15, metadata=metadata) + +fig = plt.figure() +l, = plt.plot([], [], 'k-o') + +plt.xlim(-5, 5) +plt.ylim(-5, 5) + +x0,y0 = 0, 0 + +with writer.saving(fig, "writer_test.mp4", 100): + for i in range(100): + x0 += 0.1 * np.random.randn() + y0 += 0.1 * np.random.randn() + l.set_data(x0, y0) + writer.grab_frame() + diff -Nru matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/animate_decay_tk_blit.py matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/animate_decay_tk_blit.py --- matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/animate_decay_tk_blit.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/animate_decay_tk_blit.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import time, sys import numpy as np import matplotlib.pyplot as plt @@ -44,7 +45,7 @@ if run.cnt==1000: # print the timing info and quit - print 'FPS:' , 1000/(time.time()-tstart) + print('FPS:' , 1000/(time.time()-tstart)) sys.exit() run.cnt += 1 diff -Nru matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/animation_blit_fltk.py matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/animation_blit_fltk.py --- matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/animation_blit_fltk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/animation_blit_fltk.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import sys import fltk import matplotlib @@ -37,7 +38,7 @@ self.cnt+=1 if self.cnt==1000: # print the timing info and quit - print 'FPS:' , 1000/(time.time()-self.tstart) + print('FPS:' , 1000/(time.time()-self.tstart)) sys.exit() return True diff -Nru matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/animation_blit_gtk.py matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/animation_blit_gtk.py --- matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/animation_blit_gtk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/animation_blit_gtk.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import print_function + # For detailed comments on animation and the techniques used here, see # the wiki entry # http://www.scipy.org/wikis/topical_software/MatplotlibAnimation @@ -30,7 +32,7 @@ tstart = time.time() def update_line(*args): - print 'you are here', update_line.cnt + print('you are here', update_line.cnt) if update_line.background is None: update_line.background = canvas.copy_from_bbox(ax.bbox) @@ -46,7 +48,7 @@ if update_line.cnt==1000: # print the timing info and quit - print 'FPS:' , 1000/(time.time()-tstart) + print('FPS:' , 1000/(time.time()-tstart)) gtk.mainquit() raise SystemExit diff -Nru matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/animation_blit_gtk2.py matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/animation_blit_gtk2.py --- matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/animation_blit_gtk2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/animation_blit_gtk2.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import print_function + """ This example utlizes restore_region with optional bbox and xy arguments. The plot is continuously shifted to the left. Instead of @@ -137,7 +139,7 @@ dt = (time.time()-tstart) if dt>15: # print the timing info and quit - print 'FPS:' , self.cnt/dt + print('FPS:' , self.cnt/dt) gtk.main_quit() raise SystemExit diff -Nru matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/animation_blit_qt.py matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/animation_blit_qt.py --- matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/animation_blit_qt.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/animation_blit_qt.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,8 @@ # For detailed comments on animation and the techniqes used here, see # the wiki entry http://www.scipy.org/Cookbook/Matplotlib/Animations +from __future__ import print_function + import os, sys import matplotlib matplotlib.use('QtAgg') # qt3 example @@ -47,7 +49,7 @@ if self.cnt==ITERS: # print the timing info and quit - print 'FPS:' , ITERS/(time.time()-self.tstart) + print('FPS:', ITERS/(time.time()-self.tstart)) sys.exit() else: diff -Nru matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/animation_blit_qt4.py matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/animation_blit_qt4.py --- matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/animation_blit_qt4.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/animation_blit_qt4.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,8 @@ # For detailed comments on animation and the techniqes used here, see # the wiki entry http://www.scipy.org/Cookbook/Matplotlib/Animations +from __future__ import print_function + import os import sys @@ -63,7 +65,7 @@ self.draw() if self.cnt==ITERS: # print the timing info and quit - print 'FPS:' , ITERS/(time.time()-self.tstart) + print('FPS:' , ITERS/(time.time()-self.tstart)) sys.exit() else: self.cnt += 1 diff -Nru matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/animation_blit_tk.py matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/animation_blit_tk.py --- matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/animation_blit_tk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/animation_blit_tk.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,8 @@ # For detailed comments on animation and the techniqes used here, see # the wiki entry http://www.scipy.org/Cookbook/Matplotlib/Animations +from __future__ import print_function + import matplotlib matplotlib.use('TkAgg') @@ -34,7 +36,7 @@ if run.cnt==1000: # print the timing info and quit - print 'FPS:' , 1000/(time.time()-tstart) + print('FPS:', 1000/(time.time()-tstart)) sys.exit() run.cnt += 1 diff -Nru matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/animation_blit_wx.py matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/animation_blit_wx.py --- matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/animation_blit_wx.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/animation_blit_wx.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,6 +2,8 @@ # the wiki entry # http://www.scipy.org/wikis/topical_software/MatplotlibAnimation +from __future__ import print_function + # The number of blits() to make before exiting NBLITS = 1000 @@ -58,11 +60,11 @@ if update_line.cnt == NBLITS: # print the timing info and quit frame_time = time.time() - tstart - print '%d frames: %.2f seconds' % (NBLITS, frame_time) - print '%d blits: %.2f seconds' % (NBLITS, blit_time) - print - print 'FPS: %.2f' % (NBLITS/frame_time) - print 'BPS: %.2f' % (NBLITS/blit_time) + print('%d frames: %.2f seconds' % (NBLITS, frame_time)) + print('%d blits: %.2f seconds' % (NBLITS, blit_time)) + print() + print('FPS: %.2f' % (NBLITS/frame_time)) + print('BPS: %.2f' % (NBLITS/blit_time)) sys.exit() update_line.cnt += 1 diff -Nru matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/dynamic_image_gtkagg.py matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/dynamic_image_gtkagg.py --- matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/dynamic_image_gtkagg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/dynamic_image_gtkagg.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,6 @@ #!/usr/bin/env python + +from __future__ import print_function """ An animated image """ @@ -34,7 +36,7 @@ manager.canvas.draw() cnt += 1 if cnt==50: - print 'FPS', cnt/(time.time() - tstart) + print('FPS', cnt/(time.time() - tstart)) return False return True diff -Nru matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/movie_demo.py matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/movie_demo.py --- matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/movie_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/movie_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -15,6 +15,8 @@ # the script to suit your own needs. # +from __future__ import print_function + import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt # For plotting graphs. @@ -28,9 +30,9 @@ # Python interpreter, and matplotlib. The version of # Mencoder is printed when it is called. # -print 'Executing on', os.uname() -print 'Python version', sys.version -print 'matplotlib version', matplotlib.__version__ +print('Executing on', os.uname()) +print('Python version', sys.version) +print('matplotlib version', matplotlib.__version__) not_found_msg = """ The mencoder command was not found; @@ -42,7 +44,7 @@ try: subprocess.check_call(['mencoder']) except subprocess.CalledProcessError: - print "mencoder command was found" + print("mencoder command was found") pass # mencoder is found, but returns non-zero exit as expected # This is a quick and dirty check; it leaves some spurious output # for the user to puzzle over. @@ -61,7 +63,7 @@ # distributed Gaussian noise at each time step. # -print 'Initializing data set...' # Let the user know what's happening. +print('Initializing data set...') # Let the user know what's happening. # Initialize variables needed to create and store the example data set. numberOfTimeSteps = 100 # Number of frames we want in the movie. @@ -78,7 +80,7 @@ mean = mean + meaninc stddev = stddev + stddevinc -print 'Done.' # Let the user know what's happening. +print('Done.') # Let the user know what's happening. # # Now that we have an example data set (x,y) to work with, we can @@ -113,7 +115,7 @@ # # Let the user know what's happening. # - print 'Wrote file', filename + print('Wrote file', filename) # # Clear the figure to make way for the next image. @@ -147,10 +149,10 @@ #os.spawnvp(os.P_WAIT, 'mencoder', command) -print "\n\nabout to execute:\n%s\n\n" % ' '.join(command) +print("\n\nabout to execute:\n%s\n\n" % ' '.join(command)) subprocess.check_call(command) -print "\n\n The movie was written to 'output.avi'" +print("\n\n The movie was written to 'output.avi'") -print "\n\n You may want to delete *.png now.\n\n" +print("\n\n You may want to delete *.png now.\n\n") diff -Nru matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/simple_anim_gtk.py matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/simple_anim_gtk.py --- matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/simple_anim_gtk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/simple_anim_gtk.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,7 @@ """ A simple example of an animated plot using a gtk backend """ +from __future__ import print_function import time import numpy as np import matplotlib @@ -20,11 +21,11 @@ for i in np.arange(1,200): line.set_ydata(np.sin(x+i/10.0)) # update the data fig.canvas.draw() # redraw the canvas - print 'FPS:' , 200/(time.time()-tstart) + print('FPS:' , 200/(time.time()-tstart)) raise SystemExit import gobject -print 'adding idle' +print('adding idle') gobject.idle_add(animate) -print 'showing' +print('showing') plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/simple_anim_tkagg.py matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/simple_anim_tkagg.py --- matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/simple_anim_tkagg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/simple_anim_tkagg.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,9 @@ #!/usr/bin/env python + """ A simple example of an animated plot in tkagg """ +from __future__ import print_function import time import numpy as np import matplotlib @@ -19,7 +21,7 @@ for i in np.arange(1,200): line.set_ydata(np.sin(x+i/10.0)) # update the data fig.canvas.draw() # redraw the canvas - print 'FPS:' , 200/(time.time()-tstart) + print('FPS:' , 200/(time.time()-tstart)) win = fig.canvas.manager.window fig.canvas.manager.window.after(100, animate) diff -Nru matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/simple_idle_wx.py matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/simple_idle_wx.py --- matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/simple_idle_wx.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/simple_idle_wx.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,7 @@ """ A simple example of an animated plot using a wx backend """ +from __future__ import print_function import time import numpy as np import matplotlib @@ -18,7 +19,7 @@ def update_line(idleevent): if update_line.i==200: return False - print 'animate', update_line.i + print('animate', update_line.i) line.set_ydata(np.sin(t+update_line.i/10.)) fig.canvas.draw_idle() # redraw the canvas update_line.i += 1 diff -Nru matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/simple_timer_wx.py matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/simple_timer_wx.py --- matplotlib-1.1.1/lib/mpl_examples/animation/old_animation/simple_timer_wx.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/animation/old_animation/simple_timer_wx.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function """ A simple example of an animated plot using a wx backend """ @@ -19,7 +20,7 @@ def update_line(event): if update_line.i==200: return False - print 'update', update_line.i + print('update', update_line.i) line.set_ydata(np.sin(t+update_line.i/10.)) fig.canvas.draw() # redraw the canvas update_line.i += 1 diff -Nru matplotlib-1.1.1/lib/mpl_examples/animation/simple_3danim.py matplotlib-1.2.0/lib/mpl_examples/animation/simple_3danim.py --- matplotlib-1.1.1/lib/mpl_examples/animation/simple_3danim.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/animation/simple_3danim.py 2012-10-31 00:11:13.000000000 +0000 @@ -15,7 +15,7 @@ """ lineData = np.empty((dims, length)) lineData[:, 0] = np.random.rand(dims) - for index in xrange(1, length) : + for index in range(1, length) : # scaling the random numbers by 0.1 so # movement is small compared to position. # subtraction by 0.5 is to change the range to [-0.5, 0.5] @@ -37,7 +37,7 @@ ax = p3.Axes3D(fig) # Fifty lines of random 3-D lines -data = [Gen_RandLine(25, 3) for index in xrange(50)] +data = [Gen_RandLine(25, 3) for index in range(50)] # Creating fifty line objects. # NOTE: Can't pass empty arrays into 3d version of plot() diff -Nru matplotlib-1.1.1/lib/mpl_examples/api/README.txt matplotlib-1.2.0/lib/mpl_examples/api/README.txt --- matplotlib-1.1.1/lib/mpl_examples/api/README.txt 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/api/README.txt 2012-10-31 00:11:13.000000000 +0000 @@ -5,23 +5,15 @@ procedural state machine. For robust, production level scripts, or for applications or web application servers, we recommend you use the matplotlib API directly as it gives you the maximum control over your -figures, axes and plottng commands. There are a few documentation -resources for the API +figures, axes and plottng commands. - - the matplotlib artist tutorial : - http://matplotlib.sourceforge.net/pycon/artist_api_tut.pdf - - - the "leftwich tutorial" : - http://matplotlib.sourceforge.net/leftwich_tut.txt - - The example agg_oo.py is the simplest example of using the Agg - backend which is readily ported to other output formats. This - example is a good starting point if your are a web application - developer. Many of the other examples in this directory use - matplotlib.pyplot just to create the figure and show calls, and use - the API for everything else. This is a good solution for production - quality scripts. For full fledged GUI applications, see the - user_interfaces examples. +The example agg_oo.py is the simplest example of using the Agg backend +which is readily ported to other output formats. This example is a +good starting point if your are a web application developer. Many of +the other examples in this directory use matplotlib.pyplot just to +create the figure and show calls, and use the API for everything else. +This is a good solution for production quality scripts. For full +fledged GUI applications, see the user_interfaces examples. Example style guide =================== diff -Nru matplotlib-1.1.1/lib/mpl_examples/api/artist_demo.py matplotlib-1.2.0/lib/mpl_examples/api/artist_demo.py --- matplotlib-1.1.1/lib/mpl_examples/api/artist_demo.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/api/artist_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,17 +1,17 @@ """ Show examples of matplotlib artists -http://matplotlib.sourceforge.net/api/artist_api.html +http://matplotlib.org/api/artist_api.html Several examples of standard matplotlib graphics primitives (artists) are drawn using matplotlib API. Full list of artists and the documentation is available at -http://matplotlib.sourceforge.net/api/artist_api.html +http://matplotlib.org/api/artist_api.html Copyright (c) 2010, Bartosz Telenczuk License: This work is licensed under the BSD. A copy should be included with this source code, and is also available at -http://www.opensource.org/licenses/bsd-license.php +http://www.opensource.org/licenses/bsd-license.php """ @@ -69,7 +69,7 @@ plt.text(pos[0,5], pos[1,5]-0.15, "Arrow", ha="center", family=font, size=14) -# add a path patch +# add a path patch Path = mpath.Path verts = np.array([ (0.158, -0.257), @@ -83,7 +83,7 @@ (0.158, -0.257), ]) verts = verts-verts.mean(0) -codes = [Path.MOVETO, +codes = [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, Path.LINETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, Path.CLOSEPOLY] @@ -95,7 +95,7 @@ # add a fancy box fancybox = mpatches.FancyBboxPatch( - pos[:,7]-np.array([0.025, 0.05]), 0.05, 0.1, + pos[:,7]-np.array([0.025, 0.05]), 0.05, 0.1, boxstyle=mpatches.BoxStyle("Round", pad=0.02)) patches.append(fancybox) plt.text(pos[0,7], pos[1,7]-0.15, "FancyBoxPatch", ha="center", diff -Nru matplotlib-1.1.1/lib/mpl_examples/api/bbox_intersect.py matplotlib-1.2.0/lib/mpl_examples/api/bbox_intersect.py --- matplotlib-1.1.1/lib/mpl_examples/api/bbox_intersect.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/api/bbox_intersect.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,21 +1,19 @@ -from pylab import * import numpy as np +import matplotlib.pyplot as plt from matplotlib.transforms import Bbox from matplotlib.path import Path -from matplotlib.patches import Rectangle -rect = Rectangle((-1, -1), 2, 2, facecolor="#aaaaaa") -gca().add_patch(rect) +rect = plt.Rectangle((-1, -1), 2, 2, facecolor="#aaaaaa") +plt.gca().add_patch(rect) bbox = Bbox.from_bounds(-1, -1, 2, 2) for i in range(12): - vertices = (np.random.random((4, 2)) - 0.5) * 6.0 - vertices = np.ma.masked_array(vertices, [[False, False], [True, True], [False, False], [False, False]]) + vertices = (np.random.random((2, 2)) - 0.5) * 6.0 path = Path(vertices) if path.intersects_bbox(bbox): color = 'r' else: color = 'b' - plot(vertices[:,0], vertices[:,1], color=color) + plt.plot(vertices[:,0], vertices[:,1], color=color) -show() +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/api/clippath_demo.py matplotlib-1.2.0/lib/mpl_examples/api/clippath_demo.py --- matplotlib-1.1.1/lib/mpl_examples/api/clippath_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/api/clippath_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,7 +3,6 @@ """ import numpy as np import matplotlib.pyplot as plt -import matplotlib.path as path import matplotlib.patches as patches diff -Nru matplotlib-1.1.1/lib/mpl_examples/api/collections_demo.py matplotlib-1.2.0/lib/mpl_examples/api/collections_demo.py --- matplotlib-1.1.1/lib/mpl_examples/api/collections_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/api/collections_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -17,31 +17,31 @@ ''' -import matplotlib.pyplot as P -from matplotlib import collections, axes, transforms +import matplotlib.pyplot as plt +from matplotlib import collections, transforms from matplotlib.colors import colorConverter -import numpy as N +import numpy as np nverts = 50 npts = 100 # Make some spirals -r = N.array(range(nverts)) -theta = N.array(range(nverts)) * (2*N.pi)/(nverts-1) -xx = r * N.sin(theta) -yy = r * N.cos(theta) -spiral = zip(xx,yy) +r = np.array(range(nverts)) +theta = np.array(range(nverts)) * (2*np.pi)/(nverts-1) +xx = r * np.sin(theta) +yy = r * np.cos(theta) +spiral = list(zip(xx,yy)) # Make some offsets -rs = N.random.RandomState([12345678]) +rs = np.random.RandomState([12345678]) xo = rs.randn(npts) yo = rs.randn(npts) -xyo = zip(xo, yo) +xyo = list(zip(xo, yo)) # Make a list of colors cycling through the rgbcmyk series. colors = [colorConverter.to_rgba(c) for c in ('r','g','b','c','y','m','k')] -fig = P.figure() +fig = plt.figure() a = fig.add_subplot(2,2,1) col = collections.LineCollection([spiral], offsets=xyo, @@ -88,7 +88,7 @@ a = fig.add_subplot(2,2,3) col = collections.RegularPolyCollection(7, - sizes = N.fabs(xx)*10.0, offsets=xyo, + sizes = np.fabs(xx)*10.0, offsets=xyo, transOffset=a.transData) trans = transforms.Affine2D().scale(fig.dpi/72.0) col.set_transform(trans) # the points to pixels transform @@ -108,13 +108,13 @@ ncurves = 20 offs = (0.1, 0.0) -yy = N.linspace(0, 2*N.pi, nverts) -ym = N.amax(yy) -xx = (0.2 + (ym-yy)/ym)**2 * N.cos(yy-0.4) * 0.5 +yy = np.linspace(0, 2*np.pi, nverts) +ym = np.amax(yy) +xx = (0.2 + (ym-yy)/ym)**2 * np.cos(yy-0.4) * 0.5 segs = [] for i in range(ncurves): xxx = xx + 0.02*rs.randn(nverts) - curve = zip(xxx, yy*100) + curve = list(zip(xxx, yy*100)) segs.append(curve) col = collections.LineCollection(segs, offsets=offs) @@ -128,6 +128,6 @@ a.set_ylim(a.get_ylim()[::-1]) -P.show() +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/api/colorbar_only.py matplotlib-1.2.0/lib/mpl_examples/api/colorbar_only.py --- matplotlib-1.1.1/lib/mpl_examples/api/colorbar_only.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/api/colorbar_only.py 2012-10-31 00:11:13.000000000 +0000 @@ -6,8 +6,9 @@ # Make a figure and axes with dimensions as desired. fig = pyplot.figure(figsize=(8,3)) -ax1 = fig.add_axes([0.05, 0.65, 0.9, 0.15]) -ax2 = fig.add_axes([0.05, 0.25, 0.9, 0.15]) +ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15]) +ax2 = fig.add_axes([0.05, 0.475, 0.9, 0.15]) +ax3 = fig.add_axes([0.05, 0.15, 0.9, 0.15]) # Set the colormap and norm to correspond to the data for which # the colorbar will be used. @@ -47,5 +48,27 @@ orientation='horizontal') cb2.set_label('Discrete intervals, some other units') +# The third example illustrates the use of custom length colorbar +# extensions, used on a colorbar with discrete intervals. +cmap = mpl.colors.ListedColormap([[0., .4, 1.], [0., .8, 1.], + [1., .8, 0.], [1., .4, 0.]]) +cmap.set_over((1., 0., 0.)) +cmap.set_under((0., 0., 1.)) + +bounds = [-1., -.5, 0., .5, 1.] +norm = mpl.colors.BoundaryNorm(bounds, cmap.N) +cb3 = mpl.colorbar.ColorbarBase(ax3, cmap=cmap, + norm=norm, + boundaries=[-10]+bounds+[10], + extend='both', + # Make the length of each extension + # the same as the length of the + # interior colors: + extendfrac='auto', + ticks=bounds, + spacing='uniform', + orientation='horizontal') +cb3.set_label('Custom extension lengths, some other units') + pyplot.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/api/custom_projection_example.py matplotlib-1.2.0/lib/mpl_examples/api/custom_projection_example.py --- matplotlib-1.1.1/lib/mpl_examples/api/custom_projection_example.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/api/custom_projection_example.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,10 @@ +from __future__ import unicode_literals + from matplotlib.axes import Axes -from matplotlib import cbook from matplotlib.patches import Circle from matplotlib.path import Path -from matplotlib.ticker import Formatter, Locator, NullLocator, FixedLocator, NullFormatter -from matplotlib.transforms import Affine2D, Affine2DBase, Bbox, \ - BboxTransformTo, IdentityTransform, Transform, TransformWrapper +from matplotlib.ticker import NullLocator, Formatter, FixedLocator +from matplotlib.transforms import Affine2D, BboxTransformTo, Transform from matplotlib.projections import register_projection import matplotlib.spines as mspines import matplotlib.axis as maxis @@ -280,7 +280,7 @@ else: ew = 'W' # \u00b0 : degree symbol - return u'%f\u00b0%s, %f\u00b0%s' % (abs(lat), ns, abs(long), ew) + return '%f\u00b0%s, %f\u00b0%s' % (abs(lat), ns, abs(long), ew) class DegreeFormatter(Formatter): """ @@ -294,7 +294,7 @@ degrees = (x / np.pi) * 180.0 degrees = round(degrees / self._round_to) * self._round_to # \u00b0 : degree symbol - return u"%d\u00b0" % degrees + return "%d\u00b0" % degrees def set_longitude_grid(self, degrees): """ @@ -308,7 +308,7 @@ # by degrees. number = (360.0 / degrees) + 1 self.xaxis.set_major_locator( - FixedLocator( + plt.FixedLocator( np.linspace(-np.pi, np.pi, number, True)[1:-1])) # Set the formatter to display the tick labels in degrees, # rather than radians. @@ -446,11 +446,12 @@ # it. register_projection(HammerAxes) -# Now make a simple example using the custom projection. -from pylab import * +if __name__ == '__main__': + import matplotlib.pyplot as plt + # Now make a simple example using the custom projection. + plt.subplot(111, projection="custom_hammer") + p = plt.plot([-1, 1, 1], [-1, -1, 1], "o-") + plt.grid(True) -subplot(111, projection="custom_hammer") -p = plot([-1, 1, 1], [-1, -1, 1], "o-") -grid(True) + plt.show() -show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/api/custom_scale_example.py matplotlib-1.2.0/lib/mpl_examples/api/custom_scale_example.py --- matplotlib-1.1.1/lib/mpl_examples/api/custom_scale_example.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/api/custom_scale_example.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,11 @@ +from __future__ import unicode_literals + +import numpy as np +from numpy import ma from matplotlib import scale as mscale from matplotlib import transforms as mtransforms +from matplotlib.ticker import Formatter, FixedLocator + class MercatorLatitudeScale(mscale.ScaleBase): """ @@ -67,7 +73,7 @@ class DegreeFormatter(Formatter): def __call__(self, x, pos=None): # \u00b0 : degree symbol - return u"%d\u00b0" % ((x / np.pi) * 180.0) + return "%d\u00b0" % ((x / np.pi) * 180.0) deg2rad = np.pi / 180.0 axis.set_major_locator(FixedLocator( @@ -148,18 +154,20 @@ # that ``matplotlib`` can find it. mscale.register_scale(MercatorLatitudeScale) -from pylab import * -import numpy as np -t = arange(-180.0, 180.0, 0.1) -s = t / 360.0 * np.pi +if __name__ == '__main__': + import matplotlib.pyplot as plt + + t = np.arange(-180.0, 180.0, 0.1) + s = t / 360.0 * np.pi + + plt.plot(t, s, '-', lw=2) + plt.gca().set_yscale('mercator') -plot(t, s, '-', lw=2) -gca().set_yscale('mercator') + plt.xlabel('Longitude') + plt.ylabel('Latitude') + plt.title('Mercator: Projection of the Oppressor') + plt.grid(True) -xlabel('Longitude') -ylabel('Latitude') -title('Mercator: Projection of the Oppressor') -grid(True) + plt.show() -show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/api/date_demo.py matplotlib-1.2.0/lib/mpl_examples/api/date_demo.py --- matplotlib-1.1.1/lib/mpl_examples/api/date_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/api/date_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -13,10 +13,8 @@ """ import datetime import numpy as np -import matplotlib import matplotlib.pyplot as plt import matplotlib.dates as mdates -import matplotlib.mlab as mlab import matplotlib.cbook as cbook years = mdates.YearLocator() # every year diff -Nru matplotlib-1.1.1/lib/mpl_examples/api/date_index_formatter.py matplotlib-1.2.0/lib/mpl_examples/api/date_index_formatter.py --- matplotlib-1.1.1/lib/mpl_examples/api/date_index_formatter.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/api/date_index_formatter.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,6 +3,7 @@ to leave out days on which there is no data, eh weekends. The example below shows how to use an 'index formatter' to achieve the desired plot """ +from __future__ import print_function import numpy as np import matplotlib.pyplot as plt import matplotlib.mlab as mlab @@ -10,7 +11,7 @@ import matplotlib.ticker as ticker datafile = cbook.get_sample_data('aapl.csv', asfileobj=False) -print 'loading', datafile +print ('loading %s' % datafile) r = mlab.csv2rec(datafile) r.sort() diff -Nru matplotlib-1.1.1/lib/mpl_examples/api/fahrenheit_celcius_scales.py matplotlib-1.2.0/lib/mpl_examples/api/fahrenheit_celcius_scales.py --- matplotlib-1.1.1/lib/mpl_examples/api/fahrenheit_celcius_scales.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/api/fahrenheit_celcius_scales.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -""" -Shoiw how to display two scales on the left and right y axis -- Fahrenheit and Celcius -""" - -import matplotlib.pyplot as plt - -fig = plt.figure() -ax1 = fig.add_subplot(111) # the Fahrenheit scale -ax2 = ax1.twinx() # the Celcius scale - -def Tc(Tf): - return (5./9.)*(Tf-32) - - -def update_ax2(ax1): - y1, y2 = ax1.get_ylim() - ax2.set_ylim(Tc(y1), Tc(y2)) - ax2.figure.canvas.draw() - -# automatically update ylim of ax2 when ylim of ax1 changes. -ax1.callbacks.connect("ylim_changed", update_ax2) -ax1.plot([78, 79, 79, 77]) - -ax1.set_title('Two scales: Fahrenheit and Celcius') -ax1.set_ylabel('Fahrenheit') -ax2.set_ylabel('Celcius') - -plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/api/fahrenheit_celsius_scales.py matplotlib-1.2.0/lib/mpl_examples/api/fahrenheit_celsius_scales.py --- matplotlib-1.1.1/lib/mpl_examples/api/fahrenheit_celsius_scales.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/api/fahrenheit_celsius_scales.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,28 @@ +""" +Show how to display two scales on the left and right y axis -- Fahrenheit and Celsius +""" + +import matplotlib.pyplot as plt + +fig = plt.figure() +ax1 = fig.add_subplot(111) # the Fahrenheit scale +ax2 = ax1.twinx() # the Celsius scale + +def Tc(Tf): + return (5./9.)*(Tf-32) + + +def update_ax2(ax1): + y1, y2 = ax1.get_ylim() + ax2.set_ylim(Tc(y1), Tc(y2)) + ax2.figure.canvas.draw() + +# automatically update ylim of ax2 when ylim of ax1 changes. +ax1.callbacks.connect("ylim_changed", update_ax2) +ax1.plot([78, 79, 79, 77]) + +ax1.set_title('Two scales: Fahrenheit and Celsius') +ax1.set_ylabel('Fahrenheit') +ax2.set_ylabel('Celsius') + +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/api/logo2.py matplotlib-1.2.0/lib/mpl_examples/api/logo2.py --- matplotlib-1.1.1/lib/mpl_examples/api/logo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/api/logo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -6,8 +6,6 @@ import matplotlib as mpl import matplotlib.pyplot as plt import matplotlib.cm as cm -import matplotlib.mlab as mlab -from pylab import rand mpl.rcParams['xtick.labelsize'] = 10 mpl.rcParams['ytick.labelsize'] = 12 diff -Nru matplotlib-1.1.1/lib/mpl_examples/api/patch_collection.py matplotlib-1.2.0/lib/mpl_examples/api/patch_collection.py --- matplotlib-1.1.1/lib/mpl_examples/api/patch_collection.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/api/patch_collection.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,26 +1,28 @@ +import numpy as np import matplotlib from matplotlib.patches import Circle, Wedge, Polygon from matplotlib.collections import PatchCollection -import pylab +import matplotlib.pyplot as plt -fig=pylab.figure() + +fig=plt.figure() ax=fig.add_subplot(111) resolution = 50 # the number of vertices N = 3 -x = pylab.rand(N) -y = pylab.rand(N) -radii = 0.1*pylab.rand(N) +x = np.random.rand(N) +y = np.random.rand(N) +radii = 0.1*np.random.rand(N) patches = [] for x1,y1,r in zip(x, y, radii): circle = Circle((x1,y1), r) patches.append(circle) -x = pylab.rand(N) -y = pylab.rand(N) -radii = 0.1*pylab.rand(N) -theta1 = 360.0*pylab.rand(N) -theta2 = 360.0*pylab.rand(N) +x = np.random.rand(N) +y = np.random.rand(N) +radii = 0.1*np.random.rand(N) +theta1 = 360.0*np.random.rand(N) +theta2 = 360.0*np.random.rand(N) for x1,y1,r,t1,t2 in zip(x, y, radii, theta1, theta2): wedge = Wedge((x1,y1), r, t1, t2) patches.append(wedge) @@ -34,13 +36,13 @@ ] for i in range(N): - polygon = Polygon(pylab.rand(N,2), True) + polygon = Polygon(np.random.rand(N,2), True) patches.append(polygon) -colors = 100*pylab.rand(len(patches)) +colors = 100*np.random.rand(len(patches)) p = PatchCollection(patches, cmap=matplotlib.cm.jet, alpha=0.4) -p.set_array(pylab.array(colors)) +p.set_array(np.array(colors)) ax.add_collection(p) -pylab.colorbar(p) +plt.colorbar(p) -pylab.show() +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/api/radar_chart.py matplotlib-1.2.0/lib/mpl_examples/api/radar_chart.py --- matplotlib-1.1.1/lib/mpl_examples/api/radar_chart.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/api/radar_chart.py 2012-10-31 00:11:13.000000000 +0000 @@ -46,7 +46,7 @@ patch_dict = {'polygon': draw_poly_patch, 'circle': draw_circle_patch} if frame not in patch_dict: - raise ValueError, 'unknown value for `frame`: %s' % frame + raise ValueError('unknown value for `frame`: %s' % frame) class RadarAxes(PolarAxes): @@ -133,7 +133,8 @@ # 4)Inclusion of both gas-phase speciesis present... data = { 'column names': - ['Sulfate', 'Nitrate', 'EC', 'OC1', 'OC2', 'OC3', 'OP', 'CO', 'O3'], + ['Sulfate', 'Nitrate', 'EC', 'OC1', 'OC2', 'OC3', 'OP', 'CO', + 'O3'], 'Basecase': [[0.88, 0.01, 0.03, 0.03, 0.00, 0.06, 0.01, 0.00, 0.00], [0.07, 0.95, 0.04, 0.05, 0.00, 0.02, 0.01, 0.00, 0.00], @@ -157,8 +158,7 @@ [0.09, 0.95, 0.02, 0.03, 0.00, 0.01, 0.13, 0.06, 0.00], [0.01, 0.02, 0.71, 0.24, 0.13, 0.16, 0.00, 0.50, 0.00], [0.01, 0.03, 0.00, 0.28, 0.24, 0.23, 0.00, 0.44, 0.88], - [0.02, 0.00, 0.18, 0.45, 0.64, 0.55, 0.86, 0.00, 0.16]] - } + [0.02, 0.00, 0.18, 0.45, 0.64, 0.55, 0.86, 0.00, 0.16]]} return data @@ -185,12 +185,11 @@ ax.set_varlabels(spoke_labels) # add legend relative to top-left plot - plt.subplot(2,2,1) + plt.subplot(2, 2, 1) labels = ('Factor 1', 'Factor 2', 'Factor 3', 'Factor 4', 'Factor 5') legend = plt.legend(labels, loc=(0.9, .95), labelspacing=0.1) plt.setp(legend.get_texts(), fontsize='small') - plt.figtext(0.5, 0.965, '5-Factor Solution Profiles Across Four Scenarios', - ha='center', color='black', weight='bold', size='large') + plt.figtext(0.5, 0.965, '5-Factor Solution Profiles Across Four Scenarios', + ha='center', color='black', weight='bold', size='large') plt.show() - diff -Nru matplotlib-1.1.1/lib/mpl_examples/api/sankey_demo_links.py matplotlib-1.2.0/lib/mpl_examples/api/sankey_demo_links.py --- matplotlib-1.1.1/lib/mpl_examples/api/sankey_demo_links.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/api/sankey_demo_links.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,31 +1,35 @@ """Demonstrate/test the Sankey class by producing a long chain of connections. """ -import numpy as np -import matplotlib.pyplot as plt -from matplotlib.sankey import Sankey from itertools import cycle +import matplotlib.pyplot as plt +from matplotlib.sankey import Sankey + links_per_side = 6 + + def side(sankey, n=1): - """Generate a side chain. - """ + """Generate a side chain.""" prior = len(sankey.diagrams) colors = cycle(['orange', 'b', 'g', 'r', 'c', 'm', 'y']) for i in range(0, 2*n, 2): sankey.add(flows=[1, -1], orientations=[-1, -1], - patchlabel=str(prior+i), facecolor=colors.next(), + patchlabel=str(prior+i), facecolor=next(colors), prior=prior+i-1, connect=(1, 0), alpha=0.5) sankey.add(flows=[1, -1], orientations=[1, 1], - patchlabel=str(prior+i+1), facecolor=colors.next(), + patchlabel=str(prior+i+1), facecolor=next(colors), prior=prior+i, connect=(1, 0), alpha=0.5) + + def corner(sankey): - """Generate a corner link. - """ + """Generate a corner link.""" prior = len(sankey.diagrams) sankey.add(flows=[1, -1], orientations=[0, 1], patchlabel=str(prior), facecolor='k', prior=prior-1, connect=(1, 0), alpha=0.5) + + fig = plt.figure() ax = fig.add_subplot(1, 1, 1, xticks=[], yticks=[], title="Why would you want to do this?\n(But you could.)") diff -Nru matplotlib-1.1.1/lib/mpl_examples/api/sankey_demo_old.py matplotlib-1.2.0/lib/mpl_examples/api/sankey_demo_old.py --- matplotlib-1.1.1/lib/mpl_examples/api/sankey_demo_old.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/api/sankey_demo_old.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,12 @@ #!/usr/bin/env python +from __future__ import print_function + __author__ = "Yannick Copin " __version__ = "Time-stamp: <10/02/2010 16:49 ycopin@lyopc548.in2p3.fr>" -import numpy as N +import numpy as np + def sankey(ax, outputs=[100.], outlabels=None, @@ -11,143 +14,142 @@ dx=40, dy=10, outangle=45, w=3, inangle=30, offset=2, **kwargs): """Draw a Sankey diagram. -outputs: array of outputs, should sum up to 100% -outlabels: output labels (same length as outputs), -or None (use default labels) or '' (no labels) -inputs and inlabels: similar for inputs -dx: horizontal elongation -dy: vertical elongation -outangle: output arrow angle [deg] -w: output arrow shoulder -inangle: input dip angle -offset: text offset -**kwargs: propagated to Patch (e.g. fill=False) - -Return (patch,[intexts,outtexts]).""" + outputs: array of outputs, should sum up to 100% + outlabels: output labels (same length as outputs), + or None (use default labels) or '' (no labels) + inputs and inlabels: similar for inputs + dx: horizontal elongation + dy: vertical elongation + outangle: output arrow angle [deg] + w: output arrow shoulder + inangle: input dip angle + offset: text offset + **kwargs: propagated to Patch (e.g. fill=False) + Return (patch,[intexts,outtexts]). + """ import matplotlib.patches as mpatches from matplotlib.path import Path - outs = N.absolute(outputs) - outsigns = N.sign(outputs) - outsigns[-1] = 0 # Last output - - ins = N.absolute(inputs) - insigns = N.sign(inputs) - insigns[0] = 0 # First input + outs = np.absolute(outputs) + outsigns = np.sign(outputs) + outsigns[-1] = 0 # Last output + + ins = np.absolute(inputs) + insigns = np.sign(inputs) + insigns[0] = 0 # First input - assert sum(outs)==100, "Outputs don't sum up to 100%" - assert sum(ins)==100, "Inputs don't sum up to 100%" + assert sum(outs) == 100, "Outputs don't sum up to 100%" + assert sum(ins) == 100, "Inputs don't sum up to 100%" def add_output(path, loss, sign=1): - h = (loss/2+w)*N.tan(outangle/180.*N.pi) # Arrow tip height - move,(x,y) = path[-1] # Use last point as reference - if sign==0: # Final loss (horizontal) - path.extend([(Path.LINETO,[x+dx,y]), - (Path.LINETO,[x+dx,y+w]), - (Path.LINETO,[x+dx+h,y-loss/2]), # Tip - (Path.LINETO,[x+dx,y-loss-w]), - (Path.LINETO,[x+dx,y-loss])]) - outtips.append((sign,path[-3][1])) - else: # Intermediate loss (vertical) - path.extend([(Path.CURVE4,[x+dx/2,y]), - (Path.CURVE4,[x+dx,y]), - (Path.CURVE4,[x+dx,y+sign*dy]), - (Path.LINETO,[x+dx-w,y+sign*dy]), - (Path.LINETO,[x+dx+loss/2,y+sign*(dy+h)]), # Tip - (Path.LINETO,[x+dx+loss+w,y+sign*dy]), - (Path.LINETO,[x+dx+loss,y+sign*dy]), - (Path.CURVE3,[x+dx+loss,y-sign*loss]), - (Path.CURVE3,[x+dx/2+loss,y-sign*loss])]) - outtips.append((sign,path[-5][1])) + h = (loss/2 + w)*np.tan(outangle/180. * np.pi) # Arrow tip height + move, (x, y) = path[-1] # Use last point as reference + if sign == 0: # Final loss (horizontal) + path.extend([(Path.LINETO, [x+dx, y]), + (Path.LINETO, [x+dx, y+w]), + (Path.LINETO, [x+dx+h, y-loss/2]), # Tip + (Path.LINETO, [x+dx, y-loss-w]), + (Path.LINETO, [x+dx, y-loss])]) + outtips.append((sign, path[-3][1])) + else: # Intermediate loss (vertical) + path.extend([(Path.CURVE4, [x+dx/2, y]), + (Path.CURVE4, [x+dx, y]), + (Path.CURVE4, [x+dx, y+sign*dy]), + (Path.LINETO, [x+dx-w, y+sign*dy]), + (Path.LINETO, [x+dx+loss/2, y+sign*(dy+h)]), # Tip + (Path.LINETO, [x+dx+loss+w, y+sign*dy]), + (Path.LINETO, [x+dx+loss, y+sign*dy]), + (Path.CURVE3, [x+dx+loss, y-sign*loss]), + (Path.CURVE3, [x+dx/2+loss, y-sign*loss])]) + outtips.append((sign, path[-5][1])) def add_input(path, gain, sign=1): - h = (gain/2)*N.tan(inangle/180.*N.pi) # Dip depth - move,(x,y) = path[-1] # Use last point as reference - if sign==0: # First gain (horizontal) - path.extend([(Path.LINETO,[x-dx,y]), - (Path.LINETO,[x-dx+h,y+gain/2]), # Dip - (Path.LINETO,[x-dx,y+gain])]) - xd,yd = path[-2][1] # Dip position - indips.append((sign,[xd-h,yd])) - else: # Intermediate gain (vertical) - path.extend([(Path.CURVE4,[x-dx/2,y]), - (Path.CURVE4,[x-dx,y]), - (Path.CURVE4,[x-dx,y+sign*dy]), - (Path.LINETO,[x-dx-gain/2,y+sign*(dy-h)]), # Dip - (Path.LINETO,[x-dx-gain,y+sign*dy]), - (Path.CURVE3,[x-dx-gain,y-sign*gain]), - (Path.CURVE3,[x-dx/2-gain,y-sign*gain])]) - xd,yd = path[-4][1] # Dip position - indips.append((sign,[xd,yd+sign*h])) - - outtips = [] # Output arrow tip dir. and positions - urpath = [(Path.MOVETO,[0,100])] # 1st point of upper right path - lrpath = [(Path.LINETO,[0,0])] # 1st point of lower right path - for loss,sign in zip(outs,outsigns): + h = (gain/2)*np.tan(inangle/180. * np.pi) # Dip depth + move, (x, y) = path[-1] # Use last point as reference + if sign == 0: # First gain (horizontal) + path.extend([(Path.LINETO, [x-dx, y]), + (Path.LINETO, [x-dx+h, y+gain/2]), # Dip + (Path.LINETO, [x-dx, y+gain])]) + xd, yd = path[-2][1] # Dip position + indips.append((sign, [xd-h, yd])) + else: # Intermediate gain (vertical) + path.extend([(Path.CURVE4, [x-dx/2, y]), + (Path.CURVE4, [x-dx, y]), + (Path.CURVE4, [x-dx, y+sign*dy]), + (Path.LINETO, [x-dx-gain/2, y+sign*(dy-h)]), # Dip + (Path.LINETO, [x-dx-gain, y+sign*dy]), + (Path.CURVE3, [x-dx-gain, y-sign*gain]), + (Path.CURVE3, [x-dx/2-gain, y-sign*gain])]) + xd, yd = path[-4][1] # Dip position + indips.append((sign, [xd, yd+sign*h])) + + outtips = [] # Output arrow tip dir. and positions + urpath = [(Path.MOVETO, [0, 100])] # 1st point of upper right path + lrpath = [(Path.LINETO, [0, 0])] # 1st point of lower right path + for loss, sign in zip(outs, outsigns): add_output(sign>=0 and urpath or lrpath, loss, sign=sign) - indips = [] # Input arrow tip dir. and positions - llpath = [(Path.LINETO,[0,0])] # 1st point of lower left path - ulpath = [(Path.MOVETO,[0,100])] # 1st point of upper left path - for gain,sign in zip(ins,insigns)[::-1]: + indips = [] # Input arrow tip dir. and positions + llpath = [(Path.LINETO, [0, 0])] # 1st point of lower left path + ulpath = [(Path.MOVETO, [0, 100])] # 1st point of upper left path + for gain, sign in reversed(list(zip(ins, insigns))): add_input(sign<=0 and llpath or ulpath, gain, sign=sign) def revert(path): """A path is not just revertable by path[::-1] because of Bezier -curves.""" + curves.""" rpath = [] nextmove = Path.LINETO - for move,pos in path[::-1]: - rpath.append((nextmove,pos)) + for move, pos in path[::-1]: + rpath.append((nextmove, pos)) nextmove = move return rpath # Concatenate subpathes in correct order path = urpath + revert(lrpath) + llpath + revert(ulpath) - codes,verts = zip(*path) - verts = N.array(verts) + codes, verts = zip(*path) + verts = np.array(verts) # Path patch - path = Path(verts,codes) + path = Path(verts, codes) patch = mpatches.PathPatch(path, **kwargs) ax.add_patch(patch) - if False: # DEBUG - print "urpath", urpath - print "lrpath", revert(lrpath) - print "llpath", llpath - print "ulpath", revert(ulpath) - - xs,ys = zip(*verts) - ax.plot(xs,ys,'go-') + if False: # DEBUG + print("urpath", urpath) + print("lrpath", revert(lrpath)) + print("llpath", llpath) + print("ulpath", revert(ulpath)) + xs, ys = zip(*verts) + ax.plot(xs, ys, 'go-') # Labels - def set_labels(labels,values): + def set_labels(labels, values): """Set or check labels according to values.""" - if labels=='': # No labels + if labels == '': # No labels return labels - elif labels is None: # Default labels - return [ '%2d%%' % val for val in values ] + elif labels is None: # Default labels + return ['%2d%%' % val for val in values] else: - assert len(labels)==len(values) + assert len(labels) == len(values) return labels - def put_labels(labels,positions,output=True): + def put_labels(labels, positions, output=True): """Put labels to positions.""" texts = [] lbls = output and labels or labels[::-1] - for i,label in enumerate(lbls): - s,(x,y) = positions[i] # Label direction and position - if s==0: - t = ax.text(x+offset,y,label, + for i, label in enumerate(lbls): + s, (x, y) = positions[i] # Label direction and position + if s == 0: + t = ax.text(x+offset, y, label, ha=output and 'left' or 'right', va='center') - elif s>0: - t = ax.text(x,y+offset,label, ha='center', va='bottom') + elif s > 0: + t = ax.text(x, y+offset, label, ha='center', va='bottom') else: - t = ax.text(x,y-offset,label, ha='center', va='top') + t = ax.text(x, y-offset, label, ha='center', va='top') texts.append(t) return texts @@ -158,32 +160,30 @@ intexts = put_labels(inlabels, indips, output=False) # Axes management - ax.set_xlim(verts[:,0].min()-dx, verts[:,0].max()+dx) - ax.set_ylim(verts[:,1].min()-dy, verts[:,1].max()+dy) + ax.set_xlim(verts[:, 0].min()-dx, verts[:, 0].max()+dx) + ax.set_ylim(verts[:, 1].min()-dy, verts[:, 1].max()+dy) ax.set_aspect('equal', adjustable='datalim') - return patch,[intexts,outtexts] + return patch, [intexts, outtexts] + if __name__=='__main__': - import matplotlib.pyplot as P + import matplotlib.pyplot as plt - outputs = [10.,-20.,5.,15.,-10.,40.] - outlabels = ['First','Second','Third','Fourth','Fifth','Hurray!'] - outlabels = [ s+'\n%d%%' % abs(l) for l,s in zip(outputs,outlabels) ] - - inputs = [60.,-25.,15.] - - fig = P.figure() - ax = fig.add_subplot(1,1,1, xticks=[],yticks=[], - title="Sankey diagram" - ) - - patch,(intexts,outtexts) = sankey(ax, outputs=outputs, outlabels=outlabels, - inputs=inputs, inlabels=None, - fc='g', alpha=0.2) + outputs = [10., -20., 5., 15., -10., 40.] + outlabels = ['First', 'Second', 'Third', 'Fourth', 'Fifth', 'Hurray!'] + outlabels = [s+'\n%d%%' % abs(l) for l, s in zip(outputs, outlabels)] + + inputs = [60., -25., 15.] + + fig = plt.figure() + ax = fig.add_subplot(1, 1, 1, xticks=[], yticks=[], title="Sankey diagram") + + patch, (intexts, outtexts) = sankey(ax, outputs=outputs, + outlabels=outlabels, inputs=inputs, + inlabels=None, fc='g', alpha=0.2) outtexts[1].set_color('r') outtexts[-1].set_fontweight('bold') - P.show() - + plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/api/scatter_piecharts.py matplotlib-1.2.0/lib/mpl_examples/api/scatter_piecharts.py --- matplotlib-1.1.1/lib/mpl_examples/api/scatter_piecharts.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/api/scatter_piecharts.py 2012-10-31 00:11:13.000000000 +0000 @@ -20,16 +20,16 @@ # some points on a circle cos,sin x = [0] + np.cos(np.linspace(0, 2*math.pi*r1, 10)).tolist() y = [0] + np.sin(np.linspace(0, 2*math.pi*r1, 10)).tolist() -xy1 = zip(x,y) +xy1 = list(zip(x,y)) # ... x = [0] + np.cos(np.linspace(2*math.pi*r1, 2*math.pi*r2, 10)).tolist() y = [0] + np.sin(np.linspace(2*math.pi*r1, 2*math.pi*r2, 10)).tolist() -xy2 = zip(x,y) +xy2 = list(zip(x,y)) x = [0] + np.cos(np.linspace(2*math.pi*r2, 2*math.pi, 10)).tolist() y = [0] + np.sin(np.linspace(2*math.pi*r2, 2*math.pi, 10)).tolist() -xy3 = zip(x,y) +xy3 = list(zip(x,y)) fig = plt.figure() diff -Nru matplotlib-1.1.1/lib/mpl_examples/api/watermark_image.py matplotlib-1.2.0/lib/mpl_examples/api/watermark_image.py --- matplotlib-1.1.1/lib/mpl_examples/api/watermark_image.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/api/watermark_image.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,7 @@ """ Use a PNG file as a watermark """ +from __future__ import print_function import numpy as np import matplotlib import matplotlib.cbook as cbook @@ -8,7 +9,7 @@ import matplotlib.pyplot as plt datafile = cbook.get_sample_data('logo2.png', asfileobj=False) -print 'loading', datafile +print ('loading %s' % datafile) im = image.imread(datafile) im[:,:,-1] = 0.5 # set the alpha channel diff -Nru matplotlib-1.1.1/lib/mpl_examples/axes_grid/demo_edge_colorbar.py matplotlib-1.2.0/lib/mpl_examples/axes_grid/demo_edge_colorbar.py --- matplotlib-1.1.1/lib/mpl_examples/axes_grid/demo_edge_colorbar.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/axes_grid/demo_edge_colorbar.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,89 @@ +import matplotlib.pyplot as plt +from mpl_toolkits.axes_grid1 import AxesGrid + +def get_demo_image(): + import numpy as np + from matplotlib.cbook import get_sample_data + f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False) + z = np.load(f) + # z is a numpy array of 15x15 + return z, (-3,4,-4,3) + + +def demo_bottom_cbar(fig): + """ + A grid of 2x2 images with a colorbar for each column. + """ + grid = AxesGrid(fig, 121, # similar to subplot(132) + nrows_ncols = (2, 2), + axes_pad = 0.10, + share_all=True, + label_mode = "1", + cbar_location = "bottom", + cbar_mode="edge", + cbar_pad = 0.25, + cbar_size = "15%", + direction="column" + ) + + Z, extent = get_demo_image() + cmaps = [plt.get_cmap("autumn"), plt.get_cmap("summer")] + for i in range(4): + im = grid[i].imshow(Z, extent=extent, interpolation="nearest", + cmap=cmaps[i//2]) + if i % 2: + cbar = grid.cbar_axes[i//2].colorbar(im) + + for cax in grid.cbar_axes: + cax.toggle_label(True) + cax.axis[cax.orientation].set_label("Bar") + + # This affects all axes as share_all = True. + grid.axes_llc.set_xticks([-2, 0, 2]) + grid.axes_llc.set_yticks([-2, 0, 2]) + + +def demo_right_cbar(fig): + """ + A grid of 2x2 images. Each row has its own colorbar. + """ + + grid = AxesGrid(F, 122, # similar to subplot(122) + nrows_ncols = (2, 2), + axes_pad = 0.10, + label_mode = "1", + share_all = True, + cbar_location="right", + cbar_mode="edge", + cbar_size="7%", + cbar_pad="2%", + ) + Z, extent = get_demo_image() + cmaps = [plt.get_cmap("spring"), plt.get_cmap("winter")] + for i in range(4): + im = grid[i].imshow(Z, extent=extent, interpolation="nearest", + cmap=cmaps[i//2]) + if i % 2: + grid.cbar_axes[i//2].colorbar(im) + + for cax in grid.cbar_axes: + cax.toggle_label(True) + cax.axis[cax.orientation].set_label('Foo') + + # This affects all axes because we set share_all = True. + grid.axes_llc.set_xticks([-2, 0, 2]) + grid.axes_llc.set_yticks([-2, 0, 2]) + + + +if 1: + F = plt.figure(1, (5.5, 2.5)) + + F.subplots_adjust(left=0.05, right=0.93) + + demo_bottom_cbar(F) + demo_right_cbar(F) + + plt.draw() + plt.show() + diff -Nru matplotlib-1.1.1/lib/mpl_examples/event_handling/close_event.py matplotlib-1.2.0/lib/mpl_examples/event_handling/close_event.py --- matplotlib-1.1.1/lib/mpl_examples/event_handling/close_event.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/event_handling/close_event.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,8 @@ +from __future__ import print_function import matplotlib.pyplot as plt def handle_close(evt): - print 'Closed Figure!' + print('Closed Figure!') fig = plt.figure() fig.canvas.mpl_connect('close_event', handle_close) diff -Nru matplotlib-1.1.1/lib/mpl_examples/event_handling/data_browser.py matplotlib-1.2.0/lib/mpl_examples/event_handling/data_browser.py --- matplotlib-1.1.1/lib/mpl_examples/event_handling/data_browser.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/event_handling/data_browser.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,22 +1,11 @@ import numpy as np -from pylab import figure, show -X = np.random.rand(100, 200) -xs = np.mean(X, axis=1) -ys = np.std(X, axis=1) - -fig = figure() -ax = fig.add_subplot(211) -ax.set_title('click on point to plot time series') -line, = ax.plot(xs, ys, 'o', picker=5) # 5 points tolerance -ax2 = fig.add_subplot(212) - class PointBrowser: """ Click on a point to select and highlight it -- the data that generated the point will be shown in the lower axes. Use the 'n' - and 'p' keys to browse through the next and pervious points + and 'p' keys to browse through the next and previous points """ def __init__(self): self.lastind = 0 @@ -74,9 +63,23 @@ fig.canvas.draw() -browser = PointBrowser() +if __name__ == '__main__': + import matplotlib.pyplot as plt + + X = np.random.rand(100, 200) + xs = np.mean(X, axis=1) + ys = np.std(X, axis=1) + + fig = plt.figure() + ax = fig.add_subplot(211) + ax.set_title('click on point to plot time series') + line, = ax.plot(xs, ys, 'o', picker=5) # 5 points tolerance + ax2 = fig.add_subplot(212) + + browser = PointBrowser() + + fig.canvas.mpl_connect('pick_event', browser.onpick) + fig.canvas.mpl_connect('key_press_event', browser.onpress) -fig.canvas.mpl_connect('pick_event', browser.onpick) -fig.canvas.mpl_connect('key_press_event', browser.onpress) + plt.show() -show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/event_handling/figure_axes_enter_leave.py matplotlib-1.2.0/lib/mpl_examples/event_handling/figure_axes_enter_leave.py --- matplotlib-1.1.1/lib/mpl_examples/event_handling/figure_axes_enter_leave.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/event_handling/figure_axes_enter_leave.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,25 +2,26 @@ Illustrate the figure and axes enter and leave events by changing the frame colors on enter and leave """ +from __future__ import print_function import matplotlib.pyplot as plt def enter_axes(event): - print 'enter_axes', event.inaxes + print('enter_axes', event.inaxes) event.inaxes.patch.set_facecolor('yellow') event.canvas.draw() def leave_axes(event): - print 'leave_axes', event.inaxes + print('leave_axes', event.inaxes) event.inaxes.patch.set_facecolor('white') event.canvas.draw() def enter_figure(event): - print 'enter_figure', event.canvas.figure + print('enter_figure', event.canvas.figure) event.canvas.figure.patch.set_facecolor('red') event.canvas.draw() def leave_figure(event): - print 'leave_figure', event.canvas.figure + print('leave_figure', event.canvas.figure) event.canvas.figure.patch.set_facecolor('grey') event.canvas.draw() diff -Nru matplotlib-1.1.1/lib/mpl_examples/event_handling/idle_and_timeout.py matplotlib-1.2.0/lib/mpl_examples/event_handling/idle_and_timeout.py --- matplotlib-1.1.1/lib/mpl_examples/event_handling/idle_and_timeout.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/event_handling/idle_and_timeout.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function """ Demonstrate/test the idle and timeout API @@ -18,7 +19,7 @@ N = 100 def on_idle(event): on_idle.count +=1 - print 'idle', on_idle.count + print('idle', on_idle.count) line1.set_ydata(np.sin(2*np.pi*t*(N-on_idle.count)/float(N))) event.canvas.draw() # test boolean return removal diff -Nru matplotlib-1.1.1/lib/mpl_examples/event_handling/keypress_demo.py matplotlib-1.2.0/lib/mpl_examples/event_handling/keypress_demo.py --- matplotlib-1.1.1/lib/mpl_examples/event_handling/keypress_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/event_handling/keypress_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,23 +1,26 @@ #!/usr/bin/env python + """ Show how to connect to keypress events """ -import numpy as n -from pylab import figure, show +from __future__ import print_function +import numpy as np +import matplotlib.pyplot as plt + def press(event): - print 'press', event.key + print('press', event.key) if event.key=='x': visible = xl.get_visible() xl.set_visible(not visible) fig.canvas.draw() -fig = figure() +fig = plt.figure() ax = fig.add_subplot(111) fig.canvas.mpl_connect('key_press_event', press) -ax.plot(n.random.rand(12), n.random.rand(12), 'go') +ax.plot(np.random.rand(12), np.random.rand(12), 'go') xl = ax.set_xlabel('easy come, easy go') -show() +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/event_handling/lasso_demo.py matplotlib-1.2.0/lib/mpl_examples/event_handling/lasso_demo.py --- matplotlib-1.1.1/lib/mpl_examples/event_handling/lasso_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/event_handling/lasso_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -4,21 +4,20 @@ selected points This is currently a proof-of-concept implementation (though it is -usable as is). There will be some refinement of the API and the -inside polygon detection routine. +usable as is). There will be some refinement of the API. """ from matplotlib.widgets import Lasso -from matplotlib.nxutils import points_inside_poly from matplotlib.colors import colorConverter from matplotlib.collections import RegularPolyCollection +from matplotlib import path -from matplotlib.pyplot import figure, show +import matplotlib.pyplot as plt from numpy import nonzero from numpy.random import rand -class Datum: +class Datum(object): colorin = colorConverter.to_rgba('red') - colorout = colorConverter.to_rgba('green') + colorout = colorConverter.to_rgba('blue') def __init__(self, x, y, include=False): self.x = x self.y = y @@ -26,7 +25,7 @@ else: self.color = self.colorout -class LassoManager: +class LassoManager(object): def __init__(self, ax, data): self.axes = ax self.canvas = ax.figure.canvas @@ -46,13 +45,13 @@ ax.add_collection(self.collection) self.cid = self.canvas.mpl_connect('button_press_event', self.onpress) - self.ind = None def callback(self, verts): facecolors = self.collection.get_facecolors() - ind = nonzero(points_inside_poly(self.xys, verts))[0] - for i in range(self.Nxy): - if i in ind: + p = path.Path(verts) + ind = p.contains_points(self.xys) + for i in range(len(self.xys)): + if ind[i]: facecolors[i] = Datum.colorin else: facecolors[i] = Datum.colorout @@ -60,7 +59,7 @@ self.canvas.draw_idle() self.canvas.widgetlock.release(self.lasso) del self.lasso - self.ind = ind + def onpress(self, event): if self.canvas.widgetlock.locked(): return if event.inaxes is None: return @@ -72,8 +71,7 @@ data = [Datum(*xy) for xy in rand(100, 2)] - fig = figure() - ax = fig.add_subplot(111, xlim=(0,1), ylim=(0,1), autoscale_on=False) + ax = plt.axes(xlim=(0,1), ylim=(0,1), autoscale_on=False) lman = LassoManager(ax, data) - show() + plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/event_handling/legend_picking.py matplotlib-1.2.0/lib/mpl_examples/event_handling/legend_picking.py --- matplotlib-1.1.1/lib/mpl_examples/event_handling/legend_picking.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/event_handling/legend_picking.py 2012-10-31 00:11:13.000000000 +0000 @@ -28,7 +28,7 @@ def onpick(event): # on the pick event, find the orig line corresponding to the - # legend proxy line, and toggle the visibilit + # legend proxy line, and toggle the visibility legline = event.artist origline = lined[legline] vis = not origline.get_visible() diff -Nru matplotlib-1.1.1/lib/mpl_examples/event_handling/path_editor.py matplotlib-1.2.0/lib/mpl_examples/event_handling/path_editor.py --- matplotlib-1.1.1/lib/mpl_examples/event_handling/path_editor.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/event_handling/path_editor.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,7 +2,6 @@ import matplotlib.path as mpath import matplotlib.patches as mpatches import matplotlib.pyplot as plt -import matplotlib.mlab as mlab Path = mpath.Path diff -Nru matplotlib-1.1.1/lib/mpl_examples/event_handling/pick_event_demo.py matplotlib-1.2.0/lib/mpl_examples/event_handling/pick_event_demo.py --- matplotlib-1.1.1/lib/mpl_examples/event_handling/pick_event_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/event_handling/pick_event_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,8 +1,9 @@ #!/usr/bin/env python + """ -You can enable picking by setting the"picker" property of an artist -(eg a matplotlib Line2D, Text, Patch, Polygon, AxesImage, +You can enable picking by setting the "picker" property of an artist +(for example, a matplotlib Line2D, Text, Patch, Polygon, AxesImage, etc...) There are a variety of meanings of the picker property @@ -14,27 +15,27 @@ the artist float - if picker is a number it is interpreted as an - epsilon tolerance in points and the the artist will fire + epsilon tolerance in points and the artist will fire off an event if it's data is within epsilon of the mouse event. For some artists like lines and patch collections, the artist may provide additional data to the pick event - that is generated, eg the indices of the data within + that is generated, for example, the indices of the data within epsilon of the pick event - function - if picker is callable, it is a user supplied + function - if picker is callable, it is a user supplied function which determines whether the artist is hit by the mouse event. hit, props = picker(artist, mouseevent) - to determine the hit test. if the mouse event is over the + to determine the hit test. If the mouse event is over the artist, return hit=True and props is a dictionary of properties you want added to the PickEvent attributes After you have enabled an artist for picking by setting the "picker" property, you need to connect to the figure canvas pick_event to get -pick callbacks on mouse press events. Eg, +pick callbacks on mouse press events. For example, def pick_handler(event): mouseevent = event.mouseevent @@ -46,9 +47,9 @@ your callback is always fired with two attributes: mouseevent - the mouse event that generate the pick event. The - mouse event in turn has attributes like x and y (the coords in - display space, eg pixels from left, bottom) and xdata, ydata (the - coords in data space). Additionaly, you can get information about + mouse event in turn has attributes like x and y (the coordinates in + display space, such as pixels from left, bottom) and xdata, ydata (the + coords in data space). Additionally, you can get information about which buttons were pressed, which keys were pressed, which Axes the mouse is over, etc. See matplotlib.backend_bases.MouseEvent for details. @@ -57,18 +58,19 @@ Additionally, certain artists like Line2D and PatchCollection may attach additional meta data like the indices into the data that meet -the picker criteria (eg all the points in the line that are within the -specified epsilon tolerance) +the picker criteria (for example, all the points in the line that are within +the specified epsilon tolerance) The examples below illustrate each of these methods. """ +from __future__ import print_function from matplotlib.pyplot import figure, show from matplotlib.lines import Line2D -from matplotlib.patches import Patch, Rectangle +from matplotlib.patches import Rectangle from matplotlib.text import Text from matplotlib.image import AxesImage -import numpy as npy +import numpy as np from numpy.random import rand if 1: # simple picking, lines, rectangles and text @@ -92,13 +94,13 @@ xdata = thisline.get_xdata() ydata = thisline.get_ydata() ind = event.ind - print 'onpick1 line:', zip(npy.take(xdata, ind), npy.take(ydata, ind)) + print('onpick1 line:', zip(np.take(xdata, ind), np.take(ydata, ind))) elif isinstance(event.artist, Rectangle): patch = event.artist - print 'onpick1 patch:', patch.get_path() + print('onpick1 patch:', patch.get_path()) elif isinstance(event.artist, Text): text = event.artist - print 'onpick1 text:', text.get_text() + print('onpick1 text:', text.get_text()) @@ -124,19 +126,19 @@ xdata = line.get_xdata() ydata = line.get_ydata() maxd = 0.05 - d = npy.sqrt((xdata-mouseevent.xdata)**2. + (ydata-mouseevent.ydata)**2.) + d = np.sqrt((xdata-mouseevent.xdata)**2. + (ydata-mouseevent.ydata)**2.) - ind = npy.nonzero(npy.less_equal(d, maxd)) + ind = np.nonzero(np.less_equal(d, maxd)) if len(ind): - pickx = npy.take(xdata, ind) - picky = npy.take(ydata, ind) + pickx = np.take(xdata, ind) + picky = np.take(ydata, ind) props = dict(ind=ind, pickx=pickx, picky=picky) return True, props else: return False, dict() def onpick2(event): - print 'onpick2 line:', event.pickx, event.picky + print('onpick2 line:', event.pickx, event.picky) fig = figure() ax1 = fig.add_subplot(111) @@ -150,7 +152,7 @@ x, y, c, s = rand(4, 100) def onpick3(event): ind = event.ind - print 'onpick3 scatter:', ind, npy.take(x, ind), npy.take(y, ind) + print('onpick3 scatter:', ind, np.take(x, ind), np.take(y, ind)) fig = figure() ax1 = fig.add_subplot(111) @@ -172,7 +174,7 @@ if isinstance(artist, AxesImage): im = artist A = im.get_array() - print 'onpick4 image', A.shape + print('onpick4 image', A.shape) fig.canvas.mpl_connect('pick_event', onpick4) diff -Nru matplotlib-1.1.1/lib/mpl_examples/event_handling/pick_event_demo2.py matplotlib-1.2.0/lib/mpl_examples/event_handling/pick_event_demo2.py --- matplotlib-1.1.1/lib/mpl_examples/event_handling/pick_event_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/event_handling/pick_event_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,17 +1,17 @@ """ -compute the mean and stddev of 100 data sets and plot mean vs stddev. -When you click on one of the mu, sigma points, plot the raw data from -the dataset that generated the mean and stddev +compute the mean and standard deviation (stddev) of 100 data sets and plot +mean vs stddev. When you click on one of the mu, sigma points, plot the raw +data from the dataset that generated the mean and stddev. """ import numpy -from pylab import figure, show +import matplotlib.pyplot as plt X = numpy.random.rand(100, 1000) xs = numpy.mean(X, axis=1) ys = numpy.std(X, axis=1) -fig = figure() +fig = plt.figure() ax = fig.add_subplot(111) ax.set_title('click on point to plot time series') line, = ax.plot(xs, ys, 'o', picker=5) # 5 points tolerance @@ -25,19 +25,19 @@ if not N: return True - figi = figure() + figi = plt.figure() for subplotnum, dataind in enumerate(event.ind): ax = figi.add_subplot(N,1,subplotnum+1) ax.plot(X[dataind]) ax.text(0.05, 0.9, 'mu=%1.3f\nsigma=%1.3f'%(xs[dataind], ys[dataind]), transform=ax.transAxes, va='top') - ax.set_ylim(-0.5, 1.5) + ax.set_ylim(-0.5, 1.5) figi.show() return True fig.canvas.mpl_connect('pick_event', onpick) -show() +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/event_handling/pipong.py matplotlib-1.2.0/lib/mpl_examples/event_handling/pipong.py --- matplotlib-1.1.1/lib/mpl_examples/event_handling/pipong.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/event_handling/pipong.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,8 +1,10 @@ #!/usr/bin/env python # A matplotlib based game of Pong illustrating one way to write interactive -# animation which are easily ported to multiply backends +# animation which are easily ported to multiple backends # pipong.py was written by Paul Ivanov +from __future__ import print_function + import numpy as np import matplotlib.pyplot as plt from numpy.random import randn, randint @@ -200,7 +202,7 @@ if self.cnt==50000: # just so we don't get carried away - print "...and you've been playing for too long!!!" + print("...and you've been playing for too long!!!") plt.close() self.cnt += 1 diff -Nru matplotlib-1.1.1/lib/mpl_examples/event_handling/poly_editor.py matplotlib-1.2.0/lib/mpl_examples/event_handling/poly_editor.py --- matplotlib-1.1.1/lib/mpl_examples/event_handling/poly_editor.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/event_handling/poly_editor.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,9 +3,9 @@ matplotlib event handling to interact with objects on the canvas """ +import numpy as np +from matplotlib.lines import Line2D from matplotlib.artist import Artist -from matplotlib.patches import Polygon, CirclePolygon -from numpy import sqrt, nonzero, equal, array, asarray, dot, amin, cos, sin from matplotlib.mlab import dist_point_to_segment @@ -36,7 +36,7 @@ self.poly = poly x, y = zip(*self.poly.xy) - self.line = Line2D(x,y,marker='o', markerfacecolor='r', animated=True) + self.line = Line2D(x, y, marker='o', markerfacecolor='r', animated=True) self.ax.add_line(self.line) #self._update_line(poly) @@ -69,11 +69,11 @@ 'get the index of the vertex under point if within epsilon tolerance' # display coords - xy = asarray(self.poly.xy) + xy = np.asarray(self.poly.xy) xyt = self.poly.get_transform().transform(xy) xt, yt = xyt[:, 0], xyt[:, 1] - d = sqrt((xt-event.x)**2 + (yt-event.y)**2) - indseq = nonzero(equal(d, amin(d)))[0] + d = np.sqrt((xt-event.x)**2 + (yt-event.y)**2) + indseq = np.nonzero(np.equal(d, np.amin(d)))[0] ind = indseq[0] if d[ind]>=self.epsilon: @@ -114,7 +114,7 @@ s1 = xys[i+1] d = dist_point_to_segment(p, s0, s1) if d<=self.epsilon: - self.poly.xy = array( + self.poly.xy = np.array( list(self.poly.xy[:i]) + [(event.xdata, event.ydata)] + list(self.poly.xy[i:])) @@ -141,31 +141,26 @@ self.canvas.blit(self.ax.bbox) +if __name__ == '__main__': + import matplotlib.pyplot as plt + from matplotlib.patches import Polygon + + fig = plt.figure() + theta = np.arange(0, 2*np.pi, 0.1) + r = 1.5 + + xs = r*np.cos(theta) + ys = r*np.sin(theta) + + poly = Polygon(list(zip(xs, ys)), animated=True) + + ax = plt.subplot(111) + ax.add_patch(poly) + p = PolygonInteractor(ax, poly) + + #ax.add_line(p.line) + ax.set_title('Click and drag a point to move it') + ax.set_xlim((-2,2)) + ax.set_ylim((-2,2)) + plt.show() -from pylab import * - - - - - -fig = figure() -theta = arange(0, 2*pi, 0.1) -r = 1.5 - -xs = r*cos(theta) -ys = r*sin(theta) - -poly = Polygon(zip(xs, ys,), animated=True) - - - - -ax = subplot(111) -ax.add_patch(poly) -p = PolygonInteractor( ax, poly) - -#ax.add_line(p.line) -ax.set_title('Click and drag a point to move it') -ax.set_xlim((-2,2)) -ax.set_ylim((-2,2)) -show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/event_handling/pong_gtk.py matplotlib-1.2.0/lib/mpl_examples/event_handling/pong_gtk.py --- matplotlib-1.1.1/lib/mpl_examples/event_handling/pong_gtk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/event_handling/pong_gtk.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import print_function + # For detailed comments on animation and the techniques used here, see # the wiki entry # http://www.scipy.org/wikis/topical_software/MatplotlibAnimation @@ -10,10 +12,8 @@ import matplotlib matplotlib.use('GTKAgg') -import numpy as np import matplotlib.pyplot as plt import pipong -from numpy.random import randn, randint fig = plt.figure() @@ -33,4 +33,4 @@ tstart = time.time() plt.grid() # to ensure proper background restore plt.show() -print 'FPS:' , animation.cnt/(time.time()-tstart) +print('FPS:' , animation.cnt/(time.time()-tstart)) diff -Nru matplotlib-1.1.1/lib/mpl_examples/event_handling/pong_qt.py matplotlib-1.2.0/lib/mpl_examples/event_handling/pong_qt.py --- matplotlib-1.1.1/lib/mpl_examples/event_handling/pong_qt.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/event_handling/pong_qt.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,8 @@ # For detailed comments on animation and the techniqes used here, see # the wiki entry http://www.scipy.org/Cookbook/Matplotlib/Animations -import os, sys +from __future__ import print_function + import matplotlib matplotlib.use('QtAgg') # qt3 example @@ -14,12 +15,9 @@ FALSE = 0 ITERS = 1000 -import pylab as p import matplotlib.pyplot as plt -import numpy as np import time import pipong -from numpy.random import randn, randint class BlitQT(QObject): def __init__(self): @@ -39,4 +37,4 @@ app.startTimer(10) plt.show() -print 'FPS:' , app.animation.cnt/(time.time()-app.tstart) +print('FPS:' , app.animation.cnt/(time.time()-app.tstart)) diff -Nru matplotlib-1.1.1/lib/mpl_examples/event_handling/test_mouseclicks.py matplotlib-1.2.0/lib/mpl_examples/event_handling/test_mouseclicks.py --- matplotlib-1.1.1/lib/mpl_examples/event_handling/test_mouseclicks.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/event_handling/test_mouseclicks.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,35 @@ +#!/usr/bin/env python +from __future__ import print_function + +import matplotlib +#matplotlib.use("WxAgg") +#matplotlib.use("TkAgg") +#matplotlib.use("GTKAgg") +#matplotlib.use("QtAgg") +#matplotlib.use("Qt4Agg") +#matplotlib.use("CocoaAgg") +#matplotlib.use("MacOSX") +import matplotlib.pyplot as plt + +#print("***** TESTING WITH BACKEND: %s"%matplotlib.get_backend() + " *****") + + +def OnClick(event): + if event.dblclick: + print("DBLCLICK", event) + else: + print("DOWN ", event) + + +def OnRelease(event): + print("UP ", event) + + +fig = plt.gcf() +cid_up = fig.canvas.mpl_connect('button_press_event', OnClick) +cid_down = fig.canvas.mpl_connect('button_release_event', OnRelease) + +plt.gca().text(0.5, 0.5, "Click on the canvas to test mouse events.", + ha="center", va="center") + +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/event_handling/viewlims.py matplotlib-1.2.0/lib/mpl_examples/event_handling/viewlims.py --- matplotlib-1.1.1/lib/mpl_examples/event_handling/viewlims.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/event_handling/viewlims.py 2012-10-31 00:11:13.000000000 +0000 @@ -30,7 +30,7 @@ threshold_time = np.zeros((self.height, self.width)) z = np.zeros(threshold_time.shape, dtype=np.complex) mask = np.ones(threshold_time.shape, dtype=np.bool) - for i in xrange(self.niter): + for i in range(self.niter): z[mask] = z[mask]**self.power + c[mask] mask = (np.abs(z) < self.radius) threshold_time += mask diff -Nru matplotlib-1.1.1/lib/mpl_examples/event_handling/zoom_window.py matplotlib-1.2.0/lib/mpl_examples/event_handling/zoom_window.py --- matplotlib-1.1.1/lib/mpl_examples/event_handling/zoom_window.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/event_handling/zoom_window.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,10 @@ """ -This example shows how to connect events in one window, eg a mouse +This example shows how to connect events in one window, for example, a mouse press, to another figure window. If you click on a point in the first window, the z and y limits of the second will be adjusted so that the center of the zoom in the second -window will be the x,y coords of the clicked point. +window will be the x,y coordinates of the clicked point. Note the diameter of the circles in the scatter are defined in points**2, so their size is independent of the zoom diff -Nru matplotlib-1.1.1/lib/mpl_examples/misc/developer_commit_history.py matplotlib-1.2.0/lib/mpl_examples/misc/developer_commit_history.py --- matplotlib-1.1.1/lib/mpl_examples/misc/developer_commit_history.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/misc/developer_commit_history.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function """ report how many days it has been since each developer committed. You must do an diff -Nru matplotlib-1.1.1/lib/mpl_examples/misc/font_indexing.py matplotlib-1.2.0/lib/mpl_examples/misc/font_indexing.py --- matplotlib-1.1.1/lib/mpl_examples/misc/font_indexing.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/misc/font_indexing.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,6 +3,7 @@ tables relate to one another. Mainly for mpl developers.... """ +from __future__ import print_function import matplotlib from matplotlib.ft2font import FT2Font, KERNING_DEFAULT, KERNING_UNFITTED, KERNING_UNSCALED @@ -34,8 +35,8 @@ code = coded['A'] glyph = font.load_char(code) #print glyph.bbox -print glyphd['A'], glyphd['V'], coded['A'], coded['V'] -print 'AV', font.get_kerning(glyphd['A'], glyphd['V'], KERNING_DEFAULT) -print 'AV', font.get_kerning(glyphd['A'], glyphd['V'], KERNING_UNFITTED) -print 'AV', font.get_kerning(glyphd['A'], glyphd['V'], KERNING_UNSCALED) -print 'AV', font.get_kerning(glyphd['A'], glyphd['T'], KERNING_UNSCALED) +print(glyphd['A'], glyphd['V'], coded['A'], coded['V']) +print('AV', font.get_kerning(glyphd['A'], glyphd['V'], KERNING_DEFAULT)) +print('AV', font.get_kerning(glyphd['A'], glyphd['V'], KERNING_UNFITTED)) +print('AV', font.get_kerning(glyphd['A'], glyphd['V'], KERNING_UNSCALED)) +print('AV', font.get_kerning(glyphd['A'], glyphd['T'], KERNING_UNSCALED)) diff -Nru matplotlib-1.1.1/lib/mpl_examples/misc/ftface_props.py matplotlib-1.2.0/lib/mpl_examples/misc/ftface_props.py --- matplotlib-1.1.1/lib/mpl_examples/misc/ftface_props.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/misc/ftface_props.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,6 @@ #!/usr/bin/env python + +from __future__ import print_function """ This is a demo script to show you how to use all the properties of an FT2Font object. These describe global font properties. For @@ -29,48 +31,48 @@ FT_STYLE_FLAG_ITALIC = 1 << 0 FT_STYLE_FLAG_BOLD = 1 << 1 -print 'Num faces :', font.num_faces # number of faces in file -print 'Num glyphs :', font.num_glyphs # number of glyphs in the face -print 'Family name :', font.family_name # face family name -print 'Syle name :', font.style_name # face syle name -print 'PS name :', font.postscript_name # the postscript name -print 'Num fixed :', font.num_fixed_sizes # number of embedded bitmap in face +print('Num faces :', font.num_faces) # number of faces in file +print('Num glyphs :', font.num_glyphs) # number of glyphs in the face +print('Family name :', font.family_name) # face family name +print('Syle name :', font.style_name) # face syle name +print('PS name :', font.postscript_name) # the postscript name +print('Num fixed :', font.num_fixed_sizes) # number of embedded bitmap in face # the following are only available if face.scalable if font.scalable: # the face global bounding box (xmin, ymin, xmax, ymax) - print 'Bbox :', font.bbox + print('Bbox :', font.bbox) # number of font units covered by the EM - print 'EM :', font.units_per_EM + print('EM :', font.units_per_EM) # the ascender in 26.6 units - print 'Ascender :', font.ascender + print('Ascender :', font.ascender) # the descender in 26.6 units - print 'Descender :', font.descender + print('Descender :', font.descender) # the height in 26.6 units - print 'Height :', font.height + print('Height :', font.height) # maximum horizontal cursor advance - print 'Max adv width :', font.max_advance_width + print('Max adv width :', font.max_advance_width) # same for vertical layout - print 'Max adv height :', font.max_advance_height + print('Max adv height :', font.max_advance_height) # vertical position of the underline bar - print 'Underline pos :', font.underline_position + print('Underline pos :', font.underline_position) # vertical thickness of the underline - print 'Underline thickness :', font.underline_thickness + print('Underline thickness :', font.underline_thickness) -print 'Italics :', font.style_flags & FT_STYLE_FLAG_ITALIC != 0 -print 'Bold :', font.style_flags & FT_STYLE_FLAG_BOLD != 0 -print 'Scalable :', font.style_flags & FT_FACE_FLAG_SCALABLE != 0 -print 'Fixed sizes :', font.style_flags & FT_FACE_FLAG_FIXED_SIZES != 0 -print 'Fixed width :', font.style_flags & FT_FACE_FLAG_FIXED_WIDTH != 0 -print 'SFNT :', font.style_flags & FT_FACE_FLAG_SFNT != 0 -print 'Horizontal :', font.style_flags & FT_FACE_FLAG_HORIZONTAL != 0 -print 'Vertical :', font.style_flags & FT_FACE_FLAG_VERTICAL != 0 -print 'Kerning :', font.style_flags & FT_FACE_FLAG_KERNING != 0 -print 'Fast glyphs :', font.style_flags & FT_FACE_FLAG_FAST_GLYPHS != 0 -print 'Mult. masters :', font.style_flags & FT_FACE_FLAG_MULTIPLE_MASTERS != 0 -print 'Glyph names :', font.style_flags & FT_FACE_FLAG_GLYPH_NAMES != 0 +print('Italics :', font.style_flags & FT_STYLE_FLAG_ITALIC != 0) +print('Bold :', font.style_flags & FT_STYLE_FLAG_BOLD != 0) +print('Scalable :', font.style_flags & FT_FACE_FLAG_SCALABLE != 0) +print('Fixed sizes :', font.style_flags & FT_FACE_FLAG_FIXED_SIZES != 0) +print('Fixed width :', font.style_flags & FT_FACE_FLAG_FIXED_WIDTH != 0) +print('SFNT :', font.style_flags & FT_FACE_FLAG_SFNT != 0) +print('Horizontal :', font.style_flags & FT_FACE_FLAG_HORIZONTAL != 0) +print('Vertical :', font.style_flags & FT_FACE_FLAG_VERTICAL != 0) +print('Kerning :', font.style_flags & FT_FACE_FLAG_KERNING != 0) +print('Fast glyphs :', font.style_flags & FT_FACE_FLAG_FAST_GLYPHS != 0) +print('Mult. masters :', font.style_flags & FT_FACE_FLAG_MULTIPLE_MASTERS != 0) +print('Glyph names :', font.style_flags & FT_FACE_FLAG_GLYPH_NAMES != 0) -print dir(font) +print(dir(font)) cmap = font.get_charmap() -print font.get_kerning +print(font.get_kerning) diff -Nru matplotlib-1.1.1/lib/mpl_examples/misc/image_thumbnail.py matplotlib-1.2.0/lib/mpl_examples/misc/image_thumbnail.py --- matplotlib-1.1.1/lib/mpl_examples/misc/image_thumbnail.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/misc/image_thumbnail.py 2012-10-31 00:11:13.000000000 +0000 @@ -4,17 +4,18 @@ image types transparently if your have PIL installed """ +from __future__ import print_function # build thumbnails of all images in a directory import sys, os, glob import matplotlib.image as image if len(sys.argv)!=2: - print 'Usage: python %s IMAGEDIR'%__file__ + print('Usage: python %s IMAGEDIR'%__file__) raise SystemExit indir = sys.argv[1] if not os.path.isdir(indir): - print 'Could not find input directory "%s"'%indir + print('Could not find input directory "%s"'%indir) raise SystemExit outdir = 'thumbs' @@ -25,5 +26,5 @@ basedir, basename = os.path.split(fname) outfile = os.path.join(outdir, basename) fig = image.thumbnail(fname, outfile, scale=0.15) - print 'saved thumbnail of %s to %s'%(fname, outfile) + print('saved thumbnail of %s to %s'%(fname, outfile)) diff -Nru matplotlib-1.1.1/lib/mpl_examples/misc/multiprocess.py matplotlib-1.2.0/lib/mpl_examples/misc/multiprocess.py --- matplotlib-1.1.1/lib/mpl_examples/misc/multiprocess.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/misc/multiprocess.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,6 +3,8 @@ #Written by Robert Cimrman #Requires >= Python 2.6 for the multiprocessing module or having the #standalone processing module installed + +from __future__ import print_function import time try: from multiprocessing import Process, Pipe @@ -48,7 +50,7 @@ return call_back def __call__(self, pipe): - print 'starting plotter...' + print('starting plotter...') self.pipe = pipe self.fig = plt.figure() @@ -56,7 +58,7 @@ self.ax = self.fig.add_subplot(111) self.gid = gobject.timeout_add(1000, self.poll_draw()) - print '...done' + print('...done') plt.show() @@ -79,7 +81,7 @@ def main(): pl = NBPlot() - for ii in xrange(10): + for ii in range(10): pl.plot() time.sleep(0.5) raw_input('press Enter...') diff -Nru matplotlib-1.1.1/lib/mpl_examples/misc/rc_traits.py matplotlib-1.2.0/lib/mpl_examples/misc/rc_traits.py --- matplotlib-1.1.1/lib/mpl_examples/misc/rc_traits.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/misc/rc_traits.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,8 +3,10 @@ # matplotlib does not ship with enthought.traits, so you will need to # install it separately. +from __future__ import print_function + import sys, os, re -import enthought.traits.api as traits +import traits.api as traits from matplotlib.cbook import is_string_like from matplotlib.artist import Artist @@ -140,11 +142,11 @@ rc = RC() rc.lines.color = 'r' if doprint: - print 'RC' + print('RC') rc.print_traits() - print 'RC lines' + print('RC lines') rc.lines.print_traits() - print 'RC patches' + print('RC patches') rc.patch.print_traits() @@ -182,13 +184,13 @@ p.facecolor = (1,.5,.5,.25) p.facecolor = 0.25 p.fill = 'f' -print 'p.facecolor', type(p.facecolor), p.facecolor -print 'p.fill', type(p.fill), p.fill -if p.fill_: print 'fill' -else: print 'no fill' +print('p.facecolor', type(p.facecolor), p.facecolor) +print('p.fill', type(p.fill), p.fill) +if p.fill_: print('fill') +else: print('no fill') if doprint: - print - print 'Patch' + print() + print('Patch') p.print_traits() diff -Nru matplotlib-1.1.1/lib/mpl_examples/misc/rec_groupby_demo.py matplotlib-1.2.0/lib/mpl_examples/misc/rec_groupby_demo.py --- matplotlib-1.1.1/lib/mpl_examples/misc/rec_groupby_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/misc/rec_groupby_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,10 @@ +from __future__ import print_function import numpy as np import matplotlib.mlab as mlab import matplotlib.cbook as cbook datafile = cbook.get_sample_data('aapl.csv', asfileobj=False) -print 'loading', datafile +print('loading', datafile) r = mlab.csv2rec(datafile) r.sort() @@ -44,19 +45,19 @@ ) # you can summarize over a single variable, like years or months -print 'summary by years' +print('summary by years') ry = mlab.rec_groupby(rsum, ('years',), stats) -print mlab. rec2txt(ry) +print(mlab. rec2txt(ry)) -print 'summary by months' +print('summary by months') rm = mlab.rec_groupby(rsum, ('months',), stats) -print mlab.rec2txt(rm) +print(mlab.rec2txt(rm)) # or over multiple variables like years and months -print 'summary by year and month' +print('summary by year and month') rym = mlab.rec_groupby(rsum, ('years','months'), stats) -print mlab.rec2txt(rym) +print(mlab.rec2txt(rym)) -print 'summary by volume' +print('summary by volume') rv = mlab.rec_groupby(rsum, ('volcode',), stats) -print mlab.rec2txt(rv) +print(mlab.rec2txt(rv)) diff -Nru matplotlib-1.1.1/lib/mpl_examples/misc/rec_join_demo.py matplotlib-1.2.0/lib/mpl_examples/misc/rec_join_demo.py --- matplotlib-1.1.1/lib/mpl_examples/misc/rec_join_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/misc/rec_join_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,10 @@ +from __future__ import print_function import numpy as np import matplotlib.mlab as mlab import matplotlib.cbook as cbook datafile = cbook.get_sample_data('aapl.csv', asfileobj=False) -print 'loading', datafile +print('loading', datafile) r = mlab.csv2rec(datafile) r.sort() @@ -17,14 +18,14 @@ r2.high = r.high[-17:-5] r2.marker = np.arange(12) -print "r1:" -print mlab.rec2txt(r1) -print "r2:" -print mlab.rec2txt(r2) +print("r1:") +print(mlab.rec2txt(r1)) +print("r2:") +print(mlab.rec2txt(r2)) defaults = {'marker':-1, 'close':np.NaN, 'low':-4444.} for s in ('inner', 'outer', 'leftouter'): rec = mlab.rec_join(['date', 'high'], r1, r2, jointype=s, defaults=defaults) - print "\n%sjoin :\n%s" % (s, mlab.rec2txt(rec)) + print("\n%sjoin :\n%s" % (s, mlab.rec2txt(rec))) diff -Nru matplotlib-1.1.1/lib/mpl_examples/misc/sample_data_demo.py matplotlib-1.2.0/lib/mpl_examples/misc/sample_data_demo.py --- matplotlib-1.1.1/lib/mpl_examples/misc/sample_data_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/misc/sample_data_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,11 +2,12 @@ Grab mpl data from the ~/.matplotlib/sample_data cache if it exists, else fetch it from github and cache it """ +from __future__ import print_function import matplotlib.cbook as cbook import matplotlib.pyplot as plt fname = cbook.get_sample_data('lena.png', asfileobj=False) -print 'fname', fname +print('fname', fname) im = plt.imread(fname) plt.imshow(im) plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/misc/sample_data_test.py matplotlib-1.2.0/lib/mpl_examples/misc/sample_data_test.py --- matplotlib-1.1.1/lib/mpl_examples/misc/sample_data_test.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/misc/sample_data_test.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -""" -Demonstrate how get_sample_data works with git revisions in the data. - - git clone git@github.com/matplotlib/sample_data.git - -and edit testdata.csv to add a new row. After committing the changes, -when you rerun this script you will get the updated data (and the new -git version will be cached in ~/.matplotlib/sample_data) -""" - -import matplotlib.mlab as mlab -import matplotlib.cbook as cbook - -# get the file handle to the cached data and print the contents -datafile = 'testdir/subdir/testsub.csv' -fh = cbook.get_sample_data(datafile) -print fh.read() - -# make sure we can read it using csv2rec -fh.seek(0) -r = mlab.csv2rec(fh) - -print mlab.rec2txt(r) - -fh.close() - diff -Nru matplotlib-1.1.1/lib/mpl_examples/misc/svg_filter_line.py matplotlib-1.2.0/lib/mpl_examples/misc/svg_filter_line.py --- matplotlib-1.1.1/lib/mpl_examples/misc/svg_filter_line.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/misc/svg_filter_line.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,9 +2,10 @@ Demonstrate SVG filtering effects which might be used with mpl. Note that the filtering effects are only effective if your svg rederer -support it. +support it. """ +from __future__ import print_function import matplotlib matplotlib.use("Svg") @@ -68,7 +69,7 @@ """ -# read in the saved svg +# read in the saved svg tree, xmlid = ET.XMLID(f.getvalue()) # insert the filter definition in the svg dom tree. @@ -81,5 +82,5 @@ shadow.set("filter",'url(#dropshadow)') fn = "svg_filter_line.svg" -print "Saving '%s'" % fn +print("Saving '%s'" % fn) ET.ElementTree(tree).write(fn) diff -Nru matplotlib-1.1.1/lib/mpl_examples/misc/tight_bbox_test.py matplotlib-1.2.0/lib/mpl_examples/misc/tight_bbox_test.py --- matplotlib-1.1.1/lib/mpl_examples/misc/tight_bbox_test.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/misc/tight_bbox_test.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import matplotlib.pyplot as plt import numpy as np @@ -9,6 +10,6 @@ plt.ylabel("My y-label") plt.title("Check saved figures for their bboxes") for ext in ["png", "pdf", "svg", "svgz", "eps"]: - print "saving tight_bbox_test.%s" % (ext,) + print("saving tight_bbox_test.%s" % (ext,)) plt.savefig("tight_bbox_test.%s" % (ext,), bbox_inches="tight") plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/mplot3d/contour3d_demo.py matplotlib-1.2.0/lib/mpl_examples/mplot3d/contour3d_demo.py --- matplotlib-1.1.1/lib/mpl_examples/mplot3d/contour3d_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/mplot3d/contour3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,11 @@ from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt +from matplotlib import cm fig = plt.figure() ax = fig.add_subplot(111, projection='3d') X, Y, Z = axes3d.get_test_data(0.05) -cset = ax.contour(X, Y, Z) +cset = ax.contour(X, Y, Z, cmap=cm.coolwarm) ax.clabel(cset, fontsize=9, inline=1) plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/mplot3d/contour3d_demo2.py matplotlib-1.2.0/lib/mpl_examples/mplot3d/contour3d_demo2.py --- matplotlib-1.1.1/lib/mpl_examples/mplot3d/contour3d_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/mplot3d/contour3d_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,11 @@ from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt +from matplotlib import cm fig = plt.figure() ax = fig.gca(projection='3d') X, Y, Z = axes3d.get_test_data(0.05) -cset = ax.contour(X, Y, Z, extend3d=True) +cset = ax.contour(X, Y, Z, extend3d=True, cmap=cm.coolwarm) ax.clabel(cset, fontsize=9, inline=1) plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/mplot3d/contour3d_demo3.py matplotlib-1.2.0/lib/mpl_examples/mplot3d/contour3d_demo3.py --- matplotlib-1.1.1/lib/mpl_examples/mplot3d/contour3d_demo3.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/mplot3d/contour3d_demo3.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,13 +1,14 @@ from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt +from matplotlib import cm fig = plt.figure() ax = fig.gca(projection='3d') X, Y, Z = axes3d.get_test_data(0.05) ax.plot_surface(X, Y, Z, rstride=8, cstride=8, alpha=0.3) -cset = ax.contour(X, Y, Z, zdir='z', offset=-100) -cset = ax.contour(X, Y, Z, zdir='x', offset=-40) -cset = ax.contour(X, Y, Z, zdir='y', offset=40) +cset = ax.contour(X, Y, Z, zdir='z', offset=-100, cmap=cm.coolwarm) +cset = ax.contour(X, Y, Z, zdir='x', offset=-40, cmap=cm.coolwarm) +cset = ax.contour(X, Y, Z, zdir='y', offset=40, cmap=cm.coolwarm) ax.set_xlabel('X') ax.set_xlim(-40, 40) diff -Nru matplotlib-1.1.1/lib/mpl_examples/mplot3d/contourf3d_demo.py matplotlib-1.2.0/lib/mpl_examples/mplot3d/contourf3d_demo.py --- matplotlib-1.1.1/lib/mpl_examples/mplot3d/contourf3d_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/mplot3d/contourf3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,11 @@ from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt +from matplotlib import cm fig = plt.figure() ax = fig.gca(projection='3d') X, Y, Z = axes3d.get_test_data(0.05) -cset = ax.contourf(X, Y, Z) +cset = ax.contourf(X, Y, Z, cmap=cm.coolwarm) ax.clabel(cset, fontsize=9, inline=1) plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/mplot3d/contourf3d_demo2.py matplotlib-1.2.0/lib/mpl_examples/mplot3d/contourf3d_demo2.py --- matplotlib-1.1.1/lib/mpl_examples/mplot3d/contourf3d_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/mplot3d/contourf3d_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -5,14 +5,15 @@ from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt +from matplotlib import cm fig = plt.figure() ax = fig.gca(projection='3d') X, Y, Z = axes3d.get_test_data(0.05) ax.plot_surface(X, Y, Z, rstride=8, cstride=8, alpha=0.3) -cset = ax.contourf(X, Y, Z, zdir='z', offset=-100) -cset = ax.contourf(X, Y, Z, zdir='x', offset=-40) -cset = ax.contourf(X, Y, Z, zdir='y', offset=40) +cset = ax.contourf(X, Y, Z, zdir='z', offset=-100, cmap=cm.coolwarm) +cset = ax.contourf(X, Y, Z, zdir='x', offset=-40, cmap=cm.coolwarm) +cset = ax.contourf(X, Y, Z, zdir='y', offset=40, cmap=cm.coolwarm) ax.set_xlabel('X') ax.set_xlim(-40, 40) diff -Nru matplotlib-1.1.1/lib/mpl_examples/mplot3d/lorenz_attractor.py matplotlib-1.2.0/lib/mpl_examples/mplot3d/lorenz_attractor.py --- matplotlib-1.1.1/lib/mpl_examples/mplot3d/lorenz_attractor.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/mplot3d/lorenz_attractor.py 2012-10-31 00:11:13.000000000 +0000 @@ -30,7 +30,7 @@ xs[0], ys[0], zs[0] = (0., 1., 1.05) # Stepping through "time". -for i in xrange(stepCnt) : +for i in range(stepCnt) : # Derivatives of the X, Y, Z state x_dot, y_dot, z_dot = lorenz(xs[i], ys[i], zs[i]) xs[i + 1] = xs[i] + (x_dot * dt) diff -Nru matplotlib-1.1.1/lib/mpl_examples/mplot3d/pathpatch3d_demo.py matplotlib-1.2.0/lib/mpl_examples/mplot3d/pathpatch3d_demo.py --- matplotlib-1.1.1/lib/mpl_examples/mplot3d/pathpatch3d_demo.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/mplot3d/pathpatch3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,14 +1,15 @@ import matplotlib.pyplot as plt from matplotlib.patches import Circle, PathPatch +# register Axes3D class with matplotlib by importing Axes3D from mpl_toolkits.mplot3d import Axes3D import mpl_toolkits.mplot3d.art3d as art3d from matplotlib.text import TextPath from matplotlib.transforms import Affine2D -def text3d(ax, (x, y, z), s, zdir="z", size=None, angle=0, usetex=False, - **kwargs): +def text3d(ax, xyz, s, zdir="z", size=None, angle=0, usetex=False, **kwargs): + x, y, z = xyz if zdir == "y": xy1, z1 = (x, z), y elif zdir == "y": @@ -34,13 +35,14 @@ text3d(ax, (4, -2, 0), "X-axis", zdir="z", size=.5, usetex=False, ec="none", fc="k") -text3d(ax, (12, 4, 0), "Y-axis", zdir="z", size=.5, usetex=False, angle=.5*3.14159, - ec="none", fc="k") -text3d(ax, (12, 10, 4), "Z-axis", zdir="y", size=.5, usetex=False, angle=.5*3.14159, - ec="none", fc="k") +text3d(ax, (12, 4, 0), "Y-axis", zdir="z", size=.5, usetex=False, + angle=.5*3.14159, ec="none", fc="k") +text3d(ax, (12, 10, 4), "Z-axis", zdir="y", size=.5, usetex=False, + angle=.5*3.14159, ec="none", fc="k") text3d(ax, (1, 5, 0), - r"$\displaystyle G_{\mu\nu} + \Lambda g_{\mu\nu} = \frac{8\pi G}{c^4} T_{\mu\nu} $", + r"$\displaystyle G_{\mu\nu} + \Lambda g_{\mu\nu} = " + r"\frac{8\pi G}{c^4} T_{\mu\nu} $", zdir="z", size=1, usetex=True, ec="none", fc="k") @@ -49,4 +51,3 @@ ax.set_zlim3d(0, 10) plt.show() - diff -Nru matplotlib-1.1.1/lib/mpl_examples/mplot3d/polys3d_demo.py matplotlib-1.2.0/lib/mpl_examples/mplot3d/polys3d_demo.py --- matplotlib-1.1.1/lib/mpl_examples/mplot3d/polys3d_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/mplot3d/polys3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -15,7 +15,7 @@ for z in zs: ys = np.random.rand(len(xs)) ys[0], ys[-1] = 0, 0 - verts.append(zip(xs, ys)) + verts.append(list(zip(xs, ys))) poly = PolyCollection(verts, facecolors = [cc('r'), cc('g'), cc('b'), cc('y')]) diff -Nru matplotlib-1.1.1/lib/mpl_examples/mplot3d/subplot3d_demo.py matplotlib-1.2.0/lib/mpl_examples/mplot3d/subplot3d_demo.py --- matplotlib-1.1.1/lib/mpl_examples/mplot3d/subplot3d_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/mplot3d/subplot3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -17,7 +17,7 @@ X, Y = np.meshgrid(X, Y) R = np.sqrt(X**2 + Y**2) Z = np.sin(R) -surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet, +surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False) ax.set_zlim3d(-1.01, 1.01) diff -Nru matplotlib-1.1.1/lib/mpl_examples/mplot3d/surface3d_demo.py matplotlib-1.2.0/lib/mpl_examples/mplot3d/surface3d_demo.py --- matplotlib-1.1.1/lib/mpl_examples/mplot3d/surface3d_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/mplot3d/surface3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -11,7 +11,7 @@ X, Y = np.meshgrid(X, Y) R = np.sqrt(X**2 + Y**2) Z = np.sin(R) -surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet, +surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False) ax.set_zlim(-1.01, 1.01) diff -Nru matplotlib-1.1.1/lib/mpl_examples/mplot3d/surface3d_radial_demo.py matplotlib-1.2.0/lib/mpl_examples/mplot3d/surface3d_radial_demo.py --- matplotlib-1.1.1/lib/mpl_examples/mplot3d/surface3d_radial_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/mplot3d/surface3d_radial_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -18,7 +18,7 @@ X,Y = R*np.cos(P),R*np.sin(P) Z = ((R**2 - 1)**2) -ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet) +ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.YlGnBu_r) ax.set_zlim3d(0, 1) ax.set_xlabel(r'$\phi_\mathrm{real}$') ax.set_ylabel(r'$\phi_\mathrm{im}$') diff -Nru matplotlib-1.1.1/lib/mpl_examples/mplot3d/trisurf3d_demo.py matplotlib-1.2.0/lib/mpl_examples/mplot3d/trisurf3d_demo.py --- matplotlib-1.1.1/lib/mpl_examples/mplot3d/trisurf3d_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/mplot3d/trisurf3d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,32 @@ +from mpl_toolkits.mplot3d import Axes3D +from matplotlib import cm +import matplotlib.pyplot as plt +import numpy as np + +n_angles = 36 +n_radii = 8 + +# An array of radii +# Does not include radius r=0, this is to eliminate duplicate points +radii = np.linspace(0.125, 1.0, n_radii) + +# An array of angles +angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False) + +# Repeat all angles for each radius +angles = np.repeat(angles[...,np.newaxis], n_radii, axis=1) + +# Convert polar (radii, angles) coords to cartesian (x, y) coords +# (0, 0) is added here. There are no duplicate points in the (x, y) plane +x = np.append(0, (radii*np.cos(angles)).flatten()) +y = np.append(0, (radii*np.sin(angles)).flatten()) + +# Pringle surface +z = np.sin(-x*y) + +fig = plt.figure() +ax = fig.gca(projection='3d') + +ax.plot_trisurf(x, y, z, cmap=cm.jet, linewidth=0.2) + +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/mplot3d/wire3d_animation_demo.py matplotlib-1.2.0/lib/mpl_examples/mplot3d/wire3d_animation_demo.py --- matplotlib-1.1.1/lib/mpl_examples/mplot3d/wire3d_animation_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/mplot3d/wire3d_animation_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function """ A very simple 'animation' of a 3D plot """ @@ -34,4 +35,4 @@ plt.draw() -print 'FPS: %f' % (100 / (time.time() - tstart)) +print ('FPS: %f' % (100 / (time.time() - tstart))) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/agg_buffer_to_array.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/agg_buffer_to_array.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/agg_buffer_to_array.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/agg_buffer_to_array.py 2012-11-08 02:24:12.000000000 +0000 @@ -1,5 +1,4 @@ import matplotlib -matplotlib.use('Agg') from pylab import figure, show import numpy as np @@ -10,10 +9,12 @@ ax.set_title('a simple figure') fig.canvas.draw() -# grab rhe pixel buffer and dumpy it into a numpy array -buf = fig.canvas.buffer_rgba(0,0) +# grab the pixel buffer and dump it into a numpy array +buf = fig.canvas.buffer_rgba() l, b, w, h = fig.bbox.bounds -X = np.fromstring(buf, np.uint8) +# The array needs to be copied, because the underlying buffer +# may be reallocated when the window is resized. +X = np.frombuffer(buf, np.uint8).copy() X.shape = h,w,4 # now display the array X as an Axes in a new figure diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/anchored_artists.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/anchored_artists.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/anchored_artists.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/anchored_artists.py 2012-10-31 00:11:13.000000000 +0000 @@ -22,7 +22,7 @@ pad=0.1, borderpad=0.1, sep=2, prop=None, frameon=True): """ Draw a horizontal bar with the size in data coordinate of the give axes. - A label will be drawn underneath (center-alinged). + A label will be drawn underneath (center-aligned). pad, borderpad in fraction of the legend font size (or prop) sep in points. diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/animation_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/animation_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/animation_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/animation_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -23,8 +23,5 @@ z = z + 2 p.set_data(z) - print "step", i + print("step", i) plt.pause(0.5) - - - diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/annotation_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/annotation_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/annotation_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/annotation_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -113,7 +113,7 @@ if 1: - # You can also use polar notation on a catesian axes. Here the + # You can also use polar notation on a cartesian axes. Here the # native coordinate system ('data') is cartesian, so you need to # specify the xycoords and textcoords as 'polar' if you want to # use (theta, radius) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/anscombe.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/anscombe.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/anscombe.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/anscombe.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,6 @@ #!/usr/bin/env python + +from __future__ import print_function """ Edward Tufte uses this example from Anscombe to show 4 datasets of x and y that have the same mean, standard deviation, and regression @@ -38,7 +40,7 @@ subplot(223) plot(x,y3,'ks', xfit, fit(xfit), 'r-', lw=2) axis([2,20,2,14]) -text(3,12, 'IIII', fontsize=20) +text(3,12, 'III', fontsize=20) setp(gca(), yticks=(4,8,12), xticks=(0,10,20)) subplot(224) @@ -52,6 +54,6 @@ #verify the stats pairs = (x,y1), (x,y2), (x,y3), (x4,y4) for x,y in pairs: - print 'mean=%1.2f, std=%1.2f, r=%1.2f'%(mean(y), std(y), corrcoef(x,y)[0][1]) + print ('mean=%1.2f, std=%1.2f, r=%1.2f'%(mean(y), std(y), corrcoef(x,y)[0][1])) show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/arrow_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/arrow_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/arrow_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/arrow_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -199,7 +199,7 @@ elif where == 'center': orig_position = array([[length/2.0, 3*max_arrow_width]]) else: - raise ValueError, "Got unknown position parameter %s" % where + raise ValueError("Got unknown position parameter %s" % where) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/arrow_simple_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/arrow_simple_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/arrow_simple_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/arrow_simple_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,5 @@ +import matplotlib.pyplot as plt + +ax = plt.axes() +ax.arrow(0, 0, 0.5, 0.5, head_width=0.05, head_length=0.1, fc='k', ec='k') +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/axes_zoom_effect.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/axes_zoom_effect.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/axes_zoom_effect.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/axes_zoom_effect.py 2012-10-31 00:11:13.000000000 +0000 @@ -30,7 +30,7 @@ def zoom_effect01(ax1, ax2, xmin, xmax, **kwargs): - u""" + """ ax1 : the main axes ax1 : the zoomed axes (xmin,xmax) : the limits of the colored area in both plot axes. @@ -68,7 +68,7 @@ def zoom_effect02(ax1, ax2, **kwargs): - u""" + """ ax1 : the main axes ax1 : the zoomed axes diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/axhspan_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/axhspan_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/axhspan_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/axhspan_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -14,7 +14,7 @@ # draw a default vline at x=1 that spans the yrange l = plt.axvline(x=1) -# draw a thick blue vline at x=0 that spans the the upper quadrant of +# draw a thick blue vline at x=0 that spans the upper quadrant of # the yrange l = plt.axvline(x=0, ymin=0.75, linewidth=4, color='b') diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/boxplot_demo2.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/boxplot_demo2.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/boxplot_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/boxplot_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -80,7 +80,7 @@ medianY.append(med.get_ydata()[j]) plt.plot(medianX, medianY, 'k') medians[i] = medianY[0] - # Finally, overplot the sample averages, with horixzontal alignment + # Finally, overplot the sample averages, with horizontal alignment # in the center of each box plt.plot([np.average(med.get_xdata())], [np.average(data[i])], color='w', marker='*', markeredgecolor='k') diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/boxplot_demo3.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/boxplot_demo3.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/boxplot_demo3.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/boxplot_demo3.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,26 +2,48 @@ import matplotlib.transforms as mtransforms import numpy as np +def fakeBootStrapper(n): + ''' + This is just a placeholder for the user's method of + bootstrapping the median and its confidence intervals. + + Returns an arbitrary median and confidence intervals + packed into a tuple + ''' + if n == 1: + med = 0.1 + CI = (-0.25, 0.25) + else: + med = 0.2 + CI = (-0.35, 0.50) + + return med, CI + + + np.random.seed(2) inc = 0.1 -e1 = np.random.uniform(0,1, size=(500,)) -e2 = np.random.uniform(0,1, size=(500,)) -e3 = np.random.uniform(0,1 + inc, size=(500,)) -e4 = np.random.uniform(0,1 + 2*inc, size=(500,)) +e1 = np.random.normal(0, 1, size=(500,)) +e2 = np.random.normal(0, 1, size=(500,)) +e3 = np.random.normal(0, 1 + inc, size=(500,)) +e4 = np.random.normal(0, 1 + 2*inc, size=(500,)) treatments = [e1,e2,e3,e4] +med1, CI1 = fakeBootStrapper(1) +med2, CI2 = fakeBootStrapper(2) +medians = [None, None, med1, med2] +conf_intervals = [None, None, CI1, CI2] fig = plt.figure() ax = fig.add_subplot(111) pos = np.array(range(len(treatments)))+1 -bp = ax.boxplot( treatments, sym='k+', patch_artist=True, - positions=pos, notch=1, bootstrap=5000 ) -text_transform= mtransforms.blended_transform_factory(ax.transData, - ax.transAxes) +bp = ax.boxplot(treatments, sym='k+', positions=pos, + notch=1, bootstrap=5000, + usermedians=medians, + conf_intervals=conf_intervals) + ax.set_xlabel('treatment') ax.set_ylabel('response') -ax.set_ylim(-0.2, 1.4) plt.setp(bp['whiskers'], color='k', linestyle='-' ) plt.setp(bp['fliers'], markersize=3.0) -fig.subplots_adjust(right=0.99,top=0.99) plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/centered_ticklabels.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/centered_ticklabels.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/centered_ticklabels.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/centered_ticklabels.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,10 @@ # sometimes it is nice to have ticklabels centered. mpl currently # associates a label with a tick, and the label can be aligned -# 'center', 'feft', or 'right' using the horizontal alignment property: +# 'center', 'left', or 'right' using the horizontal alignment property: # # # for label in ax.xaxis.get_xticklabels(): -# label.set_horizntal_alignment('right') +# label.set_horizontalalignment('right') # # # but this doesn't help center the label between ticks. One solution @@ -21,7 +21,7 @@ import matplotlib.pyplot as plt # load some financial data; apple's stock price -fh = cbook.get_sample_data('aapl.npy') +fh = cbook.get_sample_data('aapl.npy.gz') r = np.load(fh); fh.close() r = r[-250:] # get the last 250 days diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/colorbar_tick_labelling_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/colorbar_tick_labelling_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/colorbar_tick_labelling_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/colorbar_tick_labelling_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -5,7 +5,7 @@ import matplotlib.pyplot as plt import numpy as np - +from matplotlib import cm from numpy.random import randn # Make plot with vertical (default) colorbar @@ -14,7 +14,7 @@ data = np.clip(randn(250, 250), -1, 1) -cax = ax.imshow(data, interpolation='nearest') +cax = ax.imshow(data, interpolation='nearest', cmap=cm.coolwarm) ax.set_title('Gaussian noise with vertical colorbar') # Add colorbar, make sure to specify tick locations to match desired ticklabels @@ -27,7 +27,7 @@ data = np.clip(randn(250, 250), -1, 1) -cax = ax.imshow(data, interpolation='nearest') +cax = ax.imshow(data, interpolation='nearest', cmap=cm.afmhot) ax.set_title('Gaussian noise with horizontal colorbar') cbar = fig.colorbar(cax, ticks=[-1, 0, 1], orientation='horizontal') diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/contour_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/contour_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/contour_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/contour_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -35,6 +35,16 @@ plt.title('Simplest default with labels') +# contour labels can be placed manually by providing list of positions +# (in data coordinate). See ginput_manual_clabel.py for interactive +# placement. +plt.figure() +CS = plt.contour(X, Y, Z) +manual_locations = [(-1, -1.4), (-0.62, -0.7), (-2, 0.5), (1.7, 1.2), (2.0, 1.4), (2.4, 1.7)] +plt.clabel(CS, inline=1, fontsize=10, manual=manual_locations) +plt.title('labels at selected locations') + + # You can force all the contours to be the same color. plt.figure() CS = plt.contour(X, Y, Z, 6, diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/contour_image.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/contour_image.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/contour_image.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/contour_image.py 2012-10-31 00:11:13.000000000 +0000 @@ -26,13 +26,17 @@ levels = arange(-2.0, 1.601, 0.4) # Boost the upper limit to avoid truncation # errors. +norm = cm.colors.Normalize(vmax=abs(Z).max(), vmin=-abs(Z).max()) +cmap = cm.PRGn + figure() subplot(2,2,1) cset1 = contourf(X, Y, Z, levels, - cmap=cm.get_cmap('jet', len(levels)-1), + cmap=cm.get_cmap(cmap, len(levels)-1), + norm=norm, ) # It is not necessary, but for the colormap, we need only the # number of levels minus 1. To avoid discretization error, use @@ -65,7 +69,7 @@ subplot(2,2,2) -imshow(Z, extent=extent) +imshow(Z, extent=extent, cmap=cmap, norm=norm) v = axis() contour(Z, levels, hold='on', colors = 'k', origin='upper', extent=extent) @@ -74,7 +78,7 @@ subplot(2,2,3) -imshow(Z, origin='lower', extent=extent) +imshow(Z, origin='lower', extent=extent, cmap=cmap, norm=norm) v = axis() contour(Z, levels, hold='on', colors = 'k', origin='lower', extent=extent) @@ -89,7 +93,7 @@ # This is intentional. The Z values are defined at the center of each # image pixel (each color block on the following subplot), so the # domain that is contoured does not extend beyond these pixel centers. -im = imshow(Z, interpolation='nearest', extent=extent) +im = imshow(Z, interpolation='nearest', extent=extent, cmap=cmap, norm=norm) v = axis() contour(Z, levels, hold='on', colors = 'k', origin='image', extent=extent) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/contour_label_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/contour_label_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/contour_label_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/contour_label_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -50,7 +50,11 @@ CS.levels = [nf(val) for val in CS.levels ] # Label levels with specially formatted floats -plt.clabel(CS, CS.levels, inline=True, fmt='%r %%', fontsize=10) +if plt.rcParams["text.usetex"]: + fmt = r'%r \%%' +else: + fmt = '%r %%' +plt.clabel(CS, CS.levels, inline=True, fmt=fmt, fontsize=10) ################################################## # Label contours with arbitrary strings using a diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/contourf_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/contourf_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/contourf_demo.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/contourf_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,39 +1,41 @@ #!/usr/bin/env python -from pylab import * +import numpy as np +import matplotlib.pyplot as plt + origin = 'lower' #origin = 'upper' delta = 0.025 -x = y = arange(-3.0, 3.01, delta) -X, Y = meshgrid(x, y) -Z1 = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) -Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1) +x = y = np.arange(-3.0, 3.01, delta) +X, Y = np.meshgrid(x, y) +Z1 = plt.mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) +Z2 = plt.mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1) Z = 10 * (Z1 - Z2) nr, nc = Z.shape # put NaNs in one corner: -Z[-nr//6:, -nc//6:] = nan +Z[-nr//6:, -nc//6:] = np.nan # contourf will convert these to masked -Z = ma.array(Z) +Z = np.ma.array(Z) # mask another corner: -Z[:nr//6, :nc//6] = ma.masked +Z[:nr//6, :nc//6] = np.ma.masked # mask a circle in the middle: -interior = sqrt((X**2) + (Y**2)) < 0.5 -Z[interior] = ma.masked +interior = np.sqrt((X**2) + (Y**2)) < 0.5 +Z[interior] = np.ma.masked # We are using automatic selection of contour levels; # this is usually not such a good idea, because they don't # occur on nice boundaries, but we do it here for purposes # of illustration. -CS = contourf(X, Y, Z, 10, # [-1, -0.1, 0, 0.1], +CS = plt.contourf(X, Y, Z, 10, # [-1, -0.1, 0, 0.1], #alpha=0.5, - cmap=cm.bone, + cmap=plt.cm.bone, origin=origin) # Note that in the following, we explicitly pass in a subset of @@ -41,28 +43,28 @@ # We could pass in additional levels to provide extra resolution, # or leave out the levels kwarg to use all of the original levels. -CS2 = contour(CS, levels=CS.levels[::2], +CS2 = plt.contour(CS, levels=CS.levels[::2], colors = 'r', origin=origin, hold='on') -title('Nonsense (3 masked regions)') -xlabel('word length anomaly') -ylabel('sentence length anomaly') +plt.title('Nonsense (3 masked regions)') +plt.xlabel('word length anomaly') +plt.ylabel('sentence length anomaly') # Make a colorbar for the ContourSet returned by the contourf call. -cbar = colorbar(CS) +cbar = plt.colorbar(CS) cbar.ax.set_ylabel('verbosity coefficient') # Add the contour line levels to the colorbar cbar.add_lines(CS2) -figure() +plt.figure() # Now make a contour plot with the levels specified, # and with the colormap generated automatically from a list # of colors. levels = [-1.5, -1, -0.5, 0, 0.5, 1] -CS3 = contourf(X, Y, Z, levels, +CS3 = plt.contourf(X, Y, Z, levels, colors = ('r', 'g', 'b'), origin=origin, extend='both') @@ -72,16 +74,34 @@ CS3.cmap.set_under('yellow') CS3.cmap.set_over('cyan') -CS4 = contour(X, Y, Z, levels, +CS4 = plt.contour(X, Y, Z, levels, colors = ('k',), linewidths = (3,), origin = origin) -title('Listed colors (3 masked regions)') -clabel(CS4, fmt = '%2.1f', colors = 'w', fontsize=14) +plt.title('Listed colors (3 masked regions)') +plt.clabel(CS4, fmt = '%2.1f', colors = 'w', fontsize=14) # Notice that the colorbar command gets all the information it # needs from the ContourSet object, CS3. -colorbar(CS3) +plt.colorbar(CS3) + +# Illustrate all 4 possible "extend" settings: +extends = ["neither", "both", "min", "max"] +cmap = plt.cm.get_cmap("winter") +cmap.set_under("magenta") +cmap.set_over("yellow") +# Note: contouring simply excludes masked or nan regions, so +# instead of using the "bad" colormap value for them, it draws +# nothing at all in them. Therefore the following would have +# no effect: +#cmap.set_bad("red") + +fig, axs = plt.subplots(2,2) +for ax, extend in zip(axs.ravel(), extends): + cs = ax.contourf(X, Y, Z, levels, cmap=cmap, extend=extend, origin=origin) + fig.colorbar(cs, ax=ax, shrink=0.9) + ax.set_title("extend = %s" % extend) + ax.locator_params(nbins=4) -show() +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/contourf_hatching.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/contourf_hatching.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/contourf_hatching.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/contourf_hatching.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,45 @@ +import matplotlib.pyplot as plt +import numpy as np + + +# invent some numbers, turning the x and y arrays into simple +# 2d arrays, which make combining them together easier. +x = np.linspace(-3, 5, 150).reshape(1, -1) +y = np.linspace(-3, 5, 120).reshape(-1, 1) +z = np.cos(x) + np.sin(y) + +# we no longer need x and y to be 2 dimensional, so flatten them. +x, y = x.flatten(), y.flatten() + + +# --------------------------------------------- +# | Plot #1 | +# --------------------------------------------- +# the simplest hatched plot with a colorbar +fig = plt.figure() +cs = plt.contourf(x, y, z, hatches=['-', '/', '\\', '//'], + cmap=plt.get_cmap('gray'), + extend='both', alpha=0.5 + ) +plt.colorbar() + + +# --------------------------------------------- +# | Plot #2 | +# --------------------------------------------- +# a plot of hatches without color with a legend +plt.figure() +n_levels = 6 +plt.contour(x, y, z, n_levels, colors='black', linestyles='-') +cs = plt.contourf(x, y, z, n_levels, colors='none', + hatches=['.', '/', '\\', None, '\\\\', '*'], + extend='lower' + ) + +# create a legend for the contour set +artists, labels = cs.legend_elements() +plt.legend(artists, labels, handleheight=2) + + + +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/contourf_log.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/contourf_log.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/contourf_log.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/contourf_log.py 2012-10-31 00:11:13.000000000 +0000 @@ -5,7 +5,7 @@ from matplotlib import pyplot as P import numpy as np from numpy import ma -from matplotlib import colors, ticker +from matplotlib import colors, ticker, cm from matplotlib.mlab import bivariate_normal N = 100 @@ -30,7 +30,7 @@ # Automatic selection of levels works; setting the # log locator tells contourf to use a log scale: -cs = P.contourf(X, Y, z, locator=ticker.LogLocator()) +cs = P.contourf(X, Y, z, locator=ticker.LogLocator(), cmap=cm.PuBu_r) # Alternatively, you can manually set the levels # and the norm: diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/coords_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/coords_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/coords_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/coords_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,8 +1,10 @@ #!/usr/bin/env python + """ An example of how to interact with the plotting canvas by connecting to move and click events """ +from __future__ import print_function import sys from pylab import * @@ -18,20 +20,20 @@ if event.inaxes: ax = event.inaxes # the axes instance - print 'data coords', event.xdata, event.ydata + print ('data coords %f %f' % (event.xdata, event.ydata)) def on_click(event): # get the x and y coords, flip y from top to bottom x, y = event.x, event.y if event.button==1: if event.inaxes is not None: - print 'data coords', event.xdata, event.ydata + print ('data coords %f %f' % (event.xdata, event.ydata)) binding_id = connect('motion_notify_event', on_move) connect('button_press_event', on_click) if "test_disconnect" in sys.argv: - print "disconnecting console coordinate printout..." + print ("disconnecting console coordinate printout...") disconnect(binding_id) show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/cursor_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/cursor_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/cursor_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/cursor_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,6 @@ #!/usr/bin/env python # -*- noplot -*- + """ This example shows how to use matplotlib to provide a data cursor. It @@ -9,6 +10,7 @@ Faster cursoring is possible using native GUI drawing, as in wxcursor_demo.py """ +from __future__ import print_function from pylab import * @@ -61,7 +63,7 @@ self.ly.set_xdata(x ) self.txt.set_text( 'x=%1.2f, y=%1.2f'%(x,y) ) - print 'x=%1.2f, y=%1.2f'%(x,y) + print ('x=%1.2f, y=%1.2f'%(x,y)) draw() t = arange(0.0, 1.0, 0.01) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/custom_cmap.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/custom_cmap.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/custom_cmap.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/custom_cmap.py 2012-10-31 00:11:13.000000000 +0000 @@ -103,6 +103,16 @@ (1.0, 0.0, 0.0)) } +# Make a modified version of cdict3 with some transparency +# in the middle of the range. +cdict4 = cdict3.copy() +cdict4['alpha'] = ((0.0, 1.0, 1.0), + # (0.25,1.0, 1.0), + (0.5, 0.3, 0.3), + # (0.75,1.0, 1.0), + (1.0, 1.0, 1.0)) + + # Now we will use this example to illustrate 3 ways of # handling custom colormaps. # First, the most direct and explicit: @@ -121,20 +131,27 @@ # leave everything to register_cmap: plt.register_cmap(name='BlueRed3', data=cdict3) # optional lut kwarg +plt.register_cmap(name='BlueRedAlpha', data=cdict4) + +# Make some illustrative fake data: x = np.arange(0, np.pi, 0.1) y = np.arange(0, 2*np.pi, 0.1) X, Y = np.meshgrid(x,y) -Z = np.cos(X) * np.sin(Y) +Z = np.cos(X) * np.sin(Y) * 10 + +# Make the figure: -plt.figure(figsize=(10,4)) -plt.subplots_adjust(wspace=0.3) +plt.figure(figsize=(6,9)) +plt.subplots_adjust(left=0.02, bottom=0.06, right=0.95, top=0.94, wspace=0.05) -plt.subplot(1,3,1) +# Make 4 subplots: + +plt.subplot(2,2,1) plt.imshow(Z, interpolation='nearest', cmap=blue_red1) plt.colorbar() -plt.subplot(1,3,2) +plt.subplot(2,2,2) cmap = plt.get_cmap('BlueRed2') plt.imshow(Z, interpolation='nearest', cmap=cmap) plt.colorbar() @@ -145,24 +162,32 @@ plt.rcParams['image.cmap'] = 'BlueRed3' -# Also see below for an alternative, particularly for -# interactive use. - -plt.subplot(1,3,3) +plt.subplot(2,2,3) plt.imshow(Z, interpolation='nearest') plt.colorbar() +plt.title("Alpha = 1") -# Or as yet another variation, we could replace the rcParams +# Or as yet another variation, we can replace the rcParams # specification *before* the imshow with the following *after* -# imshow: -# -# plt.set_cmap('BlueRed3') -# +# imshow. # This sets the new default *and* sets the colormap of the last # image-like item plotted via pyplot, if any. +# +plt.subplot(2,2,4) +# Draw a line with low zorder so it will be behind the image. +plt.plot([0, 10*np.pi], [0, 20*np.pi], color='c', lw=20, zorder=-1) + +plt.imshow(Z, interpolation='nearest') +plt.colorbar() + +# Here it is: changing the colormap for the current image and its +# colorbar after they have been plotted. +plt.set_cmap('BlueRedAlpha') +plt.title("Varying alpha") +# -plt.suptitle('Custom Blue-Red colormaps') +plt.suptitle('Custom Blue-Red colormaps', fontsize=16) plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/custom_figure_class.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/custom_figure_class.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/custom_figure_class.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/custom_figure_class.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,5 @@ """ -You can pass a custom Figure constructor to figure if youy want to derive from the default Figure. This simple example creates a figure with a figure title +You can pass a custom Figure constructor to figure if you want to derive from the default Figure. This simple example creates a figure with a figure title """ from matplotlib.pyplot import figure, show from matplotlib.figure import Figure diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/custom_ticker1.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/custom_ticker1.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/custom_ticker1.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/custom_ticker1.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,9 @@ #!/usr/bin/env python """ -The new ticker code was designed to explicity support user customized +The new ticker code was designed to explicitly support user customized ticking. The documentation -http://matplotlib.sourceforge.net/matplotlib.ticker.html details this +http://matplotlib.org/matplotlib.ticker.html details this process. That code defines a lot of preset tickers but was primarily designed to be user extensible. diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/customize_rc.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/customize_rc.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/customize_rc.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/customize_rc.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,6 @@ """ -I'm not trying to make a good liking figure here, but just to show +I'm not trying to make a good looking figure here, but just to show some examples of customizing rc params on the fly If you like to work interactively, and need to create different sets @@ -36,7 +36,7 @@ rc('xtick.major', size=5, pad=7) rc('xtick', labelsize=15) -# using aliases for color, linestyle and linewith; gray, solid, thick +# using aliases for color, linestyle and linewidth; gray, solid, thick rc('grid', c='0.5', ls='-', lw=5) rc('lines', lw=2, color='g') subplot(312) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/dashpointlabel.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/dashpointlabel.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/dashpointlabel.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/dashpointlabel.py 2012-10-31 00:11:13.000000000 +0000 @@ -21,7 +21,7 @@ (x,y) = zip(*DATA) ax.plot(x, y, marker='o') -for i in xrange(len(DATA)): +for i in range(len(DATA)): (x,y) = DATA[i] (dd, dl, r, dr, dp) = dash_style[i] #print 'dashlen call', dl diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/data_helper.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/data_helper.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/data_helper.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/data_helper.py 2012-10-31 00:11:13.000000000 +0000 @@ -11,13 +11,13 @@ """ ticker1, ticker2 = 'INTC', 'AAPL' - file1 = cbook.get_sample_data('INTC.dat', asfileobj=False) - file2 = cbook.get_sample_data('AAPL.dat', asfileobj=False) - M1 = fromstring( file(file1, 'rb').read(), ' 1: + fontname = sys.argv[1] +else: + fontname = os.path.join(matplotlib.get_data_path(), + 'fonts', 'ttf', 'Vera.ttf') + font = FT2Font(fontname) -codes = font.get_charmap().items() +codes = list(font.get_charmap().items()) codes.sort() # a 16,16 array of character strings -chars = [ ['' for c in range(16)] for r in range(16)] -colors = [ [(0.95,0.95,0.95) for c in range(16)] for r in range(16)] +chars = [['' for c in range(16)] for r in range(16)] +colors = [[(0.95, 0.95, 0.95) for c in range(16)] for r in range(16)] -figure(figsize=(8,4),dpi=120) +figure(figsize=(8, 4), dpi=120) for ccode, glyphind in codes: - if ccode>=256: continue - r,c = divmod(ccode,16) + if ccode >= 256: + continue + r, c = divmod(ccode, 16) s = unichr(ccode) chars[r][c] = s - - -lightgrn = (0.5,0.8,0.5) +lightgrn = (0.5, 0.8, 0.5) title(fontname) tab = table(cellText=chars, rowLabels=labelr, @@ -50,7 +64,7 @@ for key, cell in tab.get_celld().items(): row, col = key - if row>0 and col>0: - cell.set_text_props(fontproperties=FontProperties(fname=sys.argv[1])) + if row > 0 and col > 0: + cell.set_text_props(fontproperties=FontProperties(fname=fontname)) axis('off') show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/ganged_plots.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/ganged_plots.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/ganged_plots.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/ganged_plots.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,7 @@ #!/usr/bin/env python """ To create plots that share a common axes (visually) you can set the -hspace bewtween the subplots close to zero (do not use zero itself). +hspace between the subplots close to zero (do not use zero itself). Normally you'll want to turn off the tick labels on all but one of the axes. diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/ginput_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/ginput_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/ginput_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/ginput_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,11 @@ # -*- noplot -*- +from __future__ import print_function + from pylab import arange, plot, sin, ginput, show t = arange(10) plot(t, sin(t)) -print "Please click" +print("Please click") x = ginput(3) -print "clicked",x +print("clicked",x) show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/ginput_manual_clabel.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/ginput_manual_clabel.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/ginput_manual_clabel.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/ginput_manual_clabel.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python # -*- noplot -*- + +from __future__ import print_function """ This provides examples of uses of interactive functions, such as ginput, waitforbuttonpress and manual clabel placement. @@ -18,7 +20,7 @@ import matplotlib.pyplot as plt def tellme(s): - print s + print(s) plt.title(s,fontsize=16) plt.draw() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/griddata_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/griddata_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/griddata_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/griddata_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -16,7 +16,8 @@ zi = griddata(x,y,z,xi,yi,interp='linear') # contour the gridded data, plotting dots at the nonuniform data points. CS = plt.contour(xi,yi,zi,15,linewidths=0.5,colors='k') -CS = plt.contourf(xi,yi,zi,15,cmap=plt.cm.jet) +CS = plt.contourf(xi,yi,zi,15,cmap=plt.cm.rainbow, + vmax=abs(zi).max(), vmin=-abs(zi).max()) plt.colorbar() # draw colorbar # plot data points. plt.scatter(x,y,marker='o',c='b',s=5,zorder=10) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/hexbin_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/hexbin_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/hexbin_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/hexbin_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -6,9 +6,9 @@ """ import numpy as np -import matplotlib.cm as cm -import matplotlib.pyplot as plt +import matplotlib.pyplot as plt +np.random.seed(0) n = 100000 x = np.random.standard_normal(n) y = 2.0 + 3.0 * x + 4.0 * np.random.standard_normal(n) @@ -19,18 +19,17 @@ plt.subplots_adjust(hspace=0.5) plt.subplot(121) -plt.hexbin(x,y, cmap=cm.jet) +plt.hexbin(x,y, cmap=plt.cm.YlOrRd_r) plt.axis([xmin, xmax, ymin, ymax]) plt.title("Hexagon binning") cb = plt.colorbar() cb.set_label('counts') plt.subplot(122) -plt.hexbin(x,y,bins='log', cmap=cm.jet) +plt.hexbin(x,y,bins='log', cmap=plt.cm.YlOrRd_r) plt.axis([xmin, xmax, ymin, ymax]) plt.title("With a log color scale") cb = plt.colorbar() cb.set_label('log10(N)') plt.show() - diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/hexbin_demo2.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/hexbin_demo2.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/hexbin_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/hexbin_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -39,14 +39,15 @@ gridsize=30 plt.subplot(211) -plt.hexbin(x,y, C=z, gridsize=gridsize, marginals=True) +plt.hexbin(x,y, C=z, gridsize=gridsize, marginals=True, cmap=plt.cm.RdBu, + vmax=abs(z).max(), vmin=-abs(z).max()) plt.axis([xmin, xmax, ymin, ymax]) cb = plt.colorbar() cb.set_label('mean value') plt.subplot(212) -plt.hexbin(x,y, gridsize=gridsize) +plt.hexbin(x,y, gridsize=gridsize, cmap=plt.cm.Blues_r) plt.axis([xmin, xmax, ymin, ymax]) cb = plt.colorbar() cb.set_label('N observations') diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/hist2d_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/hist2d_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/hist2d_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/hist2d_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,7 @@ +from pylab import * +x = randn(1000) +y = randn(1000)+5 + +#normal distribution center at x=0 and y=5 +hist2d(x,y,bins=40) +show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/hist2d_log_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/hist2d_log_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/hist2d_log_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/hist2d_log_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,10 @@ +from matplotlib.colors import LogNorm +from pylab import * + +#normal distribution center at x=0 and y=5 +x = randn(100000) +y = randn(100000)+5 + +hist2d(x, y, bins=40, norm=LogNorm()) +colorbar() +show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/histogram_demo_extended.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/histogram_demo_extended.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/histogram_demo_extended.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/histogram_demo_extended.py 2012-10-31 00:11:13.000000000 +0000 @@ -82,7 +82,19 @@ # P.figure() -n, bins, patches = P.hist(x, 10, normed=1, histtype='barstacked') +n, bins, patches = P.hist(x, 10, normed=1, histtype='bar', stacked=True) + +P.show() + +# +# we can also stack using the step histtype +# + +P.figure() + +n, bins, patches = P.hist(x, 10, histtype='step', stacked=True, fill=True) + +P.show() # # finally: make a multiple-histogram of data-sets with different length diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/histogram_percent_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/histogram_percent_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/histogram_percent_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/histogram_percent_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,29 @@ +import matplotlib +from numpy.random import randn +import matplotlib.pyplot as plt +from matplotlib.ticker import FuncFormatter + +def to_percent(y, position): + # Ignore the passed in position. This has the effect of scaling the default + # tick locations. + s = str(100 * y) + + # The percent symbol needs escaping in latex + if matplotlib.rcParams['text.usetex'] == True: + return s + r'$\%$' + else: + return s + '%' + +x = randn(5000) + +# Make a normed histogram. It'll be multiplied by 100 later. +plt.hist(x, bins=50, normed=True) + +# Create the formatter using the function to_percent. This multiplies all the +# default labels by 100, making them all percentages +formatter = FuncFormatter(to_percent) + +# Set the formatter +plt.gca().yaxis.set_major_formatter(formatter) + +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/image_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/image_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/image_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/image_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -11,8 +11,9 @@ Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1) Z = Z2-Z1 # difference of Gaussians -im = plt.imshow(Z, interpolation='bilinear', cmap=cm.gray, - origin='lower', extent=[-3,3,-3,3]) +im = plt.imshow(Z, interpolation='bilinear', cmap=cm.RdYlGn, + origin='lower', extent=[-3,3,-3,3], + vmax=abs(Z).max(), vmin=-abs(Z).max()) plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/image_demo2.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/image_demo2.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/image_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/image_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,12 +1,13 @@ #!/usr/bin/env python + +from __future__ import print_function from pylab import * import matplotlib.cbook as cbook w, h = 512, 512 -datafile = cbook.get_sample_data('ct.raw', asfileobj=False) -print 'loading', datafile -s = file(datafile, 'rb').read() +datafile = cbook.get_sample_data('ct.raw.gz', asfileobj=True) +s = datafile.read() A = fromstring(s, uint16).astype(float) A *= 1.0/max(A) A.shape = w, h @@ -33,4 +34,3 @@ setp(gca(), 'xticklabels', []) show() - diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/image_demo3.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/image_demo3.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/image_demo3.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/image_demo3.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,7 +2,7 @@ from pylab import * try: from PIL import Image -except ImportError, exc: +except ImportError: raise SystemExit("PIL must be installed to run this example") import matplotlib.cbook as cbook @@ -15,7 +15,7 @@ figure(figsize=figsize) ax = axes([0,0,1,1], frameon=False) ax.set_axis_off() -im = imshow(lena, origin='lower') +im = imshow(lena) show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/image_nonuniform.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/image_nonuniform.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/image_nonuniform.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/image_nonuniform.py 2012-10-31 00:11:13.000000000 +0000 @@ -7,6 +7,7 @@ from matplotlib.pyplot import figure, show import numpy as np from matplotlib.image import NonUniformImage +from matplotlib import cm interp='nearest' @@ -19,7 +20,8 @@ fig = figure() fig.suptitle('NonUniformImage class') ax = fig.add_subplot(221) -im = NonUniformImage(ax, interpolation=interp, extent=(-4,4,-4,4)) +im = NonUniformImage(ax, interpolation=interp, extent=(-4,4,-4,4), + cmap=cm.Purples) im.set_data(x, y, z) ax.images.append(im) ax.set_xlim(-4,4) @@ -27,7 +29,8 @@ ax.set_title(interp) ax = fig.add_subplot(222) -im = NonUniformImage(ax, interpolation=interp, extent=(-64,64,-4,4)) +im = NonUniformImage(ax, interpolation=interp, extent=(-64,64,-4,4), + cmap=cm.Purples) im.set_data(x2, y, z) ax.images.append(im) ax.set_xlim(-64,64) @@ -37,7 +40,8 @@ interp = 'bilinear' ax = fig.add_subplot(223) -im = NonUniformImage(ax, interpolation=interp, extent=(-4,4,-4,4)) +im = NonUniformImage(ax, interpolation=interp, extent=(-4,4,-4,4), + cmap=cm.Purples) im.set_data(x, y, z) ax.images.append(im) ax.set_xlim(-4,4) @@ -45,7 +49,8 @@ ax.set_title(interp) ax = fig.add_subplot(224) -im = NonUniformImage(ax, interpolation=interp, extent=(-64,64,-4,4)) +im = NonUniformImage(ax, interpolation=interp, extent=(-64,64,-4,4), + cmap=cm.Purples) im.set_data(x2, y, z) ax.images.append(im) ax.set_xlim(-64,64) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/image_origin.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/image_origin.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/image_origin.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/image_origin.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,7 +3,7 @@ You can specify whether images should be plotted with the array origin x[0,0] in the upper left or upper right by using the origin parameter. You can also control the default be setting image.origin in your -matplotlibrc file; see http://matplotlib.sourceforge.net/matplotlibrc +matplotlibrc file; see http://matplotlib.org/matplotlibrc """ from pylab import * diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/image_slices_viewer.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/image_slices_viewer.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/image_slices_viewer.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/image_slices_viewer.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function import numpy from matplotlib.pyplot import figure, show @@ -17,7 +18,7 @@ self.update() def onscroll(self, event): - print event.button, event.step + print ("%s %s" % (event.button, event.step)) if event.button=='up': self.ind = numpy.clip(self.ind+1, 0, self.slices-1) else: diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/integral_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/integral_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/integral_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/integral_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -17,7 +17,7 @@ # make the shaded region ix = arange(a, b, 0.01) iy = func(ix) -verts = [(a,0)] + zip(ix,iy) + [(b,0)] +verts = [(a,0)] + list(zip(ix,iy)) + [(b,0)] poly = Polygon(verts, facecolor='0.8', edgecolor='k') ax.add_patch(poly) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/line_collection2.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/line_collection2.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/line_collection2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/line_collection2.py 2012-10-31 00:11:13.000000000 +0000 @@ -21,7 +21,7 @@ # where onoffseq is an even length tuple of on and off ink in points. # If linestyle is omitted, 'solid' is used # See matplotlib.collections.LineCollection for more information -line_segments = LineCollection([zip(x,y) for y in ys], # Make a sequence of x,y pairs +line_segments = LineCollection([list(zip(x,y)) for y in ys], # Make a sequence of x,y pairs linewidths = (0.5,1,1.5,2), linestyles = 'solid') line_segments.set_array(x) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/load_converter.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/load_converter.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/load_converter.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/load_converter.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function from matplotlib.dates import strpdate2num #from matplotlib.mlab import load import numpy as np @@ -5,7 +6,7 @@ import matplotlib.cbook as cbook datafile = cbook.get_sample_data('msft.csv', asfileobj=False) -print 'loading', datafile +print('loading', datafile) dates, closes = np.loadtxt( datafile, delimiter=',', diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/loadrec.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/loadrec.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/loadrec.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/loadrec.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,12 +1,13 @@ +from __future__ import print_function from matplotlib import mlab from pylab import figure, show import matplotlib.cbook as cbook datafile = cbook.get_sample_data('msft.csv', asfileobj=False) -print 'loading', datafile +print('loading', datafile) a = mlab.csv2rec(datafile) a.sort() -print a.dtype +print(a.dtype) fig = figure() ax = fig.add_subplot(111) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/logo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/logo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/logo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/logo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,11 +1,13 @@ #!/usr/bin/env python # This file generates the matplotlib web page logo + +from __future__ import print_function from pylab import * import matplotlib.cbook as cbook # convert data to mV datafile = cbook.get_sample_data('membrane.dat', asfileobj=False) -print 'loading', datafile +print('loading', datafile) x = 1000*0.1*fromstring(file(datafile, 'rb').read(), float32) # 0.0005 is the sample interval diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/major_minor_demo1.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/major_minor_demo1.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/major_minor_demo1.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/major_minor_demo1.py 2012-10-31 00:11:13.000000000 +0000 @@ -19,7 +19,7 @@ some base. The FormatStrFormatter uses a string format string (eg '%d' or '%1.2f' or '%1.1f cm' ) to format the tick -The pylab interface grid command chnages the grid settings of the +The pylab interface grid command changes the grid settings of the major ticks of the y and y axis together. If you want to control the grid of the minor ticks for a given axis, use for example diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/manual_axis.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/manual_axis.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/manual_axis.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/manual_axis.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,7 @@ """ The techniques here are no longer required with the new support for spines in matplotlib -- see -http://matplotlib.sourceforge.net/examples/pylab_examples/spine_placement_demo.html. +http://matplotlib.org/examples/pylab_examples/spine_placement_demo.html. This example should be considered deprecated and is left just for demo purposes for folks wanting to make a pseudo-axis @@ -55,4 +55,3 @@ make_yaxis(ax, 0, offset=5, **props) show() - diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/mathtext_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/mathtext_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/mathtext_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/mathtext_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,6 @@ #!/usr/bin/env python """ -Use matplotlib's internal LaTex parser and layout engine. For true +Use matplotlib's internal LaTeX parser and layout engine. For true latex rendering, see the text.usetex option """ import numpy as np diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/mathtext_examples.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/mathtext_examples.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/mathtext_examples.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/mathtext_examples.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import print_function + import os, sys, re import gc @@ -38,7 +40,7 @@ r"$\gamma = \frac{x=\frac{6}{8}}{y} \delta$", r'$\limsup_{x\to\infty}$', r'$\oint^\infty_0$', - r"$f^\prime$", + r"$f^'$", r'$\frac{x_2888}{y}$', r"$\sqrt[3]{\frac{X_2}{Y}}=5$", r"$\sqrt[5]{\prod^\frac{x}{2\pi^2}_\infty}$", diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/movie_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/movie_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/movie_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/movie_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,8 @@ #!/usr/bin/env python # -*- noplot -*- +from __future__ import print_function + import os, sys from pylab import * @@ -11,11 +13,11 @@ cla() imshow(rand(5,5), interpolation='nearest') fname = '_tmp%03d.png'%i - print 'Saving frame', fname + print('Saving frame', fname) savefig(fname) files.append(fname) -print 'Making movie animation.mpg - this make take a while' +print('Making movie animation.mpg - this make take a while') os.system("mencoder 'mf://_tmp*.png' -mf type=png:fps=10 -ovc lavc -lavcopts vcodec=wmv2 -oac copy -o animation.mpg") #os.system("convert _tmp*.png animation.mng") diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/mri_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/mri_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/mri_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/mri_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,14 +1,15 @@ #!/usr/bin/env python + +from __future__ import print_function from pylab import * import matplotlib.cbook as cbook # data are 256x256 16 bit integers -dfile = cbook.get_sample_data('s1045.ima', asfileobj=False) -print 'loading image', dfile -im = np.fromstring(file(dfile, 'rb').read(), np.uint16).astype(float) +dfile = cbook.get_sample_data('s1045.ima.gz') +im = np.fromstring(dfile.read(), np.uint16).astype(float) im.shape = 256, 256 #imshow(im, ColormapJet(256)) -imshow(im, cmap=cm.jet) +imshow(im, cmap=cm.gray) axis('off') show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/mri_with_eeg.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/mri_with_eeg.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/mri_with_eeg.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/mri_with_eeg.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,10 @@ #!/usr/bin/env python + """ This now uses the imshow command instead of pcolor which *is much faster* """ -from __future__ import division +from __future__ import division, print_function import numpy as np @@ -14,14 +15,13 @@ if 1: # load the data # data are 256x256 16 bit integers - dfile = cbook.get_sample_data('s1045.ima', asfileobj=False) - print 'loading image', dfile - im = np.fromstring(file(dfile, 'rb').read(), np.uint16).astype(float) + dfile = cbook.get_sample_data('s1045.ima.gz') + im = np.fromstring(dfile.read(), np.uint16).astype(float) im.shape = 256, 256 if 1: # plot the MRI in pcolor subplot(221) - imshow(im, cmap=cm.jet) + imshow(im, cmap=cm.gray) axis('off') if 1: # plot the histogram of MRI intensity @@ -40,8 +40,8 @@ numSamples, numRows = 800,4 eegfile = cbook.get_sample_data('eeg.dat', asfileobj=False) - print 'loading eeg', eegfile - data = np.fromstring(file(eegfile, 'rb').read(), float) + print ('loading eeg %s' % eegfile) + data = np.fromstring(open(eegfile, 'rb').read(), float) data.shape = numSamples, numRows t = 10.0 * np.arange(numSamples, dtype=float)/numSamples ticklocs = [] diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/pcolor_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/pcolor_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/pcolor_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/pcolor_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -19,7 +19,7 @@ X,Y = meshgrid(x, y) Z = func3(X, Y) -pcolor(X, Y, Z) +pcolor(X, Y, Z, cmap=cm.RdBu, vmax=abs(Z).max(), vmin=-abs(Z).max()) colorbar() axis([-3,3,-3,3]) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/pcolor_demo2.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/pcolor_demo2.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/pcolor_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/pcolor_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -20,7 +20,7 @@ ax = subplot(111) -im = imshow(Z, cmap=cm.jet) +im = imshow(Z, cmap=cm.RdBu, vmax=abs(Z).max(), vmin=-abs(Z).max()) #im.set_interpolation('nearest') #im.set_interpolation('bicubic') im.set_interpolation('bilinear') diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/pcolor_log.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/pcolor_log.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/pcolor_log.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/pcolor_log.py 2012-10-31 00:11:13.000000000 +0000 @@ -15,11 +15,11 @@ Z1 = bivariate_normal(X, Y, 0.1, 0.2, 1.0, 1.0) + 0.1*bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) subplot(2,1,1) -pcolor(X, Y, Z1, norm=LogNorm(vmin=Z1.min(), vmax=Z1.max())) +pcolor(X, Y, Z1, norm=LogNorm(vmin=Z1.min(), vmax=Z1.max()), cmap=cm.PuBu_r) colorbar() subplot(2,1,2) -pcolor(X, Y, Z1) +pcolor(X, Y, Z1, cmap=cm.PuBu_r) colorbar() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/pie_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/pie_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/pie_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/pie_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,10 +3,8 @@ http://matplotlib.sf.net/matplotlib.pylab.html#-pie for the docstring. This example shows a basic pie chart with labels optional features, -like autolabeling the percentage, offsetting a slice with "explode" -and adding a shadow. - -Requires matplotlib0-0.70 or later +like autolabeling the percentage, offsetting a slice with "explode", +adding a shadow, and changing the starting angle. """ from pylab import * @@ -15,11 +13,18 @@ figure(1, figsize=(6,6)) ax = axes([0.1, 0.1, 0.8, 0.8]) +# The slices will be ordered and plotted counter-clockwise. labels = 'Frogs', 'Hogs', 'Dogs', 'Logs' -fracs = [15,30,45, 10] - +fracs = [15, 30, 45, 10] explode=(0, 0.05, 0, 0) -pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%', shadow=True) + +pie(fracs, explode=explode, labels=labels, + autopct='%1.1f%%', shadow=True, startangle=90) + # The default startangle is 0, which would start + # the Frogs slice on the x-axis. With startangle=90, + # everything is rotated counter-clockwise by 90 degrees, + # so the plotting starts on the positive y-axis. + title('Raining Hogs and Dogs', bbox={'facecolor':'0.8', 'pad':5}) show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/pie_demo2.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/pie_demo2.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/pie_demo2.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/pie_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,60 @@ +""" +Make a pie charts of varying size - see +http://matplotlib.sf.net/matplotlib.pylab.html#-pie for the docstring. + +This example shows a basic pie charts with labels optional features, +like autolabeling the percentage, offsetting a slice with "explode" +and adding a shadow, in different sizes. + +""" +from pylab import * +from matplotlib.gridspec import GridSpec + +# Some data + +labels = 'Frogs', 'Hogs', 'Dogs', 'Logs' +fracs = [15,30,45, 10] + +explode=(0, 0.05, 0, 0) + +# Make square figures and axes + +the_grid = GridSpec(2, 2) + +figure(1, figsize=(6,6)) + +subplot(the_grid[0, 0]) + +pie(fracs, labels=labels, autopct='%1.1f%%', shadow=True) + +subplot(the_grid[0, 1]) + +pie(fracs, explode=explode, labels=labels, autopct='%.0f%%', shadow=True) + +subplot(the_grid[1, 0]) + +patches, texts, autotexts = pie(fracs, labels=labels, + autopct='%.0f%%', + shadow=True, radius=0.5) + +# Make the labels on the small plot easier to read. +for t in texts: + t.set_size('smaller') +for t in autotexts: + t.set_size('x-small') +autotexts[0].set_color('y') + +subplot(the_grid[1, 1]) + +patches, texts, autotexts = pie(fracs, explode=explode, + labels=labels, autopct='%.0f%%', + shadow=False, radius=0.5) + # Turn off shadow for tiny plot + # with exploded slice. +for t in texts: + t.set_size('smaller') +for t in autotexts: + t.set_size('x-small') +autotexts[0].set_color('y') + +show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/polar_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/polar_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/polar_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/polar_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -9,7 +9,7 @@ # PolarAxes) -- other axes plotting functions may work on PolarAxes # but haven't been tested and may need tweaking. # -# you can get get a PolarSubplot instance by doing, for example +# you can get a PolarSubplot instance by doing, for example # # subplot(211, polar=True) # diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/polar_scatter.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/polar_scatter.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/polar_scatter.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/polar_scatter.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,8 +1,8 @@ #!/usr/bin/env python # a polar scatter plot; size increases radially in this example and # color increases with angle (just to verify the symbols are being -# scattered correctlu). In a real example, this would be wasting -# dimensionlaity of the plot +# scattered correctly). In a real example, this would be wasting +# dimensionality of the plot from pylab import * N = 150 @@ -11,8 +11,7 @@ area = 200*r**2*rand(N) colors = theta ax = subplot(111, polar=True) -c = scatter(theta, r, c=colors, s=area) +c = scatter(theta, r, c=colors, s=area, cmap=cm.hsv) c.set_alpha(0.75) - show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/poormans_contour.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/poormans_contour.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/poormans_contour.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/poormans_contour.py 2012-10-31 00:11:13.000000000 +0000 @@ -18,9 +18,10 @@ Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1) Z = Z2 - Z1 # difference of Gaussians -cmap = cm.get_cmap('jet', 10) # 10 discrete colors +cmap = cm.get_cmap('PiYG', 11) # 11 discrete colors -im = imshow(Z, cmap=cmap, interpolation='bilinear') +im = imshow(Z, cmap=cmap, interpolation='bilinear', + vmax=abs(Z).max(), vmin=-abs(Z).max()) axis('off') colorbar() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/psd_demo2.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/psd_demo2.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/psd_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/psd_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -22,7 +22,7 @@ ax2.psd(y, NFFT=len(t), pad_to=len(t)*4, Fs=fs) plt.title('zero padding') -#Plot the PSD with different block sizes, Zero pad to the length of the orignal +#Plot the PSD with different block sizes, Zero pad to the length of the original #data sequence. ax3 = fig.add_subplot(2, 3, 5, sharex=ax2, sharey=ax2) ax3.psd(y, NFFT=len(t), pad_to=len(t), Fs=fs) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/pythonic_matplotlib.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/pythonic_matplotlib.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/pythonic_matplotlib.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/pythonic_matplotlib.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,7 +1,7 @@ #!/usr/bin/env python """ Some people prefer to write more pythonic, object oriented, code -rather than use the pylab interface to matplotlib. This example show +rather than use the pylab interface to matplotlib. This example shows you how. Unless you are an application developer, I recommend using part of the diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/scatter_custom_symbol.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/scatter_custom_symbol.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/scatter_custom_symbol.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/scatter_custom_symbol.py 2012-10-31 00:11:13.000000000 +0000 @@ -6,7 +6,7 @@ rx, ry = 3., 1. area = rx * ry * pi theta = arange(0, 2*pi+0.01, 0.1) -verts = zip(rx/area*cos(theta), ry/area*sin(theta)) +verts = list(zip(rx/area*cos(theta), ry/area*sin(theta))) x,y,s,c = rand(4, 30) s*= 10**2. diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/scatter_profile.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/scatter_profile.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/scatter_profile.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/scatter_profile.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,6 @@ #!/usr/bin/env python # -*- noplot -*- + """ N Classic Base renderer Ext renderer 20 0.22 0.14 0.14 @@ -8,15 +9,16 @@ 10000 3.30 1.31 0.53 50000 19.30 6.53 1.98 """ -from pylab import * +from __future__ import print_function +import pylab import time for N in (20,100,1000,10000,50000): tstart = time.time() - x = 0.9*rand(N) - y = 0.9*rand(N) - s = 20*rand(N) - scatter(x,y,s) - print '%d symbols in %1.2f s' % (N, time.time()-tstart) + x = 0.9*pylab.rand(N) + y = 0.9*pylab.rand(N) + s = 20*pylab.rand(N) + pylab.scatter(x,y,s) + print ('%d symbols in %1.2f s' % (N, time.time()-tstart)) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/scatter_star_poly.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/scatter_star_poly.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/scatter_star_poly.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/scatter_star_poly.py 2012-10-31 00:11:13.000000000 +0000 @@ -12,7 +12,7 @@ plt.subplot(322) plt.scatter(x,y,s=80, c=z, marker=(5,0)) -verts = zip([-1.,1.,1.,-1.],[-1.,-1.,1.,-1.]) +verts = list(zip([-1.,1.,1.,-1.],[-1.,-1.,1.,-1.])) plt.subplot(323) plt.scatter(x,y,s=80, c=z, marker=(verts,0)) # equivalent: diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/set_and_get.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/set_and_get.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/set_and_get.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/set_and_get.py 2012-10-31 00:11:13.000000000 +0000 @@ -21,8 +21,8 @@ >>> setp(line) set operates on a single instance or a list of instances. If you are - in quey mode introspecting the possible values, only the first - instance in the sequnce is used. When actually setting values, all + in query mode introspecting the possible values, only the first + instance in the sequence is used. When actually setting values, all the instances will be set. Eg, suppose you have a list of two lines, the following will make both lines thicker and red @@ -52,7 +52,7 @@ color = b ... long listing skipped ... -Alisases: +Aliases: To reduce keystrokes in interactive mode, a number of properties have short aliases, eg 'lw' for 'linewidth' and 'mec' for @@ -64,6 +64,7 @@ """ +from __future__ import print_function from pylab import * @@ -77,20 +78,20 @@ setp(l2, linewidth=1, color='g') # line2 is thicker and green -print 'Line setters' +print ('Line setters') setp(l1) -print 'Line getters' +print ('Line getters') getp(l1) -print 'Rectangle setters' +print ('Rectangle setters') setp(gca().patch) -print 'Rectangle getters' +print ('Rectangle getters') getp(gca().patch) t = title('Hi mom') -print 'Text setters' +print ('Text setters') setp(t) -print 'Text getters' +print ('Text getters') getp(t) show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/shading_example.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/shading_example.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/shading_example.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/shading_example.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,7 +3,7 @@ from matplotlib.colors import LightSource # example showing how to make shaded relief plots -# like mathematica +# like Mathematica # (http://reference.wolfram.com/mathematica/ref/ReliefPlot.html) # or Generic Mapping Tools # (http://gmt.soest.hawaii.edu/gmt/doc/gmt/html/GMT_Docs/node145.html) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/simple_plot.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/simple_plot.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/simple_plot.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/simple_plot.py 2012-11-01 19:19:04.000000000 +0000 @@ -8,4 +8,5 @@ ylabel('voltage (mV)') title('About as simple as it gets, folks') grid(True) +savefig("test.png") show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/simple_plot_fps.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/simple_plot_fps.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/simple_plot_fps.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/simple_plot_fps.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,9 +1,11 @@ #!/usr/bin/env python + """ Example: simple line plot. Show how to make and save a simple line plot with labels, title and grid """ # -*- noplot -*- +from __future__ import print_function from pylab import * ion() @@ -22,11 +24,11 @@ frames = 100.0 t = time.time() c = time.clock() -for i in xrange(int(frames)): +for i in range(int(frames)): part = i / frames axis([0.0, 1.0 - part, -1.0 + part, 1.0 - part]) wallclock = time.time() - t user = time.clock() - c -print "wallclock:", wallclock -print "user:", user -print "fps:", frames / wallclock +print ("wallclock:", wallclock) +print ("user:", user) +print ("fps:", frames / wallclock) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/specgram_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/specgram_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/specgram_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/specgram_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -25,5 +25,6 @@ ax1 = subplot(211) plot(t, x) subplot(212, sharex=ax1) -Pxx, freqs, bins, im = specgram(x, NFFT=NFFT, Fs=Fs, noverlap=900) +Pxx, freqs, bins, im = specgram(x, NFFT=NFFT, Fs=Fs, noverlap=900, + cmap=cm.gist_heat) show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/spine_placement_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/spine_placement_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/spine_placement_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/spine_placement_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +import sys import matplotlib.pyplot as plt import numpy as np from matplotlib.pyplot import show @@ -8,7 +9,7 @@ ax = fig.add_subplot(1,2,1) ax.set_title('dropped spines') ax.plot(x,y) -for loc, spine in ax.spines.iteritems(): +for loc, spine in ax.spines.items(): if loc in ['left','bottom']: spine.set_position(('outward',10)) # outward by 10 points elif loc in ['right','top']: @@ -80,7 +81,7 @@ # ---------------------------------------------------- def adjust_spines(ax,spines): - for loc, spine in ax.spines.iteritems(): + for loc, spine in ax.spines.items(): if loc in spines: spine.set_position(('outward',10)) # outward by 10 points spine.set_smart_bounds(True) @@ -141,7 +142,10 @@ # x ax.set_xlim((0,2*np.pi)) ax.set_xticks([0,np.pi,2*np.pi]) -pichr = unichr(0x03C0) +if sys.version_info[0] < 3: + pichr = unichr(0x03C0) +else: + pichr = chr(0x03C0) ax.set_xticklabels(['0',pichr,'2 '+pichr]) # y diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/stackplot_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/stackplot_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/stackplot_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/stackplot_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,18 @@ +import numpy as np +from matplotlib import pyplot as plt + +fnx = lambda : np.random.randint(5, 50, 10) +y = np.row_stack((fnx(), fnx(), fnx())) +x = np.arange(10) + +y1, y2, y3 = fnx(), fnx(), fnx() + +fig = plt.figure() +ax = fig.add_subplot(111) +ax.stackplot(x, y) +plt.show() + +fig = plt.figure() +ax = fig.add_subplot(111) +ax.stackplot(x, y1, y2, y3) +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/stix_fonts_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/stix_fonts_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/stix_fonts_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/stix_fonts_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import unicode_literals + import os, sys, re import gc @@ -17,9 +19,6 @@ if sys.maxunicode > 0xffff: s = r'Direct Unicode: $\u23ce \mathrm{\ue0f2 \U0001D538}$' - stests.append( - unicode(s, encoding="unicode_escape") - ) from pylab import * diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/streamplot_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/streamplot_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/streamplot_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/streamplot_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,19 @@ +import numpy as np +import matplotlib.pyplot as plt + +Y, X = np.mgrid[-3:3:100j, -3:3:100j] +U = -1 - X**2 + Y +V = 1 + X - Y**2 +speed = np.sqrt(U*U + V*V) + +plt.streamplot(X, Y, U, V, color=U, linewidth=2, cmap=plt.cm.autumn) +plt.colorbar() + +f, (ax1, ax2) = plt.subplots(ncols=2) +ax1.streamplot(X, Y, U, V, density=[0.5, 1]) + +lw = 5*speed/speed.max() +ax2.streamplot(X, Y, U, V, density=0.6, color='k', linewidth=lw) + +plt.show() + diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/streamplot_with_mask.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/streamplot_with_mask.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/streamplot_with_mask.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/streamplot_with_mask.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,23 @@ +""" +Demonstrate the use of the `streamplot` function using a masked array +and NaN values. +""" +import numpy as np +import matplotlib.pyplot as plt + +w = 3 +Y, X = np.mgrid[-w:w:100j, -w:w:100j] +U = -1 - X**2 + Y +V = 1 + X - Y**2 +speed = np.sqrt(U*U + V*V) + +mask = np.zeros(U.shape, dtype=bool) +mask[40:60, 40:60] = 1 +U = np.ma.array(U, mask=mask) +U[:20, :20] = np.nan + +plt.streamplot(X, Y, U, V, color='r') +plt.imshow(~mask, extent=(-w, w, -w, w), alpha=0.5, interpolation='nearest') + +plt.show() + diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/subplots_adjust.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/subplots_adjust.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/subplots_adjust.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/subplots_adjust.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,9 +2,9 @@ subplot(211) -imshow(rand(100,100)) +imshow(rand(100,100), cmap=cm.BuPu_r) subplot(212) -imshow(rand(100,100)) +imshow(rand(100,100), cmap=cm.BuPu_r) subplots_adjust(bottom=0.1, right=0.8, top=0.9) cax = axes([0.85, 0.1, 0.075, 0.8]) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/subplots_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/subplots_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/subplots_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/subplots_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -10,8 +10,8 @@ import numpy as np # Simple data to display in various forms -x = np.linspace(0, 2*np.pi, 400) -y = np.sin(x**2) +x = np.linspace(0, 2 * np.pi, 400) +y = np.sin(x ** 2) plt.close('all') @@ -37,25 +37,33 @@ ax1.plot(x, y) ax1.set_title('Sharing both axes') ax2.scatter(x, y) -ax3.scatter(x, 2*y**2-1,color='r') +ax3.scatter(x, 2 * y ** 2 - 1, color='r') # Fine-tune figure; make subplots close to each other and hide x ticks for # all but bottom plot. f.subplots_adjust(hspace=0) plt.setp([a.get_xticklabels() for a in f.axes[:-1]], visible=False) +# row and column sharing +f, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, sharex='col', sharey='row') +ax1.plot(x, y) +ax1.set_title('Sharing x per column, y per row') +ax2.scatter(x, y) +ax3.scatter(x, 2 * y ** 2 - 1, color='r') +ax4.plot(x, 2 * y ** 2 - 1, color='r') + # Four axes, returned as a 2-d array f, axarr = plt.subplots(2, 2) -axarr[0,0].plot(x, y) -axarr[0,0].set_title('Axis [0,0]') -axarr[0,1].scatter(x, y) -axarr[0,1].set_title('Axis [0,1]') -axarr[1,0].plot(x, y**2) -axarr[1,0].set_title('Axis [1,0]') -axarr[1,1].scatter(x, y**2) -axarr[1,1].set_title('Axis [1,1]') +axarr[0, 0].plot(x, y) +axarr[0, 0].set_title('Axis [0,0]') +axarr[0, 1].scatter(x, y) +axarr[0, 1].set_title('Axis [0,1]') +axarr[1, 0].plot(x, y ** 2) +axarr[1, 0].set_title('Axis [1,0]') +axarr[1, 1].scatter(x, y ** 2) +axarr[1, 1].set_title('Axis [1,1]') # Fine-tune figure; hide x ticks for top plots and y ticks for right plots -plt.setp([a.get_xticklabels() for a in axarr[0,:]], visible=False) -plt.setp([a.get_yticklabels() for a in axarr[:,1]], visible=False) +plt.setp([a.get_xticklabels() for a in axarr[0, :]], visible=False) +plt.setp([a.get_yticklabels() for a in axarr[:, 1]], visible=False) # Four polar axes plt.subplots(2, 2, subplot_kw=dict(polar=True)) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/table_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/table_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/table_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/table_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -71,7 +71,7 @@ cellText = [] width = 0.4 # the width of the bars yoff = array([0.0] * len(colLabels)) # the bottom values for stacked bar chart -for row in xrange(rows): +for row in range(rows): bar(ind, data[row], width, bottom=yoff, color=colours[row]) yoff = yoff + data[row] cellText.append(['%1.1f' % (x/1000.0) for x in yoff]) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/tex_unicode_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/tex_unicode_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/tex_unicode_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/tex_unicode_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -4,12 +4,13 @@ This demo is tex_demo.py modified to have unicode. See that file for more information. """ -from matplotlib import rcParams -rcParams['text.usetex']=True -rcParams['text.latex.unicode']=True +from __future__ import unicode_literals +import matplotlib as mpl +mpl.rcParams['text.usetex']=True +mpl.rcParams['text.latex.unicode']=True from numpy import arange, cos, pi -from matplotlib.pyplot import figure, axes, plot, xlabel, ylabel, title, \ - grid, savefig, show +from matplotlib.pyplot import (figure, axes, plot, xlabel, ylabel, title, + grid, savefig, show) figure(1, figsize=(6,4)) ax = axes([0.1, 0.1, 0.8, 0.7]) @@ -18,7 +19,7 @@ plot(t, s) xlabel(r'\textbf{time (s)}') -ylabel(ur'\textit{Velocity (\u00B0/sec)}', fontsize=16) +ylabel(r'\textit{Velocity (\u00B0/sec)}', fontsize=16) title(r"\TeX\ is Number $\displaystyle\sum_{n=1}^\infty\frac{-e^{i\pi}}{2^n}$!", fontsize=16, color='r') grid(True) diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/text_rotation.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/text_rotation.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/text_rotation.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/text_rotation.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,6 @@ #!/usr/bin/env python """ -The way matplotlib does text layout is counter-intuituve to some, so +The way matplotlib does text layout is counter-intuitive to some, so this example is designed to make it a little clearer. The text is aligned by it's bounding box (the rectangular box that surrounds the ink rectangle). The order of operations is basically rotation then diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/text_rotation_relative_to_line.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/text_rotation_relative_to_line.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/text_rotation_relative_to_line.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/text_rotation_relative_to_line.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,7 +2,7 @@ """ Text objects in matplotlib are normally rotated with respect to the screen coordinate system (i.e., 45 degrees rotation plots text along a -line that is inbetween horizontal and vertical no matter how the axes +line that is in between horizontal and vertical no matter how the axes are changed). However, at times one wants to rotate text with respect to something on the plot. In this case, the correct angle won't be the angle of that object in the plot coordinate system, but the angle diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/to_numeric.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/to_numeric.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/to_numeric.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/to_numeric.py 2012-10-31 00:11:13.000000000 +0000 @@ -5,16 +5,17 @@ rendering """ -from pylab import * +import pylab from matplotlib.backends.backend_agg import FigureCanvasAgg + try: from PIL import Image -except ImportError, exc: +except ImportError: raise SystemExit("PIL must be installed to run this example") -plot([1,2,3]) +pylab.plot([1,2,3]) -canvas = get_current_fig_manager().canvas +canvas = pylab.get_current_fig_manager().canvas agg = canvas.switch_backends(FigureCanvasAgg) agg.draw() @@ -25,9 +26,9 @@ w, h = int(w), int(h) -X = fromstring(s, uint8) +X = pylab.fromstring(s, pylab.uint8) X.shape = h, w, 3 im = Image.fromstring( "RGB", (w,h), s) -# im.show() +im.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/tricontour_vs_griddata.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/tricontour_vs_griddata.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/tricontour_vs_griddata.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/tricontour_vs_griddata.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,7 @@ """ Comparison of griddata and tricontour for an unstructured triangular grid. """ +from __future__ import print_function import matplotlib.pyplot as plt import matplotlib.tri as tri import numpy as np @@ -23,25 +24,27 @@ yi = np.linspace(-2.1,2.1,ngridy) zi = griddata(x,y,z,xi,yi,interp='linear') plt.contour(xi,yi,zi,15,linewidths=0.5,colors='k') -plt.contourf(xi,yi,zi,15,cmap=plt.cm.jet) +plt.contourf(xi,yi,zi,15,cmap=plt.cm.rainbow, + norm=plt.normalize(vmax=abs(zi).max(), vmin=-abs(zi).max())) plt.colorbar() # draw colorbar plt.plot(x, y, 'ko', ms=3) plt.xlim(-2,2) plt.ylim(-2,2) plt.title('griddata and contour (%d points, %d grid points)' % (npts, ngridx*ngridy)) -print 'griddata and contour seconds:', time.clock() - start +print ('griddata and contour seconds: %f' % (time.clock() - start)) # tricontour. start = time.clock() plt.subplot(212) triang = tri.Triangulation(x, y) plt.tricontour(x, y, z, 15, linewidths=0.5, colors='k') -plt.tricontourf(x, y, z, 15, cmap=plt.cm.jet) +plt.tricontourf(x, y, z, 15, cmap=plt.cm.rainbow, + norm=plt.normalize(vmax=abs(zi).max(), vmin=-abs(zi).max())) plt.colorbar() plt.plot(x, y, 'ko', ms=3) plt.xlim(-2,2) plt.ylim(-2,2) plt.title('tricontour (%d points)' % npts) -print 'tricontour seconds:', time.clock() - start +print ('tricontour seconds: %f' % (time.clock() - start)) plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/tripcolor_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/tripcolor_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/tripcolor_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/tripcolor_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -32,12 +32,19 @@ mask = np.where(xmid*xmid + ymid*ymid < min_radius*min_radius, 1, 0) triang.set_mask(mask) -# pcolor plot. +# tripcolor plot. plt.figure() plt.gca().set_aspect('equal') -plt.tripcolor(triang, z, shading='faceted') +plt.tripcolor(triang, z, shading='flat', cmap=plt.cm.rainbow) plt.colorbar() -plt.title('tripcolor of Delaunay triangulation') +plt.title('tripcolor of Delaunay triangulation, flat shading') + +# Illustrate Gouraud shading. +plt.figure() +plt.gca().set_aspect('equal') +plt.tripcolor(triang, z, shading='gouraud', cmap=plt.cm.rainbow) +plt.colorbar() +plt.title('tripcolor of Delaunay triangulation, gouraud shading') # You can specify your own triangulation rather than perform a Delaunay @@ -63,9 +70,6 @@ [-0.057,0.916],[-0.025,0.933],[-0.077,0.990],[-0.059,0.993] ]) x = xy[:,0]*180/3.14159 y = xy[:,1]*180/3.14159 -x0 = -5 -y0 = 52 -z = np.exp(-0.01*( (x-x0)*(x-x0) + (y-y0)*(y-y0) )) triangles = np.asarray([ [67,66, 1],[65, 2,66],[ 1,66, 2],[64, 2,65],[63, 3,64],[60,59,57], @@ -83,13 +87,21 @@ [32,31,33],[39,38,72],[33,72,38],[33,38,34],[37,35,38],[34,38,35], [35,37,36] ]) +xmid = x[triangles].mean(axis=1) +ymid = y[triangles].mean(axis=1) +x0 = -5 +y0 = 52 +zfaces = np.exp(-0.01*( (xmid-x0)*(xmid-x0) + (ymid-y0)*(ymid-y0) )) + # Rather than create a Triangulation object, can simply pass x, y and triangles # arrays to tripcolor directly. It would be better to use a Triangulation object # if the same triangulation was to be used more than once to save duplicated # calculations. +# Can specify one color value per face rather than one per point by using the +# facecolors kwarg. plt.figure() plt.gca().set_aspect('equal') -plt.tripcolor(x, y, triangles, z, shading='faceted') +plt.tripcolor(x, y, triangles, facecolors=zfaces, edgecolors='k') plt.colorbar() plt.title('tripcolor of user-specified triangulation') plt.xlabel('Longitude (degrees)') diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/unicode_demo.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/unicode_demo.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/unicode_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/unicode_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,12 +1,15 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -from pylab import * -plot([1,2,4]) -title(u'Développés et fabriqués') -xlabel(u"réactivité nous permettent d'être sélectionnés et adoptés") -ylabel(u'André was here!') -text( 0.5, 2.5, u'Institut für Festkörperphysik', rotation=45) -text( 1, 1.5, u'AVA (check kerning)') +from __future__ import unicode_literals -show() +import pylab + +pylab.plot([1, 2, 4]) +pylab.title('Développés et fabriqués') +pylab.xlabel("réactivité nous permettent d'être sélectionnés et adoptés") +pylab.ylabel('André was here!') +pylab.text( 0.5, 2.5, 'Institut für Festkörperphysik', rotation=45) +pylab.text( 1, 1.5, 'AVA (check kerning)') + +pylab.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/pylab_examples/usetex_baseline_test.py matplotlib-1.2.0/lib/mpl_examples/pylab_examples/usetex_baseline_test.py --- matplotlib-1.1.1/lib/mpl_examples/pylab_examples/usetex_baseline_test.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/pylab_examples/usetex_baseline_test.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,6 +3,10 @@ import matplotlib.pyplot as plt import matplotlib.axes as maxes +from matplotlib import rcParams +rcParams['text.usetex']=True +rcParams['text.latex.unicode']=True + class Axes(maxes.Axes): """ A hackish way to simultaneously draw texts w/ usetex=True and diff -Nru matplotlib-1.1.1/lib/mpl_examples/tests/backend_driver.py matplotlib-1.2.0/lib/mpl_examples/tests/backend_driver.py --- matplotlib-1.1.1/lib/mpl_examples/tests/backend_driver.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/tests/backend_driver.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,6 @@ #!/usr/bin/env python + +from __future__ import print_function, division """ This is used to drive many of the examples across the backends, for regression testing, and comparing backend efficiency. @@ -7,11 +9,10 @@ switch, which takes a comma-separated list, or as separate arguments, e.g. - python backend_driver.py agg ps cairo.png cairo.ps + python backend_driver.py agg ps -would test the agg and ps backends, and the cairo backend with output -to png and ps files. If no arguments are given, a default list of -backends will be tested. +would test the agg and ps backends. If no arguments are given, a +default list of backends will be tested. Interspersed with the backend arguments can be switches for the Python interpreter executing the tests. If entering such arguments causes an @@ -19,14 +20,12 @@ switches with a --. """ -from __future__ import division import os, time, sys, glob, string from optparse import OptionParser import matplotlib.rcsetup as rcsetup from matplotlib.cbook import Bunch, dedent all_backends = list(rcsetup.all_backends) # to leave the original list alone -all_backends.extend(['cairo.png', 'cairo.ps', 'cairo.pdf', 'cairo.svg']) # actual physical directory for each dir dirs = dict(pylab = os.path.join('..', 'pylab_examples'), @@ -160,6 +159,7 @@ 'pcolor_log.py', 'pcolor_small.py', 'pie_demo.py', + 'pie_demo2.py', 'plotfile_demo.py', 'polar_bar.py', 'polar_demo.py', @@ -285,7 +285,7 @@ missing = list(pyfiles-flist-exclude) missing.sort() if missing: - print '%s files not tested: %s'%(dir, ', '.join(missing)) + print ('%s files not tested: %s'%(dir, ', '.join(missing))) def report_all_missing(directories): for f in directories: @@ -323,7 +323,7 @@ if os.path.exists(path): import glob for fname in os.listdir(path): - os.unlink(os.path.join(path,fname)) + os.unlink(os.path.join(path, fname)) else: os.mkdir(backend) failures = [] @@ -338,34 +338,35 @@ fpath, fname = os.path.split(fullpath) if fname in exclude: - print '\tSkipping %s, known to fail on backend: %s'%backend + print ('\tSkipping %s, known to fail on backend: %s'%backend) continue basename, ext = os.path.splitext(fname) - outfile = os.path.join(path,basename) + outfile = os.path.join(path, basename) tmpfile_name = '_tmp_%s.py' % basename - tmpfile = file(tmpfile_name, 'w') + tmpfile = open(tmpfile_name, 'w') - for line in file(fullpath): + future_imports = 'from __future__ import division, print_function' + for line in open(fullpath): line_lstrip = line.lstrip() if line_lstrip.startswith("#"): tmpfile.write(line) - else: - break + elif 'unicode_literals' in line: + future_imports = future_imports + ', unicode_literals' tmpfile.writelines(( - 'from __future__ import division\n', + future_imports+'\n', 'import sys\n', - 'sys.path.append("%s")\n'%fpath, + 'sys.path.append("%s")\n' % fpath.replace('\\', '\\\\'), 'import matplotlib\n', 'matplotlib.use("%s")\n' % backend, 'from pylab import savefig\n', 'import numpy\n', 'numpy.seterr(invalid="ignore")\n', )) - for line in file(fullpath): + for line in open(fullpath): line_lstrip = line.lstrip() - if (line_lstrip.startswith('from __future__ import division') or + if (line_lstrip.startswith('from __future__ import') or line_lstrip.startswith('matplotlib.use') or line_lstrip.startswith('savefig') or line_lstrip.startswith('show')): @@ -381,7 +382,7 @@ program = [x % {'name': basename} for x in python] ret = run(program + [tmpfile_name] + switches) end_time = time.time() - print (end_time - start_time), ret + print ("%s %s" % ((end_time - start_time), ret)) #os.system('%s %s %s' % (python, tmpfile_name, ' '.join(switches))) os.remove(tmpfile_name) if ret: @@ -405,8 +406,7 @@ help=dedent(''' Run tests only for these backends; comma-separated list of one or more of: agg, ps, svg, pdf, template, cairo, - cairo.png, cairo.ps, cairo.pdf, cairo.svg. Default is everything - except cairo.''')) + Default is everything except cairo.''')) op.add_option('--clean', action='store_true', dest='clean', help='Remove result directories, run no tests') op.add_option('-c', '--coverage', action='store_true', dest='coverage', @@ -418,7 +418,7 @@ switches = [x for x in args if x.startswith('--')] backends = [x.lower() for x in args if not x.startswith('--')] if options.backends: - backends += map(string.lower, options.backends.split(',')) + backends += [be.lower() for be in options.backends.split(',')] result = Bunch( dirs = options.dirs.split(','), @@ -430,7 +430,7 @@ if 'pylab_examples' in result.dirs: result.dirs[result.dirs.index('pylab_examples')] = 'pylab' #print result - return result + return (result) if __name__ == '__main__': times = {} @@ -443,28 +443,28 @@ for d in localdirs: if d.lower() not in all_backends_set: continue - print 'removing %s'%d + print ('removing %s'%d) for fname in glob.glob(os.path.join(d, '*')): os.remove(fname) os.rmdir(d) for fname in glob.glob('_tmp*.py'): os.remove(fname) - print 'all clean...' + print ('all clean...') raise SystemExit if options.coverage: python = ['coverage.py', '-x'] elif options.valgrind: python = ['valgrind', '--tool=memcheck', '--leak-check=yes', - '--log-file=%(name)s', 'python'] + '--log-file=%(name)s', sys.executable] elif sys.platform == 'win32': python = [sys.executable] else: - python = ['python'] + python = [sys.executable] report_all_missing(options.dirs) for backend in options.backends: - print 'testing %s %s' % (backend, ' '.join(options.switches)) + print ('testing %s %s' % (backend, ' '.join(options.switches))) t0 = time.time() failures[backend] = \ drive(backend, options.dirs, python, options.switches) @@ -473,10 +473,10 @@ # print times for backend, elapsed in times.items(): - print 'Backend %s took %1.2f minutes to complete' % (backend, elapsed) + print ('Backend %s took %1.2f minutes to complete' % (backend, elapsed)) failed = failures[backend] if failed: - print ' Failures: ', failed + print (' Failures: %s' % failed) if 'template' in times: - print '\ttemplate ratio %1.3f, template residual %1.3f' % ( - elapsed/times['template'], elapsed-times['template']) + print ('\ttemplate ratio %1.3f, template residual %1.3f' % ( + elapsed/times['template'], elapsed-times['template'])) diff -Nru matplotlib-1.1.1/lib/mpl_examples/units/bar_demo2.py matplotlib-1.2.0/lib/mpl_examples/units/bar_demo2.py --- matplotlib-1.1.1/lib/mpl_examples/units/bar_demo2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/units/bar_demo2.py 2012-10-31 00:11:13.000000000 +0000 @@ -9,13 +9,14 @@ """ import numpy as np from basic_units import cm, inch -from pylab import figure, show +import matplotlib.pyplot as plt + cms = cm *np.arange(0, 10, 2) bottom=0*cm width=0.8*cm -fig = figure() +fig = plt.figure() ax1 = fig.add_subplot(2,2,1) ax1.bar(cms, cms, bottom=bottom) @@ -32,4 +33,4 @@ #fig.savefig('simple_conversion_plot.png') ax4.set_xlim(2*cm, 6*cm) # cm are converted to inches -show() +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/units/bar_unit_demo.py matplotlib-1.2.0/lib/mpl_examples/units/bar_unit_demo.py --- matplotlib-1.1.1/lib/mpl_examples/units/bar_unit_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/units/bar_unit_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,13 +1,14 @@ #!/usr/bin/env python import numpy as np from basic_units import cm, inch -from pylab import figure, show +import matplotlib.pyplot as plt + N = 5 menMeans = (150*cm, 160*cm, 146*cm, 172*cm, 155*cm) menStd = ( 20*cm, 30*cm, 32*cm, 10*cm, 20*cm) -fig = figure() +fig = plt.figure() ax = fig.add_subplot(111) ind = np.arange(N) # the x locations for the groups @@ -27,5 +28,5 @@ ax.yaxis.set_units(inch) ax.autoscale_view() -#savefig('barchart_demo') -show() +#plt.savefig('barchart_demo') +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/units/basic_units.py matplotlib-1.2.0/lib/mpl_examples/units/basic_units.py --- matplotlib-1.1.1/lib/mpl_examples/units/basic_units.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/units/basic_units.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,5 @@ import math + import numpy as np import matplotlib.units as units @@ -6,35 +7,42 @@ from matplotlib.axes import Axes from matplotlib.cbook import iterable + class ProxyDelegate(object): def __init__(self, fn_name, proxy_type): self.proxy_type = proxy_type self.fn_name = fn_name + def __get__(self, obj, objtype=None): return self.proxy_type(self.fn_name, obj) + class TaggedValueMeta (type): def __init__(cls, name, bases, dict): for fn_name in cls._proxies.keys(): try: dummy = getattr(cls, fn_name) except AttributeError: - setattr(cls, fn_name, ProxyDelegate(fn_name, cls._proxies[fn_name])) + setattr(cls, fn_name, + ProxyDelegate(fn_name, cls._proxies[fn_name])) + class PassThroughProxy(object): def __init__(self, fn_name, obj): self.fn_name = fn_name self.target = obj.proxy_target + def __call__(self, *args): - #print 'passthrough', self.target, self.fn_name fn = getattr(self.target, self.fn_name) ret = fn(*args) return ret + class ConvertArgsProxy(PassThroughProxy): def __init__(self, fn_name, obj): PassThroughProxy.__init__(self, fn_name, obj) self.unit = obj.unit + def __call__(self, *args): converted_args = [] for a in args: @@ -45,16 +53,19 @@ converted_args = tuple([c.get_value() for c in converted_args]) return PassThroughProxy.__call__(self, *converted_args) + class ConvertReturnProxy(PassThroughProxy): def __init__(self, fn_name, obj): PassThroughProxy.__init__(self, fn_name, obj) self.unit = obj.unit + def __call__(self, *args): ret = PassThroughProxy.__call__(self, *args) if (type(ret) == type(NotImplemented)): return NotImplemented return TaggedValue(ret, self.unit) + class ConvertAllProxy(PassThroughProxy): def __init__(self, fn_name, obj): PassThroughProxy.__init__(self, fn_name, obj) @@ -91,184 +102,186 @@ return NotImplemented return TaggedValue(ret, ret_unit) -class TaggedValue (object): - __metaclass__ = TaggedValueMeta - _proxies = {'__add__':ConvertAllProxy, - '__sub__':ConvertAllProxy, - '__mul__':ConvertAllProxy, - '__rmul__':ConvertAllProxy, - '__cmp__':ConvertAllProxy, - '__lt__':ConvertAllProxy, - '__gt__':ConvertAllProxy, - '__len__':PassThroughProxy} - - def __new__(cls, value, unit): - # generate a new subclass for value - value_class = type(value) - try: - subcls = type('TaggedValue_of_%s' % (value_class.__name__), - tuple([cls, value_class]), - {}) - if subcls not in units.registry: - units.registry[subcls] = basicConverter - return object.__new__(subcls, value, unit) - except TypeError: - if cls not in units.registry: - units.registry[cls] = basicConverter - return object.__new__(cls, value, unit) - - def __init__(self, value, unit): - self.value = value - self.unit = unit - self.proxy_target = self.value - - def get_compressed_copy(self, mask): - compressed_value = np.ma.masked_array(self.value, mask=mask).compressed() - return TaggedValue(compressed_value, self.unit) - - def __getattribute__(self, name): - if (name.startswith('__')): - return object.__getattribute__(self, name) - variable = object.__getattribute__(self, 'value') - if (hasattr(variable, name) and name not in self.__class__.__dict__): - return getattr(variable, name) - return object.__getattribute__(self, name) - - def __array__(self, t = None, context = None): - if t is not None: - return np.asarray(self.value).astype(t) - else: - return np.asarray(self.value, 'O') +class _TaggedValue(object): - def __array_wrap__(self, array, context): - return TaggedValue(array, self.unit) + _proxies = {'__add__': ConvertAllProxy, + '__sub__': ConvertAllProxy, + '__mul__': ConvertAllProxy, + '__rmul__': ConvertAllProxy, + '__cmp__': ConvertAllProxy, + '__lt__': ConvertAllProxy, + '__gt__': ConvertAllProxy, + '__len__': PassThroughProxy} + + def __new__(cls, value, unit): + # generate a new subclass for value + value_class = type(value) + try: + subcls = type('TaggedValue_of_%s' % (value_class.__name__), + tuple([cls, value_class]), + {}) + if subcls not in units.registry: + units.registry[subcls] = basicConverter + return object.__new__(subcls, value, unit) + except TypeError: + if cls not in units.registry: + units.registry[cls] = basicConverter + return object.__new__(cls, value, unit) - def __repr__(self): - return 'TaggedValue(' + repr(self.value) + ', ' + repr(self.unit) + ')' + def __init__(self, value, unit): + self.value = value + self.unit = unit + self.proxy_target = self.value - def __str__(self): - return str(self.value) + ' in ' + str(self.unit) + def __getattribute__(self, name): + if (name.startswith('__')): + return object.__getattribute__(self, name) + variable = object.__getattribute__(self, 'value') + if (hasattr(variable, name) and name not in self.__class__.__dict__): + return getattr(variable, name) + return object.__getattribute__(self, name) + + def __array__(self, t=None, context=None): + if t is not None: + return np.asarray(self.value).astype(t) + else: + return np.asarray(self.value, 'O') - def __iter__(self): - class IteratorProxy(object): - def __init__(self, iter, unit): - self.iter = iter - self.unit = unit - def next(self): - value = self.iter.next() - return TaggedValue(value, self.unit) - return IteratorProxy(iter(self.value), self.unit) - - def get_compressed_copy(self, mask): - new_value = np.ma.masked_array(self.value, mask=mask).compressed() - return TaggedValue(new_value, self.unit) - - def convert_to(self, unit): - #print 'convert to', unit, self.unit - if (unit == self.unit or not unit): - return self - new_value = self.unit.convert_value_to(self.value, unit) - return TaggedValue(new_value, unit) + def __array_wrap__(self, array, context): + return TaggedValue(array, self.unit) + + def __repr__(self): + return 'TaggedValue(' + repr(self.value) + ', ' + repr(self.unit) + ')' + + def __str__(self): + return str(self.value) + ' in ' + str(self.unit) + + def __len__(self): + return len(self.value) + + def __iter__(self): + class IteratorProxy(object): + def __init__(self, iter, unit): + self.iter = iter + self.unit = unit + + def __next__(self): + value = next(self.iter) + return TaggedValue(value, self.unit) + next = __next__ # for Python 2 + return IteratorProxy(iter(self.value), self.unit) - def get_value(self): - return self.value + def get_compressed_copy(self, mask): + new_value = np.ma.masked_array(self.value, mask=mask).compressed() + return TaggedValue(new_value, self.unit) - def get_unit(self): - return self.unit + def convert_to(self, unit): + if (unit == self.unit or not unit): + return self + new_value = self.unit.convert_value_to(self.value, unit) + return TaggedValue(new_value, unit) + + def get_value(self): + return self.value + + def get_unit(self): + return self.unit + + +TaggedValue = TaggedValueMeta('TaggedValue', (_TaggedValue, ), {}) class BasicUnit(object): - def __init__(self, name, fullname=None): - self.name = name - if fullname is None: fullname = name - self.fullname = fullname - self.conversions = dict() - - - def __repr__(self): - return 'BasicUnit(%s)'%self.name - - def __str__(self): - return self.fullname - - def __call__(self, value): - return TaggedValue(value, self) - - def __mul__(self, rhs): - value = rhs - unit = self - if hasattr(rhs, 'get_unit'): - value = rhs.get_value() - unit = rhs.get_unit() - unit = unit_resolver('__mul__', (self, unit)) - if (unit == NotImplemented): - return NotImplemented - return TaggedValue(value, unit) - - def __rmul__(self, lhs): - return self*lhs - - def __array_wrap__(self, array, context): - return TaggedValue(array, self) - - def __array__(self, t=None, context=None): - ret = np.array([1]) - if t is not None: - return ret.astype(t) - else: - return ret + def __init__(self, name, fullname=None): + self.name = name + if fullname is None: + fullname = name + self.fullname = fullname + self.conversions = dict() + + def __repr__(self): + return 'BasicUnit(%s)'%self.name + + def __str__(self): + return self.fullname + + def __call__(self, value): + return TaggedValue(value, self) + + def __mul__(self, rhs): + value = rhs + unit = self + if hasattr(rhs, 'get_unit'): + value = rhs.get_value() + unit = rhs.get_unit() + unit = unit_resolver('__mul__', (self, unit)) + if (unit == NotImplemented): + return NotImplemented + return TaggedValue(value, unit) - def add_conversion_factor(self, unit, factor): - def convert(x): - return x*factor - self.conversions[unit] = convert + def __rmul__(self, lhs): + return self*lhs - def add_conversion_fn(self, unit, fn): - self.conversions[unit] = fn + def __array_wrap__(self, array, context): + return TaggedValue(array, self) - def get_conversion_fn(self, unit): - return self.conversions[unit] + def __array__(self, t=None, context=None): + ret = np.array([1]) + if t is not None: + return ret.astype(t) + else: + return ret - def convert_value_to(self, value, unit): - #print 'convert value to: value ="%s", unit="%s"'%(value, type(unit)), self.conversions - conversion_fn = self.conversions[unit] - ret = conversion_fn(value) - return ret + def add_conversion_factor(self, unit, factor): + def convert(x): + return x*factor + self.conversions[unit] = convert + + def add_conversion_fn(self, unit, fn): + self.conversions[unit] = fn + + def get_conversion_fn(self, unit): + return self.conversions[unit] + + def convert_value_to(self, value, unit): + conversion_fn = self.conversions[unit] + ret = conversion_fn(value) + return ret + def get_unit(self): + return self - def get_unit(self): - return self class UnitResolver(object): - def addition_rule(self, units): - for unit_1, unit_2 in zip(units[:-1], units[1:]): - if (unit_1 != unit_2): - return NotImplemented - return units[0] - def multiplication_rule(self, units): - non_null = [u for u in units if u] - if (len(non_null) > 1): - return NotImplemented - return non_null[0] - - op_dict = { - '__mul__':multiplication_rule, - '__rmul__':multiplication_rule, - '__add__':addition_rule, - '__radd__':addition_rule, - '__sub__':addition_rule, - '__rsub__':addition_rule, - } - - def __call__(self, operation, units): - if (operation not in self.op_dict): - return NotImplemented + def addition_rule(self, units): + for unit_1, unit_2 in zip(units[:-1], units[1:]): + if (unit_1 != unit_2): + return NotImplemented + return units[0] + + def multiplication_rule(self, units): + non_null = [u for u in units if u] + if (len(non_null) > 1): + return NotImplemented + return non_null[0] - return self.op_dict[operation](self, units) + op_dict = { + '__mul__': multiplication_rule, + '__rmul__': multiplication_rule, + '__add__': addition_rule, + '__radd__': addition_rule, + '__sub__': addition_rule, + '__rsub__': addition_rule} + + def __call__(self, operation, units): + if (operation not in self.op_dict): + return NotImplemented + + return self.op_dict[operation](self, units) -unit_resolver = UnitResolver() +unit_resolver = UnitResolver() cm = BasicUnit('cm', 'centimeters') inch = BasicUnit('inch', 'inches') @@ -284,22 +297,23 @@ hertz = BasicUnit('Hz', 'Hertz') minutes = BasicUnit('min', 'minutes') -secs.add_conversion_fn(hertz, lambda x:1./x) +secs.add_conversion_fn(hertz, lambda x: 1./x) secs.add_conversion_factor(minutes, 1/60.0) + # radians formatting -def rad_fn(x,pos=None): - n = int((x / np.pi) * 2.0 + 0.25) - if n == 0: - return '0' - elif n == 1: - return r'$\pi/2$' - elif n == 2: - return r'$\pi$' - elif n % 2 == 0: - return r'$%s\pi$' % (n/2,) - else: - return r'$%s\pi/2$' % (n,) +def rad_fn(x, pos=None): + n = int((x / np.pi) * 2.0 + 0.25) + if n == 0: + return '0' + elif n == 1: + return r'$\pi/2$' + elif n == 2: + return r'$\pi$' + elif n % 2 == 0: + return r'$%s\pi$' % (n/2,) + else: + return r'$%s\pi/2$' % (n,) class BasicUnitConverter(units.ConversionInterface): @@ -310,16 +324,16 @@ if unit==radians: return units.AxisInfo( - majloc=ticker.MultipleLocator(base=np.pi/2), - majfmt=ticker.FuncFormatter(rad_fn), - label=unit.fullname, - ) + majloc=ticker.MultipleLocator(base=np.pi/2), + majfmt=ticker.FuncFormatter(rad_fn), + label=unit.fullname, + ) elif unit==degrees: return units.AxisInfo( - majloc=ticker.AutoLocator(), - majfmt=ticker.FormatStrFormatter(r'$%i^\circ$'), - label=unit.fullname, - ) + majloc=ticker.AutoLocator(), + majfmt=ticker.FormatStrFormatter(r'$%i^\circ$'), + label=unit.fullname, + ) elif unit is not None: if hasattr(unit, 'fullname'): return units.AxisInfo(label=unit.fullname) @@ -331,7 +345,6 @@ def convert(val, unit, axis): if units.ConversionInterface.is_numlike(val): return val - #print 'convert checking iterable' if iterable(val): return [thisval.convert_to(unit).get_value() for thisval in val] else: @@ -346,17 +359,13 @@ return x.unit +def cos(x): + if iterable(x): + return [math.cos(val.convert_to(radians).get_value()) for val in x] + else: + return math.cos(x.convert_to(radians).get_value()) -def cos( x ): - if ( iterable(x) ): - result = [] - for val in x: - result.append( math.cos( val.convert_to( radians ).get_value() ) ) - return result - else: - return math.cos( x.convert_to( radians ).get_value() ) basicConverter = BasicUnitConverter() units.registry[BasicUnit] = basicConverter units.registry[TaggedValue] = basicConverter - diff -Nru matplotlib-1.1.1/lib/mpl_examples/units/ellipse_with_units.py matplotlib-1.2.0/lib/mpl_examples/units/ellipse_with_units.py --- matplotlib-1.1.1/lib/mpl_examples/units/ellipse_with_units.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/units/ellipse_with_units.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,31 +2,32 @@ Compare the ellipse generated with arcs versus a polygonal approximation """ from basic_units import cm -import numpy as npy +import numpy as np from matplotlib import patches -from pylab import figure, show +import matplotlib.pyplot as plt + xcenter, ycenter = 0.38*cm, 0.52*cm #xcenter, ycenter = 0., 0. width, height = 1e-1*cm, 3e-1*cm angle = -30 -theta = npy.arange(0.0, 360.0, 1.0)*npy.pi/180.0 -x = 0.5 * width * npy.cos(theta) -y = 0.5 * height * npy.sin(theta) - -rtheta = angle*npy.pi/180. -R = npy.array([ - [npy.cos(rtheta), -npy.sin(rtheta)], - [npy.sin(rtheta), npy.cos(rtheta)], +theta = np.arange(0.0, 360.0, 1.0)*np.pi/180.0 +x = 0.5 * width * np.cos(theta) +y = 0.5 * height * np.sin(theta) + +rtheta = angle*np.pi/180. +R = np.array([ + [np.cos(rtheta), -np.sin(rtheta)], + [np.sin(rtheta), np.cos(rtheta)], ]) -x, y = npy.dot(R, npy.array([x, y])) +x, y = np.dot(R, np.array([x, y])) x += xcenter y += ycenter -fig = figure() +fig = plt.figure() ax = fig.add_subplot(211, aspect='auto') ax.fill(x, y, alpha=0.2, facecolor='yellow', edgecolor='yellow', linewidth=1, zorder=1) @@ -46,7 +47,7 @@ #fig.savefig('ellipse_compare.png') fig.savefig('ellipse_compare') -fig = figure() +fig = plt.figure() ax = fig.add_subplot(211, aspect='auto') ax.fill(x, y, alpha=0.2, facecolor='yellow', edgecolor='yellow', linewidth=1, zorder=1) @@ -66,4 +67,4 @@ #fig.savefig('arc_compare.png') fig.savefig('arc_compare') -show() +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/units/evans_test.py matplotlib-1.2.0/lib/mpl_examples/units/evans_test.py --- matplotlib-1.1.1/lib/mpl_examples/units/evans_test.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/units/evans_test.py 2012-10-31 00:11:13.000000000 +0000 @@ -4,13 +4,11 @@ Here the "unit" is just a scalar conversion factor, but this example shows mpl is entirely agnostic to what kind of units client packages use """ - -import matplotlib - from matplotlib.cbook import iterable import matplotlib.units as units import matplotlib.ticker as ticker -from pylab import figure, show +import matplotlib.pyplot as plt + class Foo: def __init__( self, val, unit=1.0 ): @@ -71,7 +69,7 @@ # plot specifying units -fig = figure() +fig = plt.figure() fig.suptitle("Custom units") fig.subplots_adjust(bottom=0.2) ax = fig.add_subplot(1,2,2) @@ -90,4 +88,4 @@ label.set_rotation(30) label.set_ha('right') -show() +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/units/units_sample.py matplotlib-1.2.0/lib/mpl_examples/units/units_sample.py --- matplotlib-1.1.1/lib/mpl_examples/units/units_sample.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/units/units_sample.py 2012-10-31 00:11:13.000000000 +0000 @@ -8,12 +8,12 @@ """ from basic_units import cm, inch -from pylab import figure, show +import matplotlib.pyplot as plt import numpy cms = cm *numpy.arange(0, 10, 2) -fig = figure() +fig = plt.figure() ax1 = fig.add_subplot(2,2,1) ax1.plot(cms, cms) @@ -30,4 +30,4 @@ #fig.savefig('simple_conversion_plot.png') ax4.set_xlim(3*cm, 6*cm) # cm are converted to inches -show() +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_gtk2.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_gtk2.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_gtk2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_gtk2.py 2012-10-31 00:11:13.000000000 +0000 @@ -17,6 +17,8 @@ #from matplotlib.backends.backend_gtk import NavigationToolbar2GTK as NavigationToolbar from matplotlib.backends.backend_gtkagg import NavigationToolbar2GTKAgg as NavigationToolbar +# implement the default mpl key bindings +from matplotlib.backend_bases import key_press_handler win = gtk.Window() win.connect("destroy", lambda x: gtk.main_quit()) @@ -40,5 +42,11 @@ vbox.pack_start(toolbar, False, False) +def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvas, toolbar) + +canvas.mpl_connect('key_press_event', on_key_event) + win.show_all() gtk.main() diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_gtk3.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_gtk3.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_gtk3.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_gtk3.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,20 +1,17 @@ #!/usr/bin/env python """ -demonstrate adding a FigureCanvasGTK/GTKAgg widget to a gtk.ScrolledWindow +demonstrate adding a FigureCanvasGTK3Agg widget to a Gtk.ScrolledWindow +using GTK3 accessed via pygobject """ -import gtk +from gi.repository import Gtk from matplotlib.figure import Figure from numpy import arange, sin, pi +from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas -# uncomment to select /GTK/GTKAgg/GTKCairo -#from matplotlib.backends.backend_gtk import FigureCanvasGTK as FigureCanvas -from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas -#from matplotlib.backends.backend_gtkcairo import FigureCanvasGTKCairo as FigureCanvas - -win = gtk.Window() -win.connect("destroy", lambda x: gtk.main_quit()) +win = Gtk.Window() +win.connect("delete-event", Gtk.main_quit ) win.set_default_size(400,300) win.set_title("Embedding in GTK") @@ -24,17 +21,15 @@ s = sin(2*pi*t) a.plot(t,s) -sw = gtk.ScrolledWindow() +sw = Gtk.ScrolledWindow() win.add (sw) # A scrolled window border goes outside the scrollbars and viewport sw.set_border_width (10) -# policy: ALWAYS, AUTOMATIC, NEVER -sw.set_policy (hscrollbar_policy=gtk.POLICY_AUTOMATIC, - vscrollbar_policy=gtk.POLICY_ALWAYS) -canvas = FigureCanvas(f) # a gtk.DrawingArea +canvas = FigureCanvas(f) # a Gtk.DrawingArea canvas.set_size_request(800,600) sw.add_with_viewport (canvas) win.show_all() -gtk.main() +Gtk.main() + diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_gtk3_panzoom.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_gtk3_panzoom.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_gtk3_panzoom.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_gtk3_panzoom.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,37 @@ +#!/usr/bin/env python +""" +demonstrate NavigationToolbar with GTK3 accessed via pygobject +""" + +from gi.repository import Gtk + +from matplotlib.figure import Figure +from numpy import arange, sin, pi +from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas +from matplotlib.backends.backend_gtk3 import NavigationToolbar2GTK3 as NavigationToolbar + +win = Gtk.Window() +win.connect("delete-event", Gtk.main_quit ) +win.set_default_size(400,300) +win.set_title("Embedding in GTK") + +f = Figure(figsize=(5,4), dpi=100) +a = f.add_subplot(1,1,1) +t = arange(0.0,3.0,0.01) +s = sin(2*pi*t) +a.plot(t,s) + +vbox = Gtk.VBox() +win.add(vbox) + +# Add canvas to vbox +canvas = FigureCanvas(f) # a Gtk.DrawingArea +vbox.pack_start(canvas, True, True, 0) + +# Create toolbar +toolbar = NavigationToolbar(canvas, win) +vbox.pack_start(toolbar, False, False, 0) + +win.show_all() +Gtk.main() + diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_qt.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_qt.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_qt.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_qt.py 2012-10-31 00:11:13.000000000 +0000 @@ -8,6 +8,7 @@ # modified with no restriction; raw copies as well as modified versions # may be distributed without limitation. +from __future__ import unicode_literals import sys, os, random from qt import * @@ -75,7 +76,7 @@ def update_figure(self): # Build a list of 4 random integers between 0 and 10 (both inclusive) - l = [ random.randint(0, 10) for i in xrange(4) ] + l = [ random.randint(0, 10) for i in range(4) ] self.axes.plot([0, 1, 2, 3], l, 'r') self.draw() @@ -118,7 +119,7 @@ def about(self): QMessageBox.about(self, "About %s" % progname, -u"""%(prog)s version %(version)s +"""%(prog)s version %(version)s Copyright \N{COPYRIGHT SIGN} 2005 Florent Rougon This program is a simple example of a Qt application embedding matplotlib diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_qt4.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_qt4.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_qt4.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_qt4.py 2012-10-31 00:11:13.000000000 +0000 @@ -9,6 +9,7 @@ # modified with no restriction; raw copies as well as modified versions # may be distributed without limitation. +from __future__ import unicode_literals import sys, os, random from PyQt4 import QtGui, QtCore @@ -64,7 +65,7 @@ def update_figure(self): # Build a list of 4 random integers between 0 and 10 (both inclusive) - l = [ random.randint(0, 10) for i in xrange(4) ] + l = [ random.randint(0, 10) for i in range(4) ] self.axes.plot([0, 1, 2, 3], l, 'r') self.draw() @@ -107,16 +108,16 @@ self.fileQuit() def about(self): - QtGui.QMessageBox.about(self, "About %s" % progname, -u"""%(prog)s version %(version)s -Copyright \N{COPYRIGHT SIGN} 2005 Florent Rougon, 2006 Darren Dale + QtGui.QMessageBox.about(self, "About", +"""embedding_in_qt4.py example +Copyright 2005 Florent Rougon, 2006 Darren Dale This program is a simple example of a Qt4 application embedding matplotlib canvases. It may be used and modified with no restriction; raw copies as well as modified versions may be distributed without limitation.""" -% {"prog": progname, "version": progversion}) +) qApp = QtGui.QApplication(sys.argv) diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_qt4_wtoolbar.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_qt4_wtoolbar.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_qt4_wtoolbar.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_qt4_wtoolbar.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,67 @@ +from __future__ import print_function + +import sys + +import numpy as np +from matplotlib.figure import Figure +from matplotlib.backend_bases import key_press_handler +from matplotlib.backends.backend_qt4agg import ( + FigureCanvasQTAgg as FigureCanvas, + NavigationToolbar2QTAgg as NavigationToolbar) +from PyQt4.QtCore import * +from PyQt4.QtGui import * + + +class AppForm(QMainWindow): + def __init__(self, parent=None): + QMainWindow.__init__(self, parent) + #self.x, self.y = self.get_data() + self.data = self.get_data2() + self.create_main_frame() + self.on_draw() + + def create_main_frame(self): + self.main_frame = QWidget() + + self.fig = Figure((5.0, 4.0), dpi=100) + self.canvas = FigureCanvas(self.fig) + self.canvas.setParent(self.main_frame) + self.canvas.setFocusPolicy(Qt.StrongFocus) + self.canvas.setFocus() + + self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame) + + self.canvas.mpl_connect('key_press_event', self.on_key_press) + + vbox = QVBoxLayout() + vbox.addWidget(self.canvas) # the matplotlib canvas + vbox.addWidget(self.mpl_toolbar) + self.main_frame.setLayout(vbox) + self.setCentralWidget(self.main_frame) + + def get_data2(self): + return np.arange(20).reshape([4, 5]).copy() + + def on_draw(self): + self.fig.clear() + self.axes = self.fig.add_subplot(111) + #self.axes.plot(self.x, self.y, 'ro') + self.axes.imshow(self.data, interpolation='nearest') + #self.axes.plot([1,2,3]) + self.canvas.draw() + + def on_key_press(self, event): + print('you pressed', event.key) + # implement the default mpl key press events described at + # http://matplotlib.org/users/navigation_toolbar.html#navigation-keyboard-shortcuts + key_press_handler(event, self.canvas, self.mpl_toolbar) + + +def main(): + app = QApplication(sys.argv) + form = AppForm() + form.show() + app.exec_() + +if __name__ == "__main__": + main() diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_tk.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_tk.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_tk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_tk.py 2012-10-31 00:11:13.000000000 +0000 @@ -5,10 +5,17 @@ from numpy import arange, sin, pi from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +# implement the default mpl key bindings +from matplotlib.backend_bases import key_press_handler + + from matplotlib.figure import Figure -import Tkinter as Tk import sys +if sys.version_info[0] < 3: + import Tkinter as Tk +else: + import tkinter as Tk root = Tk.Tk() root.wm_title("Embedding in TK") @@ -31,6 +38,12 @@ toolbar.update() canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) +def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvas, toolbar) + +canvas.mpl_connect('key_press_event', on_key_event) + def _quit(): root.quit() # stops mainloop root.destroy() # this is necessary on Windows to prevent diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_tk2.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_tk2.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_tk2.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_tk2.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,45 @@ +#!/usr/bin/env python +import matplotlib +matplotlib.use('TkAgg') + +from numpy import arange, sin, pi +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +from matplotlib.figure import Figure + +import sys +if sys.version_info[0] < 3: + import Tkinter as Tk +else: + import tkinter as Tk + +def destroy(e): sys.exit() + +root = Tk.Tk() +root.wm_title("Embedding in TK") +#root.bind("", destroy) + + +f = Figure(figsize=(5,4), dpi=100) +a = f.add_subplot(111) +t = arange(0.0,3.0,0.01) +s = sin(2*pi*t) + +a.plot(t,s) +a.set_title('Tk embedding') +a.set_xlabel('X axis label') +a.set_ylabel('Y label') + + +# a tk.DrawingArea +canvas = FigureCanvasTkAgg(f, master=root) +canvas.show() +canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) + +#toolbar = NavigationToolbar2TkAgg( canvas, root ) +#toolbar.update() +canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) + +button = Tk.Button(master=root, text='Quit', command=sys.exit) +button.pack(side=Tk.BOTTOM) + +Tk.mainloop() diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_wx2.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_wx2.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_wx2.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_wx2.py 2012-10-31 00:11:13.000000000 +0000 @@ -32,7 +32,7 @@ wx.Frame.__init__(self,None,-1, 'CanvasFrame',size=(550,350)) - self.SetBackgroundColour(wx.NamedColor("WHITE")) + self.SetBackgroundColour(wx.NamedColour("WHITE")) self.figure = Figure() self.axes = self.figure.add_subplot(111) diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_wx3.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_wx3.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_wx3.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_wx3.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,5 @@ #!/usr/bin/env python + """ Copyright (C) 2003-2004 Andrew Straw, Jeremy O'Donoghue and others @@ -18,6 +19,7 @@ Thanks to matplotlib and wx teams for creating such great software! """ +from __future__ import print_function # Used to guarantee to use at least Wx2.8 import wxversion @@ -30,7 +32,7 @@ import matplotlib.cbook as cbook from matplotlib.backends.backend_wxagg import Toolbar, FigureCanvasWxAgg from matplotlib.figure import Figure -import numpy as npy +import numpy as np import wx import wx.xrc as xrc @@ -63,14 +65,14 @@ def init_plot_data(self): a = self.fig.add_subplot(111) - x = npy.arange(120.0)*2*npy.pi/60.0 - y = npy.arange(100.0)*2*npy.pi/50.0 - self.x, self.y = npy.meshgrid(x, y) - z = npy.sin(self.x) + npy.cos(self.y) + x = np.arange(120.0)*2*np.pi/60.0 + y = np.arange(100.0)*2*np.pi/50.0 + self.x, self.y = np.meshgrid(x, y) + z = np.sin(self.x) + np.cos(self.y) self.im = a.imshow( z, cmap=cm.jet)#, interpolation='nearest') - zmax = npy.amax(z) - ERR_TOL - ymax_i, xmax_i = npy.nonzero(z >= zmax) + zmax = np.amax(z) - ERR_TOL + ymax_i, xmax_i = np.nonzero(z >= zmax) if self.im.origin == 'upper': ymax_i = z.shape[0]-ymax_i self.lines = a.plot(xmax_i,ymax_i,'ko') @@ -83,13 +85,13 @@ return self.toolbar def OnWhiz(self,evt): - self.x += npy.pi/15 - self.y += npy.pi/20 - z = npy.sin(self.x) + npy.cos(self.y) + self.x += np.pi/15 + self.y += np.pi/20 + z = np.sin(self.x) + np.cos(self.y) self.im.set_array(z) - zmax = npy.amax(z) - ERR_TOL - ymax_i, xmax_i = npy.nonzero(z >= zmax) + zmax = np.amax(z) - ERR_TOL + ymax_i, xmax_i = np.nonzero(z >= zmax) if self.im.origin == 'upper': ymax_i = z.shape[0]-ymax_i self.lines[0].set_data(xmax_i,ymax_i) @@ -103,7 +105,7 @@ class MyApp(wx.App): def OnInit(self): xrcfile = cbook.get_sample_data('embedding_in_wx3.xrc', asfileobj=False) - print 'loading', xrcfile + print('loading', xrcfile) self.res = xrc.XmlResource(xrcfile) diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_wx4.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_wx4.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/embedding_in_wx4.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/embedding_in_wx4.py 2012-10-31 00:11:13.000000000 +0000 @@ -61,7 +61,7 @@ wx.Frame.__init__(self,None,-1, 'CanvasFrame',size=(550,350)) - self.SetBackgroundColour(wx.NamedColor("WHITE")) + self.SetBackgroundColour(wx.NamedColour("WHITE")) self.figure = Figure(figsize=(5,4), dpi=100) self.axes = self.figure.add_subplot(111) diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/interactive.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/interactive.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/interactive.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/interactive.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,5 @@ #!/usr/bin/env python + """Multithreaded interactive interpreter with GTK and Matplotlib support. WARNING: @@ -21,6 +22,8 @@ Also borrows liberally from code.py in the Python standard library.""" +from __future__ import print_function + __author__ = "Fernando Perez " import sys @@ -123,11 +126,11 @@ self.ready.acquire() if self._kill: - print 'Closing threads...', + print('Closing threads...') sys.stdout.flush() for tokill in self.on_kill: tokill() - print 'Done.' + print('Done.') if self.code_to_run is not None: self.ready.notify() @@ -215,19 +218,19 @@ try: inFile = file(fname, 'r') except IOError: - print '*** ERROR *** Could not read file <%s>' % fname + print('*** ERROR *** Could not read file <%s>' % fname) else: - print '*** Executing file <%s>:' % fname + print('*** Executing file <%s>:' % fname) for line in inFile: if line.lstrip().find('show()')==0: continue - print '>>', line, + print('>>', line) push(line) inFile.close() matplotlib.interactive(1) # turn on interaction if __name__ == '__main__': - print "This demo is not presently functional, so running" - print "it as a script has been disabled." + print("This demo is not presently functional, so running") + print("it as a script has been disabled.") sys.exit() # Quick sys.argv hack to extract the option and leave filenames in sys.argv. # For real option handling, use optparse or getopt. diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/interactive2.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/interactive2.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/interactive2.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/interactive2.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import print_function + # GTK Interactive Console # (C) 2003, Jon Anderson # See www.python.org/2.2/license.html for @@ -367,7 +369,7 @@ if len(sys.argv)>1: fname = sys.argv[1] if not os.path.exists(fname): - print >> sys.stderr, '%s does not exist' % fname + print('%s does not exist' % fname) for line in file(fname): line = line.strip() diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/lineprops_dialog_gtk.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/lineprops_dialog_gtk.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/lineprops_dialog_gtk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/lineprops_dialog_gtk.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,7 +3,7 @@ from matplotlib.backends.backend_gtk import DialogLineprops import numpy as np -from pylab import figure, show +import matplotlib.pyplot as plt def f(t): s1 = np.cos(2*np.pi*t) @@ -14,12 +14,12 @@ t2 = np.arange(0.0, 5.0, 0.02) t3 = np.arange(0.0, 2.0, 0.01) -fig = figure() +fig = plt.figure() ax = fig.add_subplot(111) l1, = ax.plot(t1, f(t1), 'bo', label='line 1') l2, = ax.plot(t2, f(t2), 'k--', label='line 2') dlg = DialogLineprops([l1,l2]) dlg.show() -show() +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/mathtext_wx.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/mathtext_wx.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/mathtext_wx.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/mathtext_wx.py 2012-10-31 00:11:13.000000000 +0000 @@ -37,7 +37,7 @@ class CanvasFrame(wx.Frame): def __init__(self, parent, title): wx.Frame.__init__(self, parent, -1, title, size=(550, 350)) - self.SetBackgroundColour(wx.NamedColor("WHITE")) + self.SetBackgroundColour(wx.NamedColour("WHITE")) self.figure = Figure() self.axes = self.figure.add_subplot(111) diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/mpl_with_glade.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/mpl_with_glade.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/mpl_with_glade.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/mpl_with_glade.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,4 +1,6 @@ #!/usr/bin/env python + +from __future__ import print_function import matplotlib matplotlib.use('GTK') @@ -64,15 +66,15 @@ self.canvas.grab_focus() def keypress(widget, event): - print 'key press' + print('key press') def buttonpress(widget, event): - print 'button press' + print('button press') self.canvas.connect('key_press_event', keypress) self.canvas.connect('button_press_event', buttonpress) def onselect(xmin, xmax): - print xmin, xmax + print(xmin, xmax) span = SpanSelector(self.axis, onselect, 'horizontal', useblit=False, rectprops=dict(alpha=0.5, facecolor='red') ) diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/printing_in_wx.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/printing_in_wx.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/printing_in_wx.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/printing_in_wx.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,6 +1,8 @@ #!/usr/bin/env python # printing_in_wx.py # + +from __future__ import print_function """ This examples demonstrates Printing (ie, to a printer) with a matplotlib figure using a wx Frame. This borrows the data from @@ -166,7 +168,7 @@ self.canvas.print_figure(path,dpi=300) if (path.find(thisdir) == 0): path = path[len(thisdir)+1:] - print 'Saved plot to %s' % path + print('Saved plot to %s' % path) def onExit(self,event=None): self.Destroy() diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/pylab_with_gtk.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/pylab_with_gtk.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/pylab_with_gtk.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/pylab_with_gtk.py 2012-10-31 00:11:13.000000000 +0000 @@ -2,17 +2,19 @@ An example of how to use pylab to manage your figure windows, but modify the GUI by accessing the underlying gtk widgets """ +from __future__ import print_function import matplotlib matplotlib.use('GTKAgg') -from pylab import get_current_fig_manager, subplot, plot, legend, connect, show +import matplotlib.pyplot as plt -ax = subplot(111) -plot([1,2,3], 'ro-', label='easy as 1 2 3') -plot([1,4,9], 'gs--', label='easy as 1 2 3 squared') -legend() +ax = plt.subplot(111) +plt.plot([1,2,3], 'ro-', label='easy as 1 2 3') +plt.plot([1,4,9], 'gs--', label='easy as 1 2 3 squared') +plt.legend() -manager = get_current_fig_manager() + +manager = plt.get_current_fig_manager() # you can also access the window or vbox attributes this way toolbar = manager.toolbar @@ -23,7 +25,7 @@ button.show() def clicked(button): - print 'hi mom' + print('hi mom') button.connect('clicked', clicked) toolitem = gtk.ToolItem() @@ -49,6 +51,6 @@ else: label.set_markup('x,y=(%f, %f)'%(event.xdata, event.ydata)) -connect('motion_notify_event', update) +plt.connect('motion_notify_event', update) -show() +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/rec_edit_gtk_custom.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/rec_edit_gtk_custom.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/rec_edit_gtk_custom.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/rec_edit_gtk_custom.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,6 +3,7 @@ formatting of the cells and show how to limit string entries to a list of strings """ +from __future__ import print_function import gtk import numpy as np import matplotlib.mlab as mlab @@ -28,7 +29,7 @@ treeview = gtktools.RecTreeView(liststore, constant=constant) def mycallback(liststore, rownum, colname, oldval, newval): - print 'verify: old=%s, new=%s, rec=%s'%(oldval, newval, liststore.r[rownum][colname]) + print('verify: old=%s, new=%s, rec=%s'%(oldval, newval, liststore.r[rownum][colname])) liststore.callbacks.connect('cell_changed', mycallback) diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/svg_histogram.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/svg_histogram.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/svg_histogram.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/svg_histogram.py 2012-10-31 00:11:13.000000000 +0000 @@ -5,19 +5,38 @@ Demonstrate how to create an interactive histogram, in which bars are hidden or shown by cliking on legend markers. -The interactivity is encoded in ecmascript and inserted in the SVG code -in a post-processing step. To render the image, open it in a web -browser. SVG is supported in most web browsers used by Linux and OSX -users. Windows IE9 supports SVG, but earlier versions do not. +The interactivity is encoded in ecmascript (javascript) and inserted in +the SVG code in a post-processing step. To render the image, open it in +a web browser. SVG is supported in most web browsers used by Linux and +OSX users. Windows IE9 supports SVG, but earlier versions do not. + +Notes +----- +The matplotlib backend lets us assign ids to each object. This is the +mechanism used here to relate matplotlib objects created in python and +the corresponding SVG constructs that are parsed in the second step. +While flexible, ids are cumbersome to use for large collection of +objects. Two mechanisms could be used to simplify things: + * systematic grouping of objects into SVG tags, + * assingning classes to each SVG object according to its origin. + +For example, instead of modifying the properties of each individual bar, +the bars from the `hist` function could either be grouped in +a PatchCollection, or be assigned a class="hist_##" attribute. + +CSS could also be used more extensively to replace repetitive markup +troughout the generated SVG. __author__="david.huard@gmail.com" """ + import numpy as np import matplotlib.pyplot as plt import xml.etree.ElementTree as ET from StringIO import StringIO +import json plt.rcParams['svg.embed_char_paths'] = 'none' @@ -26,16 +45,7 @@ # space with ns0. ET.register_namespace("","http://www.w3.org/2000/svg") - -def python2js(d): - """Return a string representation of a python dictionary in - ecmascript object syntax.""" - - objs = [] - for key, value in d.items(): - objs.append( key + ':' + str(value) ) - - return '{' + ', '.join(objs) + '}' + # --- Create histogram, legend and title --- @@ -62,7 +72,11 @@ # Set ids for the legend patches for i, t in enumerate(leg.get_patches()): t.set_gid('leg_patch_%d'%i) - + +# Set ids for the text patches +for i, t in enumerate(leg.get_texts()): + t.set_gid('leg_text_%d'%i) + # Save SVG in a fake file object. f = StringIO() plt.savefig(f, format="svg") @@ -77,10 +91,15 @@ for i, t in enumerate(leg.get_patches()): el = xmlid['leg_patch_%d'%i] el.set('cursor', 'pointer') - el.set('opacity', '1.0') - el.set('onclick', "toggle_element(evt, 'hist_%d')"%i) + el.set('onclick', "toggle_hist(this)") -# Create script defining the function `toggle_element`. +# Add attributes to the text objects. +for i, t in enumerate(leg.get_texts()): + el = xmlid['leg_text_%d'%i] + el.set('cursor', 'pointer') + el.set('onclick', "toggle_hist(this)") + +# Create script defining the function `toggle_hist`. # We create a global variable `container` that stores the patches id # belonging to each histogram. Then a function "toggle_element" sets the # visibility attribute of all patches of each histogram and the opacity @@ -91,37 +110,46 @@ -"""%python2js(hist_patches) +"""%json.dumps(hist_patches) +# Add a transition effect +css = tree.getchildren()[0][0] +css.text = css.text + "g {-webkit-transition:opacity 0.4s ease-out;-moz-transition:opacity 0.4s ease-out;}" + # Insert the script and save to file. tree.insert(0, ET.XML(script)) diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/svg_tooltip.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/svg_tooltip.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/svg_tooltip.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/svg_tooltip.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,125 @@ +""" +SVG tooltip example +=================== + +This example shows how to create a tooltip that will show up when +hovering over a matplotlib patch. + +Although it is possible to create the tooltip from CSS or javascript, +here we create it in matplotlib and simply toggle its visibility on +when hovering over the patch. This approach provides total control over +the tooltip placement and appearance, at the expense of more code up +front. + +The alternative approach would be to put the tooltip content in `title` +atttributes of SVG objects. Then, using an existing js/CSS library, it +would be relatively straightforward to create the tooltip in the +browser. The content would be dictated by the `title` attribute, and +the appearance by the CSS. + + +:author: David Huard +""" + + +import matplotlib.pyplot as plt +import xml.etree.ElementTree as ET +from StringIO import StringIO + +ET.register_namespace("","http://www.w3.org/2000/svg") + +fig = plt.figure() +ax = fig.add_subplot(111) + +# Create patches to which tooltips will be assigned. +circle = plt.Circle((0,0), 5, fc='blue') +rect = plt.Rectangle((-5, 10), 10, 5, fc='green') + +ax.add_patch(circle) +ax.add_patch(rect) + +# Create the tooltips +circle_tip = ax.annotate('This is a blue circle.', + xy=(0,0), + xytext=(30,-30), + textcoords='offset points', + color='w', + ha='left', + bbox=dict(boxstyle='round,pad=.5', fc=(.1,.1,.1,.92), ec=(1.,1.,1.), lw=1, zorder=1), + ) + +rect_tip = ax.annotate('This is a green rectangle.', + xy=(-5,10), + xytext=(30,40), + textcoords='offset points', + color='w', + ha='left', + bbox=dict(boxstyle='round,pad=.5', fc=(.1,.1,.1,.92), ec=(1.,1.,1.), lw=1, zorder=1), + ) + + +# Set id for the patches +for i, t in enumerate(ax.patches): + t.set_gid('patch_%d'%i) + +# Set id for the annotations +for i, t in enumerate(ax.texts): + t.set_gid('tooltip_%d'%i) + + +# Save the figure in a fake file object +ax.set_xlim(-30, 30) +ax.set_ylim(-30, 30) +ax.set_aspect('equal') + +f = StringIO() +plt.savefig(f, format="svg") + +# --- Add interactivity --- + +# Create XML tree from the SVG file. +tree, xmlid = ET.XMLID(f.getvalue()) +tree.set('onload', 'init(evt)') + +# Hide the tooltips +for i, t in enumerate(ax.texts): + el = xmlid['tooltip_%d'%i] + el.set('visibility', 'hidden') + +# Assign onmouseover and onmouseout callbacks to patches. +for i, t in enumerate(ax.patches): + el = xmlid['patch_%d'%i] + el.set('onmouseover', "ShowTooltip(this)") + el.set('onmouseout', "HideTooltip(this)") + +# This is the script defining the ShowTooltip and HideTooltip functions. +script = """ + + """ + +# Insert the script at the top of the file and save it. +tree.insert(0, ET.XML(script)) +ET.ElementTree(tree).write('svg_tooltip.svg') diff -Nru matplotlib-1.1.1/lib/mpl_examples/user_interfaces/wxcursor_demo.py matplotlib-1.2.0/lib/mpl_examples/user_interfaces/wxcursor_demo.py --- matplotlib-1.1.1/lib/mpl_examples/user_interfaces/wxcursor_demo.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/user_interfaces/wxcursor_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -18,7 +18,7 @@ wx.Frame.__init__(self,None,-1, 'CanvasFrame',size=(550,350)) - self.SetBackgroundColour(wx.NamedColor("WHITE")) + self.SetBackgroundColour(wx.NamedColour("WHITE")) self.figure = Figure() self.axes = self.figure.add_subplot(111) diff -Nru matplotlib-1.1.1/lib/mpl_examples/widgets/lasso_selector_demo.py matplotlib-1.2.0/lib/mpl_examples/widgets/lasso_selector_demo.py --- matplotlib-1.1.1/lib/mpl_examples/widgets/lasso_selector_demo.py 1970-01-01 00:00:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/widgets/lasso_selector_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -0,0 +1,89 @@ +from __future__ import print_function + +import numpy as np + +from matplotlib.widgets import LassoSelector +from matplotlib.path import Path + +try: + raw_input +except NameError: + # Python 3 + raw_input = input + + +class SelectFromCollection(object): + """Select indices from a matplotlib collection using `LassoSelector`. + + Selected indices are saved in the `ind` attribute. This tool highlights + selected points by fading them out (i.e., reducing their alpha values). + If your collection has alpha < 1, this tool will permanently alter them. + + Note that this tool selects collection objects based on their *origins* + (i.e., `offsets`). + + Parameters + ---------- + ax : :class:`~matplotlib.axes.Axes` + Axes to interact with. + + collection : :class:`matplotlib.collections.Collection` subclass + Collection you want to select from. + + alpha_other : 0 <= float <= 1 + To highlight a selection, this tool sets all selected points to an + alpha value of 1 and non-selected points to `alpha_other`. + """ + def __init__(self, ax, collection, alpha_other=0.3): + self.canvas = ax.figure.canvas + self.collection = collection + self.alpha_other = alpha_other + + self.xys = collection.get_offsets() + self.Npts = len(self.xys) + + # Ensure that we have separate colors for each object + self.fc = collection.get_facecolors() + if len(self.fc) == 0: + raise ValueError('Collection must have a facecolor') + elif len(self.fc) == 1: + self.fc = np.tile(self.fc, self.Npts).reshape(self.Npts, -1) + + self.lasso = LassoSelector(ax, onselect=self.onselect) + self.ind = [] + + def onselect(self, verts): + path = Path(verts) + self.ind = np.nonzero([path.contains_point(xy) for xy in self.xys])[0] + self.fc[:, -1] = self.alpha_other + self.fc[self.ind, -1] = 1 + self.collection.set_facecolors(self.fc) + self.canvas.draw_idle() + + def disconnect(self): + self.lasso.disconnect_events() + self.fc[:, -1] = 1 + self.collection.set_facecolors(self.fc) + self.canvas.draw_idle() + + +if __name__ == '__main__': + import matplotlib.pyplot as plt + + plt.ion() + data = np.random.rand(100, 2) + + subplot_kw = dict(xlim=(0, 1), ylim=(0, 1), autoscale_on=False) + fig, ax = plt.subplots(subplot_kw=subplot_kw) + + pts = ax.scatter(data[:, 0], data[:, 1], s=80) + selector = SelectFromCollection(ax, pts) + + plt.draw() + raw_input('Press any key to accept selected points') + print("Selected points:") + print(selector.xys[selector.ind]) + selector.disconnect() + + # Block end of script so you can check that the lasso is disconnected. + raw_input('Press any key to quit') diff -Nru matplotlib-1.1.1/lib/mpl_examples/widgets/menu.py matplotlib-1.2.0/lib/mpl_examples/widgets/menu.py --- matplotlib-1.1.1/lib/mpl_examples/widgets/menu.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/widgets/menu.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import division, print_function import numpy as np import matplotlib import matplotlib.colors as colors @@ -75,7 +76,7 @@ self.on_select(self) def set_extent(self, x, y, w, h): - print x, y, w, h + print(x, y, w, h) self.rect.set_x(x) self.rect.set_y(y) self.rect.set_width(w) @@ -171,7 +172,7 @@ menuitems = [] for label in ('open', 'close', 'save', 'save as', 'quit'): def on_select(item): - print 'you selected', item.labelstr + print('you selected %s' % item.labelstr) item = MenuItem(fig, label, props=props, hoverprops=hoverprops, on_select=on_select) menuitems.append(item) diff -Nru matplotlib-1.1.1/lib/mpl_examples/widgets/multicursor.py matplotlib-1.2.0/lib/mpl_examples/widgets/multicursor.py --- matplotlib-1.1.1/lib/mpl_examples/widgets/multicursor.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/widgets/multicursor.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,10 +1,11 @@ +import numpy as np +import matplotlib.pyplot as plt from matplotlib.widgets import MultiCursor -from pylab import figure, show, pi, arange, sin -t = arange(0.0, 2.0, 0.01) -s1 = sin(2*pi*t) -s2 = sin(4*pi*t) -fig = figure() +t = np.arange(0.0, 2.0, 0.01) +s1 = np.sin(2*np.pi*t) +s2 = np.sin(4*np.pi*t) +fig = plt.figure() ax1 = fig.add_subplot(211) ax1.plot(t, s1) @@ -13,4 +14,4 @@ ax2.plot(t, s2) multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1) -show() +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/widgets/radio_buttons.py matplotlib-1.2.0/lib/mpl_examples/widgets/radio_buttons.py --- matplotlib-1.1.1/lib/mpl_examples/widgets/radio_buttons.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/widgets/radio_buttons.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,36 +1,38 @@ +import numpy as np +import matplotlib.pyplot as plt from matplotlib.widgets import RadioButtons -from pylab import * -t = arange(0.0, 2.0, 0.01) -s0 = sin(2*pi*t) -s1 = sin(4*pi*t) -s2 = sin(8*pi*t) -ax = subplot(111) +t = np.arange(0.0, 2.0, 0.01) +s0 = np.sin(2*np.pi*t) +s1 = np.sin(4*np.pi*t) +s2 = np.sin(8*np.pi*t) + +ax = plt.subplot(111) l, = ax.plot(t, s0, lw=2, color='red') -subplots_adjust(left=0.3) +plt.subplots_adjust(left=0.3) axcolor = 'lightgoldenrodyellow' -rax = axes([0.05, 0.7, 0.15, 0.15], axisbg=axcolor) +rax = plt.axes([0.05, 0.7, 0.15, 0.15], axisbg=axcolor) radio = RadioButtons(rax, ('2 Hz', '4 Hz', '8 Hz')) def hzfunc(label): hzdict = {'2 Hz':s0, '4 Hz':s1, '8 Hz':s2} ydata = hzdict[label] l.set_ydata(ydata) - draw() + plt.draw() radio.on_clicked(hzfunc) -rax = axes([0.05, 0.4, 0.15, 0.15], axisbg=axcolor) +rax = plt.axes([0.05, 0.4, 0.15, 0.15], axisbg=axcolor) radio2 = RadioButtons(rax, ('red', 'blue', 'green')) def colorfunc(label): l.set_color(label) - draw() + plt.draw() radio2.on_clicked(colorfunc) -rax = axes([0.05, 0.1, 0.15, 0.15], axisbg=axcolor) +rax = plt.axes([0.05, 0.1, 0.15, 0.15], axisbg=axcolor) radio3 = RadioButtons(rax, ('-', '--', '-.', 'steps', ':')) def stylefunc(label): l.set_linestyle(label) - draw() + plt.draw() radio3.on_clicked(stylefunc) -show() +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/widgets/rectangle_selector.py matplotlib-1.2.0/lib/mpl_examples/widgets/rectangle_selector.py --- matplotlib-1.1.1/lib/mpl_examples/widgets/rectangle_selector.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/widgets/rectangle_selector.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,3 +1,4 @@ +from __future__ import print_function """ Do a mouseclick somewhere, move the mouse to some destination, release the button. This class gives click- and release-events and also draws @@ -15,16 +16,16 @@ 'eclick and erelease are the press and release events' x1, y1 = eclick.xdata, eclick.ydata x2, y2 = erelease.xdata, erelease.ydata - print "(%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1, y1, x2, y2) - print " The button you used were: ", eclick.button, erelease.button + print ("(%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1, y1, x2, y2)) + print (" The button you used were: %s %s" % (eclick.button, erelease.button)) def toggle_selector(event): - print ' Key pressed.' + print (' Key pressed.') if event.key in ['Q', 'q'] and toggle_selector.RS.active: - print ' RectangleSelector deactivated.' + print (' RectangleSelector deactivated.') toggle_selector.RS.set_active(False) if event.key in ['A', 'a'] and not toggle_selector.RS.active: - print ' RectangleSelector activated.' + print (' RectangleSelector activated.') toggle_selector.RS.set_active(True) @@ -36,7 +37,7 @@ plt.plot(x, +np.cos(.2*np.pi*x), lw=3.5, c='r', alpha=.5) plt.plot(x, -np.sin(.2*np.pi*x), lw=3.5, c='g', alpha=.3) -print "\n click --> release" +print ("\n click --> release") # drawtype is 'box' or 'line' or 'none' toggle_selector.RS = RectangleSelector(current_ax, line_select_callback, diff -Nru matplotlib-1.1.1/lib/mpl_examples/widgets/slider_demo.py matplotlib-1.2.0/lib/mpl_examples/widgets/slider_demo.py --- matplotlib-1.1.1/lib/mpl_examples/widgets/slider_demo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/widgets/slider_demo.py 2012-10-31 00:11:13.000000000 +0000 @@ -1,18 +1,19 @@ -from pylab import * +import numpy as np +import matplotlib.pyplot as plt from matplotlib.widgets import Slider, Button, RadioButtons -ax = subplot(111) -subplots_adjust(left=0.25, bottom=0.25) -t = arange(0.0, 1.0, 0.001) +ax = plt.subplot(111) +plt.subplots_adjust(left=0.25, bottom=0.25) +t = np.arange(0.0, 1.0, 0.001) a0 = 5 f0 = 3 -s = a0*sin(2*pi*f0*t) -l, = plot(t,s, lw=2, color='red') -axis([0, 1, -10, 10]) +s = a0*np.sin(2*np.pi*f0*t) +l, = plt.plot(t,s, lw=2, color='red') +plt.axis([0, 1, -10, 10]) axcolor = 'lightgoldenrodyellow' -axfreq = axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor) -axamp = axes([0.25, 0.15, 0.65, 0.03], axisbg=axcolor) +axfreq = plt.axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor) +axamp = plt.axes([0.25, 0.15, 0.65, 0.03], axisbg=axcolor) sfreq = Slider(axfreq, 'Freq', 0.1, 30.0, valinit=f0) samp = Slider(axamp, 'Amp', 0.1, 10.0, valinit=a0) @@ -20,24 +21,24 @@ def update(val): amp = samp.val freq = sfreq.val - l.set_ydata(amp*sin(2*pi*freq*t)) - draw() + l.set_ydata(amp*np.sin(2*np.pi*freq*t)) + plt.draw() sfreq.on_changed(update) samp.on_changed(update) -resetax = axes([0.8, 0.025, 0.1, 0.04]) +resetax = plt.axes([0.8, 0.025, 0.1, 0.04]) button = Button(resetax, 'Reset', color=axcolor, hovercolor='0.975') def reset(event): sfreq.reset() samp.reset() button.on_clicked(reset) -rax = axes([0.025, 0.5, 0.15, 0.15], axisbg=axcolor) +rax = plt.axes([0.025, 0.5, 0.15, 0.15], axisbg=axcolor) radio = RadioButtons(rax, ('red', 'blue', 'green'), active=0) def colorfunc(label): l.set_color(label) - draw() + plt.draw() radio.on_clicked(colorfunc) -show() +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_examples/widgets/span_selector.py matplotlib-1.2.0/lib/mpl_examples/widgets/span_selector.py --- matplotlib-1.1.1/lib/mpl_examples/widgets/span_selector.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_examples/widgets/span_selector.py 2012-10-31 00:11:13.000000000 +0000 @@ -3,15 +3,15 @@ The SpanSelector is a mouse widget to select a xmin/xmax range and plot the detail view of the selected region in the lower axes """ -import numpy as npy -from pylab import figure, show +import numpy as np +import matplotlib.pyplot as plt from matplotlib.widgets import SpanSelector -fig = figure(figsize=(8,6)) +fig = plt.figure(figsize=(8,6)) ax = fig.add_subplot(211, axisbg='#FFFFCC') -x = npy.arange(0.0, 5.0, 0.01) -y = npy.sin(2*npy.pi*x) + 0.5*npy.random.randn(len(x)) +x = np.arange(0.0, 5.0, 0.01) +y = np.sin(2*np.pi*x) + 0.5*np.random.randn(len(x)) ax.plot(x, y, '-') ax.set_ylim(-2,2) @@ -22,7 +22,7 @@ def onselect(xmin, xmax): - indmin, indmax = npy.searchsorted(x, (xmin, xmax)) + indmin, indmax = np.searchsorted(x, (xmin, xmax)) indmax = min(len(x)-1, indmax) thisx = x[indmin:indmax] @@ -37,4 +37,4 @@ rectprops=dict(alpha=0.5, facecolor='red') ) -show() +plt.show() diff -Nru matplotlib-1.1.1/lib/mpl_toolkits/axes_grid/colorbar.py matplotlib-1.2.0/lib/mpl_toolkits/axes_grid/colorbar.py --- matplotlib-1.1.1/lib/mpl_toolkits/axes_grid/colorbar.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_toolkits/axes_grid/colorbar.py 2012-10-31 00:11:14.000000000 +0000 @@ -144,6 +144,19 @@ the axes objects in which the mappable and the colorbar are drawn. In this case, do not use any of the axes properties kwargs. +It is known that some vector graphics viewer (svg and pdf) renders white gaps +between segments of the colorbar. This is due to bugs in the viewers not +matplotlib. As a workaround the colorbar can be rendered with overlapping +segments:: + + cbar = colorbar() + cbar.solids.set_edgecolor("face") + draw() + +However this has negative consequences in other circumstances. Particularly with +semi transparent images (alpha < 1) and colorbar extensions and is not enabled +by default see (issue #1188). + returns: :class:`~matplotlib.colorbar.Colorbar` instance; see also its base class, :class:`~matplotlib.colorbar.ColorbarBase`. Call the diff -Nru matplotlib-1.1.1/lib/mpl_toolkits/axes_grid1/axes_divider.py matplotlib-1.2.0/lib/mpl_toolkits/axes_grid1/axes_divider.py --- matplotlib-1.1.1/lib/mpl_toolkits/axes_grid1/axes_divider.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_toolkits/axes_grid1/axes_divider.py 2012-10-31 00:11:14.000000000 +0000 @@ -15,8 +15,6 @@ from matplotlib.axes import SubplotBase -import new - import axes_size as Size @@ -343,7 +341,6 @@ return None - from matplotlib.gridspec import SubplotSpec, GridSpec class SubplotDivider(Divider): @@ -901,9 +898,10 @@ new_class = _locatableaxes_classes.get(axes_class) if new_class is None: - new_class = new.classobj("Locatable%s" % (axes_class.__name__), - (LocatableAxesBase, axes_class), - {'_axes_class': axes_class}) + new_class = type("Locatable%s" % (axes_class.__name__), + (LocatableAxesBase, axes_class), + {'_axes_class': axes_class}) + _locatableaxes_classes[axes_class] = new_class return new_class diff -Nru matplotlib-1.1.1/lib/mpl_toolkits/axes_grid1/axes_grid.py matplotlib-1.2.0/lib/mpl_toolkits/axes_grid1/axes_grid.py --- matplotlib-1.1.1/lib/mpl_toolkits/axes_grid1/axes_grid.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_toolkits/axes_grid1/axes_grid.py 2012-10-31 00:11:14.000000000 +0000 @@ -494,8 +494,8 @@ share_all False [ True | False ] aspect True [ True | False ] label_mode "L" [ "L" | "1" | "all" ] - cbar_mode None [ "each" | "single" ] - cbar_location "right" [ "right" | "top" ] + cbar_mode None [ "each" | "single" | "edge" ] + cbar_location "right" [ "left" | "right" | "bottom" | "top" ] cbar_pad None cbar_size "5%" cbar_set_cax True [ True | False ] @@ -631,42 +631,78 @@ def _update_locators(self): h = [] + v = [] h_ax_pos = [] h_cb_pos = [] - for ax in self._column_refax: - if h: h.append(self._horiz_pad_size) #Size.Fixed(self._axes_pad)) + if self._colorbar_mode == "single" and self._colorbar_location in ('left', 'bottom'): + if self._colorbar_location == "left": + #sz = Size.Fraction(Size.AxesX(self.axes_llc), self._nrows) + sz = Size.Fraction(self._nrows, Size.AxesX(self.axes_llc)) + h.append(Size.from_any(self._colorbar_size, sz)) + h.append(Size.from_any(self._colorbar_pad, sz)) + locator = self._divider.new_locator(nx=0, ny=0, ny1=-1) + elif self._colorbar_location == "bottom": + #sz = Size.Fraction(Size.AxesY(self.axes_llc), self._ncols) + sz = Size.Fraction(self._ncols, Size.AxesY(self.axes_llc)) + v.append(Size.from_any(self._colorbar_size, sz)) + v.append(Size.from_any(self._colorbar_pad, sz)) + locator = self._divider.new_locator(nx=0, nx1=-1, ny=0) + for i in range(self.ngrids): + self.cbar_axes[i].set_visible(False) + self.cbar_axes[0].set_axes_locator(locator) + self.cbar_axes[0].set_visible(True) - h_ax_pos.append(len(h)) + for col,ax in enumerate(self._column_refax): + if h: h.append(self._horiz_pad_size) #Size.Fixed(self._axes_pad)) if ax: sz = Size.AxesX(ax) else: sz = Size.AxesX(self.axes_llc) + + if (self._colorbar_mode == "each" or + (self._colorbar_mode == 'edge' and + col == 0)) and self._colorbar_location == "left": + h_cb_pos.append(len(h)) + h.append(Size.from_any(self._colorbar_size, sz)) + h.append(Size.from_any(self._colorbar_pad, sz)) + + h_ax_pos.append(len(h)) + h.append(sz) - if self._colorbar_mode == "each" and self._colorbar_location == "right": + if (self._colorbar_mode == "each" or + (self._colorbar_mode == 'edge' and + col == self._ncols - 1)) and self._colorbar_location == "right": h.append(Size.from_any(self._colorbar_pad, sz)) h_cb_pos.append(len(h)) h.append(Size.from_any(self._colorbar_size, sz)) - v = [] - v_ax_pos = [] v_cb_pos = [] - for ax in self._row_refax[::-1]: + for row,ax in enumerate(self._row_refax[::-1]): if v: v.append(self._horiz_pad_size) #Size.Fixed(self._axes_pad)) - v_ax_pos.append(len(v)) if ax: sz = Size.AxesY(ax) else: sz = Size.AxesY(self.axes_llc) - v.append(sz) + if (self._colorbar_mode == "each" or + (self._colorbar_mode == 'edge' and + row == 0)) and self._colorbar_location == "bottom": + v_cb_pos.append(len(v)) + v.append(Size.from_any(self._colorbar_size, sz)) + v.append(Size.from_any(self._colorbar_pad, sz)) + + v_ax_pos.append(len(v)) + v.append(sz) - if self._colorbar_mode == "each" and self._colorbar_location == "top": + if (self._colorbar_mode == "each" or + (self._colorbar_mode == 'edge' and + row == self._nrows - 1)) and self._colorbar_location == "top": v.append(Size.from_any(self._colorbar_pad, sz)) v_cb_pos.append(len(v)) v.append(Size.from_any(self._colorbar_size, sz)) @@ -680,13 +716,24 @@ self.axes_all[i].set_axes_locator(locator) if self._colorbar_mode == "each": - if self._colorbar_location == "right": + if self._colorbar_location in ("right", "left"): locator = self._divider.new_locator(nx=h_cb_pos[col], ny=v_ax_pos[self._nrows -1 - row]) - elif self._colorbar_location == "top": + elif self._colorbar_location in ("top", "bottom"): locator = self._divider.new_locator(nx=h_ax_pos[col], ny=v_cb_pos[self._nrows -1 - row]) self.cbar_axes[i].set_axes_locator(locator) + elif self._colorbar_mode == 'edge': + if ((self._colorbar_location == 'left' and col == 0) or + (self._colorbar_location == 'right' and col == self._ncols-1)): + locator = self._divider.new_locator(nx=h_cb_pos[0], + ny=v_ax_pos[self._nrows -1 - row]) + self.cbar_axes[row].set_axes_locator(locator) + elif ((self._colorbar_location == 'bottom' and row == self._nrows - 1) or + (self._colorbar_location == 'top' and row == 0)): + locator = self._divider.new_locator(nx=h_ax_pos[col], + ny=v_cb_pos[0]) + self.cbar_axes[col].set_axes_locator(locator) if self._colorbar_mode == "single": @@ -702,13 +749,23 @@ v.append(Size.from_any(self._colorbar_pad, sz)) v.append(Size.from_any(self._colorbar_size, sz)) locator = self._divider.new_locator(nx=0, nx1=-1, ny=-2) - for i in range(self.ngrids): - self.cbar_axes[i].set_visible(False) - self.cbar_axes[0].set_axes_locator(locator) - self.cbar_axes[0].set_visible(True) + if self._colorbar_location in ("right", "top"): + for i in range(self.ngrids): + self.cbar_axes[i].set_visible(False) + self.cbar_axes[0].set_axes_locator(locator) + self.cbar_axes[0].set_visible(True) elif self._colorbar_mode == "each": for i in range(self.ngrids): self.cbar_axes[i].set_visible(True) + elif self._colorbar_mode == "edge": + if self._colorbar_location in ('right', 'left'): + count = self._nrows + else: + count = self._ncols + for i in range(count): + self.cbar_axes[i].set_visible(True) + for j in range(i + 1, self.ngrids): + self.cbar_axes[j].set_visible(False) else: for i in range(self.ngrids): self.cbar_axes[i].set_visible(False) diff -Nru matplotlib-1.1.1/lib/mpl_toolkits/axes_grid1/axes_size.py matplotlib-1.2.0/lib/mpl_toolkits/axes_grid1/axes_size.py --- matplotlib-1.1.1/lib/mpl_toolkits/axes_grid1/axes_size.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_toolkits/axes_grid1/axes_size.py 2012-10-31 00:11:14.000000000 +0000 @@ -187,6 +187,7 @@ class Fraction(_Base): """ An instance whose size is a *fraction* of the *ref_size*. + :: >>> s = Fraction(0.3, AxesX(ax)) @@ -223,7 +224,7 @@ """ Creates Fixed unit when the first argument is a float, or a Fraction unit if that is a string that ends with %. The second - argument is only meaningful when Fraction unit is created. + argument is only meaningful when Fraction unit is created.:: >>> a = Size.from_any(1.2) # => Size.Fixed(1.2) >>> Size.from_any("50%", a) # => Size.Fraction(0.5, a) @@ -280,8 +281,7 @@ try: self._get_func = self._get_func_map[direction] except KeyError: - print "direction must be one of left, right, bottom, top" - raise + raise KeyError("direction must be one of left, right, bottom, top") def __call__(self, renderer): vl = [self._get_func(ax.get_tightbbox(renderer, False), diff -Nru matplotlib-1.1.1/lib/mpl_toolkits/axes_grid1/colorbar.py matplotlib-1.2.0/lib/mpl_toolkits/axes_grid1/colorbar.py --- matplotlib-1.1.1/lib/mpl_toolkits/axes_grid1/colorbar.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_toolkits/axes_grid1/colorbar.py 2012-10-31 00:11:14.000000000 +0000 @@ -144,6 +144,19 @@ the axes objects in which the mappable and the colorbar are drawn. In this case, do not use any of the axes properties kwargs. +It is known that some vector graphics viewer (svg and pdf) renders white gaps +between segments of the colorbar. This is due to bugs in the viewers not +matplotlib. As a workaround the colorbar can be rendered with overlapping +segments:: + + cbar = colorbar() + cbar.solids.set_edgecolor("face") + draw() + +However this has negative consequences in other circumstances. Particularly with +semi transparent images (alpha < 1) and colorbar extensions and is not enabled +by default see (issue #1188). + returns: :class:`~matplotlib.colorbar.Colorbar` instance; see also its base class, :class:`~matplotlib.colorbar.ColorbarBase`. Call the @@ -518,7 +531,7 @@ def _add_solids(self, X, Y, C): ''' - Draw the colors using :meth:`~matplotlib.axes.Axes.pcolor`; + Draw the colors using :meth:`~matplotlib.axes.Axes.pcolormesh`; optionally add separators. ''' ## Change to pcolorfast after fixing bugs in some backends... diff -Nru matplotlib-1.1.1/lib/mpl_toolkits/axes_grid1/mpl_axes.py matplotlib-1.2.0/lib/mpl_toolkits/axes_grid1/mpl_axes.py --- matplotlib-1.1.1/lib/mpl_toolkits/axes_grid1/mpl_axes.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_toolkits/axes_grid1/mpl_axes.py 2012-10-31 00:11:14.000000000 +0000 @@ -132,11 +132,11 @@ labelOn = "label%dOn" % self._axisnum if _ticks is not None: - for tick in self._axis.get_major_ticks(): - setattr(tick, tickOn, _ticks) + tickparam = {tickOn: _ticks} + self._axis.set_tick_params(**tickparam) if _ticklabels is not None: - for tick in self._axis.get_major_ticks(): - setattr(tick, labelOn, _ticklabels) + tickparam = {labelOn: _ticklabels} + self._axis.set_tick_params(**tickparam) if _label is not None: pos = self._axis.get_label_position() diff -Nru matplotlib-1.1.1/lib/mpl_toolkits/axes_grid1/parasite_axes.py matplotlib-1.2.0/lib/mpl_toolkits/axes_grid1/parasite_axes.py --- matplotlib-1.1.1/lib/mpl_toolkits/axes_grid1/parasite_axes.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_toolkits/axes_grid1/parasite_axes.py 2012-10-31 00:11:14.000000000 +0000 @@ -56,13 +56,12 @@ new_class = _parasite_axes_classes.get(axes_class) if new_class is None: - import new def _get_base_axes_attr(self, attrname): return getattr(axes_class, attrname) - new_class = new.classobj("%sParasite" % (axes_class.__name__), - (ParasiteAxesBase, axes_class), - {'_get_base_axes_attr': _get_base_axes_attr}) + new_class = type("%sParasite" % (axes_class.__name__), + (ParasiteAxesBase, axes_class), + {'_get_base_axes_attr': _get_base_axes_attr}) _parasite_axes_classes[axes_class] = new_class return new_class @@ -211,11 +210,10 @@ new_class = _parasite_axes_auxtrans_classes.get(parasite_axes_class) if new_class is None: - import new - new_class = new.classobj("%sParasiteAuxTrans" % (parasite_axes_class.__name__), - (ParasiteAxesAuxTransBase, parasite_axes_class), - {'_parasite_axes_class': parasite_axes_class, - 'name': 'parasite_axes'}) + new_class = type("%sParasiteAuxTrans" % (parasite_axes_class.__name__), + (ParasiteAxesAuxTransBase, parasite_axes_class), + {'_parasite_axes_class': parasite_axes_class, + 'name': 'parasite_axes'}) _parasite_axes_auxtrans_classes[parasite_axes_class] = new_class return new_class @@ -326,14 +324,14 @@ # for normal axes self.axis["right"].toggle(all=False) - self.axis["right"].line.set_visible(False) + self.axis["right"].line.set_visible(True) ax2.axis["right"].set_visible(True) ax2.axis["left","top", "bottom"].toggle(all=False) ax2.axis["left","top", "bottom"].line.set_visible(False) ax2.axis["right"].toggle(all=True) - ax2.axis["right"].line.set_visible(True) + ax2.axis["right"].line.set_visible(False) return ax2 @@ -358,14 +356,14 @@ self.parasites.append(ax2) self.axis["top"].toggle(all=False) - self.axis["top"].line.set_visible(False) + self.axis["top"].line.set_visible(True) ax2.axis["top"].set_visible(True) ax2.axis["left","right", "bottom"].toggle(all=False) ax2.axis["left","right", "bottom"].line.set_visible(False) ax2.axis["top"].toggle(all=True) - ax2.axis["top"].line.set_visible(True) + ax2.axis["top"].line.set_visible(False) return ax2 @@ -456,18 +454,16 @@ new_class = _host_axes_classes.get(axes_class) if new_class is None: - import new - def _get_base_axes(self): return axes_class def _get_base_axes_attr(self, attrname): return getattr(axes_class, attrname) - new_class = new.classobj("%sHostAxes" % (axes_class.__name__), - (HostAxesBase, axes_class), - {'_get_base_axes_attr': _get_base_axes_attr, - '_get_base_axes': _get_base_axes}) + new_class = type("%sHostAxes" % (axes_class.__name__), + (HostAxesBase, axes_class), + {'_get_base_axes_attr': _get_base_axes_attr, + '_get_base_axes': _get_base_axes}) _host_axes_classes[axes_class] = new_class diff -Nru matplotlib-1.1.1/lib/mpl_toolkits/axisartist/angle_helper.py matplotlib-1.2.0/lib/mpl_toolkits/axisartist/angle_helper.py --- matplotlib-1.1.1/lib/mpl_toolkits/axisartist/angle_helper.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_toolkits/axisartist/angle_helper.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,3 +1,5 @@ +from __future__ import print_function + from math import floor import numpy as np @@ -433,38 +435,38 @@ #print select_step360(20.5+21.2/3600., 20.5+33.3/3600., 5) # test threshold factor - print select_step360(20.5+11.2/3600., 20.5+53.3/3600., 5, - threshold_factor=60) + print(select_step360(20.5+11.2/3600., 20.5+53.3/3600., 5, + threshold_factor=60)) - print select_step360(20.5+11.2/3600., 20.5+53.3/3600., 5, - threshold_factor=1) + print(select_step360(20.5+11.2/3600., 20.5+53.3/3600., 5, + threshold_factor=1)) fmt = FormatterDMS() #print fmt("left", 60, [0, -30, -60]) - print fmt("left", 600, [12301, 12302, 12303]) + print(fmt("left", 600, [12301, 12302, 12303])) - print select_step360(20.5+21.2/3600., 20.5+21.4/3600., 5) - print fmt("left", 36000, [738210, 738215, 738220]) - print fmt("left", 360000, [7382120, 7382125, 7382130]) - print fmt("left", 1., [45, 46, 47]) - print fmt("left", 10., [452, 453, 454]) + print(select_step360(20.5+21.2/3600., 20.5+21.4/3600., 5)) + print(fmt("left", 36000, [738210, 738215, 738220])) + print(fmt("left", 360000, [7382120, 7382125, 7382130])) + print(fmt("left", 1., [45, 46, 47])) + print(fmt("left", 10., [452, 453, 454])) if 0: - print select_step360(20+21.2/60., 21+33.3/60., 5) - print select_step360(20.5+21.2/3600., 20.5+33.3/3600., 5) - print select_step360(20+21.2/60., 20+53.3/60., 5) + print(select_step360(20+21.2/60., 21+33.3/60., 5)) + print(select_step360(20.5+21.2/3600., 20.5+33.3/3600., 5)) + print(select_step360(20+21.2/60., 20+53.3/60., 5)) ### levs, n, factor = select_step360(20.5+21.2/3600., 20.5+27.25/3600., 5) levs = levs * 0.1 fmt = FormatterDMS() #print fmt("left", 60, [0, -30, -60]) - print fmt("left", factor, levs) + print(fmt("left", factor, levs)) - print select_step(-180, 180, 10, hour=False) - print select_step(-12, 12, 10, hour=True) + print(select_step(-180, 180, 10, hour=False)) + print(select_step(-12, 12, 10, hour=True)) fmt = FormatterDMS() #print fmt("left", 60, [0, -30, -60]) - print fmt("left", 3600, [0, -30, -60]) + print(fmt("left", 3600, [0, -30, -60])) diff -Nru matplotlib-1.1.1/lib/mpl_toolkits/axisartist/axis_artist.py matplotlib-1.2.0/lib/mpl_toolkits/axisartist/axis_artist.py --- matplotlib-1.1.1/lib/mpl_toolkits/axisartist/axis_artist.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_toolkits/axisartist/axis_artist.py 2012-10-31 00:11:14.000000000 +0000 @@ -888,16 +888,28 @@ class GridlinesCollection(LineCollection): def __init__(self, *kl, **kwargs): + """ + *which* : "major" or "minor" + *axis* : "both", "x" or "y" + """ + self._which = kwargs.pop("which", "major") + self._axis = kwargs.pop("axis", "both") super(GridlinesCollection, self).__init__(*kl, **kwargs) self.set_grid_helper(None) + def set_which(self, which): + self._which = which + + def set_axis(self, axis): + self._axis = axis + def set_grid_helper(self, grid_helper): self._grid_helper = grid_helper def draw(self, renderer): if self._grid_helper is not None: self._grid_helper.update_lim(self.axes) - gl = self._grid_helper.get_gridlines() + gl = self._grid_helper.get_gridlines(self._which, self._axis) if gl: self.set_segments([np.transpose(l) for l in gl]) else: diff -Nru matplotlib-1.1.1/lib/mpl_toolkits/axisartist/axislines.py matplotlib-1.2.0/lib/mpl_toolkits/axisartist/axislines.py --- matplotlib-1.1.1/lib/mpl_toolkits/axisartist/axislines.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_toolkits/axisartist/axislines.py 2012-10-31 00:11:14.000000000 +0000 @@ -217,7 +217,6 @@ return trans_tick - class Floating(_Base): def __init__(self, nth_coord, value): @@ -438,9 +437,36 @@ return not self._force_update - def get_gridlines(self): + def get_gridlines(self, which, axis): + """ + Return list of grid lines as a list of paths (list of points). + + *which* : "major" or "minor" + *axis* : "both", "x" or "y" + """ return [] + def new_gridlines(self, ax): + """ + Create and return a new GridlineCollection instance. + + *which* : "major" or "minor" + *axis* : "both", "x" or "y" + + """ + gridlines = GridlinesCollection(None, transform=ax.transData, + colors=rcParams['grid.color'], + linestyles=rcParams['grid.linestyle'], + linewidths=rcParams['grid.linewidth']) + ax._set_artist_props(gridlines) + gridlines.set_grid_helper(self) + + ax.axes._set_artist_props(gridlines) + # gridlines.set_clip_path(self.axes.patch) + # set_clip_path need to be deferred after Axes.cla is completed. + # It is done inside the cla. + + return gridlines class GridHelperRectlinear(GridHelperBase): @@ -497,33 +523,43 @@ return axisline - def get_gridlines(self): + def get_gridlines(self, which="major", axis="both"): """ return list of gridline coordinates in data coordinates. + + *which* : "major" or "minor" + *axis* : "both", "x" or "y" """ gridlines = [] - locs = [] - y1, y2 = self.axes.get_ylim() - if self.axes.xaxis._gridOnMajor: - locs.extend(self.axes.xaxis.major.locator()) - if self.axes.xaxis._gridOnMinor: - locs.extend(self.axes.xaxis.minor.locator()) - - for x in locs: - gridlines.append([[x, x], [y1, y2]]) - - - x1, x2 = self.axes.get_xlim() - locs = [] - if self.axes.yaxis._gridOnMajor: - locs.extend(self.axes.yaxis.major.locator()) - if self.axes.yaxis._gridOnMinor: - locs.extend(self.axes.yaxis.minor.locator()) - for y in locs: - gridlines.append([[x1, x2], [y, y]]) + if axis in ["both", "x"]: + locs = [] + y1, y2 = self.axes.get_ylim() + #if self.axes.xaxis._gridOnMajor: + if which in ["both", "major"]: + locs.extend(self.axes.xaxis.major.locator()) + #if self.axes.xaxis._gridOnMinor: + if which in ["both", "minor"]: + locs.extend(self.axes.xaxis.minor.locator()) + + for x in locs: + gridlines.append([[x, x], [y1, y2]]) + + + if axis in ["both", "y"]: + x1, x2 = self.axes.get_xlim() + locs = [] + if self.axes.yaxis._gridOnMajor: + #if which in ["both", "major"]: + locs.extend(self.axes.yaxis.major.locator()) + if self.axes.yaxis._gridOnMinor: + #if which in ["both", "minor"]: + locs.extend(self.axes.yaxis.minor.locator()) + + for y in locs: + gridlines.append([[x1, x2], [y, y]]) return gridlines @@ -627,20 +663,25 @@ axis = property(_get_axislines) - def _init_gridlines(self, grid_helper=None): - gridlines = GridlinesCollection(None, transform=self.transData, - colors=rcParams['grid.color'], - linestyles=rcParams['grid.linestyle'], - linewidths=rcParams['grid.linewidth']) - self._set_artist_props(gridlines) + def new_gridlines(self, grid_helper=None): + """ + Create and return a new GridlineCollection instance. + + *which* : "major" or "minor" + *axis* : "both", "x" or "y" + + """ if grid_helper is None: grid_helper = self.get_grid_helper() - gridlines.set_grid_helper(grid_helper) - self.axes._set_artist_props(gridlines) - # gridlines.set_clip_path(self.axes.patch) - # set_clip_path need to be deferred after Axes.cla is completed. + gridlines = grid_helper.new_gridlines(self) + + return gridlines + + + def _init_gridlines(self, grid_helper=None): # It is done inside the cla. + gridlines = self.new_gridlines(grid_helper) self.gridlines = gridlines @@ -668,7 +709,7 @@ # axes_grid and the original mpl's grid, because axes_grid # explicitly set the visibility of the gridlines. - super(Axes, self).grid(b, **kwargs) + super(Axes, self).grid(b, which=which, axis=axis, **kwargs) if not self._axisline_on: return @@ -680,6 +721,8 @@ else: b=False + self.gridlines.set_which(which) + self.gridlines.set_axis(axis) self.gridlines.set_visible(b) if len(kwargs): @@ -767,38 +810,6 @@ return _bbox - def set_xlim(self, left=None, right=None, emit=True, auto=False, - swap_axis=True, **kw): - - x1o, x2o = self.get_xlim() - - maxes.Axes.set_xlim(self, left, right, emit, auto, **kw) - x1, x2 = self.get_xlim() - - if not swap_axis: - return - - if (x1o > x2o and x1 < x2) or (x1o < x2o and x1 > x2): - self.axis["right"], self.axis["left"] = self.axis["left"], self.axis["right"] - - self.axis["left"].set_axis_direction("left") - self.axis["right"].set_axis_direction("right") - - - def set_ylim(self, bottom=None, top=None, emit=True, auto=False, - swap_axis=True, **kw): - - y1o, y2o = self.get_ylim() - - maxes.Axes.set_ylim(self, bottom, top, emit, auto, **kw) - y1, y2 = self.get_ylim() - - if y1o > y2o and y1 < y2 or (y1o < y2o and y1 > y2): - self.axis["top"], self.axis["bottom"] = self.axis["bottom"], self.axis["top"] - - self.axis["top"].set_axis_direction("top") - self.axis["bottom"].set_axis_direction("bottom") - Subplot = maxes.subplot_class_factory(Axes) diff -Nru matplotlib-1.1.1/lib/mpl_toolkits/axisartist/clip_path.py matplotlib-1.2.0/lib/mpl_toolkits/axisartist/clip_path.py --- matplotlib-1.1.1/lib/mpl_toolkits/axisartist/clip_path.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_toolkits/axisartist/clip_path.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,10 +1,11 @@ import numpy as np from math import degrees import math +import warnings def atan2(dy, dx): if dx == 0 and dx == 0: - print "warning" + warnings.warn("dx and dy is 0") return 0 else: return math.atan2(dy, dx) @@ -28,7 +29,7 @@ ysign = 1 else: ysign = -1 - + for x, y in zip(xlines, ylines): @@ -95,7 +96,7 @@ xdir = x1 > x0 ydir = y1 > y0 - + if x1 > x0: lx1, ly1, c_right_ = clip([xline], [yline], x1, clip="right", xdir=xdir, ydir=ydir) lx2, ly2, c_left_ = clip(lx1, ly1, x0, clip="left", xdir=xdir, ydir=ydir) @@ -110,7 +111,7 @@ ly3, lx3, c_top_ = clip(ly2, lx2, y0, clip="right", xdir=ydir, ydir=xdir) ly4, lx4, c_bottom_ = clip(ly3, lx3, y1, clip="left", xdir=ydir, ydir=xdir) - + # lx1, ly1, c_right_ = clip([xline], [yline], x1, clip="right") # lx2, ly2, c_left_ = clip(lx1, ly1, x0, clip="left") # ly3, lx3, c_top_ = clip(ly2, lx2, y1, clip="right") diff -Nru matplotlib-1.1.1/lib/mpl_toolkits/axisartist/floating_axes.py matplotlib-1.2.0/lib/mpl_toolkits/axisartist/floating_axes.py --- matplotlib-1.1.1/lib/mpl_toolkits/axisartist/floating_axes.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_toolkits/axisartist/floating_axes.py 2012-10-31 00:11:14.000000000 +0000 @@ -407,12 +407,14 @@ - def get_gridlines(self): + def get_gridlines(self, which="major", axis="both"): grid_lines = [] - for gl in self.grid_info["lat_lines"]: - grid_lines.extend([gl]) - for gl in self.grid_info["lon_lines"]: - grid_lines.extend([gl]) + if axis in ["both", "x"]: + for gl in self.grid_info["lon_lines"]: + grid_lines.extend([gl]) + if axis in ["both", "y"]: + for gl in self.grid_info["lat_lines"]: + grid_lines.extend([gl]) return grid_lines @@ -518,17 +520,15 @@ -import new - _floatingaxes_classes = {} def floatingaxes_class_factory(axes_class): new_class = _floatingaxes_classes.get(axes_class) if new_class is None: - new_class = new.classobj("Floating %s" % (axes_class.__name__), - (FloatingAxesBase, axes_class), - {'_axes_class_floating': axes_class}) + new_class = type("Floating %s" % (axes_class.__name__), + (FloatingAxesBase, axes_class), + {'_axes_class_floating': axes_class}) _floatingaxes_classes[axes_class] = new_class return new_class diff -Nru matplotlib-1.1.1/lib/mpl_toolkits/axisartist/grid_finder.py matplotlib-1.2.0/lib/mpl_toolkits/axisartist/grid_finder.py --- matplotlib-1.1.1/lib/mpl_toolkits/axisartist/grid_finder.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_toolkits/axisartist/grid_finder.py 2012-10-31 00:11:14.000000000 +0000 @@ -1,3 +1,5 @@ +from __future__ import print_function + import numpy as np import matplotlib.cbook as mcbook from matplotlib.transforms import Bbox @@ -7,7 +9,6 @@ import matplotlib.ticker as mticker from matplotlib.transforms import Transform - # extremes finder class ExtremeFinderSimple(object): @@ -345,4 +346,4 @@ fmt = FormatterPrettyPrint() - print fmt("left", None, locs) + print(fmt("left", None, locs)) diff -Nru matplotlib-1.1.1/lib/mpl_toolkits/axisartist/grid_helper_curvelinear.py matplotlib-1.2.0/lib/mpl_toolkits/axisartist/grid_helper_curvelinear.py --- matplotlib-1.1.1/lib/mpl_toolkits/axisartist/grid_helper_curvelinear.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_toolkits/axisartist/grid_helper_curvelinear.py 2012-10-31 00:11:14.000000000 +0000 @@ -34,10 +34,22 @@ self.nth_coord_ticks = nth_coord_ticks self.side = side + self._limits_inverted = False def update_lim(self, axes): self.grid_helper.update_lim(axes) + if self.nth_coord == 0: + xy1, xy2 = axes.get_ylim() + else: + xy1, xy2 = axes.get_xlim() + + if xy1 > xy2: + self._limits_inverted = True + else: + self._limits_inverted = False + + def change_tick_coord(self, coord_number=None): if coord_number is None: self.nth_coord_ticks = 1 - self.nth_coord_ticks @@ -55,14 +67,21 @@ g = self.grid_helper - ti1 = g.get_tick_iterator(self.nth_coord_ticks, self.side) - ti2 = g.get_tick_iterator(1-self.nth_coord_ticks, self.side, minor=True) + if self._limits_inverted: + side = {"left":"right","right":"left", + "top":"bottom", "bottom":"top"}[self.side] + else: + side = self.side + + ti1 = g.get_tick_iterator(self.nth_coord_ticks, side) + ti2 = g.get_tick_iterator(1-self.nth_coord_ticks, side, minor=True) #ti2 = g.get_tick_iterator(1-self.nth_coord_ticks, self.side, minor=True) return chain(ti1, ti2), iter([]) + class FloatingAxisArtistHelper(AxisArtistHelper.Floating): def __init__(self, grid_helper, nth_coord, value, axis_direction=None): @@ -201,7 +220,10 @@ xx0 = lon_levs dx = 0.01 - e0, e1 = sorted(self._extremes) + if None in self._extremes: + e0, e1 = self._extremes + else: + e0, e1 = sorted(self._extremes) if e0 is None: e0 = -np.inf if e1 is None: @@ -413,12 +435,15 @@ self.grid_info = self.grid_finder.get_grid_info(x1, y1, x2, y2) - def get_gridlines(self): + def get_gridlines(self, which="major", axis="both"): grid_lines = [] - for gl in self.grid_info["lat"]["lines"]: - grid_lines.extend(gl) - for gl in self.grid_info["lon"]["lines"]: - grid_lines.extend(gl) + + if axis in ["both", "x"]: + for gl in self.grid_info["lon"]["lines"]: + grid_lines.extend(gl) + if axis in ["both", "y"]: + for gl in self.grid_info["lat"]["lines"]: + grid_lines.extend(gl) return grid_lines diff -Nru matplotlib-1.1.1/lib/mpl_toolkits/mplot3d/art3d.py matplotlib-1.2.0/lib/mpl_toolkits/mplot3d/art3d.py --- matplotlib-1.1.1/lib/mpl_toolkits/mplot3d/art3d.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_toolkits/mplot3d/art3d.py 2012-10-31 00:11:14.000000000 +0000 @@ -459,7 +459,7 @@ if self._zsort: z_segments_2d = [(self._zsortfunc(zs), zip(xs, ys), fc, ec) for (xs, ys, zs), fc, ec in zip(xyzlist, cface, cedge)] - z_segments_2d.sort(cmp=lambda x, y: cmp(y[0], x[0])) + z_segments_2d.sort(key=lambda x: x[0], reverse=True) else: raise ValueError, "whoops" diff -Nru matplotlib-1.1.1/lib/mpl_toolkits/mplot3d/axes3d.py matplotlib-1.2.0/lib/mpl_toolkits/mplot3d/axes3d.py --- matplotlib-1.1.1/lib/mpl_toolkits/mplot3d/axes3d.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/mpl_toolkits/mplot3d/axes3d.py 2012-11-08 13:38:03.000000000 +0000 @@ -19,6 +19,7 @@ import matplotlib.collections as mcoll from matplotlib import docstring import matplotlib.scale as mscale +from matplotlib.tri.triangulation import Triangulation import numpy as np from matplotlib.colors import Normalize, colorConverter, LightSource @@ -1351,15 +1352,9 @@ had_data = self.has_data() Z = np.atleast_2d(Z) - rows, cols = Z.shape # TODO: Support masked arrays - X = np.asarray(X) - Y = np.asarray(Y) - # Force X and Y to take the same shape. - # If they can not be fitted to that shape, - # then an exception is automatically thrown. - X.shape = (rows, cols) - Y.shape = (rows, cols) + X, Y, Z = np.broadcast_arrays(X, Y, Z) + rows, cols = Z.shape rstride = kwargs.pop('rstride', 10) cstride = kwargs.pop('cstride', 10) @@ -1525,14 +1520,8 @@ had_data = self.has_data() Z = np.atleast_2d(Z) # FIXME: Support masked arrays - X = np.asarray(X) - Y = np.asarray(Y) + X, Y, Z = np.broadcast_arrays(X, Y, Z) rows, cols = Z.shape - # Force X and Y to take the same shape. - # If they can not be fitted to that shape, - # then an exception is automatically thrown. - X.shape = (rows, cols) - Y.shape = (rows, cols) # We want two sets of lines, one running along the "rows" of # Z and another set of lines running along the "columns" of Z. @@ -1573,6 +1562,97 @@ return linec + def plot_trisurf(self, X, Y, Z, *args, **kwargs): + """ + ============= ================================================ + Argument Description + ============= ================================================ + *X*, *Y*, *Z* Data values as 1D arrays + *color* Color of the surface patches + *cmap* A colormap for the surface patches. + *norm* An instance of Normalize to map values to colors + *vmin* Minimum value to map + *vmax* Maximum value to map + *shade* Whether to shade the facecolors + ============= ================================================ + + Other arguments are passed on to + :class:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection` + + .. versionadded:: 1.2.0 + This plotting function was added for the v1.2.0 release. + """ + + had_data = self.has_data() + + # TODO: Support custom face colours + color = np.array(colorConverter.to_rgba(kwargs.pop('color', 'b'))) + + cmap = kwargs.get('cmap', None) + norm = kwargs.pop('norm', None) + vmin = kwargs.pop('vmin', None) + vmax = kwargs.pop('vmax', None) + linewidth = kwargs.get('linewidth', None) + shade = kwargs.pop('shade', cmap is None) + lightsource = kwargs.pop('lightsource', None) + + # TODO: Support masked triangulations + tri = Triangulation(X, Y) + x = tri.x + y = tri.y + triangles = tri.triangles + + xt = x[triangles][...,np.newaxis] + yt = y[triangles][...,np.newaxis] + zt = np.array(Z)[triangles][...,np.newaxis] + + verts = np.concatenate((xt, yt, zt), axis=2) + + # Only need these vectors to shade if there is no cmap + if cmap is None and shade: + totpts = len(verts) + v1 = np.empty((totpts, 3)) + v2 = np.empty((totpts, 3)) + # This indexes the vertex points + which_pt = 0 + + colset = [] + for i in xrange(len(verts)): + avgzsum = verts[i,0,2] + verts[i,1,2] + verts[i,2,2] + colset.append(avgzsum / 3.0) + + # Only need vectors to shade if no cmap + if cmap is None and shade: + v1[which_pt] = np.array(verts[i,0]) - np.array(verts[i,1]) + v2[which_pt] = np.array(verts[i,1]) - np.array(verts[i,2]) + which_pt += 1 + + if cmap is None and shade: + normals = np.cross(v1, v2) + else: + normals = [] + + polyc = art3d.Poly3DCollection(verts, *args, **kwargs) + + if cmap: + colset = np.array(colset) + polyc.set_array(colset) + if vmin is not None or vmax is not None: + polyc.set_clim(vmin, vmax) + if norm is not None: + polyc.set_norm(norm) + else: + if shade: + colset = self._shade_colors(color, normals) + else: + colset = color + polyc.set_facecolors(colset) + + self.add_collection(polyc) + self.auto_scale_xyz(X, Y, Z, had_data) + + return polyc + def _3d_extend_contour(self, cset, stride=5): ''' Extend a contour in 3D by creating @@ -1856,9 +1936,13 @@ ys = np.ma.ravel(ys) zs = np.ma.ravel(zs) if xs.size != ys.size: - raise ValueError("x and y must be the same size") - if xs.size != zs.size and zs.size == 1: - zs = np.array(zs[0] * xs.size) + raise ValueError("Arguments 'xs' and 'ys' must be of same size.") + if xs.size != zs.size: + if zs.size == 1: + zs = np.tile(zs[0], xs.size) + else: + raise ValueError(("Argument 'zs' must be of same size as 'xs' " + "and 'ys' or of size 1.")) s = np.ma.ravel(s) # This doesn't have to match x, y in size. diff -Nru matplotlib-1.1.1/lib/pytz/README.txt matplotlib-1.2.0/lib/pytz/README.txt --- matplotlib-1.1.1/lib/pytz/README.txt 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/pytz/README.txt 2012-11-06 22:31:09.000000000 +0000 @@ -176,9 +176,8 @@ >>> normal = datetime(2009, 9, 1) >>> ambiguous = datetime(2009, 10, 31, 23, 30) -the ``is_dst`` parameter is ignormed for most timestamps, but -is used to resolve the ambiguity during ambiguous periods caused -to DST transitions. +The ``is_dst`` parameter is ignored for most timestamps. It is only used +during DST transition ambiguous periods to resulve that ambiguity. >>> tz.utcoffset(normal, is_dst=True) datetime.timedelta(-1, 77400) diff -Nru matplotlib-1.1.1/lib/pytz/__init__.py matplotlib-1.2.0/lib/pytz/__init__.py --- matplotlib-1.1.1/lib/pytz/__init__.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/pytz/__init__.py 2012-11-06 22:31:09.000000000 +0000 @@ -9,11 +9,11 @@ ''' # The Olson database is updated several times a year. -OLSON_VERSION = '2011c' +OLSON_VERSION = '2012d' VERSION = OLSON_VERSION # Version format for a patch release - only one so far. #VERSION = OLSON_VERSION + '.2' -__version__ = OLSON_VERSION +__version__ = OLSON_VERSION + "-mpl" OLSEN_VERSION = OLSON_VERSION # Old releases had this misspelling @@ -115,7 +115,7 @@ # module, as well as the Zope3 i18n package. Perhaps we should just provide # the POT file and translations, and leave it up to callers to make use # of them. -# +# # t = gettext.translation( # 'pytz', os.path.join(os.path.dirname(__file__), 'locales'), # fallback=True @@ -128,7 +128,7 @@ _tzinfo_cache = {} def timezone(zone): - r''' Return a datetime.tzinfo implementation for the given timezone + r''' Return a datetime.tzinfo implementation for the given timezone >>> from datetime import datetime, timedelta >>> utc = timezone('UTC') @@ -199,12 +199,8 @@ class UTC(datetime.tzinfo): """UTC - Identical to the reference UTC implementation given in Python docs except - that it unpickles using the single module global instance defined beneath - this class declaration. - - Also contains extra attributes and methods to match other pytz tzinfo - instances. + Optimized UTC implementation. It unpickles using the single module global + instance defined beneath this class declaration. """ zone = "UTC" @@ -212,6 +208,11 @@ _dst = ZERO _tzname = zone + def fromutc(self, dt): + if dt.tzinfo is None: + return self.localize(dt) + return super(utc.__class__, self).fromutc(dt) + def utcoffset(self, dt): return ZERO @@ -232,9 +233,11 @@ def normalize(self, dt, is_dst=False): '''Correct the timezone information on the given datetime''' + if dt.tzinfo is self: + return dt if dt.tzinfo is None: raise ValueError('Naive time - no tzinfo set') - return dt.replace(tzinfo=self) + return dt.astimezone(self) def __repr__(self): return "" @@ -249,7 +252,7 @@ def _UTC(): """Factory function for utc unpickling. - Makes sure that unpickling a utc instance always returns the same + Makes sure that unpickling a utc instance always returns the same module global. These examples belong in the UTC class above, but it is obscured; or in @@ -544,6 +547,7 @@ 'Africa/Gaborone', 'Africa/Harare', 'Africa/Johannesburg', + 'Africa/Juba', 'Africa/Kampala', 'Africa/Khartoum', 'Africa/Kigali', @@ -615,6 +619,7 @@ 'America/Coral_Harbour', 'America/Cordoba', 'America/Costa_Rica', + 'America/Creston', 'America/Cuiaba', 'America/Curacao', 'America/Danmarkshavn', @@ -658,10 +663,12 @@ 'America/Kentucky/Louisville', 'America/Kentucky/Monticello', 'America/Knox_IN', + 'America/Kralendijk', 'America/La_Paz', 'America/Lima', 'America/Los_Angeles', 'America/Louisville', + 'America/Lower_Princes', 'America/Maceio', 'America/Managua', 'America/Manaus', @@ -772,6 +779,7 @@ 'Asia/Dushanbe', 'Asia/Gaza', 'Asia/Harbin', + 'Asia/Hebron', 'Asia/Ho_Chi_Minh', 'Asia/Hong_Kong', 'Asia/Hovd', @@ -1090,7 +1098,7 @@ 'Zulu'] all_timezones = [ tz for tz in all_timezones if resource_exists(tz)] - + all_timezones_set = set(all_timezones) common_timezones = \ ['Africa/Abidjan', @@ -1118,6 +1126,7 @@ 'Africa/Gaborone', 'Africa/Harare', 'Africa/Johannesburg', + 'Africa/Juba', 'Africa/Kampala', 'Africa/Khartoum', 'Africa/Kigali', @@ -1182,6 +1191,7 @@ 'America/Chicago', 'America/Chihuahua', 'America/Costa_Rica', + 'America/Creston', 'America/Cuiaba', 'America/Curacao', 'America/Danmarkshavn', @@ -1220,9 +1230,11 @@ 'America/Juneau', 'America/Kentucky/Louisville', 'America/Kentucky/Monticello', + 'America/Kralendijk', 'America/La_Paz', 'America/Lima', 'America/Los_Angeles', + 'America/Lower_Princes', 'America/Maceio', 'America/Managua', 'America/Manaus', @@ -1325,6 +1337,7 @@ 'Asia/Dushanbe', 'Asia/Gaza', 'Asia/Harbin', + 'Asia/Hebron', 'Asia/Ho_Chi_Minh', 'Asia/Hong_Kong', 'Asia/Hovd', @@ -1520,5 +1533,5 @@ 'UTC'] common_timezones = [ tz for tz in common_timezones if tz in all_timezones] - + common_timezones_set = set(common_timezones) diff -Nru matplotlib-1.1.1/lib/pytz/tests/test_tzinfo.py matplotlib-1.2.0/lib/pytz/tests/test_tzinfo.py --- matplotlib-1.1.1/lib/pytz/tests/test_tzinfo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/pytz/tests/test_tzinfo.py 2012-11-06 22:31:09.000000000 +0000 @@ -17,11 +17,11 @@ import pytz from pytz import reference from pytz.tzfile import _byte_string -from pytz.tzinfo import StaticTzInfo +from pytz.tzinfo import DstTzInfo, StaticTzInfo # I test for expected version to ensure the correct version of pytz is # actually being tested. -EXPECTED_VERSION='2011c' +EXPECTED_VERSION='2012d' fmt = '%Y-%m-%d %H:%M:%S %Z%z' @@ -533,6 +533,24 @@ } +class SamoaInternationalDateLineChange(USEasternDSTStartTestCase): + # At the end of 2011, Samoa will switch from being east of the + # international dateline to the west. There will be no Dec 30th + # 2011 and it will switch from UTC-10 to UTC+14. + tzinfo = pytz.timezone('Pacific/Apia') + transition_time = datetime(2011, 12, 30, 10, 0, 0, tzinfo=UTC) + before = { + 'tzname': 'WSDT', + 'utcoffset': timedelta(hours=-10), + 'dst': timedelta(hours=1), + } + after = { + 'tzname': 'WSDT', + 'utcoffset': timedelta(hours=14), + 'dst': timedelta(hours=1), + } + + class ReferenceUSEasternDSTStartTestCase(USEasternDSTStartTestCase): tzinfo = reference.Eastern def test_arithmetic(self): @@ -701,6 +719,85 @@ self.assertFalse('Europe/Belfast' in pytz.common_timezones_set) +class BaseTzInfoTestCase: + '''Ensure UTC, StaticTzInfo and DstTzInfo work consistently. + + These tests are run for each type of tzinfo. + ''' + tz = None # override + tz_class = None # override + + def test_expectedclass(self): + self.assertTrue(isinstance(self.tz, self.tz_class)) + + def test_fromutc(self): + # naive datetime. + dt1 = datetime(2011, 10, 31) + + # localized datetime, same timezone. + dt2 = self.tz.localize(dt1) + + # Both should give the same results. Note that the standard + # Python tzinfo.fromutc() only supports the second. + for dt in [dt1, dt2]: + loc_dt = self.tz.fromutc(dt) + loc_dt2 = pytz.utc.localize(dt1).astimezone(self.tz) + self.assertEqual(loc_dt, loc_dt2) + + # localized datetime, different timezone. + new_tz = pytz.timezone('Europe/Paris') + self.assertTrue(self.tz is not new_tz) + dt3 = new_tz.localize(dt1) + self.assertRaises(ValueError, self.tz.fromutc, dt3) + + def test_normalize(self): + other_tz = pytz.timezone('Europe/Paris') + self.assertTrue(self.tz is not other_tz) + + dt = datetime(2012, 3, 26, 12, 0) + other_dt = other_tz.localize(dt) + + local_dt = self.tz.normalize(other_dt) + + self.assertTrue(local_dt.tzinfo is not other_dt.tzinfo) + self.assertNotEqual( + local_dt.replace(tzinfo=None), other_dt.replace(tzinfo=None)) + + def test_astimezone(self): + other_tz = pytz.timezone('Europe/Paris') + self.assertTrue(self.tz is not other_tz) + + dt = datetime(2012, 3, 26, 12, 0) + other_dt = other_tz.localize(dt) + + local_dt = other_dt.astimezone(self.tz) + + self.assertTrue(local_dt.tzinfo is not other_dt.tzinfo) + self.assertNotEqual( + local_dt.replace(tzinfo=None), other_dt.replace(tzinfo=None)) + + +class OptimizedUTCTestCase(unittest.TestCase, BaseTzInfoTestCase): + tz = pytz.utc + tz_class = tz.__class__ + + +class LegacyUTCTestCase(unittest.TestCase, BaseTzInfoTestCase): + # Deprecated timezone, but useful for comparison tests. + tz = pytz.timezone('Etc/UTC') + tz_class = StaticTzInfo + + +class StaticTzInfoTestCase(unittest.TestCase, BaseTzInfoTestCase): + tz = pytz.timezone('GMT') + tz_class = StaticTzInfo + + +class DstTzInfoTestCase(unittest.TestCase, BaseTzInfoTestCase): + tz = pytz.timezone('Australia/Melbourne') + tz_class = DstTzInfo + + def test_suite(): suite = unittest.TestSuite() suite.addTest(doctest.DocTestSuite('pytz')) diff -Nru matplotlib-1.1.1/lib/pytz/tzfile.py matplotlib-1.2.0/lib/pytz/tzfile.py --- matplotlib-1.1.1/lib/pytz/tzfile.py 2012-06-30 18:47:51.000000000 +0000 +++ matplotlib-1.2.0/lib/pytz/tzfile.py 2012-11-06 22:31:09.000000000 +0000 @@ -97,7 +97,9 @@ break dst = inf[0] - prev_inf[0] # dst offset - if dst <= 0: # Bad dst? Look further. + # Bad dst? Look further. DST > 24 hours happens when + # a timzone has moved across the international dateline. + if dst <= 0 or dst > 3600*3: for j in range(i+1, len(transitions)): stdinf = ttinfo[lindexes[j]] if not stdinf[1]: diff -Nru matplotlib-1.1.1/lib/pytz/tzinfo.py matplotlib-1.2.0/lib/pytz/tzinfo.py --- matplotlib-1.1.1/lib/pytz/tzinfo.py 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/pytz/tzinfo.py 2012-11-06 22:31:09.000000000 +0000 @@ -74,6 +74,8 @@ ''' def fromutc(self, dt): '''See datetime.tzinfo.fromutc''' + if dt.tzinfo is not None and dt.tzinfo is not self: + raise ValueError('fromutc: dt.tzinfo is not self') return (dt + self._utcoffset).replace(tzinfo=self) def utcoffset(self, dt, is_dst=None): @@ -107,10 +109,33 @@ return dt.replace(tzinfo=self) def normalize(self, dt, is_dst=False): - '''Correct the timezone information on the given datetime''' + '''Correct the timezone information on the given datetime. + + This is normally a no-op, as StaticTzInfo timezones never have + ambiguous cases to correct: + + >>> from pytz import timezone + >>> gmt = timezone('GMT') + >>> isinstance(gmt, StaticTzInfo) + True + >>> dt = datetime(2011, 5, 8, 1, 2, 3, tzinfo=gmt) + >>> gmt.normalize(dt) is dt + True + + The supported method of converting between timezones is to use + datetime.astimezone(). Currently normalize() also works: + + >>> la = timezone('America/Los_Angeles') + >>> dt = la.localize(datetime(2011, 5, 7, 1, 2, 3)) + >>> fmt = '%Y-%m-%d %H:%M:%S %Z (%z)' + >>> gmt.normalize(dt).strftime(fmt) + '2011-05-07 08:02:03 GMT (+0000)' + ''' + if dt.tzinfo is self: + return dt if dt.tzinfo is None: raise ValueError('Naive time - no tzinfo set') - return dt.replace(tzinfo=self) + return dt.astimezone(self) def __repr__(self): return '' % (self.zone,) @@ -153,6 +178,9 @@ def fromutc(self, dt): '''See datetime.tzinfo.fromutc''' + if (dt.tzinfo is not None + and getattr(dt.tzinfo, '_tzinfos', None) is not self._tzinfos): + raise ValueError('fromutc: dt.tzinfo is not self') dt = dt.replace(tzinfo=None) idx = max(0, bisect_right(self._utc_transition_times, dt) - 1) inf = self._transition_info[idx] @@ -192,6 +220,16 @@ >>> before = eastern.normalize(before) >>> before.strftime(fmt) '2002-10-27 01:50:00 EDT (-0400)' + + The supported method of converting between timezones is to use + datetime.astimezone(). Currently, normalize() also works: + + >>> th = timezone('Asia/Bangkok') + >>> am = timezone('Europe/Amsterdam') + >>> dt = th.localize(datetime(2011, 5, 7, 1, 2, 3)) + >>> fmt = '%Y-%m-%d %H:%M:%S %Z (%z)' + >>> am.normalize(dt).strftime(fmt) + '2011-05-06 20:02:03 CEST (+0200)' ''' if dt.tzinfo is None: raise ValueError('Naive time - no tzinfo set') Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Africa/Cairo and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Africa/Cairo differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Africa/Casablanca and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Africa/Casablanca differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Africa/Dar_es_Salaam and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Africa/Dar_es_Salaam differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Africa/Juba and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Africa/Juba differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Africa/Kampala and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Africa/Kampala differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Africa/Nairobi and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Africa/Nairobi differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Atikokan and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Atikokan differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Bahia and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Bahia differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Blanc-Sablon and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Blanc-Sablon differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Coral_Harbour and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Coral_Harbour differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Creston and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Creston differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Dawson_Creek and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Dawson_Creek differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Edmonton and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Edmonton differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Glace_Bay and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Glace_Bay differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Goose_Bay and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Goose_Bay differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Halifax and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Halifax differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Havana and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Havana differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Kralendijk and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Kralendijk differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Lower_Princes and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Lower_Princes differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Metlakatla and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Metlakatla differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Moncton and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Moncton differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Montreal and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Montreal differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Nipigon and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Nipigon differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Port-au-Prince and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Port-au-Prince differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Rainy_River and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Rainy_River differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Regina and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Regina differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Resolute and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Resolute differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Santiago and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Santiago differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Sitka and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Sitka differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/St_Johns and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/St_Johns differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Swift_Current and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Swift_Current differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Toronto and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Toronto differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Vancouver and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Vancouver differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/America/Winnipeg and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/America/Winnipeg differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Antarctica/Casey and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Antarctica/Casey differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Antarctica/Davis and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Antarctica/Davis differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Antarctica/Palmer and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Antarctica/Palmer differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Asia/Anadyr and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Asia/Anadyr differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Asia/Damascus and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Asia/Damascus differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Asia/Gaza and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Asia/Gaza differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Asia/Hebron and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Asia/Hebron differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Asia/Irkutsk and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Asia/Irkutsk differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Asia/Istanbul and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Asia/Istanbul differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Asia/Kamchatka and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Asia/Kamchatka differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Asia/Krasnoyarsk and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Asia/Krasnoyarsk differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Asia/Magadan and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Asia/Magadan differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Asia/Novokuznetsk and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Asia/Novokuznetsk differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Asia/Novosibirsk and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Asia/Novosibirsk differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Asia/Omsk and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Asia/Omsk differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Asia/Sakhalin and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Asia/Sakhalin differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Asia/Vladivostok and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Asia/Vladivostok differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Asia/Yakutsk and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Asia/Yakutsk differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Asia/Yekaterinburg and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Asia/Yekaterinburg differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Asia/Yerevan and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Asia/Yerevan differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Atlantic/Stanley and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Atlantic/Stanley differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Canada/Atlantic and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Canada/Atlantic differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Canada/Central and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Canada/Central differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Canada/East-Saskatchewan and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Canada/East-Saskatchewan differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Canada/Eastern and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Canada/Eastern differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Canada/Mountain and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Canada/Mountain differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Canada/Newfoundland and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Canada/Newfoundland differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Canada/Pacific and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Canada/Pacific differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Canada/Saskatchewan and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Canada/Saskatchewan differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Chile/Continental and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Chile/Continental differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Chile/EasterIsland and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Chile/EasterIsland differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Cuba and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Cuba differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Egypt and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Egypt differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Europe/Istanbul and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Europe/Istanbul differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Europe/Kaliningrad and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Europe/Kaliningrad differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Europe/Minsk and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Europe/Minsk differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Europe/Moscow and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Europe/Moscow differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Europe/Samara and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Europe/Samara differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Europe/Volgograd and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Europe/Volgograd differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Pacific/Apia and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Pacific/Apia differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Pacific/Easter and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Pacific/Easter differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Pacific/Fakaofo and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Pacific/Fakaofo differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Pacific/Fiji and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Pacific/Fiji differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/Turkey and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/Turkey differ Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/lib/pytz/zoneinfo/W-SU and /tmp/dj4q_yDaTz/matplotlib-1.2.0/lib/pytz/zoneinfo/W-SU differ diff -Nru matplotlib-1.1.1/lib/pytz/zoneinfo/iso3166.tab matplotlib-1.2.0/lib/pytz/zoneinfo/iso3166.tab --- matplotlib-1.1.1/lib/pytz/zoneinfo/iso3166.tab 2012-06-30 19:37:00.000000000 +0000 +++ matplotlib-1.2.0/lib/pytz/zoneinfo/iso3166.tab 2012-11-06 22:31:09.000000000 +0000 @@ -1,5 +1,4 @@ #
    -# @(#)iso3166.tab	8.6
     # This file is in the public domain, so clarified as of
     # 2009-05-17 by Arthur David Olson.
     # ISO 3166 alpha-2 country codes
    @@ -21,6 +20,9 @@
     #
     # Lines beginning with `#' are comments.
     #
    +# From Arthur David Olson (2011-08-17):
    +# Resynchronized today with the ISO 3166 site (adding SS for South Sudan).
    +#
     #country-
     #code	country name
     AD	Andorra
    @@ -30,7 +32,6 @@
     AI	Anguilla
     AL	Albania
     AM	Armenia
    -AN	Netherlands Antilles
     AO	Angola
     AQ	Antarctica
     AR	Argentina
    @@ -53,6 +54,7 @@
     BM	Bermuda
     BN	Brunei
     BO	Bolivia
    +BQ	Bonaire Sint Eustatius & Saba
     BR	Brazil
     BS	Bahamas
     BT	Bhutan
    @@ -75,6 +77,7 @@
     CR	Costa Rica
     CU	Cuba
     CV	Cape Verde
    +CW	Curacao
     CX	Christmas Island
     CY	Cyprus
     CZ	Czech Republic
    @@ -229,8 +232,10 @@
     SN	Senegal
     SO	Somalia
     SR	Suriname
    +SS	South Sudan
     ST	Sao Tome & Principe
     SV	El Salvador
    +SX	Sint Maarten
     SY	Syria
     SZ	Swaziland
     TC	Turks & Caicos Is
    diff -Nru matplotlib-1.1.1/lib/pytz/zoneinfo/zone.tab matplotlib-1.2.0/lib/pytz/zoneinfo/zone.tab
    --- matplotlib-1.1.1/lib/pytz/zoneinfo/zone.tab	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/lib/pytz/zoneinfo/zone.tab	2012-11-06 22:31:09.000000000 +0000
    @@ -1,5 +1,4 @@
     # 
    -# @(#)zone.tab	8.41
     # This file is in the public domain, so clarified as of
     # 2009-05-17 by Arthur David Olson.
     #
    @@ -32,7 +31,6 @@
     AI	+1812-06304	America/Anguilla
     AL	+4120+01950	Europe/Tirane
     AM	+4011+04430	Asia/Yerevan
    -AN	+1211-06900	America/Curacao
     AO	-0848+01314	Africa/Luanda
     AQ	-7750+16636	Antarctica/McMurdo	McMurdo Station, Ross Island
     AQ	-9000+00000	Antarctica/South_Pole	Amundsen-Scott Station, South Pole
    @@ -87,6 +85,7 @@
     BM	+3217-06446	Atlantic/Bermuda
     BN	+0456+11455	Asia/Brunei
     BO	-1630-06809	America/La_Paz
    +BQ	+120903-0681636	America/Kralendijk
     BR	-0351-03225	America/Noronha	Atlantic islands
     BR	-0127-04829	America/Belem	Amapa, E Para
     BR	-0343-03830	America/Fortaleza	NE Brazil (MA, PI, CE, RN, PB)
    @@ -120,7 +119,7 @@
     CA	+4823-08915	America/Thunder_Bay	Eastern Time - Thunder Bay, Ontario
     CA	+6344-06828	America/Iqaluit	Eastern Time - east Nunavut - most locations
     CA	+6608-06544	America/Pangnirtung	Eastern Time - Pangnirtung, Nunavut
    -CA	+744144-0944945	America/Resolute	Eastern Standard Time - Resolute, Nunavut
    +CA	+744144-0944945	America/Resolute	Central Standard Time - Resolute, Nunavut
     CA	+484531-0913718	America/Atikokan	Eastern Standard Time - Atikokan, Ontario and Southampton I, Nunavut
     CA	+624900-0920459	America/Rankin_Inlet	Central Time - central Nunavut
     CA	+4953-09709	America/Winnipeg	Central Time - Manitoba & west Ontario
    @@ -131,6 +130,7 @@
     CA	+690650-1050310	America/Cambridge_Bay	Mountain Time - west Nunavut
     CA	+6227-11421	America/Yellowknife	Mountain Time - central Northwest Territories
     CA	+682059-1334300	America/Inuvik	Mountain Time - west Northwest Territories
    +CA	+4906-11631	America/Creston	Mountain Standard Time - Creston, British Columbia
     CA	+5946-12014	America/Dawson_Creek	Mountain Standard Time - Dawson Creek & Fort Saint John, British Columbia
     CA	+4916-12307	America/Vancouver	Pacific Time - west British Columbia
     CA	+6043-13503	America/Whitehorse	Pacific Time - south Yukon
    @@ -155,6 +155,7 @@
     CR	+0956-08405	America/Costa_Rica
     CU	+2308-08222	America/Havana
     CV	+1455-02331	Atlantic/Cape_Verde
    +CW	+1211-06900	America/Curacao
     CX	-1025+10543	Indian/Christmas
     CY	+3510+03322	Asia/Nicosia
     CZ	+5005+01426	Europe/Prague
    @@ -318,7 +319,8 @@
     PM	+4703-05620	America/Miquelon
     PN	-2504-13005	Pacific/Pitcairn
     PR	+182806-0660622	America/Puerto_Rico
    -PS	+3130+03428	Asia/Gaza
    +PS	+3130+03428	Asia/Gaza	Gaza Strip
    +PS	+313200+0350542	Asia/Hebron	West Bank
     PT	+3843-00908	Europe/Lisbon	mainland
     PT	+3238-01654	Atlantic/Madeira	Madeira Islands
     PT	+3744-02540	Atlantic/Azores	Azores
    @@ -331,7 +333,7 @@
     RU	+5443+02030	Europe/Kaliningrad	Moscow-01 - Kaliningrad
     RU	+5545+03735	Europe/Moscow	Moscow+00 - west Russia
     RU	+4844+04425	Europe/Volgograd	Moscow+00 - Caspian Sea
    -RU	+5312+05009	Europe/Samara	Moscow - Samara, Udmurtia
    +RU	+5312+05009	Europe/Samara	Moscow+00 - Samara, Udmurtia
     RU	+5651+06036	Asia/Yekaterinburg	Moscow+02 - Urals
     RU	+5500+07324	Asia/Omsk	Moscow+03 - west Siberia
     RU	+5502+08255	Asia/Novosibirsk	Moscow+03 - Novosibirsk
    @@ -360,8 +362,10 @@
     SN	+1440-01726	Africa/Dakar
     SO	+0204+04522	Africa/Mogadishu
     SR	+0550-05510	America/Paramaribo
    +SS	+0451+03136	Africa/Juba
     ST	+0020+00644	Africa/Sao_Tome
     SV	+1342-08912	America/El_Salvador
    +SX	+180305-0630250	America/Lower_Princes
     SY	+3330+03618	Asia/Damascus
     SZ	-2618+03106	Africa/Mbabane
     TC	+2128-07108	America/Grand_Turk
    diff -Nru matplotlib-1.1.1/lib/six.py matplotlib-1.2.0/lib/six.py
    --- matplotlib-1.1.1/lib/six.py	1970-01-01 00:00:00.000000000 +0000
    +++ matplotlib-1.2.0/lib/six.py	2012-11-06 22:31:09.000000000 +0000
    @@ -0,0 +1,366 @@
    +"""Utilities for writing code that runs on Python 2 and 3"""
    +
    +import operator
    +import sys
    +import types
    +
    +__author__ = "Benjamin Peterson "
    +__version__ = "1.2.0-mpl"
    +
    +
    +# True if we are running on Python 3.
    +PY3 = sys.version_info[0] == 3
    +
    +if PY3:
    +    string_types = str,
    +    integer_types = int,
    +    class_types = type,
    +    text_type = str
    +    binary_type = bytes
    +
    +    MAXSIZE = sys.maxsize
    +else:
    +    string_types = basestring,
    +    integer_types = (int, long)
    +    class_types = (type, types.ClassType)
    +    text_type = unicode
    +    binary_type = str
    +
    +    if sys.platform == "java":
    +        # Jython always uses 32 bits.
    +        MAXSIZE = int((1 << 31) - 1)
    +    else:
    +        # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
    +        class X(object):
    +            def __len__(self):
    +                return 1 << 31
    +        try:
    +            len(X())
    +        except OverflowError:
    +            # 32-bit
    +            MAXSIZE = int((1 << 31) - 1)
    +        else:
    +            # 64-bit
    +            MAXSIZE = int((1 << 63) - 1)
    +            del X
    +
    +
    +def _add_doc(func, doc):
    +    """Add documentation to a function."""
    +    func.__doc__ = doc
    +
    +
    +def _import_module(name):
    +    """Import module, returning the module after the last dot."""
    +    __import__(name)
    +    return sys.modules[name]
    +
    +
    +class _LazyDescr(object):
    +
    +    def __init__(self, name):
    +        self.name = name
    +
    +    def __get__(self, obj, tp):
    +        result = self._resolve()
    +        setattr(obj, self.name, result)
    +        # This is a bit ugly, but it avoids running this again.
    +        delattr(tp, self.name)
    +        return result
    +
    +
    +class MovedModule(_LazyDescr):
    +
    +    def __init__(self, name, old, new=None):
    +        super(MovedModule, self).__init__(name)
    +        if PY3:
    +            if new is None:
    +                new = name
    +            self.mod = new
    +        else:
    +            self.mod = old
    +
    +    def _resolve(self):
    +        return _import_module(self.mod)
    +
    +
    +class MovedAttribute(_LazyDescr):
    +
    +    def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
    +        super(MovedAttribute, self).__init__(name)
    +        if PY3:
    +            if new_mod is None:
    +                new_mod = name
    +            self.mod = new_mod
    +            if new_attr is None:
    +                if old_attr is None:
    +                    new_attr = name
    +                else:
    +                    new_attr = old_attr
    +            self.attr = new_attr
    +        else:
    +            self.mod = old_mod
    +            if old_attr is None:
    +                old_attr = name
    +            self.attr = old_attr
    +
    +    def _resolve(self):
    +        module = _import_module(self.mod)
    +        return getattr(module, self.attr)
    +
    +
    +
    +class _MovedItems(types.ModuleType):
    +    """Lazy loading of moved objects"""
    +
    +
    +_moved_attributes = [
    +    MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
    +    MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
    +    MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
    +    MovedAttribute("map", "itertools", "builtins", "imap", "map"),
    +    MovedAttribute("reload_module", "__builtin__", "imp", "reload"),
    +    MovedAttribute("reduce", "__builtin__", "functools"),
    +    MovedAttribute("StringIO", "StringIO", "io"),
    +    MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
    +    MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
    +
    +    MovedModule("builtins", "__builtin__"),
    +    MovedModule("configparser", "ConfigParser"),
    +    MovedModule("copyreg", "copy_reg"),
    +    MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
    +    MovedModule("http_cookies", "Cookie", "http.cookies"),
    +    MovedModule("html_entities", "htmlentitydefs", "html.entities"),
    +    MovedModule("html_parser", "HTMLParser", "html.parser"),
    +    MovedModule("http_client", "httplib", "http.client"),
    +    MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
    +    MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
    +    MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
    +    MovedModule("cPickle", "cPickle", "pickle"),
    +    MovedModule("queue", "Queue"),
    +    MovedModule("reprlib", "repr"),
    +    MovedModule("socketserver", "SocketServer"),
    +    MovedModule("tkinter", "Tkinter"),
    +    MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
    +    MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
    +    MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
    +    MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
    +    MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
    +    MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
    +    MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
    +    MovedModule("tkinter_colorchooser", "tkColorChooser",
    +                "tkinter.colorchooser"),
    +    MovedModule("tkinter_commondialog", "tkCommonDialog",
    +                "tkinter.commondialog"),
    +    MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
    +    MovedModule("tkinter_font", "tkFont", "tkinter.font"),
    +    MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
    +    MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
    +                "tkinter.simpledialog"),
    +    MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
    +    MovedModule("winreg", "_winreg"),
    +]
    +for attr in _moved_attributes:
    +    setattr(_MovedItems, attr.name, attr)
    +del attr
    +
    +moves = sys.modules["six.moves"] = _MovedItems("moves")
    +
    +
    +def add_move(move):
    +    """Add an item to six.moves."""
    +    setattr(_MovedItems, move.name, move)
    +
    +
    +def remove_move(name):
    +    """Remove item from six.moves."""
    +    try:
    +        delattr(_MovedItems, name)
    +    except AttributeError:
    +        try:
    +            del moves.__dict__[name]
    +        except KeyError:
    +            raise AttributeError("no such move, %r" % (name,))
    +
    +
    +if PY3:
    +    _meth_func = "__func__"
    +    _meth_self = "__self__"
    +
    +    _func_code = "__code__"
    +    _func_defaults = "__defaults__"
    +
    +    _iterkeys = "keys"
    +    _itervalues = "values"
    +    _iteritems = "items"
    +else:
    +    _meth_func = "im_func"
    +    _meth_self = "im_self"
    +
    +    _func_code = "func_code"
    +    _func_defaults = "func_defaults"
    +
    +    _iterkeys = "iterkeys"
    +    _itervalues = "itervalues"
    +    _iteritems = "iteritems"
    +
    +
    +try:
    +    advance_iterator = next
    +except NameError:
    +    def advance_iterator(it):
    +        return it.next()
    +next = advance_iterator
    +
    +
    +if PY3:
    +    def get_unbound_function(unbound):
    +        return unbound
    +
    +    Iterator = object
    +
    +    def callable(obj):
    +        return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
    +else:
    +    def get_unbound_function(unbound):
    +        return unbound.im_func
    +
    +    class Iterator(object):
    +
    +        def next(self):
    +            return type(self).__next__(self)
    +
    +    callable = callable
    +_add_doc(get_unbound_function,
    +         """Get the function out of a possibly unbound function""")
    +
    +
    +get_method_function = operator.attrgetter(_meth_func)
    +get_method_self = operator.attrgetter(_meth_self)
    +get_function_code = operator.attrgetter(_func_code)
    +get_function_defaults = operator.attrgetter(_func_defaults)
    +
    +
    +def iterkeys(d):
    +    """Return an iterator over the keys of a dictionary."""
    +    return iter(getattr(d, _iterkeys)())
    +
    +def itervalues(d):
    +    """Return an iterator over the values of a dictionary."""
    +    return iter(getattr(d, _itervalues)())
    +
    +def iteritems(d):
    +    """Return an iterator over the (key, value) pairs of a dictionary."""
    +    return iter(getattr(d, _iteritems)())
    +
    +
    +if PY3:
    +    def b(s):
    +        return s.encode("latin-1")
    +    def u(s):
    +        return s
    +    if sys.version_info[1] <= 1:
    +        def int2byte(i):
    +            return bytes((i,))
    +    else:
    +        # This is about 2x faster than the implementation above on 3.2+
    +        int2byte = operator.methodcaller("to_bytes", 1, "big")
    +    import io
    +    StringIO = io.StringIO
    +    BytesIO = io.BytesIO
    +else:
    +    def b(s):
    +        return s
    +    def u(s):
    +        return unicode(s, "unicode_escape")
    +    int2byte = chr
    +    import StringIO
    +    StringIO = BytesIO = StringIO.StringIO
    +_add_doc(b, """Byte literal""")
    +_add_doc(u, """Text literal""")
    +
    +
    +if PY3:
    +    import builtins
    +    exec_ = getattr(builtins, "exec")
    +
    +
    +    def reraise(tp, value, tb=None):
    +        if value.__traceback__ is not tb:
    +            raise value.with_traceback(tb)
    +        raise value
    +
    +
    +    print_ = getattr(builtins, "print")
    +    del builtins
    +
    +else:
    +    def exec_(code, globs=None, locs=None):
    +        """Execute code in a namespace."""
    +        if globs is None:
    +            frame = sys._getframe(1)
    +            globs = frame.f_globals
    +            if locs is None:
    +                locs = frame.f_locals
    +            del frame
    +        elif locs is None:
    +            locs = globs
    +        exec("""exec code in globs, locs""")
    +
    +
    +    exec_("""def reraise(tp, value, tb=None):
    +    raise tp, value, tb
    +""")
    +
    +
    +    def print_(*args, **kwargs):
    +        """The new-style print function."""
    +        fp = kwargs.pop("file", sys.stdout)
    +        if fp is None:
    +            return
    +        def write(data):
    +            if not isinstance(data, basestring):
    +                data = str(data)
    +            fp.write(data)
    +        want_unicode = False
    +        sep = kwargs.pop("sep", None)
    +        if sep is not None:
    +            if isinstance(sep, unicode):
    +                want_unicode = True
    +            elif not isinstance(sep, str):
    +                raise TypeError("sep must be None or a string")
    +        end = kwargs.pop("end", None)
    +        if end is not None:
    +            if isinstance(end, unicode):
    +                want_unicode = True
    +            elif not isinstance(end, str):
    +                raise TypeError("end must be None or a string")
    +        if kwargs:
    +            raise TypeError("invalid keyword arguments to print()")
    +        if not want_unicode:
    +            for arg in args:
    +                if isinstance(arg, unicode):
    +                    want_unicode = True
    +                    break
    +        if want_unicode:
    +            newline = unicode("\n")
    +            space = unicode(" ")
    +        else:
    +            newline = "\n"
    +            space = " "
    +        if sep is None:
    +            sep = space
    +        if end is None:
    +            end = newline
    +        for i, arg in enumerate(args):
    +            if i:
    +                write(sep)
    +            write(arg)
    +        write(end)
    +
    +_add_doc(reraise, """Reraise an exception.""")
    +
    +
    +def with_metaclass(meta, base=object):
    +    """Create a base class with a metaclass."""
    +    return meta("NewBase", (base,), {})
    diff -Nru matplotlib-1.1.1/make.osx matplotlib-1.2.0/make.osx
    --- matplotlib-1.1.1/make.osx	2012-06-30 18:47:51.000000000 +0000
    +++ matplotlib-1.2.0/make.osx	1970-01-01 00:00:00.000000000 +0000
    @@ -1,117 +0,0 @@
    -# -*- makefile -*-
    -# build mpl into a local install dir with
    -# make -f make.osx PREFIX=/Users/jdhunter/dev PYVERSION=2.6 fetch deps mpl_install
    -# (see README.osx for more details)
    -
    -MPLVERSION=1.1.0
    -PYVERSION=2.6
    -PYTHON=python${PYVERSION}
    -MACOSX_DEPLOYMENT_TARGET=10.6
    -OSX_SDK_VER=10.6
    -ARCH_FLAGS?=-arch i386 -arch x86_64
    -
    -# Dependency versions and URLs
    -#
    -# Adjusting these version numbers should be enough most of the time,
    -# but the download URLs are subject to change.
    -
    -ZLIBVERSION=1.2.5
    -PNGVERSION=1.5.4
    -FREETYPEVERSION=2.4.6
    -
    -ZLIBFILE=zlib-${ZLIBVERSION}.tar.gz
    -ZLIBDIR=$(basename $(basename ${ZLIBFILE}))
    -ZLIBURL=http://sourceforge.net/projects/libpng/files/zlib/${ZLIBVERSION}/${ZLIBFILE}/download
    -
    -PNGFILE=libpng-${PNGVERSION}.tar.gz
    -PNGDIR=$(basename $(basename ${PNGFILE}))
    -PNGURL=http://sourceforge.net/projects/libpng/files/libpng15/older-releases/${PNGVERSION}/${PNGFILE}/download
    -
    -FREETYPEFILE=freetype-${FREETYPEVERSION}.tar.bz2
    -FREETYPEDIR=$(basename $(basename ${FREETYPEFILE}))
    -FREETYPEURL=http://download.savannah.gnu.org/releases/freetype/${FREETYPEFILE}
    -
    -## You shouldn't need to configure past this point
    -
    -export PKG_CONFIG_PATH=${PREFIX}/lib/pkgconfig
    -export CFLAGS=${ARCH_FLAGS} -I${PREFIX}/include -I${PREFIX}/include/freetype2 -isysroot /Developer/SDKs/MacOSX${OSX_SDK_VER}.sdk
    -export LDFLAGS=${ARCH_FLAGS} -L${PREFIX}/lib -syslibroot,/Developer/SDKs/MacOSX${OSX_SDK_VER}.sdk
    -export MACOSX_DEPLOYMENT_TARGET
    -
    -help:
    -	@echo "Interesting targets: clean, fetch, deps, mpl_build, mpl_install_std"
    -	@echo "See README.osx for details"
    -
    -check-prefix:
    -	@if [ ! -d "$(PREFIX)" ]; then echo Set PREFIX to a directory - see README.osx; exit 1; fi
    -
    -clean:
    -	rm -rf ${ZLIBFILE} ${PNGFILE} ${FREETYPEFILE} \
    -	bdist_mpkg-${BDISTMPKGVERSION}.tar.gz \
    -	bdist_mpkg-${BDISTMPKGVERSION} setupext.pyc \
    -	lib/matplotlib/mpl-data/matplotlib.conf lib/matplotlib/mpl-data/matplotlibrc \
    -	zlib-${ZLIBVERSION} libpng-${PNGVERSION} freetype-${FREETYPEVERSION} \
    -	build
    -
    -
    -
    -fetch:
    -	${PYTHON} -c 'import urllib; urllib.urlretrieve("${ZLIBURL}", "${ZLIBFILE}")' &&\
    -	${PYTHON} -c 'import urllib; urllib.urlretrieve("${PNGURL}", "${PNGFILE}")' &&\
    -	${PYTHON} -c 'import urllib; urllib.urlretrieve("${FREETYPEURL}", "${FREETYPEFILE}")'
    -
    -zlib: check-prefix
    -	rm -rf ${ZLIBDIR} &&\
    -	tar xvfz ${ZLIBFILE} &&\
    -	cd ${ZLIBDIR} &&\
    -	./configure --prefix=${PREFIX} &&\
    -	${MAKE} -j3 install
    -
    -png: check-prefix zlib
    -	rm -rf ${PNGDIR} &&\
    -	tar xvfz ${PNGFILE} && \
    -	cd ${PNGDIR} &&\
    -	./configure  --disable-dependency-tracking  --prefix=${PREFIX} &&\
    -	${MAKE} -j3 install
    -
    -freetype: check-prefix zlib
    -	rm -rf ${FREETYPEDIR} &&\
    -	tar xvfj ${FREETYPEFILE} &&\
    -	cd ${FREETYPEDIR} &&\
    -	./configure  --prefix=${PREFIX} &&\
    -	${MAKE} -j3 install &&\
    -	cp objs/.libs/libfreetype.a .
    -
    -deps: zlib png freetype
    -	echo 'all done'
    -
    -# Various build and install targets
    -#
    -# The values of PKG_CONFIG_PATH, MACOSX_DEPLOYMENT_TARGET, CFLAGS,
    -# LDFLAGS affect the compilation; note that variables are
    -# automatically put into the environment by make.
    -
    -mpl_build: check-prefix
    -	${PYTHON} setup.py build
    -
    -mpl_install: check-prefix
    -	${PYTHON} setup.py install --prefix=${PREFIX}
    -
    -mpl_install_std: check-prefix
    -	${PYTHON} setup.py install
    -
    -mpl_install_egg: check-prefix
    -	${PYTHON} setupegg.py install
    -
    -mpl_install_develop: check-prefix
    -	${PYTHON} setupegg.py develop
    -
    -
    -binaries: check-prefix
    -	@if [ -z "$(PYVERSION)" ]; then echo Must set PYVERSION; exit 1; fi
    -	unset PKG_CONFIG_PATH &&\
    -	cp release/osx/data/setup.cfg release/osx/data/ReadMe.txt . &&\
    -	rm -f ${PREFIX}/lib/*.dylib &&\
    -	VERSIONER_PYTHON_PREFER_32_BIT=yes bdist_mpkg --readme=ReadMe.txt &&\
    -	hdiutil create -srcdir dist/matplotlib-${MPLVERSION}-py${PYVERSION}-macosx${OSX_SDK_VER}.mpkg  dist/matplotlib-${MPLVERSION}-py${PYVERSION}-macosx${OSX_SDK_VER}.dmg &&\
    -	VERSIONER_PYTHON_PREFER_32_BIT=yes ${PYTHON} setupegg.py bdist_egg
    diff -Nru matplotlib-1.1.1/matplotlibrc.template matplotlib-1.2.0/matplotlibrc.template
    --- matplotlib-1.1.1/matplotlibrc.template	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/matplotlibrc.template	2012-11-06 15:42:20.000000000 +0000
    @@ -23,8 +23,9 @@
     
     #### CONFIGURATION BEGINS HERE
     
    -# the default backend; one of GTK GTKAgg GTKCairo CocoaAgg FltkAgg
    -# MacOSX QtAgg Qt4Agg TkAgg WX WXAgg Agg Cairo GDK PS PDF SVG Template
    +# the default backend; one of GTK GTKAgg GTKCairo GTK3Agg GTK3Cairo
    +# CocoaAgg FltkAgg MacOSX QtAgg Qt4Agg TkAgg WX WXAgg Agg Cairo GDK PS
    +# PDF SVG Template
     # You can also deploy your own backend outside of matplotlib by
     # referring to the module name (which must be in the PYTHONPATH) as
     # 'module://my_backend'
    @@ -46,7 +47,7 @@
     #backend_fallback: True
     
     #interactive  : False
    -#toolbar      : toolbar2   # None | classic | toolbar2
    +#toolbar      : toolbar2   # None | toolbar2  ("classic" is deprecated)
     #timezone     : UTC        # a pytz timezone string, eg US/Central or Europe/Paris
     
     # Where your matplotlib data lives if you installed to a non-default
    @@ -55,11 +56,11 @@
     
     
     ### LINES
    -# See http://matplotlib.sourceforge.net/api/artist_api.html#module-matplotlib.lines for more
    +# See http://matplotlib.org/api/artist_api.html#module-matplotlib.lines for more
     # information on line properties.
     #lines.linewidth   : 1.0     # line width in points
     #lines.linestyle   : -       # solid line
    -#lines.color       : blue
    +#lines.color       : blue    # has no affect on plot(); see axes.color_cycle
     #lines.marker      : None    # the default marker
     #lines.markeredgewidth  : 0.5     # the line width around the marker symbol
     #lines.markersize  : 6            # markersize, in points
    @@ -72,7 +73,7 @@
     ### PATCHES
     # Patches are graphical objects that fill 2D space, like polygons or
     # circles.  See
    -# http://matplotlib.sourceforge.net/api/artist_api.html#module-matplotlib.patches
    +# http://matplotlib.org/api/artist_api.html#module-matplotlib.patches
     # information on patch properties
     #patch.linewidth        : 1.0     # edge width in points
     #patch.facecolor        : blue
    @@ -82,7 +83,7 @@
     ### FONT
     #
     # font properties used by text.Text.  See
    -# http://matplotlib.sourceforge.net/api/font_manager_api.html for more
    +# http://matplotlib.org/api/font_manager_api.html for more
     # information on font properties.  The 6 font properties used for font
     # matching are given below with their default values.
     #
    @@ -133,7 +134,7 @@
     
     ### TEXT
     # text properties used by text.Text.  See
    -# http://matplotlib.sourceforge.net/api/artist_api.html#module-matplotlib.text for more
    +# http://matplotlib.org/api/artist_api.html#module-matplotlib.text for more
     # information on text properties
     
     #text.color          : black
    @@ -169,8 +170,19 @@
                                  # correction off.  None will try and
                                  # guess based on your dvipng version
     
    -#text.hinting : True # If True, text will be hinted, otherwise not.  This only
    -                     # affects the Agg backend.
    +#text.hinting : 'auto' # May be one of the following:
    +                       #   'none': Perform no hinting
    +                       #   'auto': Use freetype's autohinter
    +                       #   'native': Use the hinting information in the
    +                       #             font file, if available, and if your
    +                       #             freetype library supports it
    +                       #   'either': Use the native hinting information,
    +                       #             or the autohinter if none is available.
    +                       # For backward compatibility, this value may also be
    +                       # True === 'auto' or False === 'none'.
    +text.hinting_factor : 8 # Specifies the amount of softness for hinting in the
    +                         # horizontal direction.  A value of 1 will hint to full
    +                         # pixels.  A value of 2 will hint to half pixels etc.
     
     #text.antialiased : True # If True (default), the text will be antialiased.
                              # This only affects the Agg backend.
    @@ -200,7 +212,7 @@
     ### AXES
     # default face and edge color, default tick sizes,
     # default fontsizes for ticklabels, and so on.  See
    -# http://matplotlib.sourceforge.net/api/axes_api.html#module-matplotlib.axes
    +# http://matplotlib.org/api/axes_api.html#module-matplotlib.axes
     #axes.hold           : True    # whether to clear the axes by default on
     #axes.facecolor      : white   # axes background color
     #axes.edgecolor      : black   # axes edge color
    @@ -219,6 +231,8 @@
                                        # according to the user's locale.
                                        # For example, use ',' as a decimal
                                        # separator in the fr_FR locale.
    +#axes.formatter.use_mathtext : False # When True, use mathtext for scientific
    +                                     # notation.
     #axes.unicode_minus  : True    # use unicode for the minus symbol
                                    # rather than hyphen.  See
                                    # http://en.wikipedia.org/wiki/Plus_and_minus_signs#Character_codes
    @@ -231,7 +245,7 @@
     #axes3d.grid         : True    # display grid on 3d axes
     
     ### TICKS
    -# see http://matplotlib.sourceforge.net/api/axis_api.html#matplotlib.axis.Tick
    +# see http://matplotlib.org/api/axis_api.html#matplotlib.axis.Tick
     #xtick.major.size     : 4      # major tick size in points
     #xtick.minor.size     : 2      # minor tick size in points
     #xtick.major.width    : 0.5    # major tick width in points
    @@ -240,7 +254,7 @@
     #xtick.minor.pad      : 4      # distance to the minor tick label in points
     #xtick.color          : k      # color of the tick labels
     #xtick.labelsize      : medium # fontsize of the tick labels
    -#xtick.direction      : in     # direction: in or out
    +#xtick.direction      : in     # direction: in, out, or inout
     
     #ytick.major.size     : 4      # major tick size in points
     #ytick.minor.size     : 2      # minor tick size in points
    @@ -250,13 +264,14 @@
     #ytick.minor.pad      : 4      # distance to the minor tick label in points
     #ytick.color          : k      # color of the tick labels
     #ytick.labelsize      : medium # fontsize of the tick labels
    -#ytick.direction      : in     # direction: in or out
    +#ytick.direction      : in     # direction: in, out, or inout
     
     
     ### GRIDS
     #grid.color       :   black   # grid color
     #grid.linestyle   :   :       # dotted
     #grid.linewidth   :   0.5     # in points
    +#grid.alpha       :   1.0     # transparency, between 0.0 and 1.0
     
     ### Legend
     #legend.fancybox      : False  # if True, use a rounded box for the
    @@ -282,11 +297,13 @@
     #legend.frameon       : True   # whether or not to draw a frame around legend
     
     ### FIGURE
    -# See http://matplotlib.sourceforge.net/api/figure_api.html#matplotlib.figure.Figure
    +# See http://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure
     #figure.figsize   : 8, 6    # figure size in inches
     #figure.dpi       : 80      # figure dots per inch
     #figure.facecolor : 0.75    # figure facecolor; 0.75 is scalar gray
     #figure.edgecolor : white   # figure edgecolor
    +#figure.autolayout : False  # When True, automatically adjust subplot
    +                            # parameters to make the plot fit the figure
     
     # The figure subplot parameters.  All dimensions are a fraction of the
     # figure width or height
    @@ -332,12 +349,12 @@
     # the default savefig params can be different from the display params
     # Eg, you may want a higher resolution, or to make the figure
     # background white
    -#savefig.dpi       : 100      # figure dots per inch
    -#savefig.facecolor : white    # figure facecolor when saving
    -#savefig.edgecolor : white    # figure edgecolor when saving
    -#savefig.extension : auto     # what extension to use for savefig('foo'), or 'auto'
    -
    -#cairo.format      : png      # png, ps, pdf, svg
    +#savefig.dpi        : 100      # figure dots per inch
    +#savefig.facecolor  : white    # figure facecolor when saving
    +#savefig.edgecolor  : white    # figure edgecolor when saving
    +#savefig.format     : png      # png, ps, pdf, svg
    +#savefig.bbox       : standard # 'tight' or 'standard'.
    +#savefig.pad_inches : 0.1      # Padding to be used when bbox is set to 'tight'
     
     # tk backend params
     #tk.window_focus   : False    # Maintain shell focus for TkAgg
    @@ -400,16 +417,21 @@
     #keymap.pan : p                      # pan mnemonic
     #keymap.zoom : o                     # zoom mnemonic
     #keymap.save : s                     # saving current figure
    +#keymap.quit : ctrl+w                # close the current figure
     #keymap.grid : g                     # switching on/off a grid in current axes
     #keymap.yscale : l                   # toggle scaling of y-axes ('log'/'linear')
     #keymap.xscale : L, k                # toggle scaling of x-axes ('log'/'linear')
     #keymap.all_axes : a                 # enable all axes
     
    -# Control downloading of example data. Various examples download some
    -# data from the Matplotlib git repository to avoid distributing extra
    -# files, but sometimes you want to avoid that. In that case set
    -# examples.download to False and examples.directory to the directory
    -# where you have a checkout of https://github.com/matplotlib/sample_data
    -
    -#examples.download : True  # False to bypass downloading mechanism
    -#examples.directory : ''   # directory to look in if download is false
    +###ANIMATION settings
    +#animation.writer : ffmpeg         # MovieWriter 'backend' to use
    +#animation.codec : mp4             # Codec to use for writing movie
    +#animation.bitrate: -1             # Controls size/quality tradeoff for movie.
    +                                   # -1 implies let utility auto-determine
    +#animation.frame_format: 'png'     # Controls frame format used by temp files
    +#animation.ffmpeg_path: 'ffmpeg'   # Path to ffmpeg binary. Without full path
    +                                   # $PATH is searched
    +#animation.ffmpeg_args: ''         # Additional arugments to pass to mencoder
    +#animation.mencoder_path: 'ffmpeg' # Path to mencoder binary. Without full path
    +                                   # $PATH is searched
    +#animation.mencoder_args: ''       # Additional arugments to pass to mencoder
    Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/sampledata/AAPL.dat and /tmp/dj4q_yDaTz/matplotlib-1.2.0/sampledata/AAPL.dat differ
    Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/sampledata/INTC.dat and /tmp/dj4q_yDaTz/matplotlib-1.2.0/sampledata/INTC.dat differ
    diff -Nru matplotlib-1.1.1/sampledata/MANIFEST.in matplotlib-1.2.0/sampledata/MANIFEST.in
    --- matplotlib-1.1.1/sampledata/MANIFEST.in	2011-01-02 22:44:34.000000000 +0000
    +++ matplotlib-1.2.0/sampledata/MANIFEST.in	1970-01-01 00:00:00.000000000 +0000
    @@ -1,5 +0,0 @@
    -include *.png *.jpg *.csv *.dat *.npy *.xrc *.ima
    -include setup.py MANIFEST.in MANIFEST
    -recursive-include axes_grid *
    -recursive-include testdir *
    -
    Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/sampledata/Minduka_Present_Blue_Pack.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/sampledata/Minduka_Present_Blue_Pack.png differ
    diff -Nru matplotlib-1.1.1/sampledata/PKG-INFO matplotlib-1.2.0/sampledata/PKG-INFO
    --- matplotlib-1.1.1/sampledata/PKG-INFO	2011-01-06 13:57:56.000000000 +0000
    +++ matplotlib-1.2.0/sampledata/PKG-INFO	1970-01-01 00:00:00.000000000 +0000
    @@ -1,10 +0,0 @@
    -Metadata-Version: 1.0
    -Name: mpl_sampledata
    -Version: 1.0.1
    -Summary: matplotlib sample data
    -Home-page: http://matplotlib.sf.net
    -Author: John Hunter
    -Author-email: jdh2358@gmail.com
    -License: UNKNOWN
    -Description: UNKNOWN
    -Platform: UNKNOWN
    diff -Nru matplotlib-1.1.1/sampledata/README.txt matplotlib-1.2.0/sampledata/README.txt
    --- matplotlib-1.1.1/sampledata/README.txt	2011-01-02 22:42:00.000000000 +0000
    +++ matplotlib-1.2.0/sampledata/README.txt	1970-01-01 00:00:00.000000000 +0000
    @@ -1,2 +0,0 @@
    -This is the sample data needed for some of matplotlib's examples and
    -docs.  See matplotlib.cbook.get_sample_data for more info.
    diff -Nru matplotlib-1.1.1/sampledata/aapl.csv matplotlib-1.2.0/sampledata/aapl.csv
    --- matplotlib-1.1.1/sampledata/aapl.csv	2009-09-06 12:32:28.000000000 +0000
    +++ matplotlib-1.2.0/sampledata/aapl.csv	1970-01-01 00:00:00.000000000 +0000
    @@ -1,6082 +0,0 @@
    -Date,Open,High,Low,Close,Volume,Adj Close
    -2008-10-14,116.26,116.40,103.14,104.08,70749800,104.08
    -2008-10-13,104.55,110.53,101.02,110.26,54967000,110.26
    -2008-10-10,85.70,100.00,85.00,96.80,79260700,96.80
    -2008-10-09,93.35,95.80,86.60,88.74,57763700,88.74
    -2008-10-08,85.91,96.33,85.68,89.79,78847900,89.79
    -2008-10-07,100.48,101.50,88.95,89.16,67099000,89.16
    -2008-10-06,91.96,98.78,87.54,98.14,75264900,98.14
    -2008-10-03,104.00,106.50,94.65,97.07,81942800,97.07
    -2008-10-02,108.01,108.79,100.00,100.10,57477300,100.10
    -2008-10-01,111.92,112.36,107.39,109.12,46303000,109.12
    -2008-09-30,108.25,115.00,106.30,113.66,58095800,113.66
    -2008-09-29,119.62,119.68,100.59,105.26,93581400,105.26
    -2008-09-26,124.91,129.80,123.00,128.24,40208700,128.24
    -2008-09-25,129.80,134.79,128.52,131.93,35865600,131.93
    -2008-09-24,127.27,130.95,125.15,128.71,37393400,128.71
    -2008-09-23,131.85,135.80,126.66,126.84,45727300,126.84
    -2008-09-22,139.94,140.25,130.66,131.05,30577300,131.05
    -2008-09-19,142.60,144.20,136.31,140.91,51102700,140.91
    -2008-09-18,130.57,135.43,120.68,134.09,59819300,134.09
    -2008-09-17,138.49,138.51,127.83,127.83,42847200,127.83
    -2008-09-16,133.86,142.50,132.15,139.88,42804800,139.88
    -2008-09-15,142.03,147.69,140.36,140.36,32852600,140.36
    -2008-09-12,150.91,150.91,146.50,148.94,28322400,148.94
    -2008-09-11,148.18,152.99,146.00,152.65,34666800,152.65
    -2008-09-10,152.32,154.99,148.80,151.61,34755100,151.61
    -2008-09-09,156.86,159.96,149.79,151.68,44442500,151.68
    -2008-09-08,164.57,164.89,151.46,157.92,37356400,157.92
    -2008-09-05,158.59,162.40,157.65,160.18,28083800,160.18
    -2008-09-04,165.86,167.91,160.81,161.22,26549500,161.22
    -2008-09-03,166.84,168.68,164.00,166.96,26244100,166.96
    -2008-09-02,172.40,173.50,165.00,166.19,27884400,166.19
    -2008-08-29,172.96,173.50,169.04,169.53,21403200,169.53
    -2008-08-28,175.28,176.25,172.75,173.74,15394500,173.74
    -2008-08-27,173.31,175.76,172.19,174.67,17045900,174.67
    -2008-08-26,172.76,174.88,172.61,173.64,15912500,173.64
    -2008-08-25,176.15,176.23,171.66,172.55,17300900,172.55
    -2008-08-22,175.82,177.50,175.57,176.79,15700400,176.79
    -2008-08-21,174.47,175.45,171.89,174.29,19276600,174.29
    -2008-08-20,174.77,176.94,173.61,175.84,18105400,175.84
    -2008-08-19,174.54,177.07,171.81,173.53,21997000,173.53
    -2008-08-18,175.57,177.81,173.82,175.39,19691200,175.39
    -2008-08-15,179.04,179.75,175.05,175.74,25294700,175.74
    -2008-08-14,178.33,180.45,177.84,179.32,25393200,179.32
    -2008-08-13,177.98,180.00,175.90,179.30,30083800,179.30
    -2008-08-12,173.52,179.29,173.51,176.73,29867100,176.73
    -2008-08-11,170.07,176.50,169.67,173.56,31821100,173.56
    -2008-08-08,163.86,169.65,163.75,169.55,25499900,169.55
    -2008-08-07,162.71,166.15,161.50,163.57,24013300,163.57
    -2008-08-06,159.97,167.40,158.00,164.19,28264600,164.19
    -2008-08-05,155.42,160.80,154.82,160.64,24584700,160.64
    -2008-08-04,156.60,157.90,152.91,153.23,21161700,153.23
    -2008-08-01,159.90,159.99,155.75,156.66,19451400,156.66
    -2008-07-31,157.54,162.20,156.98,158.95,22767800,158.95
    -2008-07-30,157.78,160.49,156.08,159.88,25899400,159.88
    -2008-07-29,155.41,159.45,153.65,157.08,24431100,157.08
    -2008-07-28,162.34,162.47,154.02,154.40,27882600,154.40
    -2008-07-25,160.40,163.00,158.65,162.12,22629900,162.12
    -2008-07-24,164.32,165.26,158.45,159.03,29986400,159.03
    -2008-07-23,164.99,168.37,161.56,166.26,37920300,166.26
    -2008-07-22,149.00,162.76,146.53,162.02,67128300,162.02
    -2008-07-21,166.90,167.50,161.12,166.29,48588200,166.29
    -2008-07-18,168.52,169.65,165.00,165.15,31014800,165.15
    -2008-07-17,174.10,174.98,171.39,171.81,27054500,171.81
    -2008-07-16,170.20,172.93,168.60,172.81,26706800,172.81
    -2008-07-15,172.48,173.74,166.39,169.64,37144400,169.64
    -2008-07-14,179.24,179.30,173.08,173.88,31644800,173.88
    -2008-07-11,175.47,177.11,171.00,172.58,33214700,172.58
    -2008-07-10,174.92,177.34,171.37,176.63,30024600,176.63
    -2008-07-09,180.20,180.91,174.14,174.25,31992000,174.25
    -2008-07-08,175.40,179.70,172.74,179.55,31726800,179.55
    -2008-07-07,173.16,177.13,171.90,175.16,29299700,175.16
    -2008-07-03,169.59,172.17,165.75,170.12,18691500,170.12
    -2008-07-02,175.20,177.45,168.18,168.18,29911400,168.18
    -2008-07-01,164.23,174.72,164.00,174.68,39688600,174.68
    -2008-06-30,170.19,172.00,166.62,167.44,24435600,167.44
    -2008-06-27,166.51,170.57,164.15,170.09,37223200,170.09
    -2008-06-26,174.07,174.84,168.01,168.26,31057500,168.26
    -2008-06-25,174.61,178.83,173.88,177.39,23016100,177.39
    -2008-06-24,172.37,175.78,171.63,173.25,22212400,173.25
    -2008-06-23,174.74,175.88,171.56,173.16,23063600,173.16
    -2008-06-20,179.35,181.00,175.00,175.27,31727400,175.27
    -2008-06-19,178.55,182.34,176.80,180.90,28283900,180.90
    -2008-06-18,181.12,182.20,177.35,178.75,28981000,178.75
    -2008-06-17,178.10,181.99,177.41,181.43,32130600,181.43
    -2008-06-16,171.30,177.90,169.07,176.84,37561800,176.84
    -2008-06-13,171.64,174.16,165.31,172.37,48069900,172.37
    -2008-06-12,181.49,182.60,171.20,173.26,46726200,173.26
    -2008-06-11,184.34,186.00,179.59,180.81,34341100,180.81
    -2008-06-10,180.51,186.78,179.02,185.64,40728600,185.64
    -2008-06-09,184.79,184.94,175.75,181.61,67442600,181.61
    -2008-06-06,188.00,189.95,185.55,185.64,34438700,185.64
    -2008-06-05,186.34,189.84,185.70,189.43,26980200,189.43
    -2008-06-04,184.02,187.09,183.23,185.19,25963700,185.19
    -2008-06-03,186.86,188.20,182.34,185.37,26804300,185.37
    -2008-06-02,188.60,189.65,184.53,186.10,24280000,186.10
    -2008-05-30,187.45,189.54,187.38,188.75,21792300,188.75
    -2008-05-29,186.76,188.20,185.50,186.69,23113800,186.69
    -2008-05-28,187.41,187.95,183.72,187.01,26570700,187.01
    -2008-05-27,182.75,186.43,181.84,186.43,28210900,186.43
    -2008-05-23,180.77,181.99,177.80,181.17,32389900,181.17
    -2008-05-22,179.26,181.33,172.00,177.05,43097700,177.05
    -2008-05-21,185.67,187.95,176.25,178.19,41344900,178.19
    -2008-05-20,181.82,186.16,180.12,185.90,34637500,185.90
    -2008-05-19,187.86,188.69,181.30,183.60,33779300,183.60
    -2008-05-16,190.11,190.30,187.00,187.62,27348900,187.62
    -2008-05-15,186.81,189.90,184.20,189.73,31186000,189.73
    -2008-05-14,191.23,192.24,185.57,186.26,32743700,186.26
    -2008-05-13,188.61,191.45,187.86,189.96,29401300,189.96
    -2008-05-12,185.21,188.87,182.85,188.16,29234400,188.16
    -2008-05-09,183.16,184.25,181.37,183.45,24038300,183.45
    -2008-05-08,183.77,186.50,183.07,185.06,32110200,185.06
    -2008-05-07,186.05,188.20,180.54,182.59,41326200,182.59
    -2008-05-06,184.66,187.12,182.18,186.66,32816800,186.66
    -2008-05-05,181.92,185.31,181.05,184.73,30519900,184.73
    -2008-05-02,180.19,181.92,178.55,180.94,35931500,180.94
    -2008-05-01,174.96,180.00,174.86,180.00,32270600,180.00
    -2008-04-30,176.19,180.00,172.92,173.95,40697300,173.95
    -2008-04-29,171.11,175.66,170.25,175.05,32981300,175.05
    -2008-04-28,169.75,173.75,169.13,172.24,28114800,172.24
    -2008-04-25,170.70,171.10,166.42,169.73,35445500,169.73
    -2008-04-24,165.34,169.98,159.19,168.94,60573800,168.94
    -2008-04-23,164.05,164.84,161.08,162.89,53721100,162.89
    -2008-04-22,167.40,168.00,158.09,160.20,51413300,160.20
    -2008-04-21,162.21,168.50,161.76,168.16,37112600,168.16
    -2008-04-18,159.12,162.26,158.38,161.04,36670200,161.04
    -2008-04-17,154.17,156.00,153.35,154.49,25152400,154.49
    -2008-04-16,151.72,154.10,150.62,153.70,28420500,153.70
    -2008-04-15,149.40,149.72,145.72,148.38,24929900,148.38
    -2008-04-14,146.77,149.25,144.54,147.78,30181700,147.78
    -2008-04-11,152.72,153.30,146.40,147.14,43217000,147.14
    -2008-04-10,151.13,155.42,150.60,154.55,34134400,154.55
    -2008-04-09,153.31,153.89,150.46,151.44,31192800,151.44
    -2008-04-08,153.55,156.45,152.32,152.84,36224800,152.84
    -2008-04-07,156.13,159.69,155.11,155.89,41368800,155.89
    -2008-04-04,152.19,154.71,150.75,153.08,30514900,153.08
    -2008-04-03,147.06,153.63,147.00,151.61,37556000,151.61
    -2008-04-02,148.78,151.20,145.85,147.49,37320300,147.49
    -2008-04-01,146.30,149.66,143.61,149.53,36877400,149.53
    -2008-03-31,143.27,145.71,142.52,143.50,27430900,143.50
    -2008-03-28,141.80,144.65,141.60,143.01,25521800,143.01
    -2008-03-27,144.95,145.31,139.99,140.25,35708200,140.25
    -2008-03-26,140.87,145.74,140.64,145.06,42217300,145.06
    -2008-03-25,139.96,143.10,137.33,140.98,37585400,140.98
    -2008-03-24,134.01,140.85,133.64,139.53,38104300,139.53
    -2008-03-20,131.12,133.29,129.18,133.27,32456700,133.27
    -2008-03-19,133.12,134.29,129.67,129.67,36090600,129.67
    -2008-03-18,129.18,133.00,128.67,132.82,43040000,132.82
    -2008-03-17,122.55,128.59,122.55,126.73,38307100,126.73
    -2008-03-14,129.88,130.30,124.20,126.61,41308600,126.61
    -2008-03-13,124.10,129.50,123.00,127.94,45075100,127.94
    -2008-03-12,127.04,128.68,125.17,126.03,37843900,126.03
    -2008-03-11,124.10,127.48,122.00,127.35,41569400,127.35
    -2008-03-10,121.98,123.46,119.37,119.69,35699600,119.69
    -2008-03-07,120.41,122.98,119.05,122.25,43945100,122.25
    -2008-03-06,124.61,127.50,120.81,120.93,52632100,120.93
    -2008-03-05,123.58,125.14,122.25,124.49,43637000,124.49
    -2008-03-04,121.99,124.88,120.40,124.62,63763700,124.62
    -2008-03-03,124.44,125.98,118.00,121.73,56894400,121.73
    -2008-02-29,129.29,130.21,124.80,125.02,44838600,125.02
    -2008-02-28,127.20,132.20,125.77,129.91,57794800,129.91
    -2008-02-27,118.23,123.05,118.09,122.96,52683500,122.96
    -2008-02-26,117.64,121.09,115.44,119.15,53746000,119.15
    -2008-02-25,118.59,120.17,116.66,119.74,44884800,119.74
    -2008-02-22,122.48,122.51,115.87,119.46,54638500,119.46
    -2008-02-21,126.05,126.47,120.86,121.54,33504100,121.54
    -2008-02-20,122.20,124.60,121.68,123.82,34551400,123.82
    -2008-02-19,125.99,126.75,121.44,122.18,35894500,122.18
    -2008-02-15,126.27,127.08,124.06,124.63,32189300,124.63
    -2008-02-14,129.40,130.80,127.01,127.46,34074900,127.46
    -2008-02-13,126.68,129.78,125.63,129.40,34590500,129.40
    -2008-02-12,130.70,131.00,123.62,124.86,43785000,124.86
    -2008-02-11,128.01,129.98,127.20,129.45,42908300,129.45
    -2008-02-08,122.08,125.70,121.60,125.48,48427600,125.48
    -2008-02-07,119.97,124.78,117.27,121.24,74404700,121.24
    -2008-02-06,130.83,131.92,121.77,122.00,56188300,122.00
    -2008-02-05,130.43,134.00,128.90,129.36,40751500,129.36
    -2008-02-04,134.21,135.90,131.42,131.65,32115500,131.65
    -2008-02-01,136.24,136.59,132.18,133.75,36098000,133.75
    -2008-01-31,129.45,136.65,129.40,135.36,48059800,135.36
    -2008-01-30,131.37,135.45,130.00,132.18,44394700,132.18
    -2008-01-29,131.15,132.79,129.05,131.54,39285100,131.54
    -2008-01-28,128.16,133.20,126.45,130.01,52673000,130.01
    -2008-01-25,138.99,139.09,129.61,130.01,55526400,130.01
    -2008-01-24,139.99,140.70,132.01,135.60,71638100,135.60
    -2008-01-23,136.19,140.00,126.14,139.07,120463200,139.07
    -2008-01-22,148.06,159.98,146.00,155.64,86955500,155.64
    -2008-01-18,161.71,165.75,159.61,161.36,61583700,161.36
    -2008-01-17,161.51,165.36,158.42,160.89,62780700,160.89
    -2008-01-16,165.23,169.01,156.70,159.64,79065900,159.64
    -2008-01-15,177.72,179.22,164.66,169.04,83688500,169.04
    -2008-01-14,177.52,179.42,175.17,178.78,39301800,178.78
    -2008-01-11,176.00,177.85,170.00,172.69,44010200,172.69
    -2008-01-10,177.58,181.00,175.41,178.02,52963400,178.02
    -2008-01-09,171.30,179.50,168.30,179.40,64781500,179.40
    -2008-01-08,180.14,182.46,170.80,171.25,54422000,171.25
    -2008-01-07,181.25,183.60,170.23,177.64,74006900,177.64
    -2008-01-04,191.45,193.00,178.89,180.05,51994000,180.05
    -2008-01-03,195.41,197.39,192.69,194.93,30073800,194.93
    -2008-01-02,199.27,200.26,192.55,194.84,38542100,194.84
    -2007-12-31,199.50,200.50,197.75,198.08,19261900,198.08
    -2007-12-28,200.59,201.56,196.88,199.83,24987400,199.83
    -2007-12-27,198.95,202.96,197.80,198.57,28411700,198.57
    -2007-12-26,199.01,200.96,196.82,198.95,25133300,198.95
    -2007-12-24,195.03,199.33,194.79,198.80,17150100,198.80
    -2007-12-21,190.12,193.91,189.89,193.91,35498600,193.91
    -2007-12-20,185.43,187.83,183.33,187.21,27644900,187.21
    -2007-12-19,182.98,184.64,180.90,183.12,29552800,183.12
    -2007-12-18,186.52,187.33,178.60,182.98,43664400,182.98
    -2007-12-17,190.72,192.65,182.98,184.40,36596200,184.40
    -2007-12-14,190.37,193.20,189.54,190.39,24082600,190.39
    -2007-12-13,190.19,192.12,187.82,191.83,30879200,191.83
    -2007-12-12,193.44,194.48,185.76,190.86,43773600,190.86
    -2007-12-11,194.75,196.83,187.39,188.54,39675900,188.54
    -2007-12-10,193.59,195.66,192.69,194.21,25799200,194.21
    -2007-12-07,190.54,194.99,188.04,194.30,38073800,194.30
    -2007-12-06,186.19,190.10,186.12,189.95,32136100,189.95
    -2007-12-05,182.89,186.00,182.41,185.50,31871500,185.50
    -2007-12-04,177.15,180.90,176.99,179.81,27635700,179.81
    -2007-12-03,181.86,184.14,177.70,178.86,34338200,178.86
    -2007-11-30,187.34,187.70,179.70,182.22,42421500,182.22
    -2007-11-29,179.43,185.17,179.15,184.29,37533100,184.29
    -2007-11-28,176.82,180.60,175.35,180.22,41104000,180.22
    -2007-11-27,175.22,175.79,170.01,174.81,47036800,174.81
    -2007-11-26,173.59,177.27,172.35,172.54,46634100,172.54
    -2007-11-23,172.00,172.05,169.75,171.54,16634200,171.54
    -2007-11-21,165.84,172.35,164.67,168.46,43493200,168.46
    -2007-11-20,165.67,171.79,163.53,168.85,55130100,168.85
    -2007-11-19,166.10,168.20,162.10,163.95,41196800,163.95
    -2007-11-16,165.30,167.02,159.33,166.39,49391300,166.39
    -2007-11-15,166.39,169.59,160.30,164.30,53095600,164.30
    -2007-11-14,177.16,177.57,163.74,166.11,51695400,166.11
    -2007-11-13,160.85,170.98,153.76,169.96,62034100,169.96
    -2007-11-12,165.28,167.70,150.63,153.76,63057700,153.76
    -2007-11-09,171.15,175.12,165.21,165.37,54458700,165.37
    -2007-11-08,186.67,186.90,167.77,175.47,67458500,175.47
    -2007-11-07,190.61,192.68,186.13,186.30,35473400,186.30
    -2007-11-06,187.05,192.00,185.27,191.79,34097400,191.79
    -2007-11-05,185.29,188.96,184.24,186.18,28720600,186.18
    -2007-11-02,189.21,189.44,183.49,187.87,35789800,187.87
    -2007-11-01,188.60,190.10,180.00,187.44,28751300,187.44
    -2007-10-31,187.63,190.12,184.95,189.95,29761100,189.95
    -2007-10-30,186.18,189.37,184.73,187.00,33550500,187.00
    -2007-10-29,185.45,186.59,184.70,185.09,19305500,185.09
    -2007-10-26,185.29,185.37,182.88,184.70,25219800,184.70
    -2007-10-25,184.87,185.90,181.66,182.78,34771500,182.78
    -2007-10-24,185.81,187.21,179.24,185.93,46017200,185.93
    -2007-10-23,188.56,188.60,182.76,186.16,64113000,186.16
    -2007-10-22,170.35,174.90,169.96,174.36,58910700,174.36
    -2007-10-19,174.24,174.63,170.00,170.42,46135000,170.42
    -2007-10-18,171.50,174.19,171.05,173.50,29417000,173.50
    -2007-10-17,172.69,173.04,169.18,172.75,40271900,172.75
    -2007-10-16,165.54,170.18,165.15,169.58,38136800,169.58
    -2007-10-15,167.98,169.57,163.50,166.98,38497500,166.98
    -2007-10-12,163.01,167.28,161.80,167.25,35292000,167.25
    -2007-10-11,169.49,171.88,153.21,162.23,58714000,162.23
    -2007-10-10,167.55,167.88,165.60,166.79,23842500,166.79
    -2007-10-09,170.20,171.11,166.68,167.86,39438800,167.86
    -2007-10-08,163.49,167.91,162.97,167.91,29854600,167.91
    -2007-10-05,158.37,161.58,157.70,161.45,33695400,161.45
    -2007-10-04,158.00,158.08,153.50,156.24,23462800,156.24
    -2007-10-03,157.78,159.18,157.01,157.92,24732800,157.92
    -2007-10-02,156.55,158.59,155.89,158.45,28288200,158.45
    -2007-10-01,154.63,157.41,152.93,156.34,29895300,156.34
    -2007-09-28,153.44,154.60,152.75,153.47,21967900,153.47
    -2007-09-27,153.77,154.52,152.32,154.50,23507100,154.50
    -2007-09-26,154.47,155.00,151.25,152.77,34831000,152.77
    -2007-09-25,146.84,153.22,146.82,153.18,42591100,153.18
    -2007-09-24,146.73,149.85,146.65,148.28,37577200,148.28
    -2007-09-21,141.14,144.65,140.31,144.15,40674300,144.15
    -2007-09-20,140.15,141.79,139.32,140.31,24708600,140.31
    -2007-09-19,143.02,143.16,139.40,140.77,36674300,140.77
    -2007-09-18,139.06,142.85,137.83,140.92,38003200,140.92
    -2007-09-17,138.99,140.59,137.60,138.41,28334700,138.41
    -2007-09-14,136.57,138.98,136.20,138.81,21690000,138.81
    -2007-09-13,138.83,139.00,136.65,137.20,23434400,137.20
    -2007-09-12,135.99,139.40,135.75,136.85,36527500,136.85
    -2007-09-11,137.90,138.30,133.75,135.49,34710200,135.49
    -2007-09-10,136.99,138.04,133.95,136.71,53137100,136.71
    -2007-09-07,132.01,132.30,130.00,131.77,51092000,131.77
    -2007-09-06,135.56,137.57,132.71,135.01,67902200,135.01
    -2007-09-05,144.97,145.84,136.10,136.76,83150800,136.76
    -2007-09-04,139.94,145.73,139.84,144.16,47030100,144.16
    -2007-08-31,139.49,139.65,137.41,138.48,31317400,138.48
    -2007-08-30,132.67,138.25,132.30,136.25,51270800,136.25
    -2007-08-29,129.88,134.18,129.54,134.08,41673600,134.08
    -2007-08-28,130.99,132.41,126.63,126.82,42120200,126.82
    -2007-08-27,133.39,134.66,132.10,132.25,25265700,132.25
    -2007-08-24,130.53,135.37,129.81,135.30,32565500,135.30
    -2007-08-23,133.09,133.34,129.76,131.07,30958500,131.07
    -2007-08-22,131.22,132.75,130.33,132.51,37920200,132.51
    -2007-08-21,122.21,128.96,121.00,127.57,46537400,127.57
    -2007-08-20,123.96,124.50,120.50,122.22,28689900,122.22
    -2007-08-17,122.01,123.50,119.82,122.06,42680800,122.06
    -2007-08-16,117.01,118.50,111.62,117.05,66667500,117.05
    -2007-08-15,122.74,124.86,119.65,119.90,35459000,119.90
    -2007-08-14,128.29,128.30,123.71,124.03,26393100,124.03
    -2007-08-13,128.32,129.35,126.50,127.79,26889700,127.79
    -2007-08-10,123.12,127.75,120.30,125.00,50383900,125.00
    -2007-08-09,131.11,133.00,125.09,126.39,40192700,126.39
    -2007-08-08,136.76,136.86,132.00,134.01,28860600,134.01
    -2007-08-07,134.94,137.24,132.63,135.03,33926300,135.03
    -2007-08-06,132.90,135.27,128.30,135.25,33041800,135.25
    -2007-08-03,135.26,135.95,131.50,131.85,24256700,131.85
    -2007-08-02,136.65,136.96,134.15,136.49,30451600,136.49
    -2007-08-01,133.64,135.38,127.77,135.00,62505600,135.00
    -2007-07-31,142.97,143.48,131.52,131.76,62942600,131.76
    -2007-07-30,144.33,145.45,139.57,141.43,39535300,141.43
    -2007-07-27,146.19,148.92,143.78,143.85,41467800,143.85
    -2007-07-26,145.91,148.50,136.96,146.00,78093900,146.00
    -2007-07-25,137.35,138.36,135.00,137.26,53435100,137.26
    -2007-07-24,138.88,141.00,134.15,134.89,64117600,134.89
    -2007-07-23,143.31,145.22,140.93,143.70,37017500,143.70
    -2007-07-20,141.65,144.18,140.00,143.75,41706200,143.75
    -2007-07-19,140.30,140.81,139.65,140.00,26174700,140.00
    -2007-07-18,138.19,138.44,136.04,138.12,27030600,138.12
    -2007-07-17,138.30,139.60,137.50,138.91,25355700,138.91
    -2007-07-16,138.39,139.98,137.50,138.10,33432600,138.10
    -2007-07-13,135.03,137.85,134.52,137.73,32414500,137.73
    -2007-07-12,133.85,134.24,132.39,134.07,25164600,134.07
    -2007-07-11,132.07,133.70,131.31,132.39,29349000,132.39
    -2007-07-10,128.88,134.50,128.81,132.35,44821700,132.35
    -2007-07-09,132.38,132.90,129.18,130.33,35565000,130.33
    -2007-07-06,133.13,133.34,130.40,132.30,31239100,132.30
    -2007-07-05,128.80,132.97,128.69,132.75,51894700,132.75
    -2007-07-03,122.00,127.40,121.50,127.17,41517200,127.17
    -2007-07-02,121.05,122.09,119.30,121.26,35530800,121.26
    -2007-06-29,121.97,124.00,121.09,122.04,40637200,122.04
    -2007-06-28,122.36,122.49,120.00,120.56,29933700,120.56
    -2007-06-27,120.61,122.04,119.26,121.89,34810600,121.89
    -2007-06-26,123.98,124.00,118.72,119.65,48035900,119.65
    -2007-06-25,124.19,125.09,121.06,122.34,34478700,122.34
    -2007-06-22,123.85,124.45,122.38,123.00,22567000,123.00
    -2007-06-21,121.70,124.29,120.72,123.90,30965900,123.90
    -2007-06-20,123.87,124.66,121.50,121.55,32054000,121.55
    -2007-06-19,124.69,125.01,122.91,123.66,33679500,123.66
    -2007-06-18,123.28,125.18,122.54,125.09,32521600,125.09
    -2007-06-15,120.62,120.67,119.86,120.50,28972100,120.50
    -2007-06-14,117.20,119.45,116.42,118.75,34759500,118.75
    -2007-06-13,121.15,121.19,115.40,117.50,61476900,117.50
    -2007-06-12,119.35,121.71,118.31,120.38,50948800,120.38
    -2007-06-11,126.00,126.15,119.54,120.19,66937800,120.19
    -2007-06-08,125.82,125.83,122.29,124.49,44345800,124.49
    -2007-06-07,124.99,127.61,123.19,124.07,68395700,124.07
    -2007-06-06,122.30,124.05,121.95,123.64,39722900,123.64
    -2007-06-05,121.41,122.69,120.50,122.67,32885200,122.67
    -2007-06-04,118.63,121.73,117.90,121.33,31666900,121.33
    -2007-06-01,121.10,121.19,118.29,118.40,31616500,118.40
    -2007-05-31,120.07,122.17,119.54,121.19,46323800,121.19
    -2007-05-30,114.30,118.88,113.53,118.77,52801600,118.77
    -2007-05-29,114.45,114.86,112.69,114.35,23060500,114.35
    -2007-05-25,112.00,113.78,111.50,113.62,22605700,113.62
    -2007-05-24,112.81,114.46,110.37,110.69,31691500,110.69
    -2007-05-23,114.02,115.00,112.59,112.89,32549100,112.89
    -2007-05-22,112.49,113.75,112.01,113.54,20443200,113.54
    -2007-05-21,110.31,112.45,110.05,111.98,22853300,111.98
    -2007-05-18,110.23,110.64,109.77,110.02,22190900,110.02
    -2007-05-17,107.15,109.87,107.15,109.44,26260400,109.44
    -2007-05-16,108.53,108.83,103.42,107.34,40241700,107.34
    -2007-05-15,109.57,110.20,106.48,107.52,34089800,107.52
    -2007-05-14,109.62,110.00,108.25,109.36,23283800,109.36
    -2007-05-11,107.74,109.13,106.78,108.74,23346300,108.74
    -2007-05-10,106.63,108.84,105.92,107.34,42759200,107.34
    -2007-05-09,104.91,106.96,104.89,106.88,25634200,106.88
    -2007-05-08,103.47,105.15,103.42,105.06,27999900,105.06
    -2007-05-07,101.08,104.35,101.01,103.92,30769900,103.92
    -2007-05-04,100.80,101.60,100.50,100.81,13642400,100.81
    -2007-05-03,100.73,101.45,100.01,100.40,20574200,100.40
    -2007-05-02,99.65,100.54,99.47,100.39,18040900,100.39
    -2007-05-01,99.59,100.35,98.55,99.47,19018700,99.47
    -2007-04-30,100.09,101.00,99.67,99.80,22018200,99.80
    -2007-04-27,98.18,99.95,97.69,99.92,24978700,99.92
    -2007-04-26,101.58,102.50,98.30,98.84,62063500,98.84
    -2007-04-25,94.23,95.40,93.80,95.35,42398000,95.35
    -2007-04-24,93.96,96.39,91.30,93.24,37687600,93.24
    -2007-04-23,91.59,93.80,91.42,93.51,27867500,93.51
    -2007-04-20,90.89,91.18,90.55,90.97,18670700,90.97
    -2007-04-19,90.19,91.25,89.83,90.27,15211200,90.27
    -2007-04-18,90.16,90.85,89.60,90.40,16573000,90.40
    -2007-04-17,92.00,92.30,89.70,90.35,26854300,90.35
    -2007-04-16,90.57,91.50,90.25,91.43,21751200,91.43
    -2007-04-13,90.90,91.40,90.06,90.24,25712200,90.24
    -2007-04-12,92.04,92.31,90.72,92.19,23452700,92.19
    -2007-04-11,93.90,93.95,92.33,92.59,19607800,92.59
    -2007-04-10,93.67,94.26,93.41,94.25,12588100,94.25
    -2007-04-09,95.21,95.30,93.04,93.65,14762200,93.65
    -2007-04-05,94.12,94.68,93.52,94.68,12697000,94.68
    -2007-04-04,94.94,95.14,94.13,94.27,17028000,94.27
    -2007-04-03,94.14,95.23,93.76,94.50,20854800,94.50
    -2007-04-02,94.14,94.25,93.02,93.65,17928300,93.65
    -2007-03-30,94.28,94.68,92.75,92.91,21448500,92.91
    -2007-03-29,94.19,94.19,92.23,93.75,25918700,93.75
    -2007-03-28,94.88,95.40,93.15,93.24,33654900,93.24
    -2007-03-27,95.71,96.83,95.00,95.46,33287600,95.46
    -2007-03-26,93.99,95.90,93.30,95.85,30892400,95.85
    -2007-03-23,93.35,94.07,93.30,93.52,16103000,93.52
    -2007-03-22,93.73,94.36,93.00,93.96,20053300,93.96
    -2007-03-21,91.99,94.00,91.65,93.87,24532000,93.87
    -2007-03-20,91.35,91.84,91.06,91.48,17461300,91.48
    -2007-03-19,90.24,91.55,89.59,91.13,25462900,91.13
    -2007-03-16,89.54,89.99,89.32,89.59,20418000,89.59
    -2007-03-15,89.96,90.36,89.31,89.57,19982100,89.57
    -2007-03-14,88.60,90.00,87.92,90.00,28449500,90.00
    -2007-03-13,89.41,90.60,88.40,88.40,30996100,88.40
    -2007-03-12,88.07,89.99,87.99,89.87,26050300,89.87
    -2007-03-09,88.80,88.85,87.40,87.97,16137000,87.97
    -2007-03-08,88.59,88.72,87.46,88.00,18250400,88.00
    -2007-03-07,88.05,88.97,87.45,87.72,22367300,87.72
    -2007-03-06,87.80,88.31,87.40,88.19,25828100,88.19
    -2007-03-05,85.89,88.65,85.76,86.32,29960700,86.32
    -2007-03-02,86.77,87.54,85.21,85.41,30714300,85.41
    -2007-03-01,84.03,88.31,83.75,87.06,50554600,87.06
    -2007-02-28,83.00,85.60,83.00,84.61,32838400,84.61
    -2007-02-27,86.30,87.08,83.41,83.93,40921900,83.93
    -2007-02-26,89.84,90.00,87.61,88.51,21994600,88.51
    -2007-02-23,89.16,90.34,88.85,89.07,18496200,89.07
    -2007-02-22,90.80,90.81,88.53,89.51,29936600,89.51
    -2007-02-21,85.98,89.49,85.96,89.20,41261200,89.20
    -2007-02-20,84.65,86.16,84.16,85.90,22060800,85.90
    -2007-02-16,85.25,85.41,84.66,84.83,14281000,84.83
    -2007-02-15,85.44,85.62,84.78,85.21,12987900,85.21
    -2007-02-14,84.63,85.64,84.57,85.30,18142200,85.30
    -2007-02-13,85.16,85.29,84.30,84.70,20749500,84.70
    -2007-02-12,84.43,85.18,83.63,84.88,25859700,84.88
    -2007-02-09,85.88,86.20,83.21,83.27,30733600,83.27
    -2007-02-08,85.43,86.51,85.41,86.18,24251100,86.18
    -2007-02-07,84.48,86.38,83.55,86.15,38100900,86.15
    -2007-02-06,84.45,84.47,82.86,84.15,30871200,84.15
    -2007-02-05,84.30,85.23,83.94,83.94,20673300,83.94
    -2007-02-02,84.12,85.25,83.70,84.75,22197500,84.75
    -2007-02-01,86.23,86.27,84.74,84.74,23726500,84.74
    -2007-01-31,84.86,86.00,84.35,85.73,30573900,85.73
    -2007-01-30,86.43,86.49,85.25,85.55,20641800,85.55
    -2007-01-29,86.30,86.65,85.53,85.94,32202300,85.94
    -2007-01-26,87.11,87.37,84.99,85.38,35245500,85.38
    -2007-01-25,87.11,88.50,86.03,86.25,32356200,86.25
    -2007-01-24,86.68,87.15,86.08,86.70,33136200,86.70
    -2007-01-23,85.73,87.51,85.51,85.70,43122300,85.70
    -2007-01-22,89.14,89.16,85.65,86.79,51929500,86.79
    -2007-01-19,88.63,89.65,88.12,88.50,48731200,88.50
    -2007-01-18,92.10,92.11,89.05,89.07,84450200,89.07
    -2007-01-17,97.56,97.60,94.82,94.95,58795000,94.95
    -2007-01-16,95.68,97.25,95.45,97.10,44431300,97.10
    -2007-01-12,94.59,95.06,93.23,94.62,46881800,94.62
    -2007-01-11,95.94,96.78,95.10,95.80,51437600,95.80
    -2007-01-10,94.75,97.80,93.45,97.00,105460000,97.00
    -2007-01-09,86.45,92.98,85.15,92.57,119617800,92.57
    -2007-01-08,85.96,86.53,85.28,85.47,28468100,85.47
    -2007-01-05,85.77,86.20,84.40,85.05,29812200,85.05
    -2007-01-04,84.05,85.95,83.82,85.66,30259300,85.66
    -2007-01-03,86.29,86.58,81.90,83.80,44225700,83.80
    -2006-12-29,83.95,85.40,83.36,84.84,38443900,84.84
    -2006-12-28,80.22,81.25,79.65,80.87,39995600,80.87
    -2006-12-27,78.15,82.00,76.77,81.52,69134100,81.52
    -2006-12-26,82.15,82.57,80.89,81.51,17524600,81.51
    -2006-12-22,83.46,84.04,81.60,82.20,21903700,82.20
    -2006-12-21,84.70,85.48,82.20,82.90,32271400,82.90
    -2006-12-20,86.47,86.67,84.74,84.76,20274700,84.76
    -2006-12-19,84.73,86.68,83.62,86.31,32550200,86.31
    -2006-12-18,87.63,88.00,84.59,85.47,25770600,85.47
    -2006-12-15,89.02,89.22,87.33,87.72,26426400,87.72
    -2006-12-14,89.05,90.00,88.26,88.55,29726100,88.55
    -2006-12-13,87.95,89.07,87.15,89.05,30609000,89.05
    -2006-12-12,88.61,88.84,85.53,86.14,36665000,86.14
    -2006-12-11,88.90,89.30,88.05,88.75,17849300,88.75
    -2006-12-08,87.23,89.39,87.00,88.26,28009900,88.26
    -2006-12-07,90.03,90.50,86.90,87.04,35886700,87.04
    -2006-12-06,90.64,91.39,89.67,89.83,22792300,89.83
    -2006-12-05,91.65,92.33,90.87,91.27,23672800,91.27
    -2006-12-04,91.88,92.05,90.50,91.12,25340600,91.12
    -2006-12-01,91.80,92.33,90.10,91.32,28395700,91.32
    -2006-11-30,92.21,92.68,91.06,91.66,31088800,91.66
    -2006-11-29,93.00,93.15,90.25,91.80,41324400,91.80
    -2006-11-28,90.36,91.97,89.91,91.81,37006200,91.81
    -2006-11-27,92.51,93.16,89.50,89.54,38387000,89.54
    -2006-11-24,89.53,93.08,89.50,91.63,18524200,91.63
    -2006-11-22,88.99,90.75,87.85,90.31,23997900,90.31
    -2006-11-21,87.42,88.60,87.11,88.60,22238100,88.60
    -2006-11-20,85.40,87.00,85.20,86.47,20385500,86.47
    -2006-11-17,85.14,85.94,85.00,85.85,16658000,85.85
    -2006-11-16,84.87,86.30,84.62,85.61,24783600,85.61
    -2006-11-15,85.05,85.90,84.00,84.05,23404400,84.05
    -2006-11-14,84.80,85.00,83.90,85.00,21034100,85.00
    -2006-11-13,83.22,84.45,82.64,84.35,16095500,84.35
    -2006-11-10,83.55,83.60,82.50,83.12,13352300,83.12
    -2006-11-09,82.90,84.69,82.12,83.34,32966200,83.34
    -2006-11-08,80.02,82.69,79.89,82.45,24675600,82.45
    -2006-11-07,80.45,81.00,80.13,80.51,18783300,80.51
    -2006-11-06,78.95,80.06,78.43,79.71,15520600,79.71
    -2006-11-03,79.36,79.53,77.79,78.29,15424600,78.29
    -2006-11-02,78.92,79.32,78.50,78.98,16624400,78.98
    -2006-11-01,81.10,81.38,78.36,79.16,21828300,79.16
    -2006-10-31,81.45,81.68,80.23,81.08,17909800,81.08
    -2006-10-30,79.99,80.90,79.50,80.42,17854200,80.42
    -2006-10-27,81.75,82.45,80.01,80.41,21248800,80.41
    -2006-10-26,81.90,82.60,81.13,82.19,15455600,82.19
    -2006-10-25,81.35,82.00,81.01,81.68,17329100,81.68
    -2006-10-24,81.21,81.68,80.20,81.05,16543300,81.05
    -2006-10-23,79.99,81.90,79.75,81.46,29732400,81.46
    -2006-10-20,78.97,79.99,78.67,79.95,22836200,79.95
    -2006-10-19,79.26,79.95,78.16,78.99,54034900,78.99
    -2006-10-18,74.75,75.37,73.91,74.53,40496700,74.53
    -2006-10-17,75.04,75.27,74.04,74.29,17175900,74.29
    -2006-10-16,75.19,75.88,74.79,75.40,18167600,75.40
    -2006-10-13,75.63,76.88,74.74,75.02,24435600,75.02
    -2006-10-12,73.61,75.39,73.60,75.26,21173400,75.26
    -2006-10-11,73.42,73.98,72.60,73.23,20423400,73.23
    -2006-10-10,74.54,74.58,73.08,73.81,18985300,73.81
    -2006-10-09,73.80,75.08,73.53,74.63,15650800,74.63
    -2006-10-06,74.42,75.04,73.81,74.22,16677100,74.22
    -2006-10-05,74.53,76.16,74.13,74.83,24424400,74.83
    -2006-10-04,74.10,75.46,73.16,75.38,29610100,75.38
    -2006-10-03,74.45,74.95,73.19,74.08,28239600,74.08
    -2006-10-02,75.10,75.87,74.30,74.86,25451400,74.86
    -2006-09-29,77.11,77.52,76.68,76.98,14493300,76.98
    -2006-09-28,77.02,77.48,75.95,77.01,25843200,77.01
    -2006-09-27,77.17,77.47,75.82,76.41,28941900,76.41
    -2006-09-26,76.18,77.78,76.10,77.61,39391000,77.61
    -2006-09-25,73.81,75.86,73.72,75.75,30678300,75.75
    -2006-09-22,74.30,74.34,72.58,73.00,23754000,73.00
    -2006-09-21,75.25,76.06,74.02,74.65,28361600,74.65
    -2006-09-20,74.38,75.68,74.22,75.26,29385400,75.26
    -2006-09-19,74.10,74.36,72.80,73.77,25358900,73.77
    -2006-09-18,73.80,74.86,73.30,73.89,25188500,73.89
    -2006-09-15,74.60,74.98,73.29,74.10,35066200,74.10
    -2006-09-14,73.72,74.67,73.46,74.17,28633200,74.17
    -2006-09-13,72.85,74.32,72.30,74.20,40933500,74.20
    -2006-09-12,72.81,73.45,71.45,72.63,60167400,72.63
    -2006-09-11,72.43,73.73,71.42,72.50,33897300,72.50
    -2006-09-08,73.37,73.57,71.91,72.52,31997200,72.52
    -2006-09-07,70.60,73.48,70.25,72.80,45284200,72.80
    -2006-09-06,71.08,71.69,69.70,70.03,34789400,70.03
    -2006-09-05,68.97,71.50,68.55,71.48,36159200,71.48
    -2006-09-01,68.48,68.65,67.82,68.38,14589100,68.38
    -2006-08-31,67.28,68.30,66.66,67.85,20524900,67.85
    -2006-08-30,67.34,67.82,66.68,66.96,24290800,66.96
    -2006-08-29,66.99,67.26,65.12,66.48,33833300,66.48
    -2006-08-28,68.50,68.61,66.68,66.98,26362900,66.98
    -2006-08-25,67.34,69.05,67.31,68.75,19427100,68.75
    -2006-08-24,67.89,68.19,66.27,67.81,23399700,67.81
    -2006-08-23,68.00,68.65,66.94,67.31,19152100,67.31
    -2006-08-22,66.68,68.32,66.50,67.62,20606000,67.62
    -2006-08-21,67.30,67.31,66.15,66.56,18793800,66.56
    -2006-08-18,67.71,68.40,67.26,67.91,19155500,67.91
    -2006-08-17,68.00,68.66,67.18,67.59,20755300,67.59
    -2006-08-16,67.10,68.07,66.33,67.98,27903000,67.98
    -2006-08-15,65.34,66.50,64.80,66.45,30762600,66.45
    -2006-08-14,64.05,65.22,63.60,63.94,25629300,63.94
    -2006-08-11,63.23,64.13,62.58,63.65,27768900,63.65
    -2006-08-10,63.25,64.81,62.70,64.07,24920000,64.07
    -2006-08-09,65.43,65.60,63.40,63.59,34137100,63.59
    -2006-08-08,67.09,67.11,64.51,64.78,35638000,64.78
    -2006-08-07,67.72,69.60,66.31,67.21,44482600,67.21
    -2006-08-04,67.05,68.61,64.96,68.30,66173800,68.30
    -2006-08-03,67.91,70.00,67.81,69.59,30037300,69.59
    -2006-08-02,67.65,68.68,67.51,68.16,19670300,68.16
    -2006-08-01,67.22,67.93,65.94,67.18,25420200,67.18
    -2006-07-31,66.83,68.63,66.28,67.96,31887200,67.96
    -2006-07-28,63.94,65.68,63.50,65.59,24696700,65.59
    -2006-07-27,64.50,65.02,62.86,63.40,26251600,63.40
    -2006-07-26,62.00,64.64,61.68,63.87,32086700,63.87
    -2006-07-25,61.78,62.09,60.78,61.93,21038200,61.93
    -2006-07-24,61.26,62.10,60.43,61.42,25816300,61.42
    -2006-07-21,59.82,61.15,59.64,60.72,31853300,60.72
    -2006-07-20,60.96,61.59,59.72,60.50,70433800,60.50
    -2006-07-19,52.96,55.08,52.36,54.10,49669400,54.10
    -2006-07-18,53.16,53.85,51.85,52.90,35730300,52.90
    -2006-07-17,51.73,53.11,51.65,52.37,36590800,52.37
    -2006-07-14,52.50,52.89,50.16,50.67,35465600,50.67
    -2006-07-13,52.03,54.12,51.41,52.25,44639500,52.25
    -2006-07-12,55.17,55.24,52.92,52.96,33118900,52.96
    -2006-07-11,55.11,55.99,54.53,55.65,29465100,55.65
    -2006-07-10,55.70,56.49,54.50,55.00,18905200,55.00
    -2006-07-07,55.48,56.55,54.67,55.40,28548600,55.40
    -2006-07-06,57.09,57.40,55.61,55.77,22614600,55.77
    -2006-07-05,57.15,57.60,56.56,57.00,18508600,57.00
    -2006-07-03,57.52,58.18,57.34,57.95,6956100,57.95
    -2006-06-30,57.59,57.75,56.50,57.27,26417700,57.27
    -2006-06-29,56.76,59.09,56.39,58.97,31192800,58.97
    -2006-06-28,57.29,57.30,55.41,56.02,30382300,56.02
    -2006-06-27,59.09,59.22,57.40,57.43,19664700,57.43
    -2006-06-26,59.17,59.20,58.37,58.99,16662000,58.99
    -2006-06-23,59.72,60.17,58.73,58.83,23578700,58.83
    -2006-06-22,58.20,59.75,58.07,59.58,34486900,59.58
    -2006-06-21,57.74,58.71,57.30,57.86,30832000,57.86
    -2006-06-20,57.61,58.35,57.29,57.47,24034800,57.47
    -2006-06-19,57.83,58.18,57.00,57.20,25163400,57.20
    -2006-06-16,58.96,59.19,57.52,57.56,29932200,57.56
    -2006-06-15,57.30,59.74,56.75,59.38,42513700,59.38
    -2006-06-14,58.28,58.78,56.69,57.61,31362000,57.61
    -2006-06-13,57.61,59.10,57.36,58.33,38594400,58.33
    -2006-06-12,59.40,59.73,56.96,57.00,25635200,57.00
    -2006-06-09,61.18,61.56,59.10,59.24,27708500,59.24
    -2006-06-08,58.44,60.93,57.15,60.76,49910100,60.76
    -2006-06-07,60.10,60.40,58.35,58.56,26803800,58.56
    -2006-06-06,60.22,60.63,58.91,59.72,25929900,59.72
    -2006-06-05,61.15,61.15,59.97,60.00,21635200,60.00
    -2006-06-02,62.99,63.10,60.88,61.66,24492400,61.66
    -2006-06-01,59.85,62.28,59.52,62.17,33661000,62.17
    -2006-05-31,61.76,61.79,58.69,59.77,45749200,59.77
    -2006-05-30,63.29,63.30,61.22,61.22,20121500,61.22
    -2006-05-26,64.31,64.56,63.14,63.55,15462500,63.55
    -2006-05-25,64.26,64.45,63.29,64.33,16549000,64.33
    -2006-05-24,62.99,63.65,61.56,63.34,32715400,63.34
    -2006-05-23,64.86,65.19,63.00,63.15,24800500,63.15
    -2006-05-22,63.87,63.99,62.77,63.38,25677700,63.38
    -2006-05-19,63.26,64.88,62.82,64.51,35209500,64.51
    -2006-05-18,65.68,66.26,63.12,63.18,23515800,63.18
    -2006-05-17,64.71,65.70,64.07,65.26,26935500,65.26
    -2006-05-16,68.10,68.25,64.75,64.98,33455000,64.98
    -2006-05-15,67.37,68.38,67.12,67.79,18899200,67.79
    -2006-05-12,67.85,68.69,66.86,67.70,22920500,67.70
    -2006-05-11,70.79,70.84,67.55,68.15,29024600,68.15
    -2006-05-10,71.29,71.33,69.61,70.60,16424600,70.60
    -2006-05-09,71.82,72.56,70.62,71.03,18988100,71.03
    -2006-05-08,72.99,73.80,71.72,71.89,21244700,71.89
    -2006-05-05,71.86,72.25,71.15,71.89,20139700,71.89
    -2006-05-04,71.22,72.89,70.46,71.13,30729300,71.13
    -2006-05-03,71.83,71.95,70.18,71.14,24535400,71.14
    -2006-05-02,70.15,71.98,70.11,71.62,27559400,71.62
    -2006-05-01,70.77,71.54,69.16,69.60,26799300,69.60
    -2006-04-28,69.38,71.30,69.20,70.39,27144200,70.39
    -2006-04-27,67.73,69.86,67.35,69.36,30212400,69.36
    -2006-04-26,66.65,68.28,66.40,68.15,25388800,68.15
    -2006-04-25,65.96,66.59,65.56,66.17,18895100,66.17
    -2006-04-24,66.85,66.92,65.50,65.75,25251000,65.75
    -2006-04-21,68.19,68.64,66.47,67.04,28178100,67.04
    -2006-04-20,69.51,70.00,66.20,67.63,59535100,67.63
    -2006-04-19,66.82,67.00,65.47,65.65,38786900,65.65
    -2006-04-18,65.04,66.47,64.79,66.22,28387300,66.22
    -2006-04-17,66.51,66.84,64.35,64.81,25783500,64.81
    -2006-04-13,66.34,67.44,65.81,66.47,26238500,66.47
    -2006-04-12,68.01,68.17,66.30,66.71,26424800,66.71
    -2006-04-11,68.99,69.30,67.07,67.99,33547000,67.99
    -2006-04-10,70.29,70.93,68.45,68.67,32268400,68.67
    -2006-04-07,70.93,71.21,68.47,69.79,55187100,69.79
    -2006-04-06,68.30,72.05,68.20,71.24,95134600,71.24
    -2006-04-05,64.71,67.21,64.15,67.21,79764600,67.21
    -2006-04-04,62.10,62.22,61.05,61.17,33283000,61.17
    -2006-04-03,63.67,64.12,62.61,62.65,29135400,62.65
    -2006-03-31,63.25,63.61,62.24,62.72,29119900,62.72
    -2006-03-30,62.82,63.30,61.53,62.75,49666100,62.75
    -2006-03-29,59.13,62.52,57.67,62.33,83815500,62.33
    -2006-03-28,59.63,60.14,58.25,58.71,48940100,58.71
    -2006-03-27,60.35,61.38,59.40,59.51,39574000,59.51
    -2006-03-24,60.25,60.94,59.03,59.96,38285000,59.96
    -2006-03-23,61.82,61.90,59.61,60.16,50993800,60.16
    -2006-03-22,62.16,63.25,61.27,61.67,48067700,61.67
    -2006-03-21,64.29,64.34,61.39,61.81,47991700,61.81
    -2006-03-20,65.22,65.46,63.87,63.99,21622900,63.99
    -2006-03-17,64.75,65.54,64.11,64.66,29001500,64.66
    -2006-03-16,66.85,66.90,64.30,64.31,26772800,64.31
    -2006-03-15,67.71,68.04,65.52,66.23,31857000,66.23
    -2006-03-14,65.77,67.32,65.50,67.32,22929300,67.32
    -2006-03-13,65.05,66.28,64.79,65.68,30756700,65.68
    -2006-03-10,64.05,64.49,62.45,63.19,37255100,63.19
    -2006-03-09,65.98,66.47,63.81,63.93,28546600,63.93
    -2006-03-08,66.29,67.20,65.35,65.66,23330400,65.66
    -2006-03-07,65.76,66.90,65.08,66.31,31174200,66.31
    -2006-03-06,67.69,67.72,64.94,65.48,32595200,65.48
    -2006-03-03,69.40,69.91,67.53,67.72,26345300,67.72
    -2006-03-02,68.99,69.99,68.67,69.61,22331200,69.61
    -2006-03-01,68.84,69.49,68.02,69.10,27279200,69.10
    -2006-02-28,71.58,72.40,68.10,68.49,45249300,68.49
    -2006-02-27,71.99,72.12,70.65,70.99,28258600,70.99
    -2006-02-24,72.14,72.89,71.20,71.46,19098000,71.46
    -2006-02-23,71.79,73.00,71.43,71.75,30604200,71.75
    -2006-02-22,69.00,71.67,68.00,71.32,34937100,71.32
    -2006-02-21,70.59,70.80,68.68,69.08,27843100,69.08
    -2006-02-17,70.30,70.89,69.61,70.29,20571400,70.29
    -2006-02-16,69.91,71.01,69.48,70.57,33863400,70.57
    -2006-02-15,67.16,69.62,66.75,69.22,41420400,69.22
    -2006-02-14,65.10,68.10,65.00,67.64,41462100,67.64
    -2006-02-13,66.63,66.75,64.64,64.71,31553500,64.71
    -2006-02-10,65.18,67.67,62.90,67.31,62874200,67.31
    -2006-02-09,69.10,69.23,64.53,64.95,41063000,64.95
    -2006-02-08,68.49,69.08,66.00,68.81,34039800,68.81
    -2006-02-07,68.27,69.48,66.68,67.60,49601100,67.60
    -2006-02-06,72.02,72.51,66.74,67.30,58991700,67.30
    -2006-02-03,72.24,72.79,71.04,71.85,24718700,71.85
    -2006-02-02,75.10,75.36,72.05,72.10,25261500,72.10
    -2006-02-01,74.95,76.46,74.64,75.42,18613800,75.42
    -2006-01-31,75.50,76.34,73.75,75.51,32626500,75.51
    -2006-01-30,71.17,76.60,70.87,75.00,49942900,75.00
    -2006-01-27,72.95,73.60,71.10,72.03,34066600,72.03
    -2006-01-26,74.53,75.43,71.93,72.33,42192400,72.33
    -2006-01-25,77.39,77.50,73.25,74.20,45563800,74.20
    -2006-01-24,78.76,79.42,75.77,76.04,40794800,76.04
    -2006-01-23,76.10,79.56,76.00,77.67,37847500,77.67
    -2006-01-20,79.28,80.04,75.83,76.09,40527100,76.09
    -2006-01-19,81.25,81.66,78.74,79.04,60566000,79.04
    -2006-01-18,83.08,84.05,81.85,82.49,42879900,82.49
    -2006-01-17,85.70,86.38,83.87,84.71,29843700,84.71
    -2006-01-13,84.99,86.01,84.60,85.59,27725200,85.59
    -2006-01-12,84.97,86.40,83.62,84.29,45743200,84.29
    -2006-01-11,83.84,84.80,82.59,83.90,53349800,83.90
    -2006-01-10,76.25,81.89,75.83,80.86,81423900,80.86
    -2006-01-09,76.73,77.20,75.74,76.05,24108600,76.05
    -2006-01-06,75.25,76.70,74.55,76.30,25159200,76.30
    -2006-01-05,74.83,74.90,73.75,74.38,16050800,74.38
    -2006-01-04,75.13,75.98,74.50,74.97,22128700,74.97
    -2006-01-03,72.38,74.75,72.25,74.75,28829800,74.75
    -2005-12-30,70.91,72.43,70.34,71.89,22295100,71.89
    -2005-12-29,73.78,73.82,71.42,71.45,17500900,71.45
    -2005-12-28,74.47,74.76,73.32,73.57,14218400,73.57
    -2005-12-27,74.00,75.18,73.95,74.23,21092500,74.23
    -2005-12-23,74.17,74.26,73.30,73.35,8209200,73.35
    -2005-12-22,73.91,74.49,73.60,74.02,13236100,74.02
    -2005-12-21,72.60,73.61,72.54,73.50,16990600,73.50
    -2005-12-20,71.63,72.38,71.12,72.11,17111000,72.11
    -2005-12-19,71.11,72.60,71.04,71.38,18903400,71.38
    -2005-12-16,72.14,72.30,71.06,71.11,23970400,71.11
    -2005-12-15,72.68,72.86,71.35,72.18,20041500,72.18
    -2005-12-14,72.53,73.30,70.27,72.01,51811300,72.01
    -2005-12-13,74.85,75.46,74.21,74.98,17636300,74.98
    -2005-12-12,74.87,75.35,74.56,74.91,18749800,74.91
    -2005-12-09,74.21,74.59,73.35,74.33,19835800,74.33
    -2005-12-08,73.20,74.17,72.60,74.08,28231500,74.08
    -2005-12-07,74.23,74.46,73.12,73.95,24266600,73.95
    -2005-12-06,73.93,74.83,73.35,74.05,30608200,74.05
    -2005-12-05,71.95,72.53,71.49,71.82,20845400,71.82
    -2005-12-02,72.27,72.74,70.70,72.63,31991500,72.63
    -2005-12-01,68.95,71.73,68.81,71.60,29031900,71.60
    -2005-11-30,68.43,68.85,67.52,67.82,21274100,67.82
    -2005-11-29,69.99,70.30,67.35,68.10,31836900,68.10
    -2005-11-28,70.72,71.07,69.07,69.66,36375700,69.66
    -2005-11-25,67.66,69.54,67.50,69.34,14107600,69.34
    -2005-11-23,66.88,67.98,66.69,67.11,17351900,67.11
    -2005-11-22,64.84,66.76,64.52,66.52,19295800,66.52
    -2005-11-21,64.82,65.19,63.72,64.96,18275400,64.96
    -2005-11-18,65.31,65.43,64.37,64.56,18748700,64.56
    -2005-11-17,65.59,65.88,64.25,64.52,24150200,64.52
    -2005-11-16,63.15,65.06,63.09,64.95,28018400,64.95
    -2005-11-15,61.60,63.08,61.46,62.28,19172900,62.28
    -2005-11-14,61.54,61.98,60.91,61.45,13211900,61.45
    -2005-11-11,61.54,62.11,61.34,61.54,15194600,61.54
    -2005-11-10,60.64,61.20,59.01,61.18,23762300,61.18
    -2005-11-09,60.00,61.21,60.00,60.11,19747500,60.11
    -2005-11-08,59.95,60.38,59.10,59.90,16920200,59.90
    -2005-11-07,60.85,61.67,60.14,60.23,22815400,60.23
    -2005-11-04,60.35,61.24,59.62,61.15,31358400,61.15
    -2005-11-03,60.26,62.32,60.07,61.85,31585100,61.85
    -2005-11-02,57.72,60.00,57.60,59.95,30609300,59.95
    -2005-11-01,57.24,58.14,56.87,57.50,26774500,57.50
    -2005-10-31,55.20,57.98,54.75,57.59,33601600,57.59
    -2005-10-28,56.04,56.43,54.17,54.47,27492400,54.47
    -2005-10-27,56.99,57.01,55.41,55.41,14697900,55.41
    -2005-10-26,56.28,57.56,55.92,57.03,22556900,57.03
    -2005-10-25,56.40,56.85,55.69,56.10,16611700,56.10
    -2005-10-24,55.25,56.79,55.09,56.79,21776900,56.79
    -2005-10-21,56.84,56.98,55.36,55.66,28454500,55.66
    -2005-10-20,54.47,56.50,54.35,56.14,48491500,56.14
    -2005-10-19,52.07,54.96,51.21,54.94,36024400,54.94
    -2005-10-18,53.25,53.95,52.20,52.21,21771000,52.21
    -2005-10-17,53.98,54.23,52.68,53.44,22029800,53.44
    -2005-10-14,54.03,54.35,52.79,54.00,36984000,54.00
    -2005-10-13,49.44,53.95,49.27,53.74,66627700,53.74
    -2005-10-12,48.65,50.30,47.87,49.25,96338800,49.25
    -2005-10-11,51.23,51.87,50.40,51.59,43781600,51.59
    -2005-10-10,51.76,51.91,50.28,50.37,18125200,50.37
    -2005-10-07,51.72,51.93,50.55,51.30,24210100,51.30
    -2005-10-06,53.20,53.49,50.87,51.70,27054900,51.70
    -2005-10-05,54.33,54.36,52.75,52.78,21813200,52.78
    -2005-10-04,54.95,55.35,53.64,53.75,19266400,53.75
    -2005-10-03,54.16,54.54,53.68,54.44,18126900,54.44
    -2005-09-30,52.33,53.65,51.88,53.61,18986900,53.61
    -2005-09-29,51.23,52.59,50.81,52.34,22744500,52.34
    -2005-09-28,53.07,53.11,50.59,51.08,40198000,51.08
    -2005-09-27,53.92,54.24,53.43,53.44,12203700,53.44
    -2005-09-26,54.03,54.56,53.32,53.84,19520100,53.84
    -2005-09-23,52.10,53.50,51.84,53.20,19944900,53.20
    -2005-09-22,51.88,52.47,51.32,51.90,16561700,51.90
    -2005-09-21,52.96,53.05,51.86,52.11,15526700,52.11
    -2005-09-20,52.99,53.81,52.92,53.19,29279600,53.19
    -2005-09-19,51.05,52.89,51.05,52.64,27990400,52.64
    -2005-09-16,50.23,51.21,49.95,51.21,21107300,51.21
    -2005-09-15,50.00,50.18,49.33,49.87,14827000,49.87
    -2005-09-14,51.06,51.19,49.46,49.61,16943800,49.61
    -2005-09-13,51.02,51.29,50.32,50.82,17603000,50.82
    -2005-09-12,51.10,51.63,50.58,51.40,16171300,51.40
    -2005-09-09,50.07,51.35,49.79,51.31,21987200,51.31
    -2005-09-08,49.35,50.12,49.14,49.78,25094300,49.78
    -2005-09-07,49.05,49.40,47.92,48.68,34395500,48.68
    -2005-09-06,46.70,48.88,46.55,48.80,29236400,48.80
    -2005-09-02,46.30,46.80,46.12,46.22,7942100,46.22
    -2005-09-01,47.00,47.17,46.09,46.26,12727400,46.26
    -2005-08-31,46.86,47.03,46.27,46.89,14391300,46.89
    -2005-08-30,45.99,46.79,45.92,46.57,18527200,46.57
    -2005-08-29,45.27,46.03,45.26,45.84,9153400,45.84
    -2005-08-26,46.12,46.34,45.36,45.74,9323500,45.74
    -2005-08-25,46.12,46.49,45.81,46.06,9866200,46.06
    -2005-08-24,45.60,47.12,45.59,45.77,20431100,45.77
    -2005-08-23,45.85,46.10,45.32,45.74,10557300,45.74
    -2005-08-22,46.15,46.75,45.26,45.87,13847600,45.87
    -2005-08-19,46.28,46.70,45.77,45.83,13448900,45.83
    -2005-08-18,46.91,47.00,45.75,46.30,15805700,46.30
    -2005-08-17,46.40,47.44,46.37,47.15,17847300,47.15
    -2005-08-16,47.39,47.50,46.21,46.25,19200800,46.25
    -2005-08-15,46.48,48.33,46.45,47.68,38811700,47.68
    -2005-08-12,43.46,46.22,43.36,46.10,32715600,46.10
    -2005-08-11,43.39,44.12,43.25,44.00,9713700,44.00
    -2005-08-10,44.00,44.39,43.31,43.38,12890900,43.38
    -2005-08-09,42.93,43.89,42.91,43.82,13601400,43.82
    -2005-08-08,43.00,43.25,42.61,42.65,6299400,42.65
    -2005-08-05,42.49,43.36,42.02,42.99,8640400,42.99
    -2005-08-04,42.89,43.00,42.29,42.71,9618000,42.71
    -2005-08-03,43.19,43.31,42.77,43.22,9225800,43.22
    -2005-08-02,42.89,43.50,42.61,43.19,10602700,43.19
    -2005-08-01,42.57,43.08,42.08,42.75,11223200,42.75
    -2005-07-29,43.56,44.38,42.26,42.65,20074300,42.65
    -2005-07-28,43.85,44.00,43.30,43.80,8975400,43.80
    -2005-07-27,43.83,44.07,42.67,43.99,10133900,43.99
    -2005-07-26,44.01,44.11,43.36,43.63,9592600,43.63
    -2005-07-25,43.99,44.28,43.73,43.81,10522400,43.81
    -2005-07-22,43.44,44.00,43.39,44.00,10753800,44.00
    -2005-07-21,43.70,44.04,42.90,43.29,14438000,43.29
    -2005-07-20,42.86,43.80,42.65,43.63,16192700,43.63
    -2005-07-19,41.52,43.23,41.07,43.19,23966500,43.19
    -2005-07-18,41.41,42.10,41.37,41.49,20939200,41.49
    -2005-07-15,40.97,41.57,40.46,41.55,24560100,41.55
    -2005-07-14,40.79,42.01,40.23,40.75,74859300,40.75
    -2005-07-13,38.29,38.50,37.90,38.35,24458400,38.35
    -2005-07-12,38.23,38.40,37.91,38.24,13822800,38.24
    -2005-07-11,38.37,38.65,37.78,38.10,13885300,38.10
    -2005-07-08,37.87,38.28,37.47,38.25,10383400,38.25
    -2005-07-07,36.81,37.76,36.80,37.63,13704400,37.63
    -2005-07-06,37.71,38.16,37.20,37.39,14093800,37.39
    -2005-07-05,36.55,38.15,36.50,37.98,16223900,37.98
    -2005-07-01,36.83,36.97,36.29,36.50,8928600,36.50
    -2005-06-30,36.61,37.16,36.31,36.81,14942500,36.81
    -2005-06-29,37.23,37.29,36.12,36.37,16012800,36.37
    -2005-06-28,37.49,37.59,37.17,37.31,12510700,37.31
    -2005-06-27,36.84,38.10,36.68,37.10,21434700,37.10
    -2005-06-24,39.09,39.12,37.68,37.76,14668200,37.76
    -2005-06-23,38.83,39.78,38.65,38.89,24080500,38.89
    -2005-06-22,38.26,38.60,38.14,38.55,15175900,38.55
    -2005-06-21,37.72,38.19,37.38,37.86,13233100,37.86
    -2005-06-20,37.85,38.09,37.45,37.61,11561300,37.61
    -2005-06-17,38.47,38.54,37.83,38.31,21290200,38.31
    -2005-06-16,37.19,38.08,36.82,37.98,19559800,37.98
    -2005-06-15,36.87,37.30,36.30,37.13,20119400,37.13
    -2005-06-14,35.92,36.15,35.75,36.00,12423100,36.00
    -2005-06-13,35.89,36.61,35.82,35.90,15563300,35.90
    -2005-06-10,37.40,37.40,35.52,35.81,24247600,35.81
    -2005-06-09,37.00,37.94,36.82,37.65,13937700,37.65
    -2005-06-08,36.63,37.25,36.57,36.92,14428800,36.92
    -2005-06-07,37.60,37.73,36.45,36.54,26616600,36.54
    -2005-06-06,38.33,38.63,37.56,37.92,28998800,37.92
    -2005-06-03,38.16,38.58,37.77,38.24,34173900,38.24
    -2005-06-02,40.05,40.32,39.60,40.04,13356200,40.04
    -2005-06-01,39.89,40.76,39.86,40.30,16207600,40.30
    -2005-05-31,40.66,40.74,39.58,39.76,14435900,39.76
    -2005-05-27,40.64,40.79,40.01,40.56,11286000,40.56
    -2005-05-26,39.94,40.94,39.94,40.74,18768600,40.74
    -2005-05-25,39.50,39.95,39.32,39.78,14143100,39.78
    -2005-05-24,39.45,39.99,39.03,39.70,21195000,39.70
    -2005-05-23,37.85,39.90,37.85,39.76,37234800,39.76
    -2005-05-20,37.25,37.65,37.19,37.55,16166100,37.55
    -2005-05-19,35.78,37.68,35.78,37.55,28327200,37.55
    -2005-05-18,35.45,37.56,34.99,35.84,22740100,35.84
    -2005-05-17,35.14,35.46,34.54,35.36,21012300,35.36
    -2005-05-16,34.56,35.70,34.53,35.55,16939100,35.55
    -2005-05-13,34.20,35.23,34.07,34.77,25096900,34.77
    -2005-05-12,35.42,35.59,34.00,34.13,34651500,34.13
    -2005-05-11,35.20,35.67,33.11,35.61,72927900,35.61
    -2005-05-10,36.75,37.25,36.33,36.42,15723700,36.42
    -2005-05-09,37.28,37.45,36.75,36.97,12703400,36.97
    -2005-05-06,36.89,37.33,36.79,37.24,11651700,37.24
    -2005-05-05,37.25,37.27,36.47,36.68,13834500,36.68
    -2005-05-04,36.11,37.20,36.10,37.15,16006300,37.15
    -2005-05-03,36.40,36.74,36.03,36.21,17740700,36.21
    -2005-05-02,36.21,36.65,36.02,36.43,16640000,36.43
    -2005-04-29,36.15,36.23,35.22,36.06,23986800,36.06
    -2005-04-28,36.29,36.34,35.24,35.54,20539500,35.54
    -2005-04-27,35.89,36.36,35.51,35.95,21924600,35.95
    -2005-04-26,36.78,37.51,36.12,36.19,28946700,36.19
    -2005-04-25,36.49,37.02,36.11,36.98,26659300,36.98
    -2005-04-22,36.84,37.00,34.90,35.50,29968900,35.50
    -2005-04-21,36.40,37.21,35.90,37.18,27128300,37.18
    -2005-04-20,37.66,37.74,35.44,35.51,33754700,35.51
    -2005-04-19,36.60,37.44,35.87,37.09,38630100,37.09
    -2005-04-18,35.00,36.30,34.00,35.62,47399200,35.62
    -2005-04-15,36.62,37.25,35.28,35.35,61717400,35.35
    -2005-04-14,38.81,39.56,36.84,37.26,98328300,37.26
    -2005-04-13,42.95,42.99,40.39,41.04,48998100,41.04
    -2005-04-12,42.49,43.19,42.01,42.66,35037900,42.66
    -2005-04-11,44.15,44.25,41.91,41.92,29345100,41.92
    -2005-04-08,43.70,44.45,43.54,43.74,23212500,43.74
    -2005-04-07,42.33,43.75,42.25,43.56,18106700,43.56
    -2005-04-06,42.40,42.81,42.15,42.33,14815200,42.33
    -2005-04-05,41.22,42.24,41.09,41.89,19865700,41.89
    -2005-04-04,40.99,41.31,40.16,41.09,20714800,41.09
    -2005-04-01,42.09,42.18,40.57,40.89,22903000,40.89
    -2005-03-31,42.45,42.52,41.59,41.67,22719100,41.67
    -2005-03-30,42.07,42.80,41.82,42.80,14105700,42.80
    -2005-03-29,42.56,42.83,41.50,41.75,16477000,41.75
    -2005-03-28,42.75,42.96,42.47,42.53,9836100,42.53
    -2005-03-24,42.91,43.00,42.50,42.50,12596600,42.50
    -2005-03-23,42.45,43.40,42.02,42.55,21779400,42.55
    -2005-03-22,43.71,43.96,42.68,42.83,19693400,42.83
    -2005-03-21,43.29,43.97,42.86,43.70,19326000,43.70
    -2005-03-18,43.33,43.44,42.50,42.96,33576800,42.96
    -2005-03-17,41.53,42.88,41.32,42.25,28640000,42.25
    -2005-03-16,41.21,42.31,40.78,41.18,24921900,41.18
    -2005-03-15,40.64,41.14,40.25,40.96,18164600,40.96
    -2005-03-14,40.52,40.79,39.52,40.32,21620900,40.32
    -2005-03-11,40.21,40.59,39.80,40.27,22601100,40.27
    -2005-03-10,39.53,40.26,39.10,39.83,27753900,39.83
    -2005-03-09,39.64,40.28,38.83,39.35,47230900,39.35
    -2005-03-08,41.90,42.16,40.10,40.53,36480400,40.53
    -2005-03-07,42.80,43.25,42.35,42.75,16094000,42.75
    -2005-03-04,42.76,43.01,41.85,42.81,27022100,42.81
    -2005-03-03,44.37,44.41,41.22,41.79,50416200,41.79
    -2005-03-02,44.25,44.89,44.08,44.12,16362900,44.12
    -2005-03-01,44.99,45.11,44.16,44.50,16721000,44.50
    -2005-02-28,44.68,45.14,43.96,44.86,23271800,44.86
    -2005-02-25,89.62,89.91,88.19,88.99,32696800,44.49
    -2005-02-24,88.48,89.31,87.73,88.93,54251000,44.47
    -2005-02-23,86.72,88.45,85.55,88.23,48042200,44.12
    -2005-02-22,86.30,88.30,85.29,85.29,43546200,42.65
    -2005-02-18,87.74,87.86,86.25,86.81,41544800,43.40
    -2005-02-17,90.65,90.88,87.45,87.81,54231200,43.90
    -2005-02-16,88.15,90.20,87.35,90.13,58544400,45.06
    -2005-02-15,86.66,89.08,86.00,88.41,82579200,44.21
    -2005-02-14,82.73,84.79,82.05,84.63,45409400,42.31
    -2005-02-11,79.86,81.76,78.94,81.21,42894800,40.60
    -2005-02-10,78.72,79.28,76.66,78.36,39036400,39.18
    -2005-02-09,81.04,81.99,78.10,78.74,42552000,39.37
    -2005-02-08,79.07,81.38,78.79,80.90,31786400,40.45
    -2005-02-07,78.93,79.35,77.50,78.94,18730600,39.47
    -2005-02-04,77.87,78.93,77.53,78.84,20127000,39.42
    -2005-02-03,79.10,79.43,77.33,77.81,26130400,38.90
    -2005-02-02,77.95,79.91,77.69,79.63,36430800,39.81
    -2005-02-01,77.05,77.77,76.58,77.53,24228400,38.76
    -2005-01-31,74.58,77.89,74.51,76.90,60039200,38.45
    -2005-01-28,72.62,73.98,72.44,73.98,28629000,36.99
    -2005-01-27,72.16,72.92,71.55,72.64,17722400,36.32
    -2005-01-26,72.66,72.75,71.22,72.25,26410600,36.12
    -2005-01-25,71.37,72.84,70.94,72.05,34615400,36.03
    -2005-01-24,70.98,71.78,70.55,70.76,30058200,35.38
    -2005-01-21,71.31,71.60,70.00,70.49,32547600,35.24
    -2005-01-20,69.65,71.27,69.47,70.46,32675800,35.23
    -2005-01-19,70.49,71.46,69.75,69.88,26853400,34.94
    -2005-01-18,69.85,70.70,67.75,70.65,35945000,35.33
    -2005-01-14,70.25,71.72,69.19,70.20,63240800,35.10
    -2005-01-13,73.71,74.42,69.73,69.80,113025600,34.90
    -2005-01-12,65.45,65.90,63.30,65.46,68560800,32.73
    -2005-01-11,68.25,69.15,64.14,64.56,93272400,32.28
    -2005-01-10,69.83,70.70,67.88,68.96,61618200,34.48
    -2005-01-07,65.00,69.63,64.75,69.25,79551800,34.62
    -2005-01-06,64.67,64.91,63.33,64.55,25198400,32.28
    -2005-01-05,64.46,65.25,64.05,64.50,24301200,32.25
    -2005-01-04,63.79,65.47,62.97,63.94,39171800,31.97
    -2005-01-03,64.78,65.11,62.60,63.29,24714000,31.65
    -2004-12-31,64.89,65.00,64.03,64.40,9949600,32.20
    -2004-12-30,64.81,65.03,64.22,64.80,12333600,32.40
    -2004-12-29,63.81,64.98,63.57,64.44,16055800,32.22
    -2004-12-28,63.30,64.25,62.05,64.18,21848400,32.09
    -2004-12-27,64.80,65.15,62.88,63.16,19981800,31.58
    -2004-12-23,63.75,64.25,63.60,64.01,8783200,32.01
    -2004-12-22,63.66,64.36,63.40,63.75,20208200,31.88
    -2004-12-21,63.56,63.77,61.60,63.69,38014800,31.84
    -2004-12-20,65.47,66.00,61.76,62.72,41718800,31.36
    -2004-12-17,66.84,67.04,64.90,64.99,27982000,32.49
    -2004-12-16,66.15,67.50,66.05,66.60,40218400,33.30
    -2004-12-15,65.24,65.46,64.66,65.26,14227200,32.63
    -2004-12-14,65.40,65.88,65.02,65.29,14847200,32.65
    -2004-12-13,65.62,65.90,64.60,64.91,14108600,32.46
    -2004-12-10,65.03,66.05,64.70,65.15,27706200,32.58
    -2004-12-09,62.81,64.40,62.07,63.99,26482200,32.00
    -2004-12-08,63.08,64.43,62.05,63.28,24710800,31.64
    -2004-12-07,65.93,66.73,62.56,62.89,37746400,31.44
    -2004-12-06,64.25,66.24,62.95,65.78,44568600,32.89
    -2004-12-03,64.53,65.00,61.75,62.68,44244600,31.34
    -2004-12-02,66.13,66.90,64.66,65.21,35265800,32.60
    -2004-12-01,67.79,67.95,66.27,67.79,28591200,33.90
    -2004-11-30,68.79,68.79,67.05,67.05,36732800,33.53
    -2004-11-29,68.95,69.57,67.41,68.44,61175600,34.22
    -2004-11-26,65.35,65.76,64.34,64.55,19648000,32.28
    -2004-11-24,61.69,65.20,61.55,64.05,49671000,32.03
    -2004-11-23,62.30,62.45,61.05,61.27,32551800,30.64
    -2004-11-22,61.80,64.00,57.90,61.35,91721800,30.67
    -2004-11-19,55.49,56.91,54.50,55.17,27331400,27.58
    -2004-11-18,54.30,55.45,54.29,55.39,16398200,27.69
    -2004-11-17,55.19,55.45,54.22,54.90,14205400,27.45
    -2004-11-16,55.16,55.20,54.48,54.94,10539400,27.47
    -2004-11-15,55.20,55.46,54.34,55.24,13430200,27.62
    -2004-11-12,55.01,55.69,54.84,55.50,14132200,27.75
    -2004-11-11,54.95,55.43,54.23,55.30,14546400,27.65
    -2004-11-10,53.95,55.39,53.91,54.75,18167000,27.38
    -2004-11-09,54.23,54.55,53.38,54.05,16991600,27.02
    -2004-11-08,54.27,55.45,53.86,54.38,18818600,27.19
    -2004-11-05,54.86,55.00,52.04,54.72,43037400,27.36
    -2004-11-04,55.03,55.55,54.37,54.45,33165200,27.23
    -2004-11-03,54.37,56.11,53.99,55.31,43006200,27.66
    -2004-11-02,52.40,54.08,52.40,53.50,26071000,26.75
    -2004-11-01,52.50,53.26,52.04,52.45,21501800,26.23
    -2004-10-29,51.84,53.20,51.80,52.40,28936400,26.20
    -2004-10-28,49.98,52.22,49.50,52.19,30866600,26.09
    -2004-10-27,48.51,50.62,48.17,50.30,42624800,25.15
    -2004-10-26,47.45,48.05,46.97,47.97,21227200,23.99
    -2004-10-25,47.20,47.84,47.07,47.55,14023000,23.77
    -2004-10-22,47.54,47.67,47.02,47.41,17252400,23.70
    -2004-10-21,47.48,48.13,47.36,47.94,25875200,23.97
    -2004-10-20,47.18,47.60,46.65,47.47,21611000,23.74
    -2004-10-19,48.10,48.35,47.31,47.42,28642600,23.71
    -2004-10-18,44.70,47.75,44.70,47.75,42884000,23.88
    -2004-10-15,44.88,45.61,44.19,45.50,36826000,22.75
    -2004-10-14,43.19,45.75,42.55,44.98,98872400,22.49
    -2004-10-13,38.87,39.76,38.74,39.75,41536000,19.88
    -2004-10-12,38.50,38.58,37.65,38.29,16435400,19.15
    -2004-10-11,38.80,39.06,38.20,38.59,11566800,19.30
    -2004-10-08,39.56,39.77,38.84,39.06,12829600,19.53
    -2004-10-07,40.54,40.93,39.46,39.62,15219600,19.81
    -2004-10-06,39.50,40.76,39.47,40.64,15939400,20.32
    -2004-10-05,38.56,39.67,38.40,39.37,14505800,19.68
    -2004-10-04,39.18,39.18,38.75,38.79,20503000,19.40
    -2004-10-01,39.12,39.19,38.58,38.67,16621600,19.33
    -2004-09-30,39.00,39.27,38.45,38.75,15179000,19.38
    -2004-09-29,37.93,38.86,37.82,38.68,9768200,19.34
    -2004-09-28,37.46,38.29,37.45,38.04,12613800,19.02
    -2004-09-27,36.95,37.98,36.83,37.53,14197000,18.76
    -2004-09-24,37.45,38.00,37.15,37.29,13196000,18.65
    -2004-09-23,37.04,37.50,36.93,37.27,14193000,18.64
    -2004-09-22,38.10,38.14,36.81,36.92,14346000,18.46
    -2004-09-21,37.75,38.87,37.46,38.01,13809000,19.00
    -2004-09-20,36.88,37.98,36.87,37.71,8750000,18.85
    -2004-09-17,36.55,37.38,36.40,37.14,17939600,18.57
    -2004-09-16,35.20,36.76,35.08,36.35,17925600,18.17
    -2004-09-15,35.36,35.48,34.80,35.20,8309600,17.60
    -2004-09-14,35.24,35.55,34.78,35.49,9100800,17.75
    -2004-09-13,35.88,36.07,35.32,35.59,10070600,17.80
    -2004-09-10,35.66,36.23,35.46,35.87,11714800,17.93
    -2004-09-09,36.10,36.30,35.28,35.70,16476400,17.85
    -2004-09-08,35.70,36.57,35.68,36.35,12268800,18.17
    -2004-09-07,35.40,36.19,35.23,35.76,10784200,17.88
    -2004-09-03,35.01,35.92,35.01,35.23,10481000,17.61
    -2004-09-02,35.50,35.81,34.83,35.66,14511600,17.83
    -2004-09-01,34.30,35.99,34.19,35.86,18418800,17.93
    -2004-08-31,34.07,34.95,34.00,34.49,13448600,17.25
    -2004-08-30,34.00,34.72,33.96,34.12,7790800,17.06
    -2004-08-27,34.68,34.76,34.00,34.35,13886200,17.17
    -2004-08-26,33.04,35.18,32.74,34.66,34137800,17.33
    -2004-08-25,31.87,33.15,31.73,33.05,18057800,16.52
    -2004-08-24,31.26,31.95,31.19,31.95,13362000,15.98
    -2004-08-23,30.86,31.27,30.60,31.08,9095000,15.54
    -2004-08-20,30.71,30.99,30.49,30.80,11313600,15.40
    -2004-08-19,31.51,31.86,30.36,30.71,13890000,15.35
    -2004-08-18,30.51,31.85,30.49,31.74,13023400,15.87
    -2004-08-17,30.58,31.13,30.35,30.87,11536400,15.44
    -2004-08-16,31.00,31.72,30.64,30.78,15559800,15.39
    -2004-08-13,30.60,31.28,30.40,30.84,11716000,15.42
    -2004-08-12,30.45,30.85,30.28,30.37,8078600,15.19
    -2004-08-11,31.10,31.13,30.26,31.01,11514000,15.51
    -2004-08-10,30.39,31.54,30.35,31.52,12537000,15.76
    -2004-08-09,29.85,30.45,29.81,30.30,10387400,15.15
    -2004-08-06,30.90,31.10,29.70,29.78,17581800,14.89
    -2004-08-05,31.81,32.30,31.25,31.39,8732200,15.69
    -2004-08-04,31.19,32.12,31.17,31.79,9874600,15.90
    -2004-08-03,31.45,31.72,31.15,31.29,7558200,15.65
    -2004-08-02,31.18,32.20,31.13,31.58,13039000,15.79
    -2004-07-30,32.65,33.00,32.00,32.34,8679400,16.17
    -2004-07-29,32.47,32.82,32.13,32.64,7934200,16.32
    -2004-07-28,32.31,32.41,31.16,32.27,10180400,16.14
    -2004-07-27,31.80,32.75,31.57,32.43,15178800,16.22
    -2004-07-26,30.85,31.45,30.78,31.26,14069000,15.63
    -2004-07-23,31.53,31.75,30.48,30.70,9770400,15.35
    -2004-07-22,31.25,31.73,31.06,31.68,11932800,15.84
    -2004-07-21,32.42,32.71,31.34,31.62,10759200,15.81
    -2004-07-20,31.95,32.20,31.55,32.20,11562400,16.10
    -2004-07-19,32.01,32.22,31.66,31.97,19041800,15.98
    -2004-07-16,32.80,32.92,32.12,32.20,17442200,16.10
    -2004-07-15,32.66,33.63,32.11,32.93,63133000,16.47
    -2004-07-14,28.86,29.97,28.74,29.58,29850000,14.79
    -2004-07-13,29.25,29.60,29.02,29.22,11292000,14.61
    -2004-07-12,30.02,30.04,28.93,29.14,18272200,14.57
    -2004-07-09,30.27,30.50,30.03,30.03,7459400,15.02
    -2004-07-08,30.13,30.68,29.95,30.14,8335000,15.07
    -2004-07-07,30.85,31.36,30.13,30.39,14214000,15.19
    -2004-07-06,31.27,31.42,30.80,30.95,12463600,15.48
    -2004-07-02,30.48,31.18,29.73,31.08,32524400,15.54
    -2004-07-01,32.10,32.48,31.90,32.30,12212200,16.15
    -2004-06-30,32.56,32.97,31.89,32.54,13323000,16.27
    -2004-06-29,32.07,32.99,31.41,32.50,21091200,16.25
    -2004-06-28,34.18,34.19,32.21,32.49,18610600,16.25
    -2004-06-25,33.07,33.70,33.00,33.70,11551000,16.85
    -2004-06-24,33.51,33.70,32.98,33.18,9018400,16.59
    -2004-06-23,33.00,33.83,32.89,33.70,13959600,16.85
    -2004-06-22,32.30,33.09,32.29,33.00,12875400,16.50
    -2004-06-21,33.12,33.50,32.12,32.33,13936200,16.17
    -2004-06-18,32.66,33.41,32.43,32.91,14509000,16.45
    -2004-06-17,32.56,33.13,32.21,32.81,19690000,16.41
    -2004-06-16,30.66,33.32,30.53,32.74,32487200,16.37
    -2004-06-15,30.54,31.14,30.26,30.69,15879800,15.35
    -2004-06-14,30.65,30.68,29.50,30.12,8713800,15.06
    -2004-06-10,30.20,30.97,30.20,30.74,9199200,15.37
    -2004-06-09,30.09,30.71,30.00,30.20,12471600,15.10
    -2004-06-08,29.99,30.44,29.83,30.35,14843600,15.18
    -2004-06-07,29.04,29.98,28.81,29.81,10567000,14.90
    -2004-06-04,28.56,29.25,28.51,28.78,14254000,14.39
    -2004-06-03,28.72,28.99,28.29,28.40,8961800,14.20
    -2004-06-02,28.03,29.17,27.80,28.92,11382600,14.46
    -2004-06-01,27.79,28.20,27.61,28.06,6504800,14.03
    -2004-05-28,28.08,28.27,27.80,28.06,5204200,14.03
    -2004-05-27,28.46,28.60,27.82,28.17,8427600,14.09
    -2004-05-26,28.33,28.78,28.00,28.51,11506000,14.26
    -2004-05-25,27.50,28.51,27.29,28.41,11427800,14.20
    -2004-05-24,27.29,27.90,27.11,27.34,8414400,13.67
    -2004-05-21,26.90,27.20,26.73,27.11,6424800,13.56
    -2004-05-20,26.63,27.00,26.47,26.71,7010600,13.35
    -2004-05-19,27.40,27.50,26.42,26.47,13414000,13.23
    -2004-05-18,26.97,27.29,26.80,27.06,7359400,13.53
    -2004-05-17,26.70,27.06,26.36,26.64,10730200,13.32
    -2004-05-14,27.25,27.32,26.45,27.06,9207200,13.53
    -2004-05-13,27.10,27.72,26.90,27.19,8209000,13.60
    -2004-05-12,26.79,27.34,26.24,27.30,8765000,13.65
    -2004-05-11,26.40,27.19,26.40,27.14,10899000,13.57
    -2004-05-10,26.27,26.60,25.94,26.28,8927800,13.14
    -2004-05-07,26.55,27.57,26.55,26.67,14965600,13.34
    -2004-05-06,26.40,26.75,25.90,26.58,9412800,13.29
    -2004-05-05,26.20,26.75,25.96,26.65,8503800,13.32
    -2004-05-04,25.97,26.55,25.50,26.14,9999400,13.07
    -2004-05-03,26.00,26.33,25.74,26.07,10629800,13.03
    -2004-04-30,26.71,26.96,25.49,25.78,16660800,12.89
    -2004-04-29,26.45,27.00,25.98,26.77,16456800,13.39
    -2004-04-28,26.82,27.01,26.34,26.45,8256000,13.23
    -2004-04-27,27.24,27.44,26.69,26.94,10138000,13.47
    -2004-04-26,27.58,27.64,27.00,27.13,8254600,13.56
    -2004-04-23,27.70,28.00,27.05,27.70,11279600,13.85
    -2004-04-22,27.56,28.18,27.11,27.78,12306600,13.89
    -2004-04-21,27.60,28.12,27.37,27.73,11638400,13.86
    -2004-04-20,28.21,28.41,27.56,27.73,12661400,13.86
    -2004-04-19,28.12,28.75,27.83,28.35,25441200,14.18
    -2004-04-16,29.15,29.31,28.50,29.18,14390400,14.59
    -2004-04-15,28.82,29.58,28.16,29.30,62908800,14.65
    -2004-04-14,26.74,27.07,26.31,26.64,22847600,13.32
    -2004-04-13,27.98,28.03,26.84,26.93,15585600,13.47
    -2004-04-12,27.50,28.10,27.49,28.04,8233600,14.02
    -2004-04-08,27.88,28.00,27.20,27.53,8604200,13.77
    -2004-04-07,27.61,27.70,26.92,27.31,9111400,13.65
    -2004-04-06,27.71,28.15,27.43,27.83,9214000,13.91
    -2004-04-05,27.48,28.37,27.44,28.32,13774000,14.16
    -2004-04-02,27.75,27.93,27.23,27.50,9802800,13.75
    -2004-04-01,26.89,27.27,26.62,27.11,11369000,13.56
    -2004-03-31,27.92,27.98,26.95,27.04,13956200,13.52
    -2004-03-30,27.74,27.95,27.34,27.92,12845600,13.96
    -2004-03-29,27.37,27.99,27.20,27.91,12526000,13.95
    -2004-03-26,27.00,27.36,26.91,27.04,14996200,13.52
    -2004-03-25,26.14,26.91,25.89,26.87,20230200,13.44
    -2004-03-24,25.27,25.75,25.27,25.50,15293400,12.75
    -2004-03-23,25.88,26.00,25.22,25.29,13768400,12.65
    -2004-03-22,25.37,26.17,25.25,25.86,14965400,12.93
    -2004-03-19,25.56,26.94,25.54,25.86,14592000,12.93
    -2004-03-18,25.94,26.06,25.59,25.67,11467200,12.84
    -2004-03-17,25.96,26.38,25.78,26.19,14694000,13.10
    -2004-03-16,26.55,26.61,25.39,25.82,21622600,12.91
    -2004-03-15,27.03,27.35,26.26,26.45,17204200,13.23
    -2004-03-12,27.32,27.78,27.17,27.56,11758000,13.78
    -2004-03-11,27.27,28.04,27.09,27.15,21280400,13.57
    -2004-03-10,27.04,28.14,26.94,27.68,35963000,13.84
    -2004-03-09,25.90,27.23,25.75,27.10,22084400,13.55
    -2004-03-08,26.62,26.79,25.80,26.00,18674000,13.00
    -2004-03-05,24.95,27.49,24.90,26.74,55021400,13.37
    -2004-03-04,23.93,25.22,23.91,25.16,23579400,12.58
    -2004-03-03,23.60,24.19,23.60,23.92,8040400,11.96
    -2004-03-02,24.00,24.10,23.77,23.81,9167400,11.90
    -2004-03-01,24.10,24.30,23.87,24.02,11488600,12.01
    -2004-02-27,22.96,24.02,22.95,23.92,16744200,11.96
    -2004-02-26,22.88,23.18,22.80,23.04,7086000,11.52
    -2004-02-25,22.28,22.90,22.21,22.81,9867000,11.40
    -2004-02-24,22.14,22.74,22.00,22.36,9252000,11.18
    -2004-02-23,22.34,22.46,21.89,22.19,6931400,11.10
    -2004-02-20,22.50,22.51,22.21,22.40,9914400,11.20
    -2004-02-19,23.33,23.64,22.41,22.47,11538600,11.23
    -2004-02-18,23.18,23.44,23.05,23.26,5058400,11.63
    -2004-02-17,23.10,23.49,23.10,23.16,6105600,11.58
    -2004-02-13,23.85,24.10,22.83,23.00,11285000,11.50
    -2004-02-12,23.61,23.99,23.60,23.73,6571000,11.86
    -2004-02-11,23.09,23.87,23.05,23.80,12448000,11.90
    -2004-02-10,22.62,23.12,22.44,22.98,9119400,11.49
    -2004-02-09,22.62,22.86,22.50,22.67,6723600,11.34
    -2004-02-06,22.45,22.89,22.40,22.71,6905000,11.35
    -2004-02-05,21.82,22.91,21.81,22.42,12601600,11.21
    -2004-02-04,22.00,22.09,21.70,21.79,10912600,10.90
    -2004-02-03,22.30,22.40,22.00,22.26,6457600,11.13
    -2004-02-02,22.46,22.81,22.08,22.32,10265400,11.16
    -2004-01-30,22.65,22.87,22.42,22.56,6617800,11.28
    -2004-01-29,22.63,22.80,22.19,22.68,7596400,11.34
    -2004-01-28,22.84,23.38,22.41,22.52,9835800,11.26
    -2004-01-27,23.04,23.25,22.80,23.07,10966800,11.53
    -2004-01-26,22.46,23.06,22.43,23.01,9688200,11.51
    -2004-01-23,22.42,22.74,22.25,22.56,8113200,11.28
    -2004-01-22,22.56,22.83,22.18,22.18,7321600,11.09
    -2004-01-21,22.70,22.97,22.43,22.61,8095000,11.31
    -2004-01-20,22.67,22.80,22.25,22.73,11283800,11.36
    -2004-01-16,22.89,23.04,22.61,22.72,13315000,11.36
    -2004-01-15,22.91,23.40,22.50,22.85,36364600,11.43
    -2004-01-14,24.40,24.54,23.78,24.20,22144400,12.10
    -2004-01-13,24.70,24.84,23.86,24.12,24250600,12.06
    -2004-01-12,23.25,24.00,23.10,23.73,17412400,11.86
    -2004-01-09,23.23,24.13,22.79,23.00,15266400,11.50
    -2004-01-08,22.84,23.73,22.65,23.36,16439400,11.68
    -2004-01-07,22.10,22.83,21.93,22.59,20959800,11.30
    -2004-01-06,22.25,22.42,21.71,22.09,18191000,11.05
    -2004-01-05,21.42,22.39,21.42,22.17,14107800,11.09
    -2004-01-02,21.55,21.75,21.18,21.28,5165800,10.64
    -2003-12-31,21.35,21.53,21.18,21.37,6230400,10.69
    -2003-12-30,21.18,21.50,21.15,21.28,7316200,10.64
    -2003-12-29,20.91,21.16,20.86,21.15,8337800,10.57
    -2003-12-26,20.35,20.91,20.34,20.78,3703400,10.39
    -2003-12-24,19.72,20.59,19.65,20.41,6338400,10.20
    -2003-12-23,19.92,19.95,19.60,19.81,11017800,9.90
    -2003-12-22,19.65,19.89,19.25,19.85,13466600,9.93
    -2003-12-19,20.19,20.42,19.62,19.70,16198600,9.85
    -2003-12-18,19.90,20.18,19.90,20.04,11818400,10.02
    -2003-12-17,20.08,20.13,19.79,19.88,9795000,9.94
    -2003-12-16,20.19,20.49,20.01,20.12,13355600,10.06
    -2003-12-15,21.49,21.49,20.07,20.17,13889600,10.09
    -2003-12-12,21.32,21.32,20.70,20.89,6881200,10.44
    -2003-12-11,20.25,21.34,20.21,21.21,6540600,10.60
    -2003-12-10,20.45,20.61,19.96,20.38,9690600,10.19
    -2003-12-09,21.17,21.25,20.40,20.45,4826600,10.23
    -2003-12-08,20.78,21.08,20.41,21.05,5294200,10.52
    -2003-12-05,20.90,21.15,20.73,20.85,6649200,10.43
    -2003-12-04,20.94,21.17,20.77,21.15,6355000,10.57
    -2003-12-03,21.54,21.84,20.96,21.03,6832000,10.52
    -2003-12-02,21.60,21.90,21.41,21.54,7332000,10.77
    -2003-12-01,21.04,21.85,21.00,21.71,12912000,10.85
    -2003-11-28,20.78,21.07,20.52,20.91,2717800,10.45
    -2003-11-26,20.89,21.15,20.25,20.72,8754600,10.36
    -2003-11-25,21.23,21.25,20.61,20.68,9594800,10.34
    -2003-11-24,20.50,21.27,20.45,21.15,13636600,10.57
    -2003-11-21,20.34,20.58,19.85,20.28,8637000,10.14
    -2003-11-20,20.10,21.08,20.10,20.38,8556800,10.19
    -2003-11-19,20.56,20.65,20.26,20.42,12306600,10.21
    -2003-11-18,21.21,21.34,20.35,20.41,9542600,10.20
    -2003-11-17,21.35,21.37,20.95,21.13,8152000,10.56
    -2003-11-14,22.48,22.61,21.28,21.46,8466000,10.73
    -2003-11-13,22.07,22.56,21.92,22.42,7599000,11.21
    -2003-11-12,21.48,22.72,21.48,22.33,10714400,11.16
    -2003-11-11,21.90,22.02,21.48,21.54,7681200,10.77
    -2003-11-10,22.45,22.65,21.84,21.90,8367000,10.95
    -2003-11-07,23.19,23.24,22.45,22.50,7505200,11.25
    -2003-11-06,22.91,23.15,22.65,23.12,14181200,11.56
    -2003-11-05,22.82,23.13,22.47,23.03,11516800,11.52
    -2003-11-04,23.07,23.10,22.59,22.91,8901200,11.45
    -2003-11-03,22.83,23.30,22.78,23.15,10815800,11.57
    -2003-10-31,23.30,23.35,22.78,22.89,7791200,11.44
    -2003-10-30,23.99,24.00,22.87,23.09,9305600,11.55
    -2003-10-29,23.51,23.90,23.34,23.69,9538600,11.85
    -2003-10-28,22.56,23.77,22.40,23.72,8989800,11.86
    -2003-10-27,22.75,22.89,22.49,22.60,5786200,11.30
    -2003-10-24,22.56,22.85,22.23,22.60,7852000,11.30
    -2003-10-23,22.73,23.15,22.59,22.99,5900400,11.49
    -2003-10-22,22.94,23.20,22.68,22.76,5771400,11.38
    -2003-10-21,23.31,23.40,22.75,23.18,6302200,11.59
    -2003-10-20,22.60,23.34,22.38,23.22,9969000,11.61
    -2003-10-17,23.38,23.49,22.43,22.75,12850400,11.38
    -2003-10-16,23.80,23.84,22.41,23.25,34845800,11.62
    -2003-10-15,24.85,25.01,24.58,24.82,21789400,12.41
    -2003-10-14,24.32,24.74,24.19,24.55,9836400,12.27
    -2003-10-13,23.73,24.41,23.72,24.35,9995200,12.18
    -2003-10-10,23.50,23.81,23.37,23.68,6244200,11.84
    -2003-10-09,23.30,23.67,22.79,23.45,12419600,11.73
    -2003-10-08,23.25,23.54,22.73,23.06,15309600,11.53
    -2003-10-07,22.05,23.41,21.91,23.22,14934800,11.61
    -2003-10-06,21.67,22.33,21.58,22.29,9583200,11.15
    -2003-10-03,20.99,21.86,20.88,21.69,10700000,10.85
    -2003-10-02,20.80,20.80,20.28,20.57,7287800,10.28
    -2003-10-01,20.71,21.10,20.19,20.79,8432600,10.40
    -2003-09-30,21.09,21.22,20.44,20.72,10193800,10.36
    -2003-09-29,21.49,21.67,20.65,21.30,13060800,10.65
    -2003-09-26,20.30,21.70,20.15,20.69,12401800,10.35
    -2003-09-25,21.34,21.37,20.25,20.43,20513600,10.22
    -2003-09-24,22.21,22.31,21.08,21.32,10760200,10.66
    -2003-09-23,22.02,22.46,21.88,22.43,4730400,11.22
    -2003-09-22,22.18,22.50,21.92,22.08,6422200,11.04
    -2003-09-19,22.88,23.05,22.43,22.58,7355600,11.29
    -2003-09-18,22.10,22.99,21.95,22.88,9032400,11.44
    -2003-09-17,22.37,22.38,21.85,22.12,10335600,11.06
    -2003-09-16,22.21,22.69,22.20,22.36,9607400,11.18
    -2003-09-15,22.81,22.90,22.12,22.21,8101600,11.10
    -2003-09-12,22.51,23.14,22.31,23.10,6428200,11.55
    -2003-09-11,22.25,22.79,22.10,22.56,7631600,11.28
    -2003-09-10,22.25,22.61,22.11,22.18,8031800,11.09
    -2003-09-09,22.53,22.67,22.12,22.37,6441800,11.19
    -2003-09-08,22.48,22.79,22.47,22.74,5973000,11.37
    -2003-09-05,22.73,23.15,22.41,22.50,8576200,11.25
    -2003-09-04,23.16,23.25,22.77,22.83,7135000,11.41
    -2003-09-03,22.80,23.32,22.76,22.95,9601000,11.48
    -2003-09-02,22.66,22.90,22.40,22.85,8647600,11.43
    -2003-08-29,22.20,22.85,22.05,22.61,9398400,11.31
    -2003-08-28,21.33,22.22,21.33,22.19,11415200,11.10
    -2003-08-27,20.91,21.48,20.66,21.48,8060800,10.74
    -2003-08-26,20.75,21.07,20.35,21.05,5891400,10.52
    -2003-08-25,20.78,20.91,20.49,20.86,4920800,10.43
    -2003-08-22,21.81,22.00,20.64,20.88,8938000,10.44
    -2003-08-21,21.03,21.71,20.95,21.68,9118800,10.84
    -2003-08-20,20.18,21.27,20.14,21.01,9757600,10.51
    -2003-08-19,20.37,20.45,20.00,20.32,4774600,10.16
    -2003-08-18,19.86,20.41,19.72,20.34,6884800,10.17
    -2003-08-15,20.02,20.07,19.66,19.71,4495200,9.85
    -2003-08-14,20.21,20.33,19.94,19.97,6885000,9.98
    -2003-08-13,19.86,20.34,19.58,20.18,10146400,10.09
    -2003-08-12,19.76,19.80,19.46,19.70,5872800,9.85
    -2003-08-11,19.82,19.93,19.51,19.66,4901000,9.83
    -2003-08-08,20.11,20.13,19.60,19.64,4916400,9.82
    -2003-08-07,19.73,20.09,19.42,19.93,6227800,9.97
    -2003-08-06,20.06,20.17,19.50,19.63,8766600,9.81
    -2003-08-05,21.35,21.40,20.10,20.38,8908600,10.19
    -2003-08-04,20.53,21.50,20.28,21.21,8218400,10.60
    -2003-08-01,21.00,21.27,20.64,20.73,5343000,10.36
    -2003-07-31,20.74,21.35,20.57,21.08,10766600,10.54
    -2003-07-30,20.77,20.90,20.17,20.28,6199800,10.14
    -2003-07-29,20.99,21.08,20.52,20.72,7040000,10.36
    -2003-07-28,21.50,21.50,20.86,20.99,6084200,10.49
    -2003-07-25,20.41,21.57,20.40,21.54,7738800,10.77
    -2003-07-24,21.04,21.50,20.38,20.51,8187000,10.26
    -2003-07-23,20.95,20.96,20.46,20.79,5108400,10.40
    -2003-07-22,20.87,20.96,20.50,20.80,7086600,10.40
    -2003-07-21,20.69,20.80,20.30,20.61,6564600,10.31
    -2003-07-18,20.90,21.18,20.40,20.86,10672800,10.43
    -2003-07-17,20.19,20.95,20.13,20.90,26829000,10.45
    -2003-07-16,19.97,20.00,19.38,19.87,8961800,9.94
    -2003-07-15,20.02,20.24,19.43,19.61,7380200,9.81
    -2003-07-14,20.01,20.40,19.87,19.90,6728800,9.95
    -2003-07-11,19.66,20.00,19.53,19.85,4887800,9.93
    -2003-07-10,19.88,19.94,19.37,19.58,6104800,9.79
    -2003-07-09,20.21,20.45,19.89,19.89,7630200,9.94
    -2003-07-08,19.52,20.50,19.49,20.40,9169200,10.20
    -2003-07-07,19.27,20.18,19.13,19.87,10224000,9.94
    -2003-07-03,19.00,19.55,18.98,19.13,4920400,9.56
    -2003-07-02,19.03,19.40,19.02,19.27,11617800,9.64
    -2003-07-01,18.87,19.18,18.51,19.09,6464000,9.55
    -2003-06-30,18.68,19.21,18.59,19.06,7934000,9.53
    -2003-06-27,19.30,19.31,18.48,18.73,13064000,9.36
    -2003-06-26,18.70,19.32,18.70,19.29,5775200,9.65
    -2003-06-25,18.86,19.40,18.71,19.09,11779000,9.55
    -2003-06-24,19.47,19.67,18.72,18.78,18370800,9.39
    -2003-06-23,19.30,19.69,18.75,19.06,10977200,9.53
    -2003-06-20,19.35,19.58,18.90,19.20,12733800,9.60
    -2003-06-19,19.36,19.61,18.77,19.14,13626000,9.57
    -2003-06-18,18.45,19.48,18.31,19.12,16249400,9.56
    -2003-06-17,18.41,18.50,17.99,18.19,6338000,9.10
    -2003-06-16,17.60,18.27,17.45,18.27,8518800,9.14
    -2003-06-13,17.75,17.95,17.13,17.42,6830200,8.71
    -2003-06-12,17.55,17.88,17.45,17.77,9021000,8.89
    -2003-06-11,17.15,17.51,16.81,17.45,8039800,8.73
    -2003-06-10,16.89,17.29,16.75,17.18,6308800,8.59
    -2003-06-09,16.94,17.04,16.63,16.79,9284000,8.40
    -2003-06-06,17.74,18.04,17.14,17.15,8621000,8.57
    -2003-06-05,17.45,17.74,17.33,17.64,7339200,8.82
    -2003-06-04,17.30,17.79,17.14,17.60,9685800,8.80
    -2003-06-03,17.44,17.67,17.02,17.31,12887800,8.65
    -2003-06-02,18.10,18.29,17.27,17.45,14949600,8.73
    -2003-05-30,18.12,18.18,17.53,17.95,13669600,8.98
    -2003-05-29,18.29,18.50,17.90,18.10,11920200,9.05
    -2003-05-28,18.50,18.66,18.15,18.28,12131400,9.14
    -2003-05-27,17.96,18.90,17.91,18.88,10361800,9.44
    -2003-05-23,18.21,18.46,17.96,18.32,7382800,9.16
    -2003-05-22,17.89,18.40,17.74,18.24,6373600,9.12
    -2003-05-21,17.79,18.09,17.67,17.85,10893200,8.93
    -2003-05-20,18.10,18.16,17.60,17.79,14865000,8.90
    -2003-05-19,18.53,18.65,18.06,18.10,15924600,9.05
    -2003-05-16,18.59,19.01,18.28,18.80,12201000,9.40
    -2003-05-15,18.60,18.85,18.47,18.73,10178400,9.36
    -2003-05-14,18.83,18.84,18.43,18.55,12696000,9.27
    -2003-05-13,18.43,18.97,17.95,18.67,15957000,9.34
    -2003-05-12,18.15,18.74,18.13,18.56,14977600,9.28
    -2003-05-09,18.33,18.40,17.88,18.30,21013800,9.15
    -2003-05-08,17.70,18.07,17.29,18.00,24562000,9.00
    -2003-05-07,17.33,18.24,17.11,17.65,37656400,8.82
    -2003-05-06,16.12,17.90,16.10,17.50,54089000,8.75
    -2003-05-05,14.77,16.88,14.75,16.09,55561000,8.05
    -2003-05-02,14.46,14.59,14.34,14.45,11470800,7.22
    -2003-05-01,14.25,14.39,14.00,14.36,12241400,7.18
    -2003-04-30,13.93,14.35,13.85,14.22,16363400,7.11
    -2003-04-29,13.98,14.16,13.58,14.06,16365600,7.03
    -2003-04-28,13.48,13.96,13.43,13.86,22742800,6.93
    -2003-04-25,13.46,13.58,13.23,13.35,7332800,6.68
    -2003-04-24,13.52,13.61,13.00,13.44,11611000,6.72
    -2003-04-23,13.53,13.63,13.36,13.58,7488600,6.79
    -2003-04-22,13.18,13.62,13.09,13.51,10734600,6.76
    -2003-04-21,13.13,13.19,12.98,13.14,5440000,6.57
    -2003-04-17,13.20,13.25,12.72,13.12,22009200,6.56
    -2003-04-16,12.99,13.67,12.92,13.24,36292000,6.62
    -2003-04-15,13.59,13.60,13.30,13.39,10856000,6.70
    -2003-04-14,13.71,13.75,13.50,13.58,17962800,6.79
    -2003-04-11,14.05,14.44,12.93,13.20,49739600,6.60
    -2003-04-10,14.20,14.39,14.20,14.37,3825000,7.18
    -2003-04-09,14.52,14.62,14.14,14.19,5240200,7.09
    -2003-04-08,14.51,14.65,14.36,14.45,4604800,7.22
    -2003-04-07,14.85,14.95,14.41,14.49,7030800,7.24
    -2003-04-04,14.52,14.67,14.39,14.41,5215000,7.20
    -2003-04-03,14.56,14.70,14.35,14.46,5204000,7.23
    -2003-04-02,14.36,14.69,14.27,14.60,6120400,7.30
    -2003-04-01,14.20,14.31,14.07,14.16,5512200,7.08
    -2003-03-31,14.33,14.53,14.04,14.14,9166400,7.07
    -2003-03-28,14.40,14.62,14.37,14.57,5189400,7.28
    -2003-03-27,14.32,14.70,14.32,14.49,4371200,7.24
    -2003-03-26,14.55,14.56,14.30,14.41,6369400,7.20
    -2003-03-25,14.41,14.83,14.37,14.55,5989200,7.28
    -2003-03-24,14.67,14.80,14.35,14.37,5753600,7.18
    -2003-03-21,15.09,15.15,14.82,15.00,10641000,7.50
    -2003-03-20,14.93,14.99,14.60,14.91,5827800,7.45
    -2003-03-19,15.07,15.15,14.79,14.95,5047000,7.47
    -2003-03-18,15.00,15.09,14.82,15.00,8213600,7.50
    -2003-03-17,14.89,15.07,14.71,15.01,14282600,7.51
    -2003-03-14,14.68,15.01,14.64,14.78,5467800,7.39
    -2003-03-13,14.47,14.80,14.17,14.72,11980200,7.36
    -2003-03-12,14.17,14.39,14.06,14.22,7948600,7.11
    -2003-03-11,14.36,14.49,14.12,14.23,5756800,7.11
    -2003-03-10,14.51,14.67,14.30,14.37,4806200,7.18
    -2003-03-07,14.47,14.71,14.31,14.53,7178000,7.26
    -2003-03-06,14.58,14.60,14.40,14.56,3566400,7.28
    -2003-03-05,14.61,14.80,14.52,14.62,4524400,7.31
    -2003-03-04,14.74,14.81,14.44,14.56,4514800,7.28
    -2003-03-03,15.01,15.16,14.55,14.65,7277200,7.32
    -2003-02-28,14.86,15.09,14.77,15.01,6967800,7.51
    -2003-02-27,14.57,15.00,14.51,14.86,5512200,7.43
    -2003-02-26,14.99,15.02,14.48,14.50,7753400,7.25
    -2003-02-25,14.68,15.08,14.58,15.02,6737200,7.51
    -2003-02-24,14.86,15.03,13.80,14.74,6437600,7.37
    -2003-02-21,14.82,15.06,14.65,15.00,5623000,7.50
    -2003-02-20,14.85,14.96,14.71,14.77,8012600,7.39
    -2003-02-19,15.07,15.15,14.68,14.85,8584600,7.43
    -2003-02-18,14.75,15.30,14.72,15.27,10389200,7.64
    -2003-02-14,14.61,14.72,14.35,14.67,8689200,7.34
    -2003-02-13,14.41,14.64,14.24,14.54,7446200,7.27
    -2003-02-12,14.27,14.60,14.27,14.39,8167400,7.20
    -2003-02-11,14.50,14.63,14.20,14.35,5885000,7.18
    -2003-02-10,14.26,14.57,14.06,14.35,5996000,7.18
    -2003-02-07,14.55,14.60,14.07,14.15,9632200,7.07
    -2003-02-06,14.36,14.59,14.22,14.43,6398200,7.22
    -2003-02-05,14.71,14.93,14.44,14.45,7914800,7.22
    -2003-02-04,14.45,14.65,14.31,14.60,11336200,7.30
    -2003-02-03,14.41,14.91,14.35,14.66,9456600,7.33
    -2003-01-31,14.19,14.55,14.05,14.36,12186600,7.18
    -2003-01-30,14.98,15.07,14.29,14.32,14537800,7.16
    -2003-01-29,14.55,15.10,14.30,14.93,13323000,7.47
    -2003-01-28,14.24,14.69,14.16,14.58,10223400,7.29
    -2003-01-27,13.68,14.50,13.65,14.13,13978800,7.07
    -2003-01-24,14.24,14.24,13.56,13.80,10909600,6.90
    -2003-01-23,14.05,14.36,13.95,14.17,8152000,7.09
    -2003-01-22,13.98,14.15,13.80,13.88,7683600,6.94
    -2003-01-21,14.21,14.41,14.00,14.02,9052000,7.01
    -2003-01-17,14.56,14.56,14.08,14.10,9527200,7.05
    -2003-01-16,14.21,14.76,14.21,14.62,19966800,7.31
    -2003-01-15,14.59,14.70,14.26,14.43,13254600,7.22
    -2003-01-14,14.69,14.82,14.49,14.61,6673600,7.30
    -2003-01-13,14.90,14.90,14.36,14.63,6390800,7.32
    -2003-01-10,14.58,14.82,14.49,14.72,6253600,7.36
    -2003-01-09,14.62,14.92,14.50,14.68,7687600,7.34
    -2003-01-08,14.58,14.71,14.44,14.55,8201600,7.28
    -2003-01-07,14.79,15.00,14.47,14.85,12226600,7.43
    -2003-01-06,15.03,15.38,14.88,14.90,13947600,7.45
    -2003-01-03,14.80,14.93,14.59,14.90,5266200,7.45
    -2003-01-02,14.36,14.92,14.35,14.80,6479600,7.40
    -2002-12-31,14.00,14.36,13.95,14.33,7168800,7.16
    -2002-12-30,14.08,14.15,13.84,14.07,5537200,7.03
    -2002-12-27,14.31,14.38,14.01,14.06,2858400,7.03
    -2002-12-26,14.42,14.81,14.28,14.40,3050800,7.20
    -2002-12-24,14.44,14.47,14.30,14.36,1405000,7.18
    -2002-12-23,14.16,14.55,14.12,14.49,4493800,7.24
    -2002-12-20,14.29,14.56,13.78,14.14,11360600,7.07
    -2002-12-19,14.53,14.92,14.10,14.20,12411400,7.10
    -2002-12-18,14.80,14.86,14.50,14.57,5382200,7.28
    -2002-12-17,14.85,15.19,14.66,15.08,7952200,7.54
    -2002-12-16,14.81,15.10,14.61,14.85,8986600,7.43
    -2002-12-13,15.14,15.15,14.65,14.79,5885000,7.39
    -2002-12-12,15.51,15.55,15.01,15.19,5333600,7.59
    -2002-12-11,15.30,15.49,15.08,15.49,9053600,7.74
    -2002-12-10,14.75,15.45,14.73,15.28,11021800,7.64
    -2002-12-09,14.94,14.95,14.67,14.75,8431600,7.38
    -2002-12-06,14.65,15.19,14.52,14.95,8762800,7.47
    -2002-12-05,15.03,15.08,14.53,14.63,8692800,7.32
    -2002-12-04,15.18,15.19,14.50,14.97,11634200,7.49
    -2002-12-03,15.20,15.34,15.10,15.16,8138200,7.58
    -2002-12-02,15.90,16.10,15.01,15.18,14240800,7.59
    -2002-11-29,15.79,15.88,15.41,15.50,5122600,7.75
    -2002-11-27,15.60,15.86,15.45,15.72,10242800,7.86
    -2002-11-26,15.85,15.90,15.27,15.41,8580800,7.70
    -2002-11-25,16.03,16.14,15.71,15.97,7122400,7.99
    -2002-11-22,16.09,16.30,15.90,16.01,8137800,8.01
    -2002-11-21,15.90,16.44,15.75,16.35,14945800,8.18
    -2002-11-20,15.30,15.70,15.25,15.53,7455000,7.76
    -2002-11-19,15.55,15.75,15.01,15.27,7534000,7.64
    -2002-11-18,16.19,16.20,15.52,15.65,5877800,7.82
    -2002-11-15,16.23,16.24,15.76,15.95,5749800,7.97
    -2002-11-14,15.90,16.41,15.78,16.30,5061200,8.15
    -2002-11-13,15.50,16.07,15.28,15.59,8276400,7.80
    -2002-11-12,15.32,16.04,15.28,15.64,7992600,7.82
    -2002-11-11,15.74,15.89,15.12,15.16,5463400,7.58
    -2002-11-08,16.01,16.20,15.52,15.84,6788000,7.92
    -2002-11-07,16.94,17.10,15.81,16.00,12006400,8.00
    -2002-11-06,17.08,17.32,16.70,17.22,7728200,8.61
    -2002-11-05,16.75,16.96,16.35,16.90,7524800,8.45
    -2002-11-04,16.50,17.38,16.35,16.89,13457800,8.44
    -2002-11-01,15.94,16.50,15.89,16.36,6779600,8.18
    -2002-10-31,15.99,16.44,15.92,16.07,10565600,8.03
    -2002-10-30,15.49,16.37,15.48,15.98,9667000,7.99
    -2002-10-29,15.57,15.88,14.96,15.44,9256400,7.72
    -2002-10-28,15.55,15.95,15.25,15.61,12475000,7.80
    -2002-10-25,14.69,15.45,14.59,15.42,9966800,7.71
    -2002-10-24,15.02,15.21,14.55,14.69,6241000,7.34
    -2002-10-23,14.63,14.98,14.50,14.88,7465600,7.44
    -2002-10-22,14.47,14.88,14.26,14.70,7791000,7.35
    -2002-10-21,14.26,14.63,14.00,14.56,8518600,7.28
    -2002-10-18,14.00,14.35,13.93,14.34,10296400,7.17
    -2002-10-17,14.21,14.38,13.98,14.11,16760600,7.05
    -2002-10-16,14.86,15.13,13.90,14.56,10986600,7.28
    -2002-10-15,15.22,15.25,14.78,15.16,14482800,7.58
    -2002-10-14,14.55,14.98,14.44,14.77,6943000,7.39
    -2002-10-11,14.25,14.78,14.10,14.51,10524200,7.26
    -2002-10-10,13.63,14.22,13.58,14.11,11484800,7.05
    -2002-10-09,13.54,13.85,13.41,13.59,12738800,6.80
    -2002-10-08,13.90,13.96,13.36,13.68,16201600,6.84
    -2002-10-07,13.97,14.21,13.76,13.77,8739200,6.89
    -2002-10-04,14.36,14.40,13.99,14.03,6815200,7.01
    -2002-10-03,14.18,14.60,14.06,14.30,7782000,7.15
    -2002-10-02,14.33,14.63,14.10,14.17,8191000,7.09
    -2002-10-01,14.59,14.60,14.00,14.51,12229400,7.26
    -2002-09-30,14.40,14.57,14.14,14.50,8489200,7.25
    -2002-09-27,14.49,14.85,14.48,14.72,7362600,7.36
    -2002-09-26,15.10,15.19,14.55,14.70,7451600,7.35
    -2002-09-25,14.69,15.17,14.65,14.93,9095800,7.47
    -2002-09-24,14.40,14.82,14.40,14.64,8952200,7.32
    -2002-09-23,14.76,14.96,14.45,14.85,9418200,7.43
    -2002-09-20,14.62,14.94,14.52,14.87,12599600,7.43
    -2002-09-19,14.75,14.80,14.48,14.58,7355200,7.29
    -2002-09-18,14.69,15.09,14.52,15.02,11737200,7.51
    -2002-09-17,14.57,15.03,14.57,14.80,15285600,7.40
    -2002-09-16,14.14,14.61,14.12,14.50,10237200,7.25
    -2002-09-13,14.13,14.34,14.05,14.17,10105400,7.09
    -2002-09-12,14.20,14.51,14.12,14.14,9636800,7.07
    -2002-09-11,14.34,14.60,14.15,14.29,7229000,7.14
    -2002-09-10,14.41,14.49,14.12,14.33,8909600,7.16
    -2002-09-09,14.28,14.53,14.15,14.37,5651600,7.18
    -2002-09-06,14.51,14.65,14.23,14.38,6485400,7.19
    -2002-09-05,14.22,14.36,14.05,14.18,8077800,7.09
    -2002-09-04,14.20,14.78,14.17,14.48,15023600,7.24
    -2002-09-03,14.49,14.55,14.05,14.05,9890600,7.03
    -2002-08-30,14.73,15.14,14.58,14.75,6911400,7.38
    -2002-08-29,14.65,15.08,14.51,14.70,5863200,7.35
    -2002-08-28,14.80,15.12,14.65,14.70,8856200,7.35
    -2002-08-27,15.71,15.74,14.71,14.85,9365400,7.43
    -2002-08-26,15.95,15.95,15.16,15.53,6784600,7.76
    -2002-08-23,15.90,15.93,15.45,15.73,5830200,7.86
    -2002-08-22,16.20,16.25,15.66,15.97,9225400,7.99
    -2002-08-21,16.01,16.24,15.45,16.12,7229600,8.06
    -2002-08-20,15.97,16.09,15.53,15.91,6665200,7.95
    -2002-08-19,15.78,16.25,15.72,15.98,7734200,7.99
    -2002-08-16,15.45,16.10,15.28,15.81,8758000,7.91
    -2002-08-15,15.25,15.75,15.01,15.61,11502800,7.80
    -2002-08-14,14.67,15.35,14.54,15.17,14253000,7.59
    -2002-08-13,14.90,15.21,14.55,14.59,9638200,7.30
    -2002-08-12,14.90,15.02,14.69,14.99,6420200,7.49
    -2002-08-09,15.25,15.25,14.75,15.00,7347000,7.50
    -2002-08-08,14.77,15.38,14.77,15.30,8119600,7.65
    -2002-08-07,15.09,15.36,14.35,15.03,11909800,7.51
    -2002-08-06,14.21,15.23,14.08,14.74,9716200,7.37
    -2002-08-05,14.51,14.70,13.97,13.99,7286600,6.99
    -2002-08-02,14.74,15.00,14.25,14.45,6395000,7.22
    -2002-08-01,15.11,15.42,14.73,14.80,8177000,7.40
    -2002-07-31,15.40,15.42,14.90,15.26,11096400,7.63
    -2002-07-30,14.85,15.51,14.56,15.43,12672800,7.72
    -2002-07-29,14.48,15.10,14.37,15.02,9820000,7.51
    -2002-07-26,14.46,14.53,13.80,14.34,7418000,7.17
    -2002-07-25,14.93,14.95,14.01,14.36,17119800,7.18
    -2002-07-24,14.33,15.22,14.25,15.20,14521200,7.60
    -2002-07-23,14.90,15.13,14.44,14.47,14281800,7.24
    -2002-07-22,14.75,15.19,14.61,14.92,15389200,7.46
    -2002-07-19,14.70,15.17,14.53,14.96,13757400,7.48
    -2002-07-18,15.50,15.56,14.75,14.99,19980800,7.49
    -2002-07-17,16.13,16.20,15.19,15.63,43410200,7.82
    -2002-07-16,18.15,18.57,17.61,17.86,15956000,8.93
    -2002-07-15,17.43,18.60,16.81,18.23,10571200,9.11
    -2002-07-12,18.55,18.79,17.26,17.51,15839000,8.76
    -2002-07-11,17.26,18.35,16.97,18.30,13345600,9.15
    -2002-07-10,17.71,18.17,17.25,17.32,7388600,8.66
    -2002-07-09,18.09,18.29,17.46,17.53,8098200,8.77
    -2002-07-08,18.52,18.61,17.68,18.01,7543000,9.01
    -2002-07-05,17.71,18.75,17.71,18.74,5773200,9.37
    -2002-07-03,16.81,17.68,16.75,17.55,7108200,8.77
    -2002-07-02,17.03,17.16,16.83,16.94,10899600,8.47
    -2002-07-01,17.71,17.88,17.05,17.06,7953200,8.53
    -2002-06-28,17.10,17.82,17.00,17.72,9637800,8.86
    -2002-06-27,16.79,17.27,16.42,17.06,8987800,8.53
    -2002-06-26,16.80,17.29,15.98,16.55,19962600,8.27
    -2002-06-25,17.40,17.68,16.86,17.14,10757200,8.57
    -2002-06-24,16.77,17.73,16.70,17.27,15426200,8.64
    -2002-06-21,16.97,17.49,16.79,16.85,15899200,8.43
    -2002-06-20,17.17,17.60,16.85,17.11,14165600,8.56
    -2002-06-19,17.37,17.60,16.88,17.12,61052400,8.56
    -2002-06-18,20.42,20.59,19.98,20.15,12620000,10.07
    -2002-06-17,20.24,20.63,19.85,20.54,11593200,10.27
    -2002-06-14,19.24,20.36,18.11,20.10,15175000,10.05
    -2002-06-13,20.02,20.05,19.38,19.54,12574400,9.77
    -2002-06-12,20.41,20.75,19.94,20.09,18882800,10.05
    -2002-06-11,21.64,21.70,20.41,20.46,12482000,10.23
    -2002-06-10,21.48,21.84,21.34,21.48,9913400,10.74
    -2002-06-07,21.76,21.94,20.93,21.40,21870600,10.70
    -2002-06-06,22.96,23.23,22.04,22.16,9285600,11.08
    -2002-06-05,22.83,22.83,22.35,22.72,9895800,11.36
    -2002-06-04,22.88,23.04,22.18,22.78,12422200,11.39
    -2002-06-03,23.39,23.45,22.58,22.91,8396800,11.45
    -2002-05-31,24.09,24.25,23.28,23.30,13053400,11.65
    -2002-05-30,23.77,24.38,23.51,24.20,7013400,12.10
    -2002-05-29,23.92,24.44,23.45,23.98,7921200,11.99
    -2002-05-28,23.69,24.20,23.43,23.98,5347000,11.99
    -2002-05-24,24.99,24.99,23.96,24.15,5934800,12.07
    -2002-05-23,24.45,25.24,24.07,25.18,13192800,12.59
    -2002-05-22,23.37,24.37,23.32,24.32,10388400,12.16
    -2002-05-21,24.83,25.00,23.40,23.46,10035400,11.73
    -2002-05-20,24.57,24.93,24.53,24.74,9639800,12.37
    -2002-05-17,25.49,25.78,24.61,25.01,8446200,12.51
    -2002-05-16,25.06,25.45,24.75,25.21,8109000,12.60
    -2002-05-15,25.37,25.98,24.84,25.28,11993800,12.64
    -2002-05-14,24.45,25.68,24.22,25.61,18803800,12.81
    -2002-05-13,23.52,24.09,22.94,23.94,9486000,11.97
    -2002-05-10,24.29,24.29,22.98,23.32,8407000,11.66
    -2002-05-09,24.25,24.35,23.80,24.19,8022000,12.10
    -2002-05-08,23.20,24.52,23.04,24.37,15595800,12.19
    -2002-05-07,22.94,22.95,22.14,22.47,8669600,11.23
    -2002-05-06,23.35,23.50,22.46,22.65,8916600,11.32
    -2002-05-03,23.57,24.02,23.43,23.51,8242200,11.76
    -2002-05-02,23.81,24.34,23.60,23.69,8548000,11.85
    -2002-05-01,24.29,24.29,23.36,23.98,7668000,11.99
    -2002-04-30,23.89,24.38,23.75,24.27,10034400,12.14
    -2002-04-29,23.16,24.06,23.09,23.96,9724600,11.98
    -2002-04-26,24.28,24.37,23.00,23.01,10892200,11.51
    -2002-04-25,23.56,24.34,23.55,24.12,6935800,12.06
    -2002-04-24,24.30,24.50,23.68,23.77,5016000,11.89
    -2002-04-23,24.54,24.78,24.09,24.25,8338200,12.12
    -2002-04-22,24.84,24.93,24.23,24.53,9622400,12.27
    -2002-04-19,25.49,25.49,24.93,24.98,13407400,12.49
    -2002-04-18,25.50,25.52,24.88,25.41,14346800,12.70
    -2002-04-17,25.93,26.17,25.38,26.11,14151800,13.06
    -2002-04-16,25.15,25.99,25.12,25.74,21949200,12.87
    -2002-04-15,25.06,25.15,24.80,25.00,10691800,12.50
    -2002-04-12,25.01,25.17,24.57,25.06,11437200,12.53
    -2002-04-11,25.03,25.20,24.75,24.86,14544800,12.43
    -2002-04-10,24.21,24.95,24.01,24.66,8035000,12.33
    -2002-04-09,24.59,25.00,24.01,24.10,6840400,12.05
    -2002-04-08,24.16,24.68,23.78,24.56,9339800,12.28
    -2002-04-05,24.95,25.19,24.10,24.74,9941000,12.37
    -2002-04-04,23.67,25.05,23.67,24.90,12089200,12.45
    -2002-04-03,24.05,24.49,23.60,23.75,7661800,11.88
    -2002-04-02,24.00,24.30,23.87,24.07,7278400,12.03
    -2002-04-01,23.38,24.70,23.28,24.46,7108800,12.23
    -2002-03-28,23.70,23.88,23.46,23.67,3873400,11.84
    -2002-03-27,23.35,23.72,23.26,23.47,4560800,11.73
    -2002-03-26,23.20,23.64,23.00,23.46,9208600,11.73
    -2002-03-25,24.07,24.09,23.24,23.35,9386800,11.68
    -2002-03-22,24.22,24.56,23.87,24.09,7221200,12.05
    -2002-03-21,23.86,24.30,23.26,24.27,22012600,12.14
    -2002-03-20,24.66,25.14,24.50,24.92,10511400,12.46
    -2002-03-19,24.69,25.30,24.30,24.85,8655200,12.43
    -2002-03-18,24.95,25.05,24.32,24.74,10877000,12.37
    -2002-03-15,24.46,24.96,24.25,24.95,8603600,12.48
    -2002-03-14,24.30,24.60,23.87,24.43,7760600,12.22
    -2002-03-13,24.37,24.85,24.15,24.49,7170200,12.24
    -2002-03-12,24.51,24.74,24.10,24.72,9073400,12.36
    -2002-03-11,24.60,25.14,24.10,25.06,9385200,12.53
    -2002-03-08,24.74,25.09,24.30,24.66,9634800,12.33
    -2002-03-07,24.06,24.53,23.61,24.38,9223200,12.19
    -2002-03-06,23.48,24.34,22.93,24.07,8078800,12.03
    -2002-03-05,24.15,24.43,23.40,23.53,9810800,11.77
    -2002-03-04,23.26,24.58,22.76,24.29,12437800,12.15
    -2002-03-01,21.93,23.50,21.82,23.45,12464000,11.73
    -2002-02-28,22.15,22.59,21.35,21.70,16319200,10.85
    -2002-02-27,23.94,24.25,20.94,21.96,36791400,10.98
    -2002-02-26,23.91,24.37,23.25,23.67,9290400,11.84
    -2002-02-25,22.85,24.72,22.36,23.81,15244600,11.90
    -2002-02-22,21.66,22.95,21.50,22.74,14517000,11.37
    -2002-02-21,22.92,23.00,21.45,21.50,15955400,10.75
    -2002-02-20,22.77,23.20,22.35,23.13,10194400,11.56
    -2002-02-19,23.76,23.87,22.48,22.62,13937800,11.31
    -2002-02-15,24.53,24.98,23.85,23.90,9292400,11.95
    -2002-02-14,25.05,25.23,24.38,24.60,9291800,12.30
    -2002-02-13,24.73,25.24,24.65,25.01,11174000,12.51
    -2002-02-12,24.66,25.04,24.45,24.71,8010000,12.35
    -2002-02-11,23.93,25.00,23.74,24.98,14235800,12.49
    -2002-02-08,24.40,24.64,23.37,24.03,12690400,12.02
    -2002-02-07,24.65,25.29,24.08,24.30,12422600,12.15
    -2002-02-06,25.60,25.98,24.15,24.67,21342000,12.34
    -2002-02-05,25.09,25.98,25.08,25.45,16317400,12.73
    -2002-02-04,24.32,25.52,24.20,25.35,18656200,12.68
    -2002-02-01,24.34,24.96,24.34,24.41,14225200,12.20
    -2002-01-31,24.16,24.73,24.11,24.72,16730200,12.36
    -2002-01-30,23.07,24.14,22.94,24.09,16842000,12.05
    -2002-01-29,23.22,23.54,22.85,23.07,8583000,11.53
    -2002-01-28,23.40,23.55,22.72,23.27,6658800,11.64
    -2002-01-25,22.89,23.42,22.66,23.25,6639800,11.62
    -2002-01-24,22.91,23.51,22.90,23.21,12285800,11.60
    -2002-01-23,21.80,23.04,21.59,23.02,15831400,11.51
    -2002-01-22,22.27,22.37,21.82,21.82,11689800,10.91
    -2002-01-18,22.00,22.60,21.96,22.17,12100400,11.09
    -2002-01-17,21.96,22.74,21.87,22.48,23592000,11.24
    -2002-01-16,21.41,21.41,20.50,20.78,20246200,10.39
    -2002-01-15,21.32,21.76,21.21,21.70,10368600,10.85
    -2002-01-14,21.01,21.40,20.90,21.15,14857000,10.57
    -2002-01-11,21.39,21.84,20.60,21.05,12457200,10.52
    -2002-01-10,21.22,21.46,20.25,21.23,16169200,10.61
    -2002-01-09,22.80,22.93,21.28,21.65,11708400,10.82
    -2002-01-08,22.75,23.05,22.46,22.61,16072800,11.31
    -2002-01-07,23.72,24.00,22.75,22.90,15878000,11.45
    -2002-01-04,23.34,23.95,22.99,23.69,14642000,11.85
    -2002-01-03,23.00,23.75,22.77,23.58,21857400,11.79
    -2002-01-02,22.05,23.30,21.96,23.30,18910600,11.65
    -2001-12-31,22.51,22.66,21.83,21.90,4920800,10.95
    -2001-12-28,21.97,23.00,21.96,22.43,10683000,11.22
    -2001-12-27,21.58,22.25,21.58,22.07,6839600,11.03
    -2001-12-26,21.35,22.30,21.14,21.49,5228600,10.74
    -2001-12-24,20.90,21.45,20.90,21.36,1808200,10.68
    -2001-12-21,21.01,21.54,20.80,21.00,9154800,10.50
    -2001-12-20,21.40,21.47,20.62,20.67,7888000,10.34
    -2001-12-19,20.58,21.68,20.47,21.62,10355600,10.81
    -2001-12-18,20.89,21.33,20.22,21.01,8401400,10.51
    -2001-12-17,20.40,21.00,20.19,20.62,6204000,10.31
    -2001-12-14,20.73,20.83,20.09,20.39,6781600,10.19
    -2001-12-13,21.49,21.55,20.50,21.00,7065800,10.50
    -2001-12-12,21.87,21.92,21.25,21.49,6873600,10.74
    -2001-12-11,22.67,22.85,21.65,21.78,7338400,10.89
    -2001-12-10,22.29,22.99,22.23,22.54,6071800,11.27
    -2001-12-07,22.46,22.71,22.00,22.54,7268400,11.27
    -2001-12-06,23.48,23.50,22.14,22.78,12104800,11.39
    -2001-12-05,22.36,24.03,22.17,23.76,20306400,11.88
    -2001-12-04,21.05,22.56,20.72,22.40,13586400,11.20
    -2001-12-03,21.06,21.28,20.60,21.05,6470200,10.52
    -2001-11-30,20.47,21.44,20.25,21.30,10854000,10.65
    -2001-11-29,20.60,20.70,20.19,20.42,7241600,10.21
    -2001-11-28,20.85,21.21,20.41,20.53,8950400,10.27
    -2001-11-27,21.20,21.52,20.50,21.00,9591200,10.50
    -2001-11-26,19.94,21.55,19.88,21.37,16453200,10.69
    -2001-11-23,19.71,19.95,19.57,19.84,2143000,9.92
    -2001-11-21,19.61,19.80,19.26,19.68,7199400,9.84
    -2001-11-20,19.82,20.20,19.50,19.53,9878000,9.77
    -2001-11-19,19.00,20.05,18.96,20.00,11878200,10.00
    -2001-11-16,19.27,19.29,18.40,18.97,8238000,9.48
    -2001-11-15,19.45,19.90,19.23,19.45,7608200,9.73
    -2001-11-14,19.59,19.90,19.15,19.61,7898200,9.81
    -2001-11-13,19.08,19.39,18.71,19.37,8024000,9.69
    -2001-11-12,18.66,19.17,17.96,18.75,7196400,9.38
    -2001-11-09,18.60,19.25,18.55,18.71,4796200,9.35
    -2001-11-08,19.63,19.89,18.57,18.71,12219400,9.35
    -2001-11-07,19.46,20.13,19.33,19.59,13678200,9.80
    -2001-11-06,18.96,19.62,18.53,19.57,11286400,9.78
    -2001-11-05,18.84,19.25,18.61,19.07,8421200,9.53
    -2001-11-02,18.52,18.86,18.16,18.57,7043000,9.28
    -2001-11-01,17.65,18.78,17.25,18.59,11178400,9.30
    -2001-10-31,17.73,18.40,17.44,17.56,9776800,8.78
    -2001-10-30,17.38,18.00,17.06,17.60,9884400,8.80
    -2001-10-29,18.57,18.67,17.60,17.63,8542200,8.81
    -2001-10-26,18.86,19.25,18.62,18.67,9963000,9.34
    -2001-10-25,18.44,19.25,18.16,19.19,9105400,9.60
    -2001-10-24,18.06,19.09,17.75,18.95,13372400,9.48
    -2001-10-23,19.12,19.42,17.87,18.14,24463600,9.07
    -2001-10-22,18.21,19.07,18.09,19.02,13997800,9.51
    -2001-10-19,17.94,18.40,17.88,18.30,5956800,9.15
    -2001-10-18,17.29,18.23,17.29,18.00,21877600,9.00
    -2001-10-17,18.34,18.41,16.96,16.99,10197800,8.49
    -2001-10-16,18.09,18.20,17.77,18.01,7248200,9.01
    -2001-10-15,17.95,18.38,17.95,17.99,11384000,8.99
    -2001-10-12,17.31,18.08,16.86,18.01,10279000,9.01
    -2001-10-11,16.92,17.74,16.85,17.74,11934400,8.87
    -2001-10-10,16.10,16.85,15.95,16.82,10991400,8.41
    -2001-10-09,16.05,16.20,15.63,16.00,6215200,8.00
    -2001-10-08,15.57,16.35,15.50,16.20,7428000,8.10
    -2001-10-05,15.40,16.15,14.99,16.14,12238800,8.07
    -2001-10-04,15.35,16.25,14.99,15.88,14325800,7.94
    -2001-10-03,14.95,15.36,14.83,14.98,24394400,7.49
    -2001-10-02,15.43,15.83,14.88,15.05,8424400,7.53
    -2001-10-01,15.49,15.99,15.23,15.54,7436000,7.77
    -2001-09-28,15.71,15.91,15.39,15.51,13039600,7.76
    -2001-09-27,15.25,15.75,15.20,15.51,11508600,7.76
    -2001-09-26,15.81,15.89,14.93,15.15,17635600,7.57
    -2001-09-25,16.14,16.22,15.35,15.54,13371600,7.77
    -2001-09-24,16.11,16.84,15.95,16.45,10519200,8.23
    -2001-09-21,14.80,16.25,14.68,15.73,20375600,7.86
    -2001-09-20,16.29,16.95,15.50,15.68,14684800,7.84
    -2001-09-19,16.50,17.10,15.60,17.02,13332800,8.51
    -2001-09-18,16.90,17.72,16.17,16.28,11682200,8.14
    -2001-09-17,16.00,17.07,15.73,16.99,16357400,8.49
    -2001-09-10,17.00,17.50,16.92,17.37,11030200,8.69
    -2001-09-07,17.50,18.10,17.20,17.28,8636800,8.64
    -2001-09-06,18.40,18.93,17.65,17.72,10084600,8.86
    -2001-09-05,18.24,18.95,18.12,18.55,12859200,9.27
    -2001-09-04,18.50,19.08,18.18,18.25,12436200,9.12
    -2001-08-31,17.73,18.60,17.65,18.55,7746600,9.27
    -2001-08-30,17.74,18.18,17.28,17.83,13167600,8.91
    -2001-08-29,18.44,18.83,17.83,17.83,8570400,8.91
    -2001-08-28,18.90,19.14,18.40,18.40,6133400,9.20
    -2001-08-27,18.60,19.30,18.16,18.92,6273000,9.46
    -2001-08-24,18.00,18.62,17.65,18.57,10369000,9.28
    -2001-08-23,18.20,18.34,17.58,17.81,7752800,8.90
    -2001-08-22,17.94,18.25,17.61,18.21,6213400,9.10
    -2001-08-21,18.14,18.14,17.70,17.92,6632200,8.96
    -2001-08-20,18.14,18.23,17.81,18.12,9010800,9.06
    -2001-08-17,18.00,18.45,17.99,18.07,7443800,9.03
    -2001-08-16,18.27,18.75,17.97,18.65,10289000,9.32
    -2001-08-15,18.76,18.94,18.20,18.44,10331400,9.22
    -2001-08-14,19.20,19.36,18.67,18.73,8176800,9.36
    -2001-08-13,19.10,19.33,18.76,19.09,5285600,9.55
    -2001-08-10,19.04,19.32,18.59,19.02,6677200,9.51
    -2001-08-09,18.96,19.15,18.72,19.05,7166600,9.52
    -2001-08-08,19.26,19.70,18.54,18.90,9863200,9.45
    -2001-08-07,19.33,19.67,18.98,19.25,6019600,9.62
    -2001-08-06,19.04,19.66,19.00,19.13,3559000,9.56
    -2001-08-03,19.89,19.90,19.00,19.50,6644800,9.75
    -2001-08-02,19.65,19.87,19.26,19.82,9003200,9.91
    -2001-08-01,19.01,19.78,18.95,19.06,10862000,9.53
    -2001-07-31,19.27,19.42,18.51,18.79,8393800,9.40
    -2001-07-30,19.12,19.36,18.51,18.93,8691400,9.47
    -2001-07-27,18.75,19.25,18.50,18.96,11933400,9.48
    -2001-07-26,18.48,18.80,17.85,18.59,13183600,9.30
    -2001-07-25,19.12,19.30,17.97,18.47,15852800,9.23
    -2001-07-24,19.39,19.92,18.73,19.09,12442000,9.55
    -2001-07-23,20.09,20.50,19.51,19.54,8620000,9.77
    -2001-07-20,19.70,20.06,19.49,19.98,15878000,9.99
    -2001-07-19,21.23,21.42,19.75,19.96,30755000,9.98
    -2001-07-18,21.78,22.78,20.42,20.79,40607600,10.40
    -2001-07-17,23.98,25.22,23.01,25.10,23136800,12.55
    -2001-07-16,24.88,25.10,23.91,23.96,9952400,11.98
    -2001-07-13,24.13,25.01,23.84,24.85,16240800,12.43
    -2001-07-12,23.30,24.81,23.30,24.36,21957200,12.18
    -2001-07-11,21.03,22.55,21.00,22.54,16803800,11.27
    -2001-07-10,22.95,23.07,20.84,21.14,14116800,10.57
    -2001-07-09,22.09,23.00,21.68,22.70,12052400,11.35
    -2001-07-06,22.76,22.96,21.72,22.03,10818600,11.02
    -2001-07-05,23.60,23.77,23.01,23.19,5439000,11.60
    -2001-07-03,23.51,24.18,23.50,23.84,4019400,11.92
    -2001-07-02,23.64,24.23,23.14,23.90,8216000,11.95
    -2001-06-29,23.66,25.10,23.20,23.25,18406800,11.62
    -2001-06-28,23.05,23.91,22.94,23.54,12443200,11.77
    -2001-06-27,23.83,24.00,22.50,23.34,13361800,11.67
    -2001-06-26,23.34,23.77,23.01,23.75,9742200,11.88
    -2001-06-25,22.50,24.00,22.45,23.99,15698200,11.99
    -2001-06-22,22.48,23.00,21.76,22.26,10215200,11.13
    -2001-06-21,21.55,23.00,21.10,22.49,12190400,11.24
    -2001-06-20,20.00,21.85,19.98,21.67,15415000,10.84
    -2001-06-19,20.85,21.40,20.01,20.19,11467400,10.10
    -2001-06-18,20.41,20.85,20.00,20.33,12354000,10.16
    -2001-06-15,20.10,20.75,19.35,20.44,16236600,10.22
    -2001-06-14,20.04,20.45,19.77,19.88,10619600,9.94
    -2001-06-13,21.42,21.73,20.06,20.47,18267400,10.23
    -2001-06-12,19.77,20.69,19.76,20.31,10849800,10.15
    -2001-06-11,21.05,21.07,19.95,20.04,10500000,10.02
    -2001-06-08,21.65,21.65,20.71,21.32,12236600,10.66
    -2001-06-07,20.71,21.70,20.45,21.66,11613600,10.83
    -2001-06-06,20.93,20.93,20.33,20.73,7970600,10.36
    -2001-06-05,20.80,21.10,20.35,20.94,16849800,10.47
    -2001-06-04,21.08,21.11,20.46,20.66,10068600,10.33
    -2001-06-01,20.13,21.09,19.98,20.89,16288400,10.44
    -2001-05-31,19.80,20.24,19.49,19.95,15817600,9.98
    -2001-05-30,20.76,20.76,19.30,19.78,27752800,9.89
    -2001-05-29,22.32,22.50,20.81,21.47,18428200,10.73
    -2001-05-25,23.20,23.29,22.50,22.76,5669400,11.38
    -2001-05-24,23.29,23.30,22.62,23.20,9705600,11.60
    -2001-05-23,23.75,23.75,22.86,23.23,10037200,11.61
    -2001-05-22,24.00,24.13,23.40,23.50,14747000,11.75
    -2001-05-21,23.63,23.91,23.05,23.56,16464200,11.78
    -2001-05-18,23.36,23.64,23.12,23.53,5680400,11.77
    -2001-05-17,24.23,24.33,23.25,23.55,11861400,11.77
    -2001-05-16,23.26,24.50,22.85,24.10,11511800,12.05
    -2001-05-15,23.37,25.50,23.04,23.18,8465200,11.59
    -2001-05-14,22.89,23.68,22.75,23.29,11043600,11.65
    -2001-05-11,23.01,23.49,22.76,22.85,7251600,11.43
    -2001-05-10,24.21,24.50,22.95,23.00,10320600,11.50
    -2001-05-09,24.14,24.55,23.67,23.98,11603200,11.99
    -2001-05-08,25.35,25.45,23.95,24.57,11265600,12.28
    -2001-05-07,25.62,25.76,24.84,24.96,9876800,12.48
    -2001-05-04,24.24,25.85,23.96,25.75,10037600,12.88
    -2001-05-03,25.97,26.25,24.73,24.96,10769400,12.48
    -2001-05-02,26.34,26.70,25.76,26.59,13161600,13.30
    -2001-05-01,25.41,26.50,25.20,25.93,15259000,12.97
    -2001-04-30,26.70,27.12,24.87,25.49,17670600,12.74
    -2001-04-27,25.20,26.29,24.75,26.20,16179000,13.10
    -2001-04-26,25.17,26.10,24.68,24.69,28560600,12.35
    -2001-04-25,24.21,24.86,23.57,24.72,11813600,12.36
    -2001-04-24,24.33,24.75,23.51,24.03,13469200,12.02
    -2001-04-23,24.34,25.00,24.00,24.25,19340200,12.12
    -2001-04-20,24.93,25.63,24.60,25.04,24764400,12.52
    -2001-04-19,25.55,25.75,23.60,25.72,66916800,12.86
    -2001-04-18,21.57,24.08,21.08,22.79,39315800,11.40
    -2001-04-17,21.20,21.21,19.60,20.40,24471400,10.20
    -2001-04-16,22.09,22.40,20.86,21.44,10186600,10.72
    -2001-04-12,21.42,23.02,21.15,22.42,10676200,11.21
    -2001-04-11,22.98,23.00,21.28,21.80,11932000,10.90
    -2001-04-10,20.90,22.70,20.78,22.04,16334800,11.02
    -2001-04-09,20.69,21.34,20.06,20.54,9520800,10.27
    -2001-04-06,20.80,21.04,19.90,20.59,11603200,10.30
    -2001-04-05,20.60,22.50,20.00,20.87,15955800,10.44
    -2001-04-04,19.76,20.25,18.75,19.50,24481600,9.75
    -2001-04-03,21.36,21.40,20.13,20.24,13167400,10.12
    -2001-04-02,22.09,22.66,21.40,21.59,12175400,10.80
    -2001-03-30,22.55,22.72,21.34,22.07,14298200,11.03
    -2001-03-29,21.77,23.45,21.50,22.53,21895200,11.27
    -2001-03-28,22.08,22.50,21.50,22.17,20880800,11.09
    -2001-03-27,21.94,23.05,21.90,22.87,19422200,11.44
    -2001-03-26,23.13,23.75,21.13,21.78,26230400,10.89
    -2001-03-23,22.06,23.56,22.00,23.00,33749400,11.50
    -2001-03-22,20.37,21.75,20.19,21.62,25839000,10.81
    -2001-03-21,19.78,20.87,19.37,20.12,13265400,10.06
    -2001-03-20,20.72,20.94,19.69,19.69,17833800,9.85
    -2001-03-19,19.75,20.62,19.50,20.56,12722800,10.28
    -2001-03-16,19.00,20.31,18.87,19.62,16806600,9.81
    -2001-03-15,20.87,21.37,19.69,19.69,18906600,9.85
    -2001-03-14,18.50,20.50,18.44,20.44,17065400,10.22
    -2001-03-13,18.87,19.56,18.19,19.56,15840600,9.78
    -2001-03-12,19.69,19.87,18.12,18.62,13967800,9.31
    -2001-03-09,20.62,20.69,20.00,20.25,10685400,10.12
    -2001-03-08,20.69,21.12,20.44,20.81,7325600,10.40
    -2001-03-07,21.31,21.62,20.75,21.25,14985600,10.62
    -2001-03-06,20.72,22.06,20.69,21.50,26144600,10.75
    -2001-03-05,19.37,20.50,19.25,20.37,11587600,10.19
    -2001-03-02,18.31,20.44,18.25,19.25,14511200,9.62
    -2001-03-01,17.81,18.75,17.19,18.75,11803400,9.38
    -2001-02-28,19.37,19.44,18.12,18.25,18157600,9.12
    -2001-02-27,19.28,19.44,18.69,19.37,12451000,9.69
    -2001-02-26,19.06,19.69,18.56,19.50,7380000,9.75
    -2001-02-23,18.62,18.87,18.25,18.81,10503800,9.40
    -2001-02-22,19.06,19.37,18.00,18.81,15431200,9.40
    -2001-02-21,18.25,19.94,18.25,18.87,13947800,9.44
    -2001-02-20,19.19,19.44,18.19,18.31,11249600,9.15
    -2001-02-16,19.00,19.50,18.75,19.00,9428400,9.50
    -2001-02-15,19.69,20.56,19.69,20.06,11123200,10.03
    -2001-02-14,19.19,19.62,18.50,19.50,11040000,9.75
    -2001-02-13,19.94,20.44,19.00,19.12,8470600,9.56
    -2001-02-12,19.06,20.00,18.81,19.69,9795600,9.85
    -2001-02-09,20.50,20.81,18.69,19.12,21082600,9.56
    -2001-02-08,20.56,21.06,20.19,20.75,21585000,10.38
    -2001-02-07,20.66,20.87,19.81,20.75,14071600,10.38
    -2001-02-06,20.16,21.39,20.00,21.12,16528400,10.56
    -2001-02-05,20.50,20.56,19.75,20.19,10228800,10.10
    -2001-02-02,21.12,21.94,20.50,20.62,15263400,10.31
    -2001-02-01,20.69,21.50,20.50,21.12,13205400,10.56
    -2001-01-31,21.50,22.50,21.44,21.62,26106000,10.81
    -2001-01-30,21.56,22.00,20.87,21.75,24734600,10.88
    -2001-01-29,19.56,21.75,19.56,21.69,30562800,10.85
    -2001-01-26,19.50,19.81,19.06,19.56,17245600,9.78
    -2001-01-25,20.56,20.56,19.75,19.94,17495000,9.97
    -2001-01-24,20.62,20.69,19.56,20.50,25616200,10.25
    -2001-01-23,19.31,20.94,19.06,20.50,31418400,10.25
    -2001-01-22,19.06,19.62,18.44,19.25,18551600,9.62
    -2001-01-19,19.44,19.56,18.69,19.50,27748200,9.75
    -2001-01-18,17.81,18.75,17.62,18.69,43822800,9.35
    -2001-01-17,17.56,17.56,16.50,16.81,30037600,8.40
    -2001-01-16,17.44,18.25,17.00,17.12,10940000,8.56
    -2001-01-12,17.87,18.00,17.06,17.19,15121000,8.60
    -2001-01-11,16.25,18.50,16.25,18.00,28707600,9.00
    -2001-01-10,16.69,17.00,16.06,16.56,20743400,8.28
    -2001-01-09,16.81,17.64,16.56,17.19,21040600,8.60
    -2001-01-08,16.94,16.98,15.94,16.56,13350000,8.28
    -2001-01-05,16.94,17.37,16.06,16.37,14731000,8.19
    -2001-01-04,18.14,18.50,16.81,17.06,26411000,8.53
    -2001-01-03,14.50,16.69,14.44,16.37,29181800,8.19
    -2001-01-02,14.88,15.25,14.56,14.88,16161800,7.44
    -2000-12-29,14.69,15.00,14.50,14.88,22518800,7.44
    -2000-12-28,14.38,14.94,14.31,14.81,10910000,7.41
    -2000-12-27,14.34,14.81,14.19,14.81,11626000,7.41
    -2000-12-26,14.88,15.00,14.25,14.69,7745400,7.34
    -2000-12-22,14.13,15.00,14.13,15.00,11369600,7.50
    -2000-12-21,14.25,15.00,13.88,14.06,13102600,7.03
    -2000-12-20,13.78,14.63,13.63,14.38,20196200,7.19
    -2000-12-19,14.38,15.25,14.00,14.00,13367200,7.00
    -2000-12-18,14.56,14.63,13.94,14.25,11645000,7.12
    -2000-12-15,14.56,14.69,14.00,14.06,18363800,7.03
    -2000-12-14,15.03,15.25,14.44,14.44,9406600,7.22
    -2000-12-13,15.56,15.56,14.88,15.00,12327200,7.50
    -2000-12-12,15.25,16.00,15.00,15.38,13803400,7.69
    -2000-12-11,15.19,15.38,14.88,15.19,11884000,7.59
    -2000-12-08,14.81,15.31,14.44,15.06,15568200,7.53
    -2000-12-07,14.44,14.88,14.00,14.31,14606600,7.16
    -2000-12-06,14.63,15.00,14.00,14.31,49092400,7.16
    -2000-12-05,16.94,17.44,16.37,17.00,21932200,8.50
    -2000-12-04,17.19,17.19,16.44,16.69,13273400,8.35
    -2000-12-01,17.00,17.50,16.81,17.06,13783800,8.53
    -2000-11-30,16.69,17.00,16.12,16.50,28922200,8.25
    -2000-11-29,18.09,18.31,17.25,17.56,17586200,8.78
    -2000-11-28,18.69,19.00,17.94,18.03,9618200,9.02
    -2000-11-27,19.87,19.94,18.50,18.69,9244000,9.35
    -2000-11-24,18.86,19.50,18.81,19.31,5751800,9.65
    -2000-11-22,18.81,19.12,18.37,18.50,10029600,9.25
    -2000-11-21,19.19,19.50,18.75,18.81,10786200,9.40
    -2000-11-20,18.59,19.50,18.25,18.94,14581600,9.47
    -2000-11-17,19.19,19.25,18.25,18.50,15943400,9.25
    -2000-11-16,19.50,19.81,18.87,19.00,8554000,9.50
    -2000-11-15,20.03,20.19,19.25,19.87,10086600,9.94
    -2000-11-14,19.94,20.50,19.56,20.25,14611200,10.12
    -2000-11-13,18.75,20.00,18.25,19.37,15423200,9.69
    -2000-11-10,19.36,19.87,19.06,19.06,15080600,9.53
    -2000-11-09,19.87,20.50,19.06,20.19,17035400,10.10
    -2000-11-08,21.37,21.44,19.81,20.06,15082800,10.03
    -2000-11-07,21.50,21.81,20.81,21.31,10786800,10.65
    -2000-11-06,22.44,22.62,20.87,21.44,14060000,10.72
    -2000-11-03,23.00,23.00,21.94,22.25,18423400,11.12
    -2000-11-02,21.12,22.44,21.06,22.31,21105400,11.15
    -2000-11-01,19.44,20.87,19.44,20.50,20553800,10.25
    -2000-10-31,19.75,20.25,19.25,19.56,31649000,9.78
    -2000-10-30,19.12,19.94,18.75,19.31,22832800,9.65
    -2000-10-27,18.87,19.19,17.87,18.56,26594600,9.28
    -2000-10-26,18.81,18.87,17.50,18.50,25780600,9.25
    -2000-10-25,19.06,19.19,18.44,18.50,23720600,9.25
    -2000-10-24,20.69,20.87,18.81,18.87,28736200,9.44
    -2000-10-23,20.27,20.56,19.44,20.37,19694000,10.19
    -2000-10-20,19.06,20.37,18.94,19.50,28270400,9.75
    -2000-10-19,19.16,19.81,18.31,18.94,53818200,9.47
    -2000-10-18,19.44,21.06,18.75,20.12,29803800,10.06
    -2000-10-17,21.69,21.94,19.69,20.12,21495600,10.06
    -2000-10-16,22.31,23.25,21.37,21.50,29298800,10.75
    -2000-10-13,20.25,22.12,20.00,22.06,44564000,11.03
    -2000-10-12,20.31,20.81,19.50,20.00,42548200,10.00
    -2000-10-11,20.12,21.00,19.12,19.62,42801200,9.81
    -2000-10-10,21.62,22.44,20.50,20.87,24683400,10.44
    -2000-10-09,22.62,22.87,21.12,21.75,21342600,10.88
    -2000-10-06,22.69,22.94,21.00,22.19,21881000,11.10
    -2000-10-05,23.50,24.50,22.00,22.06,31189400,11.03
    -2000-10-04,22.37,23.75,21.87,23.62,52368200,11.81
    -2000-10-03,24.94,25.00,22.19,22.31,72795600,11.15
    -2000-10-02,26.69,26.75,23.50,24.25,86610600,12.12
    -2000-09-29,28.19,29.00,25.37,25.75,265069000,12.88
    -2000-09-28,49.31,53.81,48.13,53.50,34988200,26.75
    -2000-09-27,51.75,52.75,48.25,48.94,14370000,24.47
    -2000-09-26,53.31,54.75,51.38,51.44,10396600,25.72
    -2000-09-25,52.75,55.50,52.06,53.50,15564000,26.75
    -2000-09-22,50.31,52.44,50.00,52.19,25961200,26.09
    -2000-09-21,58.50,59.63,55.25,56.69,18238400,28.34
    -2000-09-20,59.41,61.44,58.56,61.05,8121600,30.52
    -2000-09-19,59.75,60.50,58.56,59.94,9706200,29.97
    -2000-09-18,55.25,60.75,55.06,60.66,15163200,30.33
    -2000-09-15,57.75,58.19,54.25,55.23,14095400,27.61
    -2000-09-14,58.56,59.63,56.81,56.86,15241800,28.43
    -2000-09-13,56.75,59.50,56.75,58.00,10932600,29.00
    -2000-09-12,57.34,60.06,57.00,57.75,6722200,28.88
    -2000-09-11,58.69,60.38,58.13,58.44,6699000,29.22
    -2000-09-08,61.63,61.63,58.50,58.88,6984400,29.44
    -2000-09-07,59.13,62.56,58.25,62.00,7770400,31.00
    -2000-09-06,61.38,62.38,57.75,58.44,12700400,29.22
    -2000-09-05,62.66,64.12,62.25,62.44,10669000,31.22
    -2000-09-01,61.31,63.63,61.13,63.44,9181800,31.72
    -2000-08-31,58.97,61.50,58.94,60.94,14988800,30.47
    -2000-08-30,59.00,60.00,58.70,59.50,10199600,29.75
    -2000-08-29,57.88,59.44,57.69,59.19,9546200,29.59
    -2000-08-28,57.25,59.00,57.06,58.06,12822600,29.03
    -2000-08-25,56.50,57.50,56.38,56.81,11947800,28.41
    -2000-08-24,54.67,56.63,53.38,56.11,11109400,28.06
    -2000-08-23,51.47,54.75,51.06,54.31,8470400,27.16
    -2000-08-22,50.63,52.81,50.38,51.69,9889000,25.84
    -2000-08-21,50.25,51.56,49.63,50.50,4803800,25.25
    -2000-08-18,51.38,51.81,49.88,50.00,6798800,25.00
    -2000-08-17,48.38,52.44,48.31,51.44,9683400,25.72
    -2000-08-16,46.88,49.00,46.81,48.50,5137600,24.25
    -2000-08-15,47.25,47.94,46.50,46.69,4089000,23.34
    -2000-08-14,47.59,47.69,46.31,47.06,5603400,23.53
    -2000-08-11,46.84,48.00,45.56,47.69,8503200,23.84
    -2000-08-10,48.00,48.44,47.38,47.56,8995400,23.78
    -2000-08-09,48.13,48.44,47.25,47.50,13569000,23.75
    -2000-08-08,47.94,48.00,46.31,46.75,6315400,23.38
    -2000-08-07,47.88,49.06,47.19,47.94,6697200,23.97
    -2000-08-04,49.47,51.25,46.31,47.38,9406800,23.69
    -2000-08-03,45.56,48.06,44.25,48.00,12150000,24.00
    -2000-08-02,49.00,49.94,47.19,47.25,5808800,23.62
    -2000-08-01,50.31,51.16,49.25,49.31,4904600,24.66
    -2000-07-31,49.16,51.63,48.75,50.81,5550000,25.41
    -2000-07-28,52.28,52.50,46.88,48.31,8505400,24.16
    -2000-07-27,50.00,53.25,49.88,52.00,10543800,26.00
    -2000-07-26,49.84,51.25,49.25,50.06,7526200,25.03
    -2000-07-25,50.31,50.63,49.06,50.06,7567200,25.03
    -2000-07-24,52.56,52.88,47.50,48.69,14720600,24.34
    -2000-07-21,54.36,55.63,52.94,53.56,7013200,26.78
    -2000-07-20,55.00,57.06,54.13,55.13,16631800,27.57
    -2000-07-19,55.19,56.81,51.75,52.69,16359600,26.34
    -2000-07-18,58.50,58.88,56.88,57.25,11378200,28.62
    -2000-07-17,58.25,58.81,57.13,58.31,9289000,29.16
    -2000-07-14,57.13,59.00,56.88,57.69,6804400,28.84
    -2000-07-13,58.50,60.63,54.75,56.50,15925600,28.25
    -2000-07-12,58.13,58.94,56.38,58.88,8057600,29.44
    -2000-07-11,57.00,59.25,55.44,56.94,12783200,28.47
    -2000-07-10,54.09,58.25,53.75,57.13,14211000,28.57
    -2000-07-07,52.59,54.81,52.13,54.44,9422600,27.22
    -2000-07-06,52.50,52.94,49.63,51.81,11063800,25.91
    -2000-07-05,53.25,55.19,50.75,51.63,9478800,25.82
    -2000-07-03,52.13,54.31,52.13,53.31,2535000,26.66
    -2000-06-30,52.81,54.94,51.69,52.38,11550000,26.19
    -2000-06-29,53.06,53.94,51.06,51.25,7281200,25.62
    -2000-06-28,53.31,55.38,51.50,54.44,10235000,27.22
    -2000-06-27,53.78,55.50,51.63,51.75,7270600,25.88
    -2000-06-26,52.50,54.75,52.13,54.13,6631000,27.07
    -2000-06-23,53.78,54.63,50.81,51.69,7320400,25.84
    -2000-06-22,55.75,57.63,53.56,53.75,16706200,26.88
    -2000-06-21,50.50,56.94,50.31,55.63,17500000,27.82
    -2000-06-20,98.50,103.94,98.37,101.25,17922000,25.31
    -2000-06-19,90.56,97.87,89.81,96.62,14089200,24.16
    -2000-06-16,93.50,93.75,89.06,91.19,10842400,22.80
    -2000-06-15,91.25,93.37,89.00,92.37,8898800,23.09
    -2000-06-14,94.69,96.25,90.12,90.44,9925200,22.61
    -2000-06-13,91.19,94.69,88.19,94.50,12570000,23.62
    -2000-06-12,96.37,96.44,90.87,91.19,10374400,22.80
    -2000-06-09,96.75,97.94,94.37,95.75,9020000,23.94
    -2000-06-08,97.62,98.50,93.12,94.81,8540800,23.70
    -2000-06-07,93.62,97.00,91.62,96.56,12056800,24.14
    -2000-06-06,91.97,96.75,90.31,92.87,18771200,23.22
    -2000-06-05,93.31,95.25,89.69,91.31,11582000,22.83
    -2000-06-02,93.75,99.75,89.00,92.56,28336400,23.14
    -2000-06-01,81.75,89.56,80.37,89.12,32280000,22.28
    -2000-05-31,86.87,91.25,83.81,84.00,15483600,21.00
    -2000-05-30,87.62,88.12,81.75,87.56,25481200,21.89
    -2000-05-26,88.00,89.87,85.25,86.37,6486400,21.59
    -2000-05-25,88.50,92.66,86.00,87.27,14530800,21.82
    -2000-05-24,86.19,89.75,83.00,87.69,24248000,21.92
    -2000-05-23,90.50,93.37,85.62,85.81,18488000,21.45
    -2000-05-22,93.75,93.75,86.00,89.94,26995200,22.49
    -2000-05-19,99.25,99.25,93.37,94.00,26459200,23.50
    -2000-05-18,103.00,104.94,100.62,100.75,13365600,25.19
    -2000-05-17,103.62,103.69,100.37,101.37,14227600,25.34
    -2000-05-16,104.52,109.06,102.75,105.69,15736400,26.42
    -2000-05-15,108.06,108.06,100.12,101.00,24252000,25.25
    -2000-05-12,106.00,110.50,104.77,107.62,10962000,26.91
    -2000-05-11,101.37,104.25,99.00,102.81,17852400,25.70
    -2000-05-10,104.06,105.00,98.75,99.31,19127600,24.83
    -2000-05-09,110.31,111.25,104.87,105.44,11685600,26.36
    -2000-05-08,112.09,113.69,110.00,110.12,6605600,27.53
    -2000-05-05,110.81,114.75,110.72,113.12,10160000,28.28
    -2000-05-04,115.12,115.25,110.56,110.69,14284400,27.67
    -2000-05-03,118.94,121.25,111.62,115.06,17500000,28.76
    -2000-05-02,123.25,126.25,117.50,117.87,8446400,29.47
    -2000-05-01,124.87,125.12,121.87,124.31,8100000,31.08
    -2000-04-28,127.12,127.50,121.31,124.06,8932400,31.01
    -2000-04-27,117.19,127.00,116.58,126.75,11678000,31.69
    -2000-04-26,126.62,128.00,120.00,121.31,13117600,30.33
    -2000-04-25,122.12,128.75,122.06,128.31,14002400,32.08
    -2000-04-24,115.00,120.50,114.75,120.50,15845600,30.12
    -2000-04-20,123.69,124.75,117.06,118.87,25806800,29.72
    -2000-04-19,126.19,130.25,119.75,121.12,18586400,30.28
    -2000-04-18,123.50,126.87,119.37,126.87,13962400,31.72
    -2000-04-17,109.50,123.94,109.06,123.87,14642400,30.97
    -2000-04-14,109.31,118.00,109.00,111.87,23845600,27.97
    -2000-04-13,111.50,120.00,108.50,113.81,18923600,28.45
    -2000-04-12,119.00,119.00,104.87,109.25,33618800,27.31
    -2000-04-11,123.50,124.87,118.06,119.44,19368000,29.86
    -2000-04-10,131.69,132.75,124.75,125.00,7592400,31.25
    -2000-04-07,127.25,131.88,125.50,131.75,8668800,32.94
    -2000-04-06,130.63,134.50,123.25,125.19,9290800,31.30
    -2000-04-05,126.47,132.88,124.00,130.38,16359200,32.60
    -2000-04-04,132.63,133.00,116.75,127.31,23596400,31.83
    -2000-04-03,135.50,139.50,129.44,133.31,11742400,33.33
    -2000-03-31,127.44,137.25,126.00,135.81,14457600,33.95
    -2000-03-30,133.56,137.69,125.44,125.75,14800000,31.44
    -2000-03-29,139.38,139.44,133.83,135.94,8568800,33.99
    -2000-03-28,137.25,142.00,137.13,139.13,7253600,34.78
    -2000-03-27,137.63,144.75,136.88,139.56,9976800,34.89
    -2000-03-24,142.44,143.94,135.50,138.69,15962000,34.67
    -2000-03-23,142.00,150.38,140.00,141.31,20098000,35.33
    -2000-03-22,132.78,144.38,131.56,144.19,20288800,36.05
    -2000-03-21,122.56,136.75,121.62,134.94,18729200,33.74
    -2000-03-20,123.50,126.25,122.37,123.00,7316400,30.75
    -2000-03-17,120.12,125.00,119.62,125.00,10902400,31.25
    -2000-03-16,117.31,122.00,114.50,121.56,13516800,30.39
    -2000-03-15,115.62,120.25,114.12,116.25,15845200,29.06
    -2000-03-14,121.22,124.25,114.00,114.25,15321200,28.56
    -2000-03-13,122.12,126.50,119.50,121.31,10864400,30.33
    -2000-03-10,121.69,127.94,121.00,125.75,8900800,31.44
    -2000-03-09,120.87,125.00,118.25,122.25,9884400,30.56
    -2000-03-08,122.87,123.94,118.56,122.00,9690800,30.50
    -2000-03-07,126.44,127.44,121.12,122.87,9767600,30.72
    -2000-03-06,126.00,129.13,125.00,125.69,7520000,31.42
    -2000-03-03,124.87,128.23,120.00,128.00,11565200,32.00
    -2000-03-02,127.00,127.94,120.69,122.00,11136800,30.50
    -2000-03-01,118.56,132.06,118.50,130.31,38478000,32.58
    -2000-02-29,113.56,117.25,112.56,114.62,13186800,28.66
    -2000-02-28,110.12,115.00,108.37,113.25,11729200,28.31
    -2000-02-25,114.81,117.00,110.12,110.37,8908000,27.59
    -2000-02-24,117.31,119.12,111.75,115.20,13446400,28.80
    -2000-02-23,113.23,119.00,111.00,116.25,16905600,29.06
    -2000-02-22,110.12,116.94,106.69,113.81,15083200,28.45
    -2000-02-18,114.62,115.37,110.87,111.25,8346800,27.81
    -2000-02-17,115.19,115.50,113.12,114.87,10350000,28.72
    -2000-02-16,117.75,118.12,112.12,114.12,13525200,28.53
    -2000-02-15,115.25,119.94,115.19,119.00,17363600,29.75
    -2000-02-14,109.31,115.87,108.62,115.81,13130000,28.95
    -2000-02-11,113.62,114.12,108.25,108.75,7592000,27.19
    -2000-02-10,112.87,113.87,110.00,113.50,10832400,28.38
    -2000-02-09,114.12,117.12,112.44,112.62,10698000,28.16
    -2000-02-08,114.00,116.12,111.25,114.87,14613600,28.72
    -2000-02-07,108.00,114.25,105.94,114.06,15770800,28.51
    -2000-02-04,103.94,110.00,103.62,108.00,15206800,27.00
    -2000-02-03,100.31,104.25,100.25,103.31,16977600,25.83
    -2000-02-02,100.75,102.12,97.00,98.81,16588800,24.70
    -2000-02-01,104.00,105.00,100.00,100.25,11380000,25.06
    -2000-01-31,101.00,103.87,94.50,103.75,25071200,25.94
    -2000-01-28,108.19,110.87,100.62,101.62,15142000,25.41
    -2000-01-27,108.81,113.00,107.00,110.00,12163600,27.50
    -2000-01-26,110.00,114.19,109.75,110.19,13131200,27.55
    -2000-01-25,105.00,113.12,102.37,112.25,17775200,28.06
    -2000-01-24,108.44,112.75,105.12,106.25,15760000,26.56
    -2000-01-21,114.25,114.25,110.19,111.31,17729200,27.83
    -2000-01-20,115.50,121.50,113.50,113.50,65418800,28.38
    -2000-01-19,105.62,108.75,103.37,106.56,21358000,26.64
    -2000-01-18,101.00,106.00,100.44,103.94,16421200,25.99
    -2000-01-14,100.00,102.25,99.37,100.44,13954400,25.11
    -2000-01-13,94.48,98.75,92.50,96.75,36882400,24.19
    -2000-01-12,95.00,95.50,86.50,87.19,34870800,21.80
    -2000-01-11,95.94,99.37,90.50,92.75,15775200,23.19
    -2000-01-10,102.00,102.25,94.75,97.75,18059200,24.44
    -2000-01-07,96.50,101.00,95.50,99.50,16463200,24.88
    -2000-01-06,106.12,107.00,95.00,95.00,27443200,23.75
    -2000-01-05,103.75,110.56,103.00,104.00,27818000,26.00
    -2000-01-04,108.25,110.62,101.19,102.50,18310000,25.62
    -2000-01-03,104.87,112.50,101.69,111.94,19144400,27.99
    -1999-12-31,100.94,102.87,99.50,102.81,5856400,25.70
    -1999-12-30,102.19,104.12,99.62,100.31,7419200,25.08
    -1999-12-29,96.81,102.19,95.50,100.69,10161200,25.17
    -1999-12-28,99.12,99.62,95.00,98.19,8843200,24.55
    -1999-12-27,104.37,104.44,99.25,99.31,6022000,24.83
    -1999-12-23,101.81,104.25,101.06,103.50,8218800,25.88
    -1999-12-22,102.87,104.56,98.75,99.94,11682000,24.99
    -1999-12-21,98.19,103.06,97.94,102.50,11000000,25.62
    -1999-12-20,99.56,99.62,96.62,98.00,10155200,24.50
    -1999-12-17,100.87,102.00,98.50,100.00,17700800,25.00
    -1999-12-16,98.00,98.37,94.00,98.31,16568000,24.58
    -1999-12-15,93.25,97.25,91.06,97.00,22254400,24.25
    -1999-12-14,98.37,99.75,94.75,94.87,15570800,23.72
    -1999-12-13,102.39,102.50,98.94,99.00,18931200,24.75
    -1999-12-10,105.31,109.25,99.00,103.00,22786800,25.75
    -1999-12-09,111.00,111.00,100.87,105.25,30555600,26.31
    -1999-12-08,116.25,117.87,109.50,110.06,14730800,27.51
    -1999-12-07,116.56,118.00,114.00,117.81,15901200,29.45
    -1999-12-06,114.56,117.31,111.44,116.00,16688000,29.00
    -1999-12-03,112.19,115.56,111.87,115.00,23151200,28.75
    -1999-12-02,103.12,110.62,101.75,110.19,20275600,27.55
    -1999-12-01,101.00,104.50,100.06,103.06,22098000,25.76
    -1999-11-30,98.12,103.75,97.37,97.87,30132400,24.47
    -1999-11-29,94.25,99.75,93.25,94.56,16586800,23.64
    -1999-11-26,94.75,95.50,94.12,95.06,4737600,23.76
    -1999-11-24,93.00,95.00,91.69,94.69,7683600,23.67
    -1999-11-23,91.75,95.25,88.50,92.81,19406400,23.20
    -1999-11-22,91.75,91.75,89.25,90.62,7242400,22.66
    -1999-11-19,89.50,92.87,88.06,92.44,11162000,23.11
    -1999-11-18,91.06,91.12,88.44,89.62,13043600,22.41
    -1999-11-17,90.69,94.75,90.00,90.25,13032000,22.56
    -1999-11-16,90.00,91.75,88.50,91.19,8370000,22.80
    -1999-11-15,89.62,92.87,88.50,89.44,9283600,22.36
    -1999-11-12,91.94,92.00,87.37,90.62,9970000,22.66
    -1999-11-11,91.59,92.62,89.87,92.25,9660000,23.06
    -1999-11-10,88.25,93.25,88.12,91.44,20661200,22.86
    -1999-11-09,94.37,94.50,88.00,89.62,28910000,22.41
    -1999-11-08,87.75,97.73,86.75,96.37,33962400,24.09
    -1999-11-05,84.62,88.37,84.00,88.31,14889200,22.08
    -1999-11-04,82.06,85.37,80.62,83.62,13549200,20.91
    -1999-11-03,81.62,83.25,81.00,81.50,11736800,20.38
    -1999-11-02,78.00,81.69,77.31,80.25,14268800,20.06
    -1999-11-01,80.00,80.69,77.37,77.62,9965600,19.41
    -1999-10-29,78.81,81.06,78.81,80.12,18680800,20.03
    -1999-10-28,77.06,79.00,76.06,77.87,18005200,19.47
    -1999-10-27,74.37,76.62,73.44,76.37,15837600,19.09
    -1999-10-26,74.94,75.50,73.31,75.06,12924400,18.76
    -1999-10-25,74.25,76.12,73.75,74.50,11677600,18.62
    -1999-10-22,77.12,77.25,73.37,73.94,14995200,18.49
    -1999-10-21,72.56,77.06,72.37,76.12,28347600,19.03
    -1999-10-20,70.00,75.25,70.00,75.12,38633600,18.78
    -1999-10-19,71.62,75.00,68.44,68.50,36521200,17.12
    -1999-10-18,73.87,74.25,71.12,73.25,27733600,18.31
    -1999-10-15,71.12,75.81,70.19,74.56,41910000,18.64
    -1999-10-14,69.25,73.31,69.00,73.19,67822400,18.30
    -1999-10-13,66.62,69.50,63.75,64.03,22752000,16.01
    -1999-10-12,67.87,69.62,67.00,67.69,20142000,16.92
    -1999-10-11,66.00,68.25,66.00,66.69,9418000,16.67
    -1999-10-08,66.19,66.31,63.50,65.56,13689200,16.39
    -1999-10-07,68.44,68.62,64.87,66.37,21660800,16.59
    -1999-10-06,69.37,69.62,67.00,67.19,28726400,16.80
    -1999-10-05,65.62,68.12,64.75,67.94,29100800,16.99
    -1999-10-04,62.38,64.87,62.38,64.56,16408800,16.14
    -1999-10-01,62.13,62.44,59.50,61.72,21977600,15.43
    -1999-09-30,59.56,64.19,59.25,63.31,32449200,15.83
    -1999-09-29,60.25,61.25,58.00,59.06,23493600,14.77
    -1999-09-28,61.50,62.00,57.44,59.63,50542400,14.91
    -1999-09-27,66.37,66.75,61.19,61.31,33877600,15.33
    -1999-09-24,63.38,67.02,63.00,64.94,42148800,16.24
    -1999-09-23,71.12,71.25,63.00,63.31,40853200,15.83
    -1999-09-22,69.75,71.62,69.02,70.31,40132000,17.58
    -1999-09-21,73.19,73.25,69.00,69.25,119931200,17.31
    -1999-09-20,77.00,80.12,76.87,79.06,16326400,19.76
    -1999-09-17,77.31,77.75,76.25,76.94,9915600,19.24
    -1999-09-16,76.06,78.06,73.87,76.81,15793600,19.20
    -1999-09-15,78.87,79.12,75.25,75.37,12843200,18.84
    -1999-09-14,74.72,78.50,74.69,77.81,13883200,19.45
    -1999-09-13,77.06,77.06,74.81,75.00,9000000,18.75
    -1999-09-10,76.00,77.69,74.69,77.44,16398000,19.36
    -1999-09-09,75.50,75.94,73.87,75.56,19093600,18.89
    -1999-09-08,76.19,77.69,74.50,74.50,27233600,18.62
    -1999-09-07,73.75,77.94,73.50,76.37,35177600,19.09
    -1999-09-03,71.94,75.25,70.50,73.50,58403600,18.38
    -1999-09-02,67.62,71.44,66.87,70.56,31975200,17.64
    -1999-09-01,67.00,68.81,66.00,68.62,28168000,17.16
    -1999-08-31,62.59,65.87,62.06,65.25,22675200,16.31
    -1999-08-30,65.00,65.00,62.00,62.06,12033200,15.52
    -1999-08-27,62.75,65.00,62.69,64.75,15980000,16.19
    -1999-08-26,61.13,63.13,61.13,62.13,14449200,15.53
    -1999-08-25,60.69,61.50,60.13,61.38,10553600,15.35
    -1999-08-24,60.38,60.75,59.94,60.38,17948000,15.10
    -1999-08-23,59.38,61.38,59.31,60.75,12709200,15.19
    -1999-08-20,59.25,59.38,58.19,59.19,11730800,14.80
    -1999-08-19,59.81,60.50,58.56,58.75,19645600,14.69
    -1999-08-18,60.06,62.00,59.63,60.13,16743200,15.03
    -1999-08-17,60.31,60.38,58.94,60.31,11474400,15.08
    -1999-08-16,59.81,60.69,59.50,60.50,9896400,15.12
    -1999-08-13,60.63,62.00,59.88,60.06,10668800,15.02
    -1999-08-12,59.06,61.38,58.63,60.00,23806400,15.00
    -1999-08-11,56.00,59.75,55.94,59.69,30374400,14.92
    -1999-08-10,54.00,56.00,53.63,55.38,14879200,13.85
    -1999-08-09,54.34,55.19,54.25,54.44,8338000,13.61
    -1999-08-06,54.06,55.31,53.50,54.13,15575600,13.53
    -1999-08-05,53.50,54.88,52.13,54.75,11541200,13.69
    -1999-08-04,55.19,55.88,53.25,53.81,13279200,13.45
    -1999-08-03,56.75,57.44,53.63,55.25,13176800,13.81
    -1999-08-02,55.63,58.00,55.50,55.75,12958000,13.94
    -1999-07-30,54.50,56.13,54.50,55.69,13685600,13.92
    -1999-07-29,53.38,55.25,53.13,53.88,9860000,13.47
    -1999-07-28,53.88,55.38,53.00,54.38,11762000,13.60
    -1999-07-27,52.63,53.94,52.50,53.69,14150800,13.42
    -1999-07-26,52.88,53.00,50.88,50.94,12555200,12.73
    -1999-07-23,52.81,53.75,52.69,53.31,8192000,13.33
    -1999-07-22,53.63,53.88,51.13,52.38,14529200,13.10
    -1999-07-21,54.06,55.44,52.88,54.06,25653600,13.52
    -1999-07-20,54.56,55.50,52.75,52.88,15804400,13.22
    -1999-07-19,53.94,55.81,52.31,54.44,20050000,13.61
    -1999-07-16,53.63,54.50,53.00,53.06,14705600,13.27
    -1999-07-15,55.88,55.94,51.31,53.25,60433600,13.31
    -1999-07-14,54.50,56.63,54.50,55.94,22320000,13.98
    -1999-07-13,53.50,54.19,52.88,53.69,10136800,13.42
    -1999-07-12,55.50,55.63,54.19,54.50,10862000,13.62
    -1999-07-09,54.50,55.63,53.00,55.63,21750000,13.91
    -1999-07-08,51.13,55.06,50.88,54.50,58058000,13.62
    -1999-07-07,47.38,50.75,47.00,49.88,39264400,12.47
    -1999-07-06,45.94,47.63,45.81,47.38,16212000,11.85
    -1999-07-02,45.53,46.88,45.19,46.31,4426800,11.58
    -1999-07-01,46.31,46.56,45.25,45.31,5334400,11.33
    -1999-06-30,45.69,46.94,44.94,46.31,12270800,11.58
    -1999-06-29,42.72,45.56,42.63,45.38,13599200,11.35
    -1999-06-28,42.44,42.94,42.38,42.56,9938800,10.64
    -1999-06-25,42.50,42.69,42.06,42.19,10518800,10.55
    -1999-06-24,43.63,43.63,42.25,42.31,15498000,10.58
    -1999-06-23,45.06,45.09,43.56,43.69,18994400,10.92
    -1999-06-22,46.31,46.94,45.38,45.38,5415600,11.35
    -1999-06-21,47.00,47.25,46.00,46.50,4842000,11.62
    -1999-06-18,45.38,47.25,45.19,47.13,7448000,11.78
    -1999-06-17,47.63,48.00,45.75,46.38,8022400,11.60
    -1999-06-16,46.38,48.06,46.38,47.94,8056800,11.98
    -1999-06-15,45.19,46.75,45.13,46.06,4666400,11.52
    -1999-06-14,46.50,46.63,45.13,45.44,5615600,11.36
    -1999-06-11,48.13,48.50,46.25,46.44,6613600,11.61
    -1999-06-10,47.88,48.25,47.31,48.13,11325200,12.03
    -1999-06-09,47.44,48.50,47.44,48.44,12655200,12.11
    -1999-06-08,48.75,48.81,47.56,47.69,11203200,11.92
    -1999-06-07,48.13,49.00,47.50,48.94,14949200,12.23
    -1999-06-04,47.63,48.19,47.25,48.13,13171200,12.03
    -1999-06-03,46.88,48.00,46.81,47.44,17450800,11.86
    -1999-06-02,44.50,47.94,44.00,46.56,18614400,11.64
    -1999-06-01,45.00,45.31,44.38,44.81,16479200,11.20
    -1999-05-28,43.31,44.31,43.13,44.06,7196400,11.02
    -1999-05-27,43.19,43.75,42.69,43.50,12042400,10.88
    -1999-05-26,41.75,44.38,41.25,44.06,15642000,11.02
    -1999-05-25,41.56,42.44,40.94,41.50,13095200,10.38
    -1999-05-24,43.63,44.31,41.88,41.94,9340800,10.48
    -1999-05-21,43.00,44.31,42.56,43.94,16555200,10.98
    -1999-05-20,45.44,45.75,42.50,42.50,14940000,10.62
    -1999-05-19,45.50,45.75,43.50,45.19,10660000,11.30
    -1999-05-18,44.81,46.00,44.38,45.25,14954400,11.31
    -1999-05-17,43.75,44.69,43.00,44.38,7531200,11.10
    -1999-05-14,45.13,45.81,44.38,44.38,8102000,11.10
    -1999-05-13,46.44,46.81,45.50,46.19,10573600,11.55
    -1999-05-12,44.88,46.50,44.13,46.50,14129200,11.62
    -1999-05-11,44.88,46.19,43.56,44.75,16388800,11.19
    -1999-05-10,46.75,46.94,44.63,45.25,14055600,11.31
    -1999-05-07,44.63,45.88,42.75,45.88,15528800,11.47
    -1999-05-06,46.56,46.88,44.00,44.50,15486400,11.12
    -1999-05-05,46.31,47.00,44.63,47.00,20694400,11.75
    -1999-05-04,48.25,48.63,46.19,46.50,28980000,11.62
    -1999-05-03,46.06,50.00,45.75,49.56,52535600,12.39
    -1999-04-30,44.00,47.13,44.00,46.00,52596400,11.50
    -1999-04-29,43.25,44.38,41.78,43.00,28206400,10.75
    -1999-04-28,44.63,45.69,43.63,44.06,34122000,11.02
    -1999-04-27,43.00,45.81,43.00,45.75,75225200,11.44
    -1999-04-26,39.50,41.25,39.25,40.94,33152000,10.23
    -1999-04-23,36.25,39.44,36.25,39.19,37402400,9.80
    -1999-04-22,35.06,36.63,35.06,36.38,26454400,9.10
    -1999-04-21,34.00,34.38,33.50,34.38,12566800,8.60
    -1999-04-20,33.88,34.75,33.50,34.06,18725600,8.52
    -1999-04-19,35.69,36.00,33.50,33.88,32923200,8.47
    -1999-04-16,35.88,36.06,35.25,35.44,17945600,8.86
    -1999-04-15,35.38,36.19,34.31,35.75,61960000,8.94
    -1999-04-14,35.25,37.06,35.00,35.53,24323600,8.88
    -1999-04-13,36.31,36.81,34.50,34.63,14732400,8.66
    -1999-04-12,35.00,36.88,34.88,36.25,14145600,9.06
    -1999-04-09,36.25,37.25,35.94,36.75,9608000,9.19
    -1999-04-08,36.88,37.06,36.00,36.88,10600800,9.22
    -1999-04-07,38.06,38.25,36.38,37.13,14723200,9.28
    -1999-04-06,36.81,38.31,36.81,38.00,22455200,9.50
    -1999-04-05,36.00,37.88,36.00,37.06,16474400,9.27
    -1999-04-01,36.06,36.69,35.75,36.06,9381200,9.02
    -1999-03-31,36.38,37.13,35.88,35.94,15086400,8.98
    -1999-03-30,35.00,36.38,35.00,35.88,19806800,8.97
    -1999-03-29,33.50,35.44,33.44,35.38,20337600,8.85
    -1999-03-26,33.75,33.81,33.00,33.25,9080000,8.31
    -1999-03-25,34.38,34.88,33.38,33.81,14286800,8.45
    -1999-03-24,33.25,33.75,32.50,33.69,14297600,8.42
    -1999-03-23,34.44,34.44,32.75,33.00,14842000,8.25
    -1999-03-22,34.00,35.19,32.94,35.06,21200800,8.77
    -1999-03-19,35.94,36.00,32.88,33.50,19161200,8.38
    -1999-03-18,34.38,35.63,34.25,35.50,8126800,8.88
    -1999-03-17,35.94,36.06,33.94,34.06,13084400,8.52
    -1999-03-16,35.00,35.56,34.94,35.50,14302000,8.88
    -1999-03-15,33.31,35.00,33.25,34.06,12586800,8.52
    -1999-03-12,32.31,33.50,32.31,33.19,9700000,8.30
    -1999-03-11,32.25,33.88,32.00,32.19,16936800,8.05
    -1999-03-10,34.19,34.19,32.44,32.56,19526800,8.14
    -1999-03-09,34.31,34.38,33.50,34.13,11427600,8.53
    -1999-03-08,33.25,34.69,33.19,34.38,19682000,8.60
    -1999-03-05,34.31,34.31,32.38,33.19,16735600,8.30
    -1999-03-04,34.50,34.50,32.38,33.44,13137600,8.36
    -1999-03-03,34.75,35.13,33.50,34.19,10497600,8.55
    -1999-03-02,34.13,35.31,33.75,34.63,24414400,8.66
    -1999-03-01,34.81,34.81,33.63,33.75,17435200,8.44
    -1999-02-26,36.50,37.00,34.50,34.81,23847600,8.70
    -1999-02-25,37.31,37.69,36.50,36.94,9455600,9.23
    -1999-02-24,38.81,39.00,37.38,37.44,7620000,9.36
    -1999-02-23,38.56,39.56,37.94,38.44,11521200,9.61
    -1999-02-22,37.38,38.88,37.25,38.44,10682000,9.61
    -1999-02-19,36.25,37.69,36.19,37.19,12938800,9.30
    -1999-02-18,37.56,37.88,35.56,36.00,17876400,9.00
    -1999-02-17,38.13,38.69,36.94,37.00,10581200,9.25
    -1999-02-16,38.88,38.88,37.88,38.31,10723600,9.58
    -1999-02-12,39.13,39.13,37.00,37.69,15339200,9.42
    -1999-02-11,38.75,39.75,38.56,39.63,20200000,9.91
    -1999-02-10,36.88,38.69,36.00,38.31,20135200,9.58
    -1999-02-09,37.94,39.06,37.06,37.19,25042000,9.30
    -1999-02-08,36.69,37.94,36.25,37.75,16723600,9.44
    -1999-02-05,38.25,38.38,35.50,36.31,27778000,9.08
    -1999-02-04,40.19,40.25,37.75,37.88,16565600,9.47
    -1999-02-03,39.00,40.56,38.75,40.19,12108000,10.05
    -1999-02-02,40.38,40.75,39.00,39.19,10975600,9.80
    -1999-02-01,41.69,41.94,40.31,40.94,9962000,10.23
    -1999-01-29,41.19,41.56,40.00,41.19,8684400,10.30
    -1999-01-28,40.88,41.25,40.31,40.88,12015600,10.22
    -1999-01-27,41.00,41.38,39.94,40.13,13053200,10.03
    -1999-01-26,39.94,40.88,39.63,40.50,20002400,10.12
    -1999-01-25,39.25,39.56,38.81,39.38,13763200,9.85
    -1999-01-22,37.69,39.50,37.06,38.75,12365200,9.69
    -1999-01-21,40.44,40.56,37.50,38.81,21449200,9.70
    -1999-01-20,41.06,42.00,40.50,40.56,27806800,10.14
    -1999-01-19,41.94,42.31,40.38,40.88,19116400,10.22
    -1999-01-15,41.81,42.13,40.00,41.31,35933600,10.33
    -1999-01-14,45.50,46.00,41.06,41.38,61570000,10.35
    -1999-01-13,42.88,47.31,42.25,46.50,37434400,11.62
    -1999-01-12,46.31,46.63,44.13,46.13,29330000,11.53
    -1999-01-11,45.75,46.06,44.88,45.88,20054400,11.47
    -1999-01-08,46.56,46.88,44.00,45.00,24246400,11.25
    -1999-01-07,42.25,45.06,42.13,45.00,51056800,11.25
    -1999-01-06,44.13,44.13,41.00,41.75,48165200,10.44
    -1999-01-05,41.94,43.94,41.50,43.31,50362000,10.83
    -1999-01-04,42.13,42.25,40.00,41.25,34049200,10.31
    -1998-12-31,40.50,41.38,39.50,40.94,9716400,10.23
    -1998-12-30,40.13,41.13,40.00,40.06,8498000,10.02
    -1998-12-29,41.13,41.50,40.25,40.81,13853200,10.20
    -1998-12-28,39.00,41.13,39.00,40.88,25917600,10.22
    -1998-12-24,39.88,40.00,39.19,39.25,7155200,9.81
    -1998-12-23,38.63,40.50,38.38,39.81,44124400,9.95
    -1998-12-22,36.38,38.13,36.00,38.00,41111200,9.50
    -1998-12-21,35.38,35.63,34.25,35.06,12769200,8.77
    -1998-12-18,33.38,35.38,33.25,35.19,28283200,8.80
    -1998-12-17,32.94,33.75,32.75,33.44,11812000,8.36
    -1998-12-16,33.75,34.19,32.63,32.81,13375200,8.20
    -1998-12-15,32.75,33.63,32.75,33.56,9462000,8.39
    -1998-12-14,32.88,33.31,32.25,32.50,17925200,8.12
    -1998-12-11,32.25,34.00,32.00,33.75,24644400,8.44
    -1998-12-10,32.69,32.94,31.87,32.00,13980800,8.00
    -1998-12-09,32.69,32.88,31.62,32.00,21184400,8.00
    -1998-12-08,33.94,33.94,32.00,32.06,24295200,8.02
    -1998-12-07,33.38,33.75,32.75,33.75,20255600,8.44
    -1998-12-04,34.31,34.44,32.00,32.75,25765200,8.19
    -1998-12-03,36.31,36.50,33.63,33.69,22380800,8.42
    -1998-12-02,34.13,36.88,33.50,36.00,34382400,9.00
    -1998-12-01,32.00,34.81,31.62,34.13,30941200,8.53
    -1998-11-30,34.56,34.81,31.75,31.94,20060800,7.99
    -1998-11-27,35.06,35.13,34.75,35.06,5483600,8.77
    -1998-11-25,35.88,36.06,34.94,35.13,10855600,8.78
    -1998-11-24,36.13,36.75,35.75,35.94,11430800,8.98
    -1998-11-23,35.56,36.81,35.19,36.25,20642000,9.06
    -1998-11-20,36.44,36.75,34.75,35.31,14268000,8.83
    -1998-11-19,35.50,37.19,35.44,35.75,12385200,8.94
    -1998-11-18,35.19,36.00,34.88,35.44,11781200,8.86
    -1998-11-17,35.75,35.81,34.75,34.81,7529200,8.70
    -1998-11-16,35.94,36.75,35.44,36.00,13740800,9.00
    -1998-11-13,34.94,36.06,34.69,35.69,28301200,8.92
    -1998-11-12,33.13,34.44,32.88,34.00,21261200,8.50
    -1998-11-11,35.75,35.81,32.75,33.56,33895200,8.39
    -1998-11-10,36.19,36.25,35.00,35.13,31576800,8.78
    -1998-11-09,37.69,38.13,35.50,36.63,23622000,9.16
    -1998-11-06,37.88,38.25,37.25,38.06,28496800,9.52
    -1998-11-05,38.38,39.38,38.06,38.19,21684400,9.55
    -1998-11-04,38.56,39.13,38.13,38.69,22438000,9.67
    -1998-11-03,37.38,38.25,37.31,37.81,13247600,9.45
    -1998-11-02,37.50,37.75,37.25,37.63,9076400,9.41
    -1998-10-30,36.81,37.50,36.25,37.13,11358000,9.28
    -1998-10-29,36.44,37.44,35.81,36.44,12321200,9.11
    -1998-10-28,35.25,37.00,35.13,36.81,13006400,9.20
    -1998-10-27,38.00,38.94,35.06,35.25,19233200,8.81
    -1998-10-26,36.06,37.75,35.50,37.44,17013600,9.36
    -1998-10-23,36.75,36.88,35.13,35.50,12732400,8.88
    -1998-10-22,36.88,37.63,36.25,36.75,11343200,9.19
    -1998-10-21,36.75,37.44,35.75,37.13,15390000,9.28
    -1998-10-20,37.94,38.19,36.00,36.06,13649200,9.02
    -1998-10-19,36.69,38.06,35.88,37.50,17010000,9.38
    -1998-10-16,37.13,38.06,36.50,36.69,21998000,9.17
    -1998-10-15,36.25,37.25,35.50,36.63,30037600,9.16
    -1998-10-14,39.75,41.31,36.81,37.38,81445600,9.35
    -1998-10-13,38.06,39.19,36.00,38.75,33646400,9.69
    -1998-10-12,37.50,38.44,36.56,37.44,22250000,9.36
    -1998-10-09,31.75,35.25,30.75,35.13,23880000,8.78
    -1998-10-08,31.00,31.19,28.50,30.81,24623200,7.70
    -1998-10-07,32.38,33.31,31.87,31.94,16920000,7.99
    -1998-10-06,33.69,34.31,32.50,32.56,14281200,8.14
    -1998-10-05,34.00,34.56,31.50,32.19,19726800,8.05
    -1998-10-02,35.50,36.25,34.13,35.06,16998800,8.77
    -1998-10-01,36.75,38.00,35.38,35.69,13234400,8.92
    -1998-09-30,38.75,39.25,38.00,38.13,5976800,9.53
    -1998-09-29,39.06,40.00,38.13,39.50,10907600,9.88
    -1998-09-28,39.75,40.19,38.00,39.06,14501200,9.77
    -1998-09-25,38.19,39.19,37.63,38.75,8172000,9.69
    -1998-09-24,37.88,39.56,37.75,38.50,17246800,9.62
    -1998-09-23,37.25,38.38,36.56,38.31,10284400,9.58
    -1998-09-22,37.13,37.63,36.38,37.00,9218800,9.25
    -1998-09-21,35.69,36.94,35.31,36.94,10570800,9.23
    -1998-09-18,36.06,36.75,35.56,36.75,10904400,9.19
    -1998-09-17,36.06,37.13,35.88,36.00,9627600,9.00
    -1998-09-16,38.63,38.75,37.00,37.31,9248800,9.33
    -1998-09-15,36.75,38.56,36.50,38.19,15492000,9.55
    -1998-09-14,38.25,38.81,37.13,37.19,8837600,9.30
    -1998-09-11,38.50,39.63,36.88,37.63,12593600,9.41
    -1998-09-10,36.25,38.25,35.75,38.13,18826800,9.53
    -1998-09-09,38.06,38.13,37.00,37.38,12683200,9.35
    -1998-09-08,38.00,38.25,36.75,38.25,14400000,9.56
    -1998-09-04,35.50,36.44,33.75,35.13,13493200,8.78
    -1998-09-03,35.00,35.13,34.00,34.63,14653200,8.66
    -1998-09-02,35.50,37.38,35.25,35.56,30122400,8.89
    -1998-09-01,31.37,35.38,30.62,34.13,31060000,8.53
    -1998-08-31,34.75,34.88,31.00,31.19,31012400,7.80
    -1998-08-28,37.13,38.50,34.13,34.19,33303200,8.55
    -1998-08-27,39.25,39.25,35.63,37.50,39813600,9.38
    -1998-08-26,39.88,41.13,39.50,40.38,14538000,10.10
    -1998-08-25,42.38,42.38,40.31,40.81,17709200,10.20
    -1998-08-24,43.44,43.50,40.13,41.19,21810000,10.30
    -1998-08-21,40.00,43.56,39.00,43.00,29054400,10.75
    -1998-08-20,41.00,41.13,40.25,40.63,14018000,10.16
    -1998-08-19,43.50,43.75,41.00,41.00,17377600,10.25
    -1998-08-18,42.44,43.38,42.25,42.56,21642000,10.64
    -1998-08-17,41.00,42.81,39.88,41.94,33248800,10.48
    -1998-08-14,40.69,40.75,39.50,40.50,16110000,10.12
    -1998-08-13,39.94,40.75,39.38,39.44,13976800,9.86
    -1998-08-12,39.75,40.94,39.48,40.06,24654400,10.02
    -1998-08-11,37.75,41.00,37.38,39.00,62860000,9.75
    -1998-08-10,36.31,38.06,36.25,37.94,17455600,9.48
    -1998-08-07,37.19,37.38,36.00,36.50,10645600,9.12
    -1998-08-06,35.06,36.88,34.88,36.88,15678800,9.22
    -1998-08-05,33.75,36.00,33.50,36.00,16226800,9.00
    -1998-08-04,35.50,36.00,34.00,34.19,10506800,8.55
    -1998-08-03,34.25,35.56,33.25,35.13,10786800,8.78
    -1998-07-31,36.63,36.75,34.50,34.63,6550800,8.66
    -1998-07-30,35.81,36.75,35.50,36.50,12950000,9.12
    -1998-07-29,33.75,35.88,33.69,35.13,16006800,8.78
    -1998-07-28,34.06,34.63,33.00,33.63,8054400,8.41
    -1998-07-27,34.25,34.88,33.25,34.44,7657600,8.61
    -1998-07-24,35.38,35.50,33.81,34.69,9693600,8.67
    -1998-07-23,34.81,35.63,34.75,34.94,9040800,8.73
    -1998-07-22,34.94,35.63,34.25,35.00,10040800,8.75
    -1998-07-21,36.13,37.00,35.56,35.63,11772400,8.91
    -1998-07-20,36.56,36.63,35.50,36.25,13727600,9.06
    -1998-07-17,37.25,37.25,36.19,36.88,22486400,9.22
    -1998-07-16,37.88,38.13,35.75,37.50,91497600,9.38
    -1998-07-15,33.69,34.69,33.50,34.44,21253600,8.61
    -1998-07-14,33.94,34.00,33.13,33.44,19607600,8.36
    -1998-07-13,31.94,34.13,31.87,33.94,25566400,8.48
    -1998-07-10,32.19,32.63,31.75,32.06,10806800,8.02
    -1998-07-09,32.94,33.63,31.44,31.69,20256400,7.92
    -1998-07-08,30.75,32.94,30.69,32.56,33334400,8.14
    -1998-07-07,30.37,30.87,30.00,30.50,8637600,7.62
    -1998-07-06,29.50,30.37,29.12,30.37,9697600,7.59
    -1998-07-02,29.69,30.06,29.00,29.00,10650800,7.25
    -1998-07-01,28.87,30.00,28.50,29.94,11228800,7.49
    -1998-06-30,28.62,28.81,28.12,28.69,4681200,7.17
    -1998-06-29,28.25,28.81,28.06,28.69,5943600,7.17
    -1998-06-26,28.50,28.62,27.75,28.19,3973200,7.05
    -1998-06-25,28.56,28.81,28.31,28.56,6856400,7.14
    -1998-06-24,27.75,28.62,27.31,28.25,9788800,7.06
    -1998-06-23,27.44,28.12,27.25,27.81,8258800,6.95
    -1998-06-22,27.00,27.56,26.75,27.37,4809200,6.84
    -1998-06-19,27.37,27.44,26.75,27.06,4931200,6.76
    -1998-06-18,27.75,28.06,27.19,27.31,4288800,6.83
    -1998-06-17,28.00,28.56,27.94,28.12,6687600,7.03
    -1998-06-16,27.69,28.12,27.31,28.00,4649200,7.00
    -1998-06-15,27.25,28.25,27.25,27.50,4881200,6.88
    -1998-06-12,27.62,28.25,27.37,28.12,8014400,7.03
    -1998-06-11,28.19,28.62,27.81,27.81,6451200,6.95
    -1998-06-10,28.00,29.00,27.62,28.06,8202000,7.01
    -1998-06-09,27.37,28.50,27.37,28.25,9852400,7.06
    -1998-06-08,27.00,27.69,26.81,27.25,4523600,6.81
    -1998-06-05,26.87,27.25,26.37,26.87,4406800,6.72
    -1998-06-04,26.62,26.87,25.81,26.81,5585600,6.70
    -1998-06-03,27.12,27.25,26.19,26.31,5196800,6.58
    -1998-06-02,26.44,27.31,26.00,26.87,6405600,6.72
    -1998-06-01,26.50,27.62,25.62,26.25,11427600,6.56
    -1998-05-29,27.50,27.56,26.44,26.62,7751200,6.66
    -1998-05-28,26.75,27.87,26.75,27.44,10672000,6.86
    -1998-05-27,25.69,26.81,25.62,26.75,13233200,6.69
    -1998-05-26,28.06,28.25,26.62,26.69,11143200,6.67
    -1998-05-22,28.75,28.75,27.31,27.87,9522000,6.97
    -1998-05-21,29.56,29.69,28.62,28.87,4700000,7.22
    -1998-05-20,29.62,29.87,28.75,29.56,6810000,7.39
    -1998-05-19,28.94,29.44,28.81,29.37,7815200,7.34
    -1998-05-18,29.37,29.56,28.37,28.50,8310800,7.12
    -1998-05-15,30.06,30.37,29.25,29.56,9743600,7.39
    -1998-05-14,30.37,30.44,29.75,30.06,5815600,7.51
    -1998-05-13,30.06,30.81,29.62,30.44,11245600,7.61
    -1998-05-12,30.56,30.75,29.94,30.12,9212000,7.53
    -1998-05-11,30.87,31.62,30.75,30.94,23768000,7.74
    -1998-05-08,30.06,30.50,29.94,30.44,9690000,7.61
    -1998-05-07,30.56,30.62,29.87,30.19,19761200,7.55
    -1998-05-06,29.87,30.44,29.25,30.31,32056400,7.58
    -1998-05-05,29.25,29.87,29.12,29.69,14982400,7.42
    -1998-05-04,28.87,29.50,28.87,29.06,20419200,7.26
    -1998-05-01,27.50,28.25,26.87,28.00,6582000,7.00
    -1998-04-30,27.37,27.62,27.06,27.37,6442000,6.84
    -1998-04-29,26.94,27.44,26.75,27.00,6774400,6.75
    -1998-04-28,27.87,28.00,26.25,26.94,8487600,6.74
    -1998-04-27,26.75,27.75,26.75,27.75,14655600,6.94
    -1998-04-24,27.75,28.25,27.50,27.94,7708000,6.99
    -1998-04-23,27.44,29.00,27.19,27.69,16983200,6.92
    -1998-04-22,28.75,29.00,27.50,27.50,10186400,6.88
    -1998-04-21,29.06,29.12,28.50,29.00,12446400,7.25
    -1998-04-20,27.62,29.50,27.56,29.00,18498800,7.25
    -1998-04-17,28.56,28.62,27.69,27.94,21165200,6.99
    -1998-04-16,29.25,29.62,28.19,28.62,65642000,7.16
    -1998-04-15,27.19,27.50,26.62,27.44,19928800,6.86
    -1998-04-14,26.37,27.25,26.37,26.94,11725200,6.74
    -1998-04-13,25.62,26.69,25.00,26.44,10305600,6.61
    -1998-04-09,25.06,25.87,25.00,25.62,6083600,6.41
    -1998-04-08,25.25,25.37,24.69,25.00,8044400,6.25
    -1998-04-07,25.81,26.00,24.87,25.50,10461200,6.38
    -1998-04-06,27.00,27.00,26.19,26.25,12422000,6.56
    -1998-04-03,27.12,27.25,26.81,27.06,7259200,6.76
    -1998-04-02,27.31,27.44,26.94,27.31,6950800,6.83
    -1998-04-01,27.44,27.81,27.06,27.50,6693600,6.88
    -1998-03-31,27.44,27.81,27.25,27.50,9538800,6.88
    -1998-03-30,26.75,27.50,26.75,27.44,8972400,6.86
    -1998-03-27,26.62,27.31,26.37,26.94,9133200,6.74
    -1998-03-26,26.75,27.00,26.44,26.56,7253600,6.64
    -1998-03-25,27.62,27.75,26.37,27.16,13854400,6.79
    -1998-03-24,26.37,28.00,26.25,28.00,24152000,7.00
    -1998-03-23,25.94,26.25,24.62,26.12,14818800,6.53
    -1998-03-20,26.69,26.87,26.00,26.37,7704400,6.59
    -1998-03-19,26.87,26.94,26.56,26.75,5736800,6.69
    -1998-03-18,26.00,26.94,26.00,26.94,9900000,6.74
    -1998-03-17,26.50,26.69,25.87,26.34,14658800,6.59
    -1998-03-16,27.12,27.25,26.19,26.69,14375600,6.67
    -1998-03-13,27.25,27.25,26.25,27.12,20231200,6.78
    -1998-03-12,26.12,27.00,25.56,27.00,26598000,6.75
    -1998-03-11,25.12,26.19,24.56,26.12,43374400,6.53
    -1998-03-10,23.00,24.50,22.94,24.06,25472400,6.01
    -1998-03-09,23.75,24.31,22.50,22.75,20540800,5.69
    -1998-03-06,23.87,24.50,23.37,24.44,23803600,6.11
    -1998-03-05,23.25,24.25,23.12,24.06,24129200,6.01
    -1998-03-04,22.87,24.75,22.87,24.44,29212400,6.11
    -1998-03-03,21.87,23.19,21.62,23.12,11937600,5.78
    -1998-03-02,23.56,23.56,22.25,22.75,14313600,5.69
    -1998-02-27,23.31,23.87,22.56,23.62,18578000,5.91
    -1998-02-26,22.31,23.56,21.87,23.50,21263200,5.88
    -1998-02-25,21.31,22.75,20.94,22.31,25459200,5.58
    -1998-02-24,21.31,21.37,20.75,21.31,16322000,5.33
    -1998-02-23,20.12,21.62,20.00,21.25,17060800,5.31
    -1998-02-20,20.50,20.56,19.81,20.00,11634400,5.00
    -1998-02-19,20.87,20.94,20.00,20.44,14292400,5.11
    -1998-02-18,19.56,20.75,19.56,20.56,17677600,5.14
    -1998-02-17,19.50,19.75,19.50,19.62,6530800,4.91
    -1998-02-13,19.19,19.87,19.00,19.50,7444400,4.88
    -1998-02-12,19.12,19.44,19.06,19.37,7297600,4.84
    -1998-02-11,19.50,19.50,18.87,19.00,7582000,4.75
    -1998-02-10,19.12,19.56,19.06,19.44,15090000,4.86
    -1998-02-09,18.37,19.50,18.37,19.19,17682000,4.80
    -1998-02-06,18.37,18.69,18.25,18.50,7241200,4.62
    -1998-02-05,18.25,18.50,18.00,18.31,8526400,4.58
    -1998-02-04,18.06,18.50,18.00,18.25,6100000,4.56
    -1998-02-03,17.69,18.62,17.69,18.31,14390000,4.58
    -1998-02-02,18.50,18.50,17.37,17.69,22752400,4.42
    -1998-01-30,18.31,18.87,18.25,18.31,5802400,4.58
    -1998-01-29,18.94,19.12,18.50,18.50,7571200,4.62
    -1998-01-28,19.19,19.37,18.62,19.19,5418000,4.80
    -1998-01-27,19.19,19.69,19.00,19.12,4013200,4.78
    -1998-01-26,19.44,19.56,18.81,19.44,5246800,4.86
    -1998-01-23,19.37,19.69,19.25,19.50,8331200,4.88
    -1998-01-22,18.69,19.75,18.62,19.25,11785200,4.81
    -1998-01-21,18.75,19.06,18.56,18.91,6812000,4.73
    -1998-01-20,19.06,19.31,18.62,19.06,8642400,4.76
    -1998-01-16,19.44,19.44,18.69,18.81,8820000,4.70
    -1998-01-15,19.19,19.75,18.62,19.19,19982000,4.80
    -1998-01-14,19.87,19.94,19.25,19.75,21048000,4.94
    -1998-01-13,18.62,19.62,18.50,19.50,22758800,4.88
    -1998-01-12,17.44,18.62,17.12,18.25,18444400,4.56
    -1998-01-09,18.12,19.37,17.50,18.19,31675200,4.55
    -1998-01-08,17.44,18.62,16.94,18.19,27645600,4.55
    -1998-01-07,18.81,19.00,17.31,17.50,37201200,4.38
    -1998-01-06,15.94,20.00,14.75,18.94,64737600,4.74
    -1998-01-05,16.50,16.56,15.19,15.88,23282000,3.97
    -1998-01-02,13.63,16.25,13.50,16.25,25650800,4.06
    -1997-12-31,13.13,13.63,12.94,13.13,14531200,3.28
    -1997-12-30,13.00,13.44,12.75,13.19,12250800,3.30
    -1997-12-29,13.31,13.44,12.88,13.13,9944400,3.28
    -1997-12-26,13.06,13.38,13.00,13.31,3860000,3.33
    -1997-12-24,13.00,13.25,13.00,13.13,3502000,3.28
    -1997-12-23,13.13,13.31,12.94,12.94,16402000,3.23
    -1997-12-22,13.88,14.00,13.19,13.31,5704400,3.33
    -1997-12-19,13.56,13.88,13.25,13.69,6812000,3.42
    -1997-12-18,14.00,14.00,13.75,13.81,7225200,3.45
    -1997-12-17,14.31,14.56,13.94,13.94,9494400,3.48
    -1997-12-16,14.00,14.38,14.00,14.31,6646400,3.58
    -1997-12-15,14.13,14.25,13.75,13.94,5927600,3.48
    -1997-12-12,14.75,14.88,14.00,14.13,5742400,3.53
    -1997-12-11,14.44,14.56,13.88,14.56,9185600,3.64
    -1997-12-10,15.06,15.06,14.50,14.75,6960000,3.69
    -1997-12-09,15.50,15.69,15.00,15.25,8680800,3.81
    -1997-12-08,15.56,15.75,15.38,15.56,4776800,3.89
    -1997-12-05,15.56,16.00,15.56,15.81,7926400,3.95
    -1997-12-04,16.00,16.00,15.63,15.63,7135600,3.91
    -1997-12-03,16.06,16.12,15.69,15.75,12258800,3.94
    -1997-12-02,17.37,17.50,15.88,15.88,14178800,3.97
    -1997-12-01,17.69,17.94,17.25,17.75,3135600,4.44
    -1997-11-28,17.62,17.87,17.44,17.75,1495600,4.44
    -1997-11-26,17.37,17.69,17.25,17.50,2178800,4.38
    -1997-11-25,17.69,17.87,16.87,17.37,7346400,4.34
    -1997-11-24,17.56,18.00,17.50,17.62,5630800,4.41
    -1997-11-21,18.62,18.69,18.00,18.19,3498800,4.55
    -1997-11-20,18.19,18.62,18.12,18.50,4587600,4.62
    -1997-11-19,17.87,18.31,17.87,18.25,2843600,4.56
    -1997-11-18,18.50,18.50,18.06,18.06,5258000,4.51
    -1997-11-17,18.87,18.94,18.33,18.50,7323600,4.62
    -1997-11-14,18.25,18.50,18.00,18.44,4835600,4.61
    -1997-11-13,18.00,18.06,17.50,18.00,9218000,4.50
    -1997-11-12,18.06,18.50,17.56,17.62,7448000,4.41
    -1997-11-11,19.00,19.00,18.12,18.37,11893600,4.59
    -1997-11-10,21.00,21.50,18.50,18.69,49946800,4.67
    -1997-11-07,18.87,20.00,18.75,19.75,28423200,4.94
    -1997-11-06,18.87,19.50,18.87,19.00,22060800,4.75
    -1997-11-05,18.25,18.62,18.06,18.37,13840000,4.59
    -1997-11-04,17.75,18.12,17.50,17.94,6033200,4.49
    -1997-11-03,17.56,17.75,17.06,17.37,4512000,4.34
    -1997-10-31,17.37,17.37,16.62,17.03,9549200,4.26
    -1997-10-30,17.06,17.56,16.50,16.50,6764400,4.12
    -1997-10-29,18.44,18.50,17.25,17.50,6355200,4.38
    -1997-10-28,16.00,18.50,15.88,18.12,12273200,4.53
    -1997-10-27,16.75,18.12,16.75,16.75,11764400,4.19
    -1997-10-24,18.12,18.37,16.50,16.56,13880000,4.14
    -1997-10-23,18.00,18.19,17.75,17.75,6688000,4.44
    -1997-10-22,19.06,19.25,18.50,18.56,5421200,4.64
    -1997-10-21,18.87,19.31,18.69,19.06,16982000,4.76
    -1997-10-20,20.12,20.19,18.62,18.69,14724400,4.67
    -1997-10-17,21.12,21.12,19.87,20.12,15682000,5.03
    -1997-10-16,21.12,22.06,20.87,21.50,26422000,5.38
    -1997-10-15,22.12,24.75,22.12,23.81,28982000,5.95
    -1997-10-14,22.69,22.75,22.19,22.69,5923200,5.67
    -1997-10-13,22.75,22.87,22.19,22.69,5679200,5.67
    -1997-10-10,21.50,22.75,21.50,22.69,9666800,5.67
    -1997-10-09,21.25,22.50,21.19,21.75,6696400,5.44
    -1997-10-08,21.75,21.81,21.31,21.50,3891200,5.38
    -1997-10-07,21.87,22.00,21.81,21.81,3916400,5.45
    -1997-10-06,22.19,22.25,21.69,21.94,3338800,5.49
    -1997-10-03,22.00,22.25,21.69,22.12,5813200,5.53
    -1997-10-02,21.44,22.00,21.37,21.94,4856400,5.49
    -1997-10-01,21.69,21.75,21.37,21.53,4670800,5.38
    -1997-09-30,22.00,22.31,21.69,21.69,5032000,5.42
    -1997-09-29,21.69,22.25,21.56,22.06,5980000,5.51
    -1997-09-26,21.50,21.94,21.12,21.31,7440000,5.33
    -1997-09-25,21.31,21.75,21.00,21.12,7988000,5.28
    -1997-09-24,21.69,21.75,21.37,21.50,7957600,5.38
    -1997-09-23,22.25,22.25,21.69,21.75,7163200,5.44
    -1997-09-22,22.12,23.06,22.00,22.81,7176400,5.70
    -1997-09-19,22.19,22.19,21.75,21.94,3407600,5.49
    -1997-09-18,21.50,22.50,21.50,22.31,6042400,5.58
    -1997-09-17,22.00,22.00,21.69,21.81,3109200,5.45
    -1997-09-16,22.06,22.14,21.75,21.94,4812400,5.49
    -1997-09-15,21.87,22.12,21.50,21.50,3473200,5.38
    -1997-09-12,22.19,22.25,21.44,22.06,4071200,5.51
    -1997-09-11,22.87,23.00,22.06,22.37,7504400,5.59
    -1997-09-10,21.75,23.12,21.69,22.94,9803600,5.74
    -1997-09-09,21.31,21.87,21.25,21.81,5702000,5.45
    -1997-09-08,22.25,22.25,21.44,21.50,6264400,5.38
    -1997-09-05,22.62,22.87,22.00,22.19,4883600,5.55
    -1997-09-04,22.56,22.87,22.25,22.50,4385600,5.62
    -1997-09-03,22.37,23.25,22.31,22.50,10163200,5.62
    -1997-09-02,22.00,22.56,21.94,22.37,6646800,5.59
    -1997-08-29,21.81,22.00,21.50,21.75,3937600,5.44
    -1997-08-28,22.12,22.50,22.00,22.00,3426400,5.50
    -1997-08-27,22.37,22.75,21.87,22.69,6813200,5.67
    -1997-08-26,22.62,23.00,22.12,22.25,8100800,5.56
    -1997-08-25,23.62,23.69,22.94,23.06,4968800,5.76
    -1997-08-22,23.44,24.00,23.37,23.62,8135200,5.91
    -1997-08-21,24.50,24.69,23.87,24.00,9271200,6.00
    -1997-08-20,24.44,25.12,24.19,24.62,11595200,6.16
    -1997-08-19,23.69,24.50,23.31,24.44,10331200,6.11
    -1997-08-18,23.31,23.75,22.75,23.62,7791200,5.91
    -1997-08-15,23.12,23.44,22.81,23.25,9320000,5.81
    -1997-08-14,23.62,24.25,22.69,23.00,15536400,5.75
    -1997-08-13,22.25,23.87,20.44,23.62,42923600,5.91
    -1997-08-12,24.06,24.25,21.87,22.06,37444400,5.51
    -1997-08-11,26.31,26.44,23.50,24.56,55411200,6.14
    -1997-08-08,27.81,28.37,26.12,26.81,64809200,6.70
    -1997-08-07,28.75,29.56,28.37,29.19,134124400,7.30
    -1997-08-06,25.25,27.75,25.00,26.31,149671200,6.58
    -1997-08-05,19.94,20.00,19.48,19.75,8840800,4.94
    -1997-08-04,19.19,19.81,19.19,19.75,21851200,4.94
    -1997-08-01,17.62,19.19,17.56,19.19,17217600,4.80
    -1997-07-31,17.37,17.75,17.25,17.50,9434400,4.38
    -1997-07-30,16.94,17.69,16.75,17.37,13372400,4.34
    -1997-07-29,16.44,16.62,16.37,16.50,2558000,4.12
    -1997-07-28,16.44,16.50,16.25,16.44,3962000,4.11
    -1997-07-25,15.88,16.56,15.75,16.25,7798000,4.06
    -1997-07-24,16.12,16.12,15.63,15.81,4772000,3.95
    -1997-07-23,16.75,16.87,16.00,16.12,5049200,4.03
    -1997-07-22,16.37,16.69,16.31,16.56,8274400,4.14
    -1997-07-21,17.56,17.69,16.00,16.16,12695600,4.04
    -1997-07-18,17.87,17.94,17.06,17.34,11353600,4.34
    -1997-07-17,17.00,18.12,16.44,17.50,26659200,4.38
    -1997-07-16,15.81,16.50,15.63,16.44,15947600,4.11
    -1997-07-15,15.75,16.00,15.63,15.94,14953200,3.98
    -1997-07-14,15.25,15.63,14.88,15.63,14700800,3.91
    -1997-07-11,13.38,15.50,13.31,15.19,26252400,3.80
    -1997-07-10,12.88,13.38,12.75,13.25,17606400,3.31
    -1997-07-09,13.81,13.88,13.63,13.69,5090000,3.42
    -1997-07-08,13.88,14.00,13.69,13.75,3427600,3.44
    -1997-07-07,13.94,14.25,13.75,13.81,6860000,3.45
    -1997-07-03,13.13,13.88,13.00,13.69,6688000,3.42
    -1997-07-02,13.25,13.38,13.00,13.06,8931200,3.27
    -1997-07-01,13.94,14.00,13.13,13.19,16104400,3.30
    -1997-06-30,14.75,14.75,14.00,14.25,6132400,3.56
    -1997-06-27,14.69,14.81,14.63,14.69,5642000,3.67
    -1997-06-26,15.13,15.13,14.63,14.69,13643600,3.67
    -1997-06-25,15.31,15.38,15.00,15.13,7102000,3.78
    -1997-06-24,15.44,15.56,15.25,15.31,3974800,3.83
    -1997-06-23,15.50,15.63,15.38,15.38,3574800,3.85
    -1997-06-20,15.69,15.75,15.50,15.56,3943600,3.89
    -1997-06-19,16.00,16.00,15.69,15.75,4323600,3.94
    -1997-06-18,16.12,16.25,15.75,15.94,3936400,3.98
    -1997-06-17,15.56,16.50,15.50,16.34,5080800,4.09
    -1997-06-16,15.88,15.88,15.38,15.50,4800800,3.88
    -1997-06-13,16.06,16.12,15.75,15.81,4737600,3.95
    -1997-06-12,16.37,16.37,16.00,16.06,2816400,4.01
    -1997-06-11,16.31,16.44,16.25,16.31,3766800,4.08
    -1997-06-10,16.75,16.75,16.06,16.25,4969200,4.06
    -1997-06-09,16.69,16.94,16.62,16.62,2689200,4.16
    -1997-06-06,16.62,16.75,16.50,16.75,1893200,4.19
    -1997-06-05,16.62,17.12,16.56,16.69,2323200,4.17
    -1997-06-04,16.62,16.75,16.50,16.62,2889200,4.16
    -1997-06-03,16.75,16.94,16.62,16.69,2335600,4.17
    -1997-06-02,17.00,17.00,16.75,16.94,1488000,4.24
    -1997-05-30,16.50,17.00,16.37,16.62,6340800,4.16
    -1997-05-29,17.12,17.12,16.62,16.62,3976800,4.16
    -1997-05-28,17.37,17.50,17.00,17.00,3130000,4.25
    -1997-05-27,16.75,17.37,16.75,17.25,2938000,4.31
    -1997-05-23,16.62,17.00,16.62,16.87,2413200,4.22
    -1997-05-22,16.75,16.87,16.50,16.62,2753600,4.16
    -1997-05-21,17.12,17.12,16.50,16.87,4369200,4.22
    -1997-05-20,17.00,17.44,16.75,17.25,3046400,4.31
    -1997-05-19,17.50,17.62,17.00,17.00,1881200,4.25
    -1997-05-16,17.50,17.62,17.25,17.25,3338800,4.31
    -1997-05-15,17.75,18.00,17.50,17.75,3544800,4.44
    -1997-05-14,17.87,18.00,17.50,17.69,4846800,4.42
    -1997-05-13,17.50,17.87,17.00,17.56,7056800,4.39
    -1997-05-12,17.25,17.62,17.00,17.56,5898800,4.39
    -1997-05-09,17.00,17.50,17.00,17.06,6732000,4.26
    -1997-05-08,16.62,17.12,16.50,17.00,2963200,4.25
    -1997-05-07,16.87,17.00,16.37,16.50,4101200,4.12
    -1997-05-06,17.00,17.12,16.75,16.87,2974800,4.22
    -1997-05-05,17.00,17.12,16.75,17.00,3538800,4.25
    -1997-05-02,17.00,17.12,16.75,17.00,3643600,4.25
    -1997-05-01,16.87,17.12,16.75,17.00,2596800,4.25
    -1997-04-30,17.00,17.25,16.75,17.00,9202000,4.25
    -1997-04-29,18.00,18.00,17.50,17.69,1853200,4.42
    -1997-04-28,17.75,17.87,17.50,17.62,1687600,4.41
    -1997-04-25,17.62,17.87,17.37,17.50,3121200,4.38
    -1997-04-24,18.50,18.50,17.75,17.87,2696800,4.47
    -1997-04-23,18.37,18.50,18.12,18.12,1960800,4.53
    -1997-04-22,18.12,18.50,17.87,18.50,3392000,4.62
    -1997-04-21,18.62,18.62,18.00,18.00,3197600,4.50
    -1997-04-18,19.12,19.12,18.37,18.37,5058000,4.59
    -1997-04-17,18.25,19.12,18.12,19.00,7859200,4.75
    -1997-04-16,18.62,19.00,18.37,18.56,3101200,4.64
    -1997-04-15,19.12,19.25,18.12,18.44,4869200,4.61
    -1997-04-14,18.37,18.87,18.00,18.75,4020000,4.69
    -1997-04-11,18.87,18.87,18.12,18.25,2842400,4.56
    -1997-04-10,19.00,19.12,18.50,18.87,4188000,4.72
    -1997-04-09,19.25,19.25,18.87,19.00,8766400,4.75
    -1997-04-08,19.62,19.62,18.62,19.12,6923600,4.78
    -1997-04-07,19.75,19.87,19.25,19.50,9136800,4.88
    -1997-04-04,19.12,19.62,19.00,19.25,16980800,4.81
    -1997-04-03,18.50,19.12,18.25,18.87,19603200,4.72
    -1997-04-02,17.87,18.06,17.62,18.00,7957600,4.50
    -1997-04-01,17.62,17.81,17.37,17.50,7881200,4.38
    -1997-03-31,18.62,19.37,17.25,18.25,34658000,4.56
    -1997-03-27,17.50,19.25,17.25,18.62,40695200,4.66
    -1997-03-26,16.37,16.87,16.25,16.75,3824400,4.19
    -1997-03-25,16.62,16.62,16.08,16.50,4031200,4.12
    -1997-03-24,16.50,16.62,16.25,16.50,2556800,4.12
    -1997-03-21,17.50,17.50,16.37,16.62,4892400,4.16
    -1997-03-20,16.00,17.50,15.88,17.25,11324400,4.31
    -1997-03-19,16.37,16.37,15.88,16.12,7457600,4.03
    -1997-03-18,16.37,16.50,16.12,16.25,4548800,4.06
    -1997-03-17,16.25,16.50,16.00,16.50,6886400,4.12
    -1997-03-14,16.37,16.75,16.25,16.56,8245600,4.14
    -1997-03-13,16.37,16.37,16.12,16.37,3772000,4.09
    -1997-03-12,16.25,16.75,16.12,16.25,2544400,4.06
    -1997-03-11,16.62,16.62,16.00,16.37,3539200,4.09
    -1997-03-10,16.62,16.75,16.44,16.62,3554800,4.16
    -1997-03-07,16.75,16.75,16.37,16.50,2523200,4.12
    -1997-03-06,17.00,17.00,16.50,16.62,4172000,4.16
    -1997-03-05,16.62,17.00,16.50,17.00,3453600,4.25
    -1997-03-04,16.25,16.50,16.00,16.50,3688800,4.12
    -1997-03-03,16.50,16.50,16.00,16.12,4670000,4.03
    -1997-02-28,16.87,16.87,16.25,16.25,4371200,4.06
    -1997-02-27,17.00,17.12,16.75,17.00,3700000,4.25
    -1997-02-26,17.00,17.12,16.75,17.12,3687600,4.28
    -1997-02-25,17.00,17.37,16.87,16.87,4938000,4.22
    -1997-02-24,16.25,16.87,16.25,16.62,4222000,4.16
    -1997-02-21,16.87,17.00,16.00,16.37,7549200,4.09
    -1997-02-20,17.62,17.62,17.00,17.00,4474800,4.25
    -1997-02-19,17.87,17.87,17.12,17.62,8627600,4.41
    -1997-02-18,16.62,17.87,16.25,17.87,13171200,4.47
    -1997-02-14,16.25,16.37,16.00,16.31,8492000,4.08
    -1997-02-13,15.75,16.12,15.50,16.12,7013200,4.03
    -1997-02-12,15.75,15.88,15.50,15.75,6303600,3.94
    -1997-02-11,15.88,16.00,15.50,15.69,5004400,3.92
    -1997-02-10,16.12,16.12,15.63,15.63,6633600,3.91
    -1997-02-07,16.50,16.50,15.75,15.81,8403600,3.95
    -1997-02-06,15.25,16.12,15.25,16.00,14283600,4.00
    -1997-02-05,15.25,15.63,15.25,15.25,14093600,3.81
    -1997-02-04,16.25,16.37,15.13,15.38,25458000,3.85
    -1997-02-03,16.87,17.00,16.25,16.31,13162000,4.08
    -1997-01-31,16.62,16.62,16.50,16.62,7135200,4.16
    -1997-01-30,16.75,16.75,16.50,16.75,5018800,4.19
    -1997-01-29,16.62,16.75,16.50,16.62,5428000,4.16
    -1997-01-28,17.00,17.00,16.50,16.62,7520000,4.16
    -1997-01-27,17.12,17.25,16.62,16.62,7646800,4.16
    -1997-01-24,17.25,17.25,16.87,16.87,6726800,4.22
    -1997-01-23,17.25,17.37,17.12,17.25,6175200,4.31
    -1997-01-22,17.37,17.50,17.00,17.19,7356800,4.30
    -1997-01-21,17.00,17.25,16.87,17.25,10179200,4.31
    -1997-01-20,16.87,17.12,16.75,16.94,10423600,4.24
    -1997-01-17,16.75,17.12,16.62,16.75,11619200,4.19
    -1997-01-16,17.12,17.12,16.62,16.75,23983600,4.19
    -1997-01-15,18.00,18.00,17.12,17.25,15483200,4.31
    -1997-01-14,18.37,18.37,17.75,17.87,9143200,4.47
    -1997-01-13,18.50,18.50,18.12,18.12,10942000,4.53
    -1997-01-10,17.62,18.25,17.62,18.25,12651200,4.56
    -1997-01-09,17.75,17.87,17.50,17.75,15970000,4.44
    -1997-01-08,18.25,18.37,17.37,17.62,39296400,4.41
    -1997-01-07,18.12,18.25,17.50,17.50,34896400,4.38
    -1997-01-06,17.62,18.34,17.25,17.87,67246400,4.47
    -1997-01-03,21.12,22.25,21.00,21.75,4295600,5.44
    -1997-01-02,21.12,21.25,20.75,21.00,5128800,5.25
    -1996-12-31,21.37,21.50,20.75,20.87,13719200,5.22
    -1996-12-30,23.12,23.25,21.75,21.75,9366800,5.44
    -1996-12-27,22.87,23.75,22.87,23.12,4900000,5.78
    -1996-12-26,23.25,23.25,22.87,23.00,3049200,5.75
    -1996-12-24,23.25,23.37,22.87,23.12,2067600,5.78
    -1996-12-23,24.00,24.25,23.25,23.25,11883600,5.81
    -1996-12-20,22.50,23.62,21.37,23.50,19535600,5.88
    -1996-12-19,23.00,23.25,22.25,22.25,4893600,5.56
    -1996-12-18,22.75,23.12,22.62,23.12,7326400,5.78
    -1996-12-17,22.37,22.50,22.25,22.50,5625200,5.62
    -1996-12-16,23.50,23.50,22.50,22.62,5335600,5.66
    -1996-12-13,23.75,23.87,23.25,23.25,3194400,5.81
    -1996-12-12,24.12,24.25,23.87,23.87,3122400,5.97
    -1996-12-11,23.75,24.25,23.75,24.00,5853600,6.00
    -1996-12-10,24.87,25.00,24.25,24.50,6593600,6.12
    -1996-12-09,25.25,25.37,24.81,25.00,5680800,6.25
    -1996-12-06,24.37,25.37,24.00,25.12,8210800,6.28
    -1996-12-05,25.00,25.25,25.00,25.00,5096800,6.25
    -1996-12-04,25.12,25.37,24.87,25.00,6823600,6.25
    -1996-12-03,25.25,25.50,25.00,25.12,9840800,6.28
    -1996-12-02,24.12,25.12,23.87,25.12,6254400,6.28
    -1996-11-29,24.50,24.62,24.00,24.12,1527600,6.03
    -1996-11-27,24.12,24.62,24.12,24.50,3191200,6.12
    -1996-11-26,24.87,25.00,24.00,24.25,4054800,6.06
    -1996-11-25,25.37,25.50,25.00,25.00,2830800,6.25
    -1996-11-22,24.50,25.25,24.50,25.25,3732400,6.31
    -1996-11-21,24.87,25.00,24.37,24.50,2522400,6.12
    -1996-11-20,24.87,25.37,24.87,25.00,3683200,6.25
    -1996-11-19,24.87,25.12,24.62,24.87,4446400,6.22
    -1996-11-18,25.00,25.12,24.50,24.75,5468800,6.19
    -1996-11-15,25.87,26.00,25.00,25.00,4684400,6.25
    -1996-11-14,25.50,25.75,25.37,25.62,1740800,6.41
    -1996-11-13,25.37,25.87,25.00,25.56,3000800,6.39
    -1996-11-12,26.12,26.25,25.12,25.25,5120000,6.31
    -1996-11-11,26.37,26.37,25.87,26.00,3318800,6.50
    -1996-11-08,25.87,26.25,25.75,26.25,6750800,6.56
    -1996-11-07,25.37,26.00,25.25,25.87,5548800,6.47
    -1996-11-06,25.62,25.75,24.87,25.50,6462000,6.38
    -1996-11-05,24.50,25.87,24.50,25.50,13517600,6.38
    -1996-11-04,24.37,24.50,23.75,24.37,3270800,6.09
    -1996-11-01,23.37,24.25,23.12,24.25,7563200,6.06
    -1996-10-31,23.25,23.37,22.25,23.00,6945600,5.75
    -1996-10-30,23.50,24.00,22.87,22.87,9192000,5.72
    -1996-10-29,24.62,24.75,23.12,23.25,7135200,5.81
    -1996-10-28,25.12,25.12,24.50,24.50,4288800,6.12
    -1996-10-25,24.87,25.00,24.50,24.50,2775600,6.12
    -1996-10-24,25.00,25.00,24.50,24.75,3020800,6.19
    -1996-10-23,24.75,25.25,24.37,24.75,5736800,6.19
    -1996-10-22,25.62,25.62,24.25,24.87,7651200,6.22
    -1996-10-21,26.50,26.62,25.50,25.62,6712000,6.41
    -1996-10-18,26.50,26.62,26.00,26.56,13681200,6.64
    -1996-10-17,27.50,27.75,26.37,26.37,36679200,6.59
    -1996-10-16,25.25,26.12,24.62,25.75,11975200,6.44
    -1996-10-15,25.75,25.87,25.00,25.25,12970000,6.31
    -1996-10-14,24.50,25.37,24.25,25.25,9649200,6.31
    -1996-10-11,24.37,24.62,24.00,24.25,4327600,6.06
    -1996-10-10,23.87,24.50,23.75,24.19,9883200,6.05
    -1996-10-09,23.37,23.62,22.87,23.00,3044800,5.75
    -1996-10-08,23.50,24.25,23.25,23.25,6802000,5.81
    -1996-10-07,23.00,23.37,22.87,23.12,3428800,5.78
    -1996-10-04,22.87,23.12,22.12,22.81,4770000,5.70
    -1996-10-03,23.62,23.75,22.37,22.37,8140000,5.59
    -1996-10-02,23.62,24.62,23.12,23.62,9890000,5.91
    -1996-10-01,22.00,24.75,22.00,24.62,19269200,6.16
    -1996-09-30,22.12,22.37,22.12,22.19,3058000,5.55
    -1996-09-27,22.25,22.37,22.12,22.31,2932000,5.58
    -1996-09-26,22.37,22.50,22.25,22.37,3693600,5.59
    -1996-09-25,22.50,22.62,22.00,22.37,3902400,5.59
    -1996-09-24,22.37,22.87,22.37,22.50,5143600,5.62
    -1996-09-23,22.87,22.87,22.37,22.37,1653600,5.59
    -1996-09-20,23.37,23.50,22.75,22.87,5330800,5.72
    -1996-09-19,23.62,23.62,23.37,23.37,4282000,5.84
    -1996-09-18,23.00,24.12,22.87,23.50,12631200,5.88
    -1996-09-17,22.87,23.12,22.50,23.00,7487600,5.75
    -1996-09-16,21.50,23.00,21.37,22.37,8747600,5.59
    -1996-09-13,20.37,21.25,20.37,21.00,5967600,5.25
    -1996-09-12,21.00,21.12,20.25,20.37,9340000,5.09
    -1996-09-11,21.50,21.75,21.00,21.12,5266800,5.28
    -1996-09-10,22.12,22.12,21.50,21.50,5562000,5.38
    -1996-09-09,22.62,22.75,21.87,22.00,5302400,5.50
    -1996-09-06,23.12,23.25,22.62,23.00,8602000,5.75
    -1996-09-05,23.50,23.75,22.87,22.87,9999200,5.72
    -1996-09-04,23.87,24.62,23.87,24.12,3636400,6.03
    -1996-09-03,24.12,24.37,23.87,24.12,2461200,6.03
    -1996-08-30,24.75,24.75,24.25,24.25,3784800,6.06
    -1996-08-29,24.87,24.87,24.37,24.50,3829200,6.12
    -1996-08-28,24.87,25.00,24.50,24.87,5844400,6.22
    -1996-08-27,24.12,25.00,24.00,24.86,10339200,6.22
    -1996-08-26,23.87,24.12,23.50,24.12,3204400,6.03
    -1996-08-23,23.00,24.00,23.00,23.87,7281200,5.97
    -1996-08-22,23.00,23.25,22.87,23.25,3138000,5.81
    -1996-08-21,23.50,23.62,22.87,23.00,4052400,5.75
    -1996-08-20,23.87,23.87,23.37,23.50,7564400,5.88
    -1996-08-19,22.37,23.62,22.37,23.62,8084400,5.91
    -1996-08-16,22.62,22.62,22.12,22.50,5075600,5.62
    -1996-08-15,22.62,22.75,22.25,22.25,3845600,5.56
    -1996-08-14,22.62,23.00,22.62,22.75,2570000,5.69
    -1996-08-13,22.87,23.12,22.37,22.50,3706400,5.62
    -1996-08-12,23.37,23.62,22.37,23.00,5408000,5.75
    -1996-08-09,22.25,23.37,22.12,23.12,8243600,5.78
    -1996-08-08,22.37,22.37,21.87,22.12,3640000,5.53
    -1996-08-07,21.75,22.62,21.62,22.37,8892400,5.59
    -1996-08-06,21.00,21.50,20.75,21.50,3354800,5.38
    -1996-08-05,21.62,21.87,20.87,21.00,3612000,5.25
    -1996-08-02,21.62,22.00,21.25,21.62,4574800,5.41
    -1996-08-01,22.00,22.00,21.12,21.25,3942400,5.31
    -1996-07-31,21.25,22.00,21.25,22.00,3332400,5.50
    -1996-07-30,22.62,22.75,21.25,21.37,6766800,5.34
    -1996-07-29,22.00,22.50,21.75,22.25,7005600,5.56
    -1996-07-26,21.50,22.00,21.12,22.00,4426800,5.50
    -1996-07-25,21.12,21.37,20.75,21.00,4090800,5.25
    -1996-07-24,20.00,21.00,19.87,20.81,9448800,5.20
    -1996-07-23,20.50,20.62,20.25,20.50,4651200,5.12
    -1996-07-22,20.87,20.87,20.00,20.25,5456400,5.06
    -1996-07-19,20.87,21.00,20.75,20.75,9510000,5.19
    -1996-07-18,21.50,21.75,20.36,20.87,32058800,5.22
    -1996-07-17,17.37,17.50,16.62,16.87,8355600,4.22
    -1996-07-16,17.37,17.37,16.00,16.87,10334400,4.22
    -1996-07-15,18.12,18.12,17.12,17.19,4779200,4.30
    -1996-07-12,18.37,18.37,17.25,18.06,9610800,4.51
    -1996-07-11,18.75,18.87,17.37,17.87,10420000,4.47
    -1996-07-10,19.12,19.50,18.75,18.75,6055200,4.69
    -1996-07-09,19.50,19.62,19.00,19.00,6723600,4.75
    -1996-07-08,19.62,19.87,19.00,19.12,6762000,4.78
    -1996-07-05,19.37,19.75,19.25,19.50,3808800,4.88
    -1996-07-03,20.37,20.37,19.37,19.37,10323200,4.84
    -1996-07-02,21.37,21.50,21.00,21.00,3189200,5.25
    -1996-07-01,21.12,21.50,21.00,21.50,4732400,5.38
    -1996-06-28,20.87,21.00,20.62,21.00,4138000,5.25
    -1996-06-27,20.00,21.00,19.75,20.62,8202400,5.16
    -1996-06-26,20.62,20.75,19.62,19.87,14440800,4.97
    -1996-06-25,22.12,22.25,20.37,20.62,8831200,5.16
    -1996-06-24,22.62,22.62,22.12,22.25,4398000,5.56
    -1996-06-21,22.87,22.87,22.37,22.62,5792000,5.66
    -1996-06-20,23.37,23.37,22.50,22.75,5260800,5.69
    -1996-06-19,23.12,23.37,22.62,23.12,4803600,5.78
    -1996-06-18,23.62,23.75,22.62,22.75,7979200,5.69
    -1996-06-17,24.12,24.12,23.62,23.62,4052000,5.91
    -1996-06-14,24.75,24.75,23.87,23.94,5186800,5.99
    -1996-06-13,24.37,24.92,24.00,24.62,6856800,6.16
    -1996-06-12,24.50,24.50,24.00,24.25,5440000,6.06
    -1996-06-11,24.25,24.25,24.00,24.00,5481200,6.00
    -1996-06-10,24.37,24.50,24.00,24.12,3820800,6.03
    -1996-06-07,24.00,24.37,23.50,24.37,9565200,6.09
    -1996-06-06,25.00,25.25,24.12,24.25,12938800,6.06
    -1996-06-05,25.37,25.50,24.25,25.12,18228000,6.28
    -1996-06-04,24.00,24.37,23.87,24.19,27235600,6.05
    -1996-06-03,25.87,26.00,24.75,24.75,4481200,6.19
    -1996-05-31,25.62,26.62,25.50,26.12,5813600,6.53
    -1996-05-30,24.87,25.75,24.75,25.50,3703600,6.38
    -1996-05-29,26.25,26.25,24.75,24.87,7840000,6.22
    -1996-05-28,26.75,27.25,26.37,26.37,3658800,6.59
    -1996-05-24,26.25,26.87,26.12,26.75,4046800,6.69
    -1996-05-23,26.12,26.62,25.75,26.25,4447600,6.56
    -1996-05-22,27.37,27.37,25.75,26.06,7215600,6.51
    -1996-05-21,28.00,28.12,27.12,27.12,4088000,6.78
    -1996-05-20,27.87,28.12,27.62,27.94,3028800,6.99
    -1996-05-17,28.37,28.37,27.50,27.62,4405600,6.91
    -1996-05-16,28.25,28.62,27.87,28.37,4648800,7.09
    -1996-05-15,27.87,28.87,27.75,28.50,10442400,7.12
    -1996-05-14,27.75,28.00,27.50,27.50,7068000,6.88
    -1996-05-13,27.12,27.62,26.62,27.06,6701200,6.76
    -1996-05-10,26.25,27.37,26.00,27.25,3966400,6.81
    -1996-05-09,26.37,26.50,25.75,26.12,3515600,6.53
    -1996-05-08,27.25,27.25,25.62,26.75,6688800,6.69
    -1996-05-07,26.37,27.37,26.25,26.87,12641200,6.72
    -1996-05-06,24.87,25.87,24.75,25.62,10349200,6.41
    -1996-05-03,24.12,24.12,23.50,23.87,3892400,5.97
    -1996-05-02,24.50,24.50,23.50,23.75,6728000,5.94
    -1996-05-01,24.37,24.75,24.12,24.37,4039200,6.09
    -1996-04-30,24.87,24.87,24.12,24.37,4881200,6.09
    -1996-04-29,25.00,25.00,24.50,24.75,4324800,6.19
    -1996-04-26,25.00,25.12,24.62,24.75,6759200,6.19
    -1996-04-25,24.37,24.87,24.12,24.87,6245200,6.22
    -1996-04-24,24.62,24.75,24.19,24.25,4596800,6.06
    -1996-04-23,25.12,25.25,24.62,24.75,6086400,6.19
    -1996-04-22,25.25,25.50,24.87,25.12,3973200,6.28
    -1996-04-19,24.62,25.12,24.62,25.06,3655600,6.26
    -1996-04-18,25.37,25.39,24.25,24.75,7780800,6.19
    -1996-04-17,25.87,26.00,25.12,25.25,3056400,6.31
    -1996-04-16,25.87,26.00,25.62,25.87,3634400,6.47
    -1996-04-15,25.50,25.75,25.00,25.75,5515600,6.44
    -1996-04-12,25.87,25.87,25.37,25.50,2924400,6.38
    -1996-04-11,26.12,26.25,25.50,25.75,3526400,6.44
    -1996-04-10,26.12,26.50,25.87,26.00,6242400,6.50
    -1996-04-09,24.87,26.50,24.37,26.00,8415600,6.50
    -1996-04-08,23.87,24.50,23.75,24.37,6046400,6.09
    -1996-04-04,24.62,24.62,24.00,24.12,3092000,6.03
    -1996-04-03,25.12,25.12,24.33,24.56,2591200,6.14
    -1996-04-02,25.62,25.62,24.87,25.00,3635600,6.25
    -1996-04-01,25.12,25.87,24.52,25.50,5680000,6.38
    -1996-03-29,24.25,24.75,23.75,24.56,5962400,6.14
    -1996-03-28,24.75,25.62,24.12,24.19,10572000,6.05
    -1996-03-27,23.25,25.25,23.00,25.25,15338800,6.31
    -1996-03-26,24.00,24.50,23.62,23.87,5755600,5.97
    -1996-03-25,25.50,25.75,24.00,24.00,5887600,6.00
    -1996-03-22,25.25,25.37,24.87,25.37,3842400,6.34
    -1996-03-21,25.50,25.50,25.00,25.12,3932400,6.28
    -1996-03-20,25.75,25.75,25.12,25.25,4154800,6.31
    -1996-03-19,26.37,26.50,25.62,25.75,4442400,6.44
    -1996-03-18,25.94,26.12,25.75,26.12,3907600,6.53
    -1996-03-15,26.00,26.00,25.50,25.87,3632400,6.47
    -1996-03-14,25.87,25.87,25.50,25.62,3342400,6.41
    -1996-03-13,25.87,26.12,25.62,25.75,3560000,6.44
    -1996-03-12,26.00,26.37,25.62,25.81,3453200,6.45
    -1996-03-11,26.25,26.37,25.75,25.87,4544800,6.47
    -1996-03-08,25.75,26.25,25.00,26.00,5322400,6.50
    -1996-03-07,26.25,26.37,25.37,25.81,9292400,6.45
    -1996-03-06,26.75,26.87,26.12,26.19,3547600,6.55
    -1996-03-05,26.50,26.75,26.25,26.62,4246800,6.66
    -1996-03-04,27.25,27.37,26.25,26.25,6708800,6.56
    -1996-03-01,27.62,27.62,26.62,26.87,8263200,6.72
    -1996-02-29,27.50,27.75,27.25,27.50,4049200,6.88
    -1996-02-28,28.87,28.87,27.62,27.75,6728800,6.94
    -1996-02-27,29.87,29.87,28.50,28.62,5331200,7.16
    -1996-02-26,30.00,30.12,29.50,29.50,4238000,7.38
    -1996-02-23,29.87,30.25,29.62,29.87,6205200,7.47
    -1996-02-22,30.00,30.12,29.62,29.87,6588000,7.47
    -1996-02-21,29.37,29.75,29.12,29.62,7924400,7.41
    -1996-02-20,28.00,29.50,28.00,29.00,13473200,7.25
    -1996-02-16,28.12,28.37,27.50,27.50,5602400,6.88
    -1996-02-15,27.62,28.12,27.37,28.00,4360000,7.00
    -1996-02-14,28.25,28.25,27.44,27.62,5843600,6.91
    -1996-02-13,28.00,28.87,27.87,28.12,8161200,7.03
    -1996-02-12,28.12,28.50,28.00,28.37,6948800,7.09
    -1996-02-09,27.87,28.50,27.62,27.75,7360800,6.94
    -1996-02-08,27.50,28.12,27.50,27.87,9420800,6.97
    -1996-02-07,29.75,29.75,27.75,28.25,12885200,7.06
    -1996-02-06,29.25,30.00,29.25,29.62,8101200,7.41
    -1996-02-05,29.69,29.75,29.00,29.25,11396400,7.31
    -1996-02-02,28.87,29.62,28.75,29.25,19865600,7.31
    -1996-02-01,27.50,28.37,27.50,28.37,11902400,7.09
    -1996-01-31,27.75,28.00,27.37,27.62,11736800,6.91
    -1996-01-30,27.00,28.12,26.86,27.31,22246800,6.83
    -1996-01-29,29.00,29.75,28.75,29.12,11900000,7.28
    -1996-01-26,30.37,31.25,28.62,30.62,26297600,7.66
    -1996-01-25,31.75,32.00,30.12,30.25,15911200,7.56
    -1996-01-24,32.13,32.25,31.75,32.25,23438800,8.06
    -1996-01-23,33.75,34.00,31.00,31.62,35305200,7.91
    -1996-01-22,29.75,31.00,29.25,30.50,17852400,7.62
    -1996-01-19,31.00,31.75,29.37,29.87,29623600,7.47
    -1996-01-18,32.88,33.38,30.37,31.94,24955200,7.99
    -1996-01-17,34.38,34.38,33.75,34.00,8445200,8.50
    -1996-01-16,34.38,34.75,33.63,34.56,12606400,8.64
    -1996-01-15,33.75,34.50,33.38,34.13,12971200,8.53
    -1996-01-12,34.75,34.75,33.25,33.88,14370000,8.47
    -1996-01-11,32.63,35.00,32.38,35.00,27041200,8.75
    -1996-01-10,32.50,34.75,32.25,34.25,13057600,8.56
    -1996-01-09,34.63,34.63,32.75,32.75,8978800,8.19
    -1996-01-08,34.50,35.50,34.00,34.63,4341200,8.66
    -1996-01-05,31.62,34.25,31.37,34.25,15929200,8.56
    -1996-01-04,32.38,32.38,31.37,31.56,10721200,7.89
    -1996-01-03,32.00,32.88,31.87,32.13,15368800,8.03
    -1996-01-02,32.25,32.25,31.75,32.13,4983200,8.03
    -1995-12-29,32.00,32.38,31.62,31.87,10874400,7.97
    -1995-12-28,32.13,32.75,31.87,32.00,8933200,8.00
    -1995-12-27,32.13,33.38,31.87,32.38,9609200,8.10
    -1995-12-26,32.50,32.50,31.75,32.06,4994800,8.02
    -1995-12-22,32.63,32.88,32.13,32.25,8392400,8.06
    -1995-12-21,32.75,32.75,31.62,32.50,11893200,8.12
    -1995-12-20,33.50,33.63,32.50,32.63,13074400,8.16
    -1995-12-19,32.75,33.25,32.25,32.75,15403600,8.19
    -1995-12-18,35.13,35.25,31.87,32.25,23807600,8.06
    -1995-12-15,35.50,36.63,34.38,35.25,25960000,8.81
    -1995-12-14,38.88,39.38,38.00,38.25,11928000,9.56
    -1995-12-13,38.25,39.00,36.75,38.38,24472400,9.60
    -1995-12-12,38.63,38.63,38.00,38.00,6353200,9.50
    -1995-12-11,39.50,39.63,38.38,38.63,4003200,9.66
    -1995-12-08,38.75,39.38,37.88,39.38,5053200,9.85
    -1995-12-07,38.75,38.75,37.88,38.56,5084800,9.64
    -1995-12-06,39.75,39.88,38.38,38.75,7195200,9.69
    -1995-12-05,38.50,39.88,38.25,39.50,13000000,9.88
    -1995-12-04,40.13,40.13,39.00,39.50,17171200,9.88
    -1995-12-01,38.00,38.25,37.13,37.63,7300800,9.41
    -1995-11-30,38.88,39.00,38.00,38.13,6247600,9.53
    -1995-11-29,40.13,40.13,39.00,39.25,3782000,9.81
    -1995-11-28,39.38,40.13,39.25,40.00,6305200,10.00
    -1995-11-27,40.63,40.63,39.38,39.38,4148800,9.85
    -1995-11-24,38.88,40.38,38.75,40.19,3930800,10.05
    -1995-11-22,38.63,39.25,38.50,38.63,3533600,9.66
    -1995-11-21,38.75,38.75,37.88,38.63,6845200,9.66
    -1995-11-20,40.25,40.25,38.50,38.63,5314400,9.63
    -1995-11-17,40.00,40.38,39.75,40.13,4607600,10.00
    -1995-11-16,40.88,41.50,39.50,39.94,8102000,9.95
    -1995-11-15,42.00,42.00,40.13,41.00,8874400,10.22
    -1995-11-14,41.00,42.50,41.00,41.50,14560000,10.34
    -1995-11-13,40.25,41.25,40.00,40.88,11343200,10.19
    -1995-11-10,39.38,40.25,38.88,39.75,7973200,9.91
    -1995-11-09,39.75,40.00,38.88,39.38,9295200,9.81
    -1995-11-08,39.75,41.00,38.75,38.88,12823600,9.69
    -1995-11-07,37.75,40.50,37.50,39.63,26310800,9.88
    -1995-11-06,36.50,38.75,36.38,38.13,11143200,9.50
    -1995-11-03,36.75,36.88,35.88,36.50,6413200,9.10
    -1995-11-02,36.88,36.88,36.25,36.63,5464400,9.13
    -1995-11-01,36.63,37.13,35.50,36.63,6913200,9.13
    -1995-10-31,35.25,36.63,35.13,36.31,10334400,9.05
    -1995-10-30,34.88,35.25,34.63,35.25,6291200,8.79
    -1995-10-27,34.88,34.88,34.13,34.75,5523200,8.66
    -1995-10-26,34.88,35.00,34.50,34.88,4503600,8.69
    -1995-10-25,35.25,35.38,34.75,34.75,4761200,8.66
    -1995-10-24,35.50,35.50,34.88,35.13,7638800,8.76
    -1995-10-23,35.13,35.13,34.75,35.13,7078000,8.76
    -1995-10-20,35.25,35.25,34.63,35.13,13818800,8.76
    -1995-10-19,35.88,36.13,34.75,34.75,33761200,8.66
    -1995-10-18,37.00,39.56,36.75,37.38,18311200,9.32
    -1995-10-17,36.50,36.88,35.88,36.63,6390000,9.13
    -1995-10-16,36.25,37.00,35.88,36.13,6515200,9.00
    -1995-10-13,35.75,36.88,35.50,36.00,8422000,8.97
    -1995-10-12,35.00,35.38,34.75,35.31,5803200,8.80
    -1995-10-11,35.25,35.63,34.13,34.88,11893200,8.69
    -1995-10-10,34.38,35.00,33.63,34.69,14303600,8.65
    -1995-10-09,35.38,35.75,34.38,34.81,13320800,8.68
    -1995-10-06,36.75,37.00,35.63,35.69,11058000,8.89
    -1995-10-05,36.25,36.63,35.88,36.50,8737600,9.10
    -1995-10-04,36.63,37.00,36.00,36.38,9532000,9.07
    -1995-10-03,38.13,38.50,37.13,37.63,10368000,9.38
    -1995-10-02,37.75,38.50,37.50,37.63,14000000,9.38
    -1995-09-29,38.00,38.25,36.88,37.25,10123200,9.28
    -1995-09-28,36.50,37.88,36.50,37.75,11843600,9.41
    -1995-09-27,37.50,37.50,34.75,36.25,16135600,9.03
    -1995-09-26,37.75,37.88,37.13,37.38,8961200,9.32
    -1995-09-25,38.25,38.27,37.38,37.52,11267600,9.35
    -1995-09-22,36.88,37.25,36.38,37.06,14258000,9.24
    -1995-09-21,36.50,37.50,36.38,37.00,12407600,9.22
    -1995-09-20,37.25,37.38,36.50,36.63,11500800,9.13
    -1995-09-19,36.75,37.13,36.13,36.75,17512400,9.16
    -1995-09-18,36.38,36.81,35.88,36.69,22216400,9.14
    -1995-09-15,37.38,39.88,35.50,35.88,43286800,8.94
    -1995-09-14,41.38,41.63,39.75,40.00,19675600,9.97
    -1995-09-13,42.88,43.38,42.00,42.38,11530800,10.56
    -1995-09-12,44.50,44.88,42.63,42.94,11658800,10.70
    -1995-09-11,44.88,45.50,44.25,44.25,6160800,11.03
    -1995-09-08,44.75,44.88,44.50,44.75,6243200,11.15
    -1995-09-07,44.00,45.31,43.75,44.75,9373600,11.15
    -1995-09-06,43.88,44.17,43.50,43.75,7175600,10.90
    -1995-09-05,43.50,43.50,42.75,43.50,6443200,10.84
    -1995-09-01,43.00,43.50,42.88,42.94,3532400,10.70
    -1995-08-31,43.38,43.50,43.00,43.00,3148000,10.72
    -1995-08-30,43.25,43.75,43.13,43.38,5482000,10.81
    -1995-08-29,43.00,43.25,42.50,43.13,11325600,10.75
    -1995-08-28,44.88,45.00,43.00,43.00,8680000,10.72
    -1995-08-25,45.88,45.88,44.63,44.75,4819200,11.15
    -1995-08-24,45.63,46.25,45.50,45.75,10285200,11.40
    -1995-08-23,44.88,45.88,44.63,45.50,9078000,11.34
    -1995-08-22,44.38,45.13,44.13,44.75,7769200,11.15
    -1995-08-21,44.88,45.38,44.13,44.13,9721200,11.00
    -1995-08-18,44.88,45.13,43.75,44.88,8620000,11.19
    -1995-08-17,44.63,45.50,44.13,44.63,8827600,11.12
    -1995-08-16,44.00,44.50,43.63,44.50,10457600,11.09
    -1995-08-15,43.88,44.13,43.13,44.06,11370800,10.95
    -1995-08-14,43.00,43.75,42.88,43.38,5989200,10.78
    -1995-08-11,42.88,43.13,41.88,43.06,7407600,10.70
    -1995-08-10,43.13,43.25,42.63,42.75,5868000,10.63
    -1995-08-09,42.63,43.75,42.50,43.13,13190000,10.72
    -1995-08-08,43.63,43.75,42.38,42.50,8388800,10.56
    -1995-08-07,44.13,44.63,43.13,43.38,6920000,10.78
    -1995-08-04,45.00,45.13,43.75,44.25,6884400,11.00
    -1995-08-03,44.13,45.63,43.88,45.00,7640800,11.18
    -1995-08-02,43.88,45.00,43.75,44.38,9840800,11.03
    -1995-08-01,44.88,44.88,43.50,43.50,7540000,10.81
    -1995-07-31,45.50,45.63,44.75,45.00,5673600,11.18
    -1995-07-28,46.75,47.25,45.00,45.50,9341200,11.31
    -1995-07-27,45.50,47.50,45.50,46.81,11621200,11.63
    -1995-07-26,46.25,46.25,45.38,45.38,6125200,11.28
    -1995-07-25,46.00,46.38,45.63,45.75,9418000,11.37
    -1995-07-24,44.00,45.50,43.75,45.38,7679200,11.28
    -1995-07-21,43.00,44.88,43.00,43.75,27082400,10.87
    -1995-07-20,46.00,47.38,45.00,47.06,11848800,11.70
    -1995-07-19,47.00,48.00,45.00,45.50,18613200,11.31
    -1995-07-18,49.00,49.56,47.75,48.13,9102000,11.96
    -1995-07-17,48.88,49.75,48.63,49.00,8098000,12.18
    -1995-07-14,47.38,49.00,47.00,48.75,9929200,12.12
    -1995-07-13,47.38,48.75,47.13,47.63,12596400,11.84
    -1995-07-12,47.25,48.00,46.13,47.00,10145200,11.68
    -1995-07-11,47.75,48.63,47.06,47.13,7683200,11.71
    -1995-07-10,48.63,49.88,48.13,48.63,10640800,12.09
    -1995-07-07,46.88,49.25,46.75,48.63,13840000,12.09
    -1995-07-06,46.50,47.00,45.75,47.00,6583200,11.68
    -1995-07-05,46.88,47.88,46.50,46.50,6325600,11.56
    -1995-07-03,46.50,47.13,46.25,46.94,1410800,11.67
    -1995-06-30,47.25,47.88,46.13,46.44,5927600,11.54
    -1995-06-29,46.38,48.13,46.00,47.25,8320000,11.74
    -1995-06-28,46.00,47.50,45.38,46.63,9531200,11.59
    -1995-06-27,47.38,48.25,46.38,46.38,7772400,11.53
    -1995-06-26,48.25,48.50,47.63,48.13,5465600,11.96
    -1995-06-23,48.75,49.00,47.75,48.75,8286800,12.12
    -1995-06-22,49.00,49.63,48.63,49.13,16928800,12.21
    -1995-06-21,47.63,50.13,46.75,49.38,22378800,12.27
    -1995-06-20,46.00,47.75,46.00,47.38,26385200,11.78
    -1995-06-19,43.88,45.25,43.50,44.38,16774400,11.03
    -1995-06-16,43.88,44.00,43.50,43.88,3200800,10.91
    -1995-06-15,43.63,43.75,43.38,43.63,3331200,10.84
    -1995-06-14,43.88,43.88,43.38,43.63,4224800,10.84
    -1995-06-13,44.50,44.63,43.88,44.00,4508000,10.94
    -1995-06-12,44.00,44.50,43.88,44.17,7584400,10.98
    -1995-06-09,43.63,43.75,43.13,43.50,6679200,10.81
    -1995-06-08,43.38,43.38,42.13,42.94,4874400,10.67
    -1995-06-07,44.13,44.13,43.13,43.13,4451200,10.72
    -1995-06-06,43.63,44.38,43.50,44.00,11270800,10.94
    -1995-06-05,42.38,43.50,42.13,43.50,9103200,10.81
    -1995-06-02,41.88,42.38,41.50,42.13,3783200,10.47
    -1995-06-01,41.88,42.50,41.75,42.19,6685200,10.49
    -1995-05-31,42.13,42.13,41.00,41.56,5707600,10.33
    -1995-05-30,42.63,42.88,41.50,42.00,7021200,10.44
    -1995-05-26,43.00,43.13,42.25,42.69,4097600,10.61
    -1995-05-25,43.25,44.00,43.00,43.38,6536800,10.75
    -1995-05-24,43.75,44.25,42.88,43.50,9459200,10.78
    -1995-05-23,44.13,44.38,43.50,43.88,9881200,10.88
    -1995-05-22,42.50,44.13,42.25,44.13,13282400,10.94
    -1995-05-19,42.88,43.75,42.63,42.75,11522000,10.60
    -1995-05-18,44.13,44.13,43.25,43.38,13287600,10.75
    -1995-05-17,43.75,44.38,43.50,44.00,9419200,10.91
    -1995-05-16,43.13,44.38,42.50,43.75,11895600,10.84
    -1995-05-15,43.13,43.75,42.50,43.63,14053200,10.81
    -1995-05-12,40.88,43.69,40.50,43.63,23153200,10.81
    -1995-05-11,41.63,41.63,40.38,41.00,18712400,10.16
    -1995-05-10,41.50,41.88,40.75,41.44,9837600,10.27
    -1995-05-09,40.63,41.38,40.00,41.25,11540800,10.22
    -1995-05-08,39.88,41.00,39.75,40.50,13832000,10.04
    -1995-05-05,38.75,39.13,38.13,38.88,7445200,9.64
    -1995-05-04,38.25,39.88,38.00,38.50,10846800,9.54
    -1995-05-03,38.25,38.63,38.00,38.13,6043600,9.45
    -1995-05-02,38.25,38.38,37.50,38.13,4289200,9.45
    -1995-05-01,38.25,38.75,38.00,38.25,6375600,9.48
    -1995-04-28,38.00,38.38,37.50,38.25,6984400,9.48
    -1995-04-27,38.50,38.50,37.75,37.88,5014800,9.39
    -1995-04-26,37.63,38.75,37.38,38.25,8246800,9.48
    -1995-04-25,39.13,39.38,37.25,37.75,9780000,9.36
    -1995-04-24,39.00,39.63,38.50,39.00,9724400,9.67
    -1995-04-21,37.25,39.50,37.13,39.13,23812400,9.70
    -1995-04-20,37.13,38.50,36.63,37.63,11772400,9.33
    -1995-04-19,37.50,37.50,35.63,36.38,9990800,9.02
    -1995-04-18,38.50,38.63,37.50,37.50,8263200,9.29
    -1995-04-17,38.13,39.38,37.88,38.38,7467600,9.51
    -1995-04-13,39.25,39.25,37.88,38.25,6242400,9.48
    -1995-04-12,38.25,39.63,37.38,39.00,16973200,9.67
    -1995-04-11,36.75,37.88,36.63,37.75,7673200,9.36
    -1995-04-10,36.88,37.00,36.13,36.63,4211200,9.08
    -1995-04-07,37.00,37.13,36.25,36.75,10562400,9.11
    -1995-04-06,37.25,38.00,35.53,36.75,25823600,9.11
    -1995-04-05,34.13,34.75,33.75,34.75,9470000,8.61
    -1995-04-04,35.75,35.88,33.63,33.88,15300000,8.40
    -1995-04-03,35.50,35.75,35.13,35.50,5528000,8.80
    -1995-03-31,35.13,35.63,34.75,35.25,6558000,8.74
    -1995-03-30,34.63,35.50,34.50,35.38,9767600,8.77
    -1995-03-29,34.00,34.88,33.88,34.38,17760000,8.52
    -1995-03-28,36.25,36.34,34.13,34.38,24655600,8.52
    -1995-03-27,37.63,37.63,36.63,37.19,5111200,9.22
    -1995-03-24,37.38,37.88,37.25,37.75,4584400,9.36
    -1995-03-23,37.88,38.00,36.98,37.13,6094400,9.20
    -1995-03-22,36.25,39.50,36.25,38.06,17130800,9.43
    -1995-03-21,35.50,36.75,35.25,36.25,10920800,8.98
    -1995-03-20,35.13,35.63,35.00,35.25,6793600,8.74
    -1995-03-17,35.50,35.50,34.88,35.13,7713600,8.71
    -1995-03-16,35.25,36.00,35.00,35.25,11330000,8.74
    -1995-03-15,35.50,36.25,34.88,35.00,26120800,8.67
    -1995-03-14,38.25,38.25,34.50,35.00,26015200,8.67
    -1995-03-13,39.63,39.63,38.00,38.13,11653200,9.45
    -1995-03-10,39.63,40.38,39.38,39.50,4923200,9.79
    -1995-03-09,39.88,40.38,39.38,39.75,7038000,9.85
    -1995-03-08,38.75,40.13,37.75,39.56,13048800,9.81
    -1995-03-07,39.88,39.88,38.25,38.31,5399200,9.50
    -1995-03-06,39.75,40.00,39.50,39.75,4751200,9.85
    -1995-03-03,39.75,40.69,39.50,40.25,5209200,9.98
    -1995-03-02,40.13,40.75,39.75,40.00,9619200,9.91
    -1995-03-01,39.75,40.13,39.42,40.00,8025200,9.91
    -1995-02-28,38.50,39.88,38.00,39.50,7965200,9.79
    -1995-02-27,38.25,39.00,38.11,38.25,9600800,9.48
    -1995-02-24,40.13,40.38,38.50,39.00,20334400,9.67
    -1995-02-23,41.13,41.88,40.00,40.19,11262000,9.96
    -1995-02-22,40.63,41.00,40.13,40.81,10501200,10.12
    -1995-02-21,42.63,42.75,40.88,41.00,10776800,10.16
    -1995-02-17,42.88,43.00,42.50,42.50,4366400,10.53
    -1995-02-16,43.13,43.25,42.63,43.19,7821200,10.70
    -1995-02-15,43.25,43.50,42.50,42.56,6604400,10.55
    -1995-02-14,43.75,44.13,42.63,42.94,5934400,10.64
    -1995-02-13,43.50,44.50,43.25,43.75,10120800,10.84
    -1995-02-10,43.63,44.19,43.38,43.75,12542400,10.81
    -1995-02-09,42.13,43.88,42.13,43.63,16988800,10.78
    -1995-02-08,41.00,42.38,40.88,42.31,14403600,10.46
    -1995-02-07,40.38,41.00,40.00,40.81,7200000,10.09
    -1995-02-06,40.75,40.75,39.50,40.50,8702000,10.01
    -1995-02-03,42.00,42.13,40.38,40.50,11400800,10.01
    -1995-02-02,40.13,41.88,40.13,41.63,7288000,10.29
    -1995-02-01,40.75,40.75,39.88,40.13,5665200,9.92
    -1995-01-31,40.50,40.88,40.00,40.38,7621200,9.98
    -1995-01-30,40.13,40.50,39.88,40.13,8255200,9.92
    -1995-01-27,39.88,40.38,39.00,39.88,10676400,9.86
    -1995-01-26,40.88,41.50,39.25,39.50,8822000,9.76
    -1995-01-25,39.50,42.00,39.50,40.98,18482000,10.13
    -1995-01-24,42.25,42.38,41.38,41.63,7805600,10.29
    -1995-01-23,41.88,42.63,41.00,42.25,14252400,10.44
    -1995-01-20,47.00,47.00,42.50,42.63,35731200,10.54
    -1995-01-19,45.50,46.00,45.00,45.88,11238800,11.34
    -1995-01-18,45.00,45.63,44.75,45.63,4581200,11.28
    -1995-01-17,44.50,45.50,44.13,45.00,11806400,11.12
    -1995-01-16,44.88,45.25,44.25,44.50,6765600,11.00
    -1995-01-13,46.13,46.13,44.38,44.88,12565600,11.09
    -1995-01-12,46.13,46.38,44.75,45.38,19721200,11.22
    -1995-01-11,43.75,48.06,42.69,46.75,31212400,11.56
    -1995-01-10,41.25,44.00,41.25,43.69,21977600,10.80
    -1995-01-09,41.63,41.88,41.00,41.20,9805200,10.18
    -1995-01-06,41.63,43.13,41.13,42.00,38456800,10.38
    -1995-01-05,39.25,39.38,38.75,38.88,2646800,9.61
    -1995-01-04,38.63,39.63,38.63,39.38,5682400,9.73
    -1995-01-03,38.88,38.88,37.88,38.38,3726400,9.49
    -1994-12-30,39.38,39.88,38.75,39.00,2616400,9.64
    -1994-12-29,39.25,39.88,39.13,39.50,4341200,9.76
    -1994-12-28,39.13,39.25,38.25,39.13,3198000,9.67
    -1994-12-27,39.25,39.75,38.88,39.13,2928800,9.67
    -1994-12-23,38.50,39.38,38.50,38.88,3372000,9.61
    -1994-12-22,38.50,38.88,38.25,38.63,4771200,9.55
    -1994-12-21,37.88,38.50,37.50,38.38,5635600,9.49
    -1994-12-20,39.13,39.25,38.38,38.50,6263600,9.52
    -1994-12-19,37.25,39.38,37.25,39.13,11890000,9.67
    -1994-12-16,37.25,37.75,36.75,37.25,6432400,9.21
    -1994-12-15,38.00,38.38,36.88,37.13,8133200,9.18
    -1994-12-14,36.50,38.13,36.50,37.88,11123600,9.36
    -1994-12-13,36.63,36.94,36.25,36.38,4266800,8.99
    -1994-12-12,36.38,36.75,35.50,36.50,8004400,9.02
    -1994-12-09,35.88,36.38,34.75,36.25,9329200,8.96
    -1994-12-08,36.88,37.00,35.75,35.88,6081200,8.87
    -1994-12-07,37.50,37.81,36.06,36.63,4916800,9.05
    -1994-12-06,37.00,38.38,36.88,37.56,8516400,9.28
    -1994-12-05,36.50,37.38,36.13,37.19,6460000,9.19
    -1994-12-02,36.50,36.75,35.63,36.56,6170000,9.04
    -1994-12-01,37.00,37.63,36.00,36.19,11051200,8.95
    -1994-11-30,38.38,39.38,37.00,37.25,11157600,9.21
    -1994-11-29,38.00,38.50,37.75,38.25,5163200,9.45
    -1994-11-28,37.63,38.25,37.31,37.81,4971200,9.35
    -1994-11-25,36.88,37.75,36.75,37.75,3012400,9.33
    -1994-11-23,37.00,37.88,36.38,36.88,11723200,9.12
    -1994-11-22,37.75,39.13,37.25,37.38,8018800,9.24
    -1994-11-21,40.00,40.25,38.00,38.13,7255600,9.42
    -1994-11-18,40.00,40.50,39.63,40.00,5257600,9.89
    -1994-11-17,40.88,41.00,39.88,40.00,5380000,9.86
    -1994-11-16,40.75,41.56,40.63,40.94,6700000,10.09
    -1994-11-15,42.50,43.00,41.25,41.38,6001200,10.20
    -1994-11-14,41.25,42.75,41.25,42.50,5002000,10.47
    -1994-11-11,41.25,41.50,41.00,41.13,2237600,10.14
    -1994-11-10,41.75,41.88,41.00,41.31,5476800,10.18
    -1994-11-09,42.75,43.00,41.00,41.63,14530000,10.26
    -1994-11-08,40.63,42.63,40.25,42.25,12476400,10.41
    -1994-11-07,40.38,41.25,40.13,40.75,4058000,10.04
    -1994-11-04,41.50,41.63,40.00,40.38,6869200,9.95
    -1994-11-03,41.75,42.00,41.00,41.50,3962400,10.23
    -1994-11-02,43.13,43.25,41.38,41.38,7819200,10.20
    -1994-11-01,42.88,43.48,42.38,43.13,7805600,10.63
    -1994-10-31,42.00,43.38,41.50,43.19,12728000,10.64
    -1994-10-28,42.38,42.88,41.75,42.13,9762400,10.38
    -1994-10-27,43.25,43.75,42.50,42.75,5700800,10.54
    -1994-10-26,42.63,43.27,42.63,43.25,7043200,10.66
    -1994-10-25,41.63,42.63,41.50,42.63,10771200,10.51
    -1994-10-24,42.75,43.13,41.88,42.25,7316800,10.41
    -1994-10-21,40.75,42.75,40.75,42.63,11528000,10.51
    -1994-10-20,41.25,41.81,40.50,41.00,7808000,10.10
    -1994-10-19,41.00,42.13,41.00,41.25,12549200,10.17
    -1994-10-18,40.63,41.63,40.50,41.25,16749200,10.17
    -1994-10-17,40.88,41.50,38.88,39.75,10866400,9.80
    -1994-10-14,41.50,42.00,40.88,41.13,6292000,10.14
    -1994-10-13,42.63,42.88,40.63,41.13,18761200,10.14
    -1994-10-12,39.63,42.63,39.13,42.13,21340000,10.38
    -1994-10-11,41.38,41.88,39.38,39.63,30083600,9.77
    -1994-10-10,37.13,39.63,37.00,38.88,18700800,9.58
    -1994-10-07,36.13,37.06,35.50,37.00,13022000,9.12
    -1994-10-06,37.38,37.48,36.00,36.25,18828800,8.93
    -1994-10-05,33.63,38.13,33.38,37.88,25366800,9.33
    -1994-10-04,33.25,34.00,33.00,33.75,5822000,8.32
    -1994-10-03,33.63,33.75,32.50,33.13,4644400,8.16
    -1994-09-30,34.13,34.50,33.63,33.69,2561200,8.30
    -1994-09-29,33.75,34.38,33.38,34.13,3921200,8.41
    -1994-09-28,34.00,34.38,33.63,33.88,2914800,8.35
    -1994-09-27,33.75,34.13,33.38,33.88,3904800,8.35
    -1994-09-26,33.88,34.50,33.63,33.94,5072400,8.36
    -1994-09-23,33.88,34.50,33.88,33.94,4760000,8.36
    -1994-09-22,34.25,34.25,33.63,33.88,5235600,8.35
    -1994-09-21,34.50,34.63,33.75,34.13,8402400,8.41
    -1994-09-20,35.13,35.38,34.38,34.56,7047600,8.52
    -1994-09-19,36.38,36.75,35.50,35.50,6242000,8.75
    -1994-09-16,35.88,37.25,35.50,36.38,13008000,8.97
    -1994-09-15,35.13,36.13,35.13,36.00,9253200,8.87
    -1994-09-14,35.63,35.75,35.00,35.13,3549200,8.66
    -1994-09-13,35.75,36.25,35.63,35.81,3723600,8.82
    -1994-09-12,35.63,35.75,35.38,35.75,3252400,8.81
    -1994-09-09,35.75,36.00,35.38,35.75,5624400,8.81
    -1994-09-08,36.00,36.25,35.63,36.13,5691200,8.90
    -1994-09-07,35.63,36.63,35.38,36.13,7283200,8.90
    -1994-09-06,35.25,35.63,35.00,35.56,3279200,8.76
    -1994-09-02,35.25,35.50,35.00,35.38,3628000,8.72
    -1994-09-01,35.38,35.75,34.63,35.00,7305200,8.63
    -1994-08-31,36.00,37.38,35.75,36.19,12568800,8.92
    -1994-08-30,35.25,36.38,35.13,36.25,6515600,8.93
    -1994-08-29,35.75,36.13,35.25,35.38,5450800,8.72
    -1994-08-26,35.25,36.13,35.25,35.75,7300000,8.81
    -1994-08-25,34.25,36.38,34.25,35.06,10688800,8.64
    -1994-08-24,34.75,35.00,34.38,34.88,6132400,8.60
    -1994-08-23,34.88,35.88,34.75,35.00,7669200,8.63
    -1994-08-22,34.75,35.00,34.63,34.88,5445600,8.60
    -1994-08-19,34.75,35.00,34.25,34.88,4674800,8.60
    -1994-08-18,34.75,35.25,34.50,34.63,7370000,8.53
    -1994-08-17,34.88,35.38,34.63,35.00,10232400,8.63
    -1994-08-16,34.38,34.75,34.00,34.75,5563200,8.56
    -1994-08-15,34.75,35.00,34.25,34.63,4293200,8.53
    -1994-08-12,34.38,35.13,33.88,34.75,6425200,8.53
    -1994-08-11,34.25,35.13,33.88,34.31,10649200,8.43
    -1994-08-10,33.63,34.88,33.25,34.63,9065200,8.50
    -1994-08-09,33.50,33.88,33.13,33.63,2811200,8.26
    -1994-08-08,33.13,34.00,33.00,33.75,5048800,8.29
    -1994-08-05,32.88,33.38,32.88,33.25,3123200,8.17
    -1994-08-04,33.13,33.75,33.13,33.25,6620000,8.17
    -1994-08-03,32.75,33.25,32.13,33.13,8113600,8.14
    -1994-08-02,33.50,33.63,32.38,32.56,9642400,8.00
    -1994-08-01,33.63,33.75,32.75,33.38,8204400,8.20
    -1994-07-29,31.87,34.00,31.87,33.69,19853600,8.27
    -1994-07-28,31.00,32.13,30.87,31.87,8762000,7.83
    -1994-07-27,31.25,31.37,30.62,31.06,4788000,7.63
    -1994-07-26,31.75,32.00,31.12,31.37,6756400,7.70
    -1994-07-25,31.12,31.87,30.75,31.69,15103200,7.78
    -1994-07-22,31.62,31.97,30.00,31.00,28098800,7.61
    -1994-07-21,26.62,28.50,26.50,28.00,10348800,6.88
    -1994-07-20,27.37,27.62,26.37,26.62,7765200,6.54
    -1994-07-19,28.62,28.75,27.37,27.69,4176400,6.80
    -1994-07-18,28.12,29.00,28.00,28.37,2734800,6.97
    -1994-07-15,28.23,28.62,27.50,28.25,3409200,6.94
    -1994-07-14,29.62,29.75,28.25,28.62,6459200,7.03
    -1994-07-13,28.50,30.25,28.50,29.69,16081200,7.29
    -1994-07-12,27.00,28.44,26.37,28.37,8662000,6.97
    -1994-07-11,27.12,27.37,26.62,27.00,3801200,6.63
    -1994-07-08,26.50,27.62,26.50,27.06,7457600,6.65
    -1994-07-07,25.87,27.00,25.50,26.81,6097600,6.58
    -1994-07-06,26.25,26.50,26.00,26.12,3499200,6.41
    -1994-07-05,25.62,26.75,25.62,26.50,3080800,6.51
    -1994-07-01,26.37,26.50,25.37,25.75,6404400,6.32
    -1994-06-30,26.25,26.87,26.25,26.50,3652000,6.51
    -1994-06-29,26.75,27.12,25.87,26.12,4842400,6.41
    -1994-06-28,26.25,27.12,25.62,26.75,6235200,6.57
    -1994-06-27,25.25,26.25,24.62,26.25,9153200,6.45
    -1994-06-24,25.12,26.12,24.75,25.61,10470000,6.29
    -1994-06-23,26.25,26.25,24.87,25.12,7283200,6.17
    -1994-06-22,26.25,26.75,26.00,26.25,4081200,6.45
    -1994-06-21,26.87,27.25,25.75,26.00,8693200,6.39
    -1994-06-20,26.25,27.25,26.00,27.12,7150000,6.66
    -1994-06-17,26.00,26.75,25.87,26.50,8027600,6.51
    -1994-06-16,27.75,27.75,26.12,26.37,7812400,6.48
    -1994-06-15,27.00,28.00,26.87,27.81,5704400,6.83
    -1994-06-14,27.25,27.37,26.62,27.06,5531200,6.65
    -1994-06-13,26.37,27.19,26.37,27.00,3339200,6.63
    -1994-06-10,27.12,27.37,26.37,26.50,5107600,6.51
    -1994-06-09,25.62,27.00,25.50,27.00,10485200,6.63
    -1994-06-08,27.50,27.62,26.00,26.12,9809200,6.41
    -1994-06-07,27.25,27.75,27.25,27.50,5013600,6.75
    -1994-06-06,27.50,27.75,27.00,27.37,4513200,6.72
    -1994-06-03,27.12,28.00,26.75,27.62,12649200,6.78
    -1994-06-02,28.37,28.50,27.12,27.37,13762400,6.72
    -1994-06-01,28.50,28.62,27.87,28.25,13786800,6.94
    -1994-05-31,29.50,29.50,28.50,29.25,9211200,7.18
    -1994-05-27,30.25,30.75,29.50,29.94,3882400,7.35
    -1994-05-26,31.50,31.50,30.25,30.50,2613200,7.46
    -1994-05-25,30.25,31.75,30.00,31.25,4873200,7.64
    -1994-05-24,31.00,31.25,30.25,30.75,4536400,7.52
    -1994-05-23,31.00,31.25,30.00,30.50,4286400,7.46
    -1994-05-20,31.75,32.25,31.00,31.06,3519200,7.60
    -1994-05-19,30.75,32.50,30.50,32.13,9776800,7.86
    -1994-05-18,29.75,30.75,29.25,30.62,4436800,7.49
    -1994-05-17,29.75,29.75,28.75,29.37,6450800,7.18
    -1994-05-16,30.00,30.50,29.50,29.50,4854800,7.22
    -1994-05-13,29.75,30.50,29.25,30.00,3323200,7.34
    -1994-05-12,30.50,30.75,29.50,29.69,3839200,7.26
    -1994-05-11,31.00,31.50,29.75,30.25,5218000,7.40
    -1994-05-10,31.75,32.00,31.00,31.00,5246800,7.58
    -1994-05-09,32.25,32.50,30.75,31.25,5026400,7.64
    -1994-05-06,32.25,32.75,31.25,32.31,6721200,7.90
    -1994-05-05,33.25,33.75,32.25,32.88,10307600,8.04
    -1994-05-04,31.00,33.25,30.50,33.00,13008800,8.07
    -1994-05-03,31.00,31.25,29.50,30.25,4761200,7.40
    -1994-05-02,30.00,31.25,30.00,31.00,4401200,7.58
    -1994-04-29,30.00,30.50,29.75,30.00,3399200,7.34
    -1994-04-28,31.00,31.25,29.75,30.25,3604400,7.40
    -1994-04-26,31.50,31.50,31.00,31.25,5879200,7.64
    -1994-04-25,29.75,31.00,29.50,31.00,12846800,7.58
    -1994-04-22,31.25,32.00,28.50,29.75,24923600,7.28
    -1994-04-21,28.50,30.50,27.00,29.62,14674400,7.25
    -1994-04-20,29.25,30.00,28.00,28.25,10080800,6.91
    -1994-04-19,29.75,30.00,28.50,29.00,5947600,7.09
    -1994-04-18,30.50,30.50,29.25,29.62,8238800,7.25
    -1994-04-15,31.25,31.50,30.00,30.25,6730800,7.40
    -1994-04-14,30.50,31.75,30.00,31.50,7933200,7.71
    -1994-04-13,32.25,32.50,31.25,31.75,8330000,7.77
    -1994-04-12,33.38,33.38,31.75,32.00,4890800,7.83
    -1994-04-11,33.50,33.50,32.50,33.50,3823600,8.19
    -1994-04-08,33.75,34.00,33.25,33.50,6336400,8.19
    -1994-04-07,33.50,33.75,32.75,33.38,2764800,8.17
    -1994-04-06,34.00,34.00,32.75,33.50,4616400,8.19
    -1994-04-05,33.75,34.25,33.50,33.50,3505600,8.19
    -1994-04-04,32.25,33.25,31.75,33.25,6016800,8.13
    -1994-03-31,32.50,33.50,31.50,33.25,7481200,8.13
    -1994-03-30,32.50,33.25,31.75,32.50,6079200,7.95
    -1994-03-29,33.25,33.75,32.25,32.75,7640000,8.01
    -1994-03-28,33.00,34.00,32.75,33.25,10098800,8.13
    -1994-03-25,34.75,34.75,32.75,32.75,12291200,8.01
    -1994-03-24,35.13,35.25,34.00,34.63,6738800,8.47
    -1994-03-23,35.25,35.50,34.25,35.13,7749200,8.59
    -1994-03-22,35.25,35.50,34.50,35.00,8690800,8.56
    -1994-03-21,36.38,36.50,35.25,35.50,8806400,8.68
    -1994-03-18,36.75,36.75,35.75,36.38,8004400,8.90
    -1994-03-17,36.75,37.00,36.25,36.50,5590800,8.93
    -1994-03-16,37.50,37.75,36.50,36.75,5265200,8.99
    -1994-03-15,38.25,38.25,37.25,37.63,7319200,9.20
    -1994-03-14,38.50,38.50,37.75,38.13,15783600,9.33
    -1994-03-11,37.00,37.75,36.75,37.25,5791200,9.11
    -1994-03-10,37.25,37.63,36.75,37.25,5142400,9.11
    -1994-03-09,36.63,37.50,36.00,37.50,8896800,9.17
    -1994-03-08,38.00,38.00,36.75,37.00,6647600,9.05
    -1994-03-07,37.00,38.13,36.75,37.88,11088800,9.27
    -1994-03-04,36.00,37.50,35.75,36.75,8113600,8.99
    -1994-03-03,35.75,36.25,35.50,35.75,6737600,8.75
    -1994-03-02,35.25,36.25,34.75,35.63,10519200,8.72
    -1994-03-01,36.75,36.75,35.75,36.25,7570800,8.87
    -1994-02-28,36.25,37.00,36.00,36.50,4434800,8.93
    -1994-02-25,37.00,37.25,35.50,36.00,8468000,8.81
    -1994-02-24,37.00,37.25,36.25,36.63,7081200,8.96
    -1994-02-23,37.25,38.25,37.00,37.25,9318800,9.11
    -1994-02-22,36.25,37.50,35.75,37.25,7676400,9.11
    -1994-02-18,36.50,37.00,36.25,36.25,5326400,8.87
    -1994-02-17,37.25,37.88,36.25,37.00,5197600,9.05
    -1994-02-16,37.50,37.50,36.75,36.75,4379200,8.99
    -1994-02-15,36.75,37.50,36.25,37.13,4654400,9.08
    -1994-02-14,37.00,38.00,36.75,37.00,8775200,9.05
    -1994-02-11,36.25,37.50,36.25,37.00,5880800,9.05
    -1994-02-10,36.25,37.50,36.00,36.50,10802000,8.93
    -1994-02-09,35.75,36.50,35.25,36.25,6699200,8.87
    -1994-02-08,36.00,36.50,35.25,35.75,10210800,8.75
    -1994-02-07,33.50,37.13,33.50,36.50,25925200,8.93
    -1994-02-04,33.50,35.00,33.25,33.50,12645200,8.17
    -1994-02-03,33.00,33.63,32.50,33.50,4933200,8.17
    -1994-02-02,33.25,33.25,32.50,33.00,5247600,8.04
    -1994-02-01,33.00,33.50,32.25,33.25,5618000,8.10
    -1994-01-31,33.50,33.75,32.75,32.75,8532400,7.98
    -1994-01-28,34.25,34.75,33.75,34.00,4891200,8.29
    -1994-01-27,33.50,34.25,33.00,34.13,4724800,8.32
    -1994-01-26,33.75,34.00,33.25,33.50,5922400,8.17
    -1994-01-25,34.75,35.00,33.25,33.88,15818800,8.26
    -1994-01-24,33.25,35.25,33.25,35.00,24742000,8.53
    -1994-01-21,33.25,33.50,32.25,33.38,35007600,8.14
    -1994-01-20,29.50,30.75,29.50,29.87,9582400,7.28
    -1994-01-19,29.25,29.75,28.75,29.25,10066400,7.13
    -1994-01-18,30.25,30.25,29.00,29.37,12978000,7.16
    -1994-01-17,31.00,31.50,30.00,30.37,5206400,7.40
    -1994-01-14,30.75,31.75,30.50,31.00,7673200,7.56
    -1994-01-13,30.00,30.75,29.75,30.62,19000000,7.46
    -1994-01-12,32.25,32.25,30.50,30.50,15684400,7.43
    -1994-01-11,33.50,33.75,31.75,31.87,12700000,7.77
    -1994-01-10,33.00,33.88,32.75,33.63,7222000,8.20
    -1994-01-07,32.00,33.25,31.25,33.13,10688800,8.08
    -1994-01-06,33.75,34.00,32.50,32.75,13095200,7.98
    -1994-01-05,31.75,33.88,31.75,33.75,21874400,8.23
    -1994-01-04,30.25,31.50,30.00,31.50,10198800,7.68
    -1994-01-03,29.50,30.00,29.00,29.87,6485200,7.28
    -1993-12-31,29.75,30.25,29.25,29.25,5765200,7.13
    -1993-12-30,28.50,30.25,28.50,29.75,11253200,7.25
    -1993-12-29,29.25,29.25,28.50,28.50,3853200,6.95
    -1993-12-28,28.75,29.50,28.50,29.12,5705600,7.10
    -1993-12-27,27.75,28.75,27.25,28.50,5730000,6.95
    -1993-12-23,27.25,27.25,26.50,27.25,8120000,6.64
    -1993-12-22,27.25,28.50,27.00,28.00,6498800,6.82
    -1993-12-21,28.50,28.75,27.25,27.50,8973600,6.70
    -1993-12-20,29.25,29.75,28.25,28.50,6768800,6.95
    -1993-12-17,29.50,29.75,29.12,29.50,5197600,7.19
    -1993-12-16,29.50,29.75,29.00,29.37,4532000,7.16
    -1993-12-15,29.00,29.75,29.00,29.75,4438000,7.25
    -1993-12-14,29.25,29.75,29.00,29.12,10492400,7.10
    -1993-12-13,28.25,29.50,27.75,29.50,8729200,7.19
    -1993-12-10,30.25,30.50,27.75,28.25,17781200,6.89
    -1993-12-09,31.75,32.00,29.75,30.00,6531200,7.31
    -1993-12-08,32.00,32.25,31.50,31.87,1422000,7.77
    -1993-12-07,32.00,32.25,31.50,32.25,2280800,7.86
    -1993-12-06,31.50,32.50,31.25,32.25,5610000,7.86
    -1993-12-03,31.75,32.00,31.00,31.50,4314800,7.68
    -1993-12-02,31.75,32.00,31.00,31.75,3614400,7.74
    -1993-12-01,32.00,32.25,31.25,31.50,3978800,7.68
    -1993-11-30,31.75,32.63,31.50,31.50,4036800,7.68
    -1993-11-29,32.25,32.50,31.50,31.75,3462000,7.74
    -1993-11-26,32.75,33.00,32.25,32.63,1569200,7.95
    -1993-11-24,32.75,33.50,32.63,33.00,3246800,8.04
    -1993-11-23,32.50,33.00,31.25,33.00,6653600,8.04
    -1993-11-22,32.75,33.00,32.25,32.50,5389200,7.92
    -1993-11-19,33.00,33.50,32.50,33.00,4409200,8.04
    -1993-11-18,33.50,33.75,33.00,33.50,4089200,8.14
    -1993-11-17,34.00,35.00,32.75,33.50,10812400,8.14
    -1993-11-16,32.00,34.25,31.75,34.00,10838000,8.26
    -1993-11-15,31.50,32.75,31.50,32.00,5616800,7.77
    -1993-11-12,31.50,32.00,30.50,31.75,5136800,7.71
    -1993-11-11,30.75,32.00,30.50,31.37,5090800,7.62
    -1993-11-10,30.25,30.75,30.00,30.75,2765600,7.47
    -1993-11-09,31.00,31.25,29.75,30.12,6136400,7.32
    -1993-11-08,32.00,32.13,30.50,30.75,5966400,7.47
    -1993-11-05,31.87,32.25,30.75,31.87,13513200,7.74
    -1993-11-04,31.50,32.25,30.75,32.25,6632000,7.83
    -1993-11-03,33.00,33.00,31.00,31.62,6320000,7.68
    -1993-11-02,31.25,33.00,31.00,32.75,8013600,7.95
    -1993-11-01,30.75,31.50,30.25,31.50,3798800,7.65
    -1993-10-29,31.00,31.75,30.50,30.75,4892400,7.47
    -1993-10-28,31.75,32.25,31.00,31.00,8736800,7.53
    -1993-10-27,30.00,32.25,29.75,31.75,16415200,7.71
    -1993-10-26,29.75,30.00,29.00,29.75,7960000,7.23
    -1993-10-25,30.25,30.50,29.62,30.00,7840800,7.29
    -1993-10-22,30.50,31.50,29.75,30.25,14160000,7.35
    -1993-10-21,27.50,31.25,27.25,30.25,22417600,7.35
    -1993-10-20,28.00,28.25,27.25,27.75,4956400,6.74
    -1993-10-19,28.25,28.50,27.25,27.75,7643200,6.74
    -1993-10-18,28.00,28.75,27.75,28.37,11900000,6.89
    -1993-10-15,27.75,28.50,26.75,28.25,34136400,6.86
    -1993-10-14,24.00,24.50,23.50,23.75,5749200,5.77
    -1993-10-13,24.25,24.25,23.50,24.00,6322400,5.83
    -1993-10-12,24.00,25.00,23.75,24.00,10952400,5.83
    -1993-10-11,22.75,24.00,22.75,23.75,5775200,5.77
    -1993-10-08,23.25,23.25,22.25,22.62,4989200,5.49
    -1993-10-07,23.50,23.75,22.75,23.00,4828000,5.59
    -1993-10-06,23.75,24.00,23.37,23.62,6271200,5.74
    -1993-10-05,23.00,24.00,23.00,23.50,6306400,5.71
    -1993-10-04,22.62,23.00,22.00,22.75,6891200,5.53
    -1993-10-01,22.75,23.00,22.50,22.75,12022000,5.53
    -1993-09-30,24.00,24.00,23.00,23.37,9828000,5.68
    -1993-09-29,24.25,24.87,23.75,23.87,8463600,5.80
    -1993-09-28,24.75,25.00,24.25,24.75,3386400,6.01
    -1993-09-27,25.00,25.25,24.25,24.75,4043200,6.01
    -1993-09-24,25.00,25.25,24.50,25.00,2743200,6.07
    -1993-09-23,25.50,25.50,24.50,24.75,4697600,6.01
    -1993-09-22,24.25,25.50,24.25,25.50,3960800,6.19
    -1993-09-21,24.75,25.25,23.87,24.50,5250000,5.95
    -1993-09-20,25.25,25.50,24.75,24.87,3968800,6.04
    -1993-09-17,24.37,25.50,24.25,25.25,6157600,6.13
    -1993-09-16,24.25,25.00,24.25,24.75,3086800,6.01
    -1993-09-15,24.50,25.00,23.50,24.50,9206800,5.95
    -1993-09-14,24.25,25.00,24.00,24.25,9880000,5.89
    -1993-09-13,26.25,26.50,24.75,25.25,9143600,6.13
    -1993-09-10,26.25,26.25,25.37,26.25,4804800,6.38
    -1993-09-09,26.75,27.00,26.00,26.00,5352000,6.31
    -1993-09-08,26.25,27.00,26.00,26.75,8102000,6.50
    -1993-09-07,26.00,27.00,25.75,26.25,5130000,6.38
    -1993-09-03,26.00,26.00,25.25,25.75,5830000,6.25
    -1993-09-02,26.00,26.25,25.25,25.75,10081200,6.25
    -1993-09-01,26.50,26.75,25.75,26.12,8065200,6.34
    -1993-08-31,26.50,26.75,26.00,26.50,4570800,6.44
    -1993-08-30,26.50,26.50,25.87,26.00,9785600,6.31
    -1993-08-27,27.00,27.00,26.25,26.50,6676400,6.44
    -1993-08-26,27.25,27.25,26.50,26.87,6296800,6.53
    -1993-08-25,28.00,28.25,26.75,27.25,5209200,6.62
    -1993-08-24,28.25,28.75,27.75,28.00,3625600,6.80
    -1993-08-23,28.00,28.75,27.50,28.37,3265600,6.89
    -1993-08-20,27.75,28.00,27.00,28.00,3574400,6.80
    -1993-08-19,28.75,28.75,27.50,27.50,5452000,6.68
    -1993-08-18,29.00,29.75,28.25,28.50,6751200,6.92
    -1993-08-17,27.75,28.50,27.25,28.37,3876800,6.89
    -1993-08-16,27.50,28.00,27.25,27.50,3669200,6.68
    -1993-08-13,26.50,27.75,26.25,27.37,4978800,6.62
    -1993-08-12,27.50,27.75,26.00,26.50,12098800,6.41
    -1993-08-11,28.50,28.50,27.00,27.50,5965200,6.65
    -1993-08-10,29.50,29.75,28.25,28.50,5465600,6.89
    -1993-08-09,29.25,30.25,29.00,29.75,5767600,7.19
    -1993-08-06,29.25,30.25,29.25,29.25,4506800,7.07
    -1993-08-05,30.75,30.75,29.00,29.50,7498800,7.13
    -1993-08-04,29.25,30.50,29.00,30.25,8700000,7.31
    -1993-08-03,29.00,29.25,28.75,29.00,6315600,7.01
    -1993-08-02,28.25,29.25,28.00,28.50,7728000,6.89
    -1993-07-30,27.50,28.25,27.00,27.75,7669200,6.71
    -1993-07-29,27.00,27.50,26.75,27.25,4343200,6.59
    -1993-07-28,26.25,27.00,26.25,26.87,3300000,6.50
    -1993-07-27,26.75,27.50,26.25,26.50,7100800,6.41
    -1993-07-26,26.75,27.50,26.00,26.87,5468000,6.50
    -1993-07-23,27.00,27.50,26.00,26.25,8365600,6.35
    -1993-07-22,26.00,27.00,25.75,26.50,7554400,6.41
    -1993-07-21,26.00,26.75,25.50,26.25,16283600,6.35
    -1993-07-20,26.25,27.75,25.75,26.87,19017600,6.50
    -1993-07-19,28.00,28.75,25.50,25.62,28813200,6.20
    -1993-07-16,28.50,29.62,26.50,27.50,75744400,6.65
    -1993-07-15,37.25,37.75,35.25,35.75,12091200,8.64
    -1993-07-14,36.75,37.50,35.75,37.25,8816800,9.01
    -1993-07-13,38.75,38.75,37.00,37.25,5650800,9.01
    -1993-07-12,36.75,38.13,36.25,38.00,6215600,9.19
    -1993-07-09,37.00,37.25,36.50,36.75,5604400,8.89
    -1993-07-08,36.50,37.50,36.25,36.50,4964800,8.83
    -1993-07-07,37.50,37.88,36.25,36.50,8124400,8.83
    -1993-07-06,38.25,39.00,37.50,37.75,5558800,9.13
    -1993-07-02,38.25,38.75,37.75,38.50,6846400,9.31
    -1993-07-01,39.00,39.75,38.00,38.00,7809200,9.19
    -1993-06-30,38.75,39.75,38.50,39.50,7170000,9.55
    -1993-06-29,40.25,40.25,38.50,39.00,10526400,9.43
    -1993-06-28,40.50,40.50,38.75,40.13,12645600,9.70
    -1993-06-25,40.38,40.75,39.50,40.00,9198000,9.67
    -1993-06-24,40.50,41.75,40.00,41.75,7980000,10.10
    -1993-06-23,41.75,41.75,40.00,40.50,6462400,9.79
    -1993-06-22,40.88,42.00,39.75,41.38,12021200,10.01
    -1993-06-21,40.50,40.50,39.50,39.63,9776800,9.58
    -1993-06-18,41.63,42.13,39.75,41.00,11138800,9.91
    -1993-06-17,42.50,42.50,40.50,41.25,14635600,9.97
    -1993-06-16,42.25,43.25,41.50,42.25,12615600,10.22
    -1993-06-15,45.25,45.25,41.88,42.00,16018000,10.16
    -1993-06-14,44.00,44.75,43.50,44.63,8927600,10.79
    -1993-06-11,45.00,45.25,43.38,43.75,8662400,10.58
    -1993-06-10,43.50,44.75,42.75,44.50,19783600,10.76
    -1993-06-09,45.00,45.63,44.00,44.25,42090000,10.70
    -1993-06-08,48.75,50.00,48.00,49.50,22194400,11.97
    -1993-06-07,54.50,54.75,50.38,50.75,17239200,12.27
    -1993-06-04,55.75,56.25,54.50,54.88,7649200,13.27
    -1993-06-03,57.00,57.25,56.00,56.38,5603200,13.63
    -1993-06-02,56.75,58.25,56.00,57.00,7160000,13.78
    -1993-06-01,56.50,57.75,56.50,57.00,4837600,13.78
    -1993-05-28,57.00,57.50,56.25,56.63,6575200,13.69
    -1993-05-27,57.75,58.50,57.25,57.50,7049200,13.87
    -1993-05-26,56.00,57.75,55.38,57.75,4353600,13.94
    -1993-05-25,56.75,57.50,55.75,56.38,6462400,13.60
    -1993-05-24,56.75,58.75,56.75,57.63,5373200,13.91
    -1993-05-21,58.75,59.13,56.75,57.50,5300000,13.87
    -1993-05-20,57.25,59.00,57.25,58.75,10385200,14.18
    -1993-05-19,54.75,57.50,54.50,57.25,6176400,13.81
    -1993-05-18,55.50,56.25,55.00,55.50,5860000,13.39
    -1993-05-17,55.50,56.00,55.00,55.75,2491200,13.45
    -1993-05-14,55.25,56.00,55.00,55.50,4212000,13.39
    -1993-05-13,53.50,55.75,53.50,55.50,12940800,13.39
    -1993-05-12,54.25,54.75,53.00,53.25,3779200,12.85
    -1993-05-11,55.00,55.25,54.00,54.50,5665600,13.15
    -1993-05-10,55.00,55.88,55.00,55.00,4929200,13.27
    -1993-05-07,53.50,54.75,53.50,54.75,2927600,13.21
    -1993-05-06,54.50,54.75,53.50,53.75,2536800,12.97
    -1993-05-05,53.00,55.50,53.00,54.50,9059200,13.15
    -1993-05-04,52.25,54.25,52.00,53.38,6112400,12.88
    -1993-05-03,51.25,52.00,51.00,51.88,2332400,12.52
    -1993-04-30,50.75,52.50,50.75,51.25,4730000,12.37
    -1993-04-29,51.50,51.75,50.13,50.75,2958000,12.25
    -1993-04-28,49.75,52.00,49.75,51.38,5846800,12.40
    -1993-04-27,48.75,50.25,48.75,50.25,4648800,12.13
    -1993-04-26,49.25,49.75,48.50,49.00,3689200,11.82
    -1993-04-23,49.75,50.25,48.75,49.25,4808000,11.88
    -1993-04-22,49.25,50.50,49.00,50.00,5648800,12.06
    -1993-04-21,50.25,50.75,49.25,49.63,7337600,11.98
    -1993-04-20,48.75,50.25,48.25,50.00,8580800,12.06
    -1993-04-19,48.50,49.50,48.25,48.50,8148000,11.70
    -1993-04-16,48.25,48.75,47.38,48.13,24533200,11.61
    -1993-04-15,48.25,48.25,46.75,47.25,7816800,11.40
    -1993-04-14,48.25,48.75,47.63,48.75,6092400,11.76
    -1993-04-13,50.50,51.25,48.25,48.50,5893600,11.70
    -1993-04-12,49.50,51.00,49.50,50.00,3324800,12.06
    -1993-04-08,50.00,50.50,49.00,49.75,5857600,12.00
    -1993-04-07,49.00,50.75,48.50,50.50,5825200,12.19
    -1993-04-06,50.00,50.25,48.75,48.75,6020800,11.76
    -1993-04-05,50.00,50.50,49.50,50.00,5332000,12.06
    -1993-04-02,50.50,51.25,49.50,50.13,9077600,12.10
    -1993-04-01,51.25,52.00,51.00,51.75,3878000,12.49
    -1993-03-31,52.50,52.75,51.25,51.50,7968800,12.43
    -1993-03-30,51.13,52.25,50.25,52.25,9447600,12.61
    -1993-03-29,52.25,52.50,50.75,51.00,9362000,12.31
    -1993-03-26,54.75,54.75,52.50,53.25,5431200,12.85
    -1993-03-25,53.75,54.75,53.50,54.75,6125200,13.21
    -1993-03-24,52.75,54.25,52.50,53.75,5126400,12.97
    -1993-03-23,53.25,54.00,52.63,52.75,3674400,12.73
    -1993-03-22,53.50,53.88,52.75,53.25,5911200,12.85
    -1993-03-19,55.00,55.25,53.50,53.75,5516800,12.97
    -1993-03-18,55.00,55.63,54.50,54.50,3810800,13.15
    -1993-03-17,56.50,57.00,55.00,55.13,6301200,13.30
    -1993-03-16,57.25,57.75,56.50,56.50,3626800,13.63
    -1993-03-15,56.00,57.25,55.38,57.00,4868800,13.75
    -1993-03-12,56.75,56.75,55.50,56.25,4527600,13.57
    -1993-03-11,57.00,57.25,56.25,56.88,5167600,13.73
    -1993-03-10,56.75,57.25,56.00,56.75,4738800,13.69
    -1993-03-09,56.50,57.50,56.50,56.75,5535200,13.69
    -1993-03-08,55.00,56.75,55.00,56.50,6322400,13.63
    -1993-03-05,54.75,55.75,54.75,55.00,4001200,13.27
    -1993-03-04,54.50,55.25,53.50,55.00,6730000,13.27
    -1993-03-03,54.00,55.00,53.25,54.63,7261200,13.18
    -1993-03-02,53.00,54.50,53.00,54.25,5294400,13.09
    -1993-03-01,53.00,53.50,52.75,53.25,4272400,12.85
    -1993-02-26,54.25,54.25,52.25,53.00,10538000,12.79
    -1993-02-25,53.25,54.75,53.25,54.75,5979200,13.21
    -1993-02-24,52.13,53.88,52.13,53.63,10253600,12.94
    -1993-02-23,55.00,55.25,54.00,54.25,6937600,13.09
    -1993-02-22,55.00,56.00,54.75,55.13,3531200,13.30
    -1993-02-19,55.25,55.50,54.75,55.00,6366800,13.27
    -1993-02-18,55.00,55.25,53.50,55.00,10006800,13.27
    -1993-02-17,53.25,54.00,52.00,53.88,8932400,13.00
    -1993-02-16,53.50,53.50,51.50,53.00,14563200,12.79
    -1993-02-12,55.00,55.50,53.75,53.88,9855600,13.00
    -1993-02-11,55.75,56.25,55.00,55.13,6015200,13.27
    -1993-02-10,57.00,57.25,55.00,55.75,9593600,13.42
    -1993-02-09,57.00,57.38,56.50,56.88,8525600,13.70
    -1993-02-08,57.00,57.50,55.50,56.50,10060000,13.60
    -1993-02-05,59.25,59.50,56.25,57.25,13134400,13.78
    -1993-02-04,60.00,60.25,59.00,59.50,7453200,14.33
    -1993-02-03,61.00,61.00,58.50,60.00,9455200,14.45
    -1993-02-02,60.75,61.50,60.25,60.25,6530000,14.51
    -1993-02-01,59.25,61.25,59.25,61.25,8608800,14.75
    -1993-01-29,60.25,61.25,59.00,59.50,9516800,14.33
    -1993-01-28,60.00,60.25,59.25,59.88,6580000,14.42
    -1993-01-27,61.00,61.75,58.75,60.25,8101200,14.51
    -1993-01-26,60.50,62.00,60.50,60.75,10201200,14.63
    -1993-01-25,59.25,60.50,59.25,60.00,7237600,14.45
    -1993-01-22,60.25,60.25,59.00,59.50,5252400,14.33
    -1993-01-21,59.75,60.25,58.75,60.00,6601200,14.45
    -1993-01-20,59.75,60.25,59.50,60.00,5685600,14.45
    -1993-01-19,59.75,60.50,59.25,59.75,9802400,14.39
    -1993-01-18,59.50,60.00,58.00,59.50,11935600,14.33
    -1993-01-15,61.00,62.25,60.00,60.25,32257600,14.51
    -1993-01-14,64.00,65.25,63.75,65.00,13145200,15.65
    -1993-01-13,61.50,64.00,61.25,63.50,7135600,15.29
    -1993-01-12,62.75,63.75,61.50,61.50,12364400,14.81
    -1993-01-11,62.00,64.37,61.75,64.12,9785200,15.44
    -1993-01-08,60.75,63.00,59.75,62.25,11474400,14.99
    -1993-01-07,61.75,62.50,60.63,61.00,9741200,14.69
    -1993-01-06,60.75,62.00,60.50,61.75,10055600,14.87
    -1993-01-05,58.00,59.25,57.25,59.25,6658800,14.27
    -1993-01-04,59.50,60.00,57.75,58.25,4618800,14.03
    -1992-12-31,58.75,60.00,58.75,59.75,3302000,14.39
    -1992-12-30,59.75,59.75,58.75,58.75,3610800,14.15
    -1992-12-29,59.50,60.75,59.50,59.63,4171200,14.36
    -1992-12-28,59.25,59.75,59.25,59.50,2536400,14.33
    -1992-12-24,60.00,60.00,59.00,59.00,1642400,14.21
    -1992-12-23,60.25,60.50,59.25,59.75,4018800,14.39
    -1992-12-22,59.75,61.25,59.75,60.63,10009200,14.60
    -1992-12-21,58.25,60.00,58.00,59.63,9159200,14.36
    -1992-12-18,57.50,59.25,57.25,58.25,8414400,14.03
    -1992-12-17,55.25,57.50,55.25,56.88,8370800,13.70
    -1992-12-16,56.25,57.00,54.50,55.00,8085200,13.24
    -1992-12-15,56.75,57.00,55.50,56.38,6541200,13.57
    -1992-12-14,57.50,57.75,56.75,57.25,3962000,13.78
    -1992-12-11,57.25,58.25,57.25,57.50,4299200,13.84
    -1992-12-10,57.25,57.63,56.50,57.25,5010800,13.78
    -1992-12-09,57.75,58.00,57.25,57.63,5700800,13.88
    -1992-12-08,57.75,58.75,57.75,58.13,7035600,14.00
    -1992-12-07,56.75,57.75,56.75,57.75,5168000,13.90
    -1992-12-04,57.25,57.50,56.50,56.88,3432400,13.70
    -1992-12-03,56.50,57.63,56.13,57.50,6710800,13.84
    -1992-12-02,58.25,58.50,57.00,57.25,3498800,13.78
    -1992-12-01,57.25,59.00,56.75,58.25,4652400,14.03
    -1992-11-30,56.25,57.50,55.63,57.50,5739200,13.84
    -1992-11-27,56.50,57.25,56.25,56.50,1688800,13.57
    -1992-11-25,57.00,57.25,56.00,56.50,4208000,13.57
    -1992-11-24,57.00,57.50,56.50,57.50,5601200,13.82
    -1992-11-23,56.50,57.00,56.25,56.75,5462400,13.63
    -1992-11-20,58.50,58.75,57.00,57.50,5572000,13.82
    -1992-11-19,57.75,59.50,57.75,58.25,8608000,14.00
    -1992-11-18,56.00,58.25,55.50,57.75,10889200,13.88
    -1992-11-17,57.25,57.50,54.88,55.25,6045200,13.27
    -1992-11-16,56.25,57.75,56.00,57.38,2419200,13.79
    -1992-11-13,57.00,57.25,56.00,56.25,3042000,13.51
    -1992-11-12,57.00,57.50,56.38,56.88,3844400,13.67
    -1992-11-11,56.50,58.25,56.25,56.75,5023600,13.63
    -1992-11-10,55.00,56.50,54.75,56.25,4368000,13.51
    -1992-11-09,56.00,56.00,54.75,55.25,4052000,13.27
    -1992-11-06,54.75,56.50,54.75,55.75,9443200,13.39
    -1992-11-05,52.50,55.00,52.50,55.00,10647600,13.21
    -1992-11-04,52.00,52.75,52.00,52.50,5086800,12.61
    -1992-11-03,52.50,52.50,51.50,52.00,4042000,12.49
    -1992-11-02,52.50,52.75,51.75,52.25,6094400,12.55
    -1992-10-30,53.50,53.50,52.00,52.50,4657600,12.61
    -1992-10-29,52.25,54.00,51.50,53.25,7661200,12.79
    -1992-10-28,51.25,52.75,50.75,52.25,7033200,12.55
    -1992-10-27,51.50,52.50,51.00,51.50,7575600,12.37
    -1992-10-26,48.75,51.50,48.50,51.50,8972000,12.37
    -1992-10-23,49.25,49.50,48.25,48.75,3279200,11.71
    -1992-10-22,48.50,49.25,48.25,48.75,3026400,11.71
    -1992-10-21,49.25,49.50,48.00,48.50,4080800,11.65
    -1992-10-20,49.00,50.00,48.50,49.13,10269200,11.80
    -1992-10-19,49.00,49.25,48.50,49.00,7002400,11.77
    -1992-10-16,46.75,49.50,46.50,49.00,16142000,11.77
    -1992-10-15,45.75,46.00,45.25,45.50,2701200,10.93
    -1992-10-14,45.25,46.25,45.00,46.00,3429200,11.05
    -1992-10-13,44.75,46.00,44.00,45.38,5265600,10.90
    -1992-10-12,43.25,44.25,43.25,44.00,2580000,10.57
    -1992-10-09,43.50,44.00,43.00,43.38,2108000,10.42
    -1992-10-08,44.00,44.25,43.00,43.50,4543200,10.45
    -1992-10-07,45.00,45.25,43.50,43.75,4050800,10.51
    -1992-10-06,43.75,45.00,42.75,44.75,4058000,10.75
    -1992-10-05,43.25,43.75,41.50,43.50,9475600,10.45
    -1992-10-02,44.50,44.75,43.00,43.75,4063600,10.51
    -1992-10-01,44.75,45.13,44.25,44.25,4396400,10.63
    -1992-09-30,45.00,45.50,44.50,45.13,3580800,10.84
    -1992-09-29,44.50,45.50,44.00,44.88,5626400,10.78
    -1992-09-28,45.00,45.00,43.75,44.75,5351200,10.75
    -1992-09-25,46.25,46.50,45.25,45.50,4926400,10.93
    -1992-09-24,47.25,47.75,46.25,46.25,4492000,11.11
    -1992-09-23,46.00,47.50,45.50,47.50,4443200,11.41
    -1992-09-22,46.75,46.75,45.25,45.75,3996800,10.99
    -1992-09-21,46.75,47.75,46.25,46.50,3204400,11.17
    -1992-09-18,45.75,46.88,45.25,46.50,4133600,11.17
    -1992-09-17,47.25,47.25,45.38,46.00,6180000,11.05
    -1992-09-16,47.75,48.25,46.50,47.00,6395600,11.29
    -1992-09-15,49.25,49.25,47.75,48.25,7806800,11.59
    -1992-09-14,49.00,50.00,48.50,49.50,7682400,11.89
    -1992-09-11,49.00,49.25,47.50,47.63,6438000,11.44
    -1992-09-10,48.00,49.50,47.50,49.25,8165600,11.83
    -1992-09-09,48.00,49.25,47.75,49.00,5622400,11.77
    -1992-09-08,46.75,48.00,46.50,47.75,2511200,11.47
    -1992-09-04,48.25,48.25,46.75,47.25,2268800,11.35
    -1992-09-03,49.00,49.25,47.75,47.75,7570000,11.47
    -1992-09-02,46.50,48.75,46.50,48.50,6794400,11.65
    -1992-09-01,46.25,46.50,45.75,46.50,2172000,11.17
    -1992-08-31,45.00,46.25,44.75,46.00,4328800,11.05
    -1992-08-28,44.25,45.25,44.00,45.00,2202400,10.81
    -1992-08-27,44.75,45.13,44.25,44.50,2974800,10.69
    -1992-08-26,44.25,44.50,43.25,44.25,4325600,10.63
    -1992-08-25,43.25,44.50,43.25,44.38,4731200,10.66
    -1992-08-24,44.25,44.75,43.25,43.25,5454400,10.39
    -1992-08-21,44.75,45.25,44.00,44.63,3926400,10.72
    -1992-08-20,44.75,45.00,44.25,44.75,3894800,10.75
    -1992-08-19,44.63,45.25,44.50,44.50,6096800,10.69
    -1992-08-18,44.50,45.25,44.50,44.75,4017600,10.75
    -1992-08-17,44.25,44.75,43.75,44.75,4617600,10.75
    -1992-08-14,45.00,45.25,44.50,44.75,4872400,10.72
    -1992-08-13,44.50,45.50,44.25,44.75,6122000,10.72
    -1992-08-12,43.75,44.25,43.25,44.13,4343600,10.57
    -1992-08-11,44.50,44.50,43.00,43.50,4339200,10.42
    -1992-08-10,43.25,44.50,43.00,44.13,3280800,10.57
    -1992-08-07,42.00,43.75,41.50,43.38,7842400,10.39
    -1992-08-06,44.25,44.50,42.75,44.00,9220800,10.54
    -1992-08-05,45.50,45.50,44.50,44.75,4981200,10.72
    -1992-08-04,45.00,45.75,44.75,45.50,4295600,10.90
    -1992-08-03,46.75,47.25,45.50,45.75,2452400,10.96
    -1992-07-31,47.25,47.50,46.75,46.75,3262000,11.20
    -1992-07-30,47.25,47.50,46.75,47.25,4927600,11.32
    -1992-07-29,46.63,47.75,46.50,47.25,8976400,11.32
    -1992-07-28,45.50,46.50,45.25,46.50,4813600,11.14
    -1992-07-27,45.75,46.50,45.25,45.25,88800,10.84
    -1992-07-24,44.50,46.25,44.00,45.88,4832000,10.99
    -1992-07-23,44.50,44.75,43.75,44.75,6128800,10.72
    -1992-07-22,45.25,45.50,44.00,44.25,5798800,10.60
    -1992-07-21,45.50,46.25,45.00,45.75,4730800,10.96
    -1992-07-20,44.75,45.25,44.00,44.75,6873600,10.72
    -1992-07-17,45.00,46.00,44.63,45.00,15135600,10.78
    -1992-07-16,47.75,49.00,47.25,48.75,5011200,11.68
    -1992-07-15,47.50,49.00,47.25,48.00,6248000,11.50
    -1992-07-14,47.00,48.00,47.00,47.50,4510800,11.38
    -1992-07-13,45.75,47.13,45.25,47.00,4486800,11.26
    -1992-07-10,46.00,46.25,44.88,45.75,5144400,10.96
    -1992-07-09,46.00,46.50,45.75,45.88,5922000,10.99
    -1992-07-08,44.00,45.75,44.00,45.75,7020000,10.96
    -1992-07-07,46.25,46.25,43.50,44.25,7416400,10.60
    -1992-07-06,46.50,46.75,45.50,46.25,4378000,11.08
    -1992-07-02,49.00,49.00,45.75,46.25,9169200,11.08
    -1992-07-01,48.00,49.50,47.75,49.00,5129200,11.74
    -1992-06-30,46.75,48.25,46.50,48.00,6919200,11.50
    -1992-06-29,45.75,47.13,45.25,46.75,6735200,11.20
    -1992-06-26,45.75,46.00,44.50,45.25,3953600,10.84
    -1992-06-25,46.50,46.50,45.25,45.63,5745200,10.93
    -1992-06-24,45.50,46.00,45.25,46.00,7548000,11.02
    -1992-06-23,45.00,45.50,44.50,45.25,11130800,10.84
    -1992-06-22,44.00,44.75,42.75,44.25,13930000,10.60
    -1992-06-19,46.00,46.00,43.75,44.75,15280000,10.72
    -1992-06-18,47.50,49.00,44.75,45.25,15495600,10.84
    -1992-06-17,49.00,49.25,47.00,47.50,10880800,11.38
    -1992-06-16,51.75,52.00,48.75,49.25,13053200,11.80
    -1992-06-15,54.00,54.00,52.50,52.63,6777600,12.61
    -1992-06-12,54.50,55.00,54.25,54.63,3450800,13.09
    -1992-06-11,53.75,54.25,53.50,53.88,5028800,12.91
    -1992-06-10,54.00,54.75,53.50,53.75,4522400,12.88
    -1992-06-09,54.25,54.25,53.50,54.00,3626800,12.94
    -1992-06-08,55.00,55.00,54.00,54.25,3730000,13.00
    -1992-06-05,54.75,55.25,54.25,54.88,4040800,13.15
    -1992-06-04,54.25,54.75,53.50,54.50,6453200,13.06
    -1992-06-03,56.50,56.50,54.00,54.13,10743200,12.97
    -1992-06-02,57.50,57.50,56.25,56.50,5560000,13.54
    -1992-06-01,57.25,59.50,56.00,57.50,8869200,13.78
    -1992-05-29,59.75,60.63,59.50,59.75,6369200,14.29
    -1992-05-28,60.00,60.25,59.00,59.50,4558000,14.23
    -1992-05-27,59.25,60.25,59.00,60.25,5516400,14.41
    -1992-05-26,59.50,59.75,58.75,59.25,3423200,14.17
    -1992-05-22,59.00,59.75,59.00,59.50,1670800,14.23
    -1992-05-21,60.25,60.25,58.75,59.13,4938800,14.14
    -1992-05-20,59.75,60.25,59.25,60.00,6200800,14.35
    -1992-05-19,60.75,60.75,59.00,59.38,4715600,14.20
    -1992-05-18,61.50,61.50,60.00,60.38,4616400,14.44
    -1992-05-15,61.00,61.25,60.50,60.63,4339200,14.50
    -1992-05-14,62.75,63.00,60.25,61.38,5606800,14.68
    -1992-05-13,62.50,63.25,62.25,62.75,3482000,15.01
    -1992-05-12,62.25,63.00,61.75,62.25,2769200,14.89
    -1992-05-11,62.00,62.75,61.50,62.25,3250000,14.89
    -1992-05-08,61.50,62.88,61.00,62.00,7105600,14.83
    -1992-05-07,61.50,62.25,60.50,60.75,6175600,14.53
    -1992-05-06,60.75,62.13,60.50,61.75,6377600,14.77
    -1992-05-05,60.50,60.63,59.50,60.50,6449200,14.47
    -1992-05-04,59.50,61.25,59.25,60.50,4402000,14.47
    -1992-05-01,60.00,60.75,58.25,59.25,4821200,14.17
    -1992-04-30,57.25,60.25,56.50,60.13,9303600,14.38
    -1992-04-29,54.25,57.00,54.25,57.00,7116800,13.63
    -1992-04-28,55.25,55.75,53.00,54.25,6229200,12.97
    -1992-04-27,56.00,56.25,55.00,55.75,5014800,13.33
    -1992-04-24,57.00,58.25,56.00,56.50,3526800,13.51
    -1992-04-23,57.50,58.25,56.00,57.00,6534400,13.63
    -1992-04-22,56.25,58.00,56.25,57.63,6129200,13.78
    -1992-04-21,57.00,57.25,56.00,56.25,6442400,13.45
    -1992-04-20,59.00,59.00,56.00,56.75,7380800,13.57
    -1992-04-16,60.25,60.75,58.50,59.00,9260800,14.11
    -1992-04-15,58.00,60.88,57.50,60.50,7764400,14.47
    -1992-04-14,57.75,59.25,57.25,58.75,5178000,14.05
    -1992-04-13,55.50,56.75,55.25,56.50,4402000,13.51
    -1992-04-10,57.25,57.50,55.00,55.50,9803600,13.27
    -1992-04-09,56.00,58.25,55.25,57.25,6874400,13.69
    -1992-04-08,57.00,57.00,54.75,55.88,13123600,13.36
    -1992-04-07,61.00,61.25,57.25,57.25,8234400,13.69
    -1992-04-06,59.00,61.00,59.00,60.75,3643600,14.53
    -1992-04-03,58.75,59.25,58.50,59.00,4181200,14.11
    -1992-04-02,59.00,59.50,58.38,58.75,4798800,14.05
    -1992-04-01,57.25,59.25,57.25,59.00,5714400,14.11
    -1992-03-31,58.25,59.75,58.00,58.25,7613200,13.93
    -1992-03-30,61.25,61.25,57.75,58.13,12124400,13.90
    -1992-03-27,63.88,64.00,60.50,61.00,9452000,14.59
    -1992-03-26,64.75,65.25,63.75,64.00,4412400,15.30
    -1992-03-25,65.00,65.00,64.25,64.50,4353200,15.42
    -1992-03-24,63.50,65.00,63.25,65.00,7501200,15.54
    -1992-03-23,63.00,63.75,63.00,63.00,1804400,15.07
    -1992-03-20,63.00,63.25,63.00,63.25,1942400,15.13
    -1992-03-19,63.75,63.75,62.75,63.00,4251200,15.07
    -1992-03-18,63.25,64.00,63.00,63.75,2902000,15.25
    -1992-03-17,63.50,63.75,62.75,62.88,3061200,15.04
    -1992-03-16,62.75,63.50,61.75,63.38,2016400,15.16
    -1992-03-13,63.25,63.75,62.00,63.13,2843600,15.10
    -1992-03-12,63.25,63.75,61.50,62.75,5472400,15.01
    -1992-03-11,63.75,64.25,63.00,63.25,4714400,15.13
    -1992-03-10,64.00,64.75,63.75,63.75,4394400,15.25
    -1992-03-09,63.75,64.25,63.50,63.75,3896800,15.25
    -1992-03-06,63.50,64.00,63.00,64.00,4816400,15.30
    -1992-03-05,64.50,65.50,63.00,63.50,8462400,15.19
    -1992-03-04,66.25,66.75,64.75,65.00,4120800,15.54
    -1992-03-03,67.75,68.00,66.25,66.37,3560000,15.87
    -1992-03-02,67.75,68.50,67.25,67.25,3203200,16.08
    -1992-02-28,68.50,69.00,67.00,67.50,3244400,16.14
    -1992-02-27,70.00,70.00,68.00,68.50,4364800,16.38
    -1992-02-26,68.25,70.00,68.25,69.87,8193600,16.71
    -1992-02-25,66.25,68.50,65.25,68.50,8134400,16.38
    -1992-02-24,66.25,66.50,65.75,66.12,6122400,15.81
    -1992-02-21,64.75,65.50,64.50,65.00,5421200,15.54
    -1992-02-20,62.50,64.75,62.25,64.62,4692400,15.45
    -1992-02-19,62.75,63.00,61.75,62.00,3426400,14.83
    -1992-02-18,64.25,64.50,62.75,62.75,2442000,15.01
    -1992-02-14,63.75,64.25,63.25,64.12,2610800,15.33
    -1992-02-13,65.25,65.25,63.75,64.25,2734400,15.34
    -1992-02-12,63.75,65.50,63.00,65.25,4931200,15.57
    -1992-02-11,63.00,63.75,62.25,62.88,4378800,15.01
    -1992-02-10,64.00,64.25,63.00,63.13,3091200,15.07
    -1992-02-07,64.25,64.75,62.75,64.00,5285600,15.28
    -1992-02-06,65.75,66.00,64.00,64.12,3330000,15.30
    -1992-02-05,66.25,66.75,65.12,66.12,5772400,15.78
    -1992-02-04,65.75,66.25,65.00,65.75,6896400,15.69
    -1992-02-03,64.75,66.25,64.50,65.75,5652000,15.69
    -1992-01-31,64.00,65.25,63.50,64.75,5164400,15.46
    -1992-01-30,63.50,63.75,62.75,63.75,3128800,15.22
    -1992-01-29,64.75,65.75,63.25,63.25,5164400,15.10
    -1992-01-28,64.75,65.37,63.00,65.25,6206800,15.57
    -1992-01-27,64.75,65.25,64.25,64.50,2992000,15.40
    -1992-01-24,64.50,65.75,64.00,64.62,6356400,15.42
    -1992-01-23,64.25,64.75,63.00,64.50,4953200,15.40
    -1992-01-22,61.50,63.75,61.25,63.50,6560000,15.16
    -1992-01-21,64.25,64.25,61.00,61.13,6938000,14.59
    -1992-01-20,64.50,65.25,64.00,64.00,7492400,15.28
    -1992-01-17,67.75,69.00,64.75,64.75,30308800,15.46
    -1992-01-16,63.75,64.25,62.50,62.75,10485200,14.98
    -1992-01-15,64.50,65.00,63.00,63.50,11652400,15.16
    -1992-01-14,62.25,64.75,62.25,64.50,9789200,15.40
    -1992-01-13,62.25,62.75,61.50,62.00,3858800,14.80
    -1992-01-10,61.50,62.50,61.00,62.25,7012400,14.86
    -1992-01-09,60.50,62.25,60.25,62.25,7450800,14.86
    -1992-01-08,58.50,61.25,58.50,60.50,8330800,14.44
    -1992-01-07,57.50,59.50,57.50,59.13,5059200,14.11
    -1992-01-06,58.75,59.00,57.75,58.00,4080000,13.84
    -1992-01-03,60.00,60.25,58.25,59.00,6814400,14.08
    -1992-01-02,55.75,59.75,55.50,59.50,8357600,14.20
    -1991-12-31,57.38,58.00,56.00,56.38,4802000,13.46
    -1991-12-30,55.00,57.25,55.00,56.75,6580800,13.55
    -1991-12-27,54.75,55.75,54.50,55.00,6008000,13.13
    -1991-12-26,52.75,55.00,52.25,54.88,4805600,13.10
    -1991-12-24,52.00,53.75,51.75,52.25,6742400,12.47
    -1991-12-23,50.50,51.75,50.00,51.50,3686800,12.29
    -1991-12-20,51.25,51.50,50.25,50.25,4588000,11.99
    -1991-12-19,51.25,51.75,50.75,50.75,4140800,12.11
    -1991-12-18,50.25,52.00,50.00,51.75,6678000,12.35
    -1991-12-17,50.50,51.00,50.25,50.50,3502400,12.05
    -1991-12-16,50.38,50.75,50.00,50.50,2777600,12.05
    -1991-12-13,49.75,50.75,49.75,50.38,3418000,12.03
    -1991-12-12,49.38,49.75,49.00,49.38,3297600,11.79
    -1991-12-11,49.25,49.75,48.50,49.00,3031200,11.70
    -1991-12-10,49.00,49.50,48.50,49.13,4390000,11.73
    -1991-12-09,49.00,50.00,48.75,49.13,3502000,11.73
    -1991-12-06,49.50,49.75,48.50,48.75,7055200,11.64
    -1991-12-05,50.50,51.00,49.25,50.00,3555600,11.93
    -1991-12-04,50.75,50.75,50.00,50.50,2897600,12.05
    -1991-12-03,52.00,52.00,50.25,50.50,3692400,12.05
    -1991-12-02,50.75,52.00,50.00,51.75,4250000,12.35
    -1991-11-29,50.50,51.50,50.50,50.75,1227600,12.11
    -1991-11-27,51.25,51.50,50.50,51.00,2268800,12.17
    -1991-11-26,51.50,52.00,50.00,51.50,4982000,12.29
    -1991-11-25,51.00,52.25,51.00,51.25,2802000,12.23
    -1991-11-22,51.00,51.75,50.25,51.25,3502400,12.23
    -1991-11-21,50.50,51.75,50.50,51.00,3823200,12.17
    -1991-11-20,51.25,52.00,50.25,50.50,6005600,12.05
    -1991-11-19,51.75,51.75,49.75,51.25,10216400,12.23
    -1991-11-18,50.00,52.50,50.00,52.13,8530000,12.44
    -1991-11-15,54.50,54.75,49.75,50.00,9186400,11.91
    -1991-11-14,54.25,55.25,54.00,54.75,6733600,13.04
    -1991-11-13,54.00,54.50,53.50,54.13,6640000,12.89
    -1991-11-12,54.25,54.75,53.75,54.50,5972000,12.98
    -1991-11-11,53.50,54.50,53.25,53.75,5896800,12.80
    -1991-11-08,51.25,53.75,51.00,53.25,13435200,12.68
    -1991-11-07,48.50,50.50,48.25,49.75,10618800,11.85
    -1991-11-06,49.00,49.25,47.50,48.00,8466400,11.43
    -1991-11-05,49.75,50.50,48.75,48.75,7711200,11.61
    -1991-11-04,50.75,50.75,48.50,49.75,6983200,11.85
    -1991-11-01,51.25,52.00,50.50,51.00,7203600,12.14
    -1991-10-31,50.75,51.75,50.00,51.50,8300800,12.26
    -1991-10-30,52.00,52.75,49.50,49.75,5302400,11.85
    -1991-10-29,51.50,52.00,50.75,51.75,3624400,12.32
    -1991-10-28,51.50,51.75,50.75,51.50,2792400,12.26
    -1991-10-25,51.75,52.25,50.75,51.25,3832000,12.20
    -1991-10-24,53.00,53.25,51.50,52.13,6372400,12.41
    -1991-10-23,55.00,55.25,52.75,53.13,6046400,12.65
    -1991-10-22,55.50,56.25,54.50,54.50,7456400,12.98
    -1991-10-21,55.25,55.88,54.25,54.75,4172000,13.04
    -1991-10-18,55.13,55.50,54.50,55.00,15964400,13.10
    -1991-10-17,53.00,53.25,51.50,52.38,5423200,12.47
    -1991-10-16,52.50,54.00,52.25,53.50,7182000,12.74
    -1991-10-15,50.50,52.50,50.00,52.50,10300800,12.50
    -1991-10-14,49.00,50.25,48.75,49.88,4015600,11.88
    -1991-10-11,48.13,48.88,46.50,48.50,4292000,11.55
    -1991-10-10,48.75,49.00,46.75,47.75,5623200,11.37
    -1991-10-09,48.25,48.75,47.75,48.00,4752400,11.43
    -1991-10-08,48.13,48.50,46.50,48.25,6170000,11.49
    -1991-10-07,48.00,48.75,47.50,48.13,2328000,11.46
    -1991-10-04,48.00,48.75,47.50,48.25,2854400,11.49
    -1991-10-03,50.00,50.00,47.50,47.75,6478000,11.37
    -1991-10-02,51.75,51.75,49.50,49.75,643600,11.85
    -1991-10-01,49.25,51.25,49.00,50.75,4698800,12.08
    -1991-09-30,49.25,49.75,49.00,49.50,2266800,11.79
    -1991-09-27,50.00,50.75,48.75,49.00,2245200,11.67
    -1991-09-26,50.25,50.25,49.00,50.00,2556800,11.91
    -1991-09-25,50.25,50.50,49.25,50.50,1959200,12.02
    -1991-09-24,49.50,50.38,48.25,50.25,3805600,11.97
    -1991-09-23,50.00,50.75,49.25,49.50,3136800,11.79
    -1991-09-20,49.75,51.00,49.50,50.63,6742000,12.06
    -1991-09-19,50.25,50.50,49.50,49.75,6374400,11.85
    -1991-09-18,48.75,50.50,48.50,50.13,4342000,11.94
    -1991-09-17,47.00,49.00,46.75,49.00,4856400,11.67
    -1991-09-16,49.25,49.25,46.50,47.25,7365600,11.25
    -1991-09-13,50.00,50.25,48.50,48.63,5974400,11.58
    -1991-09-12,51.25,51.25,49.75,50.63,4267600,12.06
    -1991-09-11,50.75,51.00,49.50,50.50,6378000,12.02
    -1991-09-10,52.75,53.38,49.75,50.13,6535600,11.94
    -1991-09-09,51.75,53.50,51.50,53.25,4538000,12.68
    -1991-09-06,51.00,51.75,50.50,51.50,2848800,12.26
    -1991-09-05,51.50,51.75,50.75,51.00,2793600,12.14
    -1991-09-04,52.75,52.75,51.38,51.50,4299200,12.26
    -1991-09-03,52.75,53.25,52.00,52.50,2443200,12.50
    -1991-08-30,53.00,53.25,52.25,53.00,2363200,12.62
    -1991-08-29,53.25,53.88,52.50,53.00,4053200,12.62
    -1991-08-28,54.00,54.25,53.13,53.25,3843600,12.68
    -1991-08-27,53.00,54.00,52.75,54.00,3597600,12.86
    -1991-08-26,53.00,53.50,52.50,53.00,3644400,12.62
    -1991-08-23,54.00,55.50,52.75,53.00,8601200,12.62
    -1991-08-22,54.00,54.75,53.75,54.25,5936400,12.92
    -1991-08-21,52.50,54.13,52.00,53.75,7987600,12.80
    -1991-08-20,51.50,51.75,50.50,51.00,7123600,12.14
    -1991-08-19,49.50,51.63,48.50,50.50,11538000,12.02
    -1991-08-16,52.75,54.25,52.25,53.25,5689200,12.65
    -1991-08-15,55.00,55.00,53.00,53.25,5219200,12.65
    -1991-08-14,54.75,55.00,53.88,54.88,7173200,13.04
    -1991-08-13,52.00,54.00,52.00,53.50,10255200,12.71
    -1991-08-12,50.75,52.25,50.50,51.75,5096400,12.29
    -1991-08-09,50.50,51.00,49.75,50.75,5533600,12.06
    -1991-08-08,50.75,51.75,50.00,50.50,6769200,12.00
    -1991-08-07,49.50,51.00,49.38,50.38,7578800,11.97
    -1991-08-06,48.75,50.25,47.75,49.50,7890800,11.76
    -1991-08-05,49.75,49.75,48.25,48.50,3620800,11.52
    -1991-08-02,49.75,50.25,49.00,50.00,9767600,11.88
    -1991-08-01,46.00,49.25,45.75,49.13,16023600,11.67
    -1991-07-31,46.50,46.88,45.00,46.25,3689200,10.99
    -1991-07-30,45.50,46.75,45.50,46.50,3281200,11.05
    -1991-07-29,45.25,45.50,44.50,45.50,1916800,10.81
    -1991-07-26,45.75,45.75,44.75,44.88,2657600,10.66
    -1991-07-25,45.25,45.75,45.00,45.25,2366800,10.75
    -1991-07-24,45.25,45.75,44.50,45.00,4703200,10.69
    -1991-07-23,46.25,46.50,44.50,45.00,4770000,10.69
    -1991-07-22,45.75,46.25,45.50,46.00,3882000,10.93
    -1991-07-19,45.25,46.25,45.00,46.00,4601200,10.93
    -1991-07-18,44.00,45.13,43.00,44.88,14240000,10.66
    -1991-07-17,43.50,44.50,42.25,42.50,7474400,10.10
    -1991-07-16,45.50,45.75,43.50,43.75,7966400,10.39
    -1991-07-15,46.75,46.75,45.50,45.50,4932400,10.81
    -1991-07-12,47.25,47.25,46.25,46.75,4753200,11.11
    -1991-07-11,47.00,47.25,46.00,46.75,5217600,11.11
    -1991-07-10,47.50,48.25,46.75,47.25,5610000,11.23
    -1991-07-09,47.25,48.25,46.50,46.88,8091200,11.14
    -1991-07-08,45.25,47.25,45.00,46.75,10971200,11.11
    -1991-07-05,43.00,46.00,42.75,45.63,11842000,10.84
    -1991-07-03,42.25,43.50,41.75,43.13,11087600,10.25
    -1991-07-02,42.25,42.75,41.75,42.25,4296800,10.04
    -1991-07-01,42.25,43.00,41.75,42.50,6979200,10.10
    -1991-06-28,42.25,42.50,40.25,41.50,8102400,9.86
    -1991-06-27,42.50,42.75,41.75,42.50,5400000,10.10
    -1991-06-26,42.75,43.50,42.25,43.00,8958000,10.22
    -1991-06-25,42.00,43.00,41.75,42.38,8151200,10.07
    -1991-06-24,41.75,42.25,41.25,41.75,7443600,9.92
    -1991-06-21,42.00,42.50,41.75,42.00,7378800,9.98
    -1991-06-20,41.25,42.00,40.75,42.00,5158000,9.98
    -1991-06-19,41.75,42.25,41.25,41.75,6408000,9.92
    -1991-06-18,42.25,43.25,41.50,42.13,8749200,10.01
    -1991-06-17,41.00,42.25,41.00,42.00,5966800,9.98
    -1991-06-14,42.75,42.75,40.75,41.13,8049200,9.77
    -1991-06-13,42.50,43.00,41.75,42.13,7565200,10.01
    -1991-06-12,44.00,44.75,41.25,42.38,15580000,10.07
    -1991-06-11,45.00,45.50,44.25,44.63,6742400,10.60
    -1991-06-10,46.00,47.13,45.75,46.00,5991200,10.93
    -1991-06-07,46.25,47.00,45.63,46.13,5463600,10.96
    -1991-06-06,48.25,48.25,46.50,46.63,6028000,11.08
    -1991-06-05,49.25,49.25,47.75,48.00,4760800,11.40
    -1991-06-04,49.50,49.50,48.50,49.13,6593600,11.67
    -1991-06-03,47.00,49.50,46.75,49.25,7870800,11.70
    -1991-05-31,47.50,47.75,46.25,47.00,7792400,11.17
    -1991-05-30,47.00,47.75,46.50,47.63,5663600,11.32
    -1991-05-29,46.25,47.75,45.88,47.00,13733600,11.17
    -1991-05-28,46.00,46.25,45.25,46.00,6124400,10.93
    -1991-05-24,45.50,46.00,45.00,45.88,3484800,10.90
    -1991-05-23,46.50,46.75,44.75,45.13,7458800,10.72
    -1991-05-22,45.75,46.50,45.50,46.25,8137600,10.99
    -1991-05-21,45.25,46.50,44.75,45.25,12500000,10.75
    -1991-05-20,47.25,47.50,44.00,44.25,9365200,10.51
    -1991-05-17,48.75,48.75,46.50,47.00,16836800,11.14
    -1991-05-16,51.00,51.25,48.50,49.00,13652000,11.61
    -1991-05-15,51.50,52.00,49.00,50.50,18530800,11.97
    -1991-05-14,52.75,53.75,52.50,53.50,7763600,12.68
    -1991-05-13,52.25,53.50,51.50,52.75,8763600,12.50
    -1991-05-10,51.50,53.25,50.75,51.25,8652000,12.14
    -1991-05-09,50.00,51.50,49.75,50.75,8523200,12.03
    -1991-05-08,50.75,50.75,49.25,49.75,6332400,11.79
    -1991-05-07,51.00,51.25,50.50,50.63,9671200,12.00
    -1991-05-06,48.50,50.50,48.25,50.25,7596400,11.91
    -1991-05-03,49.00,49.50,48.25,49.00,8717600,11.61
    -1991-05-02,47.75,49.75,47.50,49.00,28973600,11.61
    -1991-05-01,48.00,49.00,47.00,47.25,66732000,11.20
    -1991-04-30,57.75,58.25,54.50,55.00,25413600,13.03
    -1991-04-29,58.50,60.25,58.25,58.25,7395200,13.80
    -1991-04-26,58.50,59.00,57.75,58.63,4481200,13.89
    -1991-04-25,59.75,59.75,58.50,58.50,11276800,13.86
    -1991-04-24,61.75,62.00,60.50,60.75,3769200,14.40
    -1991-04-23,62.25,63.00,60.25,61.50,8494400,14.57
    -1991-04-22,59.50,62.00,58.75,61.50,9190000,14.57
    -1991-04-19,61.00,61.50,59.50,59.63,10272400,14.13
    -1991-04-18,62.75,63.00,60.75,61.00,8853600,14.46
    -1991-04-17,65.00,65.00,62.00,63.25,11533600,14.99
    -1991-04-16,63.25,64.50,62.50,64.25,22176800,15.23
    -1991-04-15,61.75,64.50,60.00,62.25,60732400,14.75
    -1991-04-12,71.50,73.25,69.75,71.75,13140000,17.00
    -1991-04-11,67.75,71.37,67.50,71.00,12710800,16.83
    -1991-04-10,68.50,69.25,66.75,66.87,7733600,15.85
    -1991-04-09,69.75,70.00,68.25,68.75,4280800,16.29
    -1991-04-08,69.25,70.00,68.75,70.00,2604400,16.59
    -1991-04-05,71.75,71.75,68.75,69.37,5567600,16.44
    -1991-04-04,70.00,72.00,69.50,71.50,6024400,16.94
    -1991-04-03,72.50,72.75,70.00,70.00,8585200,16.59
    -1991-04-02,69.00,72.75,68.50,72.75,10473600,17.24
    -1991-04-01,68.00,69.50,67.50,68.50,4218000,16.23
    -1991-03-28,69.25,70.00,67.75,68.00,2816800,16.11
    -1991-03-27,70.00,70.25,68.50,69.25,6812400,16.41
    -1991-03-26,64.75,70.25,64.75,70.00,11935200,16.59
    -1991-03-25,63.50,65.00,63.25,64.50,4858800,15.28
    -1991-03-22,64.00,64.75,62.25,63.25,12096400,14.99
    -1991-03-21,68.25,68.75,63.75,64.75,10600000,15.34
    -1991-03-20,69.25,69.50,66.87,67.75,12939200,16.06
    -1991-03-19,66.50,70.25,65.75,69.50,15100000,16.47
    -1991-03-18,65.75,68.25,65.75,67.75,7645200,16.06
    -1991-03-15,65.75,66.50,65.25,66.25,7335600,15.70
    -1991-03-14,66.75,67.50,64.50,65.25,8126400,15.46
    -1991-03-13,62.75,66.50,62.75,66.25,6253200,15.70
    -1991-03-12,63.00,63.75,62.50,62.88,8360000,14.90
    -1991-03-11,64.50,64.75,62.25,63.50,6276400,15.05
    -1991-03-08,67.75,68.25,65.00,65.00,11522400,15.40
    -1991-03-07,63.50,67.50,63.25,67.25,11497600,15.94
    -1991-03-06,64.00,65.62,62.88,63.00,18731200,14.93
    -1991-03-05,59.00,63.25,59.00,63.13,15769200,14.96
    -1991-03-04,58.00,58.75,57.00,58.38,3175600,13.83
    -1991-03-01,57.00,59.00,57.00,57.75,4518800,13.69
    -1991-02-28,58.25,58.50,56.25,57.25,8120000,13.57
    -1991-02-27,58.25,58.50,57.50,58.25,6243200,13.80
    -1991-02-26,57.50,58.75,56.50,58.25,8934400,13.80
    -1991-02-25,60.25,60.50,57.50,58.00,12848800,13.74
    -1991-02-22,59.00,61.75,58.50,59.75,8320800,14.16
    -1991-02-21,61.25,62.25,58.75,59.00,6826400,13.98
    -1991-02-20,59.50,61.75,59.25,61.00,7646800,14.46
    -1991-02-19,57.50,60.25,57.38,60.00,8080800,14.22
    -1991-02-15,57.25,58.50,57.25,57.63,13067600,13.66
    -1991-02-14,60.00,60.00,56.75,57.13,13493200,13.51
    -1991-02-13,60.00,60.25,58.00,60.00,9130800,14.19
    -1991-02-12,61.00,61.25,59.38,60.00,8042000,14.19
    -1991-02-11,60.00,61.50,59.75,61.38,11546400,14.51
    -1991-02-08,57.50,60.25,57.50,59.88,11220000,14.16
    -1991-02-07,57.00,58.75,55.75,57.75,18587600,13.66
    -1991-02-06,57.75,58.25,56.50,56.88,7965200,13.45
    -1991-02-05,55.25,58.00,54.75,57.75,12740000,13.66
    -1991-02-04,55.75,56.00,55.00,55.25,9569200,13.07
    -1991-02-01,55.50,57.88,55.50,55.75,15897600,13.18
    -1991-01-31,55.50,56.00,54.75,55.50,8677600,13.12
    -1991-01-30,53.25,55.75,53.25,55.50,12043200,13.12
    -1991-01-29,54.25,54.50,52.25,53.75,7708800,12.71
    -1991-01-28,53.25,55.25,53.25,54.50,9771200,12.89
    -1991-01-25,52.00,53.63,52.00,53.50,8012000,12.65
    -1991-01-24,51.50,52.75,51.50,52.13,8374400,12.33
    -1991-01-23,51.25,52.25,51.00,51.75,8725600,12.24
    -1991-01-22,51.00,52.50,50.50,51.25,15296400,12.12
    -1991-01-21,49.75,51.50,49.75,50.75,11595200,12.00
    -1991-01-18,48.75,50.75,48.50,50.25,33691200,11.88
    -1991-01-17,52.50,52.75,49.00,51.25,21137600,12.12
    -1991-01-16,47.00,50.00,46.75,49.75,13968800,11.76
    -1991-01-15,46.50,46.75,46.00,46.75,6870000,11.06
    -1991-01-14,46.00,46.75,46.00,46.25,7535600,10.94
    -1991-01-11,47.00,47.25,46.00,47.00,11003200,11.11
    -1991-01-10,45.75,47.25,45.75,47.13,15562400,11.15
    -1991-01-09,44.25,46.00,43.75,45.25,16692400,10.70
    -1991-01-08,43.75,43.88,42.50,43.25,7816400,10.23
    -1991-01-07,43.00,45.25,43.00,43.25,11111200,10.23
    -1991-01-04,43.00,44.25,43.00,43.25,5062400,10.23
    -1991-01-03,43.50,44.25,43.00,43.00,5365600,10.17
    -1991-01-02,42.75,44.00,42.00,43.50,5543600,10.29
    -1990-12-31,43.00,43.25,42.75,43.00,1593200,10.17
    -1990-12-28,43.25,43.50,42.75,43.00,2285200,10.17
    -1990-12-27,43.25,44.00,43.25,43.50,3492000,10.29
    -1990-12-26,44.00,44.25,43.00,43.75,3682000,10.35
    -1990-12-24,44.75,45.00,44.00,44.00,2106800,10.40
    -1990-12-21,44.25,45.25,43.50,45.00,12363200,10.64
    -1990-12-20,41.25,44.50,41.25,44.00,14326400,10.40
    -1990-12-19,42.50,42.50,41.13,41.88,5036800,9.90
    -1990-12-18,41.00,42.50,40.75,42.25,7899200,9.99
    -1990-12-17,39.00,40.50,39.00,40.13,4683600,9.49
    -1990-12-14,40.25,40.50,39.50,39.88,3126400,9.43
    -1990-12-13,39.50,41.00,39.50,40.75,5752000,9.64
    -1990-12-12,39.75,40.00,39.00,39.63,8664400,9.37
    -1990-12-11,41.25,41.50,40.00,40.00,12438000,9.46
    -1990-12-10,42.25,42.50,41.50,41.75,8966400,9.87
    -1990-12-07,41.00,42.75,41.00,42.50,11781200,10.05
    -1990-12-06,41.25,41.75,40.50,41.25,19013600,9.75
    -1990-12-05,38.50,40.25,37.88,40.13,7822000,9.49
    -1990-12-04,37.50,38.75,37.50,38.50,5453200,9.10
    -1990-12-03,37.25,38.25,37.00,38.13,5922400,9.02
    -1990-11-30,36.25,37.25,36.25,36.75,4350800,8.69
    -1990-11-29,37.00,37.00,36.25,36.75,4528000,8.69
    -1990-11-28,37.75,38.50,36.75,36.75,6250800,8.69
    -1990-11-27,37.00,38.25,36.75,37.50,5899200,8.87
    -1990-11-26,36.00,37.00,36.00,36.75,2925600,8.69
    -1990-11-23,36.25,37.00,36.00,36.38,1911200,8.60
    -1990-11-21,35.25,36.25,34.75,36.13,4400800,8.54
    -1990-11-20,36.50,36.75,35.25,35.50,5490800,8.39
    -1990-11-19,35.50,36.38,35.25,36.38,8017600,8.60
    -1990-11-16,35.75,36.00,34.75,35.13,6545200,8.31
    -1990-11-15,36.75,37.00,35.50,36.00,5787600,8.48
    -1990-11-14,35.75,37.25,35.75,37.00,6819200,8.72
    -1990-11-13,36.25,36.50,35.75,36.00,5086400,8.48
    -1990-11-12,35.50,36.75,35.25,36.25,5192000,8.54
    -1990-11-09,35.00,35.75,34.50,35.50,7102000,8.37
    -1990-11-08,33.00,35.00,33.00,34.50,7136400,8.13
    -1990-11-07,33.50,33.75,32.63,33.25,7254400,7.84
    -1990-11-06,33.50,34.50,33.25,33.50,6620800,7.90
    -1990-11-05,32.25,33.50,32.00,33.25,6604400,7.84
    -1990-11-02,30.50,32.38,30.50,31.75,5323200,7.48
    -1990-11-01,30.50,31.00,29.75,30.50,3258800,7.19
    -1990-10-31,30.50,31.87,30.25,30.75,5331200,7.25
    -1990-10-30,29.75,30.75,28.87,30.37,3513600,7.16
    -1990-10-29,30.25,30.50,29.75,29.87,4415600,7.04
    -1990-10-26,29.75,31.25,29.75,30.00,4811200,7.07
    -1990-10-25,30.25,31.25,29.62,30.00,5481200,7.07
    -1990-10-24,30.75,31.00,30.00,30.50,5079200,7.19
    -1990-10-23,31.00,31.50,30.25,31.00,5969200,7.31
    -1990-10-22,31.50,31.50,30.50,31.12,9041200,7.33
    -1990-10-19,31.25,31.75,30.25,31.37,33363200,7.39
    -1990-10-18,26.50,28.75,26.50,28.50,11255600,6.72
    -1990-10-17,25.25,26.50,25.00,26.50,11059200,6.25
    -1990-10-16,27.50,27.50,24.25,25.00,10913200,5.89
    -1990-10-15,28.50,28.75,26.62,27.75,7190000,6.54
    -1990-10-12,28.25,28.50,27.00,28.25,8169200,6.66
    -1990-10-11,26.75,27.87,25.50,27.75,7376800,6.54
    -1990-10-10,27.25,28.00,26.00,26.50,5283600,6.25
    -1990-10-09,28.50,29.00,27.75,28.00,4321200,6.60
    -1990-10-08,28.75,29.25,28.25,29.12,2218800,6.86
    -1990-10-05,27.00,28.75,27.00,28.00,3572000,6.60
    -1990-10-04,26.75,28.00,26.25,28.00,7638800,6.60
    -1990-10-03,29.75,29.75,26.75,27.00,9591200,6.36
    -1990-10-02,31.00,32.00,29.50,29.62,9699200,6.98
    -1990-10-01,29.50,31.00,29.25,30.50,5581200,7.19
    -1990-09-28,28.50,29.00,27.25,29.00,6291200,6.83
    -1990-09-27,30.00,30.50,28.00,28.25,5085600,6.66
    -1990-09-26,30.00,30.50,29.75,29.75,3363200,7.01
    -1990-09-25,30.50,30.75,29.25,30.00,5642000,7.07
    -1990-09-24,31.50,31.50,29.75,30.25,4961200,7.13
    -1990-09-21,32.00,32.50,31.00,31.50,5503600,7.42
    -1990-09-20,32.25,32.25,31.25,31.62,3607600,7.45
    -1990-09-19,33.25,33.75,32.00,32.50,6536800,7.66
    -1990-09-18,33.75,33.75,33.00,33.38,4456400,7.87
    -1990-09-17,34.00,35.25,33.50,33.75,2782000,7.95
    -1990-09-14,33.50,34.25,33.25,34.00,4084400,8.01
    -1990-09-13,34.50,34.75,33.00,33.75,3492400,7.95
    -1990-09-12,34.50,34.50,33.50,34.00,3600800,8.01
    -1990-09-11,36.00,36.13,33.75,34.00,6370800,8.01
    -1990-09-10,37.00,37.00,35.75,35.75,2732400,8.43
    -1990-09-07,35.50,36.75,35.13,36.38,2098800,8.57
    -1990-09-06,35.50,36.00,35.25,35.75,3134800,8.43
    -1990-09-05,37.25,37.25,35.75,36.00,2292000,8.48
    -1990-09-04,36.50,37.50,36.50,37.00,2974800,8.72
    -1990-08-31,36.00,37.25,36.00,37.00,3570000,8.72
    -1990-08-30,37.25,37.50,36.00,36.25,4388800,8.54
    -1990-08-29,38.00,38.13,36.75,37.25,5407600,8.78
    -1990-08-28,37.50,38.38,37.25,38.13,2877600,8.99
    -1990-08-27,36.75,38.00,36.25,37.75,4214800,8.90
    -1990-08-24,35.25,36.00,34.75,35.50,2634400,8.37
    -1990-08-23,34.25,35.00,33.50,34.50,5138800,8.13
    -1990-08-22,37.00,37.00,34.88,35.13,4395600,8.28
    -1990-08-21,35.75,36.75,35.25,36.25,5769200,8.54
    -1990-08-20,36.50,37.50,36.25,36.75,2681200,8.66
    -1990-08-17,38.50,38.50,35.75,36.50,8806400,8.58
    -1990-08-16,39.00,39.63,38.50,38.50,4438800,9.05
    -1990-08-15,40.00,40.25,39.25,39.25,3292000,9.22
    -1990-08-14,40.00,40.00,39.25,39.75,3520800,9.34
    -1990-08-13,38.00,40.00,37.88,39.88,5584400,9.37
    -1990-08-10,38.75,39.25,38.25,38.75,3683600,9.11
    -1990-08-09,40.25,40.50,39.25,39.50,3443600,9.28
    -1990-08-08,39.50,40.75,39.50,40.13,3674400,9.43
    -1990-08-07,40.25,40.63,38.75,39.50,7096400,9.28
    -1990-08-06,39.00,40.50,38.50,39.50,6425600,9.28
    -1990-08-03,43.50,43.75,39.75,41.25,9609200,9.69
    -1990-08-02,41.25,43.75,41.25,43.50,7973600,10.22
    -1990-08-01,42.00,42.75,41.50,42.38,3350800,9.96
    -1990-07-31,42.50,42.75,41.50,42.00,3444800,9.87
    -1990-07-30,40.75,42.50,40.75,42.38,3058800,9.96
    -1990-07-27,41.25,41.75,40.50,41.38,2240000,9.72
    -1990-07-26,42.25,42.50,41.00,41.38,2885600,9.72
    -1990-07-25,42.00,43.25,41.75,42.25,3762400,9.93
    -1990-07-24,42.00,42.25,41.00,42.13,6928800,9.90
    -1990-07-23,41.00,41.75,40.00,41.50,9655200,9.75
    -1990-07-20,42.00,42.50,40.75,41.00,6858000,9.63
    -1990-07-19,40.75,42.50,40.00,41.75,20932400,9.81
    -1990-07-18,44.50,45.00,43.00,44.63,10309200,10.49
    -1990-07-17,45.75,46.00,44.00,44.25,4892000,10.40
    -1990-07-16,46.75,47.13,45.25,45.63,6428000,10.72
    -1990-07-13,47.50,47.75,46.75,46.75,8254400,10.99
    -1990-07-12,46.75,47.50,46.50,47.38,6537600,11.13
    -1990-07-11,46.75,47.00,45.75,47.00,8808800,11.04
    -1990-07-10,47.00,47.50,46.75,47.00,12923600,11.04
    -1990-07-09,45.00,47.00,44.75,46.63,11281200,10.96
    -1990-07-06,43.50,45.00,43.25,44.75,7481200,10.52
    -1990-07-05,43.75,44.25,43.25,43.50,3859200,10.22
    -1990-07-03,43.88,44.50,43.75,44.00,3572400,10.34
    -1990-07-02,44.50,44.50,43.75,44.00,4856400,10.34
    -1990-06-29,43.00,44.88,42.75,44.75,11622000,10.52
    -1990-06-28,42.75,43.25,41.75,43.00,8930000,10.10
    -1990-06-27,40.75,42.00,40.25,41.50,3490800,9.75
    -1990-06-26,41.75,42.00,40.38,40.63,4558800,9.55
    -1990-06-25,41.50,41.75,40.25,41.25,4378000,9.69
    -1990-06-22,42.00,42.63,41.25,41.50,10154400,9.75
    -1990-06-21,40.00,42.00,40.00,41.88,7455600,9.84
    -1990-06-20,39.88,40.25,39.75,40.00,5530000,9.40
    -1990-06-19,39.00,39.75,38.38,39.63,5623600,9.31
    -1990-06-18,39.25,39.50,39.00,39.25,3988800,9.22
    -1990-06-15,39.75,40.00,39.13,39.50,5163600,9.28
    -1990-06-14,40.00,40.25,39.25,39.75,5018000,9.34
    -1990-06-13,40.38,40.75,39.75,39.75,4963600,9.34
    -1990-06-12,39.13,40.50,38.75,40.50,5902000,9.52
    -1990-06-11,37.75,39.00,37.75,39.00,5661200,9.16
    -1990-06-08,38.50,38.50,37.50,38.25,11926800,8.99
    -1990-06-07,39.50,39.75,38.50,39.00,6668800,9.16
    -1990-06-06,39.00,39.50,38.75,39.50,7563600,9.28
    -1990-06-05,41.00,41.00,39.00,39.50,10702000,9.28
    -1990-06-04,40.75,41.00,39.75,40.75,6412400,9.58
    -1990-06-01,41.38,42.00,40.75,40.75,5624400,9.58
    -1990-05-31,41.50,41.50,41.00,41.25,3682400,9.69
    -1990-05-30,41.63,41.75,41.25,41.38,9890000,9.72
    -1990-05-29,40.00,41.25,39.25,41.00,8689200,9.63
    -1990-05-25,39.50,40.75,39.00,40.00,11562400,9.40
    -1990-05-24,42.25,42.25,41.50,42.00,5296400,9.87
    -1990-05-23,41.25,42.50,41.25,42.00,7417600,9.87
    -1990-05-22,40.13,41.50,40.00,41.38,10772000,9.72
    -1990-05-21,39.50,40.00,38.75,39.50,9382400,9.28
    -1990-05-18,41.25,41.50,39.50,39.75,9248000,9.31
    -1990-05-17,41.75,42.25,41.00,41.50,5488000,9.72
    -1990-05-16,41.75,41.75,41.00,41.63,3139200,9.76
    -1990-05-15,41.38,42.00,41.00,41.75,5343600,9.78
    -1990-05-14,42.75,42.75,41.25,41.75,8088000,9.78
    -1990-05-11,41.38,42.75,40.75,42.63,7691200,9.99
    -1990-05-10,41.75,41.75,40.50,41.38,6413600,9.70
    -1990-05-09,41.63,42.00,41.25,41.88,3491200,9.81
    -1990-05-08,41.00,42.00,41.00,41.75,4025600,9.78
    -1990-05-07,39.75,41.75,39.75,41.50,4866400,9.72
    -1990-05-04,40.00,40.75,39.25,40.00,6063200,9.37
    -1990-05-03,39.75,40.25,39.75,40.00,5950800,9.37
    -1990-05-02,39.75,40.00,39.25,39.75,4857600,9.31
    -1990-05-01,39.75,40.00,39.38,39.63,5845200,9.29
    -1990-04-30,39.25,39.75,39.00,39.38,4888800,9.23
    -1990-04-27,39.00,39.50,38.75,39.13,4178800,9.17
    -1990-04-26,39.00,39.50,38.13,38.88,5098000,9.11
    -1990-04-25,38.75,39.00,38.25,38.75,4743200,9.08
    -1990-04-24,40.00,40.50,38.50,38.75,10852000,9.08
    -1990-04-23,40.25,40.50,39.50,39.75,4597600,9.31
    -1990-04-20,40.88,41.50,39.75,40.25,11573600,9.43
    -1990-04-19,41.75,43.13,40.00,40.25,17215600,9.43
    -1990-04-18,43.25,43.75,42.50,43.25,6925200,10.13
    -1990-04-17,43.25,43.50,42.75,43.25,4683600,10.13
    -1990-04-16,43.50,44.25,43.25,43.75,8116400,10.25
    -1990-04-12,43.00,44.00,42.50,43.25,7566800,10.13
    -1990-04-11,41.50,43.00,41.50,42.50,7620000,9.96
    -1990-04-10,41.25,42.00,41.00,41.25,4695600,9.67
    -1990-04-09,39.75,41.50,39.50,41.13,3771200,9.64
    -1990-04-06,40.25,41.25,39.75,39.88,4235600,9.35
    -1990-04-05,41.00,41.25,40.00,40.25,3877600,9.43
    -1990-04-04,41.50,42.00,40.75,41.25,5363200,9.67
    -1990-04-03,40.50,41.75,40.50,41.75,5006400,9.78
    -1990-04-02,40.00,40.63,39.50,40.25,5332000,9.43
    -1990-03-30,40.00,41.00,40.00,40.25,7986400,9.43
    -1990-03-29,41.00,41.50,40.75,41.13,3472000,9.64
    -1990-03-28,42.00,42.13,41.00,41.25,3696800,9.67
    -1990-03-27,42.00,42.25,41.25,42.00,3033600,9.84
    -1990-03-26,42.50,43.38,42.00,42.25,4581200,9.90
    -1990-03-23,41.25,43.00,41.00,42.25,8155200,9.90
    -1990-03-22,41.75,42.25,40.75,40.75,8292400,9.55
    -1990-03-21,41.25,42.25,41.25,41.63,5463200,9.76
    -1990-03-20,42.25,43.00,40.75,41.38,13984400,9.70
    -1990-03-19,40.50,42.50,40.00,42.38,15433200,9.93
    -1990-03-16,40.00,40.75,39.13,40.25,23042400,9.43
    -1990-03-15,36.50,38.00,36.50,36.75,4302000,8.61
    -1990-03-14,36.75,37.25,36.50,37.00,3654800,8.67
    -1990-03-13,36.50,37.25,36.25,36.88,5321200,8.64
    -1990-03-12,37.25,37.50,36.25,36.63,5864400,8.58
    -1990-03-09,36.75,37.50,36.25,36.88,8248800,8.64
    -1990-03-08,35.75,37.00,35.00,36.75,8013600,8.61
    -1990-03-07,35.00,36.00,35.00,35.38,7301200,8.29
    -1990-03-06,35.00,35.25,34.50,35.25,5578800,8.26
    -1990-03-05,33.50,34.75,33.50,34.50,6537600,8.08
    -1990-03-02,33.50,34.75,33.25,33.75,3761200,7.91
    -1990-03-01,33.50,34.75,33.25,34.25,7283200,8.03
    -1990-02-28,33.50,34.00,33.25,34.00,3918800,7.97
    -1990-02-27,34.00,34.25,33.50,33.50,2642000,7.85
    -1990-02-26,33.00,34.25,33.00,34.00,2844800,7.97
    -1990-02-23,32.75,33.50,32.75,33.25,5375600,7.79
    -1990-02-22,34.00,34.50,33.00,33.00,6976800,7.73
    -1990-02-21,32.75,34.25,32.50,34.00,6283600,7.97
    -1990-02-20,33.50,33.75,33.00,33.50,4402400,7.85
    -1990-02-16,34.25,34.50,33.75,33.75,4556400,7.91
    -1990-02-15,33.75,34.25,33.50,34.25,3509200,8.00
    -1990-02-14,34.50,34.75,33.75,34.25,3448000,8.00
    -1990-02-13,34.00,35.00,33.75,34.50,3653600,8.06
    -1990-02-12,34.25,34.50,33.75,34.00,2695600,7.94
    -1990-02-09,33.50,34.50,33.25,34.25,6004400,8.00
    -1990-02-08,33.25,33.50,32.25,33.00,6680000,7.71
    -1990-02-07,33.00,34.00,32.50,33.25,11180800,7.77
    -1990-02-06,34.75,35.00,34.00,34.75,2640000,8.12
    -1990-02-05,34.25,35.25,34.00,35.00,3653200,8.18
    -1990-02-02,33.25,34.75,33.25,34.25,4248800,8.00
    -1990-02-01,34.50,34.63,33.50,33.63,4193200,7.86
    -1990-01-31,34.50,34.75,33.00,34.00,5152400,7.94
    -1990-01-30,33.25,34.50,33.00,34.00,4180800,7.94
    -1990-01-29,33.00,33.50,32.13,33.25,4284800,7.77
    -1990-01-26,34.00,34.00,32.25,32.75,6492000,7.65
    -1990-01-25,34.25,34.75,34.00,34.13,3996800,7.97
    -1990-01-24,32.50,34.25,32.25,34.00,6077600,7.94
    -1990-01-23,33.75,34.25,33.00,33.75,5048800,7.88
    -1990-01-22,34.00,34.50,33.25,33.25,5200800,7.77
    -1990-01-19,33.75,34.50,33.50,34.25,9485600,8.00
    -1990-01-18,33.00,33.50,32.25,32.38,9760800,7.56
    -1990-01-17,34.75,34.75,33.00,33.25,7050000,7.77
    -1990-01-16,33.50,35.00,32.75,34.88,7658000,8.15
    -1990-01-15,34.50,35.75,34.25,34.25,5785600,8.00
    -1990-01-12,34.25,34.75,33.75,34.50,6150000,8.06
    -1990-01-11,36.25,36.25,34.50,34.50,7547600,8.06
    -1990-01-10,37.63,37.63,35.75,36.00,7140000,8.41
    -1990-01-09,38.00,38.00,37.00,37.63,3096800,8.79
    -1990-01-08,37.50,38.00,37.00,38.00,3643200,8.88
    -1990-01-05,37.75,38.25,37.00,37.75,4406400,8.82
    -1990-01-04,38.25,38.75,37.25,37.63,7928800,8.79
    -1990-01-03,38.00,38.00,37.50,37.50,7444400,8.76
    -1990-01-02,35.25,37.50,35.00,37.25,6555600,8.70
    -1989-12-29,34.75,35.75,34.38,35.25,5445200,8.23
    -1989-12-28,35.00,35.25,34.25,34.63,5403200,8.09
    -1989-12-27,35.50,35.75,35.00,35.13,9189200,8.21
    -1989-12-26,36.75,36.75,35.25,35.50,4849200,8.29
    -1989-12-22,36.25,37.25,36.00,36.50,6610800,8.53
    -1989-12-21,35.75,36.25,35.50,36.25,10889200,8.47
    -1989-12-20,35.75,36.25,35.25,35.75,6377600,8.35
    -1989-12-19,34.50,35.50,34.50,35.00,8977600,8.18
    -1989-12-18,33.75,35.00,33.75,34.75,10978000,8.12
    -1989-12-15,34.75,35.00,32.50,33.75,18520800,7.88
    -1989-12-14,35.75,36.13,34.50,34.88,10886400,8.15
    -1989-12-13,36.00,36.50,35.50,36.00,13920000,8.41
    -1989-12-12,39.25,39.50,35.00,36.00,36634400,8.41
    -1989-12-11,41.00,41.50,38.38,39.25,23223200,9.17
    -1989-12-08,42.50,43.00,41.25,41.75,9032400,9.75
    -1989-12-07,42.25,43.25,42.00,42.75,6378800,9.99
    -1989-12-06,45.00,45.25,41.00,42.75,11965600,9.99
    -1989-12-05,45.25,45.75,44.50,45.00,4364800,10.51
    -1989-12-04,43.75,45.50,43.75,45.25,3498000,10.57
    -1989-12-01,44.50,45.00,43.63,44.00,5235200,10.28
    -1989-11-30,43.75,44.50,43.50,44.25,2280800,10.34
    -1989-11-29,43.50,44.25,42.50,44.00,5475200,10.28
    -1989-11-28,43.75,44.25,42.75,44.13,4854400,10.31
    -1989-11-27,44.75,45.25,43.75,44.00,3774800,10.28
    -1989-11-24,44.75,45.00,44.75,44.75,1014400,10.45
    -1989-11-22,45.50,45.75,44.50,44.75,3508000,10.45
    -1989-11-21,45.25,46.50,45.25,45.25,5013600,10.57
    -1989-11-20,45.00,45.50,44.50,45.25,3870800,10.57
    -1989-11-17,44.50,45.25,44.50,44.75,3164400,10.45
    -1989-11-16,44.50,44.75,43.75,44.75,3453600,10.43
    -1989-11-15,45.00,45.25,44.00,44.25,3499200,10.31
    -1989-11-14,46.50,46.75,44.50,44.75,3021200,10.43
    -1989-11-13,46.50,47.25,46.50,46.50,2445600,10.83
    -1989-11-10,45.75,47.00,45.75,46.75,2336800,10.89
    -1989-11-09,45.00,46.00,44.50,46.00,3166400,10.72
    -1989-11-08,44.25,45.25,44.25,45.00,5102000,10.49
    -1989-11-07,43.25,44.50,43.25,44.00,5406800,10.25
    -1989-11-06,43.50,44.00,43.00,43.25,4416400,10.08
    -1989-11-03,44.00,44.50,43.25,43.25,6258800,10.08
    -1989-11-02,45.00,45.00,43.00,44.00,16170800,10.25
    -1989-11-01,46.25,46.75,45.75,46.13,2199200,10.75
    -1989-10-31,45.75,46.50,45.50,46.50,3288800,10.83
    -1989-10-30,45.50,46.00,45.00,45.75,3121200,10.66
    -1989-10-27,45.25,45.75,44.50,45.25,4634400,10.54
    -1989-10-26,45.50,46.50,45.00,45.25,6048000,10.54
    -1989-10-25,47.75,47.75,46.25,46.50,4263600,10.83
    -1989-10-24,46.25,48.50,45.25,47.63,7735600,11.10
    -1989-10-23,48.00,48.25,46.25,46.75,4375600,10.89
    -1989-10-20,47.75,49.25,47.50,48.00,9350800,11.18
    -1989-10-19,48.25,49.50,48.25,48.75,4016800,11.36
    -1989-10-18,46.50,48.25,46.00,48.25,5157600,11.24
    -1989-10-17,46.00,48.75,45.00,47.25,8935600,11.01
    -1989-10-16,44.75,46.75,42.50,46.75,15184400,10.89
    -1989-10-13,48.75,49.50,45.00,45.75,7195600,10.66
    -1989-10-12,49.00,49.25,48.50,48.75,2969200,11.36
    -1989-10-11,48.75,49.25,48.00,48.88,5608800,11.39
    -1989-10-10,49.75,50.38,48.50,49.50,10262400,11.53
    -1989-10-09,48.00,49.75,47.50,49.50,6997600,11.53
    -1989-10-06,46.25,48.25,46.00,48.13,12939200,11.21
    -1989-10-05,44.50,46.50,44.25,45.50,8760000,10.60
    -1989-10-04,43.75,44.63,43.50,44.25,5687600,10.31
    -1989-10-03,44.25,44.50,43.13,43.63,6094400,10.17
    -1989-10-02,44.50,44.75,43.75,44.38,4922400,10.34
    -1989-09-29,45.25,45.50,44.50,44.50,2500800,10.37
    -1989-09-28,45.00,45.75,45.00,45.50,2856800,10.60
    -1989-09-27,44.25,45.13,44.00,44.75,3229200,10.43
    -1989-09-26,45.00,45.50,44.75,45.25,2762400,10.54
    -1989-09-25,44.75,45.75,44.75,45.25,4875600,10.54
    -1989-09-22,44.75,45.25,44.25,44.88,2605600,10.46
    -1989-09-21,45.00,46.00,44.25,44.75,7186800,10.43
    -1989-09-20,44.00,45.00,43.75,44.63,4230800,10.40
    -1989-09-19,44.25,44.50,43.00,43.25,2888800,10.08
    -1989-09-18,44.50,45.00,44.00,44.00,2264400,10.25
    -1989-09-15,45.00,45.25,44.25,45.00,4470800,10.49
    -1989-09-14,45.00,45.25,44.50,44.75,4693600,10.43
    -1989-09-13,46.25,46.63,45.00,45.00,4616400,10.49
    -1989-09-12,45.50,46.75,45.00,46.00,3710800,10.72
    -1989-09-11,44.75,46.00,44.50,45.75,3522000,10.66
    -1989-09-08,44.75,45.25,44.50,45.00,2013200,10.49
    -1989-09-07,44.75,45.50,44.75,44.75,4083200,10.43
    -1989-09-06,44.75,44.88,44.00,44.75,3108800,10.43
    -1989-09-05,44.50,45.38,44.50,44.75,4112400,10.43
    -1989-09-01,44.50,44.75,44.25,44.63,2651200,10.40
    -1989-08-31,44.50,45.00,44.25,44.50,2016400,10.37
    -1989-08-30,44.00,44.75,44.00,44.50,4161200,10.37
    -1989-08-29,44.75,45.00,43.75,44.13,6339200,10.28
    -1989-08-28,44.50,45.00,44.00,44.75,2936800,10.43
    -1989-08-25,44.00,45.00,44.00,44.75,5766400,10.43
    -1989-08-24,43.75,44.50,43.50,44.13,5829200,10.28
    -1989-08-23,43.00,44.25,42.50,43.75,6202400,10.19
    -1989-08-22,42.00,43.00,42.00,42.88,4013200,9.99
    -1989-08-21,42.25,43.25,42.00,42.25,4923600,9.84
    -1989-08-18,41.75,42.50,41.50,42.25,3003600,9.82
    -1989-08-17,40.25,41.25,40.00,41.00,5495600,9.53
    -1989-08-16,41.50,41.75,40.00,40.38,4318800,9.39
    -1989-08-15,40.75,41.50,40.75,41.38,5852000,9.62
    -1989-08-14,41.50,42.00,40.50,40.75,3690800,9.47
    -1989-08-11,44.00,44.00,41.25,41.88,8226800,9.74
    -1989-08-10,44.00,44.00,42.75,43.25,5442400,10.05
    -1989-08-09,44.00,45.75,43.88,44.00,6975600,10.23
    -1989-08-08,43.50,44.75,43.50,44.13,7366400,10.26
    -1989-08-07,43.00,44.00,42.63,43.75,6012000,10.17
    -1989-08-04,41.25,42.75,41.13,42.75,6564400,9.94
    -1989-08-03,40.50,41.50,40.50,41.25,6185600,9.59
    -1989-08-02,39.75,40.50,39.50,40.50,3633600,9.41
    -1989-08-01,39.75,40.25,39.25,39.88,4996800,9.27
    -1989-07-31,39.25,40.00,39.00,39.75,4014800,9.24
    -1989-07-28,39.25,39.75,39.00,39.38,4274400,9.15
    -1989-07-27,38.25,39.50,38.00,39.25,6193200,9.12
    -1989-07-26,38.25,38.50,37.75,38.25,8363600,8.89
    -1989-07-25,39.25,39.75,38.00,38.75,7502400,9.01
    -1989-07-24,39.75,39.75,39.25,39.25,4154800,9.12
    -1989-07-21,39.75,40.00,39.00,40.00,4993600,9.30
    -1989-07-20,40.75,41.25,39.75,40.00,8448800,9.30
    -1989-07-19,39.50,40.75,39.00,40.50,8543200,9.41
    -1989-07-18,40.75,40.75,38.75,39.25,17050800,9.12
    -1989-07-17,40.75,41.25,39.75,40.75,4694400,9.47
    -1989-07-14,40.75,41.00,39.75,40.75,9206800,9.47
    -1989-07-13,40.00,41.00,39.50,40.63,8057600,9.44
    -1989-07-12,39.75,40.25,39.50,40.00,4452000,9.30
    -1989-07-11,40.75,41.00,39.75,39.75,8729200,9.24
    -1989-07-10,41.00,41.25,40.00,40.50,7294400,9.41
    -1989-07-07,41.25,42.00,40.50,41.25,3806400,9.59
    -1989-07-06,40.75,41.75,40.25,41.25,6218000,9.59
    -1989-07-05,40.50,40.75,40.00,40.50,4264400,9.41
    -1989-07-03,41.75,41.75,40.75,40.75,1730800,9.47
    -1989-06-30,40.50,41.75,39.50,41.25,5885600,9.59
    -1989-06-29,41.00,41.25,40.00,40.63,8351200,9.44
    -1989-06-28,42.25,42.25,41.00,41.75,9190800,9.70
    -1989-06-27,43.75,44.25,42.50,42.63,3788000,9.91
    -1989-06-26,44.00,44.00,43.25,43.50,6568800,10.11
    -1989-06-23,43.25,44.25,43.25,43.88,4438800,10.20
    -1989-06-22,42.50,43.75,42.00,43.25,4911200,10.05
    -1989-06-21,43.00,43.50,42.25,42.50,4659200,9.88
    -1989-06-20,44.00,44.00,42.25,43.00,4807600,10.00
    -1989-06-19,44.50,44.75,43.50,44.00,6551200,10.23
    -1989-06-16,44.75,45.50,43.50,44.50,19378000,10.34
    -1989-06-15,49.50,49.75,47.50,47.50,5766800,11.04
    -1989-06-14,49.00,50.25,48.25,49.63,8983600,11.54
    -1989-06-13,47.50,48.75,47.00,48.50,8254400,11.27
    -1989-06-12,46.75,47.75,46.25,47.50,2892400,11.04
    -1989-06-09,47.25,47.75,46.50,47.00,3378800,10.93
    -1989-06-08,48.50,49.00,47.25,47.63,6378800,11.07
    -1989-06-07,46.75,48.50,46.75,48.25,6293200,11.22
    -1989-06-06,46.75,47.00,46.25,46.75,5189200,10.87
    -1989-06-05,48.75,49.00,46.50,47.00,4451200,10.93
    -1989-06-02,48.50,49.50,48.50,49.00,4448800,11.39
    -1989-06-01,47.75,49.25,47.50,48.75,6416800,11.33
    -1989-05-31,47.50,48.13,47.00,47.75,4134400,11.10
    -1989-05-30,48.25,49.00,47.38,47.50,4018000,11.04
    -1989-05-26,48.25,49.00,48.00,48.50,4028800,11.27
    -1989-05-25,47.25,49.00,47.25,48.25,8309200,11.22
    -1989-05-24,45.25,47.75,45.25,47.75,10645200,11.10
    -1989-05-23,46.00,46.00,45.25,45.50,4803600,10.58
    -1989-05-22,45.75,46.25,45.25,46.00,6800000,10.69
    -1989-05-19,44.75,46.25,44.75,45.75,11820800,10.61
    -1989-05-18,45.25,45.50,44.75,44.75,7558800,10.38
    -1989-05-17,45.25,45.50,45.00,45.25,8892400,10.50
    -1989-05-16,46.00,46.25,45.00,45.38,8170800,10.53
    -1989-05-15,44.75,46.25,44.75,46.00,11372400,10.67
    -1989-05-12,44.50,45.00,44.00,45.00,16685600,10.44
    -1989-05-11,43.25,44.25,43.00,43.88,10763600,10.18
    -1989-05-10,43.00,43.50,42.50,43.25,8380000,10.03
    -1989-05-09,42.00,43.00,42.00,42.50,12398800,9.86
    -1989-05-08,41.50,42.25,41.50,42.25,7373600,9.80
    -1989-05-05,42.50,42.75,41.50,41.50,16464400,9.63
    -1989-05-04,40.25,41.25,40.00,41.00,6762000,9.51
    -1989-05-03,39.75,40.75,39.75,40.25,7896800,9.34
    -1989-05-02,39.00,40.25,39.00,39.88,7719200,9.25
    -1989-05-01,38.50,39.25,38.50,39.00,2881200,9.05
    -1989-04-28,39.25,39.50,38.50,39.00,3725600,9.05
    -1989-04-27,39.50,40.00,39.00,39.38,4988000,9.13
    -1989-04-26,40.00,40.25,39.13,39.75,6652000,9.22
    -1989-04-25,40.00,40.50,39.75,40.00,4165600,9.28
    -1989-04-24,40.00,40.25,39.50,40.13,3977600,9.31
    -1989-04-21,40.50,40.88,39.75,40.13,4132000,9.31
    -1989-04-20,40.75,41.50,40.25,40.75,6434400,9.45
    -1989-04-19,40.00,41.63,39.75,40.88,15215600,9.48
    -1989-04-18,39.50,40.50,39.25,40.13,20055200,9.31
    -1989-04-17,38.50,39.25,38.00,39.25,5008000,9.10
    -1989-04-14,39.00,39.25,38.25,38.75,4408800,8.99
    -1989-04-13,38.75,39.50,38.25,38.50,6493200,8.93
    -1989-04-12,38.25,39.25,37.88,38.50,13862000,8.93
    -1989-04-11,37.50,38.00,37.00,37.75,5252400,8.76
    -1989-04-10,37.25,38.00,36.75,37.00,4854400,8.58
    -1989-04-07,36.00,37.50,36.00,37.38,12699200,8.67
    -1989-04-06,34.75,36.13,34.50,36.00,5598800,8.35
    -1989-04-05,34.50,35.25,34.25,35.00,4303200,8.12
    -1989-04-04,34.50,34.88,33.88,34.50,4140800,8.00
    -1989-04-03,35.50,36.25,34.75,35.00,5949200,8.12
    -1989-03-31,35.00,35.75,34.75,35.63,6630800,8.26
    -1989-03-30,34.25,35.00,34.00,34.75,3780800,8.06
    -1989-03-29,34.00,34.50,34.00,34.25,2666800,7.94
    -1989-03-28,34.00,34.50,34.00,34.00,5047600,7.89
    -1989-03-27,34.25,34.50,33.50,33.75,5425600,7.83
    -1989-03-23,34.00,34.50,33.75,34.38,4250800,7.97
    -1989-03-22,34.25,34.75,33.75,33.88,5180800,7.86
    -1989-03-21,35.50,35.50,34.75,34.88,4588800,8.09
    -1989-03-20,35.00,35.25,34.50,34.88,6480800,8.09
    -1989-03-17,34.50,35.75,34.00,34.88,8485200,8.09
    -1989-03-16,35.00,35.50,34.50,35.25,6880000,8.18
    -1989-03-15,35.25,35.50,34.75,35.00,3225600,8.12
    -1989-03-14,35.00,35.50,34.88,35.25,5796800,8.18
    -1989-03-13,35.00,35.50,34.75,35.00,4683600,8.12
    -1989-03-10,34.50,35.00,34.25,35.00,3684400,8.12
    -1989-03-09,35.25,35.75,34.50,34.50,4768800,8.00
    -1989-03-08,35.63,36.25,35.25,35.25,7727600,8.18
    -1989-03-07,35.50,36.00,35.00,35.75,9327600,8.29
    -1989-03-06,35.00,35.88,34.50,35.50,6028800,8.23
    -1989-03-03,35.25,35.25,34.00,34.75,13854400,8.06
    -1989-03-02,35.75,36.25,34.75,35.00,13440800,8.12
    -1989-03-01,36.25,36.50,35.50,36.00,6096400,8.35
    -1989-02-28,36.50,36.75,36.00,36.25,6290000,8.41
    -1989-02-27,36.00,36.50,35.75,36.50,4151200,8.47
    -1989-02-24,37.00,37.00,36.00,36.00,5452000,8.35
    -1989-02-23,36.50,37.00,36.25,36.75,3409200,8.52
    -1989-02-22,37.25,37.50,36.50,36.75,8529200,8.52
    -1989-02-21,36.88,37.75,36.75,37.50,6808800,8.70
    -1989-02-17,36.25,37.00,36.25,36.75,4180800,8.52
    -1989-02-16,36.25,37.25,36.00,36.38,9138800,8.41
    -1989-02-15,35.75,36.25,35.50,36.25,11812400,8.38
    -1989-02-14,36.88,37.00,35.25,35.75,31843200,8.27
    -1989-02-13,36.75,37.25,36.75,37.00,8422000,8.56
    -1989-02-10,38.25,38.25,37.00,37.25,12441200,8.62
    -1989-02-09,38.25,39.00,38.00,38.25,5756400,8.85
    -1989-02-08,39.00,39.50,38.00,38.25,5612000,8.85
    -1989-02-07,38.25,39.25,38.25,39.00,5908800,9.02
    -1989-02-06,39.50,39.50,38.25,38.50,4174400,8.91
    -1989-02-03,40.00,40.25,39.00,39.25,6406400,9.08
    -1989-02-02,39.50,40.25,39.25,39.75,16927600,9.19
    -1989-02-01,37.75,39.63,37.38,39.25,17420000,9.08
    -1989-01-31,37.25,37.75,36.75,37.75,16442000,8.73
    -1989-01-30,37.63,38.00,37.25,37.38,20961200,8.65
    -1989-01-27,38.25,39.25,36.25,37.63,75976400,8.70
    -1989-01-26,40.75,42.13,40.63,41.75,10203600,9.66
    -1989-01-25,41.75,42.00,41.00,41.50,3963200,9.60
    -1989-01-24,41.00,41.75,40.75,41.63,7983200,9.63
    -1989-01-23,40.75,41.25,40.75,41.00,6452000,9.48
    -1989-01-20,40.50,41.50,40.25,41.00,6207600,9.48
    -1989-01-19,40.50,41.00,40.00,40.50,9155200,9.37
    -1989-01-18,40.75,41.13,39.50,39.75,17440800,9.19
    -1989-01-17,43.25,43.50,40.00,40.38,27033600,9.34
    -1989-01-16,43.25,44.00,43.00,43.75,6033200,10.12
    -1989-01-13,42.75,43.50,42.38,43.25,6928000,10.00
    -1989-01-12,42.25,43.00,42.00,42.75,5373200,9.89
    -1989-01-11,42.25,42.50,41.25,42.13,5585200,9.74
    -1989-01-10,42.50,42.88,41.50,42.63,3695600,9.86
    -1989-01-09,43.00,43.13,42.25,43.00,2850800,9.95
    -1989-01-06,42.25,43.50,42.25,42.63,7103600,9.86
    -1989-01-05,42.00,43.25,41.25,42.25,10985200,9.77
    -1989-01-04,40.75,42.13,40.50,42.00,8575200,9.71
    -1989-01-03,40.25,40.50,40.00,40.38,3578800,9.34
    -1988-12-30,40.50,41.25,40.25,40.25,2938800,9.31
    -1988-12-29,40.25,40.75,40.25,40.50,4212000,9.37
    -1988-12-28,40.50,40.75,39.75,40.25,1841200,9.31
    -1988-12-27,41.00,41.50,40.50,40.50,2155200,9.37
    -1988-12-23,41.00,41.38,41.00,41.13,1475600,9.51
    -1988-12-22,41.75,42.00,40.75,41.00,3802000,9.48
    -1988-12-21,41.00,42.00,41.00,41.75,8642400,9.66
    -1988-12-20,41.00,41.50,40.63,41.00,9810800,9.48
    -1988-12-19,40.25,41.00,40.00,40.75,8373600,9.43
    -1988-12-16,39.50,40.50,39.25,40.13,6572000,9.28
    -1988-12-15,40.00,40.50,39.25,39.50,4032000,9.14
    -1988-12-14,38.50,40.00,38.50,39.75,6916800,9.19
    -1988-12-13,38.50,38.75,38.25,38.75,4386400,8.96
    -1988-12-12,39.25,39.50,38.50,38.50,4215600,8.91
    -1988-12-09,39.25,39.50,38.75,39.13,1608800,9.05
    -1988-12-08,39.25,39.25,38.75,39.13,2125600,9.05
    -1988-12-07,39.00,39.50,38.75,39.38,3518800,9.11
    -1988-12-06,39.25,39.75,39.00,39.50,3763200,9.14
    -1988-12-05,39.50,40.00,38.75,39.50,5534400,9.14
    -1988-12-02,38.25,39.88,38.00,39.25,11940000,9.08
    -1988-12-01,37.75,39.00,37.50,38.75,7586800,8.96
    -1988-11-30,36.75,38.00,36.75,37.63,6013600,8.70
    -1988-11-29,36.50,36.75,36.00,36.75,3326400,8.50
    -1988-11-28,36.50,36.75,36.00,36.50,4986800,8.44
    -1988-11-25,36.25,36.75,36.00,36.50,1727600,8.44
    -1988-11-23,35.75,37.00,35.50,36.88,6733200,8.53
    -1988-11-22,36.50,36.88,36.00,36.13,5299200,8.36
    -1988-11-21,37.50,37.75,36.25,36.63,7928000,8.47
    -1988-11-18,38.50,38.50,38.00,38.00,2066400,8.77
    -1988-11-17,38.00,38.50,38.00,38.25,2841200,8.82
    -1988-11-16,39.00,39.25,37.75,38.00,5280000,8.77
    -1988-11-15,39.00,39.25,38.75,39.00,2866800,9.00
    -1988-11-14,38.75,39.00,38.25,38.88,3046400,8.97
    -1988-11-11,39.00,39.63,38.50,38.50,3882400,8.88
    -1988-11-10,39.50,39.75,39.00,39.50,3573200,9.11
    -1988-11-09,38.25,39.38,38.00,39.25,7206800,9.05
    -1988-11-08,37.50,38.75,37.38,38.50,5540800,8.88
    -1988-11-07,37.25,37.75,37.00,37.50,6093600,8.65
    -1988-11-04,36.75,38.00,36.75,37.75,5500000,8.71
    -1988-11-03,37.25,37.50,36.75,37.13,8670000,8.57
    -1988-11-02,38.25,38.25,36.75,37.25,7451200,8.59
    -1988-11-01,38.50,38.75,37.75,38.00,5138800,8.77
    -1988-10-31,38.75,38.75,37.50,38.63,8695200,8.91
    -1988-10-28,39.00,39.50,38.50,38.50,3026800,8.88
    -1988-10-27,38.75,39.25,38.25,39.00,5138000,9.00
    -1988-10-26,40.00,40.00,38.50,39.25,6751200,9.05
    -1988-10-25,40.25,40.25,39.75,39.88,3043600,9.20
    -1988-10-24,41.25,41.25,39.63,40.00,4842400,9.23
    -1988-10-21,41.25,41.75,40.75,41.00,4422400,9.46
    -1988-10-20,40.00,41.63,40.00,41.50,6215200,9.57
    -1988-10-19,39.75,40.75,39.50,40.00,9918000,9.23
    -1988-10-18,39.00,39.50,38.25,39.38,5100000,9.08
    -1988-10-17,38.50,39.00,38.25,38.50,3360800,8.88
    -1988-10-14,39.50,39.50,38.13,38.75,5625200,8.94
    -1988-10-13,38.50,39.75,38.50,39.00,5892400,9.00
    -1988-10-12,38.50,39.00,38.00,38.75,4763600,8.94
    -1988-10-11,38.25,39.50,38.25,39.00,6964400,9.00
    -1988-10-10,39.50,39.75,37.50,38.50,11880000,8.88
    -1988-10-07,39.00,39.75,38.38,39.75,16355200,9.17
    -1988-10-06,40.50,40.88,39.25,39.75,6009200,9.17
    -1988-10-05,41.25,41.75,40.50,40.88,4400000,9.43
    -1988-10-04,42.25,42.75,41.13,41.50,1847600,9.57
    -1988-10-03,43.00,43.25,42.00,42.50,3243200,9.80
    -1988-09-30,44.00,44.00,43.25,43.25,3338800,9.98
    -1988-09-29,43.75,44.25,43.50,44.00,3804400,10.15
    -1988-09-28,43.50,44.13,43.25,43.50,3038800,10.04
    -1988-09-27,42.50,43.50,42.50,43.38,5832400,10.01
    -1988-09-26,43.75,44.00,42.50,42.75,3124400,9.86
    -1988-09-23,43.50,44.25,43.50,43.75,3638000,10.09
    -1988-09-22,43.00,44.00,42.75,44.00,5203600,10.15
    -1988-09-21,41.75,43.00,41.50,42.75,3274800,9.86
    -1988-09-20,41.75,42.25,41.38,41.50,3682400,9.57
    -1988-09-19,42.00,42.25,41.25,41.75,3296400,9.63
    -1988-09-16,41.50,42.75,41.38,42.25,4431200,9.75
    -1988-09-15,42.00,42.75,41.50,41.63,5920000,9.60
    -1988-09-14,41.75,42.38,41.50,42.00,8520800,9.69
    -1988-09-13,40.25,41.25,40.00,41.00,4293600,9.46
    -1988-09-12,41.00,41.75,40.13,41.00,5290800,9.46
    -1988-09-09,38.75,41.00,37.75,40.50,8393200,9.34
    -1988-09-08,38.25,39.50,37.75,38.75,7403200,8.94
    -1988-09-07,39.00,39.50,37.75,38.25,6417600,8.82
    -1988-09-06,40.00,40.00,38.75,38.88,5125200,8.97
    -1988-09-02,39.50,40.00,39.00,39.75,6661200,9.17
    -1988-09-01,39.75,39.75,38.50,38.88,8818800,8.97
    -1988-08-31,41.00,41.13,39.50,39.88,8493600,9.20
    -1988-08-30,40.75,41.00,40.00,40.88,1809200,9.43
    -1988-08-29,40.75,41.00,40.50,40.88,2046400,9.43
    -1988-08-26,40.00,40.75,40.00,40.25,1453200,9.29
    -1988-08-25,40.25,40.50,39.25,40.13,4560000,9.26
    -1988-08-24,39.75,40.75,39.50,40.75,4482000,9.40
    -1988-08-23,39.75,40.25,39.25,39.50,5843200,9.11
    -1988-08-22,40.25,40.75,39.50,39.75,6100000,9.17
    -1988-08-19,42.50,42.75,40.50,40.75,8120000,9.40
    -1988-08-18,42.00,43.00,41.75,42.50,2648000,9.80
    -1988-08-17,42.50,42.75,41.75,42.00,4252400,9.69
    -1988-08-16,41.00,43.25,40.75,42.50,4397600,9.80
    -1988-08-15,42.25,42.25,40.50,41.25,5971200,9.52
    -1988-08-12,43.00,43.00,42.25,42.50,2771200,9.79
    -1988-08-11,42.25,43.25,42.00,43.25,3803200,9.96
    -1988-08-10,43.75,43.75,41.75,41.88,5300800,9.64
    -1988-08-09,44.00,44.25,43.00,43.50,6090800,10.02
    -1988-08-08,44.50,44.75,44.00,44.00,1085600,10.13
    -1988-08-05,44.50,45.00,44.25,44.25,1881200,10.19
    -1988-08-04,44.75,45.25,44.50,44.63,2473200,10.28
    -1988-08-03,44.75,44.75,44.00,44.75,3980800,10.30
    -1988-08-02,45.00,45.50,44.50,44.63,4338000,10.28
    -1988-08-01,44.50,45.75,44.25,45.00,3085600,10.36
    -1988-07-29,43.25,44.50,43.00,44.38,5697600,10.22
    -1988-07-28,42.50,43.00,42.25,42.63,3326800,9.82
    -1988-07-27,42.75,43.25,42.50,42.75,4162400,9.84
    -1988-07-26,42.75,43.25,42.25,42.75,3640800,9.84
    -1988-07-25,42.75,43.25,42.25,42.75,3794400,9.84
    -1988-07-22,43.00,43.25,42.50,42.50,3724800,9.79
    -1988-07-21,43.75,44.00,42.75,43.00,5323600,9.90
    -1988-07-20,44.75,45.00,44.00,44.25,4293600,10.19
    -1988-07-19,45.00,45.50,43.88,44.75,4372400,10.30
    -1988-07-18,45.38,46.00,45.25,45.50,4061200,10.48
    -1988-07-15,45.00,45.50,44.75,45.00,2968000,10.36
    -1988-07-14,44.75,45.25,44.50,45.00,2245200,10.36
    -1988-07-13,44.75,45.00,44.25,44.75,4132000,10.30
    -1988-07-12,45.00,45.25,44.50,44.75,3605600,10.30
    -1988-07-11,45.50,45.50,44.88,45.13,2646400,10.39
    -1988-07-08,45.50,46.00,45.00,45.25,3766400,10.42
    -1988-07-07,46.50,46.50,45.25,45.88,3778000,10.56
    -1988-07-06,47.13,47.50,46.13,46.50,5608800,10.71
    -1988-07-05,46.50,47.25,46.13,47.25,3736400,10.88
    -1988-07-01,46.50,46.88,46.25,46.50,3385600,10.71
    -1988-06-30,46.25,46.75,46.00,46.25,4104800,10.65
    -1988-06-29,46.00,46.75,45.75,46.38,5125200,10.68
    -1988-06-28,44.75,46.25,44.50,46.25,5809200,10.65
    -1988-06-27,44.50,45.38,44.50,44.50,3001200,10.25
    -1988-06-24,45.00,45.50,44.50,45.00,2684400,10.36
    -1988-06-23,45.75,45.75,45.00,45.00,2566400,10.36
    -1988-06-22,45.50,45.88,45.00,45.63,6998000,10.51
    -1988-06-21,44.00,45.00,43.88,44.88,4422000,10.33
    -1988-06-20,44.38,44.75,44.00,44.13,2811200,10.16
    -1988-06-17,44.75,44.75,44.25,44.75,3410800,10.30
    -1988-06-16,45.00,45.25,44.25,44.50,3854400,10.25
    -1988-06-15,45.25,45.75,45.00,45.75,4360000,10.53
    -1988-06-14,45.25,46.00,45.00,45.25,10445600,10.42
    -1988-06-13,45.00,45.25,44.25,45.00,5320000,10.36
    -1988-06-10,43.50,44.75,43.00,44.50,6320000,10.25
    -1988-06-09,45.00,45.25,43.25,43.50,9640000,10.02
    -1988-06-08,44.25,45.50,44.00,45.00,9240000,10.36
    -1988-06-07,43.75,45.25,43.50,44.00,11120000,10.13
    -1988-06-06,42.75,44.00,42.75,44.00,5880000,10.13
    -1988-06-03,41.75,43.25,41.75,43.00,6280000,9.90
    -1988-06-02,42.00,42.50,41.50,41.75,4760000,9.61
    -1988-06-01,41.50,42.50,41.25,42.50,8200000,9.79
    -1988-05-31,40.00,41.50,39.75,41.50,4400000,9.56
    -1988-05-27,39.25,40.00,39.00,39.75,3020000,9.15
    -1988-05-26,38.50,39.50,38.50,39.38,3076800,9.07
    -1988-05-25,39.00,39.75,38.50,38.50,4840000,8.87
    -1988-05-24,38.00,39.00,37.75,38.88,5080000,8.95
    -1988-05-23,38.50,38.88,37.38,38.00,6560000,8.75
    -1988-05-20,39.25,39.50,38.75,38.75,2941200,8.92
    -1988-05-19,39.50,39.75,38.50,39.00,8920000,8.98
    -1988-05-18,40.50,40.75,39.50,39.75,6240000,9.15
    -1988-05-17,41.50,42.00,40.25,40.50,6920000,9.33
    -1988-05-16,40.50,41.38,40.00,41.25,2686800,9.50
    -1988-05-13,40.25,40.50,40.00,40.50,2566800,9.31
    -1988-05-12,39.50,40.25,39.50,39.75,2965600,9.13
    -1988-05-11,40.25,40.75,39.50,39.50,6240000,9.08
    -1988-05-10,40.50,41.00,40.25,40.88,3439200,9.39
    -1988-05-09,41.25,41.25,40.50,40.75,2732000,9.36
    -1988-05-06,41.63,41.75,41.25,41.25,3835600,9.48
    -1988-05-05,42.00,42.25,41.50,41.75,2536800,9.59
    -1988-05-04,41.88,43.13,41.75,42.00,8000000,9.65
    -1988-05-03,41.00,42.25,40.75,41.75,4440000,9.59
    -1988-05-02,40.75,41.25,40.50,41.00,2944400,9.42
    -1988-04-29,41.25,41.50,40.50,41.00,3222000,9.42
    -1988-04-28,41.75,42.00,41.25,41.38,3553600,9.51
    -1988-04-27,41.75,42.00,41.50,41.75,4520000,9.59
    -1988-04-26,41.00,41.75,40.75,41.50,6280000,9.54
    -1988-04-25,40.25,41.00,40.00,40.88,5360000,9.39
    -1988-04-22,39.75,40.25,39.50,40.13,3846800,9.22
    -1988-04-21,40.38,40.50,39.00,39.50,6360000,9.08
    -1988-04-20,40.25,40.50,39.25,39.75,7680000,9.13
    -1988-04-19,40.13,41.50,40.13,40.25,7596400,9.25
    -1988-04-18,39.75,40.75,39.25,40.00,6080000,9.19
    -1988-04-15,39.75,40.00,38.50,39.50,8320000,9.08
    -1988-04-14,40.50,41.50,39.00,39.50,6720000,9.08
    -1988-04-13,41.75,42.00,41.00,41.25,5120000,9.48
    -1988-04-12,41.75,42.25,41.25,41.75,6200000,9.59
    -1988-04-11,41.75,42.00,41.00,41.50,5320000,9.54
    -1988-04-08,40.75,41.75,39.75,41.00,7240000,9.42
    -1988-04-07,41.75,42.38,40.75,40.75,5840000,9.36
    -1988-04-06,39.50,41.75,39.00,41.75,6800000,9.59
    -1988-04-05,39.25,39.50,38.50,39.25,5280000,9.02
    -1988-04-04,39.75,40.50,38.50,38.75,6480000,8.91
    -1988-03-31,39.75,40.50,39.25,40.00,7760000,9.19
    -1988-03-30,40.75,41.25,38.75,39.50,13280000,9.08
    -1988-03-29,41.50,42.00,40.63,41.00,7640000,9.42
    -1988-03-28,40.00,41.75,39.50,41.50,6160000,9.54
    -1988-03-25,40.75,41.25,40.00,40.13,4680000,9.22
    -1988-03-24,41.75,42.50,40.00,40.88,11440000,9.39
    -1988-03-23,44.00,44.00,41.88,42.50,7480000,9.77
    -1988-03-22,44.00,44.50,43.25,44.00,4265600,10.11
    -1988-03-21,44.38,44.63,43.00,43.88,8120000,10.08
    -1988-03-18,45.00,45.50,44.25,44.75,9720000,10.28
    -1988-03-17,46.25,46.50,44.75,45.00,9320000,10.34
    -1988-03-16,44.88,46.38,44.50,46.13,4240000,10.60
    -1988-03-15,46.00,46.25,44.75,45.00,6480000,10.34
    -1988-03-14,45.75,46.50,45.50,46.25,3518000,10.63
    -1988-03-11,45.50,45.75,44.50,45.75,5640000,10.51
    -1988-03-10,47.00,47.25,45.25,45.25,6320000,10.40
    -1988-03-09,46.25,47.25,46.25,46.75,4800000,10.74
    -1988-03-08,46.75,47.00,46.00,46.25,5160000,10.63
    -1988-03-07,46.75,47.75,46.50,46.88,7400000,10.77
    -1988-03-04,46.00,47.00,45.50,46.88,7480000,10.77
    -1988-03-03,44.50,47.00,44.50,46.50,16920000,10.69
    -1988-03-02,43.75,45.00,43.50,44.75,10440000,10.28
    -1988-03-01,43.25,43.50,42.50,43.25,6120000,9.94
    -1988-02-29,41.75,43.25,41.50,43.00,4000000,9.88
    -1988-02-26,42.00,42.25,41.25,41.75,2952400,9.59
    -1988-02-25,42.00,43.00,41.75,41.75,6400000,9.59
    -1988-02-24,42.75,43.00,42.00,42.25,5200000,9.71
    -1988-02-23,43.25,43.75,42.25,42.75,7880000,9.82
    -1988-02-22,41.50,43.63,41.50,43.25,7160000,9.94
    -1988-02-19,41.75,42.00,41.50,41.75,3242400,9.59
    -1988-02-18,41.63,42.75,41.50,41.75,5120000,9.59
    -1988-02-17,41.25,42.50,41.25,41.88,9160000,9.62
    -1988-02-16,41.00,41.25,40.00,41.25,5520000,9.48
    -1988-02-12,40.63,41.50,40.50,41.00,4920000,9.42
    -1988-02-11,41.00,41.25,40.25,40.63,5280000,9.32
    -1988-02-10,39.75,41.50,39.75,41.00,8160000,9.40
    -1988-02-09,39.00,39.88,38.75,39.75,4160000,9.12
    -1988-02-08,38.50,39.25,37.75,38.75,7280000,8.89
    -1988-02-05,40.00,40.38,38.50,38.63,4720000,8.86
    -1988-02-04,39.50,40.13,39.00,39.75,7120000,9.12
    -1988-02-03,41.00,41.25,39.25,39.50,8080000,9.06
    -1988-02-02,41.50,41.88,40.50,41.25,6840000,9.46
    -1988-02-01,41.75,42.50,41.38,41.75,7120000,9.58
    -1988-01-29,41.50,41.75,40.25,41.50,9480000,9.52
    -1988-01-28,40.00,41.50,39.75,41.25,8320000,9.46
    -1988-01-27,40.25,40.50,38.75,39.75,9240000,9.12
    -1988-01-26,40.75,41.00,39.25,39.75,5120000,9.12
    -1988-01-25,39.50,41.50,39.50,40.88,7160000,9.38
    -1988-01-22,40.50,40.75,38.25,39.25,15920000,9.00
    -1988-01-21,40.50,40.75,39.38,40.13,17640000,9.20
    -1988-01-20,43.00,43.00,38.25,39.75,24320000,9.12
    -1988-01-19,42.25,43.25,41.38,42.75,9800000,9.80
    -1988-01-18,43.00,43.00,42.00,42.75,4480000,9.80
    -1988-01-15,43.50,45.00,42.50,42.88,12280000,9.83
    -1988-01-14,42.75,42.88,42.00,42.25,4720000,9.69
    -1988-01-13,42.00,43.25,41.13,42.25,7560000,9.69
    -1988-01-12,43.00,43.50,39.75,42.00,14320000,9.63
    -1988-01-11,40.00,42.75,39.75,42.50,14440000,9.75
    -1988-01-08,44.50,45.25,39.50,40.00,17360000,9.17
    -1988-01-07,43.50,44.75,42.50,44.50,7600000,10.21
    -1988-01-06,45.00,45.00,43.75,43.75,9600000,10.03
    -1988-01-05,46.00,46.25,44.25,44.63,11040000,10.24
    -1988-01-04,42.75,44.75,42.25,44.75,11800000,10.26
    -1987-12-31,42.50,43.00,41.88,42.00,4200000,9.63
    -1987-12-30,42.50,43.75,42.50,43.38,5560000,9.95
    -1987-12-29,40.50,42.25,40.25,42.13,4240000,9.66
    -1987-12-28,42.25,42.50,39.50,40.25,8200000,9.23
    -1987-12-24,42.00,43.00,41.75,42.63,2508000,9.78
    -1987-12-23,41.75,42.75,41.25,42.25,6120000,9.69
    -1987-12-22,41.75,41.75,40.50,41.50,4600000,9.52
    -1987-12-21,40.50,41.75,40.25,41.75,6720000,9.58
    -1987-12-18,39.50,41.25,39.25,40.50,10800000,9.29
    -1987-12-17,40.50,40.75,39.25,39.25,11640000,9.00
    -1987-12-16,37.75,39.75,37.25,39.25,11800000,9.00
    -1987-12-15,37.75,38.25,37.00,37.50,10680000,8.60
    -1987-12-14,34.50,37.50,34.25,37.25,12200000,8.54
    -1987-12-11,34.75,34.75,33.50,34.00,4360000,7.80
    -1987-12-10,33.75,36.00,33.25,34.75,9880000,7.97
    -1987-12-09,34.50,36.25,33.88,35.00,6400000,8.03
    -1987-12-08,33.50,34.88,33.25,34.50,9080000,7.91
    -1987-12-07,31.00,33.25,31.00,33.00,7280000,7.57
    -1987-12-04,30.25,31.25,29.75,30.75,8720000,7.05
    -1987-12-03,33.00,33.38,29.75,30.50,11400000,7.00
    -1987-12-02,33.25,33.50,32.50,32.50,5080000,7.45
    -1987-12-01,33.50,34.00,32.75,33.25,6480000,7.63
    -1987-11-30,33.75,34.50,30.50,33.00,14880000,7.57
    -1987-11-27,36.25,36.50,34.75,35.00,2526800,8.03
    -1987-11-25,37.00,37.00,36.00,36.50,3311200,8.37
    -1987-11-24,36.75,37.75,36.13,37.00,7040000,8.49
    -1987-11-23,35.50,36.25,34.75,36.25,3500000,8.31
    -1987-11-20,34.00,36.00,33.25,35.50,8960000,8.14
    -1987-11-19,36.50,36.50,34.00,34.50,6520000,7.91
    -1987-11-18,35.75,36.50,34.50,36.25,9480000,8.31
    -1987-11-17,36.75,37.00,35.00,35.00,9600000,8.03
    -1987-11-16,37.75,38.50,36.50,36.75,6600000,8.41
    -1987-11-13,39.25,39.50,37.00,37.25,5520000,8.52
    -1987-11-12,38.50,40.00,38.38,38.75,8800000,8.87
    -1987-11-11,37.25,38.25,36.75,37.25,6640000,8.52
    -1987-11-10,36.50,37.50,36.00,36.25,8280000,8.30
    -1987-11-09,37.00,37.50,36.25,37.25,7520000,8.52
    -1987-11-06,38.25,39.50,37.00,37.75,6680000,8.64
    -1987-11-05,36.25,38.75,36.25,38.00,9120000,8.70
    -1987-11-04,35.50,37.25,34.75,36.00,8360000,8.24
    -1987-11-03,38.00,38.50,34.25,36.25,11200000,8.30
    -1987-11-02,38.75,39.50,37.50,38.75,6720000,8.87
    -1987-10-30,40.00,43.00,38.50,38.63,15040000,8.84
    -1987-10-29,34.25,40.00,32.25,39.50,11840000,9.04
    -1987-10-28,30.75,33.75,29.25,33.50,14960000,7.67
    -1987-10-27,29.50,32.25,29.00,30.25,16280000,6.92
    -1987-10-26,34.50,35.00,27.62,28.00,11200000,6.41
    -1987-10-23,35.75,36.50,34.25,35.50,7080000,8.12
    -1987-10-22,39.25,40.50,36.00,36.75,13760000,8.41
    -1987-10-21,38.50,42.00,38.00,40.50,19080000,9.27
    -1987-10-20,38.50,42.00,32.63,34.50,20320000,7.90
    -1987-10-19,48.25,48.25,35.50,36.50,17000000,8.35
    -1987-10-16,52.25,53.00,47.50,48.25,15000000,11.04
    -1987-10-15,53.25,54.50,51.75,52.00,12440000,11.90
    -1987-10-14,53.75,54.00,52.00,53.25,9240000,12.19
    -1987-10-13,54.50,54.75,53.25,54.50,5800000,12.47
    -1987-10-12,54.25,54.38,51.75,53.25,7120000,12.19
    -1987-10-09,54.25,55.50,54.00,54.13,5200000,12.39
    -1987-10-08,55.50,56.00,53.25,54.25,5880000,12.42
    -1987-10-07,55.50,55.75,54.25,55.50,8000000,12.70
    -1987-10-06,59.50,59.50,55.50,55.75,7200000,12.76
    -1987-10-05,58.50,59.75,57.75,59.25,4800000,13.56
    -1987-10-02,58.25,58.75,57.50,58.50,3450000,13.39
    -1987-10-01,56.75,58.75,56.50,58.25,4160000,13.33
    -1987-09-30,54.25,57.00,54.25,56.50,4360000,12.93
    -1987-09-29,56.00,56.00,54.25,54.50,6120000,12.47
    -1987-09-28,57.50,58.75,55.50,55.75,7280000,12.76
    -1987-09-25,56.75,58.00,56.50,57.50,3806800,13.16
    -1987-09-24,55.25,57.88,55.25,56.50,6520000,12.93
    -1987-09-23,54.13,56.00,53.75,55.25,9098800,12.64
    -1987-09-22,50.50,54.25,50.25,54.13,5480000,12.39
    -1987-09-21,51.75,52.75,50.25,50.25,4600000,11.50
    -1987-09-18,52.00,52.25,51.38,51.75,2555600,11.84
    -1987-09-17,52.00,52.25,51.00,52.00,2400000,11.90
    -1987-09-16,51.75,52.63,51.25,51.75,6000000,11.84
    -1987-09-15,53.00,53.00,51.50,51.75,3744800,11.84
    -1987-09-14,54.75,55.25,52.75,53.00,2928000,12.13
    -1987-09-11,54.00,55.50,52.75,54.50,4440000,12.47
    -1987-09-10,53.25,54.50,53.13,53.75,5000000,12.30
    -1987-09-09,50.25,53.00,49.50,52.75,5640000,12.07
    -1987-09-08,50.25,50.50,48.50,49.88,6280000,11.42
    -1987-09-04,51.25,51.75,50.00,50.50,3891200,11.56
    -1987-09-03,52.50,52.75,50.25,51.25,6600000,11.73
    -1987-09-02,52.00,53.25,50.75,52.00,8200000,11.90
    -1987-09-01,54.75,55.25,52.50,52.50,4960000,12.01
    -1987-08-31,52.25,54.25,51.75,54.00,5360000,12.36
    -1987-08-28,52.00,52.50,51.50,52.00,3434400,11.90
    -1987-08-27,52.25,52.75,51.50,52.00,4440000,11.90
    -1987-08-26,53.00,53.50,52.00,52.00,7000000,11.90
    -1987-08-25,52.75,53.25,52.00,52.00,4880000,11.90
    -1987-08-24,53.00,53.50,52.25,52.25,4320000,11.96
    -1987-08-21,51.75,53.75,51.50,53.00,5000000,12.13
    -1987-08-20,50.25,52.50,49.75,51.75,6280000,11.84
    -1987-08-19,49.50,50.00,49.00,50.00,2404400,11.44
    -1987-08-18,49.25,49.50,48.25,48.75,8480000,11.16
    -1987-08-17,49.50,50.00,48.75,49.50,5200000,11.33
    -1987-08-14,48.50,50.00,48.00,49.00,3758800,11.21
    -1987-08-13,48.75,50.25,48.50,49.00,7000000,11.21
    -1987-08-12,49.50,49.75,48.25,48.75,5760000,11.16
    -1987-08-11,49.50,50.25,48.75,49.50,9680000,11.33
    -1987-08-10,48.25,48.25,45.75,48.25,2800000,11.04
    -1987-08-07,46.25,47.25,46.00,46.50,5440000,10.63
    -1987-08-06,43.25,46.75,42.75,46.25,9000000,10.57
    -1987-08-05,42.25,43.50,42.00,43.25,4640000,9.89
    -1987-08-04,40.50,42.25,40.00,42.25,4320000,9.66
    -1987-08-03,41.00,41.50,40.25,40.25,2275600,9.20
    -1987-07-31,41.25,42.00,41.25,41.25,2613600,9.43
    -1987-07-30,41.00,41.50,40.75,41.50,3727600,9.49
    -1987-07-29,42.00,42.00,40.50,41.00,3534800,9.37
    -1987-07-28,42.50,42.75,41.75,41.88,2660800,9.57
    -1987-07-27,42.50,43.00,42.00,42.25,2035600,9.66
    -1987-07-24,41.50,42.75,41.50,42.50,4200000,9.71
    -1987-07-23,43.00,43.50,40.50,41.75,2685600,9.54
    -1987-07-22,41.50,42.75,41.25,42.50,2185200,9.71
    -1987-07-21,42.00,42.50,41.25,41.38,3966400,9.46
    -1987-07-20,43.00,43.25,41.50,41.75,4440000,9.54
    -1987-07-17,44.25,44.75,42.75,43.25,3300000,9.89
    -1987-07-16,44.00,44.00,43.25,44.00,3388000,10.06
    -1987-07-15,43.00,44.75,42.25,44.00,9680000,10.06
    -1987-07-14,41.00,43.00,41.00,43.00,9200000,9.83
    -1987-07-13,39.00,40.75,38.75,40.50,9120000,9.26
    -1987-07-10,38.00,39.25,37.75,38.00,5600000,8.69
    -1987-07-09,37.25,38.75,37.25,37.75,8560000,8.63
    -1987-07-08,39.25,39.25,36.50,37.25,12200000,8.51
    -1987-07-07,40.50,41.00,38.75,39.25,7280000,8.97
    -1987-07-06,40.75,41.75,40.50,40.75,3060800,9.31
    -1987-07-02,40.00,41.00,39.75,40.63,2931200,9.29
    -1987-07-01,40.75,40.75,39.75,40.00,3402000,9.14
    -1987-06-30,40.50,41.00,39.75,40.50,5160000,9.26
    -1987-06-29,40.50,40.75,40.00,40.75,3628000,9.31
    -1987-06-26,40.75,41.50,40.00,40.50,4560000,9.26
    -1987-06-25,42.00,42.50,40.50,40.50,4320000,9.26
    -1987-06-24,41.50,43.25,40.50,42.00,4240000,9.60
    -1987-06-23,42.00,42.13,40.75,41.25,2892000,9.43
    -1987-06-22,41.25,42.25,40.88,42.00,6040000,9.60
    -1987-06-19,41.50,41.75,40.38,41.00,4480000,9.37
    -1987-06-18,40.25,41.75,39.50,41.50,8200000,9.49
    -1987-06-17,41.50,42.50,40.00,40.50,10640000,9.26
    -1987-06-16,41.50,41.75,38.00,41.50,12240000,9.49
    -1987-06-15,79.00,79.50,77.50,78.50,9280000,8.97
    -1987-06-12,79.00,79.75,78.75,79.00,3653600,9.03
    -1987-06-11,78.50,80.00,78.00,79.00,4521600,9.03
    -1987-06-10,78.75,80.25,78.00,78.50,5235200,8.97
    -1987-06-09,77.50,79.50,77.50,78.50,4570400,8.97
    -1987-06-08,77.75,78.00,76.75,77.75,7213600,8.89
    -1987-06-05,78.75,78.75,77.75,77.75,4696000,8.89
    -1987-06-04,78.00,78.75,77.00,78.50,5511200,8.97
    -1987-06-03,77.25,79.50,77.25,77.75,6140000,8.89
    -1987-06-02,77.50,78.00,77.00,77.25,4927200,8.83
    -1987-06-01,79.50,79.50,77.50,77.75,2984000,8.89
    -1987-05-29,80.25,80.50,79.00,79.00,3322400,9.03
    -1987-05-28,79.50,80.25,78.50,80.00,5424000,9.14
    -1987-05-27,78.00,80.25,77.50,79.50,6484000,9.09
    -1987-05-26,74.50,78.00,74.00,78.00,5481600,8.91
    -1987-05-22,75.00,75.50,73.75,74.12,3484000,8.47
    -1987-05-21,74.75,75.75,74.50,74.50,6233600,8.51
    -1987-05-20,73.00,75.00,72.50,74.50,10320000,8.51
    -1987-05-19,75.75,75.75,72.62,73.25,8560000,8.37
    -1987-05-18,78.25,78.50,75.50,75.75,8640000,8.66
    -1987-05-15,79.25,79.25,78.00,78.25,5220000,8.94
    -1987-05-14,78.25,79.50,78.25,79.25,5316000,9.06
    -1987-05-13,75.75,78.62,75.50,78.50,11120000,8.97
    -1987-05-12,76.00,76.50,75.00,75.50,9280000,8.63
    -1987-05-11,77.00,79.50,76.75,77.00,7048800,8.80
    -1987-05-08,80.50,81.00,79.00,79.00,6618400,9.01
    -1987-05-07,79.75,81.00,79.75,80.25,6488800,9.16
    -1987-05-06,80.50,82.25,79.25,80.00,10240000,9.13
    -1987-05-05,80.00,80.75,78.00,80.25,8240000,9.16
    -1987-05-04,79.50,80.25,79.00,79.75,5095200,9.10
    -1987-05-01,79.50,80.00,78.75,80.00,4751200,9.13
    -1987-04-30,78.00,80.00,77.75,79.25,9040000,9.04
    -1987-04-29,77.25,79.75,77.00,77.75,10400000,8.87
    -1987-04-28,75.75,77.87,75.50,77.00,11600000,8.79
    -1987-04-27,74.25,75.25,73.25,75.00,13680000,8.56
    -1987-04-24,75.75,76.50,74.50,74.75,9120000,8.53
    -1987-04-23,74.25,77.25,74.25,76.00,10880000,8.67
    -1987-04-22,76.62,77.00,74.00,74.25,14400000,8.47
    -1987-04-21,70.25,75.00,69.50,74.75,15440000,8.53
    -1987-04-20,71.50,72.75,70.75,71.12,5353600,8.12
    -1987-04-16,71.25,73.25,71.00,71.50,12400000,8.16
    -1987-04-15,69.50,71.00,68.75,71.00,12480000,8.10
    -1987-04-14,66.75,69.75,66.50,68.00,14560000,7.76
    -1987-04-13,70.00,70.25,67.50,67.50,5101600,7.70
    -1987-04-10,71.25,71.50,69.75,70.25,7791200,8.02
    -1987-04-09,68.75,71.50,67.75,71.00,8480000,8.10
    -1987-04-08,67.75,70.25,67.50,69.00,8240000,7.87
    -1987-04-07,69.75,70.25,67.75,67.75,9280000,7.73
    -1987-04-06,71.50,72.75,69.25,70.00,10320000,7.99
    -1987-04-03,71.50,71.87,70.25,71.75,19280000,8.19
    -1987-04-02,68.25,71.75,67.00,71.75,27760000,8.19
    -1987-04-01,63.00,67.00,62.38,66.75,7792800,7.62
    -1987-03-31,62.25,64.75,62.25,64.50,9760000,7.36
    -1987-03-30,63.50,64.25,62.25,62.50,9280000,7.13
    -1987-03-27,67.25,67.50,64.75,65.00,4817600,7.42
    -1987-03-26,66.75,67.75,66.50,67.25,5146400,7.67
    -1987-03-25,66.50,67.00,65.25,66.75,9760000,7.62
    -1987-03-24,67.75,68.50,66.25,66.25,9600000,7.56
    -1987-03-23,68.00,68.25,66.25,67.50,8800000,7.70
    -1987-03-20,68.25,69.75,68.25,68.25,12400000,7.79
    -1987-03-19,65.75,68.50,65.50,68.37,7396000,7.80
    -1987-03-18,67.25,67.50,64.75,66.00,10800000,7.53
    -1987-03-17,65.50,68.00,65.00,67.00,8720000,7.65
    -1987-03-16,63.50,65.25,62.50,65.25,8800000,7.45
    -1987-03-13,65.25,66.00,63.50,63.50,7067200,7.25
    -1987-03-12,66.00,66.25,63.63,65.25,10800000,7.45
    -1987-03-11,67.25,68.00,66.25,66.25,7826400,7.56
    -1987-03-10,64.50,66.87,64.50,66.75,8720000,7.62
    -1987-03-09,66.50,66.75,64.50,64.62,9120000,7.37
    -1987-03-06,67.25,68.37,66.75,67.25,6332800,7.67
    -1987-03-05,67.50,69.00,67.25,68.50,12080000,7.82
    -1987-03-04,65.75,68.25,65.37,67.62,16000000,7.72
    -1987-03-03,67.50,68.12,64.75,65.00,15600000,7.42
    -1987-03-02,70.25,70.50,67.00,67.50,14160000,7.70
    -1987-02-27,69.12,71.00,67.75,70.00,14480000,7.99
    -1987-02-26,69.50,71.37,68.00,69.12,17840000,7.89
    -1987-02-25,65.50,69.50,64.62,69.12,16240000,7.89
    -1987-02-24,63.25,66.00,63.13,65.50,12720000,7.47
    -1987-02-23,60.88,64.25,59.63,63.13,12560000,7.20
    -1987-02-20,62.38,62.50,60.63,61.25,6813600,6.99
    -1987-02-19,63.50,63.50,61.75,62.38,11200000,7.12
    -1987-02-18,66.62,67.37,63.38,63.50,16800000,7.25
    -1987-02-17,62.13,66.50,61.88,66.37,14640000,7.57
    -1987-02-13,58.63,62.50,58.00,62.13,18240000,7.09
    -1987-02-12,57.00,59.88,57.00,58.63,25360000,6.69
    -1987-02-11,53.00,56.75,52.75,56.50,12240000,6.45
    -1987-02-10,52.50,52.75,51.63,52.75,5977600,6.02
    -1987-02-09,52.88,53.38,52.25,52.63,5611200,6.01
    -1987-02-06,54.00,54.00,52.88,54.00,10480000,6.16
    -1987-02-05,55.00,55.13,53.13,53.88,12160000,6.15
    -1987-02-04,55.50,55.50,54.38,55.00,7791200,6.28
    -1987-02-03,56.00,56.13,54.75,55.50,6412800,6.33
    -1987-02-02,55.50,56.00,54.25,55.88,8800000,6.38
    -1987-01-30,54.00,55.88,52.63,55.50,14640000,6.33
    -1987-01-29,55.88,57.25,53.38,54.13,19920000,6.18
    -1987-01-28,53.00,55.75,52.13,55.38,14800000,6.32
    -1987-01-27,50.00,53.13,49.88,52.75,13520000,6.02
    -1987-01-26,50.00,50.50,49.50,49.75,12560000,5.68
    -1987-01-23,52.50,53.00,50.25,50.25,16400000,5.73
    -1987-01-22,48.88,52.63,48.50,52.50,16880000,5.99
    -1987-01-21,50.88,51.13,49.00,49.00,19040000,5.59
    -1987-01-20,55.00,55.75,51.50,51.63,27680000,5.89
    -1987-01-19,48.75,53.13,47.88,53.13,12960000,6.06
    -1987-01-16,50.00,50.00,47.75,48.75,14560000,5.56
    -1987-01-15,48.25,51.38,48.00,49.88,19520000,5.69
    -1987-01-14,44.63,48.25,44.50,48.13,18000000,5.49
    -1987-01-13,45.13,45.38,44.63,44.63,7584800,5.09
    -1987-01-12,45.50,45.75,44.75,45.50,8320000,5.19
    -1987-01-09,44.75,45.75,44.38,45.38,8560000,5.18
    -1987-01-08,44.75,45.13,44.50,44.75,10400000,5.11
    -1987-01-07,43.88,44.88,43.63,44.75,15520000,5.11
    -1987-01-06,43.13,44.00,42.63,43.75,11600000,4.99
    -1987-01-05,41.25,43.25,41.00,43.00,8560000,4.91
    -1987-01-02,40.38,41.13,40.13,40.88,4360000,4.66
    -1986-12-31,41.00,41.38,40.38,40.50,4742400,4.62
    -1986-12-30,40.50,41.50,40.38,41.00,5297600,4.68
    -1986-12-29,41.00,41.13,40.25,40.50,4224800,4.62
    -1986-12-26,41.88,41.88,41.00,41.00,3215200,4.68
    -1986-12-24,42.00,42.13,41.63,41.88,3453600,4.78
    -1986-12-23,42.25,42.38,41.88,42.13,8720000,4.81
    -1986-12-22,42.00,42.50,41.75,42.13,5887200,4.81
    -1986-12-19,41.38,42.50,41.38,42.13,7149600,4.81
    -1986-12-18,41.13,41.88,40.75,41.38,6258400,4.72
    -1986-12-17,42.38,42.50,40.88,41.25,5417600,4.71
    -1986-12-16,41.63,42.50,41.63,42.50,5464000,4.85
    -1986-12-15,41.00,41.75,40.38,41.75,7481600,4.76
    -1986-12-12,42.88,43.00,41.25,41.25,6451200,4.71
    -1986-12-11,43.63,43.88,42.63,42.88,8080000,4.89
    -1986-12-10,42.38,43.75,42.00,43.50,8720000,4.96
    -1986-12-09,42.38,42.63,41.13,42.38,10800000,4.84
    -1986-12-08,43.63,43.88,42.38,42.50,12400000,4.85
    -1986-12-05,42.63,43.75,42.50,43.75,9360000,4.99
    -1986-12-04,42.63,42.75,42.00,42.50,9600000,4.85
    -1986-12-03,41.63,43.00,41.50,42.75,12000000,4.88
    -1986-12-02,40.50,41.75,40.00,41.50,13200000,4.74
    -1986-12-01,40.00,40.13,39.13,40.13,12400000,4.58
    -1986-11-28,40.50,40.63,39.63,40.00,7897600,4.56
    -1986-11-26,40.13,41.25,40.00,40.50,18080000,4.62
    -1986-11-25,38.00,40.38,38.00,40.25,30320000,4.59
    -1986-11-24,36.25,38.13,36.00,38.00,13440000,4.34
    -1986-11-21,35.25,36.25,35.13,36.00,10240000,4.11
    -1986-11-20,34.88,35.38,34.88,35.25,10560000,4.02
    -1986-11-19,35.13,35.25,34.50,35.00,10800000,3.99
    -1986-11-18,36.38,36.75,35.13,35.38,6115200,4.04
    -1986-11-17,35.25,37.00,35.00,36.38,5071200,4.15
    -1986-11-14,35.50,35.50,34.88,35.25,4840000,4.02
    -1986-11-13,36.50,36.50,35.50,35.50,4928800,4.05
    -1986-11-12,35.75,36.63,35.63,36.63,4700000,4.18
    -1986-11-11,35.50,35.75,35.25,35.50,1809600,4.05
    -1986-11-10,35.88,35.88,35.13,35.38,3793600,4.04
    -1986-11-07,36.00,36.13,34.88,35.75,5153600,4.08
    -1986-11-06,36.63,36.88,35.75,36.13,11840000,4.12
    -1986-11-05,35.75,37.13,35.50,37.00,22320000,4.22
    -1986-11-04,34.88,35.88,33.88,35.75,8800000,4.08
    -1986-11-03,34.75,35.13,34.63,35.00,5457600,3.99
    -1986-10-31,34.25,34.88,34.25,34.63,4338400,3.95
    -1986-10-30,33.50,34.75,33.38,34.25,10480000,3.91
    -1986-10-29,33.50,33.50,33.13,33.38,3057600,3.81
    -1986-10-28,34.00,34.13,33.00,33.38,5102400,3.81
    -1986-10-27,33.50,34.00,33.25,34.00,5422400,3.88
    -1986-10-24,33.13,33.25,32.75,33.00,2718400,3.77
    -1986-10-23,32.50,33.13,32.50,33.13,4441600,3.78
    -1986-10-22,32.75,32.88,32.25,32.50,3382400,3.71
    -1986-10-21,33.00,33.00,32.63,32.75,4096000,3.74
    -1986-10-20,33.50,33.63,32.88,32.88,5344000,3.75
    -1986-10-17,33.75,34.00,33.38,33.63,5460000,3.84
    -1986-10-16,33.38,33.88,33.25,33.63,4876000,3.84
    -1986-10-15,33.50,33.50,32.75,33.38,7367200,3.81
    -1986-10-14,34.63,35.25,33.75,34.00,7164000,3.88
    -1986-10-13,33.13,34.63,33.00,34.63,3582400,3.95
    -1986-10-10,32.88,33.38,32.38,33.25,2096000,3.79
    -1986-10-09,32.75,33.25,32.63,33.00,2820000,3.77
    -1986-10-08,32.88,33.00,32.25,32.75,4021600,3.74
    -1986-10-07,34.00,34.13,32.88,33.00,4577600,3.77
    -1986-10-06,33.75,34.25,33.63,34.13,3384000,3.89
    -1986-10-03,34.38,34.75,33.38,33.75,4997600,3.85
    -1986-10-02,33.75,34.38,33.50,34.13,3401600,3.89
    -1986-10-01,33.38,34.50,33.38,34.13,4988800,3.89
    -1986-09-30,32.88,33.88,32.63,33.50,6488800,3.82
    -1986-09-29,33.63,33.88,31.62,32.50,7475200,3.71
    -1986-09-26,34.13,34.38,33.88,34.25,2512800,3.91
    -1986-09-25,35.13,35.25,33.63,34.50,6744800,3.94
    -1986-09-24,36.13,36.38,34.00,35.13,6360000,4.01
    -1986-09-23,35.25,36.25,35.13,36.13,12080000,4.12
    -1986-09-22,33.50,35.38,33.50,35.25,8560000,4.02
    -1986-09-19,33.75,33.88,33.25,33.63,4601600,3.84
    -1986-09-18,34.25,34.50,33.75,34.00,3546400,3.88
    -1986-09-17,34.88,35.00,34.25,34.25,4181600,3.91
    -1986-09-16,33.13,35.13,32.50,34.88,8800000,3.98
    -1986-09-15,32.25,33.13,32.00,33.13,7973600,3.78
    -1986-09-12,32.50,32.75,31.75,31.75,8160000,3.62
    -1986-09-11,34.63,34.75,32.50,32.63,4842400,3.72
    -1986-09-10,35.63,35.88,34.75,35.00,2737600,3.99
    -1986-09-09,34.63,36.00,34.63,35.75,5398400,4.08
    -1986-09-08,35.00,35.00,33.63,34.75,4522400,3.97
    -1986-09-05,35.63,35.88,35.00,35.13,3561600,4.01
    -1986-09-04,35.00,35.50,34.75,35.50,7133600,4.05
    -1986-09-03,34.75,34.88,34.13,34.75,4216000,3.97
    -1986-09-02,37.13,37.13,34.75,34.75,8320000,3.97
    -1986-08-29,37.63,38.00,36.88,37.00,4846400,4.22
    -1986-08-28,37.00,38.00,36.88,37.75,7849600,4.31
    -1986-08-27,36.63,37.00,36.25,37.00,5280000,4.22
    -1986-08-26,36.38,36.88,36.38,36.63,4713600,4.18
    -1986-08-25,36.50,36.88,36.38,36.38,4533600,4.15
    -1986-08-22,35.88,36.63,35.88,36.25,4162400,4.14
    -1986-08-21,36.13,36.38,35.75,35.75,6992800,4.08
    -1986-08-20,35.25,36.50,35.25,36.25,6140000,4.14
    -1986-08-19,35.13,35.50,34.63,35.38,4944000,4.04
    -1986-08-18,35.75,35.88,35.00,35.38,5297600,4.04
    -1986-08-15,36.13,36.50,35.63,35.75,4910400,4.08
    -1986-08-14,36.00,37.00,36.00,36.00,8240000,4.11
    -1986-08-13,34.25,36.25,34.25,36.00,16240000,4.11
    -1986-08-12,33.38,34.38,33.38,34.25,8720000,3.91
    -1986-08-11,31.87,33.50,31.75,33.50,6591200,3.82
    -1986-08-08,31.87,32.38,31.62,31.62,3941600,3.61
    -1986-08-07,31.12,32.63,31.12,31.75,6211200,3.62
    -1986-08-06,32.13,32.13,31.00,31.12,6644800,3.55
    -1986-08-05,31.62,32.38,31.50,32.13,4238400,3.67
    -1986-08-04,31.37,31.50,30.62,31.50,4653600,3.59
    -1986-08-01,31.12,31.75,31.12,31.37,5360000,3.58
    -1986-07-31,30.50,31.50,30.50,31.25,10080000,3.57
    -1986-07-30,31.25,31.50,30.00,30.50,9120000,3.48
    -1986-07-29,32.25,32.25,30.75,31.25,21280000,3.57
    -1986-07-28,33.88,34.00,32.25,32.38,8800000,3.69
    -1986-07-25,33.13,34.00,33.00,34.00,7769600,3.88
    -1986-07-24,34.25,34.38,33.00,33.13,5187200,3.78
    -1986-07-23,34.63,34.63,34.13,34.13,6416000,3.89
    -1986-07-22,33.50,34.63,33.25,34.63,8560000,3.95
    -1986-07-21,33.00,33.75,32.75,33.50,8160000,3.82
    -1986-07-18,32.25,32.50,31.25,31.75,11040000,3.62
    -1986-07-17,33.50,33.75,32.13,32.25,8960000,3.68
    -1986-07-16,35.50,35.63,32.75,33.50,19280000,3.82
    -1986-07-15,35.00,35.00,34.25,34.88,10640000,3.98
    -1986-07-14,37.13,37.38,36.25,36.25,8480000,4.14
    -1986-07-11,35.38,37.75,35.25,37.13,8000000,4.24
    -1986-07-10,34.75,35.38,34.63,35.38,7453600,4.04
    -1986-07-09,34.25,34.75,34.00,34.63,13040000,3.95
    -1986-07-08,35.25,35.25,34.13,34.25,9782400,3.91
    -1986-07-07,37.63,37.75,35.38,35.63,6501600,4.07
    -1986-07-03,36.13,37.75,35.63,37.63,6509600,4.29
    -1986-07-02,35.38,36.25,35.38,36.13,5202400,4.12
    -1986-07-01,35.88,36.13,34.75,35.38,3140000,4.04
    -1986-06-30,35.88,36.25,35.75,35.88,2553600,4.09
    -1986-06-27,36.25,36.75,35.50,35.88,1811200,4.09
    -1986-06-26,35.88,36.38,35.50,36.25,4184800,4.14
    -1986-06-25,35.00,36.00,35.00,35.88,4755200,4.09
    -1986-06-24,34.75,35.13,34.38,34.88,5088800,3.98
    -1986-06-23,36.00,36.25,34.63,34.75,4196000,3.97
    -1986-06-20,35.00,36.13,35.00,36.00,5761600,4.11
    -1986-06-19,34.25,35.75,33.88,35.00,12347200,3.99
    -1986-06-18,34.25,34.75,32.50,34.25,15381600,3.91
    -1986-06-17,35.88,36.00,34.00,34.25,7936000,3.91
    -1986-06-16,36.38,36.88,35.63,35.88,6222400,4.09
    -1986-06-13,36.00,36.38,35.25,36.38,5144800,4.15
    -1986-06-12,36.13,36.38,36.00,36.00,4638400,4.11
    -1986-06-11,36.00,36.25,35.50,36.13,6692800,4.12
    -1986-06-10,36.00,36.00,35.13,36.00,8827200,4.11
    -1986-06-09,37.75,37.88,35.88,36.00,8835200,4.11
    -1986-06-06,38.88,38.88,37.50,37.75,6342400,4.31
    -1986-06-05,38.75,39.13,38.50,38.88,5282400,4.44
    -1986-06-04,37.88,38.88,37.75,38.75,10747200,4.42
    -1986-06-03,37.13,38.13,37.13,37.88,11661600,4.32
    -1986-06-02,37.00,37.38,36.75,37.13,7158400,4.24
    -1986-05-30,37.00,37.25,36.50,37.00,4591200,4.22
    -1986-05-29,37.25,37.25,36.50,37.00,3635200,4.22
    -1986-05-28,36.88,37.50,36.75,37.25,7418400,4.25
    -1986-05-27,37.00,37.00,36.38,36.88,3058400,4.21
    -1986-05-23,36.75,37.13,36.38,37.00,5013600,4.22
    -1986-05-22,37.00,37.50,35.75,36.75,7895200,4.19
    -1986-05-21,35.38,37.25,35.00,37.00,12418400,4.22
    -1986-05-20,35.63,35.63,34.25,35.38,8811200,4.04
    -1986-05-19,36.00,36.50,35.50,35.63,7506400,4.07
    -1986-05-16,36.00,36.25,35.13,36.00,11424800,4.11
    -1986-05-15,36.88,37.00,35.63,36.00,7964000,4.11
    -1986-05-14,36.00,37.38,36.00,36.88,17277600,4.21
    -1986-05-13,36.38,36.50,35.25,36.00,16876000,4.11
    -1986-05-12,33.38,36.63,33.25,36.38,14335200,4.15
    -1986-05-09,33.00,33.63,32.75,33.38,7961600,3.81
    -1986-05-08,31.50,33.13,31.50,33.00,8342400,3.77
    -1986-05-07,32.63,32.88,31.25,31.50,7133600,3.59
    -1986-05-06,32.25,33.25,32.25,32.63,7829600,3.72
    -1986-05-05,30.50,32.50,30.50,32.13,5364000,3.67
    -1986-05-02,30.25,31.00,30.12,30.50,3377600,3.48
    -1986-05-01,30.25,30.25,29.75,30.25,9218400,3.45
    -1986-04-30,31.25,31.62,30.25,30.25,4944000,3.45
    -1986-04-29,32.00,32.25,26.87,31.25,4750400,3.57
    -1986-04-28,32.25,32.75,31.75,32.00,5241600,3.65
    -1986-04-25,31.37,32.63,31.37,32.25,9348800,3.68
    -1986-04-24,29.62,31.50,29.50,31.37,16398400,3.58
    -1986-04-23,29.87,30.37,29.37,29.62,9371200,3.38
    -1986-04-22,30.37,31.25,29.62,29.87,11726400,3.41
    -1986-04-21,29.87,30.75,29.87,30.37,9775200,3.47
    -1986-04-18,29.00,29.87,28.75,29.75,8871200,3.39
    -1986-04-17,28.25,29.12,28.00,29.00,9672800,3.31
    -1986-04-16,27.37,28.50,27.37,28.25,7535200,3.22
    -1986-04-15,26.87,27.50,26.87,27.37,4722400,3.12
    -1986-04-14,27.00,27.25,26.75,26.87,3076000,3.07
    -1986-04-11,27.25,27.50,27.00,27.00,2737600,3.08
    -1986-04-10,27.12,27.37,26.87,27.25,3932800,3.11
    -1986-04-09,27.62,27.75,26.87,27.12,4851200,3.09
    -1986-04-08,27.25,27.75,27.25,27.62,6912800,3.15
    -1986-04-07,26.75,27.50,26.25,27.25,4318400,3.11
    -1986-04-04,27.00,27.00,26.62,26.75,4508800,3.05
    -1986-04-03,27.25,27.62,26.87,27.00,7548800,3.08
    -1986-04-02,27.25,27.37,26.25,27.25,11627200,3.11
    -1986-04-01,28.25,28.25,27.00,27.25,7973600,3.11
    -1986-03-31,28.25,28.50,28.00,28.25,6744800,3.22
    -1986-03-27,28.25,29.00,28.25,28.25,7856000,3.22
    -1986-03-26,27.87,28.75,27.87,28.25,7941600,3.22
    -1986-03-25,26.75,27.87,26.75,27.87,10060000,3.18
    -1986-03-24,27.62,27.62,26.37,26.75,10528800,3.05
    -1986-03-21,28.25,28.75,27.50,27.62,9309600,3.15
    -1986-03-20,28.00,29.62,28.00,28.25,32318400,3.22
    -1986-03-19,26.87,27.25,26.37,26.50,6816000,3.02
    -1986-03-18,26.00,27.25,25.87,26.87,8920000,3.07
    -1986-03-17,26.00,26.00,25.37,26.00,4240000,2.97
    -1986-03-14,24.75,26.25,24.75,26.12,13781600,2.98
    -1986-03-13,24.75,25.00,24.37,24.75,4176000,2.82
    -1986-03-12,24.87,25.12,24.75,24.75,3071200,2.82
    -1986-03-11,24.62,24.87,24.50,24.87,3681600,2.84
    -1986-03-10,24.75,24.87,24.62,24.62,2727200,2.81
    -1986-03-07,25.37,25.37,24.75,24.75,3477600,2.82
    -1986-03-06,25.25,25.75,25.12,25.37,3630400,2.89
    -1986-03-05,24.62,25.50,24.25,25.25,6324000,2.88
    -1986-03-04,24.62,25.00,24.50,24.62,3217600,2.81
    -1986-03-03,25.00,25.12,24.50,24.62,3912800,2.81
    -1986-02-28,25.62,25.87,24.87,25.00,4507200,2.85
    -1986-02-27,26.00,26.12,25.50,25.62,3873600,2.92
    -1986-02-26,26.37,26.75,26.00,26.00,5907200,2.97
    -1986-02-25,25.75,26.37,25.12,26.37,8041600,3.01
    -1986-02-24,25.25,25.75,25.00,25.75,8840000,2.94
    -1986-02-21,25.12,25.75,25.12,25.25,6771200,2.88
    -1986-02-20,25.00,25.37,24.87,25.12,4951200,2.87
    -1986-02-19,23.87,25.50,23.87,25.00,12871200,2.85
    -1986-02-18,23.75,24.00,23.25,23.87,5295200,2.72
    -1986-02-14,23.87,24.12,23.75,23.75,4928800,2.71
    -1986-02-13,24.00,24.00,23.75,23.87,3944000,2.72
    -1986-02-12,23.87,24.00,23.75,24.00,4770400,2.74
    -1986-02-11,23.87,24.00,23.50,23.87,5504000,2.72
    -1986-02-10,24.00,24.50,23.75,23.87,4036000,2.72
    -1986-02-07,24.12,24.12,23.50,24.00,4656000,2.74
    -1986-02-06,23.75,24.25,23.62,24.12,4835200,2.75
    -1986-02-05,23.75,23.87,23.50,23.75,7042400,2.71
    -1986-02-04,23.87,24.37,23.75,23.75,9298400,2.71
    -1986-02-03,23.12,24.00,22.87,23.87,12512800,2.72
    -1986-01-31,23.00,23.25,22.87,23.12,5317600,2.64
    -1986-01-30,23.50,23.50,22.87,23.00,8493600,2.62
    -1986-01-29,22.25,24.37,22.00,23.62,21064800,2.70
    -1986-01-28,22.12,22.37,22.00,22.25,7949600,2.54
    -1986-01-27,22.62,22.75,22.00,22.12,13955200,2.52
    -1986-01-24,23.00,23.37,22.62,22.62,4044000,2.58
    -1986-01-23,23.37,23.50,22.75,23.00,5624000,2.62
    -1986-01-22,24.00,24.12,22.37,23.37,5144800,2.67
    -1986-01-21,23.87,24.12,23.75,24.00,5464800,2.74
    -1986-01-20,24.00,24.00,23.37,23.87,4590400,2.72
    -1986-01-17,24.50,24.75,23.87,24.00,12344000,2.74
    -1986-01-16,23.87,24.75,23.87,24.50,19132800,2.80
    -1986-01-15,23.25,24.00,23.12,23.87,15126400,2.72
    -1986-01-14,23.00,23.75,22.50,23.25,9772800,2.65
    -1986-01-13,22.75,23.12,22.50,23.00,7701600,2.62
    -1986-01-10,22.62,23.12,22.62,22.75,5491200,2.60
    -1986-01-09,22.87,23.00,21.87,22.62,16002400,2.58
    -1986-01-08,23.00,23.50,22.75,22.87,21711200,2.61
    -1986-01-07,22.25,23.00,22.12,23.00,16807200,2.62
    -1986-01-06,22.37,22.37,21.87,22.25,6636000,2.54
    -1986-01-03,22.25,22.37,22.12,22.37,8653600,2.55
    -1986-01-02,22.00,22.25,21.75,22.25,4212800,2.54
    -1985-12-31,22.25,22.37,22.00,22.00,3158400,2.51
    -1985-12-30,22.37,22.62,22.12,22.25,3848800,2.54
    -1985-12-27,21.75,22.62,21.75,22.37,4427200,2.55
    -1985-12-26,21.75,22.00,21.62,21.75,1658400,2.48
    -1985-12-24,21.87,22.00,21.62,21.75,2344800,2.48
    -1985-12-23,22.37,22.50,21.62,21.87,5157600,2.50
    -1985-12-20,22.50,22.75,22.25,22.37,7402400,2.55
    -1985-12-19,22.25,22.75,22.12,22.50,9673600,2.57
    -1985-12-18,21.37,22.87,21.37,22.25,20033600,2.54
    -1985-12-17,20.87,21.00,20.37,20.62,3926400,2.35
    -1985-12-16,20.00,21.25,20.00,20.87,10362400,2.38
    -1985-12-13,20.00,20.25,19.75,20.00,8975200,2.28
    -1985-12-12,19.87,20.25,19.87,20.00,4515200,2.28
    -1985-12-11,19.50,20.12,19.50,19.75,8489600,2.25
    -1985-12-10,19.37,19.62,19.25,19.50,7206400,2.23
    -1985-12-09,19.75,20.00,19.25,19.37,5015200,2.21
    -1985-12-06,20.12,20.12,19.62,19.75,2347200,2.25
    -1985-12-05,20.50,20.75,20.00,20.12,4508800,2.30
    -1985-12-04,20.12,20.62,20.12,20.50,5928800,2.34
    -1985-12-03,20.25,20.37,20.00,20.12,5548800,2.30
    -1985-12-02,20.12,20.25,20.00,20.25,3611200,2.31
    -1985-11-29,20.00,20.12,19.87,20.12,3546400,2.30
    -1985-11-27,19.37,20.12,19.25,20.00,6873600,2.28
    -1985-11-26,19.12,19.50,19.00,19.37,5892800,2.21
    -1985-11-25,19.00,19.25,19.00,19.12,3488800,2.18
    -1985-11-22,19.00,19.25,18.87,19.00,4620000,2.17
    -1985-11-21,19.00,19.25,19.00,19.00,3720000,2.17
    -1985-11-20,19.25,19.37,19.00,19.00,3548800,2.17
    -1985-11-19,19.87,20.00,19.25,19.25,3373600,2.20
    -1985-11-18,19.87,20.00,19.87,19.87,2342400,2.27
    -1985-11-15,20.00,20.25,19.87,19.87,2932800,2.27
    -1985-11-14,20.00,20.12,20.00,20.00,4995200,2.28
    -1985-11-13,19.87,19.87,19.37,19.37,3642400,2.21
    -1985-11-12,20.00,20.25,19.87,19.87,6224800,2.27
    -1985-11-11,20.50,20.75,20.00,20.00,6421600,2.28
    -1985-11-08,20.50,20.75,20.50,20.50,10517600,2.34
    -1985-11-07,19.62,19.87,19.62,19.62,11352800,2.24
    -1985-11-06,19.25,19.37,19.25,19.25,7181600,2.20
    -1985-11-05,18.75,19.12,18.62,18.62,3841600,2.12
    -1985-11-04,18.75,19.12,18.75,18.75,5584800,2.14
    -1985-11-01,18.62,19.00,18.62,18.62,3320000,2.12
    -1985-10-31,19.00,19.25,18.62,18.62,5548800,2.12
    -1985-10-30,19.00,19.00,19.00,19.00,8098400,2.17
    -1985-10-29,18.00,18.00,17.87,17.87,4693600,2.04
    -1985-10-28,18.00,18.12,18.00,18.00,2148800,2.05
    -1985-10-25,18.37,18.37,18.00,18.00,2271200,2.05
    -1985-10-24,18.37,18.87,18.37,18.37,9768800,2.10
    -1985-10-23,18.00,18.50,18.00,18.00,5309600,2.05
    -1985-10-22,18.00,18.25,18.00,18.00,15186400,2.05
    -1985-10-21,17.75,17.75,17.25,17.25,4248800,1.97
    -1985-10-18,18.25,18.37,17.75,17.75,8268800,2.03
    -1985-10-17,18.25,19.12,18.25,18.25,12455200,2.08
    -1985-10-16,18.00,18.12,18.00,18.00,10336000,2.05
    -1985-10-15,17.00,17.12,17.00,17.00,10504800,1.94
    -1985-10-14,16.62,16.62,16.62,16.62,5555200,1.90
    -1985-10-11,16.00,16.25,16.00,16.00,4261600,1.83
    -1985-10-10,15.88,16.00,15.88,15.88,9386400,1.81
    -1985-10-09,15.13,15.25,15.00,15.00,3001600,1.71
    -1985-10-08,15.13,15.13,15.13,15.13,3144000,1.73
    -1985-10-07,15.00,15.25,15.00,15.00,3284800,1.71
    -1985-10-04,15.50,15.50,15.00,15.00,2484800,1.71
    -1985-10-03,15.63,15.63,15.50,15.50,1784800,1.77
    -1985-10-02,15.75,15.88,15.63,15.63,795200,1.78
    -1985-10-01,15.75,15.88,15.75,15.75,3175200,1.80
    -1985-09-30,15.88,16.00,15.75,15.75,1324800,1.80
    -1985-09-27,15.88,16.00,15.88,15.88,250400,1.81
    -1985-09-26,15.88,16.00,15.88,15.88,1949600,1.81
    -1985-09-25,16.50,16.50,15.88,15.88,3761600,1.81
    -1985-09-24,16.87,17.25,16.50,16.50,3161600,1.88
    -1985-09-23,16.87,17.12,16.87,16.87,4277600,1.92
    -1985-09-20,17.00,17.12,16.75,16.75,4846400,1.91
    -1985-09-19,17.00,17.00,17.00,17.00,6662400,1.94
    -1985-09-18,16.25,16.25,16.25,16.25,4316000,1.85
    -1985-09-17,15.25,15.25,15.25,15.25,6564000,1.74
    -1985-09-16,15.75,15.75,15.25,15.25,1344000,1.74
    -1985-09-13,16.12,16.12,15.75,15.75,2541600,1.80
    -1985-09-12,16.12,16.12,16.12,16.12,3998400,1.84
    -1985-09-11,15.50,15.63,15.50,15.50,3150400,1.77
    -1985-09-10,15.38,15.63,15.38,15.38,4364800,1.75
    -1985-09-09,15.25,15.38,15.25,15.25,4728800,1.74
    -1985-09-06,15.00,15.00,15.00,15.00,3333600,1.71
    -1985-09-05,14.88,15.00,14.88,14.88,1201600,1.70
    -1985-09-04,14.88,15.13,14.88,14.88,1708800,1.70
    -1985-09-03,15.00,15.00,14.75,14.75,1369600,1.68
    -1985-08-30,15.00,15.00,15.00,15.00,1537600,1.71
    -1985-08-29,15.25,15.25,14.88,14.88,2006400,1.70
    -1985-08-28,15.25,15.38,15.25,15.25,1475200,1.74
    -1985-08-27,15.25,15.25,15.25,15.25,1540000,1.74
    -1985-08-26,15.13,15.13,15.13,15.13,1315200,1.73
    -1985-08-23,14.88,15.00,14.75,14.75,1601600,1.68
    -1985-08-22,15.25,15.25,14.88,14.88,4406400,1.70
    -1985-08-21,15.25,15.25,15.25,15.25,2767200,1.74
    -1985-08-20,15.25,15.25,15.25,15.25,2431200,1.74
    -1985-08-19,15.00,15.25,15.00,15.00,1726400,1.71
    -1985-08-16,14.63,14.88,14.63,14.63,3008800,1.67
    -1985-08-15,14.63,14.75,14.50,14.50,3800000,1.65
    -1985-08-14,15.25,15.25,14.63,14.63,10372800,1.67
    -1985-08-13,15.25,15.50,15.25,15.25,1555200,1.74
    -1985-08-12,15.25,15.25,15.00,15.00,1988800,1.71
    -1985-08-09,15.25,15.25,15.25,15.25,2186400,1.74
    -1985-08-08,15.13,15.25,15.13,15.13,5321600,1.73
    -1985-08-07,15.25,16.00,14.88,14.88,5452800,1.70
    -1985-08-06,15.38,15.75,15.25,15.25,2260000,1.74
    -1985-08-05,15.75,15.88,15.38,15.38,3307200,1.75
    -1985-08-02,15.88,15.88,15.75,15.75,3501600,1.80
    -1985-08-01,15.88,16.12,15.88,15.88,1842400,1.81
    -1985-07-31,16.25,16.37,15.88,15.88,2917600,1.81
    -1985-07-30,16.25,16.37,16.25,16.25,3237600,1.85
    -1985-07-29,16.62,16.62,16.00,16.00,2808800,1.83
    -1985-07-26,16.62,16.75,16.62,16.62,4673600,1.90
    -1985-07-25,16.62,16.75,16.62,16.62,11282400,1.90
    -1985-07-24,16.50,16.75,16.25,16.25,6040000,1.85
    -1985-07-23,16.87,17.12,16.50,16.50,6038400,1.88
    -1985-07-22,17.37,17.37,16.87,16.87,6906400,1.92
    -1985-07-19,17.37,17.37,17.37,17.37,4117600,1.98
    -1985-07-18,17.62,17.62,17.25,17.25,6437600,1.97
    -1985-07-17,17.62,17.87,17.62,17.62,4255200,2.01
    -1985-07-16,17.75,17.87,17.50,17.50,5120000,2.00
    -1985-07-15,17.87,18.25,17.75,17.75,2804800,2.03
    -1985-07-12,18.00,18.00,17.87,17.87,1680000,2.04
    -1985-07-11,18.00,18.12,18.00,18.00,2361600,2.05
    -1985-07-10,18.00,18.00,18.00,18.00,3802400,2.05
    -1985-07-09,17.62,17.75,17.62,17.62,5284000,2.01
    -1985-07-08,17.62,17.75,17.62,17.62,3301600,2.01
    -1985-07-05,17.62,17.75,17.62,17.62,1321600,2.01
    -1985-07-03,17.50,17.50,17.50,17.50,2472800,2.00
    -1985-07-02,18.12,18.25,17.25,17.25,2807200,1.97
    -1985-07-01,18.12,18.25,18.12,18.12,3702400,2.07
    -1985-06-28,18.37,18.50,18.00,18.00,4875200,2.05
    -1985-06-27,18.37,18.50,18.37,18.37,6915200,2.10
    -1985-06-26,18.12,18.12,18.12,18.12,4722400,2.07
    -1985-06-25,17.50,17.87,17.50,17.50,10506400,2.00
    -1985-06-24,17.25,17.50,17.25,17.25,7387200,1.97
    -1985-06-21,16.12,16.50,16.12,16.12,5941600,1.84
    -1985-06-20,15.75,15.75,15.75,15.75,6822400,1.80
    -1985-06-19,15.63,15.88,15.63,15.63,6177600,1.78
    -1985-06-18,15.25,15.50,15.25,15.25,9489600,1.74
    -1985-06-17,14.88,15.00,14.88,14.88,8464000,1.70
    -1985-06-14,14.88,15.75,14.75,14.75,20226400,1.68
    -1985-06-13,15.75,15.88,14.88,14.88,13573600,1.70
    -1985-06-12,16.12,16.25,15.75,15.75,8888800,1.80
    -1985-06-11,16.12,16.50,16.12,16.12,10751200,1.84
    -1985-06-10,16.37,16.50,16.12,16.12,11296000,1.84
    -1985-06-07,17.00,17.00,16.37,16.37,16980000,1.87
    -1985-06-06,17.00,17.00,17.00,17.00,9688800,1.94
    -1985-06-05,17.25,17.75,16.87,16.87,10267200,1.92
    -1985-06-04,17.25,17.37,17.25,17.25,14373600,1.97
    -1985-06-03,17.00,17.00,16.00,16.00,20578400,1.83
    -1985-05-31,17.62,18.00,17.37,17.37,13235200,1.98
    -1985-05-30,17.62,17.87,17.62,17.62,11273600,2.01
    -1985-05-29,17.12,17.25,17.12,17.12,8808800,1.95
    -1985-05-28,17.87,17.87,16.87,16.87,18253600,1.92
    -1985-05-24,19.75,19.75,18.12,18.12,21060000,2.07
    -1985-05-23,20.50,20.50,19.75,19.75,8576000,2.25
    -1985-05-22,20.75,20.87,20.62,20.62,4342400,2.35
    -1985-05-21,21.25,21.25,20.75,20.75,5452800,2.37
    -1985-05-20,21.75,22.25,21.37,21.37,7044000,2.44
    -1985-05-17,21.37,22.12,21.25,21.75,7592800,2.48
    -1985-05-16,21.37,22.00,21.37,21.37,8275200,2.44
    -1985-05-15,20.00,20.37,20.00,20.00,4668800,2.28
    -1985-05-14,20.00,20.12,19.75,19.75,4364000,2.25
    -1985-05-13,20.25,20.37,20.00,20.00,3157600,2.28
    -1985-05-10,20.00,20.50,20.00,20.25,4893600,2.31
    -1985-05-09,20.00,20.12,20.00,20.00,4571200,2.28
    -1985-05-08,19.87,19.87,19.87,19.87,5177600,2.27
    -1985-05-07,20.00,20.00,20.00,20.00,3844800,2.28
    -1985-05-06,20.00,20.25,19.75,19.75,2007200,2.25
    -1985-05-03,19.25,20.12,19.25,20.00,5673600,2.28
    -1985-05-02,20.62,20.62,19.25,19.25,11787200,2.20
    -1985-05-01,21.25,21.37,20.87,20.87,2075200,2.38
    -1985-04-30,21.25,21.37,21.25,21.25,3396000,2.42
    -1985-04-29,21.87,22.00,21.12,21.12,2256000,2.41
    -1985-04-26,22.00,22.62,21.87,21.87,4295200,2.50
    -1985-04-25,22.00,22.12,22.00,22.00,3135200,2.51
    -1985-04-24,22.12,22.50,22.00,22.00,2830400,2.51
    -1985-04-23,22.12,22.25,22.12,22.12,4261600,2.52
    -1985-04-22,22.50,22.50,21.62,21.62,3700000,2.47
    -1985-04-19,22.87,22.87,22.37,22.50,3468800,2.57
    -1985-04-18,22.87,23.00,22.87,22.87,7246400,2.61
    -1985-04-17,22.62,22.87,22.62,22.62,4402400,2.58
    -1985-04-16,21.62,21.75,21.62,21.62,2424800,2.47
    -1985-04-15,21.37,21.62,21.37,21.37,2168800,2.44
    -1985-04-12,21.37,21.37,20.75,20.87,2607200,2.38
    -1985-04-11,21.37,22.00,21.37,21.37,5260000,2.44
    -1985-04-10,21.00,21.25,21.00,21.00,8117600,2.40
    -1985-04-09,19.62,19.75,19.62,19.62,9461600,2.24
    -1985-04-08,20.87,21.00,19.62,19.62,7129600,2.24
    -1985-04-04,21.00,21.12,20.62,20.87,5792800,2.38
    -1985-04-03,21.00,21.12,21.00,21.00,8681600,2.40
    -1985-04-02,21.62,21.75,21.00,21.00,8146400,2.40
    -1985-04-01,22.12,22.62,21.62,21.62,4115200,2.47
    -1985-03-29,21.87,22.25,21.87,22.12,3155200,2.52
    -1985-03-28,21.87,22.25,21.87,21.87,4667200,2.50
    -1985-03-27,22.50,22.75,21.87,21.87,4008800,2.50
    -1985-03-26,22.50,22.50,22.50,22.50,4346400,2.57
    -1985-03-25,22.25,22.25,21.62,21.62,3931200,2.47
    -1985-03-22,22.62,23.00,22.25,22.25,2910400,2.54
    -1985-03-21,22.62,23.00,22.62,22.62,5826400,2.58
    -1985-03-20,22.25,22.62,22.25,22.25,14498400,2.54
    -1985-03-19,22.87,23.12,22.00,22.00,6147200,2.51
    -1985-03-18,22.87,23.12,22.87,22.87,4487200,2.61
    -1985-03-15,21.75,23.12,21.62,22.62,6524000,2.58
    -1985-03-14,21.75,21.87,21.75,21.75,8667200,2.48
    -1985-03-13,23.00,23.00,21.75,21.75,8973600,2.48
    -1985-03-12,23.00,23.25,23.00,23.00,7880000,2.62
    -1985-03-11,22.25,22.37,22.25,22.25,10244800,2.54
    -1985-03-08,22.12,22.12,20.75,21.50,16931200,2.45
    -1985-03-07,24.62,24.75,22.12,22.12,26244000,2.52
    -1985-03-06,25.87,25.87,24.62,24.62,6933600,2.81
    -1985-03-05,25.87,25.87,25.87,25.87,4687200,2.95
    -1985-03-04,25.25,26.00,25.25,25.25,5484000,2.88
    -1985-03-01,24.75,24.87,24.00,24.87,8857600,2.84
    -1985-02-28,25.12,25.12,24.75,24.75,11415200,2.82
    -1985-02-27,26.75,26.75,25.12,25.12,14421600,2.87
    -1985-02-26,27.25,27.37,26.75,26.75,6764800,3.05
    -1985-02-25,27.62,27.75,27.25,27.25,3564000,3.11
    -1985-02-22,26.87,27.87,26.87,27.62,8096000,3.15
    -1985-02-21,26.87,27.00,26.87,26.87,11035200,3.07
    -1985-02-20,27.62,27.75,26.37,26.37,7864800,3.01
    -1985-02-19,27.87,27.87,27.62,27.62,5391200,3.15
    -1985-02-15,27.62,28.12,27.37,28.00,6224000,3.19
    -1985-02-14,28.37,28.62,27.62,27.62,15268800,3.15
    -1985-02-13,29.75,29.75,28.37,28.37,18835200,3.24
    -1985-02-12,30.50,30.62,29.75,29.75,8095200,3.39
    -1985-02-11,30.50,30.75,30.50,30.50,12431200,3.48
    -1985-02-08,29.87,30.00,29.50,29.87,4757600,3.41
    -1985-02-07,30.00,30.37,29.87,29.87,8793600,3.41
    -1985-02-06,30.00,30.00,30.00,30.00,6980000,3.42
    -1985-02-05,29.50,30.00,29.50,29.50,6824800,3.37
    -1985-02-04,29.25,29.37,29.25,29.25,7801600,3.34
    -1985-02-01,29.00,29.12,28.37,28.62,4941600,3.27
    -1985-01-31,29.87,30.00,29.00,29.00,9880000,3.31
    -1985-01-30,29.87,30.50,29.87,29.87,17624800,3.41
    -1985-01-29,30.25,30.50,29.87,29.87,8029600,3.41
    -1985-01-28,30.25,30.62,30.25,30.25,14721600,3.45
    -1985-01-25,29.00,29.62,28.37,29.62,11381600,3.38
    -1985-01-24,29.62,29.62,29.00,29.00,14192800,3.31
    -1985-01-23,30.12,30.25,29.62,29.62,15384000,3.38
    -1985-01-22,30.12,30.25,30.12,30.12,15202400,3.44
    -1985-01-21,29.25,29.50,29.25,29.25,11635200,3.34
    -1985-01-18,28.12,29.25,28.00,28.62,12615200,3.27
    -1985-01-17,30.25,30.75,28.12,28.12,19573600,3.21
    -1985-01-16,30.25,30.75,30.25,30.25,6816000,3.45
    -1985-01-15,30.62,31.12,30.00,30.00,9476000,3.42
    -1985-01-14,30.62,30.87,30.62,30.62,9691200,3.49
    -1985-01-11,30.00,30.25,29.50,29.75,7347200,3.39
    -1985-01-10,30.00,30.12,30.00,30.00,9926400,3.42
    -1985-01-09,28.75,29.12,28.75,28.75,5973600,3.28
    -1985-01-08,28.25,28.50,28.00,28.00,5040000,3.19
    -1985-01-07,28.37,28.50,28.25,28.25,6117600,3.22
    -1985-01-04,28.37,28.50,28.00,28.37,4915200,3.24
    -1985-01-03,28.37,29.12,28.37,28.37,5967200,3.24
    -1985-01-02,29.12,29.12,27.87,27.87,6272800,3.18
    -1984-12-31,29.12,29.25,29.12,29.12,7453600,3.32
    -1984-12-28,27.75,28.87,27.62,28.75,5941600,3.28
    -1984-12-27,27.75,27.87,27.75,27.75,3531200,3.17
    -1984-12-26,27.62,27.87,27.62,27.62,2444000,3.15
    -1984-12-24,27.50,27.62,27.50,27.50,2418400,3.14
    -1984-12-21,27.37,27.50,26.75,27.00,4438400,3.08
    -1984-12-20,27.50,28.00,27.37,27.37,5013600,3.12
    -1984-12-19,28.62,28.75,27.50,27.50,11372800,3.14
    -1984-12-18,28.62,28.75,28.62,28.62,12164800,3.27
    -1984-12-17,27.00,27.25,27.00,27.00,4513600,3.08
    -1984-12-14,25.75,26.62,25.75,26.37,3475200,3.01
    -1984-12-13,25.75,26.25,25.75,25.75,2424800,2.94
    -1984-12-12,26.37,26.37,25.50,25.50,3937600,2.91
    -1984-12-11,26.75,27.12,26.37,26.37,4432800,3.01
    -1984-12-10,27.25,27.25,26.75,26.75,4016000,3.05
    -1984-12-07,27.37,28.37,27.12,27.25,17696000,3.11
    -1984-12-06,27.37,27.50,27.37,27.37,11360000,3.12
    -1984-12-05,26.12,26.12,26.12,26.12,9406400,2.98
    -1984-12-04,24.87,25.37,24.87,24.87,4332800,2.84
    -1984-12-03,24.75,24.87,24.37,24.37,3533600,2.78
    -1984-11-30,25.37,25.62,24.62,24.75,3906400,2.82
    -1984-11-29,25.87,25.87,25.37,25.37,6248800,2.89
    -1984-11-28,25.87,26.50,25.87,25.87,14673600,2.95
    -1984-11-27,24.62,24.87,24.62,24.62,4590400,2.81
    -1984-11-26,24.00,24.00,24.00,24.00,3636000,2.74
    -1984-11-23,23.37,24.12,23.37,23.75,4904800,2.71
    -1984-11-21,23.12,23.25,23.12,23.12,6418400,2.64
    -1984-11-20,22.62,22.75,22.62,22.62,9424800,2.58
    -1984-11-19,23.25,23.37,21.87,21.87,8321600,2.50
    -1984-11-16,23.75,24.12,23.12,23.25,5920000,2.65
    -1984-11-15,23.75,24.00,23.75,23.75,3833600,2.71
    -1984-11-14,23.75,24.00,23.75,23.75,3752800,2.71
    -1984-11-13,24.12,24.62,23.50,23.50,4548800,2.68
    -1984-11-12,24.12,24.25,24.12,24.12,4070400,2.75
    -1984-11-09,24.75,24.87,23.00,23.25,10518400,2.65
    -1984-11-08,25.75,25.75,24.75,24.75,3162400,2.82
    -1984-11-07,26.25,26.37,25.75,25.75,8286400,2.94
    -1984-11-06,26.25,26.37,26.25,26.25,8073600,3.00
    -1984-11-05,24.87,25.37,24.75,24.75,3764800,2.82
    -1984-11-02,25.00,25.12,24.75,24.87,1004800,2.84
    -1984-11-01,25.00,25.25,25.00,25.00,1680000,2.85
    -1984-10-31,25.00,25.25,24.87,24.87,2191200,2.84
    -1984-10-30,25.00,25.25,25.00,25.00,2677600,2.85
    -1984-10-29,24.75,24.87,24.75,24.75,1836000,2.82
    -1984-10-26,25.25,25.25,24.50,24.62,4113600,2.81
    -1984-10-25,26.25,26.25,25.25,25.25,5676000,2.88
    -1984-10-24,26.25,26.50,26.25,26.25,5989600,3.00
    -1984-10-23,26.00,26.25,26.00,26.00,6668800,2.97
    -1984-10-22,25.62,26.00,25.37,25.37,4108800,2.89
    -1984-10-19,25.62,27.37,25.50,25.62,11673600,2.92
    -1984-10-18,25.62,25.75,25.62,25.62,8842400,2.92
    -1984-10-17,24.87,25.00,24.87,24.87,5636000,2.84
    -1984-10-16,24.00,24.12,23.87,23.87,4246400,2.72
    -1984-10-15,24.00,24.25,24.00,24.00,8715200,2.74
    -1984-10-12,23.75,23.87,22.50,22.75,9522400,2.60
    -1984-10-11,23.87,24.50,23.75,23.75,6553600,2.71
    -1984-10-10,24.62,24.62,23.87,23.87,13070400,2.72
    -1984-10-09,24.87,25.00,24.62,24.62,4515200,2.81
    -1984-10-08,24.87,25.00,24.87,24.87,1721600,2.84
    -1984-10-05,25.37,25.37,24.75,24.87,3510400,2.84
    -1984-10-04,25.37,25.62,25.37,25.37,4482400,2.89
    -1984-10-03,25.12,25.50,25.12,25.12,4335200,2.87
    -1984-10-02,24.75,25.62,24.75,24.75,4258400,2.82
    -1984-10-01,25.00,25.00,24.50,24.50,3521600,2.80
    -1984-09-28,25.75,25.75,24.62,25.12,8344800,2.87
    -1984-09-27,25.75,25.87,25.75,25.75,3796000,2.94
    -1984-09-26,26.12,27.25,25.75,25.75,3987200,2.94
    -1984-09-25,26.50,26.50,26.12,26.12,5977600,2.98
    -1984-09-24,26.87,27.00,26.62,26.62,2833600,3.04
    -1984-09-21,27.12,27.87,26.50,26.87,3591200,3.07
    -1984-09-20,27.12,27.37,27.12,27.12,2387200,3.09
    -1984-09-19,27.62,27.87,27.00,27.00,3816000,3.08
    -1984-09-18,28.62,28.87,27.62,27.62,3495200,3.15
    -1984-09-17,28.62,29.00,28.62,28.62,6886400,3.27
    -1984-09-14,27.62,28.50,27.62,27.87,8826400,3.18
    -1984-09-13,27.50,27.62,27.50,27.50,7429600,3.14
    -1984-09-12,26.87,27.00,26.12,26.12,4773600,2.98
    -1984-09-11,26.62,27.37,26.62,26.87,5444000,3.07
    -1984-09-10,26.50,26.62,25.87,26.37,2346400,3.01
    -1984-09-07,26.50,26.87,26.25,26.50,2981600,3.02
    Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/sampledata/aapl.npy and /tmp/dj4q_yDaTz/matplotlib-1.2.0/sampledata/aapl.npy differ
    Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/sampledata/axes_grid/bivariate_normal.npy and /tmp/dj4q_yDaTz/matplotlib-1.2.0/sampledata/axes_grid/bivariate_normal.npy differ
    diff -Nru matplotlib-1.1.1/sampledata/data_x_x2_x3.csv matplotlib-1.2.0/sampledata/data_x_x2_x3.csv
    --- matplotlib-1.1.1/sampledata/data_x_x2_x3.csv	2009-09-06 12:32:28.000000000 +0000
    +++ matplotlib-1.2.0/sampledata/data_x_x2_x3.csv	1970-01-01 00:00:00.000000000 +0000
    @@ -1,11 +0,0 @@
    - 0   0    0
    - 1   1    1
    - 2   4    8
    - 3   9   27
    - 4  16   64
    - 5  25  125
    - 6  36  216
    - 7  49  343
    - 8  64  512
    - 9  81  729
    -10 100 1000
    diff -Nru matplotlib-1.1.1/sampledata/demodata.csv matplotlib-1.2.0/sampledata/demodata.csv
    --- matplotlib-1.1.1/sampledata/demodata.csv	2009-09-06 12:32:28.000000000 +0000
    +++ matplotlib-1.2.0/sampledata/demodata.csv	1970-01-01 00:00:00.000000000 +0000
    @@ -1,11 +0,0 @@
    -clientid,date,weekdays,gains,prices,up
    -0,2008-04-30,Wed,-0.52458192906686452,7791404.0091921333,False
    -1,2008-05-01,Thu,0.076191536201738269,3167180.7366340165,True
    -2,2008-05-02,Fri,-0.86850970062880861,9589766.9613829032,False
    -3,2008-05-03,Sat,-0.42701083852713395,8949415.1867596991,False
    -4,2008-05-04,Sun,0.2532553652693274,937163.44375252665,True
    -5,2008-05-05,Mon,-0.68151636911081892,949579.88022264629,False
    -6,2008-05-06,Tue,0.0071911579626532168,7268426.906552773,True
    -7,2008-05-07,Wed,0.67449747200412147,7517014.782897247,True
    -8,2008-05-08,Thu,-1.1841008656818983,1920959.5423492221,False
    -9,2008-05-09,Fri,-1.5803692595811152,8456240.6198725495,False
    Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/sampledata/eeg.dat and /tmp/dj4q_yDaTz/matplotlib-1.2.0/sampledata/eeg.dat differ
    diff -Nru matplotlib-1.1.1/sampledata/embedding_in_wx3.xrc matplotlib-1.2.0/sampledata/embedding_in_wx3.xrc
    --- matplotlib-1.1.1/sampledata/embedding_in_wx3.xrc	2009-09-06 12:32:28.000000000 +0000
    +++ matplotlib-1.2.0/sampledata/embedding_in_wx3.xrc	1970-01-01 00:00:00.000000000 +0000
    @@ -1,65 +0,0 @@
    -
    -
    -  
    -    embedding_in_wx3
    -    
    -      
    -        wxVERTICAL
    -        
    -          
    -            
    -            
    -          
    -          
    -          wxALL|wxEXPAND
    -          5
    -        
    -        
    -          
    -            wxHORIZONTAL
    -            
    -              
    -                
    -              
    -              
    -              wxALL|wxEXPAND
    -              2
    -            
    -            
    -              
    -                
    -              
    -              
    -              wxALL|wxEXPAND
    -              2
    -            
    -            
    -              
    -                
    -                
    -              
    -              
    -              wxALL|wxEXPAND
    -              2
    -            
    -            
    -              
    -                0
    -              
    -              
    -              wxEXPAND
    -            
    -          
    -          
    -          wxLEFT|wxRIGHT|wxEXPAND
    -          5
    -        
    -        
    -          
    -          
    -          wxEXPAND
    -        
    -      
    -    
    -  
    -
    \ No newline at end of file
    Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/sampledata/goog.npy and /tmp/dj4q_yDaTz/matplotlib-1.2.0/sampledata/goog.npy differ
    Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/sampledata/lena.jpg and /tmp/dj4q_yDaTz/matplotlib-1.2.0/sampledata/lena.jpg differ
    Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/sampledata/lena.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/sampledata/lena.png differ
    Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/sampledata/logo2.png and /tmp/dj4q_yDaTz/matplotlib-1.2.0/sampledata/logo2.png differ
    diff -Nru matplotlib-1.1.1/sampledata/membrane.dat matplotlib-1.2.0/sampledata/membrane.dat
    --- matplotlib-1.1.1/sampledata/membrane.dat	2009-09-06 12:32:28.000000000 +0000
    +++ matplotlib-1.2.0/sampledata/membrane.dat	1970-01-01 00:00:00.000000000 +0000
    @@ -1,64 +0,0 @@
    -**+**:,:,:,*++*+*Z***Z*Z**:,:,)Z*Z****+:,:,*+*++++++**+++**+Z***++*+++***Z*Z**+Z*++Z***++++:,:,+++Z*)+**:,++Z*:,:,Z******:,+***+++**+:,:,*+++**+**++++***Z*Z*+++++Z*++***:,**:,,,+:,:,+*:,+++Z*Z**++Z***Z*Z*Z**+Z*Z*Z*+++:,**+*+++)**:,*****Z*Z*Z*Z***Z*Z*++++++Z***:,*:,:,,*Z*Z*Z*++*****))++**+**Z*++****+++++***++)Z*Z*:,*****Z*Z**Z*Z*++++***,,+**:,*+++Z*Z*Z****+***Z*Z*Z*+*Z*Z*++++:,:,++++:,:,+Z*+++)***)),*****Z*Z**:,:,+++:,+***,+++++Z***+Z*Z****Z**)Z*Z*Z*Z*Z*:,**+++*++**:,**,**+**Z*********+*+Z*+:,++*++:,**++++**:,)Z**+Z*Z*Z*Z***Z*******:,:,*+:,***Z*Z****++++Z****Z***Z*Z*Z*+:,:,Z*Z*Z*Z*Z*+**+++:,++++:,+*+:,:,Z*Z*Z****+**Z*Z*Z*+++*++Z*Z*++++:,:,******:,***Z**Z*Z**))*+++++*+****+++++Z*++**Z*++Z****))*Z*Z**Z*Z*++Z***:,***:,:,***Z*:,+*:,*Z*Z*+++****))+Z*Z**++Z***+++++*++Z*++***+Z*)*+Z*Z*Z*+**+***++*:,:,*Z**+++*****Z***+**:,*Z*Z*Z*Z*))*++*++)**+++*Z*Z*++Z*++*))+**Z*Z*Z*Z***Z*Z*Z*+*:,Z***:,:,Z***+Z*Z*+++***Z***Z**+Z*Z*)++Z*Z*Z*+**++++++:,++Z*Z**++***)***Z*Z****+***Z*+***Z*Z*:,:,Z**:,+++:,:,:,Z******Z*Z*Z**Z*Z*:,:,)Z*Z*:,Z*Z*+++*+++***++**Z*++Z*Z*Z*+Z*Z**:,:,***+++Z*Z*+++*++*Z*Z*******Z**Z*Z**Z*Z*Z*Z***+***++)**:,**+++***++*Z*Z**Z*)Z*:,Z*))*++*+++**Z*++*********)))*****Z*Z**Z********Z*++)**+Z****:,***++*))+++Z*:,*))*++Z*++***Z*:,:,*Z**:,:,+**Z*))+*Z*++***Z*Z*Z**)):,**+++`%VZ%8z#$:"z\\*8	vXvX:&X/[[nnモ.C.C.ݾ˭ܾ˭ܾgm־+ҾmѾmѾξwlǾwlǾwlǾ'l¾,,뫾뿾뿾kkk뫾뫾뫾뫾,,,'l¾c,ƾwlǾwlǾwlǾɾɾ,˾l̾l̾mѾ-о-о+Ҿ?Ӿ?ӾS-վgm־gm־{׾{׾{׾ؾ-ھ˭ܾm۾m۾ݾݾݾ˭ܾ-߾-߾n-߾ݾn/WnWn///C.////C.C.-߾nnn/nn-߾nnnn˭ܾ˭ܾݾn˭ܾ˭ܾݾݾ-ھ-ھ-ھ{׾{׾ؾS-վS-վgm־ؾؾ+Ҿ+Ҿ+Ҿ+ҾmѾmѾξ-о۬;۬;۬;-оl̾l̾l̾,˾,˾ɾ,˾,˾ɾɾɾȾȾȾc,ƾc,ƾwlǾwlǾwlǾOľOľOľc,ƾOľOľOľOľOľOľwlǾOľwlǾɾwlǾwlǾwlǾ,˾ɾɾ,˾,˾,˾ɾl̾l̾ɾɾl̾,˾,˾۬;۬;۬;۬;-о-оmѾ-о-о+Ҿ-о-о+ҾS-վS-վS-վgm־gm־gm־S-վ{׾ؾؾ{׾{׾{׾{׾˭ܾ˭ܾm۾m۾m۾-ھؾؾm۾m۾ؾm۾m۾m۾-ھm۾˭ܾm۾m۾m۾m۾m۾˭ܾ˭ܾ˭ܾ-ھm۾m۾-ھؾ-ھ˭ܾؾؾؾؾgm־gm־gm־gm־gm־gm־gm־?Ӿ?Ӿ?ӾmѾmѾξmѾmѾ۬;۬;۬;-оl̾l̾,˾,˾wlǾɾɾc,ƾwlǾwlǾc,ƾ'l¾'l¾;þ,뿾,,kkkkkk뺾뺾뺾kks+_뵾_뵾_뵾s+_뵾_뵾#+_뵾_뵾7k7k7kkKKs+_뵾s+7k7k_뵾kkk뺾뺾k뺾뺾k뫾뫾뫾,;þwlǾwlǾc,ƾwlǾwlǾȾȾȾ,˾l̾l̾l̾,˾,˾-о-оξ-о-о+Ҿ-о-о?Ӿ?Ӿ?ӾS-վS-վS-վS-վgm־gm־gm־ؾؾ{׾{׾-ھؾؾؾ-ھ-ھ-ھ{׾{׾-ھ-ھ-ھ-ھ{׾{׾gm־ؾ{׾gm־gm־gm־gm־gm־?Ӿ?Ӿ?Ӿ+Ҿ+ҾmѾξξ-о+Ҿ+Ҿ۬;ξξl̾ɾɾȾ,˾,˾wlǾOľOľc,ƾ'l¾'l¾뿾뿾뿾++kkks+s+7k#+#+7k7k7kjjj*꫾꫾j[[Gj[꡾꡾i霾霾闾WiWighM]M]9ii]U]U*c,ƾ-ھk3//bvXvX8	8	x
    -x
    -x
    -x
    -	8	x
    -x
    -llvXllNbbXxXxN:::&X&X&X&Xxxo//o//o[3/nn𾻮羓.龓.龓.C.C.knnݾݾm۾-ھ-ھؾgm־gm־S-վ+Ҿ+Ҿ-оmѾξ,˾ɾɾɾc,ƾc,ƾc,ƾc,ƾ'l¾,,뿾kk뺾K7k7k7k**꫾*[[3*꡾꡾霾ikWi/钾((_ɊɊmFgh*;þ;þWn../NNNvXvXvXbbllllbllNNND8D8D8::x&X/oooGooo[GoGoGo...n꾻뾻뾻kkk-߾n˭ܾm۾m۾-ھ-ھ-ھ?ӾS-վS-վmѾmѾmѾξξξl̾,˾ɾwlǾwlǾ;þc,ƾc,ƾ,뫾뫾뫾++kkk7k7k#+#+#+j**j**3*[iiC){}}
    -)))HH荾*;þS-վS-վn[[:D8D80NNN::D8::00&X&Xxxo///o[[oGoGoGoGo3/3/.쾧n꾧n꾧nkkC.C.C.n-߾˭ܾ˭ܾm۾-ھ-ھ-ھgm־gm־{׾gm־gm־+Ҿ?ӾmѾξξ۬;,˾,˾ȾɾɾwlǾc,ƾc,ƾ,뿾뿾+뺾s+_뵾_뵾_뵾#+밾밾jjj[霾霾霾闾闾/钾/钾+NlNl	q
    -Wq
    -W
    -
    -Wi7k7k˭ܾknGoo&X&X&X&Xxxxo/oo[ooGoGo3/3/3/nn..n꾓.龓.龧nkkkWnWnnC./nn-߾-߾-߾˭ܾm۾m۾ؾؾؾS-վgm־gm־S-վ-о-о-оmѾmѾ,˾۬;,˾,˾ɾɾc,ƾc,ƾOľ'l¾'l¾k,,뺾뺾kKK7k밾jjoꦾ[[꡾))霾(˨?胾=sMX			OqOqkl̾l̾knnᆱ/xoooooo///oo[oo3/3/3/3/n.nnᄏ쾧n꾓.龓.龓.羓.龓.龓.C.C.Wn-߾-߾ݾ-߾-߾ݾ˭ܾ˭ܾ˭ܾ-ھ-ھ-ھ{׾{׾{׾gm־+Ҿ+Ҿ+Ҿ?ӾmѾmѾmѾξξ,˾l̾l̾ɾwlǾwlǾOľ;þ'l¾;þ,뫾뫾뫾뺾뺾뺾k7k7k_뵾#+#+밾꫾꫾꫾*GjGj[ii霾C)iiS(hnELD)a
    -
    --2-2oꦾ뿾+Ҿnྒྷ.GoGo/o//ooo/oooooGo3/3/[..n𾻮쾓.龧n꾧n꾧nkkWnkk/ݾݾnݾݾݾݾ˭ܾm۾m۾m۾-ھ-ھ{׾ؾؾ{׾gm־gm־?Ӿ?Ӿ?ӾmѾ-о-оmѾ-о۬;ξξ۬;,˾,˾wlǾȾȾc,ƾc,ƾc,ƾ;þ;þ;þ뿾뿾k++뺾뺾_뵾s+s+#+밾밾밾*oꦾ**iii)闾闾C)((gh}}<޽9a	qK0K0oꦾ뿾뿾ݾkk[[ooooo[[[oGoGoGon.쾻뾻뾻뾧nkkWnWnWnWn//C.nnnྷm۾˭ܾ˭ܾ˭ܾ˭ܾ˭ܾ-ھm۾-ھgm־ؾ{׾{׾{׾{׾gm־gm־S-վ+Ҿ+Ҿ+Ҿ?Ӿ?Ӿξξξξξ۬;۬;۬;,˾,˾,˾wlǾwlǾwlǾwlǾOľOľ'l¾Oľ뿾,,k뿾뿾kkK7k7k7k밾밾j꫾꫾j3*Gj[[i))iC)C)荾荾}eOveOv%Iىى!k5HZ/钾7kɾɾᾓ.龓.Go[[oooo///GoGoGoGo3/nnnᄏ뾓.龓.龓.龓.龓.WnWnC.Wn///n-߾-߾-߾ݾݾ˭ܾ˭ܾ˭ܾ-ھ-ھ-ھ-ھ-ھؾ{׾{׾ؾ{׾{׾?Ӿgm־S-վ?Ӿ?ӾmѾS-վS-վmѾmѾmѾξ۬;۬;l̾l̾l̾l̾ɾɾɾɾwlǾc,ƾc,ƾc,ƾOľOľ'l¾c,ƾc,ƾ뿾뫾뫾뺾뺾뺾+뺾kk_뵾_뵾#+밾밾*꫾꫾꫾jGjGj꡾3*iiiiC)/钾/钾(S(S(uNgK?MM
    -ɊɊeOviil̾ؾؾn..Goo[//[GoGoo3/3/Go3/񾻮뾻뾧n꾻뾻뾓.龓.龓.WnWnC.nC.-߾-߾ᾷm۾ݾݾ˭ܾؾؾm۾m۾m۾-ھؾؾؾgm־ؾS-վS-վgm־S-վS-վS-վgm־gm־-оmѾmѾ-о-о-оξ۬;۬;l̾l̾,˾ɾɾɾc,ƾc,ƾȾwlǾwlǾwlǾȾȾ;þ;þOľ뫾'l¾'l¾,,뫾뫾뫾뺾뺾뺾k_뵾_뵾_뵾#+#+#+밾꫾꫾꫾꫾jjoꦾ[[꡾)闾/钾荾舾舾eOv__)qϽAhh,mѾmѾC.侧n꾧n3/3//[[/o3/3/3/[n쾻뾻뾧n꾧n꾧nk澓.///WnWn-߾ݾݾݾݾm۾ݾ-ھؾ-ھ-ھؾؾؾ{׾{׾{׾{׾{׾{׾mѾmѾmѾ+Ҿ-о-оmѾmѾξ۬;۬;l̾l̾l̾l̾ɾɾl̾ȾȾȾ,˾,˾c,ƾwlǾȾOľ;þ;þOľOľ뿾'l¾'l¾뫾뫾뫾kk뺾kkk#+#+#+K밾밾jj꫾jj*[꡾3*i/钾WiWi{ghgheOvMXMɊ	K:舾舾,-о-оk澧n꾧nGo3/3/3/ooo[[[...뾧n꾧n꾧nWnkkkC.C.C.WnC.C./ݾ-߾m۾ݾ˭ܾm۾-ھ-ھm۾m۾m۾S-վ{׾{׾?Ӿgm־gm־S-վ+Ҿ+Ҿ+Ҿ+Ҿ+Ҿ-о-о-оξξ-о۬;۬;۬;۬;۬;l̾۬;l̾ɾɾɾɾɾwlǾwlǾwlǾ;þ;þ;þ;þ;þ;þ,뿾뿾뿾kk++뺾s+s+k_뵾_뵾7k밾밾밾꫾jjoꦾoꦾGj3*3*霾C)C)(˨˨+O{O{UK5ٽ
    -/A4A4)II){׾//nn3/GoGoGo3/3/3/nnn쾻쾧n꾧n꾧nkkkC.C.C.-߾ݾݾ˭ܾm۾m۾m۾m۾m۾ؾؾ-ھgm־gm־{׾{׾{׾S-վgm־gm־S-վ?Ӿ?Ӿ+Ҿ?Ӿ?ӾmѾ۬;۬;mѾ-оξ۬;ξl̾,˾,˾ɾ,˾,˾ɾɾɾȾwlǾwlǾ;þOľOľ;þ'l¾'l¾;þ;þ뿾,,kkkk++s+s+s+K7k밾#+꫾꫾****oꦾoꦾGjii)霾霾闾/钾/钾(S(hxM]	iK0K0+۬;-ھn.Go3/3/GoGo3/Go񾻮쾻뾧n꾻WnWnWn/C.C.-߾nn-߾˭ܾ˭ܾݾݾݾ-ھ-ھ-ھؾ-ھ-ھgm־gm־{׾{׾{׾S-վS-վS-վ+Ҿ+Ҿ+Ҿ?Ӿ-о-оmѾmѾmѾξ۬;۬;۬;l̾l̾,˾ɾ,˾ȾȾ,˾ȾȾwlǾwlǾwlǾ;þOľOľOľOľOľ;þ;þ'l¾,,뫾kk뺾뺾뺾s+s+KKK#+#+꫾jjjoꦾoꦾGj3*3*i霾霾i闾/钾i(hS(S(iLILIQua	a	9))(**mѾm۾C.侻n3/GoGo[3/3/3/..뾻뾻뾻뾓.龓.龓.龓.WnWnWn/nn/nn-߾-߾-߾ݾ˭ܾ˭ܾ˭ܾ-ھ-ھ-ھ-ھؾؾ{׾gm־gm־-оS-վS-վS-վmѾ+Ҿ+Ҿ-оmѾ-о-оξξξξl̾l̾ξl̾l̾l̾l̾,˾ɾɾɾȾȾwlǾȾȾ;þOľOľ,'l¾'l¾뿾뫾뫾뿾뺾k++k_뵾_뵾_뵾KK밾밾***oꦾ[oꦾGj3*)闾闾kii˨S(S(eOvMdMdʽ
    -/!INlNlKɾɾ-߾kk.nnGo3/3/3/쾻뾻뾻쾓.kkkWnC./C.nnnnݾݾ˭ܾؾ-ھ˭ܾ˭ܾؾ-ھ-ھ-ھ{׾{׾{׾?Ӿ?Ӿ?Ӿgm־?Ӿ+Ҿ+ҾS-վmѾmѾ+Ҿ-о-о-оmѾmѾ۬;۬;۬;ξ,˾,˾,˾,˾ɾɾɾwlǾɾɾc,ƾOľOľc,ƾ;þ;þ;þ;þ,뿾뿾,뫾뫾k++뺾s+_뵾_뵾K7k7k밾***oꦾ**oꦾ꡾iii)闾闾Wi/钾/钾(ghgheOvM]=#	Q
    -%!!=s=ss+ȾȾ˭ܾkk3/3/3/3/쾻뾻뾻뾧n꾧nkkkWnC.C.Wn/n-߾-߾nݾݾ˭ܾݾݾm۾-ھ-ھ-ھؾ-ھ{׾{׾{׾gm־gm־gm־{׾{׾S-վ?Ӿ?Ӿ?Ӿ+ҾmѾ+ҾmѾ۬;ξξ-оξξl̾l̾l̾,˾ɾȾwlǾȾwlǾc,ƾc,ƾȾc,ƾc,ƾc,ƾwlǾwlǾ'l¾;þ;þ,,,뿾뫾뫾+kkK_뵾_뵾7k밾밾#+#+꫾**[GjGj꡾iiiii(((?胾}ii5HIIp		mF((뿾۬;۬;ᾓ.龧n3/3/3/GoGoGonn...n꾧n羧n꾧nWnkkkC./-߾n-߾-߾-߾-߾m۾m۾ݾ˭ܾ˭ܾ-ھ-ھ-ھ{׾{׾{׾ؾ?Ӿgm־?Ӿ?Ӿ?Ӿ+Ҿ+Ҿ+ҾmѾmѾmѾξξ-о۬;۬;ξξξ۬;l̾۬;,˾,˾,˾l̾l̾wlǾwlǾwlǾwlǾc,ƾOľc,ƾ;þ'l¾'l¾'l¾뿾'l¾'l¾k뺾뺾뫾뺾뺾s+kkKKK7k밾밾**oꦾoꦾ꡾꡾霾)闾kC)i荾荾{}}Za
    -
    -=#=#)s+,˾gm־˭ܾk澻뾻3/3/nnᄃn쾻뾓.龓.羓.龓.WnWnC.C.//n-߾ݾ˭ܾ˭ܾm۾ؾ-ھؾؾ{׾gm־gm־gm־S-վS-վ?Ӿ+Ҿ+ҾS-վ?Ӿ?Ӿ+Ҿ+Ҿ+ҾmѾmѾ+ҾmѾmѾ-о-о-оl̾l̾l̾,˾Ⱦɾɾɾɾc,ƾc,ƾOľOľOľ;þ;þ;þ;þ뿾뿾뫾뫾뫾++뺾_뵾_뵾K7k7k밾7k7k꫾꫾[[GjGj)iiiikii˨舾+xMdK?ََ
    -\ppَ
    -P
    -P*,,˭ܾᾓ.龻뾻3/3/nGoGo.nnn.뾻쾓.龓.龧nWnWnWn/-߾-߾/ݾݾݾ˭ܾ-ھ-ھ-ھؾؾ-ھ-ھm۾-ھ-ھgm־gm־gm־gm־?Ӿ?Ӿgm־+Ҿ+Ҿ+ҾmѾ+ҾmѾmѾ-оl̾l̾ξ۬;۬;l̾l̾l̾,˾ȾȾȾwlǾȾȾc,ƾ;þwlǾwlǾ;þ,,'l¾'l¾'l¾뿾뫾뫾k++k_뵾KK7k7k꫾****oꦾoꦾGj꡾꡾꡾))))Wi荾荾˨{{=sZZ!MNl)KɾɾݾWnWn..Go3/3/GoGoGonnnnnnᄃn꾧nWnWnC.////nn-߾-߾-߾-߾ݾݾ˭ܾ˭ܾ˭ܾm۾ݾݾ{׾{׾{׾{׾gm־ؾgm־{׾?ӾS-վS-վS-վmѾmѾ+Ҿ-о-о+Ҿξξl̾ξ۬;l̾l̾ξl̾l̾,˾,˾,˾ȾȾȾwlǾOľc,ƾc,ƾc,ƾ;þ'l¾'l¾뫾뿾뿾kk뺾kks+kkK_뵾_뵾#+밾밾밾*꫾꫾**[oꦾ3*i闾C)C)˨{{(nnJ+		
    -aHHk#+#+?Ӿ˭ܾ˭ܾnn.3/3/3/3/3/n.nnᄏ뾧n꾧n羧n꾓.龓.WnWnWnWnC./C.nnn˭ܾ˭ܾ˭ܾݾ-ھ-ھ-ھؾ{׾{׾{׾{׾ؾؾgm־?Ӿ?Ӿ?Ӿ?Ӿ?Ӿ?Ӿ?Ӿ+Ҿ+Ҿ+ҾmѾmѾmѾξξξl̾l̾l̾l̾l̾l̾ɾȾȾɾɾc,ƾwlǾwlǾ,'l¾'l¾;þ뿾뿾뿾뫾뫾+kk+kk_뵾K_뵾#+#+밾밾밾꫾*GjGj3*3*3*霾i闾闾/钾(({S(S(NlMXMX)
    -ىeJ&}s+ɾɾnWnWn...3/[[nnnnᄏ...龧n꾧n羓.kkWnWnWnnnnn-߾-߾nݾݾm۾m۾m۾m۾m۾ؾؾؾؾ{׾{׾{׾-ھ-ھ?Ӿgm־gm־gm־+Ҿ?Ӿ?Ӿ?ӾmѾ+Ҿ+ҾmѾξξ۬;l̾l̾۬;,˾,˾l̾ɾɾȾwlǾȾc,ƾOľwlǾwlǾOľ;þ;þ;þ,,,뫾kkkkkKK#+밾jjjjjoꦾGjGj)))ki˨({+xx<ََȻp	َK荾-о-ھ-ھ.Go3/3/nnn.n꾧n꾻뾻뾻뾧nWnkk/C.C.C.-߾//-߾ݾݾݾ-߾-߾ݾm۾m۾˭ܾ-ھ-ھ{׾{׾ؾS-վS-վgm־ؾؾgm־S-վS-վS-վmѾmѾ-о+Ҿ+Ҿ-о۬;۬;-оl̾l̾ξξl̾ɾɾ,˾ɾɾwlǾwlǾwlǾc,ƾ;þ;þ;þOľ'l¾뿾뿾뿾kk뺾뺾s+_뵾KKK#+밾밾**꫾jjoꦾ[[Gj꡾꡾霾kk/钾iigh++Md}7}71CIԽELD(*+l̾l̾WnWn.3/3/3/3/n.뾻Wn///////nnC.nnݾnnྏؾm۾m۾-ھ{׾{׾ؾS-վS-վgm־gm־+Ҿ?ӾS-վ+Ҿ+Ҿ+Ҿ+Ҿ+Ҿ+ҾmѾ?Ӿ?Ӿ۬;-о-оξξl̾l̾l̾l̾,˾,˾ɾɾɾc,ƾOľc,ƾc,ƾc,ƾ,c,ƾc,ƾ뿾뫾뫾k++뺾kks+s+s+KKj#+**jGj3*3*꡾霾霾霾kk/钾hghgh=s_K:ٽٽA4ppٽLILIkk-ھΆnn3/Go...쾻쾻뾧n꾧n꾓.WnWnWnC.////-߾-߾nݾݾ˭ܾm۾m۾˭ܾ˭ܾ˭ܾ-ھ-ھ-ھؾ{׾-ھ-ھgm־S-վؾؾ+ҾS-վS-վS-վ+Ҿ+ҾmѾ-о-оmѾξ۬;-оξl̾,˾,˾ɾȾȾɾȾȾ;þc,ƾc,ƾOľ;þ;þ,,k,,뺾kkkkk7k7kK밾밾jj**[[Gj3*3*)ii闾kkihhS(((M]J+YŽ	ppMMMX'l¾+Ҿ+Ҿn.3/n..nk澻뾻C./WnWn///nn-߾nnݾݾݾݾnnྣ-ھ-ھ-ھ-ھ{׾ؾ{׾ؾ{׾{׾{׾S-վS-վS-վ+ҾmѾmѾ+ҾmѾmѾξξξl̾l̾l̾l̾,˾ɾl̾,˾ɾɾɾc,ƾc,ƾc,ƾOľ'l¾'l¾'l¾'l¾'l¾뿾kk+++kkK_뵾7k#+7k7kjjj*3*3*3*i霾iiiWiWi(˨˨?胾((Zq
    -
    -q
    -W5HMXC)C),mѾmѾC.WnWn3/3/GoGonn..羓.kkWnWnC.C.//nnnnnݾnnྣ-ھ˭ܾ˭ܾ˭ܾ-ھ-ھ-ھؾؾS-վؾؾgm־{׾S-վ+Ҿ+ҾS-վmѾmѾmѾ?Ӿ?Ӿ-о-о-оξξξ۬;۬;,˾ɾɾȾȾȾOľOľOľc,ƾ,,,'l¾'l¾k뫾k뺾kkkK_뵾_뵾7k밾밾jjj*jjjoꦾoꦾ3*꡾i)kWiWi(荾荾S(((%NbK?K?kaiJ++3*,˾,˾nWnWn...n꾧n꾧n꾓.龧n꾧nkkkkWnkkC.nC.C.-߾nnݾݾݾ˭ܾ˭ܾ-ھm۾m۾m۾-ھ-ھgm־{׾{׾{׾S-վS-վؾS-վS-վ?Ӿ?ӾS-վ-о-о+ҾmѾmѾ-о-о-о۬;l̾l̾,˾,˾,˾ȾȾc,ƾwlǾOľ;þ;þ;þ'l¾뿾뿾,뿾뿾+kk+s+_뵾k_뵾#+#+#+꫾*oꦾoꦾ3*)ii))/钾((({{O{%Nb%Nb
    -IIp;!(O{is+s+S-վݾݾ羻뾻nnnnnn.쾓.龧n꾓.kC.C.C.C.nݾݾ-߾-߾˭ܾݾݾ˭ܾؾؾm۾m۾m۾m۾ؾؾ{׾S-վgm־S-վS-վ?Ӿ+Ҿ+Ҿ+Ҿ+Ҿ+Ҿ-оmѾmѾξ۬;۬;ξ,˾,˾,˾l̾,˾ȾȾwlǾwlǾwlǾc,ƾOľOľ;þ;þ;þk뫾뫾뺾뺾_뵾_뵾_뵾밾밾밾꫾jj*oꦾoꦾGjGji霾霾)闾闾ii{?胾?胾iLNyy
    -ȻȻH%Nb%Nbj,,˭ܾk澻뾻nGoGo3/nnn쾧n..羧n꾧n꾓.WnWnWnC.C.WnC./WnWn-߾-߾-߾nnnݾݾݾm۾m۾m۾ؾؾؾ{׾{׾gm־{׾{׾gm־?Ӿ?Ӿ?ӾmѾmѾ+Ҿ+Ҿξ-о-о-о-о-оl̾,˾l̾l̾l̾ȾȾȾȾc,ƾc,ƾ;þ;þ,,,kkk뫾뺾뺾s+s+_뵾s+K#+#+#+jj꫾꫾*oꦾoꦾ꡾꡾i霾k))/钾(({{{=s__
    -kkp;
    -ɊJ+O{s+s++Ҿݾݾ羻뾻n3/3/3/3/3/n..n쾓.龓.龓.龧n꾧n꾧n꾧n꾓.WnWnkk/C.C.nݾ˭ܾ˭ܾ-߾˭ܾ˭ܾ-ھ-ھm۾m۾m۾-ھ-ھ-ھgm־S-վS-վ{׾S-վS-վ?ӾS-վS-վ?Ӿ?ӾmѾmѾmѾmѾ۬;۬;l̾,˾,˾Ⱦ,˾,˾c,ƾȾwlǾOľOľ;þ;þ;þ,,,뫾뫾뫾k뺾+s+_뵾_뵾_뵾#+밾밾#+꫾꫾**Gj3*3*i)闾WiWi(((S(?胾?胾iLILI)p;ȻȻH%Nb%Nbj,,m۾nnྦྷnnn3/.....n쾧n꾻뾻WnWnWnWn/C.C.n-߾-߾-߾ݾݾm۾ݾ˭ܾ-ھ-ھ˭ܾm۾m۾-ھؾؾgm־{׾{׾S-վgm־gm־?Ӿ+Ҿ?Ӿ+Ҿ+Ҿξ-о-оξl̾l̾۬;,˾ɾɾ,˾ȾwlǾwlǾwlǾwlǾwlǾOľ'l¾'l¾'l¾,,k뫾뫾++k밾KKjj꫾꫾꫾joꦾGjGjGjiii霾kk闾WiWihhghhhuNgELDELD
    -\
    -\Qu%IMdMd#+;þ;þ-ھC.C.侓...3/...񾻮뾻쾻뾻뾓.龓.龓.WnkkWnC.C.//-߾nC.n-߾n-߾-߾ݾ-ھ-ھݾ˭ܾ˭ܾm۾ؾؾ{׾gm־gm־{׾ؾgm־+Ҿ?Ӿgm־?Ӿ?ӾmѾmѾmѾξ۬;۬;ξ۬;,˾l̾,˾,˾ɾɾc,ƾȾȾOľ;þ;þ;þ'l¾'l¾뫾뫾k뺾뺾뺾kKK7k7k7k*밾j꫾jGj[3*3*)霾霾霾闾闾/钾ii(S(S(}n]UJ!J!	
    -:
    -:	99ghoꦾoꦾl̾S-վS-վC....3/3/nn.𾻮..뾧n꾻뾓.龓.羓.龓.k澓.龓.Wn//C.///nnn-߾-߾n˭ܾ˭ܾ˭ܾؾؾm۾m۾m۾gm־-ھgm־gm־gm־?Ӿؾؾ+Ҿ?Ӿ?Ӿ?Ӿ+Ҿ+Ҿ+Ҿ-оmѾξξ,˾l̾l̾ɾɾɾɾOľOľwlǾc,ƾc,ƾ'l¾'l¾,,뿾k뫾뫾뺾k7k#+#+#+j*jj[3*꡾iiiikWiWi˨(舾++i%Nb%Nb)aa<
    -\
    -\J+eOv霾_뵾_뵾-оm۾m۾羓.龓.nnnnn..nᄏ뾻뾻...龓.龓.龓.kC.C.C.C.//nnnݾݾ-߾ݾݾ˭ܾݾ˭ܾm۾m۾-ھm۾m۾{׾{׾{׾{׾ؾؾ{׾S-վS-վ?Ӿ+Ҿ+Ҿ?Ӿ?Ӿξ۬;۬;mѾ۬;۬;,˾۬;۬;ȾȾȾȾwlǾwlǾc,ƾ;þ;þ;þ'l¾뫾뿾뿾kkk+kkks+s+#+7k7kjjj*[[3*3*3*霾霾霾i闾闾/钾/钾/钾h{+xx]U=#=#Q
    -%p;p;	IԽ>>49RR>>Hy\\\\\fYfYfY\pppp9999yʙ999Y99Y999ʙyyyyyyyy Z yyZ Z Z       !!   $:"!!!$:"$:"$:"$:"$:"!$:"$:"8z#$:"."."."!$:"$:"!."."8z#."."8z#8z#L$8z#8z#B$."."B$8z#8z#L$B$8z#B$B$VZ%8z#8z#B$L$L$B$L$L$B$B$L$8z#B$VZ%B$B$L$`%`%8z#VZ%VZ%VZ%VZ%VZ%`%VZ%VZ%L$L$`%VZ%VZ%`%L$L$VZ%VZ%VZ%VZ%`%`%L$VZ%VZ%VZ%`%`%`%VZ%VZ%t:'t:'`%`%`%`%j&j&t:'`%`%~'t:'t:'j&t:'t:'j&j&j&~'~'`%j&j&j&`%`%VZ%t:'t:'`%j&j&~'j&`%`%z(~'j&j&~'~'~'t:'t:'t:'`%t:'t:'`%t:'t:'j&j&~'t:'t:'j&t:'t:'j&j&j&t:'~'~'~'t:'j&t:'t:'~'t:'t:'~'~'~'z(~'~'~'t:'t:'j&~'~'~'t:'t:'~'~'~'t:'t:'j&t:'t:'~'z(z(z(z(z(t:'z()t:'t:'z(~'~'~'z(z(~'~'~'t:'t:'t:'t:'t:'~'z(t:'~'t:'t:'~'t:'t:'z())~'z(z(z(z(z(t:'~')z(z(z(z(z(~'~'~'t:'t:'t:')~'t:'~'~'z(t:'t:')z(z()~'~'z(~'~'~'z()z(z()))z())~'z(z(t:'z(z(t:'t:'t:'z(z(t:'~'~'~'t:'t:')z(z(z())z(z(z(z(z(z(z(z(z(z(z(~'))t:'z(z()~'z(z(t:'z(~'~'~')))z(z()))))z(~'~'~'z(z(~'))z(z(z(t:'z(z(~'~'~')~'~'~'~'z(~'~')~'~'z()))~'~')))~'~'~'z(z(t:'z(z(~'t:'t:')z(z(z(~'~'~'~'z(~'~')~'~')z(z(z(z(z(t:')z())~'z(z()~'~'~'~'~'~'z(~'z(z(t:')))~'~'z(~'~'~'z(~'z(~'z(~'~'z(~'~')~'~'~'z(z(~'z(z())~'t:'t:'z())~'~'~'~'t:'t:'z())~'~')~'~'z())t:'z(z(t:'z(z(t:'~'~'~'~'~'))t:'~'~'z(t:'t:')))z(z(z(z(~')t:'t:')t:'t:'~'z(z(t:'t:'t:'~'j&j&t:'z(t:'z(~'~'))z(~'~'z(~'~'z())~'z(z(t:'~'~'z(z()~'~'z(~'~'t:'~'~'z(j&t:')~'t:'z(z()~'~'z())t:'z(z()~'~'z(z(z(~'~'t:'))t:'z(z(~'~'z(z(z(~'~'~'z())z(z(z(z(z(z(z(z(~'z(z()~'~'z(t:'t:'~'~'~'~'~'z(z(z()~'~'z())t:'z(z()j&j&)z(~'~')~')))z(z()z(z(z())j&z(z(~'t:'~'z(z(~'))~'z(z()~'~')~'~')))t:'))j&j&~'~'~'t:'~'~')~'~'~'t:'z()))))~'~'~')~'~')z(z())~'z(z(t:'t:'t:')~'~'t:'z(z(j&z(z(z(t:'~'z(z()z(z(z(z(z()z(z()~'~')z(~'t:'t:')t:'t:'~'z(z(t:'~'~'j&~'~'~'t:'t:')~'z())j&)))z(z(z())t:'))~'~'~'t:'t:')z(z(j&z(z(t:'~'~'z(t:'t:'z(~'~'z(z(t:'z(z(~'~')z()z(z(z(t:'~'~'z(z(z(z(~'~'t:'~'t:'~'~'~'))z(~'~'~'~'~'j&j&
    \ No newline at end of file
    diff -Nru matplotlib-1.1.1/sampledata/msft.csv matplotlib-1.2.0/sampledata/msft.csv
    --- matplotlib-1.1.1/sampledata/msft.csv	2009-09-06 12:32:28.000000000 +0000
    +++ matplotlib-1.2.0/sampledata/msft.csv	1970-01-01 00:00:00.000000000 +0000
    @@ -1,66 +0,0 @@
    -Date,Open,High,Low,Close,Volume,Adj. Close*
    -19-Sep-03,29.76,29.97,29.52,29.96,92433800,29.79
    -18-Sep-03,28.49,29.51,28.42,29.50,67268096,29.34
    -17-Sep-03,28.76,28.95,28.47,28.50,47221600,28.34
    -16-Sep-03,28.41,28.95,28.32,28.90,52060600,28.74
    -15-Sep-03,28.37,28.61,28.33,28.36,41432300,28.20
    -12-Sep-03,27.48,28.40,27.45,28.34,55777200,28.18
    -11-Sep-03,27.66,28.11,27.59,27.84,37813300,27.68
    -10-Sep-03,28.03,28.18,27.48,27.55,54763500,27.40
    -9-Sep-03,28.65,28.71,28.31,28.37,44315200,28.21
    -8-Sep-03,28.39,28.92,28.34,28.84,46105300,28.68
    -5-Sep-03,28.23,28.75,28.17,28.38,64024500,28.22
    -4-Sep-03,28.10,28.47,27.99,28.43,59840800,28.27
    -3-Sep-03,27.42,28.40,27.38,28.30,109437800,28.14
    -2-Sep-03,26.70,27.30,26.47,27.26,74168896,27.11
    -29-Aug-03,26.46,26.55,26.35,26.52,34503000,26.37
    -28-Aug-03,26.50,26.58,26.24,26.51,46211200,26.36
    -27-Aug-03,26.51,26.58,26.30,26.42,30633900,26.27
    -26-Aug-03,26.31,26.67,25.96,26.57,47546000,26.42
    -25-Aug-03,26.31,26.54,26.23,26.50,36132900,26.35
    -22-Aug-03,26.78,26.95,26.21,26.22,65846300,26.07
    -21-Aug-03,26.65,26.73,26.13,26.24,63802700,26.09
    -20-Aug-03,26.30,26.53,26.00,26.45,56739300,26.30
    -19-Aug-03,25.85,26.65,25.77,26.62,72952896,26.47
    -18-Aug-03,25.56,25.83,25.46,25.70,45817400,25.56
    -15-Aug-03,25.61,25.66,25.43,25.54,27607900,25.40
    -14-Aug-03,25.66,25.71,25.52,25.63,37338300,25.49
    -13-Aug-03,25.79,25.89,25.50,25.60,39636900,25.46
    -12-Aug-03,25.71,25.77,25.45,25.73,38208400,25.59
    -11-Aug-03,25.61,25.99,25.54,25.61,36433900,25.47
    -8-Aug-03,25.88,25.98,25.50,25.58,33241400,25.44
    -7-Aug-03,25.72,25.81,25.45,25.71,44258500,25.57
    -6-Aug-03,25.54,26.19,25.43,25.65,56294900,25.51
    -5-Aug-03,26.31,26.54,25.60,25.66,58825800,25.52
    -4-Aug-03,26.15,26.41,25.75,26.18,51825600,26.03
    -1-Aug-03,26.33,26.51,26.12,26.17,42649700,26.02
    -31-Jul-03,26.60,26.99,26.31,26.41,64504800,26.26
    -30-Jul-03,26.46,26.57,26.17,26.23,41240300,26.08
    -29-Jul-03,26.88,26.90,26.24,26.47,62391100,26.32
    -28-Jul-03,26.94,27.00,26.49,26.61,52658300,26.46
    -25-Jul-03,26.28,26.95,26.07,26.89,54173000,26.74
    -24-Jul-03,26.78,26.92,25.98,26.00,53556600,25.85
    -23-Jul-03,26.42,26.65,26.14,26.45,49828200,26.30
    -22-Jul-03,26.28,26.56,26.13,26.38,51791000,26.23
    -21-Jul-03,26.87,26.91,26.00,26.04,48480800,25.89
    -18-Jul-03,27.11,27.23,26.75,26.89,63388400,26.74
    -17-Jul-03,27.14,27.27,26.54,26.69,72805000,26.54
    -16-Jul-03,27.56,27.62,27.20,27.52,49838900,27.37
    -15-Jul-03,27.47,27.53,27.10,27.27,53567600,27.12
    -14-Jul-03,27.63,27.81,27.05,27.40,60464400,27.25
    -11-Jul-03,26.95,27.45,26.89,27.31,50377300,27.16
    -10-Jul-03,27.25,27.42,26.59,26.91,55350800,26.76
    -9-Jul-03,27.56,27.70,27.25,27.47,62300700,27.32
    -8-Jul-03,27.26,27.80,27.25,27.70,61896800,27.55
    -7-Jul-03,27.02,27.55,26.95,27.42,88960800,27.27
    -3-Jul-03,26.69,26.95,26.41,26.50,39440900,26.35
    -2-Jul-03,26.50,26.93,26.45,26.88,94069296,26.73
    -1-Jul-03,25.59,26.20,25.39,26.15,60926000,26.00
    -30-Jun-03,25.94,26.12,25.50,25.64,48073100,25.50
    -27-Jun-03,25.95,26.34,25.53,25.63,76040304,25.49
    -26-Jun-03,25.39,26.51,25.21,25.75,51758100,25.61
    -25-Jun-03,25.64,25.99,25.14,25.26,60483500,25.12
    -24-Jun-03,25.65,26.04,25.52,25.70,51820300,25.56
    -23-Jun-03,26.14,26.24,25.49,25.78,52584500,25.64
    -20-Jun-03,26.34,26.38,26.01,26.33,86048896,26.18
    -19-Jun-03,26.09,26.39,26.01,26.07,63626900,25.92
    \ No newline at end of file
    Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/sampledata/msft_nasdaq.npy and /tmp/dj4q_yDaTz/matplotlib-1.2.0/sampledata/msft_nasdaq.npy differ
    Binary files /tmp/7Z2s8lkXZI/matplotlib-1.1.1/sampledata/s1045.ima and /tmp/dj4q_yDaTz/matplotlib-1.2.0/sampledata/s1045.ima differ
    diff -Nru matplotlib-1.1.1/sampledata/setup.py matplotlib-1.2.0/sampledata/setup.py
    --- matplotlib-1.1.1/sampledata/setup.py	2011-01-06 13:57:31.000000000 +0000
    +++ matplotlib-1.2.0/sampledata/setup.py	1970-01-01 00:00:00.000000000 +0000
    @@ -1,9 +0,0 @@
    -from distutils.core import setup
    -
    -setup(name='mpl_sampledata',
    -            version='1.0.1',
    -            description='matplotlib sample data',
    -            author='John Hunter',
    -            author_email='jdh2358@gmail.com',
    -            url='http://matplotlib.sf.net',
    -           )
    diff -Nru matplotlib-1.1.1/sampledata/testdata.csv matplotlib-1.2.0/sampledata/testdata.csv
    --- matplotlib-1.1.1/sampledata/testdata.csv	2009-09-06 12:32:28.000000000 +0000
    +++ matplotlib-1.2.0/sampledata/testdata.csv	1970-01-01 00:00:00.000000000 +0000
    @@ -1,5 +0,0 @@
    -name,age
    -john,41
    -miriam,38
    -rahel,11
    -
    diff -Nru matplotlib-1.1.1/sampledata/testdir/subdir/testsub.csv matplotlib-1.2.0/sampledata/testdir/subdir/testsub.csv
    --- matplotlib-1.1.1/sampledata/testdir/subdir/testsub.csv	2009-09-06 12:32:28.000000000 +0000
    +++ matplotlib-1.2.0/sampledata/testdir/subdir/testsub.csv	1970-01-01 00:00:00.000000000 +0000
    @@ -1,5 +0,0 @@
    -name,age
    -john,41
    -miriam,38
    -rahel,11
    -
    diff -Nru matplotlib-1.1.1/setup.cfg.template matplotlib-1.2.0/setup.cfg.template
    --- matplotlib-1.1.1/setup.cfg.template	2012-06-30 18:47:51.000000000 +0000
    +++ matplotlib-1.2.0/setup.cfg.template	2012-11-06 22:31:09.000000000 +0000
    @@ -28,6 +28,7 @@
     ## Date/timezone support:
     #pytz = False
     #dateutil = False
    +#six = False
     
     [gui_support]
     # Matplotlib supports multiple GUI toolkits, including Cocoa,
    diff -Nru matplotlib-1.1.1/setup.py matplotlib-1.2.0/setup.py
    --- matplotlib-1.1.1/setup.py	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/setup.py	2012-11-08 02:24:12.000000000 +0000
    @@ -1,11 +1,13 @@
     """
    -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.
     
     The matplotlib build options can be modified with a setup.cfg file. See
     setup.cfg.template for more information.
     """
    +from __future__ import print_function
    +
     # distutils is breaking our sdists for files in symlinked dirs.
     # distutils will copy if os.link is not available, so this is a hack
     # to force copying
    @@ -28,23 +30,27 @@
     import sys
     major, minor1, minor2, s, tmp = sys.version_info
     
    -if major==2 and minor1<4 or major<2:
    -    raise SystemExit("""matplotlib requires Python 2.4 or later.""")
    +if major==2 and minor1<6 or major<2:
    +    raise SystemExit("""matplotlib requires Python 2.6 or later.""")
     
     import glob
     from distutils.core import setup
    +try:
    +    from distutils.command.build_py import build_py_2to3 as build_py
    +except ImportError:
    +    from distutils.command.build_py import build_py
     from setupext import build_agg, build_gtkagg, build_tkagg,\
          build_macosx, build_ft2font, build_image, build_windowing, build_path, \
    -     build_contour, build_delaunay, build_nxutils, build_gdk, \
    +     build_contour, build_delaunay, build_gdk, \
          build_ttconv, print_line, print_status, print_message, \
          print_raw, check_for_freetype, check_for_libpng, check_for_gtk, \
          check_for_tk, check_for_macosx, check_for_numpy, \
          check_for_qt, check_for_qt4, check_for_pyside, check_for_cairo, \
          check_provide_pytz, check_provide_dateutil,\
          check_for_dvipng, check_for_ghostscript, check_for_latex, \
    -     check_for_pdftops, check_for_datetime, options, build_png, build_tri
    +     check_for_pdftops, options, build_png, build_tri, check_provide_six
    +
     
    -# jdh
     packages = [
         'matplotlib',
         'matplotlib.backends',
    @@ -67,6 +73,16 @@
     
     ext_modules = []
     
    +classifiers = [
    +    'Development Status :: 5 - Production/Stable',
    +    'Intended Audience :: Science/Research',
    +    'License :: OSI Approved :: Python Software Foundation License',
    +    'Programming Language :: Python',
    +    'Programming Language :: Python :: 2',
    +    'Programming Language :: Python :: 3',
    +    'Topic :: Scientific/Engineering :: Visualization',
    +    ]
    +
     for line in open('lib/matplotlib/__init__.py').readlines():
         if (line.startswith('__version__')):
             exec(line.strip())
    @@ -92,15 +108,19 @@
                                   'mpl-data/fonts/ttf/RELEASENOTES.TXT',
                                   'mpl-data/images/*.xpm',
                                   'mpl-data/images/*.svg',
    +                              'mpl-data/images/*.gif',
                                   'mpl-data/images/*.png',
                                   'mpl-data/images/*.ppm',
                                   'mpl-data/example/*.npy',
                                   'mpl-data/matplotlibrc',
    -                              'mpl-data/matplotlib.conf',
                                   'mpl-data/*.glade',
    +                              'mpl-data/sample_data/*.*',
    +                              'mpl-data/sample_data/axes_grid/*.*',
                                   'backends/Matplotlib.nib/*',
                                   ]}
     
    +package_dir = {'': 'lib'}
    +
     if 1:
         # TODO: exclude these when making release?
         baseline_images = glob.glob(os.path.join('lib','matplotlib','tests',
    @@ -113,6 +133,7 @@
         baseline_images = [chop_package(f) for f in baseline_images]
         package_data['matplotlib'].extend(baseline_images)
         package_data['matplotlib'].append('tests/mpltest.ttf')
    +    package_data['matplotlib'].append('tests/test_rcparams.rc')
     
     if not check_for_numpy(__version__numpy__):
         sys.exit(1)
    @@ -124,7 +145,6 @@
     build_ttconv(ext_modules, packages)
     build_contour(ext_modules, packages)
     build_delaunay(ext_modules, packages)
    -build_nxutils(ext_modules, packages)
     build_path(ext_modules, packages)
     build_tri(ext_modules, packages)
     
    @@ -180,46 +200,52 @@
     print_raw("")
     print_raw("OPTIONAL DATE/TIMEZONE DEPENDENCIES")
     
    -hasdatetime = check_for_datetime()
    -provide_dateutil = check_provide_dateutil(hasdatetime)
    -provide_pytz = check_provide_pytz(hasdatetime)
    -
    -if hasdatetime: # dates require python23 datetime
    -    # only install pytz and dateutil if the user hasn't got them
    -
    -    def add_pytz():
    -        packages.append('pytz')
    -
    -        resources = ['zone.tab', 'locales/pytz.pot']
    -        for dirpath, dirnames, filenames in os.walk(
    -            os.path.join('lib', 'pytz', 'zoneinfo')
    -            ):
    -
    -            # remove the 'pytz' part of the path
    -            basepath = os.path.join(*dirpath.split(os.path.sep)[2:])
    -            #print dirpath, basepath
    -            resources.extend([os.path.join(basepath, filename)
    -                              for filename in filenames])
    -        package_data['pytz'] = resources
    -        #print resources
    -        assert len(resources) > 10, 'zoneinfo files not found!'
    -
    -
    -    def add_dateutil():
    -        packages.append('dateutil')
    -        packages.append('dateutil.zoneinfo')
    -        package_data['dateutil'] = ['zoneinfo/zoneinfo*.tar.*']
    +provide_dateutil = check_provide_dateutil()
    +provide_pytz = check_provide_pytz()
    +provide_six = check_provide_six()
    +
    +def add_pytz():
    +    packages.append('pytz')
    +
    +    resources = ['zone.tab', 'locales/pytz.pot']
    +    for dirpath, dirnames, filenames in os.walk(
    +        os.path.join('lib', 'pytz', 'zoneinfo')
    +        ):
    +
    +        # remove the 'pytz' part of the path
    +        basepath = os.path.join(*dirpath.split(os.path.sep)[2:])
    +        #print dirpath, basepath
    +        resources.extend([os.path.join(basepath, filename)
    +                          for filename in filenames])
    +    package_data['pytz'] = resources
    +    #print resources
    +    assert len(resources) > 10, 'zoneinfo files not found!'
    +
    +def add_dateutil():
    +    packages.append('dateutil')
    +    packages.append('dateutil.zoneinfo')
    +    package_data['dateutil'] = ['zoneinfo/*.tar.gz']
    +    if sys.version_info[0] >= 3:
    +        package_dir['dateutil'] = 'lib/dateutil_py3'
    +    else:
    +        package_dir['dateutil'] = 'lib/dateutil_py2'
    +
    +def add_six():
    +    py_modules.append('six')
     
    -    if sys.platform=='win32':
    -        # always add these to the win32 installer
    +if sys.platform=='win32':
    +    # always add these to the win32 installer
    +    add_pytz()
    +    add_dateutil()
    +    add_six()
    +else:
    +    # only add them if we need them
    +    if provide_pytz:
             add_pytz()
    +    if provide_dateutil:
             add_dateutil()
    -    else:
    -        # only add them if we need them
    -        if provide_pytz:
    -            add_pytz()
    -            print_raw("adding pytz")
    -        if provide_dateutil: add_dateutil()
    +    if provide_six:
    +        add_six()
     
     print_raw("")
     print_raw("OPTIONAL USETEX DEPENDENCIES")
    @@ -237,12 +263,6 @@
     template = open('matplotlibrc.template').read()
     open('lib/matplotlib/mpl-data/matplotlibrc', 'w').write(template%rc)
     
    -# Write the default matplotlib.conf file
    -template = open('lib/matplotlib/mpl-data/matplotlib.conf.template').read()
    -template = template.replace("datapath = ", "#datapath = ")
    -template = template.replace("    use = 'Agg'", "    use = '%s'"%rc['backend'])
    -open('lib/matplotlib/mpl-data/matplotlib.conf', 'w').write(template)
    -
     try: additional_params # has setupegg.py provided
     except NameError: additional_params = {}
     
    @@ -250,14 +270,51 @@
         if options['verbose']:
             mod.extra_compile_args.append('-DVERBOSE')
     
    +if sys.version_info[0] >= 3:
    +    def should_2to3(file, root):
    +        file = os.path.abspath(file)[len(os.path.abspath(root))+1:]
    +        if ('py3' in file or
    +            file.startswith('pytz') or
    +            file.startswith('dateutil') or
    +            file.startswith('six')):
    +            return False
    +        return True
    +
    +    import multiprocessing
    +    def refactor(x):
    +        from lib2to3.refactor import RefactoringTool, get_fixers_from_package
    +        class DistutilsRefactoringTool(RefactoringTool):
    +            def ignore(self, msg, *args, **kw):
    +                pass
    +            log_error = log_message = log_debug = ignore
    +        fixer_names = get_fixers_from_package('lib2to3.fixes')
    +        r = DistutilsRefactoringTool(fixer_names, options=None)
    +        r.refactor([x], write=True)
    +
    +    original_build_py = build_py
    +    class build_py(original_build_py):
    +        def run_2to3(self, files):
    +            # We need to skip certain files that have already been
    +            # converted to Python 3.x
    +            filtered = [x for x in files if should_2to3(x, self.build_lib)]
    +            if sys.platform.startswith('win'):
    +                # doing this in parallel on windows may crash your computer
    +                [refactor(f) for f in filtered]
    +            else:
    +                p = multiprocessing.Pool()
    +                for i, x in enumerate(p.imap_unordered(refactor, filtered)):
    +                    print("Running 2to3... %.02f%%" %
    +                          (float(i) / len(filtered) * 100.0), end='\r')
    +            print()
    +
     print_raw("pymods %s" % py_modules)
     print_raw("packages %s" % packages)
     distrib = setup(name="matplotlib",
           version= __version__,
           description = "Python plotting package",
    -      author = "John D. Hunter",
    -      author_email="jdh2358@gmail.com",
    -      url = "http://matplotlib.sourceforge.net",
    +      author = "John D. Hunter, Michael Droettboom",
    +      author_email="mdroe@stsci.edu",
    +      url = "http://matplotlib.org",
           long_description = """
           matplotlib strives to produce publication quality 2D graphics
           for interactive graphing, scientific publishing, user interface
    @@ -269,7 +326,9 @@
           platforms='any',
           py_modules = py_modules,
           ext_modules = ext_modules,
    -      package_dir = {'': 'lib'},
    +      package_dir = package_dir,
           package_data = package_data,
    +      classifiers = classifiers,
    +      cmdclass = {'build_py': build_py},
           **additional_params
           )
    diff -Nru matplotlib-1.1.1/setupegg.py matplotlib-1.2.0/setupegg.py
    --- matplotlib-1.1.1/setupegg.py	2012-06-30 18:47:51.000000000 +0000
    +++ matplotlib-1.2.0/setupegg.py	2012-11-06 22:31:09.000000000 +0000
    @@ -2,7 +2,19 @@
     Poor man's setuptools script...
     """
     
    +import os
    +import sys
     from setuptools import setup
    +
    +# Setupegg assumes the install tree and source tree are exactly the same. Since
    +# this is not the case, symlink the correct dateutil dir depending on which
    +# version of python is used
    +if not os.path.isdir('lib/dateutil'):
    +    if sys.version_info[0] >= 3:
    +        os.symlink('dateutil_py3', 'lib/dateutil')
    +    else:
    +        os.symlink('dateutil_py2', 'lib/dateutil')
    +
     execfile('setup.py',
              {'additional_params' :
               {'namespace_packages' : ['mpl_toolkits'],
    diff -Nru matplotlib-1.1.1/setupext.py matplotlib-1.2.0/setupext.py
    --- matplotlib-1.1.1/setupext.py	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/setupext.py	2012-11-06 22:31:09.000000000 +0000
    @@ -47,39 +47,23 @@
     import re
     import subprocess
     from distutils import sysconfig, version
    +from collections import defaultdict
     
    -basedir = {
    +# basedir is a dictionary keyed by sys.platform, and on most platforms it is
    +# set to ['/usr/local', '/usr']. Giving this defaultdict a factory that
    +# returns this default removes the need to update this code every time a new
    +# version of freebsd comes out, for example, provided that the default basedir
    +# remains sufficient on that platform
    +basedir = defaultdict(lambda: ['/usr/local', '/usr'], {
    +    # execptions to the ['/usr/local', '/usr'] defaults
         'win32'  : ['win32_static',],
    -    'linux2-alpha' : ['/usr/local', '/usr'],
    -    'linux2-hppa' : ['/usr/local', '/usr'],
    -    'linux2-mips' : ['/usr/local', '/usr'],
    -    'linux2-sparc' : ['/usr/local', '/usr'],
    -    'linux2' : ['/usr/local', '/usr'],
    -    'linux3' : ['/usr/local', '/usr'],
    -    'linux'  : ['/usr/local', '/usr',],
    -    'cygwin' : ['/usr/local', '/usr',],
    -    '_darwin' : ['/sw/lib/freetype2', '/sw/lib/freetype219', '/usr/local',
    -                '/usr', '/sw'],
    -    # it appears builds with darwin are broken because of all the
    -    # different flags the deps can be compile with, so I am pushing
    -    # people to :
    -    #   make -f make.osx fetch deps mpl_build mpl_install
    -
    -    'darwin' : [],
    -
    -    'freebsd4' : ['/usr/local', '/usr'],
    -    'freebsd5' : ['/usr/local', '/usr'],
    -    'freebsd6' : ['/usr/local', '/usr'],
    +    'darwin' : ['/usr/local/', '/usr', '/usr/X11', '/opt/local'],
         'sunos5' : [os.getenv('MPLIB_BASE') or '/usr/local',],
    -    'gnukfreebsd5' : ['/usr/local', '/usr'],
    -    'gnukfreebsd6' : ['/usr/local', '/usr'],
    -    'gnukfreebsd7' : ['/usr/local', '/usr'],
    -    'gnukfreebsd8' : ['/usr/local', '/usr'],
         'gnu0' : ['/usr'],
         'aix5' : ['/usr/local'],
    -}
    +    })
     
    -import sys, os, stat
    +import sys
     
     from textwrap import fill
     from distutils.core import Extension
    @@ -107,7 +91,6 @@
     BUILT_WINDOWING = False
     BUILT_CONTOUR   = False
     BUILT_DELAUNAY  = False
    -BUILT_NXUTILS   = False
     BUILT_CONTOUR   = False
     BUILT_GDK       = False
     BUILT_PATH      = False
    @@ -124,6 +107,7 @@
                'verbose': False,
                'provide_pytz': 'auto',
                'provide_dateutil': 'auto',
    +           'provide_six': 'auto',
                'build_agg': True,
                'build_gtk': 'auto',
                'build_gtkagg': 'auto',
    @@ -138,6 +122,9 @@
             ('PY_ARRAY_UNIQUE_SYMBOL', 'MPL_ARRAY_API'),
             ('PYCXX_ISO_CPP_LIB', '1')]
     
    +if sys.version_info[0] >= 3:
    +    defines.append(('PYCXX_PYTHON_2TO3', '1'))
    +
     setup_cfg = os.environ.get('MPLSETUPCFG', 'setup.cfg')
     # Based on the contents of setup.cfg, determine the build options
     if os.path.exists(setup_cfg):
    @@ -157,6 +144,10 @@
                                                              "dateutil")
         except: options['provide_dateutil'] = 'auto'
     
    +    try: options['provide_six'] = config.getboolean("provide_packages",
    +                                                    "six")
    +    except: options['provide_six'] = 'auto'
    +
         try: options['build_gtk'] = config.getboolean("gui_support", "gtk")
         except: options['build_gtk'] = 'auto'
     
    @@ -182,6 +173,12 @@
         basedirlist = basedir[sys.platform]
     print("basedirlist is: %s" % basedirlist)
     
    +def make_extension(*args, **kwargs):
    +    ext = Extension(*args, **kwargs)
    +    for dir in basedirlist:
    +        ext.include_dirs.append(os.path.join(dir, 'include'))
    +    return ext
    +
     if options['display_status']:
         def print_line(char='='):
             print(char * 76)
    @@ -261,6 +258,20 @@
     else:
         std_libs = ['stdc++', 'm']
     
    +def set_pkgconfig_path():
    +    pkgconfig_path = sysconfig.get_config_var('LIBDIR')
    +    if pkgconfig_path is None:
    +        return
    +
    +    pkgconfig_path = os.path.join(pkgconfig_path, 'pkgconfig')
    +    if not os.path.isdir(pkgconfig_path):
    +        return
    +
    +    try:
    +        os.environ['PKG_CONFIG_PATH'] += ':' + pkgconfig_path
    +    except KeyError:
    +        os.environ['PKG_CONFIG_PATH'] = pkgconfig_path
    +
     def has_pkgconfig():
         if has_pkgconfig.cache is not None:
             return has_pkgconfig.cache
    @@ -270,6 +281,10 @@
             #print 'environ',  os.environ['PKG_CONFIG_PATH']
             status, output = getstatusoutput("pkg-config --help")
             has_pkgconfig.cache = (status == 0)
    +
    +        # Set the PKG_CONFIG_PATH environment variable
    +        if has_pkgconfig.cache:
    +            set_pkgconfig_path()
         return has_pkgconfig.cache
     has_pkgconfig.cache = None
     
    @@ -335,7 +350,7 @@
         return False
     
     def check_for_freetype():
    -    module = Extension('test', [])
    +    module = make_extension('test', [])
         add_base_flags(module)
         if not get_pkgconfig(module, 'freetype2'):
             basedirs = module.include_dirs[:]  # copy the list to avoid inf loop!
    @@ -351,7 +366,7 @@
         return True
     
     def check_for_libpng():
    -    module = Extension("test", [])
    +    module = make_extension("test", [])
         get_pkgconfig(module, 'libpng')
         add_base_flags(module)
     
    @@ -439,24 +454,14 @@
             print_status("Cairo", cairo.version)
             return True
     
    -def check_for_datetime():
    -    try:
    -        import datetime
    -    except ImportError:
    -        print_status("datetime", "no")
    -        return False
    -    else:
    -        print_status("datetime", "present, version unknown")
    -        return True
    -
    -def check_provide_pytz(hasdatetime=True):
    -    if hasdatetime and (options['provide_pytz'] is True):
    +def check_provide_pytz():
    +    if options['provide_pytz'] is True:
             print_status("pytz", "matplotlib will provide")
             return True
         try:
             import pytz
         except ImportError:
    -        if hasdatetime and options['provide_pytz']:
    +        if options['provide_pytz']:
                 print_status("pytz", "matplotlib will provide")
                 return True
             else:
    @@ -470,14 +475,14 @@
                 print_status("pytz", pytz.__version__)
                 return False
     
    -def check_provide_dateutil(hasdatetime=True):
    -    if hasdatetime and (options['provide_dateutil'] is True):
    +def check_provide_dateutil():
    +    if options['provide_dateutil'] is True:
             print_status("dateutil", "matplotlib will provide")
             return True
         try:
             import dateutil
         except ImportError:
    -        if hasdatetime and options['provide_dateutil']:
    +        if options['provide_dateutil']:
                 print_status("dateutil", "matplotlib will provide")
                 return True
             else:
    @@ -495,6 +500,36 @@
                 print_status("dateutil", "present, version unknown")
                 return False
     
    +def check_provide_six():
    +    # We don't need six on Python 2.x
    +    if sys.version_info[0] < 3:
    +        return
    +
    +    if options['provide_six'] is True:
    +        print_status("six", "matplotlib will provide")
    +        return True
    +    try:
    +        import six
    +    except ImportError:
    +        if options['provide_six']:
    +            print_status("six", "matplotlib will provide")
    +            return True
    +        else:
    +            print_status("six", "no")
    +            return False
    +    else:
    +        try:
    +            if six.__version__.endswith('mpl'):
    +                print_status("six", "matplotlib will provide")
    +                return True
    +            else:
    +                print_status("six", six.__version__)
    +                return False
    +        except AttributeError:
    +            print_status("six", "present, version unknown")
    +            return False
    +
    +
     def check_for_dvipng():
         try:
             stdin, stdout = run_child_process('dvipng -version')
    @@ -637,7 +672,7 @@
                 gotit = True
     
         if gotit:
    -        module = Extension('test', [])
    +        module = make_extension('test', [])
             add_pygtk_flags(module)
             if not find_include_file(module.include_dirs, os.path.join("gtk", "gtk.h")):
                 explanation = (
    @@ -742,7 +777,10 @@
         gotit = False
         explanation = None
         try:
    -        import Tkinter
    +        if sys.version_info[0] < 3:
    +            import Tkinter
    +        else:
    +            import tkinter as Tkinter
         except ImportError:
             explanation = 'TKAgg requires Tkinter'
         except RuntimeError:
    @@ -754,18 +792,18 @@
                 gotit = True
     
         if gotit:
    -        module = Extension('test', [])
    +        module = make_extension('test', [])
             try:
                 explanation = add_tk_flags(module)
    -        except RuntimeError:
    -            # This deals with the change in exception handling syntax in
    -            # python 3. If we only need to support >= 2.6, we can just use the
    -            # commented out lines below.
    -            exc_type,exc,tb = sys.exc_info()
    -            explanation = str(exc)
    -            gotit = False
    -#        except RuntimeError, e:
    -#            explanation = str(e)
    +        # except RuntimeError:
    +        #     # This deals with the change in exception handling syntax in
    +        #     # python 3. If we only need to support >= 2.6, we can just use the
    +        #     # commented out lines below.
    +        #     exc_type,exc,tb = sys.exc_info()
    +        #     explanation = str(exc)
    +        #     gotit = False
    +        except RuntimeError as e:
    +            explanation = str(e)
             else:
                 if not find_include_file(module.include_dirs, "tk.h"):
                     message = 'Tkinter present, but header files are not found. ' + \
    @@ -812,7 +850,10 @@
             return TCL_TK_CACHE
     
         # By this point, we already know that Tkinter imports correctly
    -    import Tkinter
    +    if sys.version_info[0] < 3:
    +        import Tkinter
    +    else:
    +        import tkinter as Tkinter
         tcl_lib_dir = ''
         tk_lib_dir = ''
         # First try to open a Tk window (requires a running X server)
    @@ -847,7 +888,14 @@
         return TCL_TK_CACHE
     
     def parse_tcl_config(tcl_lib_dir, tk_lib_dir):
    -    import Tkinter
    +    try:
    +        if sys.version_info[0] < 3:
    +            import Tkinter
    +        else:
    +            import tkinter as Tkinter
    +    except ImportError:
    +        return None
    +
         tcl_poss = [tcl_lib_dir,
                     os.path.normpath(os.path.join(tcl_lib_dir, '..')),
                     "/usr/lib/tcl"+str(Tkinter.TclVersion),
    @@ -871,7 +919,7 @@
                 executable="/bin/sh",
                 stdout=subprocess.PIPE)
             result = p.communicate()[0]
    -        return result
    +        return result.decode('ascii')
     
         tcl_lib_dir = get_var(tcl_config, 'TCL_LIB_SPEC').split()[0][2:].strip()
         tcl_inc_dir = get_var(tcl_config, 'TCL_INCLUDE_SPEC')[2:].strip()
    @@ -937,7 +985,7 @@
         message = None
         if sys.platform == 'win32':
             major, minor1, minor2, s, tmp = sys.version_info
    -        if major == 2 and minor1 in [6, 7]:
    +        if (2, 6) <= (major, minor1) <= (3, 3):
                 module.include_dirs.extend(['win32_static/include/tcl85'])
                 module.libraries.extend(['tk85', 'tcl85'])
             elif major == 2 and minor1 in [3, 4, 5]:
    @@ -1050,7 +1098,7 @@
            windows better, .e.g.  maintaining focus on win32"""
         global BUILT_WINDOWING
         if BUILT_WINDOWING: return # only build it if you you haven't already
    -    module = Extension('matplotlib._windowing',
    +    module = make_extension('matplotlib._windowing',
                            ['src/_windowing.cpp'],
                            )
         add_windowing_flags(module)
    @@ -1064,7 +1112,7 @@
         deps.extend(glob.glob('CXX/*.cxx'))
         deps.extend(glob.glob('CXX/*.c'))
     
    -    module = Extension('matplotlib.ft2font', deps,
    +    module = make_extension('matplotlib.ft2font', deps,
                            define_macros=defines)
         add_ft2font_flags(module)
         ext_modules.append(module)
    @@ -1078,7 +1126,7 @@
                 'ttconv/pprdrv_tt2.cpp',
                 'ttconv/ttutil.cpp']
     
    -    module = Extension('matplotlib.ttconv', deps,
    +    module = make_extension('matplotlib.ttconv', deps,
                            define_macros=defines)
         add_base_flags(module)
         ext_modules.append(module)
    @@ -1091,7 +1139,7 @@
         deps.extend(glob.glob('CXX/*.cxx'))
         deps.extend(glob.glob('CXX/*.c'))
     
    -    module = Extension('matplotlib.backends._gtkagg',
    +    module = make_extension('matplotlib.backends._gtkagg',
                            deps,
                            define_macros=defines
                            )
    @@ -1114,7 +1162,7 @@
         deps.extend(glob.glob('CXX/*.cxx'))
         deps.extend(glob.glob('CXX/*.c'))
     
    -    module = Extension('matplotlib.backends._tkagg',
    +    module = make_extension('matplotlib.backends._tkagg',
                            deps,
                            define_macros=defines
                            )
    @@ -1137,7 +1185,7 @@
                 'CXX/IndirectPythonInterface.cxx',
                 'src/agg_py_transforms.cpp',
                 'src/path_cleanup.cpp']
    -    module = Extension('matplotlib.backends._macosx',
    +    module = make_extension('matplotlib.backends._macosx',
                            deps,
                            extra_link_args = ['-framework','Cocoa'],
                            define_macros=defines
    @@ -1155,7 +1203,7 @@
         deps.extend(glob.glob('CXX/*.cxx'))
         deps.extend(glob.glob('CXX/*.c'))
     
    -    module = Extension(
    +    module = make_extension(
             'matplotlib._png',
             deps,
             include_dirs=numpy_inc_dirs,
    @@ -1187,7 +1235,7 @@
         deps.extend(glob.glob('CXX/*.c'))
         temp_copy('src/_backend_agg.cpp', 'src/backend_agg.cpp')
         deps.append('src/backend_agg.cpp')
    -    module = Extension(
    +    module = make_extension(
             'matplotlib.backends._backend_agg',
             deps,
             include_dirs=numpy_inc_dirs,
    @@ -1221,7 +1269,7 @@
         deps.extend(['src/agg_py_transforms.cpp',
                      'src/path_cleanup.cpp',
                      'src/path.cpp'])
    -    module = Extension(
    +    module = make_extension(
             'matplotlib._path',
             deps,
             include_dirs=numpy_inc_dirs,
    @@ -1250,7 +1298,7 @@
         deps.extend(glob.glob('CXX/*.cxx'))
         deps.extend(glob.glob('CXX/*.c'))
     
    -    module = Extension(
    +    module = make_extension(
             'matplotlib._image',
             deps,
             include_dirs=numpy_inc_dirs,
    @@ -1273,7 +1321,7 @@
         sourcefiles=["_delaunay.cpp", "VoronoiDiagramGenerator.cpp",
                      "delaunay_utils.cpp", "natneighbors.cpp"]
         sourcefiles = [os.path.join('lib/matplotlib/delaunay',s) for s in sourcefiles]
    -    delaunay = Extension('matplotlib._delaunay',sourcefiles,
    +    delaunay = make_extension('matplotlib._delaunay',sourcefiles,
                              include_dirs=numpy_inc_dirs,
                              define_macros=defines
                              )
    @@ -1288,7 +1336,7 @@
         global BUILT_CONTOUR
         if BUILT_CONTOUR: return # only build it if you you haven't already
     
    -    module = Extension(
    +    module = make_extension(
             'matplotlib._cntr',
             [ 'src/cntr.c'],
             include_dirs=numpy_inc_dirs,
    @@ -1301,28 +1349,12 @@
         BUILT_CONTOUR = True
     
     
    -def build_nxutils(ext_modules, packages):
    -    global BUILT_NXUTILS
    -    if BUILT_NXUTILS: return # only build it if you you haven't already
    -    module = Extension(
    -        'matplotlib.nxutils',
    -        [ 'src/nxutils.c'],
    -        include_dirs=numpy_inc_dirs,
    -        define_macros=defines
    -        )
    -    add_numpy_flags(module)
    -    add_base_flags(module)
    -    ext_modules.append(module)
    -
    -    BUILT_NXUTILS = True
    -
    -
     def build_gdk(ext_modules, packages):
         global BUILT_GDK
         if BUILT_GDK: return # only build it if you you haven't already
     
         temp_copy('src/_backend_gdk.c', 'src/backend_gdk.c')
    -    module = Extension(
    +    module = make_extension(
             'matplotlib.backends._backend_gdk',
             ['src/backend_gdk.c'],
             libraries = [],
    @@ -1346,7 +1378,7 @@
         deps.extend(glob.glob('CXX/*.cxx'))
         deps.extend(glob.glob('CXX/*.c'))
     
    -    module = Extension('matplotlib._tri', deps,
    +    module = make_extension('matplotlib._tri', deps,
                            define_macros=defines)
         add_numpy_flags(module)
         add_base_flags(module)
    diff -Nru matplotlib-1.1.1/src/_backend_agg.cpp matplotlib-1.2.0/src/_backend_agg.cpp
    --- matplotlib-1.1.1/src/_backend_agg.cpp	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/_backend_agg.cpp	2012-11-06 22:31:09.000000000 +0000
    @@ -26,6 +26,7 @@
     #include "agg_scanline_storage_aa.h"
     #include "agg_scanline_storage_bin.h"
     #include "agg_span_allocator.h"
    +#include "agg_span_converter.h"
     #include "agg_span_image_filter_gray.h"
     #include "agg_span_image_filter_rgba.h"
     #include "agg_span_interpolator_linear.h"
    @@ -102,7 +103,12 @@
     BufferRegion::to_string(const Py::Tuple &args)
     {
         // owned=true to prevent memory leak
    -    return Py::String(PyString_FromStringAndSize((const char*)data, height*stride), true);
    +    #if PY3K
    +    return Py::Bytes
    +    #else
    +    return Py::String
    +    #endif
    +        (PyBytes_FromStringAndSize((const char*)data, height*stride), true);
     }
     
     
    @@ -152,9 +158,8 @@
         unsigned char tmp;
         size_t i, j;
     
    -    PyObject* str = PyString_FromStringAndSize(
    -                        (const char*)data, height * stride);
    -    if (PyString_AsStringAndSize(str, (char**)&begin, &length))
    +    PyObject* str = PyBytes_FromStringAndSize((const char*)data, height * stride);
    +    if (PyBytes_AsStringAndSize(str, (char**)&begin, &length))
         {
             throw Py::TypeError("Could not create memory for blit");
         }
    @@ -174,7 +179,12 @@
             }
         }
     
    -    return Py::String(str, true);
    +    #if PY3K
    +    return Py::Bytes
    +    #else
    +    return Py::String
    +    #endif
    +        (str, true);
     }
     
     
    @@ -200,7 +210,7 @@
     GCAgg::_set_antialiased(const Py::Object& gc)
     {
         _VERBOSE("GCAgg::antialiased");
    -    isaa = Py::Int(gc.getAttr("_antialiased"));
    +    isaa = Py::Boolean(gc.getAttr("_antialiased"));
     }
     
     
    @@ -910,7 +920,8 @@
         }
         else
         {
    -        FT2Image *image = static_cast(image_obj.ptr());
    +        FT2Image* image = static_cast(
    +            Py::getPythonExtensionBase(image_obj.ptr()));
             if (!image->get_buffer())
             {
                 throw Py::ValueError(
    @@ -974,6 +985,30 @@
         return Py::Object();
     }
     
    +class span_conv_alpha
    +{
    +public:
    +    typedef agg::rgba8 color_type;
    +
    +    double m_alpha;
    +
    +    span_conv_alpha(double alpha) :
    +        m_alpha(alpha)
    +    {
    +    }
    +
    +    void prepare() {}
    +    void generate(color_type* span, int x, int y, unsigned len) const
    +    {
    +        do
    +            {
    +                span->a = (agg::int8u)((double)span->a * m_alpha);
    +                ++span;
    +            }
    +        while(--len);
    +    }
    +};
    +
     
     Py::Object
     RendererAgg::draw_image(const Py::Tuple& args)
    @@ -1058,11 +1093,14 @@
             typedef agg::span_interpolator_linear<> interpolator_type;
             typedef agg::span_image_filter_rgba_nn image_span_gen_type;
    +        typedef agg::span_converter span_conv;
     
             color_span_alloc_type sa;
             image_accessor_type ia(pixf, agg::rgba8(0, 0, 0, 0));
             interpolator_type interpolator(inv_mtx);
             image_span_gen_type image_span_generator(ia, interpolator);
    +        span_conv_alpha conv_alpha(alpha);
    +        span_conv spans(image_span_generator, conv_alpha);
     
             if (has_clippath)
             {
    @@ -1071,12 +1109,12 @@
                 typedef agg::renderer_base amask_ren_type;
                 typedef agg::renderer_scanline_aa
    +                                              span_conv>
                     renderer_type_alpha;
     
                 pixfmt_amask_type pfa(pixFmt, alphaMask);
                 amask_ren_type r(pfa);
    -            renderer_type_alpha ri(r, sa, image_span_generator);
    +            renderer_type_alpha ri(r, sa, spans);
     
                 theRasterizer.add_path(rect2);
                 agg::render_scanlines(theRasterizer, slineP8, ri);
    @@ -1086,11 +1124,11 @@
                 typedef agg::renderer_base ren_type;
                 typedef agg::renderer_scanline_aa
    +                                              span_conv>
                     renderer_type;
     
                 ren_type r(pixFmt);
    -            renderer_type ri(r, sa, image_span_generator);
    +            renderer_type ri(r, sa, spans);
     
                 theRasterizer.add_path(rect2);
                 agg::render_scanlines(theRasterizer, slineP8, ri);
    @@ -1101,7 +1139,8 @@
         {
             set_clipbox(gc.cliprect, rendererBase);
             rendererBase.blend_from(
    -            pixf, 0, (int)x, (int)(height - (y + image->rowsOut)), alpha * 255);
    +            pixf, 0, (int)x, (int)(height - (y + image->rowsOut)),
    +            (agg::int8u)(alpha * 255));
         }
     
         rendererBase.reset_clipping(true);
    @@ -1362,7 +1401,8 @@
      const Py::Object&              edgecolors_obj,
      const Py::SeqBase&  linewidths,
      const Py::SeqBase& linestyles_obj,
    - const Py::SeqBase&    antialiaseds)
    + const Py::SeqBase&    antialiaseds,
    + const bool                     data_offsets)
     {
         typedef agg::conv_transform transformed_path_t;
         typedef PathNanRemover                         nan_removed_t;
    @@ -1476,7 +1516,11 @@
                 double xo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0);
                 double yo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1);
                 offset_trans.transform(&xo, &yo);
    -            trans *= agg::trans_affine_translation(xo, yo);
    +            if (data_offsets) {
    +                trans = agg::trans_affine_translation(xo, yo) * trans;
    +            } else {
    +                trans *= agg::trans_affine_translation(xo, yo);
    +            }
             }
     
             // These transformations must be done post-offsets
    @@ -1521,7 +1565,7 @@
     
             if (check_snap)
             {
    -            gc.isaa = bool(Py::Int(antialiaseds[i % Naa]));
    +            gc.isaa = Py::Boolean(antialiaseds[i % Naa]);
     
                 transformed_path_t tpath(path, trans);
                 nan_removed_t      nan_removed(tpath, true, has_curves);
    @@ -1540,7 +1584,7 @@
             }
             else
             {
    -            gc.isaa = bool(Py::Int(antialiaseds[i % Naa]));
    +            gc.isaa = Py::Boolean(antialiaseds[i % Naa]);
     
                 transformed_path_t tpath(path, trans);
                 nan_removed_t      nan_removed(tpath, true, has_curves);
    @@ -1594,7 +1638,7 @@
     RendererAgg::draw_path_collection(const Py::Tuple& args)
     {
         _VERBOSE("RendererAgg::draw_path_collection");
    -    args.verify_length(12);
    +    args.verify_length(13);
     
         Py::Object gc_obj = args[0];
         GCAgg gc(gc_obj, dpi);
    @@ -1611,6 +1655,9 @@
         Py::SeqBase    antialiaseds     = args[10];
         // We don't actually care about urls for Agg, so just ignore it.
         // Py::SeqBase urls             = args[11];
    +    std::string             offset_position  = Py::String(args[12]);
    +
    +    bool data_offsets = (offset_position == "data");
     
         try
         {
    @@ -1628,7 +1675,8 @@
              edgecolors_obj,
              linewidths,
              linestyles_obj,
    -         antialiaseds);
    +         antialiaseds,
    +         data_offsets);
         }
         catch (const char *e)
         {
    @@ -1754,28 +1802,18 @@
         agg::trans_affine offset_trans     = py_to_agg_transformation_matrix(args[6].ptr());
         Py::Object        facecolors_obj   = args[7];
         bool              antialiased      = (bool)Py::Boolean(args[8]);
    -    bool              showedges        = (bool)Py::Boolean(args[9]);
    -    bool              free_edgecolors  = false;
    +    Py::Object        edgecolors_obj   = args[9];
     
         QuadMeshGenerator path_generator(mesh_width, mesh_height, coordinates.ptr());
     
         Py::SeqBase transforms_obj;
    -    Py::Object edgecolors_obj;
         Py::Tuple linewidths(1);
         linewidths[0] = Py::Float(gc.linewidth);
         Py::SeqBase linestyles_obj;
         Py::Tuple antialiaseds(1);
         antialiaseds[0] = Py::Int(antialiased ? 1 : 0);
     
    -    if (showedges)
    -    {
    -        npy_intp dims[] = { 1, 4, 0 };
    -        double data[] = { 0, 0, 0, 1 };
    -        edgecolors_obj = Py::Object(PyArray_SimpleNewFromData(2, dims, PyArray_DOUBLE,
    -                                                              (char*)data), true);
    -    }
    -    else
    -    {
    +    if (edgecolors_obj.isNone()) {
             if (antialiased)
             {
                 edgecolors_obj = facecolors_obj;
    @@ -1784,7 +1822,6 @@
             {
                 npy_intp dims[] = { 0, 0 };
                 edgecolors_obj = PyArray_SimpleNew(1, dims, PyArray_DOUBLE);
    -            free_edgecolors = true;
             }
         }
     
    @@ -1804,7 +1841,8 @@
                  edgecolors_obj,
                  linewidths,
                  linestyles_obj,
    -             antialiaseds);
    +             antialiaseds,
    +             false);
         }
         catch (const char* e)
         {
    @@ -1993,6 +2031,12 @@
         FILE *fp = NULL;
         bool close_file = false;
         Py::Object py_fileobj = Py::Object(args[0]);
    +
    +    #if PY3K
    +    int fd = PyObject_AsFileDescriptor(py_fileobj.ptr());
    +    PyErr_Clear();
    +    #endif
    +
         if (py_fileobj.isString())
         {
             std::string fileName = Py::String(py_fileobj);
    @@ -2008,6 +2052,15 @@
             }
             close_file = true;
         }
    +    #if PY3K
    +    else if (fd != -1)
    +    {
    +        if (write(fd, pixBuffer, NUMBYTES) != (ssize_t)NUMBYTES)
    +        {
    +            throw Py::RuntimeError("Error writing to file");
    +        }
    +    }
    +    #else
         else if (PyFile_CheckExact(py_fileobj.ptr()))
         {
             fp = PyFile_AsFile(py_fileobj.ptr());
    @@ -2016,6 +2069,7 @@
                 throw Py::RuntimeError("Error writing to file");
             }
         }
    +    #endif
         else
         {
             PyObject* write_method = PyObject_GetAttrString(py_fileobj.ptr(),
    @@ -2071,7 +2125,11 @@
         }
     
         //todo: how to do this with native CXX
    +    #if PY3K
    +    PyObject* o = Py_BuildValue("y#", buf_tmp, row_len * height);
    +    #else
         PyObject* o = Py_BuildValue("s#", buf_tmp, row_len * height);
    +    #endif
     
         delete [] buf_tmp;
         return Py::asObject(o);
    @@ -2107,7 +2165,12 @@
         }
     
         //todo: how to do this with native CXX
    +
    +    #if PY3K
    +    PyObject* o = Py_BuildValue("y#", buf_tmp, row_len * height);
    +    #else
         PyObject* o = Py_BuildValue("s#", buf_tmp, row_len * height);
    +    #endif
         delete [] buf_tmp;
         return Py::asObject(o);
     }
    @@ -2146,9 +2209,11 @@
         }
     
         //todo: how to do this with native CXX
    -    PyObject* o = Py_BuildValue("s#",
    -                                buf_tmp,
    -                                row_len * height);
    +    #if PY3K
    +    PyObject* o = Py_BuildValue("y#", buf_tmp, row_len * height);
    +    #else
    +    PyObject* o = Py_BuildValue("s#", buf_tmp, row_len * height);
    +    #endif
         delete [] buf_tmp;
         return Py::asObject(o);
     }
    @@ -2161,12 +2226,15 @@
     
         _VERBOSE("RendererAgg::buffer_rgba");
     
    -    args.verify_length(2);
    -    int startw = Py::Int(args[0]);
    -    int starth = Py::Int(args[1]);
    +    args.verify_length(0);
    +
    +    #if PY3K
    +    return Py::asObject(PyMemoryView_FromObject(this));
    +    #else
         int row_len = width * 4;
    -    int start = row_len * starth + startw * 4;
    -    return Py::asObject(PyBuffer_FromMemory(pixBuffer + start, row_len*height - start));
    +    return Py::asObject(PyBuffer_FromReadWriteMemory(
    +                            pixBuffer, row_len*height));
    +    #endif
     }
     
     
    @@ -2199,7 +2267,12 @@
     
         int newwidth = 0;
         int newheight = 0;
    +    #if PY3K
    +    Py::Bytes data;
    +    #else
         Py::String data;
    +    #endif
    +
         if (xmin < xmax && ymin < ymax)
         {
             // Expand the bounds by 1 pixel on all sides
    @@ -2229,7 +2302,11 @@
             }
     
             // The Py::String will take over the buffer
    -        data = Py::String((const char *)buf, (int)newsize);
    +        #if PY3K
    +        data = Py::Bytes((const char *)buf, (int) newsize);
    +        #else
    +        data = Py::String((const char *)buf, (int) newsize);
    +        #endif
         }
     
         Py::Tuple bounds(4);
    @@ -2280,6 +2357,14 @@
         return p * dpi / 72.0;
     }
     
    +#if PY3K
    +int
    +RendererAgg::buffer_get( Py_buffer* buf, int flags )
    +{
    +    return PyBuffer_FillInfo(buf, this, pixBuffer, width * height * 4, 1,
    +                             PyBUF_SIMPLE);
    +}
    +#endif
     
     RendererAgg::~RendererAgg()
     {
    @@ -2310,8 +2395,8 @@
             debug = 0;
         }
     
    -    unsigned int width = (unsigned int)Py::Int(args[0]);
    -    unsigned int height = (unsigned int)Py::Int(args[1]);
    +    unsigned int width = (int)Py::Int(args[0]);
    +    unsigned int height = (int)Py::Int(args[1]);
         double dpi = Py::Float(args[2]);
     
         if (width > 1 << 15 || height > 1 << 15)
    @@ -2401,11 +2486,18 @@
                            "restore_region(region)");
         add_varargs_method("restore_region2", &RendererAgg::restore_region2,
                            "restore_region(region, x1, y1, x2, y2, x3, y3)");
    +
    +    #if PY3K
    +    behaviors().supportBufferType();
    +    #endif
     }
     
    -extern "C"
    -    DL_EXPORT(void)
    -    init_backend_agg(void)
    +PyMODINIT_FUNC
    +#if PY3K
    +PyInit__backend_agg(void)
    +#else
    +init_backend_agg(void)
    +#endif
     {
         //static _backend_agg_module* _backend_agg = new _backend_agg_module;
     
    @@ -2415,4 +2507,8 @@
     
         static _backend_agg_module* _backend_agg = NULL;
         _backend_agg = new _backend_agg_module;
    +
    +    #if PY3K
    +    return _backend_agg->module().ptr();
    +    #endif
     }
    diff -Nru matplotlib-1.1.1/src/_backend_agg.h matplotlib-1.2.0/src/_backend_agg.h
    --- matplotlib-1.1.1/src/_backend_agg.h	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/_backend_agg.h	2012-10-31 00:11:14.000000000 +0000
    @@ -195,6 +195,10 @@
         Py::Object restore_region(const Py::Tuple & args);
         Py::Object restore_region2(const Py::Tuple & args);
     
    +    #if PY3K
    +    virtual int buffer_get( Py_buffer *, int flags );
    +    #endif
    +
         virtual ~RendererAgg();
     
         static const size_t PIXELS_PER_INCH;
    @@ -260,7 +264,8 @@
          const Py::Object&              edgecolors_obj,
          const Py::SeqBase&  linewidths,
          const Py::SeqBase& linestyles_obj,
    -     const Py::SeqBase&    antialiaseds);
    +     const Py::SeqBase&    antialiaseds,
    +     const bool                     data_offsets);
     
         void
         _draw_gouraud_triangle(
    @@ -296,4 +301,3 @@
     
     
     #endif
    -
    diff -Nru matplotlib-1.1.1/src/_backend_gdk.c matplotlib-1.2.0/src/_backend_gdk.c
    --- matplotlib-1.1.1/src/_backend_gdk.c	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/_backend_gdk.c	2012-10-31 00:11:14.000000000 +0000
    @@ -52,7 +52,7 @@
         { NULL, NULL, 0 }
     };
     
    -DL_EXPORT(void)
    +PyMODINIT_FUNC
     init_backend_gdk(void)
     {
         PyObject *mod;
    diff -Nru matplotlib-1.1.1/src/_gtkagg.cpp matplotlib-1.2.0/src/_gtkagg.cpp
    --- matplotlib-1.1.1/src/_gtkagg.cpp	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/_gtkagg.cpp	2012-10-31 00:11:14.000000000 +0000
    @@ -131,9 +131,7 @@
         }
     };
     
    -
    -extern "C"
    -DL_EXPORT(void)
    +PyMODINIT_FUNC
     init_gtkagg(void)
     {
         init_pygobject();
    diff -Nru matplotlib-1.1.1/src/_image.cpp matplotlib-1.2.0/src/_image.cpp
    --- matplotlib-1.1.1/src/_image.cpp	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/_image.cpp	2012-10-31 00:11:14.000000000 +0000
    @@ -33,7 +33,8 @@
     #include "mplutils.h"
     
     
    -typedef agg::pixfmt_rgba32_pre pixfmt;
    +typedef agg::pixfmt_rgba32 pixfmt;
    +typedef agg::pixfmt_rgba32_pre pixfmt_pre;
     typedef agg::renderer_base renderer_base;
     typedef agg::span_interpolator_linear<> interpolator_type;
     typedef agg::rasterizer_scanline_aa rasterizer;
    @@ -200,8 +201,13 @@
     
         std::pair bufpair = _get_output_buffer();
     
    +    #if PY3K
    +    Py::Object ret =  Py::asObject(Py_BuildValue("lly#", rowsOut, colsOut,
    +                                   bufpair.first, colsOut * rowsOut * 4));
    +    #else
         Py::Object ret =  Py::asObject(Py_BuildValue("lls#", rowsOut, colsOut,
                                        bufpair.first, colsOut * rowsOut * 4));
    +    #endif
     
         if (bufpair.second) delete [] bufpair.first;
         return ret;
    @@ -221,9 +227,14 @@
     
         args.verify_length(1);
         int format = Py::Int(args[0]);
    -
    +    PyObject* py_buffer = NULL;
         int row_len = colsOut * 4;
    -    PyObject* py_buffer = PyBuffer_New(row_len * rowsOut);
    +#if PY3K
    +    unsigned char* buf = (unsigned char *)malloc(row_len * rowsOut);
    +    if (buf == NULL)
    +        throw Py::MemoryError("Image::color_conv could not allocate memory");
    +#else
    +    py_buffer = PyBuffer_New(row_len * rowsOut);
         if (py_buffer == NULL)
             throw Py::MemoryError("Image::color_conv could not allocate memory");
     
    @@ -231,7 +242,11 @@
         Py_ssize_t buffer_len;
         int ret = PyObject_AsWriteBuffer(py_buffer, &buf, &buffer_len);
         if (ret != 0)
    +    {
    +        Py_XDECREF(py_buffer);
             throw Py::MemoryError("Image::color_conv could not allocate memory");
    +    }
    +#endif
     
         agg::rendering_buffer rtmp;
         rtmp.attach(reinterpret_cast(buf), colsOut, rowsOut,
    @@ -246,9 +261,17 @@
             agg::color_conv(&rtmp, rbufOut, agg::color_conv_rgba32_to_argb32());
             break;
         default:
    +        Py_XDECREF(py_buffer);
             throw Py::ValueError("Image::color_conv unknown format");
         }
     
    +#if PY3K
    +    py_buffer = PyByteArray_FromStringAndSize((char *)buf, row_len * rowsOut);
    +    if (py_buffer == NULL) {
    +        free(buf);
    +    }
    +#endif
    +
         PyObject* o = Py_BuildValue("llN", rowsOut, colsOut, py_buffer);
         return Py::asObject(o);
     }
    @@ -408,20 +431,24 @@
         ras.add_path(imageBox);
     
         typedef agg::wrap_mode_reflect reflect_type;
    -    typedef agg::image_accessor_wrap img_accessor_type;
    +    typedef agg::image_accessor_wrap img_accessor_type;
     
    -    pixfmt pixfmtin(*rbufIn);
    +    pixfmt_pre pixfmtin(*rbufIn);
         img_accessor_type ia(pixfmtin);
         switch (interpolation)
         {
     
         case NEAREST:
         {
    -        typedef agg::span_image_filter_rgba_nn span_gen_type;
    -        typedef agg::renderer_scanline_aa renderer_type;
    -        span_gen_type sg(ia, interpolator);
    -        renderer_type ri(rb, sa, sg);
    -        agg::render_scanlines(ras, sl, ri);
    +        if (colsIn == numcols && rowsIn == numrows) {
    +            memcpy(bufferOut, bufferIn, colsIn * rowsIn * 4);
    +        } else {
    +            typedef agg::span_image_filter_rgba_nn span_gen_type;
    +            typedef agg::renderer_scanline_aa renderer_type;
    +            span_gen_type sg(ia, interpolator);
    +            renderer_type ri(rb, sa, sg);
    +            agg::render_scanlines(ras, sl, ri);
    +        }
         }
         break;
     
    @@ -1529,10 +1556,10 @@
         Py::Object xp = args[0];
         Py::Object yp = args[1];
         Py::Object dp = args[2];
    -    unsigned int rows = Py::Int(args[3]);
    -    unsigned int cols = Py::Int(args[4]);
    +    unsigned int rows = (unsigned long)Py::Int(args[3]);
    +    unsigned int cols = (unsigned long)Py::Int(args[4]);
         Py::Tuple bounds = args[5];
    -    unsigned int interpolation = Py::Int(args[6]);
    +    unsigned int interpolation = (unsigned long)Py::Int(args[6]);
     
         if (rows >= 32768 || cols >= 32768)
         {
    @@ -1926,17 +1953,13 @@
         return Py::asObject(imo);
     }
     
    -
    -
    -#if defined(_MSC_VER)
    -DL_EXPORT(void)
    -#elif defined(__cplusplus)
    -extern "C" void
    +#if PY3K
    +PyMODINIT_FUNC
    +PyInit__image(void)
     #else
    -void
    -#endif
    -
    +PyMODINIT_FUNC
     init_image(void)
    +#endif
     {
         _VERBOSE("init_image");
     
    @@ -1965,8 +1988,8 @@
     
         d["ASPECT_FREE"] = Py::Int(Image::ASPECT_FREE);
         d["ASPECT_PRESERVE"] = Py::Int(Image::ASPECT_PRESERVE);
    -}
    -
    -
    -
     
    +#if PY3K
    +    return _image->module().ptr();
    +#endif
    +}
    diff -Nru matplotlib-1.1.1/src/_macosx.m matplotlib-1.2.0/src/_macosx.m
    --- matplotlib-1.1.1/src/_macosx.m	2012-06-30 18:47:51.000000000 +0000
    +++ matplotlib-1.2.0/src/_macosx.m	2012-10-31 00:11:14.000000000 +0000
    @@ -27,6 +27,9 @@
     #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
     #define COMPILING_FOR_10_5
     #endif
    +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
    +#define COMPILING_FOR_10_6
    +#endif
     
     static int nwin = 0;   /* The number of open windows */
     
    @@ -352,7 +355,11 @@
     - (void)close;
     @end
     
    +#ifdef COMPILING_FOR_10_6
    +@interface View : NSView 
    +#else
     @interface View : NSView
    +#endif
     {   PyObject* canvas;
         NSRect rubberband;
         BOOL inside;
    @@ -418,6 +425,7 @@
         NSSize size;
         int level;
         CGFloat color[4];
    +    float dpi;
     } GraphicsContext;
     
     static CGMutablePathRef _create_path(void* iterator)
    @@ -843,6 +851,15 @@
     }
     
     static PyObject*
    +GraphicsContext_set_dpi (GraphicsContext* self, PyObject* args)
    +{
    +  if (!PyArg_ParseTuple(args, "f", &(self->dpi))) return NULL;
    +
    +  Py_INCREF(Py_None);
    +  return Py_None;
    +}
    +
    +static PyObject*
     GraphicsContext_set_linewidth (GraphicsContext* self, PyObject* args)
     {
         float width;
    @@ -855,6 +872,8 @@
             return NULL;
         }
     
    +    // Convert points to pixels
    +    width *= self->dpi / 72.0;
         CGContextSetLineWidth(cr, width);
     
         Py_INCREF(Py_None);
    @@ -1175,56 +1194,42 @@
         return true;
     }
     
    -static BOOL
    -_set_offset(CGContextRef cr, PyObject* offsets, int index, PyObject* transform)
    +static int _transformation_converter(PyObject* object, void* pointer)
     {
    -    CGFloat tx;
    -    CGFloat ty;
    -    double x = *(double*)PyArray_GETPTR2(offsets, index, 0);
    -    double y = *(double*)PyArray_GETPTR2(offsets, index, 1);
    -    PyObject* translation = PyObject_CallMethod(transform, "transform_point",
    -                                                           "((ff))", x, y);
    -    if (!translation)
    -    {
    -        return false;
    -    }
    -    if (!PyArray_Check(translation))
    -    {
    -        Py_DECREF(translation);
    -        PyErr_SetString(PyExc_ValueError,
    -            "transform_point did not return a NumPy array");
    -        return false;
    -    }
    -    if (PyArray_NDIM(translation)!=1 || PyArray_DIM(translation, 0)!=2)
    -    {
    -        Py_DECREF(translation);
    -        PyErr_SetString(PyExc_ValueError,
    -            "transform_point did not return an approriate array");
    -        return false;
    -    }
    -    tx = (CGFloat)(*(double*)PyArray_GETPTR1(translation, 0));
    -    ty = (CGFloat)(*(double*)PyArray_GETPTR1(translation, 1));
    -    Py_DECREF(translation);
    -    CGContextTranslateCTM(cr, tx, ty);
    -    return true;
    +    CGAffineTransform* matrix = (CGAffineTransform*)pointer;
    +    if (!PyArray_Check(object) || PyArray_NDIM(object)!=2
    +        || PyArray_DIM(object, 0)!=3 || PyArray_DIM(object, 1)!=3)
    +        {
    +            PyErr_SetString(PyExc_ValueError,
    +                "transformation matrix is not a 3x3 NumPy array");
    +            return 0;
    +        }
    +    const double a =  *(double*)PyArray_GETPTR2(object, 0, 0);
    +    const double b =  *(double*)PyArray_GETPTR2(object, 0, 1);
    +    const double c =  *(double*)PyArray_GETPTR2(object, 1, 0);
    +    const double d =  *(double*)PyArray_GETPTR2(object, 1, 1);
    +    const double tx =  *(double*)PyArray_GETPTR2(object, 0, 2);
    +    const double ty =  *(double*)PyArray_GETPTR2(object, 1, 2);
    +    *matrix = CGAffineTransformMake(a, b, c, d, tx, ty);
    +    return 1;
     }
     
     static PyObject*
     GraphicsContext_draw_path_collection (GraphicsContext* self, PyObject* args)
     {
    -    PyObject* cliprect;
    -    PyObject* clippath;
    -    PyObject* clippath_transform;
    -    PyObject* paths;
    -    PyObject* transforms;
    +    CGAffineTransform master;
    +    PyObject* path_ids;
    +    PyObject* all_transforms;
         PyObject* offsets;
    -    PyObject* offset_transform;
    +    CGAffineTransform offset_transform;
         PyObject* facecolors;
         PyObject* edgecolors;
         PyObject* linewidths;
         PyObject* linestyles;
         PyObject* antialiaseds;
     
    +    int offset_position = 0;
    +
         CGContextRef cr = self->cr;
     
         if (!cr)
    @@ -1233,26 +1238,70 @@
             return NULL;
         }
     
    -    if(!PyArg_ParseTuple(args, "OOOOOOOOOOOO", &cliprect,
    -                                               &clippath,
    -                                               &clippath_transform,
    -                                               &paths,
    -                                               &transforms,
    -                                               &offsets,
    -                                               &offset_transform,
    -                                               &facecolors,
    -                                               &edgecolors,
    -                                               &linewidths,
    -                                               &linestyles,
    -                                               &antialiaseds))
    +    if(!PyArg_ParseTuple(args, "O&OOOO&OOOOOi",
    +                               _transformation_converter, &master,
    +                               &path_ids,
    +                               &all_transforms,
    +                               &offsets,
    +                               _transformation_converter, &offset_transform,
    +                               &facecolors,
    +                               &edgecolors,
    +                               &linewidths,
    +                               &linestyles,
    +                               &antialiaseds,
    +                               &offset_position))
             return NULL;
     
         int ok = 1;
         Py_ssize_t i;
    -    Py_ssize_t Np = 0;
    -    Py_ssize_t N = 0;
     
         CGMutablePathRef* p = NULL;
    +    CGAffineTransform* transforms = NULL;
    +    CGPoint *toffsets = NULL;
    +    CGPatternRef pattern = NULL;
    +    CGColorSpaceRef patternSpace = NULL;
    +
    +    PyObject* hatchpath;
    +    hatchpath = PyObject_CallMethod((PyObject*)self, "get_hatch_path", "");
    +    if (!hatchpath)
    +    {
    +        return NULL;
    +    }
    +    else if (hatchpath==Py_None)
    +    {
    +        Py_DECREF(hatchpath);
    +    }
    +    else
    +    {
    +        CGColorSpaceRef baseSpace;
    +        static const CGPatternCallbacks callbacks = {0,
    +                                                     &_draw_hatch,
    +                                                     &_release_hatch};
    +        baseSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
    +        if (!baseSpace)
    +        {
    +            Py_DECREF(hatchpath);
    +            PyErr_SetString(PyExc_RuntimeError,
    +                "draw_path: CGColorSpaceCreateWithName failed");
    +            return NULL;
    +        }
    +        patternSpace = CGColorSpaceCreatePattern(baseSpace);
    +        CGColorSpaceRelease(baseSpace);
    +        if (!patternSpace)
    +        {
    +            Py_DECREF(hatchpath);
    +            PyErr_SetString(PyExc_RuntimeError,
    +                "draw_path: CGColorSpaceCreatePattern failed");
    +            return NULL;
    +        }
    +        pattern = CGPatternCreate((void*)hatchpath,
    +                                  CGRectMake(0, 0, HATCH_SIZE, HATCH_SIZE),
    +                                  CGAffineTransformIdentity,
    +                                  HATCH_SIZE, HATCH_SIZE,
    +                                  kCGPatternTilingNoDistortion,
    +                                  false,
    +                                  &callbacks);
    +    }
     
         /* --------- Prepare some variables for the path iterator ------------- */
         void* iterator;
    @@ -1266,48 +1315,20 @@
     
         /* ------------------- Check paths ------------------------------------ */
     
    -    if (!PySequence_Check(paths))
    +    if (!PySequence_Check(path_ids))
         {
             PyErr_SetString(PyExc_ValueError, "paths must be a sequence object");
             return NULL;
         }
    -    const Py_ssize_t Npaths = PySequence_Size(paths);
    -
    -    /* ------------------- Check transforms ------------------------------- */
    -
    -    if (!PySequence_Check(transforms))
    -    {
    -        PyErr_SetString(PyExc_ValueError, "transforms must be a sequence object");
    -        return NULL;
    -    }
    -    const Py_ssize_t Ntransforms = PySequence_Size(transforms);
    -    if (Ntransforms==0)
    -    {
    -        PyErr_SetString(PyExc_ValueError, "transforms should contain at least one item");
    -        return NULL;
    -    }
    -
    -    /* ------------------- Read drawing arrays ---------------------------- */
    +    const Py_ssize_t Npaths = PySequence_Size(path_ids);
    +    
    +    /* -------------------------------------------------------------------- */
     
         CGContextSaveGState(cr);
    -    offsets = PyArray_FromObject(offsets, NPY_DOUBLE, 0, 2);
    -    facecolors = PyArray_FromObject(facecolors, NPY_DOUBLE, 1, 2);
    -    edgecolors = PyArray_FromObject(edgecolors, NPY_DOUBLE, 1, 2);
    -
    -    /* ------------------- Check offsets array ---------------------------- */
    -
    -    if (!offsets ||
    -        (PyArray_NDIM(offsets)==2 && PyArray_DIM(offsets, 1)!=2) ||
    -        (PyArray_NDIM(offsets)==1 && PyArray_DIM(offsets, 0)!=0))
    -    {
    -        PyErr_SetString(PyExc_ValueError, "Offsets array must be Nx2");
    -        ok = 0;
    -        goto exit;
    -    }
    -    const Py_ssize_t Noffsets = PyArray_DIM(offsets, 0);
    -
    +    
         /* ------------------- Check facecolors array ------------------------- */
     
    +    facecolors = PyArray_FromObject(facecolors, NPY_DOUBLE, 1, 2);
         if (!facecolors ||
             (PyArray_NDIM(facecolors)==1 && PyArray_DIM(facecolors, 0)!=0) ||
             (PyArray_NDIM(facecolors)==2 && PyArray_DIM(facecolors, 1)!=4))
    @@ -1316,9 +1337,11 @@
             ok = 0;
             goto exit;
         }
    +    Py_ssize_t Nfacecolors = PyArray_DIM(facecolors, 0);
     
         /* ------------------- Check edgecolors array ------------------------- */
     
    +    edgecolors = PyArray_FromObject(edgecolors, NPY_DOUBLE, 1, 2);
         if (!edgecolors ||
             (PyArray_NDIM(edgecolors)==1 && PyArray_DIM(edgecolors, 0)!=0) ||
             (PyArray_NDIM(edgecolors)==2 && PyArray_DIM(edgecolors, 1)!=4))
    @@ -1327,41 +1350,96 @@
             ok = 0;
             goto exit;
         }
    +    Py_ssize_t Nedgecolors = PyArray_DIM(edgecolors, 0);
     
         /* -------------------------------------------------------------------- */
     
    -    if (Npaths==0) goto exit; /* Nothing to do */
    +    if ((Nfacecolors==0 && Nedgecolors==0) || Npaths==0) /* Nothing to do */
    +        goto exit;
     
    -    /* -------------------------------------------------------------------- */
    +    /* ------------------- Check offsets array ---------------------------- */
    +
    +    offsets = PyArray_FromObject(offsets, NPY_DOUBLE, 0, 2);
    +
    +    if (!offsets ||
    +        (PyArray_NDIM(offsets)==2 && PyArray_DIM(offsets, 1)!=2) ||
    +        (PyArray_NDIM(offsets)==1 && PyArray_DIM(offsets, 0)!=0))
    +    {
    +        Py_XDECREF(offsets);
    +        PyErr_SetString(PyExc_ValueError, "Offsets array must be Nx2");
    +        ok = 0;
    +        goto exit;
    +    }
    +    const Py_ssize_t Noffsets = PyArray_DIM(offsets, 0);
    +    if (Noffsets > 0) {
    +        toffsets = malloc(Noffsets*sizeof(CGPoint));
    +        if (!toffsets)
    +        {
    +            Py_DECREF(offsets);
    +            ok = 0;
    +            goto exit;
    +        }
    +        CGPoint point;
    +        for (i = 0; i < Noffsets; i++)
    +        {
    +            point.x = (CGFloat) (*(double*)PyArray_GETPTR2(offsets, i, 0));
    +            point.y = (CGFloat) (*(double*)PyArray_GETPTR2(offsets, i, 1));
    +            toffsets[i] = CGPointApplyAffineTransform(point, offset_transform);
    +        }
    +    }
    +    Py_DECREF(offsets);
     
    -    Np = Npaths > Ntransforms ? Npaths : Ntransforms;
    -    N = Np > Noffsets ? Np : Noffsets;
    +    /* ------------------- Check transforms ------------------------------- */
     
    -    p = malloc(Np*sizeof(CGMutablePathRef));
    +    if (!PySequence_Check(all_transforms))
    +    {
    +        PyErr_SetString(PyExc_ValueError, "transforms must be a sequence object");
    +        return NULL;
    +    }
    +    const Py_ssize_t Ntransforms = PySequence_Size(all_transforms);
    +    if (Ntransforms > 0)
    +    {
    +        transforms = malloc(Ntransforms*sizeof(CGAffineTransform));
    +        if (!transforms)
    +            goto exit;
    +        for (i = 0; i < Ntransforms; i++)
    +        {
    +            PyObject* transform = PySequence_ITEM(all_transforms, i);
    +            if (!transform) goto exit;
    +            ok = _transformation_converter(transform, &transforms[i]);
    +            Py_DECREF(transform);
    +            if (!ok) goto exit;
    +        }
    +    }
    +
    +    /* -------------------------------------------------------------------- */
    +
    +    p = malloc(Npaths*sizeof(CGMutablePathRef));
         if (!p)
         {
             ok = 0;
             goto exit;
         }
    -    for (i = 0; i < Np; i++)
    +    for (i = 0; i < Npaths; i++)
         {
             PyObject* path;
             PyObject* transform;
             p[i] = NULL;
    -        path = PySequence_ITEM(paths, i % Npaths);
    -        if (!path)
    +        PyObject* path_id = PySequence_ITEM(path_ids, i);
    +        if (!path_id)
             {
                 ok = 0;
                 goto exit;
             }
    -        transform = PySequence_ITEM(transforms, i % Ntransforms);
    -        if (!transform)
    +        if (!PyTuple_Check(path_id) || PyTuple_Size(path_id)!=2)
             {
    -            PyErr_SetString(PyExc_RuntimeError, "failed to obtain transform");
    -            Py_DECREF(path);
                 ok = 0;
    +            PyErr_SetString(PyExc_RuntimeError,
    +                            "path_id should be a tuple of two items");
                 goto exit;
             }
    +        path = PyTuple_GET_ITEM(path_id, 0);
    +        transform = PyTuple_GET_ITEM(path_id, 1);
             iterator = get_path_iterator(path,
                                          transform,
                                          1,
    @@ -1380,8 +1458,6 @@
                                             is probably ok for now.  --
                                             MGD */
                                          0);
    -        Py_DECREF(transform);
    -        Py_DECREF(path);
             if (!iterator)
             {
                 PyErr_SetString(PyExc_RuntimeError,
    @@ -1391,6 +1467,7 @@
             }
             p[i] = _create_path(iterator);
             free_path_iterator(iterator);
    +        Py_DECREF(path_id);
             if (!p[i])
             {
                 PyErr_SetString(PyExc_RuntimeError, "failed to create path");
    @@ -1399,36 +1476,6 @@
             }
         }
     
    -    /* ------------------- Set clipping path ------------------------------ */
    -
    -    if (!_clip(cr, cliprect))
    -    {
    -        ok = 0;
    -        goto exit;
    -    }
    -    if (clippath!=Py_None)
    -    {
    -        int n;
    -        iterator  = get_path_iterator(clippath,
    -                                      clippath_transform,
    -                                      0,
    -                                      0,
    -                                      rect,
    -                                      SNAP_AUTO,
    -                                      1.0,
    -                                      0);
    -        if (!iterator)
    -        {
    -            PyErr_SetString(PyExc_RuntimeError,
    -                "draw_path_collection: failed to obtain path iterator for clipping");
    -            ok = 0;
    -            goto exit;
    -        }
    -        n = _draw_path(cr, iterator);
    -        free_path_iterator(iterator);
    -        if (n > 0) CGContextClip(cr);
    -    }
    -
         /* ------------------- Check the other arguments ---------------------- */
     
         if (!PySequence_Check(linewidths))
    @@ -1450,13 +1497,9 @@
             goto exit;
         }
     
    -    Py_ssize_t Nfacecolors = PyArray_DIM(facecolors, 0);
    -    Py_ssize_t Nedgecolors = PyArray_DIM(edgecolors, 0);
         Py_ssize_t Nlinewidths = PySequence_Size(linewidths);
         Py_ssize_t Nlinestyles = PySequence_Size(linestyles);
         Py_ssize_t Naa         = PySequence_Size(antialiaseds);
    -    if (N < Nlinestyles) Nlinestyles = N;
    -    if ((Nfacecolors == 0 && Nedgecolors == 0) || Np == 0) goto exit;
     
         /* Preset graphics context properties if possible */
         if (Naa==1)
    @@ -1476,7 +1519,9 @@
             if (!ok) goto exit;
         }
     
    -    if (Nlinewidths==1)
    +    if (Nlinewidths==0 || Nedgecolors==0)
    +        CGContextSetLineWidth(cr, 0.0);
    +    else if (Nlinewidths==1)
         {
             PyObject* linewidth = PySequence_ITEM(linewidths, 0);
             if (!linewidth)
    @@ -1489,8 +1534,6 @@
             CGContextSetLineWidth(cr, (CGFloat)PyFloat_AsDouble(linewidth));
             Py_DECREF(linewidth);
         }
    -    else if (Nlinewidths==0)
    -        CGContextSetLineWidth(cr, 0.0);
     
         if (Nlinestyles==1)
         {
    @@ -1514,6 +1557,17 @@
             const double b = *(double*)PyArray_GETPTR2(edgecolors, 0, 2);
             const double a = *(double*)PyArray_GETPTR2(edgecolors, 0, 3);
             CGContextSetRGBStrokeColor(cr, r, g, b, a);
    +        self->color[0] = r;
    +        self->color[1] = g;
    +        self->color[2] = b;
    +        self->color[3] = a;
    +    }
    +    else /* We may need these for hatching */
    +    {
    +        self->color[0] = 0;
    +        self->color[1] = 0;
    +        self->color[2] = 0;
    +        self->color[3] = 1;
         }
     
         if (Nfacecolors==1)
    @@ -1525,19 +1579,29 @@
             CGContextSetRGBFillColor(cr, r, g, b, a);
         }
     
    +    CGPoint translation = CGPointZero;
    +
    +    const Py_ssize_t N = Npaths > Noffsets ? Npaths : Noffsets;
         for (i = 0; i < N; i++)
         {
    -        if (CGPathIsEmpty(p[i % Np])) continue;
    +        if (CGPathIsEmpty(p[i % Npaths])) continue;
     
    -        CGContextSaveGState(cr);
             if (Noffsets)
             {
    -            ok = _set_offset(cr, offsets, i % Noffsets, offset_transform);
    -            if (!ok)
    +            CGAffineTransform t;
    +            CGPoint origin;
    +            translation = toffsets[i % Noffsets];
    +            if (offset_position)
                 {
    -                CGContextRestoreGState(cr);
    -                goto exit;
    +                t = master;
    +                if (Ntransforms)
    +                    t = CGAffineTransformConcat(transforms[i % Ntransforms], t);
    +                translation = CGPointApplyAffineTransform(translation, t);
    +                origin = CGPointApplyAffineTransform(CGPointZero, t);
    +                translation.x = - (origin.x - translation.x);
    +                translation.y = - (origin.y - translation.y);
                 }
    +            CGContextTranslateCTM(cr, translation.x, translation.y);
             }
     
             if (Naa > 1)
    @@ -1596,7 +1660,7 @@
                 CGContextSetRGBStrokeColor(cr, r, g, b, a);
             }
     
    -        CGContextAddPath(cr, p[i % Np]);
    +        CGContextAddPath(cr, p[i % Npaths]);
     
             if (Nfacecolors > 1)
             {
    @@ -1616,17 +1680,32 @@
             }
             else /* We checked Nedgecolors != 0 above */
                 CGContextStrokePath(cr);
    -        CGContextRestoreGState(cr);
    +
    +        if (pattern)
    +        {
    +            CGContextSaveGState(cr);
    +            CGContextSetFillColorSpace(cr, patternSpace);
    +            CGContextSetFillPattern(cr, pattern, self->color);
    +            CGContextAddPath(cr, p[i % Npaths]);
    +            CGContextFillPath(cr);
    +            CGContextRestoreGState(cr);
    +        }
    +
    +        if (Noffsets)
    +            CGContextTranslateCTM(cr, -translation.x, -translation.y);
         }
     
     exit:
         CGContextRestoreGState(cr);
    -    Py_XDECREF(offsets);
         Py_XDECREF(facecolors);
         Py_XDECREF(edgecolors);
    +    if (pattern) CGPatternRelease(pattern);
    +    if (patternSpace) CGColorSpaceRelease(patternSpace);
    +    if (transforms) free(transforms);
    +    if (toffsets) free(toffsets);
         if (p)
         {
    -        for (i = 0; i < Np; i++)
    +        for (i = 0; i < Npaths; i++)
             {
                 if (!p[i]) break;
                 CGPathRelease(p[i]);
    @@ -1641,18 +1720,17 @@
     static PyObject*
     GraphicsContext_draw_quad_mesh (GraphicsContext* self, PyObject* args)
     {
    -    PyObject* master_transform;
    -    PyObject* cliprect;
    -    PyObject* clippath;
    -    PyObject* clippath_transform;
    +    CGAffineTransform master;
         int meshWidth;
         int meshHeight;
         PyObject* coordinates;
         PyObject* offsets;
    -    PyObject* offset_transform;
    +    CGAffineTransform offset_transform;
         PyObject* facecolors;
         int antialiased;
    -    int showedges;
    +    PyObject* edgecolors;
    +
    +    CGPoint *toffsets = NULL;
     
         CGContextRef cr = self->cr;
     
    @@ -1662,81 +1740,20 @@
             return NULL;
         }
     
    -    if(!PyArg_ParseTuple(args, "OOOOiiOOOOii",
    -                               &master_transform,
    -                               &cliprect,
    -                               &clippath,
    -                               &clippath_transform,
    +    if(!PyArg_ParseTuple(args, "O&iiOOO&OiO",
    +                               _transformation_converter, &master,
                                    &meshWidth,
                                    &meshHeight,
                                    &coordinates,
                                    &offsets,
    -                               &offset_transform,
    +                               _transformation_converter, &offset_transform,
                                    &facecolors,
                                    &antialiased,
    -                               &showedges)) return NULL;
    +                               &edgecolors)) return NULL;
     
         int ok = 1;
         CGContextSaveGState(cr);
     
    -    CGAffineTransform master;
    -    double rect[4] = {0.0, 0.0, self->size.width, self->size.height};
    -
    -    /* ------------------- Set master transform --------------------------- */
    -
    -    PyObject* values = PyObject_CallMethod(master_transform, "to_values", "");
    -    if (!values)
    -    {
    -        ok = 0;
    -        goto exit;
    -    }
    -    if (PyTuple_Check(values))
    -    {
    -        double a, b, c, d, tx, ty;
    -        /* CGAffineTransform contains CGFloat; cannot use master directly */
    -        ok = PyArg_ParseTuple(values, "dddddd", &a, &b, &c, &d, &tx, &ty);
    -        master.a = a;
    -        master.b = b;
    -        master.c = c;
    -        master.d = d;
    -        master.tx = tx;
    -        master.ty = ty;
    -    }
    -    else
    -    {
    -        ok = 0;
    -    }
    -    Py_DECREF(values);
    -    if (!ok) goto exit;
    -    CGContextConcatCTM(cr, master);
    -
    -    /* ------------------- Set clipping path ------------------------------ */
    -
    -    ok = _clip(cr, cliprect);
    -    if (!ok) goto exit;
    -    if (clippath!=Py_None)
    -    {
    -        int n;
    -        void* iterator  = get_path_iterator(clippath,
    -                                            clippath_transform,
    -                                            0,
    -                                            0,
    -                                            rect,
    -                                            SNAP_AUTO,
    -                                            1.0,
    -                                            0);
    -        if (iterator)
    -        {
    -            PyErr_SetString(PyExc_RuntimeError,
    -                "draw_quad_mesh: failed to obtain path iterator");
    -            ok = 0;
    -            goto exit;
    -        }
    -        n = _draw_path(cr, iterator);
    -        free_path_iterator(iterator);
    -        if (n > 0) CGContextClip(cr);
    -    }
    -
         /* ------------------- Check coordinates array ------------------------ */
     
         coordinates = PyArray_FromObject(coordinates, NPY_DOUBLE, 3, 3);
    @@ -1751,15 +1768,35 @@
         /* ------------------- Check offsets array ---------------------------- */
     
         offsets = PyArray_FromObject(offsets, NPY_DOUBLE, 0, 2);
    +
         if (!offsets ||
             (PyArray_NDIM(offsets)==2 && PyArray_DIM(offsets, 1)!=2) ||
             (PyArray_NDIM(offsets)==1 && PyArray_DIM(offsets, 0)!=0))
         {
    +        Py_XDECREF(offsets);
             PyErr_SetString(PyExc_ValueError, "Offsets array must be Nx2");
             ok = 0;
             goto exit;
         }
         const Py_ssize_t Noffsets = PyArray_DIM(offsets, 0);
    +    if (Noffsets > 0) {
    +        int i;
    +        toffsets = malloc(Noffsets*sizeof(CGPoint));
    +        if (!toffsets)
    +        {
    +            Py_DECREF(offsets);
    +            ok = 0;
    +            goto exit;
    +        }
    +        CGPoint point;
    +        for (i = 0; i < Noffsets; i++)
    +        {
    +            point.x = (CGFloat) (*(double*)PyArray_GETPTR2(offsets, i, 0));
    +            point.y = (CGFloat) (*(double*)PyArray_GETPTR2(offsets, i, 1));
    +            toffsets[i] = CGPointApplyAffineTransform(point, offset_transform);
    +        }
    +    }
    +    Py_DECREF(offsets);
     
         /* ------------------- Check facecolors array ------------------------- */
     
    @@ -1768,7 +1805,19 @@
             (PyArray_NDIM(facecolors)==1 && PyArray_DIM(facecolors, 0)!=0) ||
             (PyArray_NDIM(facecolors)==2 && PyArray_DIM(facecolors, 1)!=4))
         {
    -        PyErr_SetString(PyExc_ValueError, "Facecolors must by a Nx4 numpy array or empty");
    +        PyErr_SetString(PyExc_ValueError, "facecolors must by a Nx4 numpy array or empty");
    +        ok = 0;
    +        goto exit;
    +    }
    +
    +    /* ------------------- Check edgecolors array ------------------------- */
    +
    +    edgecolors = PyArray_FromObject(edgecolors, NPY_DOUBLE, 1, 2);
    +    if (!edgecolors ||
    +        (PyArray_NDIM(edgecolors)==1 && PyArray_DIM(edgecolors, 0)!=0) ||
    +        (PyArray_NDIM(edgecolors)==2 && PyArray_DIM(edgecolors, 1)!=4))
    +    {
    +        PyErr_SetString(PyExc_ValueError, "edgecolors must by a Nx4 numpy array or empty");
             ok = 0;
             goto exit;
         }
    @@ -1777,7 +1826,8 @@
     
         size_t Npaths      = meshWidth * meshHeight;
         size_t Nfacecolors = (size_t) PyArray_DIM(facecolors, 0);
    -    if ((Nfacecolors == 0 && !showedges) || Npaths == 0)
    +    size_t Nedgecolors = (size_t) PyArray_DIM(edgecolors, 0);
    +    if ((Nfacecolors == 0 && Nedgecolors == 0) || Npaths == 0)
         {
             /* Nothing to do here */
             goto exit;
    @@ -1797,33 +1847,26 @@
             const double b = *(double*)PyArray_GETPTR2(facecolors, 0, 2);
             const double a = *(double*)PyArray_GETPTR2(facecolors, 0, 3);
             CGContextSetRGBFillColor(cr, r, g, b, a);
    -        if (antialiased && !showedges)
    +        if (antialiased && Nedgecolors==0)
             {
                 CGContextSetRGBStrokeColor(cr, r, g, b, a);
             }
         }
    -
    -    if (showedges)
    +    if (Nedgecolors==1)
         {
    -        CGContextSetRGBStrokeColor(cr, 0, 0, 0, 1);
    +        const double r = *(double*)PyArray_GETPTR2(edgecolors, 0, 0);
    +        const double g = *(double*)PyArray_GETPTR2(edgecolors, 0, 1);
    +        const double b = *(double*)PyArray_GETPTR2(edgecolors, 0, 2);
    +        const double a = *(double*)PyArray_GETPTR2(edgecolors, 0, 3);
    +        CGContextSetRGBStrokeColor(cr, r, g, b, a);
         }
     
    +    CGPoint translation = CGPointZero;
         double x, y;
         for (ih = 0; ih < meshHeight; ih++)
         {
             for (iw = 0; iw < meshWidth; iw++, i++)
             {
    -            CGContextSaveGState(cr);
    -            if (Noffsets)
    -            {
    -                ok = _set_offset(cr, offsets, i % Noffsets, offset_transform);
    -                if (!ok)
    -                {
    -                    CGContextRestoreGState(cr);
    -                    goto exit;
    -                }
    -            }
    -
                 CGPoint points[4];
     
                 x = *(double*)PyArray_GETPTR3(coordinates, ih, iw, 0);
    @@ -1850,6 +1893,17 @@
                 points[3].x = (CGFloat)x;
                 points[3].y = (CGFloat)y;
     
    +            points[0] = CGPointApplyAffineTransform(points[0], master);
    +            points[1] = CGPointApplyAffineTransform(points[1], master);
    +            points[2] = CGPointApplyAffineTransform(points[2], master);
    +            points[3] = CGPointApplyAffineTransform(points[3], master);
    +
    +            if (Noffsets)
    +            {
    +                translation = toffsets[i % Noffsets];
    +                CGContextTranslateCTM(cr, translation.x, translation.y);
    +            }
    +
                 CGContextMoveToPoint(cr, points[3].x, points[3].y);
                 CGContextAddLines(cr, points, 4);
                 CGContextClosePath(cr);
    @@ -1862,23 +1916,24 @@
                     const double b = *(double*)PyArray_GETPTR2(facecolors, fi, 2);
                     const double a = *(double*)PyArray_GETPTR2(facecolors, fi, 3);
                     CGContextSetRGBFillColor(cr, r, g, b, a);
    -                if (showedges)
    -                {
    -                    CGContextDrawPath(cr, kCGPathFillStroke);
    -                }
    -                else if (antialiased)
    +                if (antialiased && Nedgecolors==0)
                     {
                         CGContextSetRGBStrokeColor(cr, r, g, b, a);
    -                    CGContextDrawPath(cr, kCGPathFillStroke);
    -                }
    -                else
    -                {
    -                    CGContextFillPath(cr);
                     }
                 }
    -            else if (Nfacecolors==1)
    +            if (Nedgecolors > 1)
    +            {
    +                npy_intp fi = i % Nedgecolors;
    +                const double r = *(double*)PyArray_GETPTR2(edgecolors, fi, 0);
    +                const double g = *(double*)PyArray_GETPTR2(edgecolors, fi, 1);
    +                const double b = *(double*)PyArray_GETPTR2(edgecolors, fi, 2);
    +                const double a = *(double*)PyArray_GETPTR2(edgecolors, fi, 3);
    +                CGContextSetRGBStrokeColor(cr, r, g, b, a);
    +            }
    +	
    +            if (Nfacecolors > 0)
                 {
    -                if (showedges || antialiased)
    +                if (Nedgecolors > 0 || antialiased)
                     {
                         CGContextDrawPath(cr, kCGPathFillStroke);
                     }
    @@ -1887,17 +1942,20 @@
                         CGContextFillPath(cr);
                     }
                 }
    -            else if (showedges)
    +            else if (Nedgecolors > 0)
                 {
                     CGContextStrokePath(cr);
                 }
    -            CGContextRestoreGState(cr);
    +            if (Noffsets)
    +            {
    +                CGContextTranslateCTM(cr, -translation.x, -translation.y);
    +            }
             }
         }
     
     exit:
         CGContextRestoreGState(cr);
    -    Py_XDECREF(offsets);
    +    if (toffsets) free(toffsets);
         Py_XDECREF(facecolors);
         Py_XDECREF(coordinates);
     
    @@ -3156,6 +3214,11 @@
          METH_VARARGS,
          "Sets the current stroke and fill color to a value in the DeviceGray color space."
         },
    +    {"set_dpi",
    +     (PyCFunction)GraphicsContext_set_dpi,
    +     METH_VARARGS,
    +     "Sets the dpi for a graphics context."
    +    },
         {"set_linewidth",
          (PyCFunction)GraphicsContext_set_linewidth,
          METH_VARARGS,
    @@ -3446,7 +3509,7 @@
         int n;
         const unichar* characters;
         NSSize size;
    -    double width, height;
    +    double width, height, dpi;
     
         if(!view)
         {
    @@ -3454,8 +3517,8 @@
             return NULL;
         }
         /* NSSize contains CGFloat; cannot use size directly */
    -    if(!PyArg_ParseTuple(args, "u#dd",
    -                                &characters, &n, &width, &height)) return NULL;
    +    if(!PyArg_ParseTuple(args, "u#ddd",
    +                                &characters, &n, &width, &height, &dpi)) return NULL;
         size.width = width;
         size.height = height;
     
    @@ -3480,33 +3543,42 @@
         if (invalid) [view setNeedsDisplay: YES];
     
         NSImage* image = [[NSImage alloc] initWithData: data];
    -    [image setScalesWhenResized: YES];
    -    [image setSize: size];
    -    data = [image TIFFRepresentation];
    +    NSImage *resizedImage = [[NSImage alloc] initWithSize:size];
    +
    +    [resizedImage lockFocus];
    +    [image drawInRect:NSMakeRect(0, 0, width, height) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
    +    [resizedImage unlockFocus];
    +    data = [resizedImage TIFFRepresentation];
         [image release];
    +    [resizedImage release];
     
    -    if (! [extension isEqualToString: @"tiff"] &&
    -        ! [extension isEqualToString: @"tif"])
    -    {
    -        NSBitmapImageFileType filetype;
    -        NSBitmapImageRep* bitmapRep = [NSBitmapImageRep imageRepWithData: data];
    -        if ([extension isEqualToString: @"bmp"])
    -            filetype = NSBMPFileType;
    -        else if ([extension isEqualToString: @"gif"])
    -            filetype = NSGIFFileType;
    -        else if ([extension isEqualToString: @"jpg"] ||
    -                 [extension isEqualToString: @"jpeg"])
    -            filetype = NSJPEGFileType;
    -        else if ([extension isEqualToString: @"png"])
    -            filetype = NSPNGFileType;
    -        else
    -        {   PyErr_SetString(PyExc_ValueError, "Unknown file type");
    -            return NULL;
    -        }
    +    NSBitmapImageRep* rep = [NSBitmapImageRep imageRepWithData:data];
    +
    +    NSSize pxlSize = NSMakeSize([rep pixelsWide], [rep pixelsHigh]);
    +    NSSize newSize = NSMakeSize(72.0 * pxlSize.width / dpi, 72.0 * pxlSize.height / dpi);
    +
    +    [rep setSize:newSize];
     
    -        data = [bitmapRep representationUsingType:filetype properties:nil];
    +    NSBitmapImageFileType filetype;
    +    if ([extension isEqualToString: @"bmp"])
    +        filetype = NSBMPFileType;
    +    else if ([extension isEqualToString: @"gif"])
    +        filetype = NSGIFFileType;
    +    else if ([extension isEqualToString: @"jpg"] ||
    +             [extension isEqualToString: @"jpeg"])
    +        filetype = NSJPEGFileType;
    +    else if ([extension isEqualToString: @"png"])
    +        filetype = NSPNGFileType;
    +    else if ([extension isEqualToString: @"tiff"] ||
    +             [extension isEqualToString: @"tif"])
    +        filetype = NSTIFFFileType;
    +    else
    +    {   PyErr_SetString(PyExc_ValueError, "Unknown file type");
    +        return NULL;
         }
     
    +    data = [rep representationUsingType:filetype properties:nil];
    +
         [data writeToFile: filename atomically: YES];
         [pool release];
     
    @@ -3827,6 +3899,56 @@
         return Py_None;
     }
     
    +static PyObject*
    +FigureManager_set_window_title(FigureManager* self,
    +                               PyObject *args, PyObject *kwds)
    +{
    +    char* title;
    +    if(!PyArg_ParseTuple(args, "es", "UTF-8", &title))
    +        return NULL;
    +
    +    Window* window = self->window;
    +    if(window)
    +    {
    +        NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    +        NSString* ns_title = [[NSString alloc]
    +                              initWithCString: title
    +                              encoding: NSUTF8StringEncoding];
    +        [window setTitle: ns_title];
    +        [pool release];
    +    }
    +    PyMem_Free(title);
    +    Py_INCREF(Py_None);
    +    return Py_None;
    +}
    +
    +static PyObject*
    +FigureManager_get_window_title(FigureManager* self)
    +{
    +    Window* window = self->window;
    +    PyObject* result = NULL;
    +    if(window)
    +    {
    +        NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    +        NSString* title = [window title];
    +        if (title) {
    +            const char* cTitle = [title UTF8String];
    +#if PY3K || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 6)
    +            result = PyUnicode_FromString(cTitle);
    +#else
    +            result = PyString_FromString(cTitle);
    +#endif
    +        }
    +        [pool release];
    +    }
    +    if (result) {
    +        return result;
    +    } else {
    +        Py_INCREF(Py_None);
    +        return Py_None;
    +    }
    +}
    +
     static PyMethodDef FigureManager_methods[] = {
         {"show",
          (PyCFunction)FigureManager_show,
    @@ -3838,6 +3960,16 @@
          METH_NOARGS,
          "Closes the window associated with the figure manager."
         },
    +    {"set_window_title",
    +     (PyCFunction)FigureManager_set_window_title,
    +     METH_VARARGS,
    +     "Sets the title of the window associated with the figure manager."
    +    },
    +    {"get_window_title",
    +     (PyCFunction)FigureManager_get_window_title,
    +     METH_NOARGS,
    +     "Returns the title of the window associated with the figure manager."
    +    },
         {NULL}  /* Sentinel */
     };
     
    @@ -4142,14 +4274,22 @@
         self->handler = [self->handler initWithToolbar: (PyObject*)self];
         for (i = 0; i < 9; i++)
         {
    -        ScrollableButton* button;
    +        NSButton* button;
             SEL scrollWheelUpAction = scroll_actions[i][0];
             SEL scrollWheelDownAction = scroll_actions[i][1];
    -        if (scrollWheelUpAction || scrollWheelDownAction)
    -            button = [ScrollableButton alloc];
    +        if (scrollWheelUpAction && scrollWheelDownAction)
    +        {
    +            ScrollableButton* scrollable_button = [ScrollableButton alloc];
    +            [scrollable_button initWithFrame: rect];
    +            [scrollable_button setScrollWheelUpAction: scrollWheelUpAction];
    +            [scrollable_button setScrollWheelDownAction: scrollWheelDownAction];
    +            button = (NSButton*)scrollable_button;
    +        }
             else
    +        {
                 button = [NSButton alloc];
    -        [button initWithFrame: rect];
    +            [button initWithFrame: rect];
    +        }
             PyObject* imagedata = PyDict_GetItemString(images, imagenames[i]);
             NSImage* image = _read_ppm_image(imagedata);
             [button setBezelStyle: NSShadowlessSquareBezelStyle];
    @@ -4162,10 +4302,6 @@
             [button setToolTip: tooltips[i]];
             [button setTarget: self->handler];
             [button setAction: actions[i]];
    -        if (scrollWheelUpAction)
    -            [button setScrollWheelUpAction: scrollWheelUpAction];
    -        if (scrollWheelDownAction)
    -            [button setScrollWheelDownAction: scrollWheelDownAction];
             [[window contentView] addSubview: button];
             [button release];
             rect.origin.x += rect.size.width + smallgap;
    @@ -4806,15 +4942,37 @@
     {
         int result;
         const char* title;
    -    if(!PyArg_ParseTuple(args, "s", &title)) return NULL;
    +    char* default_filename;
    +    if(!PyArg_ParseTuple(args, "ses", &title, "UTF-8", &default_filename))
    +        return NULL;
     
         NSSavePanel* panel = [NSSavePanel savePanel];
         [panel setTitle: [NSString stringWithCString: title
                                             encoding: NSASCIIStringEncoding]];
    +    NSString* ns_default_filename =
    +        [[NSString alloc]
    +         initWithCString: default_filename
    +         encoding: NSUTF8StringEncoding];
    +    PyMem_Free(default_filename);
    +#ifdef COMPILING_FOR_10_6
    +    [panel setNameFieldStringValue: ns_default_filename];
         result = [panel runModal];
    +#else
    +    result = [panel runModalForDirectory: nil file: ns_default_filename];
    +#endif
    +    [ns_default_filename release];
         if (result == NSOKButton)
         {
    +#ifdef COMPILING_FOR_10_6
    +        NSURL* url = [panel URL];
    +        NSString* filename = [url path];
    +        if (!filename) {
    +            PyErr_SetString(PyExc_RuntimeError, "Failed to obtain filename");
    +            return 0;
    +        }
    +#else
             NSString* filename = [panel filename];
    +#endif
             unsigned int n = [filename length];
             unichar* buffer = malloc(n*sizeof(unichar));
             [filename getCharacters: buffer];
    @@ -5416,6 +5574,7 @@
     {
         PyObject* result;
         const char* s = [self convertKeyEvent: event];
    +    /* TODO: Handle ctrl, alt, super modifiers. qt4 has implemented these. */    
         PyGILState_STATE gstate = PyGILState_Ensure();
         if (s==NULL)
         {
    @@ -5437,6 +5596,7 @@
     {
         PyObject* result;
         const char* s = [self convertKeyEvent: event];
    +    /* TODO: Handle ctrl, alt, super modifiers. qt4 has implemented these. */
         PyGILState_STATE gstate = PyGILState_Ensure();
         if (s==NULL)
         {
    @@ -5609,6 +5769,12 @@
         if(nwin > 0)
         {
             [NSApp activateIgnoringOtherApps: YES];
    +        NSArray *windowsArray = [NSApp windows];
    +        NSEnumerator *enumerator = [windowsArray objectEnumerator];
    +        NSWindow *window;
    +        while ((window = [enumerator nextObject])) {
    +            [window orderFront:nil];
    +        }
             [NSApp run];
         }
         Py_INCREF(Py_None);
    diff -Nru matplotlib-1.1.1/src/_path.cpp matplotlib-1.2.0/src/_path.cpp
    --- matplotlib-1.1.1/src/_path.cpp	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/_path.cpp	2012-11-08 13:38:03.000000000 +0000
    @@ -33,6 +33,8 @@
         {
             add_varargs_method("point_in_path", &_path_module::point_in_path,
                                "point_in_path(x, y, path, trans)");
    +        add_varargs_method("points_in_path", &_path_module::points_in_path,
    +                           "points_in_path(points, path, trans)");
             add_varargs_method("point_on_path", &_path_module::point_on_path,
                                "point_on_path(x, y, r, path, trans)");
             add_varargs_method("get_path_extents", &_path_module::get_path_extents,
    @@ -66,6 +68,7 @@
     
     private:
         Py::Object point_in_path(const Py::Tuple& args);
    +    Py::Object points_in_path(const Py::Tuple& args);
         Py::Object point_on_path(const Py::Tuple& args);
         Py::Object get_path_extents(const Py::Tuple& args);
         Py::Object update_path_extents(const Py::Tuple& args);
    @@ -119,16 +122,28 @@
     // Input 2D polygon _pgon_ with _numverts_ number of vertices and test point
     // _point_, returns 1 if inside, 0 if outside.
     template
    -bool
    -point_in_path_impl(const double tx, const double ty, T& path)
    -{
    -    int yflag0, yflag1, inside_flag;
    -    double vtx0, vty0, vtx1, vty1, sx, sy;
    +static void
    +point_in_path_impl(const void* const points_, const size_t s0,
    +                   const size_t s1, const size_t n, T& path,
    +                   npy_bool* const inside_flag)
    +{
    +    int *yflag0;
    +    int yflag1;
    +    double vtx0, vty0, vtx1, vty1;
    +    double tx, ty;
    +    double sx, sy;
         double x, y;
    +    size_t i;
    +    int all_done;
    +    const char *const points = (const char * const)points_;
    +
    +    yflag0 = (int *)malloc(n * sizeof(int));
     
         path.rewind(0);
     
    -    inside_flag = 0;
    +    for (i = 0; i < n; ++i) {
    +        inside_flag[i] = 0;
    +    }
     
         unsigned code = 0;
         do
    @@ -138,23 +153,25 @@
                 code = path.vertex(&x, &y);
             }
     
    -        sx = vtx0 = x;
    -        sy = vty0 = y;
    +        sx = vtx0 = vtx1 = x;
    +        sy = vty0 = vty1 = y;
    +
    +        for (i = 0; i < n; ++i) {
    +            ty = *(double *)(points + s0 * i + s1);
     
    -        // get test bit for above/below X axis
    -        yflag0 = (vty0 >= ty);
    +            // get test bit for above/below X axis
    +            yflag0[i] = (vty0 >= ty);
     
    -        vtx1 = x;
    -        vty1 = y;
    +            inside_flag[i] = 0;
    +        }
     
    -        inside_flag = 0;
             do
             {
                 code = path.vertex(&x, &y);
     
                 // The following cases denote the beginning on a new subpath
                 if (code == agg::path_cmd_stop ||
    -                    (code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly)
    +                (code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly)
                 {
                     x = sx;
                     y = sy;
    @@ -164,38 +181,42 @@
                     break;
                 }
     
    -            yflag1 = (vty1 >= ty);
    -            // Check if endpoints straddle (are on opposite sides) of
    -            // X axis (i.e. the Y's differ); if so, +X ray could
    -            // intersect this edge.  The old test also checked whether
    -            // the endpoints are both to the right or to the left of
    -            // the test point.  However, given the faster intersection
    -            // point computation used below, this test was found to be
    -            // a break-even proposition for most polygons and a loser
    -            // for triangles (where 50% or more of the edges which
    -            // survive this test will cross quadrants and so have to
    -            // have the X intersection computed anyway).  I credit
    -            // Joseph Samosky with inspiring me to try dropping the
    -            // "both left or both right" part of my code.
    -            if (yflag0 != yflag1)
    -            {
    -                // Check intersection of pgon segment with +X ray.
    -                // Note if >= point's X; if so, the ray hits it.  The
    -                // division operation is avoided for the ">=" test by
    -                // checking the sign of the first vertex wrto the test
    -                // point; idea inspired by Joseph Samosky's and Mark
    -                // Haigh-Hutchinson's different polygon inclusion
    -                // tests.
    -                if (((vty1 - ty) * (vtx0 - vtx1) >=
    -                        (vtx1 - tx) * (vty0 - vty1)) == yflag1)
    -                {
    -                    inside_flag ^= 1;
    +            for (i = 0; i < n; ++i) {
    +                tx = *(double *)(points + s0 * i);
    +                ty = *(double *)(points + s0 * i + s1);
    +
    +                yflag1 = (vty1 >= ty);
    +                // Check if endpoints straddle (are on opposite sides) of
    +                // X axis (i.e. the Y's differ); if so, +X ray could
    +                // intersect this edge.  The old test also checked whether
    +                // the endpoints are both to the right or to the left of
    +                // the test point.  However, given the faster intersection
    +                // point computation used below, this test was found to be
    +                // a break-even proposition for most polygons and a loser
    +                // for triangles (where 50% or more of the edges which
    +                // survive this test will cross quadrants and so have to
    +                // have the X intersection computed anyway).  I credit
    +                // Joseph Samosky with inspiring me to try dropping the
    +                // "both left or both right" part of my code.
    +                if (yflag0[i] != yflag1) {
    +                    // Check intersection of pgon segment with +X ray.
    +                    // Note if >= point's X; if so, the ray hits it.  The
    +                    // division operation is avoided for the ">=" test by
    +                    // checking the sign of the first vertex wrto the test
    +                    // point; idea inspired by Joseph Samosky's and Mark
    +                    // Haigh-Hutchinson's different polygon inclusion
    +                    // tests.
    +                    if (((vty1 - ty) * (vtx0 - vtx1) >=
    +                         (vtx1 - tx) * (vty0 - vty1)) == yflag1) {
    +                        inside_flag[i] ^= 1;
    +                    }
                     }
    +
    +                // Move to the next pair of vertices, retaining info as
    +                // possible.
    +                yflag0[i] = yflag1;
                 }
     
    -            // Move to the next pair of vertices, retaining info as
    -            // possible.
    -            yflag0 = yflag1;
                 vtx0 = vtx1;
                 vty0 = vty1;
     
    @@ -205,38 +226,55 @@
             while (code != agg::path_cmd_stop &&
                    (code & agg::path_cmd_end_poly) != agg::path_cmd_end_poly);
     
    -        yflag1 = (vty1 >= ty);
    -        if (yflag0 != yflag1)
    -        {
    -            if (((vty1 - ty) * (vtx0 - vtx1) >=
    -                    (vtx1 - tx) * (vty0 - vty1)) == yflag1)
    -            {
    -                inside_flag ^= 1;
    +        all_done = 1;
    +        for (i = 0; i < n; ++i) {
    +            tx = *(double *)(points + s0 * i);
    +            ty = *(double *)(points + s0 * i + s1);
    +
    +            yflag1 = (vty1 >= ty);
    +            if (yflag0[i] != yflag1) {
    +                if (((vty1 - ty) * (vtx0 - vtx1) >=
    +                     (vtx1 - tx) * (vty0 - vty1)) == yflag1) {
    +                    inside_flag[i] ^= 1;
    +                }
    +            }
    +
    +            if (inside_flag[i] == 0) {
    +                all_done = 0;
                 }
             }
     
    -        if (inside_flag != 0)
    -        {
    -            return true;
    +        if (all_done) {
    +            goto exit;
             }
         }
         while (code != agg::path_cmd_stop);
     
    -    return (inside_flag != 0);
    + exit:
    +
    +    free(yflag0);
     }
     
    -inline bool
    -point_in_path(double x, double y, double r, PathIterator& path,
    -              const agg::trans_affine& trans)
    +inline void
    +points_in_path(const void* const points, const size_t s0,
    +               const size_t s1, const size_t n,
    +               const double r, PathIterator& path,
    +               const agg::trans_affine& trans,
    +               npy_bool* result)
     {
         typedef agg::conv_transform transformed_path_t;
         typedef PathNanRemover no_nans_t;
         typedef agg::conv_curve curve_t;
         typedef agg::conv_contour contour_t;
     
    +    size_t i;
    +    for (i = 0; i < n; ++i) {
    +        result[i] = 0;
    +    }
    +
         if (path.total_vertices() < 3)
         {
    -        return false;
    +        return;
         }
     
         transformed_path_t trans_path(path, trans);
    @@ -244,12 +282,29 @@
         curve_t curved_path(no_nans_path);
         contour_t contoured_path(curved_path);
         contoured_path.width(fabs(r));
    -    return point_in_path_impl(x, y, contoured_path);
    +    point_in_path_impl(points, s0, s1, n, contoured_path, result);
     }
     
     inline bool
    -point_on_path(double x, double y, double r, PathIterator& path,
    -              const agg::trans_affine& trans)
    +point_in_path(const double x, const double y, const double r,
    +              PathIterator& path, const agg::trans_affine& trans)
    +{
    +    double points[2];
    +    npy_bool result;
    +
    +    points[0] = x;
    +    points[1] = y;
    +
    +    points_in_path(points, 0, sizeof(double), 1, r, path, trans, &result);
    +    return result;
    +}
    +
    +inline void
    +points_on_path(const void* const points, const size_t s0,
    +               const size_t s1, const size_t n,
    +               const double r, PathIterator& path,
    +               const agg::trans_affine& trans,
    +               npy_bool* result)
     {
         typedef agg::conv_transform transformed_path_t;
         typedef PathNanRemover no_nans_t;
    @@ -261,32 +316,74 @@
         curve_t curved_path(nan_removed_path);
         stroke_t stroked_path(curved_path);
         stroked_path.width(r * 2.0);
    -    return point_in_path_impl(x, y, stroked_path);
    +    point_in_path_impl(points, s0, s1, n, stroked_path, result);
    +}
    +
    +inline bool
    +point_on_path(const double x, const double y, const double r,
    +              PathIterator& path, const agg::trans_affine& trans)
    +{
    +    double points[2];
    +    npy_bool result;
    +
    +    points[0] = x;
    +    points[1] = y;
    +
    +    points_on_path(points, 0, sizeof(double), 1, r, path, trans, &result);
    +    return result;
     }
     
     Py::Object
     _path_module::point_in_path(const Py::Tuple& args)
     {
    -    args.verify_length(5);
    -
         double x = Py::Float(args[0]);
         double y = Py::Float(args[1]);
         double r = Py::Float(args[2]);
         PathIterator path(args[3]);
         agg::trans_affine trans = py_to_agg_transformation_matrix(args[4].ptr(), false);
     
    -    if (::point_in_path(x, y, r, path, trans))
    -    {
    +    if (::point_in_path(x, y, r, path, trans)) {
             return Py::Int(1);
         }
         return Py::Int(0);
     }
     
     Py::Object
    -_path_module::point_on_path(const Py::Tuple& args)
    +_path_module::points_in_path(const Py::Tuple& args)
     {
    -    args.verify_length(5);
    +    args.verify_length(4);
    +
    +    npy_intp n;
    +    PyArrayObject* points_array;
    +    points_array = (PyArrayObject*)PyArray_FromObject(args[0].ptr(), PyArray_DOUBLE, 2, 2);
    +    if (points_array == NULL || PyArray_DIM(points_array, 1) != 2) {
    +        throw Py::TypeError(
    +            "Argument 0 to points_in_path must be an Nx2 numpy array");
    +
    +    }
    +    double r = Py::Float(args[1]);
    +    PathIterator path(args[2]);
    +    agg::trans_affine trans = py_to_agg_transformation_matrix(args[3].ptr(), false);
    +
    +    n = PyArray_DIM(points_array, 0);
    +    PyObject* result = PyArray_ZEROS(1, &n, PyArray_BOOL, 0);
    +    if (result == NULL) {
    +        throw Py::MemoryError("Could not allocate memory for result");
    +    }
    +
    +    ::points_in_path(PyArray_DATA(points_array),
    +                     PyArray_STRIDE(points_array, 0),
    +                     PyArray_STRIDE(points_array, 1),
    +                     n, r, path, trans,
    +                     (npy_bool *)PyArray_DATA(result));
    +    Py_DECREF(points_array);
    +
    +    return Py::Object(result, true);;
    +}
     
    +Py::Object
    +_path_module::point_on_path(const Py::Tuple& args)
    +{
         double x = Py::Float(args[0]);
         double y = Py::Float(args[1]);
         double r = Py::Float(args[2]);
    @@ -393,7 +490,7 @@
                 "Must pass Bbox object as arg 3 of update_path_extents");
         }
         Py::Object minpos_obj = args[3];
    -    bool ignore = bool(Py::Int(args[4]));
    +    bool ignore = Py::Boolean(args[4]);
     
         double xm, ym;
         PyArrayObject* input_minpos = NULL;
    @@ -613,7 +710,7 @@
         Py::SeqBase transforms_obj   = args[5];
         Py::SeqBase offsets_obj      = args[6];
         agg::trans_affine       offset_trans     = py_to_agg_transformation_matrix(args[7].ptr());
    -    bool                    filled           = Py::Int(args[8]);
    +    bool                    filled           = Py::Boolean(args[8]);
     
         PyArrayObject* offsets = (PyArrayObject*)PyArray_FromObject(
             offsets_obj.ptr(), PyArray_DOUBLE, 0, 2);
    @@ -942,7 +1039,7 @@
     
         PathIterator path(args[0]);
         Py::Object bbox_obj = args[1];
    -    bool inside = Py::Int(args[2]);
    +    bool inside = Py::Boolean(args[2]);
     
         double x0, y0, x1, y1;
         if (!py_convert_bbox(bbox_obj.ptr(), x0, y0, x1, y1))
    @@ -1499,7 +1596,7 @@
     
         Py::Object clip_obj = args[2];
         bool do_clip;
    -    agg::rect_base clip_rect;
    +    agg::rect_base clip_rect(0, 0, 0, 0);
         if (clip_obj.isNone() || !clip_obj.isTrue())
         {
             do_clip = false;
    @@ -1596,18 +1693,29 @@
             --wait;
         }
     
    +    #if PY3K
    +    PyObject* result = PyUnicode_FromStringAndSize(buffer, p - buffer);
    +    #else
         PyObject* result = PyString_FromStringAndSize(buffer, p - buffer);
    +    #endif
         free(buffer);
     
         return Py::Object(result, true);
     }
     
    -extern "C"
    -    DL_EXPORT(void)
    -    init_path(void)
    +PyMODINIT_FUNC
    +#if PY3K
    +PyInit__path(void)
    +#else
    +init_path(void)
    +#endif
     {
         static _path_module* _path = NULL;
         _path = new _path_module;
     
         import_array();
    +
    +    #if PY3K
    +    return _path->module().ptr();
    +    #endif
     }
    diff -Nru matplotlib-1.1.1/src/_png.cpp matplotlib-1.2.0/src/_png.cpp
    --- matplotlib-1.1.1/src/_png.cpp	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/_png.cpp	2012-10-31 00:11:14.000000000 +0000
    @@ -42,8 +42,14 @@
         {
             add_varargs_method("write_png", &_png_module::write_png,
                                "write_png(buffer, width, height, fileobj, dpi=None)");
    -        add_varargs_method("read_png", &_png_module::read_png,
    +        add_varargs_method("read_png", &_png_module::read_png_float,
                                "read_png(fileobj)");
    +        add_varargs_method("read_png_float", &_png_module::read_png_float,
    +                           "read_png_float(fileobj)");
    +        add_varargs_method("read_png_uint8", &_png_module::read_png_uint8,
    +                           "read_png_uint8(fileobj)");
    +        add_varargs_method("read_png_int", &_png_module::read_png_int,
    +                           "read_png_int(fileobj)");
             initialize("Module to write PNG files");
         }
     
    @@ -51,7 +57,10 @@
     
     private:
         Py::Object write_png(const Py::Tuple& args);
    -    Py::Object read_png(const Py::Tuple& args);
    +    Py::Object read_png_uint8(const Py::Tuple& args);
    +    Py::Object read_png_float(const Py::Tuple& args);
    +    Py::Object read_png_int(const Py::Tuple& args);
    +    PyObject* _read_png(const Py::Object& py_fileobj, const bool float_result, int result_bit_depth = -1);
     };
     
     static void write_png_data(png_structp png_ptr, png_bytep data, png_size_t length)
    @@ -61,8 +70,13 @@
         PyObject* result = NULL;
         if (write_method)
         {
    +        #if PY3K
    +        result = PyObject_CallFunction(write_method, (char *)"y#", data,
    +                                       length);
    +        #else
             result = PyObject_CallFunction(write_method, (char *)"s#", data,
                                            length);
    +        #endif
         }
         Py_XDECREF(write_method);
         Py_XDECREF(result);
    @@ -114,6 +128,10 @@
         }
     
         Py::Object py_fileobj = Py::Object(args[3]);
    +#if PY3K
    +    int fd = PyObject_AsFileDescriptor(py_fileobj.ptr());
    +    PyErr_Clear();
    +#endif
         if (py_fileobj.isString())
         {
             std::string fileName = Py::String(py_fileobj);
    @@ -125,10 +143,17 @@
             }
             close_file = true;
         }
    +#if PY3K
    +    else if (fd != -1)
    +    {
    +        fp = fdopen(fd, "w");
    +    }
    +#else
         else if (PyFile_CheckExact(py_fileobj.ptr()))
         {
             fp = PyFile_AsFile(py_fileobj.ptr());
         }
    +#endif
         else
         {
             PyObject* write_method = PyObject_GetAttrString(
    @@ -211,24 +236,30 @@
         }
         catch (...)
         {
    +        if (png_ptr && info_ptr)
    +        {
    +            png_destroy_write_struct(&png_ptr, &info_ptr);
    +        }
    +        delete [] row_pointers;
             if (fp && close_file)
             {
                 fclose(fp);
             }
    -        delete [] row_pointers;
             /* Changed calls to png_destroy_write_struct to follow
                http://www.libpng.org/pub/png/libpng-manual.txt.
                This ensures the info_ptr memory is released.
             */
    -        if (png_ptr && info_ptr)
    -        {
    -            png_destroy_write_struct(&png_ptr, &info_ptr);
    -        }
             throw;
         }
     
         png_destroy_write_struct(&png_ptr, &info_ptr);
         delete [] row_pointers;
    +#if PY3K
    +    if (fp)
    +    {
    +        fflush(fp);
    +    }
    +#endif
         if (fp && close_file)
         {
             fclose(fp);
    @@ -251,7 +282,7 @@
         {
             result = PyObject_CallFunction(read_method, (char *)"i", length);
         }
    -    if (PyString_AsStringAndSize(result, &buffer, &bufflen) == 0)
    +    if (PyBytes_AsStringAndSize(result, &buffer, &bufflen) == 0)
         {
             if (bufflen == (Py_ssize_t)length)
             {
    @@ -268,16 +299,19 @@
         _read_png_data(py_file_obj, data, length);
     }
     
    -Py::Object
    -_png_module::read_png(const Py::Tuple& args)
    +PyObject*
    +_png_module::_read_png(const Py::Object& py_fileobj, const bool float_result,
    +                       int result_bit_depth)
     {
    -
    -    args.verify_length(1);
         png_byte header[8];   // 8 is the maximum size that can be checked
         FILE* fp = NULL;
         bool close_file = false;
     
    -    Py::Object py_fileobj = Py::Object(args[0]);
    +#if PY3K
    +    int fd = PyObject_AsFileDescriptor(py_fileobj.ptr());
    +    PyErr_Clear();
    +#endif
    +
         if (py_fileobj.isString())
         {
             std::string fileName = Py::String(py_fileobj);
    @@ -289,10 +323,16 @@
             }
             close_file = true;
         }
    +#if PY3K
    +    else if (fd != -1) {
    +        fp = fdopen(fd, "r");
    +    }
    +#else
         else if (PyFile_CheckExact(py_fileobj.ptr()))
         {
             fp = PyFile_AsFile(py_fileobj.ptr());
         }
    +#endif
         else
         {
             PyObject* read_method = PyObject_GetAttrString(py_fileobj.ptr(), "read");
    @@ -382,6 +422,7 @@
         if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE)
         {
             png_set_palette_to_rgb(png_ptr);
    +        bit_depth = 8;
         }
     
         // If there's an alpha channel convert gray to RGB
    @@ -429,35 +470,96 @@
         int num_dims  = (png_get_color_type(png_ptr, info_ptr)
                                     & PNG_COLOR_MASK_COLOR) ? 3 : 2;
     
    -    double max_value = (1 << ((bit_depth < 8) ? 8 : bit_depth)) - 1;
    -    PyArrayObject *A = (PyArrayObject *) PyArray_SimpleNew(
    -        num_dims, dimensions, PyArray_FLOAT);
    +    PyArrayObject *A = NULL;
    +    if (float_result) {
    +        double max_value = (1 << bit_depth) - 1;
     
    -    if (A == NULL)
    -    {
    -        throw Py::MemoryError("Could not allocate image array");
    -    }
    +        A = (PyArrayObject *) PyArray_SimpleNew(num_dims, dimensions, NPY_FLOAT);
     
    -    for (png_uint_32 y = 0; y < height; y++)
    -    {
    -        png_byte* row = row_pointers[y];
    -        for (png_uint_32 x = 0; x < width; x++)
    +        if (A == NULL)
             {
    -            size_t offset = y * A->strides[0] + x * A->strides[1];
    -            if (bit_depth == 16)
    +            throw Py::MemoryError("Could not allocate image array");
    +        }
    +
    +        for (png_uint_32 y = 0; y < height; y++)
    +        {
    +            png_byte* row = row_pointers[y];
    +            for (png_uint_32 x = 0; x < width; x++)
                 {
    -                png_uint_16* ptr = &reinterpret_cast(row)[x * dimensions[2]];
    -                for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++)
    +                size_t offset = y * A->strides[0] + x * A->strides[1];
    +                if (bit_depth == 16)
                     {
    -                    *(float*)(A->data + offset + p*A->strides[2]) = (float)(ptr[p]) / max_value;
    +                    png_uint_16* ptr = &reinterpret_cast(row)[x * dimensions[2]];
    +                    for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++)
    +                    {
    +                        *(float*)(A->data + offset + p*A->strides[2]) = (float)(ptr[p]) / max_value;
    +                    }
    +                }
    +                else
    +                {
    +                    png_byte* ptr = &(row[x * dimensions[2]]);
    +                    for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++)
    +                    {
    +                        *(float*)(A->data + offset + p*A->strides[2]) = (float)(ptr[p]) / max_value;
    +                    }
                     }
                 }
    -            else
    +        }
    +    } else {
    +        if (result_bit_depth < 0) {
    +            result_bit_depth = bit_depth;
    +        }
    +
    +        if (result_bit_depth == 8) {
    +            A = (PyArrayObject *) PyArray_SimpleNew(num_dims, dimensions, NPY_UBYTE);
    +        } else if (result_bit_depth == 16) {
    +            A = (PyArrayObject *) PyArray_SimpleNew(num_dims, dimensions, NPY_UINT16);
    +        } else {
    +            throw Py::RuntimeError(
    +                "_image_module::readpng: image has unknown bit depth");
    +        }
    +
    +        if (A == NULL)
    +        {
    +            throw Py::MemoryError("Could not allocate image array");
    +        }
    +
    +        for (png_uint_32 y = 0; y < height; y++)
    +        {
    +            png_byte* row = row_pointers[y];
    +            for (png_uint_32 x = 0; x < width; x++)
                 {
    -                png_byte* ptr = &(row[x * dimensions[2]]);
    -                for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++)
    +                size_t offset = y * A->strides[0] + x * A->strides[1];
    +                if (bit_depth == 16)
    +                {
    +                    png_uint_16* ptr = &reinterpret_cast(row)[x * dimensions[2]];
    +
    +                    if (result_bit_depth == 16) {
    +                        for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++)
    +                        {
    +                            *(png_uint_16*)(A->data + offset + p*A->strides[2]) = ptr[p];
    +                        }
    +                    } else {
    +                        for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++)
    +                        {
    +                            *(png_byte*)(A->data + offset + p*A->strides[2]) = ptr[p] >> 8;
    +                        }
    +                    }
    +                }
    +                else
                     {
    -                    *(float*)(A->data + offset + p*A->strides[2]) = (float)(ptr[p]) / max_value;
    +                    png_byte* ptr = &(row[x * dimensions[2]]);
    +                    if (result_bit_depth == 16) {
    +                        for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++)
    +                        {
    +                            *(png_uint_16*)(A->data + offset + p*A->strides[2]) = ptr[p];
    +                        }
    +                    } else {
    +                        for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++)
    +                        {
    +                            *(png_byte*)(A->data + offset + p*A->strides[2]) = ptr[p];
    +                        }
    +                    }
                     }
                 }
             }
    @@ -482,18 +584,45 @@
     
         if (PyErr_Occurred()) {
             Py_DECREF((PyObject *)A);
    -        throw Py::Exception();
    +        return NULL;
         } else {
    -        return Py::asObject((PyObject*)A);
    +        return (PyObject *)A;
         }
     }
     
    -extern "C"
    -    DL_EXPORT(void)
    -    init_png(void)
    +Py::Object
    +_png_module::read_png_float(const Py::Tuple& args)
    +{
    +    args.verify_length(1);
    +    return Py::asObject(_read_png(args[0], true));
    +}
    +
    +Py::Object
    +_png_module::read_png_uint8(const Py::Tuple& args)
    +{
    +    throw Py::RuntimeError("read_png_uint8 is deprecated.  Use read_png_int instead.");
    +}
    +
    +Py::Object
    +_png_module::read_png_int(const Py::Tuple& args)
    +{
    +    args.verify_length(1);
    +    return Py::asObject(_read_png(args[0], false));
    +}
    +
    +PyMODINIT_FUNC
    +#if PY3K
    +PyInit__png(void)
    +#else
    +init_png(void)
    +#endif
     {
         import_array();
     
         static _png_module* _png = NULL;
         _png = new _png_module;
    +
    +#if PY3K
    +    return _png->module().ptr();
    +#endif
     }
    diff -Nru matplotlib-1.1.1/src/_tkagg.cpp matplotlib-1.2.0/src/_tkagg.cpp
    --- matplotlib-1.1.1/src/_tkagg.cpp	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/_tkagg.cpp	2012-11-06 17:13:43.000000000 +0000
    @@ -40,8 +40,6 @@
     #  define SIZE_T_FORMAT "%zu"
     #endif
     
    -
    -
     typedef struct
     {
         PyObject_HEAD
    @@ -267,10 +265,34 @@
         {NULL, NULL} /* sentinel */
     };
     
    -extern "C"
    -    DL_EXPORT(void) init_tkagg(void)
    +#if PY3K
    +static PyModuleDef _tkagg_module = {
    +    PyModuleDef_HEAD_INIT,
    +    "_tkagg",
    +    "",
    +    -1,
    +    functions,
    +    NULL, NULL, NULL, NULL
    +};
    +
    +PyMODINIT_FUNC
    +PyInit__tkagg(void)
    +{
    +    PyObject* m;
    +
    +    m = PyModule_Create(&_tkagg_module);
    +
    +    import_array();
    +
    +    return m;
    +}
    +#else
    +PyMODINIT_FUNC
    +init_tkagg(void)
     {
         import_array();
     
         Py_InitModule("_tkagg", functions);
     }
    +#endif
    +
    diff -Nru matplotlib-1.1.1/src/_ttconv.cpp matplotlib-1.2.0/src/_ttconv.cpp
    --- matplotlib-1.1.1/src/_ttconv.cpp	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/_ttconv.cpp	2012-10-31 00:11:14.000000000 +0000
    @@ -6,6 +6,8 @@
       Python wrapper for TrueType conversion library in ../ttconv.
      */
     
    +#include "mplutils.h"
    +
     #include 
     #include "ttconv/pprdrv.h"
     #include 
    @@ -46,7 +48,11 @@
             PyObject* result = NULL;
             if (_write_method)
             {
    +            #if PY3K
    +            result = PyObject_CallFunction(_write_method, (char *)"y", a);
    +            #else
                 result = PyObject_CallFunction(_write_method, (char *)"s", a);
    +            #endif
                 if (! result)
                 {
                     throw PythonExceptionOccurred();
    @@ -86,7 +92,11 @@
         PyObject* item;
         while ((item = PyIter_Next(iterator)))
         {
    +        #if PY3K
    +        long value = PyLong_AsLong(item);
    +        #else
             long value = PyInt_AsLong(item);
    +        #endif
             Py_DECREF(item);
             if (value == -1 && PyErr_Occurred())
             {
    @@ -169,7 +179,7 @@
     
         virtual void add_pair(const char* a, const char* b)
         {
    -        PyObject* value = PyString_FromString(b);
    +        PyObject* value = PyBytes_FromString(b);
             if (value)
             {
                 if (PyDict_SetItemString(_dict, a, value))
    @@ -237,7 +247,7 @@
     static PyMethodDef ttconv_methods[] =
     {
         {
    -        "convert_ttf_to_ps", (PyCFunction)convert_ttf_to_ps, METH_KEYWORDS,
    +        "convert_ttf_to_ps", (PyCFunction)convert_ttf_to_ps, METH_VARARGS | METH_KEYWORDS,
             "convert_ttf_to_ps(filename, output, fonttype, glyph_ids)\n"
             "\n"
             "Converts the Truetype font into a Type 3 or Type 42 Postscript font, "
    @@ -255,7 +265,7 @@
             "composite glyphs, then the component glyphs will also be included."
         },
         {
    -        "get_pdf_charprocs", (PyCFunction)py_get_pdf_charprocs, METH_KEYWORDS,
    +        "get_pdf_charprocs", (PyCFunction)py_get_pdf_charprocs, METH_VARARGS | METH_KEYWORDS,
             "get_pdf_charprocs(filename, glyph_ids)\n"
             "\n"
             "Given a Truetype font file, returns a dictionary containing the PDF Type 3\n"
    @@ -271,17 +281,36 @@
         {0, 0, 0, 0}  /* Sentinel */
     };
     
    -#ifndef PyMODINIT_FUNC  /* declarations for DLL import/export */
    -#define PyMODINIT_FUNC void
    -#endif
    +static const char* module_docstring =
    +    "Module to handle converting and subsetting TrueType "
    +    "fonts to Postscript Type 3, Postscript Type 42 and "
    +    "Pdf Type 3 fonts.";
    +
    +#if PY3K
    +static PyModuleDef ttconv_module = {
    +    PyModuleDef_HEAD_INIT,
    +    "ttconv",
    +    module_docstring,
    +    -1,
    +    ttconv_methods,
    +    NULL, NULL, NULL, NULL
    +};
    +
     PyMODINIT_FUNC
    -initttconv(void)
    +PyInit_ttconv(void)
     {
         PyObject* m;
     
    -    m = Py_InitModule3("ttconv", ttconv_methods,
    -                       "Module to handle converting and subsetting TrueType "
    -                       "fonts to Postscript Type 3, Postscript Type 42 and "
    -                       "Pdf Type 3 fonts.");
    +    m = PyModule_Create(&ttconv_module);
    +
    +    return m;
     }
    +#else
    +PyMODINIT_FUNC
    +initttconv(void)
    +{
    +    PyObject* m;
     
    +    m = Py_InitModule3("ttconv", ttconv_methods, module_docstring);
    +}
    +#endif
    diff -Nru matplotlib-1.1.1/src/_windowing.cpp matplotlib-1.2.0/src/_windowing.cpp
    --- matplotlib-1.1.1/src/_windowing.cpp	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/_windowing.cpp	2012-10-31 00:11:14.000000000 +0000
    @@ -1,5 +1,3 @@
    -/* -*- mode: c++; c-basic-offset: 4 -*- */
    -
     #include "Python.h"
     #include 
     
    @@ -11,14 +9,14 @@
         {
             return NULL;
         }
    -    return PyInt_FromLong((long) handle);
    +    return PyLong_FromSize_t((size_t)handle);
     }
     
     static PyObject *
     _SetForegroundWindow(PyObject *module, PyObject *args)
     {
         HWND handle;
    -    if (!PyArg_ParseTuple(args, "l:SetForegroundWindow", &handle))
    +    if (!PyArg_ParseTuple(args, "n:SetForegroundWindow", &handle))
         {
             return NULL;
         }
    @@ -38,7 +36,29 @@
         {NULL, NULL}
     };
     
    -extern "C" DL_EXPORT(void) init_windowing()
    +#if PY_MAJOR_VERSION >= 3
    +
    +static struct PyModuleDef moduledef = {
    +        PyModuleDef_HEAD_INIT,
    +        "_windowing",
    +        "",
    +        -1,
    +        _windowing_methods,
    +        NULL,
    +        NULL,
    +        NULL,
    +        NULL
    +};
    +
    +PyMODINIT_FUNC PyInit__windowing(void)
    +{
    +    PyObject *module = PyModule_Create(&moduledef);
    +    return module;
    +}
    +
    +#else
    +PyMODINIT_FUNC init_windowing()
     {
         Py_InitModule("_windowing", _windowing_methods);
     }
    +#endif
    diff -Nru matplotlib-1.1.1/src/agg_py_transforms.cpp matplotlib-1.2.0/src/agg_py_transforms.cpp
    --- matplotlib-1.1.1/src/agg_py_transforms.cpp	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/agg_py_transforms.cpp	2012-10-31 00:11:14.000000000 +0000
    @@ -9,20 +9,45 @@
     #include "agg_trans_affine.h"
     
     /** A helper function to convert from a Numpy affine transformation matrix
    - *  to an agg::trans_affine.
    + *  to an agg::trans_affine. If errors = false then an Identity transform is returned.
      */
     agg::trans_affine
     py_to_agg_transformation_matrix(PyObject* obj, bool errors = true)
     {
         PyArrayObject* matrix = NULL;
     
    +    /** If None either raise a TypeError or return an agg identity transform. */
    +    if (obj == Py_None)
    +    {
    +        if (errors)
    +        {
    +            throw Py::TypeError("Cannot convert None to an affine transform.");
    +        }
    +
    +        return agg::trans_affine();
    +    }
    +
    +    /** Try turning the object into an affine transform matrix. */
         try
         {
    -        if (obj == Py_None)
    -            throw std::exception();
             matrix = (PyArrayObject*) PyArray_FromObject(obj, PyArray_DOUBLE, 2, 2);
             if (!matrix)
                 throw std::exception();
    +    }
    +    catch (...)
    +    {
    +        Py_XDECREF(matrix);
    +        if (errors)
    +        {
    +            throw Py::TypeError("Unable to get an affine transform matrix from the given object.");
    +        }
    +
    +        return agg::trans_affine();
    +    }
    +
    +    /** Try turning the matrix into an agg transform. */
    +    try
    +    {
             if (PyArray_NDIM(matrix) == 2 || PyArray_DIM(matrix, 0) == 3 || PyArray_DIM(matrix, 1) == 3)
             {
                 size_t stride0 = PyArray_STRIDE(matrix, 0);
    @@ -54,7 +79,7 @@
             if (errors)
             {
                 Py_XDECREF(matrix);
    -            throw Py::TypeError("Invalid affine transformation matrix");
    +            throw Py::TypeError("Invalid affine transformation matrix.");
             }
         }
     
    diff -Nru matplotlib-1.1.1/src/backend_agg.cpp matplotlib-1.2.0/src/backend_agg.cpp
    --- matplotlib-1.1.1/src/backend_agg.cpp	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/backend_agg.cpp	2012-11-06 22:31:09.000000000 +0000
    @@ -26,6 +26,7 @@
     #include "agg_scanline_storage_aa.h"
     #include "agg_scanline_storage_bin.h"
     #include "agg_span_allocator.h"
    +#include "agg_span_converter.h"
     #include "agg_span_image_filter_gray.h"
     #include "agg_span_image_filter_rgba.h"
     #include "agg_span_interpolator_linear.h"
    @@ -102,7 +103,12 @@
     BufferRegion::to_string(const Py::Tuple &args)
     {
         // owned=true to prevent memory leak
    -    return Py::String(PyString_FromStringAndSize((const char*)data, height*stride), true);
    +    #if PY3K
    +    return Py::Bytes
    +    #else
    +    return Py::String
    +    #endif
    +        (PyBytes_FromStringAndSize((const char*)data, height*stride), true);
     }
     
     
    @@ -152,9 +158,8 @@
         unsigned char tmp;
         size_t i, j;
     
    -    PyObject* str = PyString_FromStringAndSize(
    -                        (const char*)data, height * stride);
    -    if (PyString_AsStringAndSize(str, (char**)&begin, &length))
    +    PyObject* str = PyBytes_FromStringAndSize((const char*)data, height * stride);
    +    if (PyBytes_AsStringAndSize(str, (char**)&begin, &length))
         {
             throw Py::TypeError("Could not create memory for blit");
         }
    @@ -174,7 +179,12 @@
             }
         }
     
    -    return Py::String(str, true);
    +    #if PY3K
    +    return Py::Bytes
    +    #else
    +    return Py::String
    +    #endif
    +        (str, true);
     }
     
     
    @@ -200,7 +210,7 @@
     GCAgg::_set_antialiased(const Py::Object& gc)
     {
         _VERBOSE("GCAgg::antialiased");
    -    isaa = Py::Int(gc.getAttr("_antialiased"));
    +    isaa = Py::Boolean(gc.getAttr("_antialiased"));
     }
     
     
    @@ -910,7 +920,8 @@
         }
         else
         {
    -        FT2Image *image = static_cast(image_obj.ptr());
    +        FT2Image* image = static_cast(
    +            Py::getPythonExtensionBase(image_obj.ptr()));
             if (!image->get_buffer())
             {
                 throw Py::ValueError(
    @@ -974,6 +985,30 @@
         return Py::Object();
     }
     
    +class span_conv_alpha
    +{
    +public:
    +    typedef agg::rgba8 color_type;
    +
    +    double m_alpha;
    +
    +    span_conv_alpha(double alpha) :
    +        m_alpha(alpha)
    +    {
    +    }
    +
    +    void prepare() {}
    +    void generate(color_type* span, int x, int y, unsigned len) const
    +    {
    +        do
    +            {
    +                span->a = (agg::int8u)((double)span->a * m_alpha);
    +                ++span;
    +            }
    +        while(--len);
    +    }
    +};
    +
     
     Py::Object
     RendererAgg::draw_image(const Py::Tuple& args)
    @@ -1058,11 +1093,14 @@
             typedef agg::span_interpolator_linear<> interpolator_type;
             typedef agg::span_image_filter_rgba_nn image_span_gen_type;
    +        typedef agg::span_converter span_conv;
     
             color_span_alloc_type sa;
             image_accessor_type ia(pixf, agg::rgba8(0, 0, 0, 0));
             interpolator_type interpolator(inv_mtx);
             image_span_gen_type image_span_generator(ia, interpolator);
    +        span_conv_alpha conv_alpha(alpha);
    +        span_conv spans(image_span_generator, conv_alpha);
     
             if (has_clippath)
             {
    @@ -1071,12 +1109,12 @@
                 typedef agg::renderer_base amask_ren_type;
                 typedef agg::renderer_scanline_aa
    +                                              span_conv>
                     renderer_type_alpha;
     
                 pixfmt_amask_type pfa(pixFmt, alphaMask);
                 amask_ren_type r(pfa);
    -            renderer_type_alpha ri(r, sa, image_span_generator);
    +            renderer_type_alpha ri(r, sa, spans);
     
                 theRasterizer.add_path(rect2);
                 agg::render_scanlines(theRasterizer, slineP8, ri);
    @@ -1086,11 +1124,11 @@
                 typedef agg::renderer_base ren_type;
                 typedef agg::renderer_scanline_aa
    +                                              span_conv>
                     renderer_type;
     
                 ren_type r(pixFmt);
    -            renderer_type ri(r, sa, image_span_generator);
    +            renderer_type ri(r, sa, spans);
     
                 theRasterizer.add_path(rect2);
                 agg::render_scanlines(theRasterizer, slineP8, ri);
    @@ -1101,7 +1139,8 @@
         {
             set_clipbox(gc.cliprect, rendererBase);
             rendererBase.blend_from(
    -            pixf, 0, (int)x, (int)(height - (y + image->rowsOut)), alpha * 255);
    +            pixf, 0, (int)x, (int)(height - (y + image->rowsOut)),
    +            (agg::int8u)(alpha * 255));
         }
     
         rendererBase.reset_clipping(true);
    @@ -1362,7 +1401,8 @@
      const Py::Object&              edgecolors_obj,
      const Py::SeqBase&  linewidths,
      const Py::SeqBase& linestyles_obj,
    - const Py::SeqBase&    antialiaseds)
    + const Py::SeqBase&    antialiaseds,
    + const bool                     data_offsets)
     {
         typedef agg::conv_transform transformed_path_t;
         typedef PathNanRemover                         nan_removed_t;
    @@ -1476,7 +1516,11 @@
                 double xo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0);
                 double yo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1);
                 offset_trans.transform(&xo, &yo);
    -            trans *= agg::trans_affine_translation(xo, yo);
    +            if (data_offsets) {
    +                trans = agg::trans_affine_translation(xo, yo) * trans;
    +            } else {
    +                trans *= agg::trans_affine_translation(xo, yo);
    +            }
             }
     
             // These transformations must be done post-offsets
    @@ -1521,7 +1565,7 @@
     
             if (check_snap)
             {
    -            gc.isaa = bool(Py::Int(antialiaseds[i % Naa]));
    +            gc.isaa = Py::Boolean(antialiaseds[i % Naa]);
     
                 transformed_path_t tpath(path, trans);
                 nan_removed_t      nan_removed(tpath, true, has_curves);
    @@ -1540,7 +1584,7 @@
             }
             else
             {
    -            gc.isaa = bool(Py::Int(antialiaseds[i % Naa]));
    +            gc.isaa = Py::Boolean(antialiaseds[i % Naa]);
     
                 transformed_path_t tpath(path, trans);
                 nan_removed_t      nan_removed(tpath, true, has_curves);
    @@ -1594,7 +1638,7 @@
     RendererAgg::draw_path_collection(const Py::Tuple& args)
     {
         _VERBOSE("RendererAgg::draw_path_collection");
    -    args.verify_length(12);
    +    args.verify_length(13);
     
         Py::Object gc_obj = args[0];
         GCAgg gc(gc_obj, dpi);
    @@ -1611,6 +1655,9 @@
         Py::SeqBase    antialiaseds     = args[10];
         // We don't actually care about urls for Agg, so just ignore it.
         // Py::SeqBase urls             = args[11];
    +    std::string             offset_position  = Py::String(args[12]);
    +
    +    bool data_offsets = (offset_position == "data");
     
         try
         {
    @@ -1628,7 +1675,8 @@
              edgecolors_obj,
              linewidths,
              linestyles_obj,
    -         antialiaseds);
    +         antialiaseds,
    +         data_offsets);
         }
         catch (const char *e)
         {
    @@ -1754,28 +1802,18 @@
         agg::trans_affine offset_trans     = py_to_agg_transformation_matrix(args[6].ptr());
         Py::Object        facecolors_obj   = args[7];
         bool              antialiased      = (bool)Py::Boolean(args[8]);
    -    bool              showedges        = (bool)Py::Boolean(args[9]);
    -    bool              free_edgecolors  = false;
    +    Py::Object        edgecolors_obj   = args[9];
     
         QuadMeshGenerator path_generator(mesh_width, mesh_height, coordinates.ptr());
     
         Py::SeqBase transforms_obj;
    -    Py::Object edgecolors_obj;
         Py::Tuple linewidths(1);
         linewidths[0] = Py::Float(gc.linewidth);
         Py::SeqBase linestyles_obj;
         Py::Tuple antialiaseds(1);
         antialiaseds[0] = Py::Int(antialiased ? 1 : 0);
     
    -    if (showedges)
    -    {
    -        npy_intp dims[] = { 1, 4, 0 };
    -        double data[] = { 0, 0, 0, 1 };
    -        edgecolors_obj = Py::Object(PyArray_SimpleNewFromData(2, dims, PyArray_DOUBLE,
    -                                                              (char*)data), true);
    -    }
    -    else
    -    {
    +    if (edgecolors_obj.isNone()) {
             if (antialiased)
             {
                 edgecolors_obj = facecolors_obj;
    @@ -1784,7 +1822,6 @@
             {
                 npy_intp dims[] = { 0, 0 };
                 edgecolors_obj = PyArray_SimpleNew(1, dims, PyArray_DOUBLE);
    -            free_edgecolors = true;
             }
         }
     
    @@ -1804,7 +1841,8 @@
                  edgecolors_obj,
                  linewidths,
                  linestyles_obj,
    -             antialiaseds);
    +             antialiaseds,
    +             false);
         }
         catch (const char* e)
         {
    @@ -1993,6 +2031,12 @@
         FILE *fp = NULL;
         bool close_file = false;
         Py::Object py_fileobj = Py::Object(args[0]);
    +
    +    #if PY3K
    +    int fd = PyObject_AsFileDescriptor(py_fileobj.ptr());
    +    PyErr_Clear();
    +    #endif
    +
         if (py_fileobj.isString())
         {
             std::string fileName = Py::String(py_fileobj);
    @@ -2008,6 +2052,15 @@
             }
             close_file = true;
         }
    +    #if PY3K
    +    else if (fd != -1)
    +    {
    +        if (write(fd, pixBuffer, NUMBYTES) != (ssize_t)NUMBYTES)
    +        {
    +            throw Py::RuntimeError("Error writing to file");
    +        }
    +    }
    +    #else
         else if (PyFile_CheckExact(py_fileobj.ptr()))
         {
             fp = PyFile_AsFile(py_fileobj.ptr());
    @@ -2016,6 +2069,7 @@
                 throw Py::RuntimeError("Error writing to file");
             }
         }
    +    #endif
         else
         {
             PyObject* write_method = PyObject_GetAttrString(py_fileobj.ptr(),
    @@ -2071,7 +2125,11 @@
         }
     
         //todo: how to do this with native CXX
    +    #if PY3K
    +    PyObject* o = Py_BuildValue("y#", buf_tmp, row_len * height);
    +    #else
         PyObject* o = Py_BuildValue("s#", buf_tmp, row_len * height);
    +    #endif
     
         delete [] buf_tmp;
         return Py::asObject(o);
    @@ -2107,7 +2165,12 @@
         }
     
         //todo: how to do this with native CXX
    +
    +    #if PY3K
    +    PyObject* o = Py_BuildValue("y#", buf_tmp, row_len * height);
    +    #else
         PyObject* o = Py_BuildValue("s#", buf_tmp, row_len * height);
    +    #endif
         delete [] buf_tmp;
         return Py::asObject(o);
     }
    @@ -2146,9 +2209,11 @@
         }
     
         //todo: how to do this with native CXX
    -    PyObject* o = Py_BuildValue("s#",
    -                                buf_tmp,
    -                                row_len * height);
    +    #if PY3K
    +    PyObject* o = Py_BuildValue("y#", buf_tmp, row_len * height);
    +    #else
    +    PyObject* o = Py_BuildValue("s#", buf_tmp, row_len * height);
    +    #endif
         delete [] buf_tmp;
         return Py::asObject(o);
     }
    @@ -2161,12 +2226,15 @@
     
         _VERBOSE("RendererAgg::buffer_rgba");
     
    -    args.verify_length(2);
    -    int startw = Py::Int(args[0]);
    -    int starth = Py::Int(args[1]);
    +    args.verify_length(0);
    +
    +    #if PY3K
    +    return Py::asObject(PyMemoryView_FromObject(this));
    +    #else
         int row_len = width * 4;
    -    int start = row_len * starth + startw * 4;
    -    return Py::asObject(PyBuffer_FromMemory(pixBuffer + start, row_len*height - start));
    +    return Py::asObject(PyBuffer_FromReadWriteMemory(
    +                            pixBuffer, row_len*height));
    +    #endif
     }
     
     
    @@ -2199,7 +2267,12 @@
     
         int newwidth = 0;
         int newheight = 0;
    +    #if PY3K
    +    Py::Bytes data;
    +    #else
         Py::String data;
    +    #endif
    +
         if (xmin < xmax && ymin < ymax)
         {
             // Expand the bounds by 1 pixel on all sides
    @@ -2229,7 +2302,11 @@
             }
     
             // The Py::String will take over the buffer
    -        data = Py::String((const char *)buf, (int)newsize);
    +        #if PY3K
    +        data = Py::Bytes((const char *)buf, (int) newsize);
    +        #else
    +        data = Py::String((const char *)buf, (int) newsize);
    +        #endif
         }
     
         Py::Tuple bounds(4);
    @@ -2280,6 +2357,14 @@
         return p * dpi / 72.0;
     }
     
    +#if PY3K
    +int
    +RendererAgg::buffer_get( Py_buffer* buf, int flags )
    +{
    +    return PyBuffer_FillInfo(buf, this, pixBuffer, width * height * 4, 1,
    +                             PyBUF_SIMPLE);
    +}
    +#endif
     
     RendererAgg::~RendererAgg()
     {
    @@ -2310,8 +2395,8 @@
             debug = 0;
         }
     
    -    unsigned int width = (unsigned int)Py::Int(args[0]);
    -    unsigned int height = (unsigned int)Py::Int(args[1]);
    +    unsigned int width = (int)Py::Int(args[0]);
    +    unsigned int height = (int)Py::Int(args[1]);
         double dpi = Py::Float(args[2]);
     
         if (width > 1 << 15 || height > 1 << 15)
    @@ -2401,11 +2486,18 @@
                            "restore_region(region)");
         add_varargs_method("restore_region2", &RendererAgg::restore_region2,
                            "restore_region(region, x1, y1, x2, y2, x3, y3)");
    +
    +    #if PY3K
    +    behaviors().supportBufferType();
    +    #endif
     }
     
    -extern "C"
    -    DL_EXPORT(void)
    -    init_backend_agg(void)
    +PyMODINIT_FUNC
    +#if PY3K
    +PyInit__backend_agg(void)
    +#else
    +init_backend_agg(void)
    +#endif
     {
         //static _backend_agg_module* _backend_agg = new _backend_agg_module;
     
    @@ -2415,4 +2507,8 @@
     
         static _backend_agg_module* _backend_agg = NULL;
         _backend_agg = new _backend_agg_module;
    +
    +    #if PY3K
    +    return _backend_agg->module().ptr();
    +    #endif
     }
    diff -Nru matplotlib-1.1.1/src/backend_gdk.c matplotlib-1.2.0/src/backend_gdk.c
    --- matplotlib-1.1.1/src/backend_gdk.c	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/backend_gdk.c	2012-10-31 00:11:14.000000000 +0000
    @@ -52,7 +52,7 @@
         { NULL, NULL, 0 }
     };
     
    -DL_EXPORT(void)
    +PyMODINIT_FUNC
     init_backend_gdk(void)
     {
         PyObject *mod;
    diff -Nru matplotlib-1.1.1/src/cntr.c matplotlib-1.2.0/src/cntr.c
    --- matplotlib-1.1.1/src/cntr.c	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/cntr.c	2012-10-31 00:11:14.000000000 +0000
    @@ -22,6 +22,12 @@
     #include 
     #include "numpy/arrayobject.h"
     
    +#if PY_MAJOR_VERSION >= 3
    +#define PY3K 1
    +#else
    +#define PY3K 0
    +#endif
    +
     /* Note that all arrays in these routines are Fortran-style,
        in the sense that the "i" index varies fastest; the dimensions
        of the corresponding C array are z[jmax][imax] in the notation
    @@ -1745,7 +1751,11 @@
     Cntr_dealloc(Cntr* self)
     {
         Cntr_clear(self);
    -    self->ob_type->tp_free((PyObject*)self);
    +    #if PY3K
    +        Py_TYPE(self)->tp_free((PyObject*)self);
    +    #else
    +        self->ob_type->tp_free((PyObject*)self);
    +    #endif
     }
     
     static PyObject *
    @@ -1915,8 +1925,12 @@
     };
     
     static PyTypeObject CntrType = {
    -    PyObject_HEAD_INIT(NULL)
    -    0,                         /*ob_size*/
    +    #if PY3K
    +        PyVarObject_HEAD_INIT(NULL, 0)
    +    #else
    +        PyObject_HEAD_INIT(NULL)
    +        0,                         /*ob_size*/
    +    #endif
         "cntr.Cntr",               /*tp_name*/
         sizeof(Cntr),              /*tp_basicsize*/
         0,                         /*tp_itemsize*/
    @@ -1960,24 +1974,54 @@
         {NULL}  /* Sentinel */
     };
     
    +#if PY3K
    +static PyModuleDef cntr_module = {
    +    PyModuleDef_HEAD_INIT,
    +    "_cntr",
    +    "Contouring engine as an extension type (numpy).",
    +    -1,
    +    module_methods,
    +    NULL, NULL, NULL, NULL
    +};
    +
    +#define ERROR_RETURN return NULL
    +
    +PyMODINIT_FUNC
    +PyInit__cntr(void)
    +#else
    +#define ERROR_RETURN return
    +
     PyMODINIT_FUNC
     init_cntr(void)
    +#endif
     {
         PyObject* m;
     
    -    if (PyType_Ready(&CntrType) < 0)
    -        return;
    +    if (PyType_Ready(&CntrType) < 0) {
    +        ERROR_RETURN;
    +    }
    +
    +    #if PY3K
    +        m = PyModule_Create(&cntr_module);
    +    #else
    +        m = Py_InitModule3("_cntr", module_methods,
    +                           "Contouring engine as an extension type (numpy).");
    +    #endif
     
    -    m = Py_InitModule3("_cntr", module_methods,
    -                       "Contouring engine as an extension type (numpy).");
    +    if (m == NULL) {
    +        ERROR_RETURN;
    +    }
     
    -    if (m == NULL)
    -      return;
         PyModule_AddIntConstant(m, "_slitkind", (long)kind_slit_up );
         /* We can add all the point_kinds values later if we need them. */
         import_array();
    +
         Py_INCREF(&CntrType);
         PyModule_AddObject(m, "Cntr", (PyObject *)&CntrType);
    +
    +    #if PY3K
    +        return m;
    +    #endif
     }
     
     
    diff -Nru matplotlib-1.1.1/src/ft2font.cpp matplotlib-1.2.0/src/ft2font.cpp
    --- matplotlib-1.1.1/src/ft2font.cpp	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/ft2font.cpp	2012-10-31 00:11:14.000000000 +0000
    @@ -36,47 +36,39 @@
           at the size at 12 pixels scaled by 2 through a transform,
           because the hints will have been computed differently (except
           you have disabled hints).
    -
    - This hack is enabled only when VERTICAL_HINTING is defined, and will
    - only be effective when load_char and set_text are called with 'flags=
    - LOAD_DEFAULT', which is the default.
      */
    -#define VERTICAL_HINTING
    -#ifdef VERTICAL_HINTING
    -#define HORIZ_HINTING 8
    -#else
    -#define HORIZ_HINTING 1
    -#endif
     
     FT_Library _ft2Library;
     
    -// FT2Image::FT2Image() :
    -//   _isDirty(true),
    -//   _buffer(NULL),
    -//   _width(0), _height(0),
    -//   _rgbCopy(NULL),
    -//   _rgbaCopy(NULL) {
    -//   _VERBOSE("FT2Image::FT2Image");
    -// }
    -
    -FT2Image::FT2Image(unsigned long width, unsigned long height) :
    +FT2Image::FT2Image(Py::PythonClassInstance *self, Py::Tuple &args, Py::Dict &kwds) :
    +    Py::PythonClass< FT2Image >::PythonClass(self, args, kwds),
         _isDirty(true),
         _buffer(NULL),
    -    _width(0), _height(0),
    -    _rgbCopy(NULL),
    -    _rgbaCopy(NULL)
    +    _width(0), _height(0)
     {
         _VERBOSE("FT2Image::FT2Image");
    +
    +    args.verify_length(2);
    +    int width = Py::Int(args[0]);
    +    int height = Py::Int(args[1]);
    +
         resize(width, height);
     }
     
    -FT2Image::~FT2Image()
    -{
    -    _VERBOSE("FT2Image::~FT2Image");
    +FT2Image::~FT2Image() {
         delete [] _buffer;
         _buffer = NULL;
    -    delete _rgbCopy;
    -    delete _rgbaCopy;
    +}
    +
    +Py::PythonClassObject FT2Image::factory(int width, int height)
    +{
    +    Py::Callable class_type(type());
    +    Py::Tuple args(2);
    +    args[0] = Py::Int(width);
    +    args[1] = Py::Int(height);
    +    Py::PythonClassObject o = Py::PythonClassObject(
    +        class_type.apply(args, Py::Dict()));
    +    return o;
     }
     
     void
    @@ -197,6 +189,7 @@
     
         return Py::Object();
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Image, py_write_bitmap)
     
     void
     FT2Image::draw_rect(unsigned long x0, unsigned long y0,
    @@ -247,6 +240,7 @@
     
         return Py::Object();
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Image, py_draw_rect)
     
     void
     FT2Image::draw_rect_filled(unsigned long x0, unsigned long y0,
    @@ -290,9 +284,10 @@
     
         return Py::Object();
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Image, py_draw_rect_filled)
     
     char FT2Image::as_str__doc__[] =
    -    "width, height, s = image_as_str()\n"
    +    "s = image.as_str()\n"
         "\n"
         "Return the image buffer as a string\n"
         "\n"
    @@ -304,124 +299,96 @@
         args.verify_length(0);
     
         return Py::asObject
    -      (PyString_FromStringAndSize((const char *)_buffer,
    -                                  _width*_height)
    -       );
    +      (PyBytes_FromStringAndSize((const char *)_buffer, _width*_height));
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Image, py_as_str)
     
    -char FT2Image::as_array__doc__[] =
    -    "x = image.as_array()\n"
    +char FT2Image::as_rgba_str__doc__[] =
    +    "s = image.as_rgba_str()\n"
         "\n"
    -    "Return the image buffer as a width x height numpy array of ubyte \n"
    +    "Return the image buffer as a RGBA string\n"
         "\n"
         ;
     Py::Object
    -FT2Image::py_as_array(const Py::Tuple & args)
    +FT2Image::py_as_rgba_str(const Py::Tuple & args)
     {
    -    _VERBOSE("FT2Image::as_array");
    +    _VERBOSE("FT2Image::as_str");
         args.verify_length(0);
     
    -    npy_intp dimensions[2];
    -    dimensions[0] = get_height();  //numrows
    -    dimensions[1] = get_width();   //numcols
    -
    -
    -    PyArrayObject *A = (PyArrayObject *) PyArray_SimpleNewFromData(2, dimensions, PyArray_UBYTE, _buffer);
    -
    -    return Py::asObject((PyObject*)A);
    -}
    +    Py_ssize_t size = _width*_height*4;
    +    PyObject* result = PyBytes_FromStringAndSize(NULL, size);
     
    -void
    -FT2Image::makeRgbCopy()
    -{
    -    if (!_isDirty)
    -    {
    -        return;
    -    }
    +    unsigned char *src     = _buffer;
    +    unsigned char *src_end = src + (_width * _height);
    +    unsigned char *dst     = (unsigned char *)PyBytes_AS_STRING(result);
     
    -    if (!_rgbCopy)
    -    {
    -        _rgbCopy = new FT2Image(_width * 3, _height);
    -    }
    -    else
    -    {
    -        _rgbCopy->resize(_width * 3, _height);
    -    }
    -    unsigned char *src            = _buffer;
    -    unsigned char *src_end        = src + (_width * _height);
    -    unsigned char *dst            = _rgbCopy->_buffer;
    -
    -    unsigned char tmp;
         while (src != src_end)
         {
    -        tmp = 255 - *src++;
    -        *dst++ = tmp;
    -        *dst++ = tmp;
    -        *dst++ = tmp;
    +        *dst++ = 0;
    +        *dst++ = 0;
    +        *dst++ = 0;
    +        *dst++ = *src++;
         }
    +
    +    return Py::asObject(result);
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Image, py_as_rgba_str)
     
    +/* TODO: This could take a color as an argument, but for
    +   now it defaults to black on white background */
     char FT2Image::as_rgb_str__doc__[] =
    -    "width, height, s = image_as_rgb_str()\n"
    +    "s = image.as_rgb_str()\n"
         "\n"
    -    "Return the image buffer as a 24-bit RGB string.\n"
    +    "Return the image buffer as a RGB string\n"
         "\n"
         ;
     Py::Object
     FT2Image::py_as_rgb_str(const Py::Tuple & args)
     {
    -    _VERBOSE("FT2Image::as_str_rgb");
    +    _VERBOSE("FT2Image::as_str");
         args.verify_length(0);
     
    -    makeRgbCopy();
    +    Py_ssize_t size = _width*_height*3;
    +    PyObject* result = PyBytes_FromStringAndSize(NULL, size);
     
    -    return _rgbCopy->py_as_str(args);
    -}
    -
    -void FT2Image::makeRgbaCopy()
    -{
    -    if (!_isDirty)
    -    {
    -        return;
    -    }
    -
    -    if (!_rgbaCopy)
    -    {
    -        _rgbaCopy = new FT2Image(_width * 4, _height);
    -    }
    -    else
    -    {
    -        _rgbaCopy->resize(_width * 4, _height);
    -    }
    -    unsigned char *src            = _buffer;
    -    unsigned char *src_end        = src + (_width * _height);
    -    unsigned char *dst            = _rgbaCopy->_buffer;
    +    unsigned char *src     = _buffer;
    +    unsigned char *src_end = src + (_width * _height);
    +    unsigned char *dst     = (unsigned char *)PyBytes_AS_STRING(result);
     
         while (src != src_end)
         {
    -        // We know the array has already been zero'ed out in
    -        // the resize method, so we just skip over the r, g and b.
    -        dst += 3;
    -        *dst++ = *src++;
    +        unsigned char tmp = 255 - *src++;
    +        *dst++ = tmp;
    +        *dst++ = tmp;
    +        *dst++ = tmp;
         }
    +
    +    return Py::asObject(result);
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Image, py_as_rgb_str)
     
    -char FT2Image::as_rgba_str__doc__[] =
    -    "width, height, s = image_as_rgb_str()\n"
    +char FT2Image::as_array__doc__[] =
    +    "x = image.as_array()\n"
         "\n"
    -    "Return the image buffer as a 32-bit RGBA string.\n"
    +    "Return the image buffer as a width x height numpy array of ubyte \n"
         "\n"
         ;
     Py::Object
    -FT2Image::py_as_rgba_str(const Py::Tuple & args)
    +FT2Image::py_as_array(const Py::Tuple & args)
     {
    -    _VERBOSE("FT2Image::as_str_rgba");
    +    _VERBOSE("FT2Image::as_array");
         args.verify_length(0);
     
    -    makeRgbaCopy();
    +    npy_intp dimensions[2];
    +    dimensions[0] = get_height();  //numrows
    +    dimensions[1] = get_width();   //numcols
    +
     
    -    return _rgbaCopy->py_as_str(args);
    +    PyArrayObject *A = (PyArrayObject *) PyArray_SimpleNewFromData(2, dimensions, PyArray_UBYTE, _buffer);
    +
    +    return Py::asObject((PyObject*)A);
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Image, py_as_array)
     
     Py::Object
     FT2Image::py_get_width(const Py::Tuple & args)
    @@ -431,6 +398,7 @@
     
         return Py::Int((long)get_width());
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Image, py_get_width)
     
     Py::Object
     FT2Image::py_get_height(const Py::Tuple & args)
    @@ -440,27 +408,30 @@
     
         return Py::Int((long)get_height());
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Image, py_get_height)
     
    -Glyph::Glyph(const FT_Face& face, const FT_Glyph& glyph, size_t ind) :
    -        glyphInd(ind)
    +Py::PythonClassObject Glyph::factory(
    +        const FT_Face& face, const FT_Glyph& glyph, size_t ind, long hinting_factor)
     {
    -    _VERBOSE("Glyph::Glyph");
    +    Py::Callable class_type(type());
    +    Py::PythonClassObject obj = Py::PythonClassObject(
    +        class_type.apply(Py::Tuple(), Py::Dict()));
    +    Glyph* o = obj.getCxxObject();
     
    +    o->glyphInd = ind;
         FT_BBox bbox;
         FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_subpixels, &bbox);
     
    -    setattr("width",        Py::Int(face->glyph->metrics.width / HORIZ_HINTING));
    -    setattr("height",       Py::Int(face->glyph->metrics.height));
    -    setattr("horiBearingX", Py::Int(face->glyph->metrics.horiBearingX / HORIZ_HINTING));
    -    setattr("horiBearingY", Py::Int(face->glyph->metrics.horiBearingY));
    -    setattr("horiAdvance",  Py::Int(face->glyph->metrics.horiAdvance));
    -    setattr("linearHoriAdvance",  Py::Int(face->glyph->linearHoriAdvance / HORIZ_HINTING));
    -    setattr("vertBearingX", Py::Int(face->glyph->metrics.vertBearingX));
    -
    -    setattr("vertBearingY", Py::Int(face->glyph->metrics.vertBearingY));
    -    setattr("vertAdvance",  Py::Int(face->glyph->metrics.vertAdvance));
    -    //setattr("bitmap_left",  Py::Int( face->glyph->bitmap_left) );
    -    //setattr("bitmap_top",  Py::Int( face->glyph->bitmap_top) );
    +    o->setattro("width",        Py::Int(face->glyph->metrics.width / hinting_factor));
    +    o->setattro("height",       Py::Int(face->glyph->metrics.height));
    +    o->setattro("horiBearingX", Py::Int(face->glyph->metrics.horiBearingX / hinting_factor));
    +    o->setattro("horiBearingY", Py::Int(face->glyph->metrics.horiBearingY));
    +    o->setattro("horiAdvance",  Py::Int(face->glyph->metrics.horiAdvance));
    +    o->setattro("linearHoriAdvance",  Py::Int(face->glyph->linearHoriAdvance / hinting_factor));
    +    o->setattro("vertBearingX", Py::Int(face->glyph->metrics.vertBearingX));
    +
    +    o->setattro("vertBearingY", Py::Int(face->glyph->metrics.vertBearingY));
    +    o->setattro("vertAdvance",  Py::Int(face->glyph->metrics.vertAdvance));
     
         Py::Tuple abbox(4);
     
    @@ -468,7 +439,9 @@
         abbox[1] = Py::Int(bbox.yMin);
         abbox[2] = Py::Int(bbox.xMax);
         abbox[3] = Py::Int(bbox.yMax);
    -    setattr("bbox", abbox);
    +    o->setattro("bbox", abbox);
    +
    +    return obj;
     }
     
     Glyph::~Glyph()
    @@ -477,7 +450,7 @@
     }
     
     int
    -Glyph::setattr(const char *name, const Py::Object &value)
    +Glyph::setattro(const Py::String &name, const Py::Object &value)
     {
         _VERBOSE("Glyph::setattr");
         __dict__[name] = value;
    @@ -485,11 +458,11 @@
     }
     
     Py::Object
    -Glyph::getattr(const char *name)
    +Glyph::getattro(const Py::String &name)
     {
         _VERBOSE("Glyph::getattr");
         if (__dict__.hasKey(name)) return __dict__[name];
    -    else return getattr_default(name);
    +    else return genericGetAttro(name);
     }
     
     inline double conv(int v)
    @@ -498,7 +471,11 @@
     }
     
     
    -//see http://freetype.sourceforge.net/freetype2/docs/glyphs/glyphs-6.html
    +char FT2Font::get_path__doc__[] =
    +    "get_path()\n"
    +    "\n"
    +    "Get the path data from the currently loaded glyph as a tuple of vertices, codes.\n"
    +    ;
     Py::Object
     FT2Font::get_path()
     {
    @@ -856,12 +833,17 @@
     
         return result;
     }
    +PYCXX_NOARGS_METHOD_DECL(FT2Font, get_path)
     
    -
    -FT2Font::FT2Font(std::string facefile) :
    -    image(NULL)
    +FT2Font::FT2Font(Py::PythonClassInstance *self, Py::Tuple &args, Py::Dict &kwds) :
    +    Py::PythonClass::PythonClass(self, args, kwds),
    +    image()
     {
    +    args.verify_length(1);
    +    std::string facefile = Py::String(args[0]);
    +
         _VERBOSE(Printf("FT2Font::FT2Font %s", facefile.c_str()).str());
    +
         clear(Py::Tuple(0));
     
         int error = FT_New_Face(_ft2Library, facefile.c_str(), 0, &face);
    @@ -870,40 +852,46 @@
         {
             std::ostringstream s;
             s << "Could not load facefile " << facefile << "; Unknown_File_Format" << std::endl;
    +        ob_refcnt--;
             throw Py::RuntimeError(s.str());
         }
         else if (error == FT_Err_Cannot_Open_Resource)
         {
             std::ostringstream s;
             s << "Could not open facefile " << facefile << "; Cannot_Open_Resource" << std::endl;
    +        ob_refcnt--;
             throw Py::RuntimeError(s.str());
         }
         else if (error == FT_Err_Invalid_File_Format)
         {
             std::ostringstream s;
             s << "Could not open facefile " << facefile << "; Invalid_File_Format" << std::endl;
    +        ob_refcnt--;
             throw Py::RuntimeError(s.str());
         }
         else if (error)
         {
             std::ostringstream s;
             s << "Could not open facefile " << facefile << "; freetype error code " << error << std::endl;
    +        ob_refcnt--;
             throw Py::RuntimeError(s.str());
         }
     
         // set a default fontsize 12 pt at 72dpi
    -#ifdef VERTICAL_HINTING
    -    error = FT_Set_Char_Size(face, 12 * 64, 0, 72 * HORIZ_HINTING, 72);
    -    static FT_Matrix transform = { 65536 / HORIZ_HINTING, 0, 0, 65536 };
    +    hinting_factor = 8;
    +    if (kwds.hasKey("hinting_factor"))
    +    {
    +        hinting_factor = Py::Long(kwds["hinting_factor"]);
    +    }
    +
    +    error = FT_Set_Char_Size(face, 12 * 64, 0, 72 * hinting_factor, 72);
    +    static FT_Matrix transform = { 65536 / hinting_factor, 0, 0, 65536 };
         FT_Set_Transform(face, &transform, 0);
    -#else
    -    error = FT_Set_Char_Size(face, 12 * 64, 0, 72, 72);
    -#endif
    -    //error = FT_Set_Char_Size( face, 20 * 64, 0, 80, 80 );
         if (error)
         {
             std::ostringstream s;
             s << "Could not set the fontsize for facefile  " << facefile << std::endl;
    +        ob_refcnt--;
             throw Py::RuntimeError(s.str());
         }
     
    @@ -929,40 +917,40 @@
             style_name = "UNAVAILABLE";
         }
     
    -    setattr("postscript_name", Py::String(ps_name));
    -    setattr("num_faces",       Py::Int(face->num_faces));
    -    setattr("family_name",     Py::String(family_name));
    -    setattr("style_name",      Py::String(style_name));
    -    setattr("face_flags",      Py::Int(face->face_flags));
    -    setattr("style_flags",     Py::Int(face->style_flags));
    -    setattr("num_glyphs",      Py::Int(face->num_glyphs));
    -    setattr("num_fixed_sizes", Py::Int(face->num_fixed_sizes));
    -    setattr("num_charmaps",    Py::Int(face->num_charmaps));
    +    setattro("postscript_name", Py::String(ps_name));
    +    setattro("num_faces",       Py::Int(face->num_faces));
    +    setattro("family_name",     Py::String(family_name));
    +    setattro("style_name",      Py::String(style_name));
    +    setattro("face_flags",      Py::Int(face->face_flags));
    +    setattro("style_flags",     Py::Int(face->style_flags));
    +    setattro("num_glyphs",      Py::Int(face->num_glyphs));
    +    setattro("num_fixed_sizes", Py::Int(face->num_fixed_sizes));
    +    setattro("num_charmaps",    Py::Int(face->num_charmaps));
     
         int scalable = FT_IS_SCALABLE(face);
     
    -    setattr("scalable", Py::Int(scalable));
    +    setattro("scalable", Py::Int(scalable));
     
         if (scalable)
         {
    -        setattr("units_per_EM", Py::Int(face->units_per_EM));
    +        setattro("units_per_EM", Py::Int(face->units_per_EM));
     
             Py::Tuple bbox(4);
             bbox[0] = Py::Int(face->bbox.xMin);
             bbox[1] = Py::Int(face->bbox.yMin);
             bbox[2] = Py::Int(face->bbox.xMax);
             bbox[3] = Py::Int(face->bbox.yMax);
    -        setattr("bbox",  bbox);
    -        setattr("ascender",            Py::Int(face->ascender));
    -        setattr("descender",           Py::Int(face->descender));
    -        setattr("height",              Py::Int(face->height));
    -        setattr("max_advance_width",   Py::Int(face->max_advance_width));
    -        setattr("max_advance_height",  Py::Int(face->max_advance_height));
    -        setattr("underline_position",  Py::Int(face->underline_position));
    -        setattr("underline_thickness", Py::Int(face->underline_thickness));
    +        setattro("bbox",  bbox);
    +        setattro("ascender",            Py::Int(face->ascender));
    +        setattro("descender",           Py::Int(face->descender));
    +        setattro("height",              Py::Int(face->height));
    +        setattro("max_advance_width",   Py::Int(face->max_advance_width));
    +        setattro("max_advance_height",  Py::Int(face->max_advance_height));
    +        setattro("underline_position",  Py::Int(face->underline_position));
    +        setattro("underline_thickness", Py::Int(face->underline_thickness));
         }
     
    -    setattr("fname", Py::String(facefile));
    +    setattro("fname", Py::String(facefile));
     
         _VERBOSE("FT2Font::FT2Font done");
     }
    @@ -971,7 +959,6 @@
     {
         _VERBOSE("FT2Font::~FT2Font");
     
    -    Py_XDECREF(image);
         FT_Done_Face(face);
     
         for (size_t i = 0; i < glyphs.size(); i++)
    @@ -981,7 +968,7 @@
     }
     
     int
    -FT2Font::setattr(const char *name, const Py::Object &value)
    +FT2Font::setattro(const Py::String &name, const Py::Object &value)
     {
         _VERBOSE("FT2Font::setattr");
         __dict__[name] = value;
    @@ -989,11 +976,11 @@
     }
     
     Py::Object
    -FT2Font::getattr(const char *name)
    +FT2Font::getattro(const Py::String &name)
     {
         _VERBOSE("FT2Font::getattr");
         if (__dict__.hasKey(name)) return __dict__[name];
    -    else return getattr_default(name);
    +    else return genericGetAttro(name);
     }
     
     char FT2Font::clear__doc__[] =
    @@ -1008,9 +995,6 @@
         _VERBOSE("FT2Font::clear");
         args.verify_length(0);
     
    -    Py_XDECREF(image);
    -    image = NULL;
    -
         angle = 0.0;
     
         pen.x = 0;
    @@ -1025,9 +1009,7 @@
     
         return Py::Object();
     }
    -
    -
    -
    +PYCXX_VARARGS_METHOD_DECL(FT2Font, clear)
     
     char FT2Font::set_size__doc__[] =
         "set_size(ptsize, dpi)\n"
    @@ -1044,24 +1026,19 @@
         double ptsize = Py::Float(args[0]);
         double dpi = Py::Float(args[1]);
     
    -#ifdef VERTICAL_HINTING
         int error = FT_Set_Char_Size(face, (long)(ptsize * 64), 0,
    -                                 (unsigned int)dpi * HORIZ_HINTING,
    +                                 (unsigned int)dpi * hinting_factor,
                                      (unsigned int)dpi);
    -    static FT_Matrix transform = { 65536 / HORIZ_HINTING, 0, 0, 65536 };
    +    static FT_Matrix transform = { 65536 / hinting_factor, 0, 0, 65536 };
         FT_Set_Transform(face, &transform, 0);
    -#else
    -    int error = FT_Set_Char_Size(face, (long)(ptsize * 64), 0,
    -                                 (unsigned int)dpi,
    -                                 (unsigned int)dpi);
    -#endif
    +
         if (error)
         {
             throw Py::RuntimeError("Could not set the fontsize");
         }
         return Py::Object();
     }
    -
    +PYCXX_VARARGS_METHOD_DECL(FT2Font, set_size)
     
     char FT2Font::set_charmap__doc__[] =
         "set_charmap(i)\n"
    @@ -1087,6 +1064,7 @@
         }
         return Py::Object();
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Font, set_charmap)
     
     char FT2Font::select_charmap__doc__[] =
         "select_charmap(i)\n"
    @@ -1108,6 +1086,7 @@
         }
         return Py::Object();
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Font, select_charmap)
     
     FT_BBox
     FT2Font::compute_string_bbox()
    @@ -1148,7 +1127,6 @@
         return bbox;
     }
     
    -
     char FT2Font::get_kerning__doc__[] =
         "dx = get_kerning(left, right, mode)\n"
         "\n"
    @@ -1176,7 +1154,7 @@
     
         if (!FT_Get_Kerning(face, left, right, mode, &delta))
         {
    -        return Py::Int(delta.x / HORIZ_HINTING);
    +        return Py::Int(delta.x / hinting_factor);
         }
         else
         {
    @@ -1184,7 +1162,7 @@
     
         }
     }
    -
    +PYCXX_VARARGS_METHOD_DECL(FT2Font, get_kerning)
     
     
     char FT2Font::set_text__doc__[] =
    @@ -1264,7 +1242,7 @@
                 FT_Vector delta;
                 FT_Get_Kerning(face, previous, glyph_index,
                                FT_KERNING_DEFAULT, &delta);
    -            pen.x += delta.x / HORIZ_HINTING;
    +            pen.x += delta.x / hinting_factor;
             }
             error = FT_Load_Glyph(face, glyph_index, flags);
             if (error)
    @@ -1306,6 +1284,7 @@
         _VERBOSE("FT2Font::set_text done");
         return xys;
     }
    +PYCXX_KEYWORDS_METHOD_DECL(FT2Font, set_text)
     
     char FT2Font::get_num_glyphs__doc__[] =
         "get_num_glyphs()\n"
    @@ -1320,6 +1299,7 @@
     
         return Py::Int((long)glyphs.size());
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Font, get_num_glyphs)
     
     char FT2Font::load_char__doc__[] =
         "load_char(charcode, flags=LOAD_FORCE_AUTOHINT)\n"
    @@ -1367,10 +1347,9 @@
     
         size_t num = glyphs.size();  //the index into the glyphs list
         glyphs.push_back(thisGlyph);
    -    Glyph* gm = new Glyph(face, thisGlyph, num);
    -    return Py::asObject(gm);
    +    return Glyph::factory(face, thisGlyph, num, hinting_factor);
     }
    -
    +PYCXX_KEYWORDS_METHOD_DECL(FT2Font, load_char)
     
     char FT2Font::load_glyph__doc__[] =
         "load_glyph(glyphindex, flags=LOAD_FORCE_AUTOHINT)\n"
    @@ -1418,10 +1397,9 @@
     
         size_t num = glyphs.size();  //the index into the glyphs list
         glyphs.push_back(thisGlyph);
    -    Glyph* gm = new Glyph(face, thisGlyph, num);
    -    return Py::asObject(gm);
    +    return Glyph::factory(face, thisGlyph, num, hinting_factor);
     }
    -
    +PYCXX_KEYWORDS_METHOD_DECL(FT2Font, load_glyph)
     
     char FT2Font::get_width_height__doc__[] =
         "w, h = get_width_height()\n"
    @@ -1443,6 +1421,7 @@
         ret[1] = Py::Int(bbox.yMax - bbox.yMin);
         return ret;
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Font, get_width_height)
     
     char FT2Font::get_descent__doc__[] =
         "d = get_descent()\n"
    @@ -1460,6 +1439,7 @@
         FT_BBox bbox = compute_string_bbox();
         return Py::Int(- bbox.yMin);;
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Font, get_descent)
     
     char FT2Font::draw_glyphs_to_bitmap__doc__[] =
         "draw_glyphs_to_bitmap()\n"
    @@ -1484,9 +1464,8 @@
         size_t width = (string_bbox.xMax - string_bbox.xMin) / 64 + 2;
         size_t height = (string_bbox.yMax - string_bbox.yMin) / 64 + 2;
     
    -    Py_XDECREF(image);
    -    image = NULL;
    -    image = new FT2Image(width, height);
    +    image = FT2Image::factory(width, height);
    +    FT2Image* image_cxx = Py::PythonClassObject(image).getCxxObject();
     
         for (size_t n = 0; n < glyphs.size(); n++)
         {
    @@ -1510,12 +1489,12 @@
             FT_Int x = (FT_Int)(bitmap->left - (string_bbox.xMin / 64.));
             FT_Int y = (FT_Int)((string_bbox.yMax / 64.) - bitmap->top + 1);
     
    -        image->draw_bitmap(&bitmap->bitmap, x, y);
    +        image_cxx->draw_bitmap(&bitmap->bitmap, x, y);
         }
     
         return Py::Object();
     }
    -
    +PYCXX_KEYWORDS_METHOD_DECL(FT2Font, draw_glyphs_to_bitmap)
     
     char FT2Font::get_xys__doc__[] =
         "get_xys()\n"
    @@ -1570,6 +1549,7 @@
     
         return xys;
     }
    +PYCXX_KEYWORDS_METHOD_DECL(FT2Font, get_xys)
     
     char FT2Font::draw_glyph_to_bitmap__doc__[] =
         "draw_glyph_to_bitmap(bitmap, x, y, glyph)\n"
    @@ -1589,11 +1569,7 @@
         _VERBOSE("FT2Font::draw_glyph_to_bitmap");
         args.verify_length(4);
     
    -    if (!FT2Image::check(args[0].ptr()))
    -    {
    -        throw Py::TypeError("Usage: draw_glyph_to_bitmap(bitmap, x,y,glyph)");
    -    }
    -    FT2Image* im = static_cast(args[0].ptr());
    +    FT2Image* im = Py::PythonClassObject(args[0]).getCxxObject();
     
         double xd = Py::Float(args[1]);
         double yd = Py::Float(args[2]);
    @@ -1603,11 +1579,7 @@
         sub_offset.x = 0; // int((xd - (double)x) * 64.0);
         sub_offset.y = 0; // int((yd - (double)y) * 64.0);
     
    -    if (!Glyph::check(args[3].ptr()))
    -    {
    -        throw Py::TypeError("Usage: draw_glyph_to_bitmap(bitmap, x,y,glyph)");
    -    }
    -    Glyph* glyph = static_cast(args[3].ptr());
    +    Glyph* glyph = Py::PythonClassObject(args[3]).getCxxObject();
     
         long antialiased = 1;
         if (kwargs.hasKey("antialiased"))
    @@ -1615,7 +1587,7 @@
             antialiased = Py::Long(kwargs["antialiased"]);
         }
     
    -    if ((size_t)glyph->glyphInd >= glyphs.size())
    +    if (glyph->glyphInd >= glyphs.size())
         {
             throw Py::ValueError("glyph num is out of range");
         }
    @@ -1636,6 +1608,7 @@
         im->draw_bitmap(&bitmap->bitmap, x + bitmap->left, y);
         return Py::Object();
     }
    +PYCXX_KEYWORDS_METHOD_DECL(FT2Font, draw_glyph_to_bitmap)
     
     char FT2Font::get_glyph_name__doc__[] =
         "get_glyph_name(index)\n"
    @@ -1654,12 +1627,13 @@
         }
     
         char buffer[128];
    -    if (FT_Get_Glyph_Name(face, (FT_UInt) Py::Int(args[0]), buffer, 128))
    +    if (FT_Get_Glyph_Name(face, (FT_UInt) (unsigned long)Py::Int(args[0]), buffer, 128))
         {
             throw Py::RuntimeError("Could not get glyph names.");
         }
         return Py::String(buffer);
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Font, get_glyph_name)
     
     char FT2Font::get_charmap__doc__[] =
         "get_charmap()\n"
    @@ -1685,7 +1659,7 @@
         }
         return charmap;
     }
    -
    +PYCXX_VARARGS_METHOD_DECL(FT2Font, get_charmap)
     
     // ID        Platform       Encoding
     // 0         Unicode        Reserved (set to 0)
    @@ -1774,10 +1748,12 @@
             key[2] = Py::Int(sfnt.language_id);
             key[3] = Py::Int(sfnt.name_id);
             names[key] = Py::String((char *) sfnt.string,
    -                                (int) sfnt.string_len);
    +                                (int) sfnt.string_len,
    +                                "latin-1");
         }
         return names;
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Font, get_sfnt)
     
     char FT2Font::get_name_index__doc__[] =
         "get_name_index(name)\n"
    @@ -1795,6 +1771,7 @@
         return Py::Long((long)
                         FT_Get_Name_Index(face, (FT_String *) glyphname.c_str()));
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Font, get_name_index)
     
     char FT2Font::get_ps_font_info__doc__[] =
         "get_ps_font_info()\n"
    @@ -1827,6 +1804,7 @@
         info[8] = Py::Int(fontinfo.underline_thickness);
         return info;
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Font, get_ps_font_info)
     
     char FT2Font::get_sfnt_table__doc__[] =
         "get_sfnt_table(name)\n"
    @@ -1922,9 +1900,15 @@
             }
         case 2:
             {
    +            #if PY3K
    +            char os_2_dict[] = "{s:h, s:h, s:h, s:h, s:h, s:h, s:h, s:h,"
    +                "s:h, s:h, s:h, s:h, s:h, s:h, s:h, s:h, s:y#, s:(llll),"
    +                "s:y#, s:h, s:h, s:h}";
    +            #else
                 char os_2_dict[] = "{s:h, s:h, s:h, s:h, s:h, s:h, s:h, s:h,"
                     "s:h, s:h, s:h, s:h, s:h, s:h, s:h, s:h, s:s#, s:(llll),"
                     "s:s#, s:h, s:h, s:h}";
    +            #endif
                 TT_OS2 *t = (TT_OS2 *)table;
                 return Py::asObject(Py_BuildValue(os_2_dict,
                                                   "version", (unsigned)t->version,
    @@ -2035,10 +2019,14 @@
                 pclt["typeFamily"]         = Py::Int((short) t->TypeFamily);
                 pclt["capHeight"]          = Py::Int((short) t->CapHeight);
                 pclt["symbolSet"]          = Py::Int((short) t->SymbolSet);
    +            #if PY3K
    +            pclt["typeFace"]           = Py::String((char *) t->TypeFace, 16, "latin-1");
    +            pclt["characterComplement"] = Py::Bytes((char *) t->CharacterComplement, 8);
    +            #else
                 pclt["typeFace"]           = Py::String((char *) t->TypeFace, 16);
    -            pclt["characterComplement"] = Py::String((char *)
    -                                                     t->CharacterComplement, 8);
    -            pclt["filename"]           = Py::String((char *) t->FileName, 6);
    +            pclt["characterComplement"] = Py::String((char *) t->CharacterComplement, 8);
    +            #endif
    +            // pclt["filename"]           = Py::String((char *) t->FileName, 6);
                 pclt["strokeWeight"]       = Py::Int((int) t->StrokeWeight);
                 pclt["widthType"]          = Py::Int((int) t->WidthType);
                 pclt["serifStyle"]         = Py::Int((int) t->SerifStyle);
    @@ -2048,6 +2036,7 @@
             return Py::Object();
         }
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Font, get_sfnt_table)
     
     char FT2Font::get_image__doc__ [] =
         "get_image()\n"
    @@ -2057,13 +2046,13 @@
     FT2Font::get_image(const Py::Tuple &args)
     {
         args.verify_length(0);
    -    if (image)
    +    if (!image.isNone())
         {
    -        Py_XINCREF(image);
    -        return Py::asObject(image);
    +        return image;
         }
         throw Py::RuntimeError("You must call .set_text() before .get_image()");
     }
    +PYCXX_VARARGS_METHOD_DECL(FT2Font, get_image)
     
     char FT2Font::attach_file__doc__ [] =
         "attach_file(filename)\n"
    @@ -2088,53 +2077,35 @@
         }
         return Py::Object();
     }
    -
    -Py::Object
    -ft2font_module::new_ft2image(const Py::Tuple &args)
    -{
    -    args.verify_length(2);
    -
    -    int width = Py::Int(args[0]);
    -    int height = Py::Int(args[1]);
    -
    -    return Py::asObject(new FT2Image(width, height));
    -}
    -
    -Py::Object
    -ft2font_module::new_ft2font(const Py::Tuple &args)
    -{
    -    _VERBOSE("ft2font_module::new_ft2font ");
    -    args.verify_length(1);
    -
    -    std::string facefile = Py::String(args[0]);
    -    return Py::asObject(new FT2Font(facefile));
    -}
    +PYCXX_VARARGS_METHOD_DECL(FT2Font, attach_file)
     
     void
    -FT2Image::init_type()
    +FT2Image::init_type(void)
     {
         _VERBOSE("FT2Image::init_type");
         behaviors().name("FT2Image");
         behaviors().doc("FT2Image");
     
    -    add_varargs_method("write_bitmap", &FT2Image::py_write_bitmap,
    -                       FT2Image::write_bitmap__doc__);
    -    add_varargs_method("draw_rect", &FT2Image::py_draw_rect,
    -                       FT2Image::draw_rect__doc__);
    -    add_varargs_method("draw_rect_filled", &FT2Image::py_draw_rect_filled,
    -                       FT2Image::draw_rect_filled__doc__);
    -    add_varargs_method("as_array", &FT2Image::py_as_array,
    -                       FT2Image::as_array__doc__);
    -    add_varargs_method("as_str", &FT2Image::py_as_str,
    -                       FT2Image::as_str__doc__);
    -    add_varargs_method("as_rgb_str", &FT2Image::py_as_rgb_str,
    -                       FT2Image::as_rgb_str__doc__);
    -    add_varargs_method("as_rgba_str", &FT2Image::py_as_rgba_str,
    -                       FT2Image::as_rgba_str__doc__);
    -    add_varargs_method("get_width", &FT2Image::py_get_width,
    -                       "Returns the width of the image");
    -    add_varargs_method("get_height", &FT2Image::py_get_height,
    -                       "Returns the height of the image");
    +    PYCXX_ADD_VARARGS_METHOD(write_bitmap, py_write_bitmap,
    +                             FT2Image::write_bitmap__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(draw_rect, py_draw_rect,
    +                             FT2Image::draw_rect__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(draw_rect_filled, py_draw_rect_filled,
    +                             FT2Image::draw_rect_filled__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(as_array, py_as_array,
    +                             FT2Image::as_array__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(as_str, py_as_str,
    +                             FT2Image::as_str__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(as_rgb_str, py_as_rgb_str,
    +                             FT2Image::as_rgb_str__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(as_rgba_str, py_as_rgba_str,
    +                             FT2Image::as_rgba_str__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(get_width, py_get_width,
    +                             "Returns the width of the image");
    +    PYCXX_ADD_VARARGS_METHOD(get_height, py_get_height,
    +                             "Returns the height of the image");
    +
    +    behaviors().readyType();
     }
     
     void
    @@ -2143,8 +2114,9 @@
         _VERBOSE("Glyph::init_type");
         behaviors().name("Glyph");
         behaviors().doc("Glyph");
    -    behaviors().supportGetattr();
    -    behaviors().supportSetattr();
    +    behaviors().supportGetattro();
    +    behaviors().supportSetattro();
    +    behaviors().readyType();
     }
     
     void
    @@ -2153,58 +2125,59 @@
         _VERBOSE("FT2Font::init_type");
         behaviors().name("FT2Font");
         behaviors().doc("FT2Font");
    +    behaviors().supportGetattro();
    +    behaviors().supportSetattro();
     
    -    add_varargs_method("clear", &FT2Font::clear,
    -                       FT2Font::clear__doc__);
    -    add_keyword_method("draw_glyph_to_bitmap", &FT2Font::draw_glyph_to_bitmap,
    -                       FT2Font::draw_glyph_to_bitmap__doc__);
    -    add_keyword_method("draw_glyphs_to_bitmap", &FT2Font::draw_glyphs_to_bitmap,
    -                       FT2Font::draw_glyphs_to_bitmap__doc__);
    -    add_keyword_method("get_xys", &FT2Font::get_xys,
    -                       FT2Font::get_xys__doc__);
    -
    -    add_varargs_method("get_num_glyphs", &FT2Font::get_num_glyphs,
    -                       FT2Font::get_num_glyphs__doc__);
    -    add_keyword_method("load_char", &FT2Font::load_char,
    -                       FT2Font::load_char__doc__);
    -    add_keyword_method("load_glyph", &FT2Font::load_glyph,
    -                       FT2Font::load_glyph__doc__);
    -    add_keyword_method("set_text", &FT2Font::set_text,
    -                       FT2Font::set_text__doc__);
    -    add_varargs_method("set_size", &FT2Font::set_size,
    -                       FT2Font::set_size__doc__);
    -    add_varargs_method("set_charmap", &FT2Font::set_charmap,
    -                       FT2Font::set_charmap__doc__);
    -    add_varargs_method("select_charmap", &FT2Font::select_charmap,
    -                       FT2Font::select_charmap__doc__);
    -
    -    add_varargs_method("get_width_height", &FT2Font::get_width_height,
    -                       FT2Font::get_width_height__doc__);
    -    add_varargs_method("get_descent", &FT2Font::get_descent,
    -                       FT2Font::get_descent__doc__);
    -    add_varargs_method("get_glyph_name", &FT2Font::get_glyph_name,
    -                       FT2Font::get_glyph_name__doc__);
    -    add_varargs_method("get_charmap", &FT2Font::get_charmap,
    -                       FT2Font::get_charmap__doc__);
    -    add_varargs_method("get_kerning", &FT2Font::get_kerning,
    -                       FT2Font::get_kerning__doc__);
    -    add_varargs_method("get_sfnt", &FT2Font::get_sfnt,
    -                       FT2Font::get_sfnt__doc__);
    -    add_varargs_method("get_name_index", &FT2Font::get_name_index,
    -                       FT2Font::get_name_index__doc__);
    -    add_varargs_method("get_ps_font_info", &FT2Font::get_ps_font_info,
    -                       FT2Font::get_ps_font_info__doc__);
    -    add_varargs_method("get_sfnt_table", &FT2Font::get_sfnt_table,
    -                       FT2Font::get_sfnt_table__doc__);
    -    add_varargs_method("get_image", &FT2Font::get_image,
    -                       FT2Font::get_image__doc__);
    -    add_varargs_method("attach_file", &FT2Font::attach_file,
    -                       FT2Font::attach_file__doc__);
    -    add_noargs_method("get_path", &FT2Font::get_path,
    -                      "");
    +    PYCXX_ADD_VARARGS_METHOD(clear, clear,
    +                             FT2Font::clear__doc__);
    +    PYCXX_ADD_KEYWORDS_METHOD(draw_glyph_to_bitmap, draw_glyph_to_bitmap,
    +                             FT2Font::draw_glyph_to_bitmap__doc__);
    +    PYCXX_ADD_KEYWORDS_METHOD(draw_glyphs_to_bitmap, draw_glyphs_to_bitmap,
    +                             FT2Font::draw_glyphs_to_bitmap__doc__);
    +    PYCXX_ADD_KEYWORDS_METHOD(get_xys, get_xys,
    +                             FT2Font::get_xys__doc__);
    +
    +    PYCXX_ADD_VARARGS_METHOD(get_num_glyphs, get_num_glyphs,
    +                             FT2Font::get_num_glyphs__doc__);
    +    PYCXX_ADD_KEYWORDS_METHOD(load_char, load_char,
    +                              FT2Font::load_char__doc__);
    +    PYCXX_ADD_KEYWORDS_METHOD(load_glyph, load_glyph,
    +                              FT2Font::load_glyph__doc__);
    +    PYCXX_ADD_KEYWORDS_METHOD(set_text, set_text,
    +                              FT2Font::set_text__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(set_size, set_size,
    +                             FT2Font::set_size__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(set_charmap, set_charmap,
    +                             FT2Font::set_charmap__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(select_charmap, select_charmap,
    +                             FT2Font::select_charmap__doc__);
    +
    +    PYCXX_ADD_VARARGS_METHOD(get_width_height, get_width_height,
    +                             FT2Font::get_width_height__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(get_descent, get_descent,
    +                             FT2Font::get_descent__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(get_glyph_name, get_glyph_name,
    +                             FT2Font::get_glyph_name__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(get_charmap, get_charmap,
    +                             FT2Font::get_charmap__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(get_kerning, get_kerning,
    +                             FT2Font::get_kerning__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(get_sfnt, get_sfnt,
    +                             FT2Font::get_sfnt__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(get_name_index, get_name_index,
    +                             FT2Font::get_name_index__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(get_ps_font_info, get_ps_font_info,
    +                             FT2Font::get_ps_font_info__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(get_sfnt_table, get_sfnt_table,
    +                             FT2Font::get_sfnt_table__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(get_image, get_image,
    +                             FT2Font::get_image__doc__);
    +    PYCXX_ADD_VARARGS_METHOD(attach_file, attach_file,
    +                             FT2Font::attach_file__doc__);
    +    PYCXX_ADD_NOARGS_METHOD(get_path, get_path,
    +                            FT2Font::get_path__doc__);
     
    -    behaviors().supportGetattr();
    -    behaviors().supportSetattr();
    +    behaviors().readyType();
     }
     
     //todo add module docs strings
    @@ -2260,18 +2233,35 @@
         "  postscript_name        PostScript name of the font\n"
         ;
     
    -#if defined(_MSC_VER)
    -DL_EXPORT(void)
    -#elif defined(__cplusplus)
    -extern "C" void
    +ft2font_module::ft2font_module()
    +    : Py::ExtensionModule("ft2font")
    +{
    +    FT2Image::init_type();
    +    Glyph::init_type();
    +    FT2Font::init_type();
    +
    +    initialize("The ft2font module");
    +
    +    Py::Dict d(moduleDictionary());
    +    Py::Object ft2font_type(FT2Font::type());
    +    d["FT2Font"] = ft2font_type;
    +    Py::Object ft2image_type(FT2Image::type());
    +    d["FT2Image"] = ft2image_type;
    +}
    +
    +ft2font_module::~ft2font_module()
    +{
    +    FT_Done_FreeType(_ft2Library);
    +}
    +
    +PyMODINIT_FUNC
    +#if PY3K
    +PyInit_ft2font(void)
     #else
    -void
    -#endif
     initft2font(void)
    +#endif
     {
         static ft2font_module* ft2font = new ft2font_module;
    -    import_array();
    -
         Py::Dict d = ft2font->moduleDictionary();
         d["SCALABLE"]         = Py::Int(FT_FACE_FLAG_SCALABLE);
         d["FIXED_SIZES"]      = Py::Int(FT_FACE_FLAG_FIXED_SIZES);
    @@ -2331,10 +2321,10 @@
     
             d["__freetype_version__"] = Py::String(version_string);
         }
    -}
     
    -ft2font_module::~ft2font_module()
    -{
    +    import_array();
     
    -    FT_Done_FreeType(_ft2Library);
    +    #if PY3K
    +    return ft2font->module().ptr();
    +    #endif
     }
    diff -Nru matplotlib-1.1.1/src/ft2font.h matplotlib-1.2.0/src/ft2font.h
    --- matplotlib-1.1.1/src/ft2font.h	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/ft2font.h	2012-10-31 00:11:14.000000000 +0000
    @@ -21,14 +21,13 @@
     #include FT_TRUETYPE_TABLES_H
     }
     
    -
     // the freetype string rendered into a width, height buffer
    -class FT2Image : public Py::PythonExtension
    +class FT2Image : public Py::PythonClass
     {
     public:
    -    // FT2Image();
    -    FT2Image(unsigned long width, unsigned long height);
    -    ~FT2Image();
    +    FT2Image(Py::PythonClassInstance *self, Py::Tuple &args, Py::Dict &kwds);
    +    virtual ~FT2Image();
    +    static Py::PythonClassObject factory(int width, int height);
     
         static void init_type();
     
    @@ -66,7 +65,6 @@
         Py::Object py_as_rgb_str(const Py::Tuple & args);
         static char as_rgba_str__doc__ [];
         Py::Object py_as_rgba_str(const Py::Tuple & args);
    -
         Py::Object py_get_width(const Py::Tuple & args);
         Py::Object py_get_height(const Py::Tuple & args);
     
    @@ -75,35 +73,31 @@
         unsigned char *_buffer;
         unsigned long _width;
         unsigned long _height;
    -    FT2Image* _rgbCopy;
    -    FT2Image* _rgbaCopy;
    -
    -    void makeRgbCopy();
    -    void makeRgbaCopy();
     
         void resize(long width, long height);
     };
     
    -
    -class Glyph : public Py::PythonExtension
    +class Glyph : public Py::PythonClass
     {
     public:
    -    Glyph(const FT_Face&, const FT_Glyph&, size_t);
    -    ~Glyph();
    -    int setattr(const char *_name, const Py::Object &value);
    -    Py::Object getattr(const char *_name);
    +    Glyph(Py::PythonClassInstance *self, Py::Tuple &args, Py::Dict &kwds) :
    +        Py::PythonClass::PythonClass(self, args, kwds) { }
    +    virtual ~Glyph();
    +    static Py::PythonClassObject factory(const FT_Face&, const FT_Glyph&, size_t, long);
    +    int setattro(const Py::String &name, const Py::Object &value);
    +    Py::Object getattro(const Py::String &name);
         static void init_type(void);
         size_t glyphInd;
     private:
         Py::Dict __dict__;
     };
     
    -class FT2Font : public Py::PythonExtension
    +class FT2Font : public Py::PythonClass
     {
     
     public:
    -    FT2Font(std::string);
    -    ~FT2Font();
    +    FT2Font(Py::PythonClassInstance *self, Py::Tuple &args, Py::Dict &kwds);
    +    virtual ~FT2Font();
         static void init_type(void);
         Py::Object clear(const Py::Tuple & args);
         Py::Object set_size(const Py::Tuple & args);
    @@ -128,10 +122,10 @@
         Py::Object get_sfnt_table(const Py::Tuple & args);
         Py::Object get_image(const Py::Tuple & args);
         Py::Object attach_file(const Py::Tuple & args);
    -    int setattr(const char *_name, const Py::Object &value);
    -    Py::Object getattr(const char *_name);
    +    int setattro(const Py::String &name, const Py::Object &value);
    +    Py::Object getattro(const Py::String &name);
         Py::Object get_path();
    -    FT2Image* image;
    +    Py::Object image;
     
     private:
         Py::Dict __dict__;
    @@ -144,7 +138,7 @@
         double angle;
         double ptsize;
         double dpi;
    -
    +    long hinting_factor;
     
         FT_BBox compute_string_bbox();
         void set_scalable_attributes();
    @@ -180,27 +174,8 @@
     
     {
     public:
    -    ft2font_module()
    -            : Py::ExtensionModule("ft2font")
    -    {
    -        FT2Image::init_type();
    -        Glyph::init_type();
    -        FT2Font::init_type();
    -
    -        add_varargs_method("FT2Font", &ft2font_module::new_ft2font,
    -                           "FT2Font");
    -        add_varargs_method("FT2Image", &ft2font_module::new_ft2image,
    -                           "FT2Image");
    -        initialize("The ft2font module");
    -    }
    -
    -    ~ft2font_module();
    -    //static FT_Library ft2Library;
    -
    -private:
    -
    -    Py::Object new_ft2font(const Py::Tuple &args);
    -    Py::Object new_ft2image(const Py::Tuple &args);
    +    ft2font_module();
    +    virtual ~ft2font_module();
     };
     
     #endif
    diff -Nru matplotlib-1.1.1/src/image.cpp matplotlib-1.2.0/src/image.cpp
    --- matplotlib-1.1.1/src/image.cpp	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/image.cpp	2012-10-31 00:11:14.000000000 +0000
    @@ -33,7 +33,8 @@
     #include "mplutils.h"
     
     
    -typedef agg::pixfmt_rgba32_pre pixfmt;
    +typedef agg::pixfmt_rgba32 pixfmt;
    +typedef agg::pixfmt_rgba32_pre pixfmt_pre;
     typedef agg::renderer_base renderer_base;
     typedef agg::span_interpolator_linear<> interpolator_type;
     typedef agg::rasterizer_scanline_aa rasterizer;
    @@ -200,8 +201,13 @@
     
         std::pair bufpair = _get_output_buffer();
     
    +    #if PY3K
    +    Py::Object ret =  Py::asObject(Py_BuildValue("lly#", rowsOut, colsOut,
    +                                   bufpair.first, colsOut * rowsOut * 4));
    +    #else
         Py::Object ret =  Py::asObject(Py_BuildValue("lls#", rowsOut, colsOut,
                                        bufpair.first, colsOut * rowsOut * 4));
    +    #endif
     
         if (bufpair.second) delete [] bufpair.first;
         return ret;
    @@ -221,9 +227,14 @@
     
         args.verify_length(1);
         int format = Py::Int(args[0]);
    -
    +    PyObject* py_buffer = NULL;
         int row_len = colsOut * 4;
    -    PyObject* py_buffer = PyBuffer_New(row_len * rowsOut);
    +#if PY3K
    +    unsigned char* buf = (unsigned char *)malloc(row_len * rowsOut);
    +    if (buf == NULL)
    +        throw Py::MemoryError("Image::color_conv could not allocate memory");
    +#else
    +    py_buffer = PyBuffer_New(row_len * rowsOut);
         if (py_buffer == NULL)
             throw Py::MemoryError("Image::color_conv could not allocate memory");
     
    @@ -231,7 +242,11 @@
         Py_ssize_t buffer_len;
         int ret = PyObject_AsWriteBuffer(py_buffer, &buf, &buffer_len);
         if (ret != 0)
    +    {
    +        Py_XDECREF(py_buffer);
             throw Py::MemoryError("Image::color_conv could not allocate memory");
    +    }
    +#endif
     
         agg::rendering_buffer rtmp;
         rtmp.attach(reinterpret_cast(buf), colsOut, rowsOut,
    @@ -246,9 +261,17 @@
             agg::color_conv(&rtmp, rbufOut, agg::color_conv_rgba32_to_argb32());
             break;
         default:
    +        Py_XDECREF(py_buffer);
             throw Py::ValueError("Image::color_conv unknown format");
         }
     
    +#if PY3K
    +    py_buffer = PyByteArray_FromStringAndSize((char *)buf, row_len * rowsOut);
    +    if (py_buffer == NULL) {
    +        free(buf);
    +    }
    +#endif
    +
         PyObject* o = Py_BuildValue("llN", rowsOut, colsOut, py_buffer);
         return Py::asObject(o);
     }
    @@ -408,20 +431,24 @@
         ras.add_path(imageBox);
     
         typedef agg::wrap_mode_reflect reflect_type;
    -    typedef agg::image_accessor_wrap img_accessor_type;
    +    typedef agg::image_accessor_wrap img_accessor_type;
     
    -    pixfmt pixfmtin(*rbufIn);
    +    pixfmt_pre pixfmtin(*rbufIn);
         img_accessor_type ia(pixfmtin);
         switch (interpolation)
         {
     
         case NEAREST:
         {
    -        typedef agg::span_image_filter_rgba_nn span_gen_type;
    -        typedef agg::renderer_scanline_aa renderer_type;
    -        span_gen_type sg(ia, interpolator);
    -        renderer_type ri(rb, sa, sg);
    -        agg::render_scanlines(ras, sl, ri);
    +        if (colsIn == numcols && rowsIn == numrows) {
    +            memcpy(bufferOut, bufferIn, colsIn * rowsIn * 4);
    +        } else {
    +            typedef agg::span_image_filter_rgba_nn span_gen_type;
    +            typedef agg::renderer_scanline_aa renderer_type;
    +            span_gen_type sg(ia, interpolator);
    +            renderer_type ri(rb, sa, sg);
    +            agg::render_scanlines(ras, sl, ri);
    +        }
         }
         break;
     
    @@ -1529,10 +1556,10 @@
         Py::Object xp = args[0];
         Py::Object yp = args[1];
         Py::Object dp = args[2];
    -    unsigned int rows = Py::Int(args[3]);
    -    unsigned int cols = Py::Int(args[4]);
    +    unsigned int rows = (unsigned long)Py::Int(args[3]);
    +    unsigned int cols = (unsigned long)Py::Int(args[4]);
         Py::Tuple bounds = args[5];
    -    unsigned int interpolation = Py::Int(args[6]);
    +    unsigned int interpolation = (unsigned long)Py::Int(args[6]);
     
         if (rows >= 32768 || cols >= 32768)
         {
    @@ -1926,17 +1953,13 @@
         return Py::asObject(imo);
     }
     
    -
    -
    -#if defined(_MSC_VER)
    -DL_EXPORT(void)
    -#elif defined(__cplusplus)
    -extern "C" void
    +#if PY3K
    +PyMODINIT_FUNC
    +PyInit__image(void)
     #else
    -void
    -#endif
    -
    +PyMODINIT_FUNC
     init_image(void)
    +#endif
     {
         _VERBOSE("init_image");
     
    @@ -1965,8 +1988,8 @@
     
         d["ASPECT_FREE"] = Py::Int(Image::ASPECT_FREE);
         d["ASPECT_PRESERVE"] = Py::Int(Image::ASPECT_PRESERVE);
    -}
    -
    -
    -
     
    +#if PY3K
    +    return _image->module().ptr();
    +#endif
    +}
    diff -Nru matplotlib-1.1.1/src/mplutils.h matplotlib-1.2.0/src/mplutils.h
    --- matplotlib-1.1.1/src/mplutils.h	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/mplutils.h	2012-10-31 00:11:14.000000000 +0000
    @@ -15,10 +15,18 @@
     #ifndef _MPLUTILS_H
     #define _MPLUTILS_H
     
    +#include 
    +
     #include 
     #include 
     #include 
     
    +#if PY_MAJOR_VERSION >= 3
    +#define PY3K 1
    +#else
    +#define PY3K 0
    +#endif
    +
     void _VERBOSE(const std::string&);
     
     
    diff -Nru matplotlib-1.1.1/src/nxutils.c matplotlib-1.2.0/src/nxutils.c
    --- matplotlib-1.1.1/src/nxutils.c	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/nxutils.c	2012-10-31 00:11:14.000000000 +0000
    @@ -238,7 +238,7 @@
     };
     
     PyMODINIT_FUNC
    -     initnxutils(void)
    +initnxutils(void)
     {
       PyObject* m;
     
    diff -Nru matplotlib-1.1.1/src/path.cpp matplotlib-1.2.0/src/path.cpp
    --- matplotlib-1.1.1/src/path.cpp	2012-06-30 19:37:00.000000000 +0000
    +++ matplotlib-1.2.0/src/path.cpp	2012-11-08 13:38:03.000000000 +0000
    @@ -33,6 +33,8 @@
         {
             add_varargs_method("point_in_path", &_path_module::point_in_path,
                                "point_in_path(x, y, path, trans)");
    +        add_varargs_method("points_in_path", &_path_module::points_in_path,
    +                           "points_in_path(points, path, trans)");
             add_varargs_method("point_on_path", &_path_module::point_on_path,
                                "point_on_path(x, y, r, path, trans)");
             add_varargs_method("get_path_extents", &_path_module::get_path_extents,
    @@ -66,6 +68,7 @@
     
     private:
         Py::Object point_in_path(const Py::Tuple& args);
    +    Py::Object points_in_path(const Py::Tuple& args);
         Py::Object point_on_path(const Py::Tuple& args);
         Py::Object get_path_extents(const Py::Tuple& args);
         Py::Object update_path_extents(const Py::Tuple& args);
    @@ -119,16 +122,28 @@
     // Input 2D polygon _pgon_ with _numverts_ number of vertices and test point
     // _point_, returns 1 if inside, 0 if outside.
     template
    -bool
    -point_in_path_impl(const double tx, const double ty, T& path)
    -{
    -    int yflag0, yflag1, inside_flag;
    -    double vtx0, vty0, vtx1, vty1, sx, sy;
    +static void
    +point_in_path_impl(const void* const points_, const size_t s0,
    +                   const size_t s1, const size_t n, T& path,
    +                   npy_bool* const inside_flag)
    +{
    +    int *yflag0;
    +    int yflag1;
    +    double vtx0, vty0, vtx1, vty1;
    +    double tx, ty;
    +    double sx, sy;
         double x, y;
    +    size_t i;
    +    int all_done;
    +    const char *const points = (const char * const)points_;
    +
    +    yflag0 = (int *)malloc(n * sizeof(int));
     
         path.rewind(0);
     
    -    inside_flag = 0;
    +    for (i = 0; i < n; ++i) {
    +        inside_flag[i] = 0;
    +    }
     
         unsigned code = 0;
         do
    @@ -138,23 +153,25 @@
                 code = path.vertex(&x, &y);
             }
     
    -        sx = vtx0 = x;
    -        sy = vty0 = y;
    +        sx = vtx0 = vtx1 = x;
    +        sy = vty0 = vty1 = y;
    +
    +        for (i = 0; i < n; ++i) {
    +            ty = *(double *)(points + s0 * i + s1);
     
    -        // get test bit for above/below X axis
    -        yflag0 = (vty0 >= ty);
    +            // get test bit for above/below X axis
    +            yflag0[i] = (vty0 >= ty);
     
    -        vtx1 = x;
    -        vty1 = y;
    +            inside_flag[i] = 0;
    +        }
     
    -        inside_flag = 0;
             do
             {
                 code = path.vertex(&x, &y);
     
                 // The following cases denote the beginning on a new subpath
                 if (code == agg::path_cmd_stop ||
    -                    (code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly)
    +                (code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly)
                 {
                     x = sx;
                     y = sy;
    @@ -164,38 +181,42 @@
                     break;
                 }
     
    -            yflag1 = (vty1 >= ty);
    -            // Check if endpoints straddle (are on opposite sides) of
    -            // X axis (i.e. the Y's differ); if so, +X ray could
    -            // intersect this edge.  The old test also checked whether
    -            // the endpoints are both to the right or to the left of
    -            // the test point.  However, given the faster intersection
    -            // point computation used below, this test was found to be
    -            // a break-even proposition for most polygons and a loser
    -            // for triangles (where 50% or more of the edges which
    -            // survive this test will cross quadrants and so have to
    -            // have the X intersection computed anyway).  I credit
    -            // Joseph Samosky with inspiring me to try dropping the
    -            // "both left or both right" part of my code.
    -            if (yflag0 != yflag1)
    -            {
    -                // Check intersection of pgon segment with +X ray.
    -                // Note if >= point's X; if so, the ray hits it.  The
    -                // division operation is avoided for the ">=" test by
    -                // checking the sign of the first vertex wrto the test
    -                // point; idea inspired by Joseph Samosky's and Mark
    -                // Haigh-Hutchinson's different polygon inclusion
    -                // tests.
    -                if (((vty1 - ty) * (vtx0 - vtx1) >=
    -                        (vtx1 - tx) * (vty0 - vty1)) == yflag1)
    -                {
    -                    inside_flag ^= 1;
    +            for (i = 0; i < n; ++i) {
    +                tx = *(double *)(points + s0 * i);
    +                ty = *(double *)(points + s0 * i + s1);
    +
    +                yflag1 = (vty1 >= ty);
    +                // Check if endpoints straddle (are on opposite sides) of
    +                // X axis (i.e. the Y's differ); if so, +X ray could
    +                // intersect this edge.  The old test also checked whether
    +                // the endpoints are both to the right or to the left of
    +                // the test point.  However, given the faster intersection
    +                // point computation used below, this test was found to be
    +                // a break-even proposition for most polygons and a loser
    +                // for triangles (where 50% or more of the edges which
    +                // survive this test will cross quadrants and so have to
    +                // have the X intersection computed anyway).  I credit
    +                // Joseph Samosky with inspiring me to try dropping the
    +                // "both left or both right" part of my code.
    +                if (yflag0[i] != yflag1) {
    +                    // Check intersection of pgon segment with +X ray.
    +                    // Note if >= point's X; if so, the ray hits it.  The
    +                    // division operation is avoided for the ">=" test by
    +                    // checking the sign of the first vertex wrto the test
    +                    // point; idea inspired by Joseph Samosky's and Mark
    +                    // Haigh-Hutchinson's different polygon inclusion
    +                    // tests.
    +                    if (((vty1 - ty) * (vtx0 - vtx1) >=
    +                         (vtx1 - tx) * (vty0 - vty1)) == yflag1) {
    +                        inside_flag[i] ^= 1;
    +                    }
                     }
    +
    +                // Move to the next pair of vertices, retaining info as
    +                // possible.
    +                yflag0[i] = yflag1;
                 }
     
    -            // Move to the next pair of vertices, retaining info as
    -            // possible.
    -            yflag0 = yflag1;
                 vtx0 = vtx1;
                 vty0 = vty1;
     
    @@ -205,38 +226,55 @@
             while (code != agg::path_cmd_stop &&
                    (code & agg::path_cmd_end_poly) != agg::path_cmd_end_poly);
     
    -        yflag1 = (vty1 >= ty);
    -        if (yflag0 != yflag1)
    -        {
    -            if (((vty1 - ty) * (vtx0 - vtx1) >=
    -                    (vtx1 - tx) * (vty0 - vty1)) == yflag1)
    -            {
    -                inside_flag ^= 1;
    +        all_done = 1;
    +        for (i = 0; i < n; ++i) {
    +            tx = *(double *)(points + s0 * i);
    +            ty = *(double *)(points + s0 * i + s1);
    +
    +            yflag1 = (vty1 >= ty);
    +            if (yflag0[i] != yflag1) {
    +                if (((vty1 - ty) * (vtx0 - vtx1) >=
    +                     (vtx1 - tx) * (vty0 - vty1)) == yflag1) {
    +                    inside_flag[i] ^= 1;
    +                }
    +            }
    +
    +            if (inside_flag[i] == 0) {
    +                all_done = 0;
                 }
             }
     
    -        if (inside_flag != 0)
    -        {
    -            return true;
    +        if (all_done) {
    +            goto exit;
             }
         }
         while (code != agg::path_cmd_stop);
     
    -    return (inside_flag != 0);
    + exit:
    +
    +    free(yflag0);
     }
     
    -inline bool
    -point_in_path(double x, double y, double r, PathIterator& path,
    -              const agg::trans_affine& trans)
    +inline void
    +points_in_path(const void* const points, const size_t s0,
    +               const size_t s1, const size_t n,
    +               const double r, PathIterator& path,
    +               const agg::trans_affine& trans,
    +               npy_bool* result)
     {
         typedef agg::conv_transform transformed_path_t;
         typedef PathNanRemover no_nans_t;
         typedef agg::conv_curve curve_t;
         typedef agg::conv_contour contour_t;
     
    +    size_t i;
    +    for (i = 0; i < n; ++i) {
    +        result[i] = 0;
    +    }
    +
         if (path.total_vertices() < 3)
         {
    -        return false;
    +        return;
         }
     
         transformed_path_t trans_path(path, trans);
    @@ -244,12 +282,29 @@
         curve_t curved_path(no_nans_path);
         contour_t contoured_path(curved_path);
         contoured_path.width(fabs(r));
    -    return point_in_path_impl(x, y, contoured_path);
    +    point_in_path_impl(points, s0, s1, n, contoured_path, result);
     }
     
     inline bool
    -point_on_path(double x, double y, double r, PathIterator& path,
    -              const agg::trans_affine& trans)
    +point_in_path(const double x, const double y, const double r,
    +              PathIterator& path, const agg::trans_affine& trans)
    +{
    +    double points[2];
    +    npy_bool result;
    +
    +    points[0] = x;
    +    points[1] = y;
    +
    +    points_in_path(points, 0, sizeof(double), 1, r, path, trans, &result);
    +    return result;
    +}
    +
    +inline void
    +points_on_path(const void* const points, const size_t s0,
    +               const size_t s1, const size_t n,
    +               const double r, PathIterator& path,
    +               const agg::trans_affine& trans,
    +               npy_bool* result)
     {
         typedef agg::conv_transform transformed_path_t;
         typedef PathNanRemover no_nans_t;
    @@ -261,32 +316,74 @@
         curve_t curved_path(nan_removed_path);
         stroke_t stroked_path(curved_path);
         stroked_path.width(r * 2.0);
    -    return point_in_path_impl(x, y, stroked_path);
    +    point_in_path_impl(points, s0, s1, n, stroked_path, result);
    +}
    +
    +inline bool
    +point_on_path(const double x, const double y, const double r,
    +              PathIterator& path, const agg::trans_affine& trans)
    +{
    +    double points[2];
    +    npy_bool result;
    +
    +    points[0] = x;
    +    points[1] = y;
    +
    +    points_on_path(points, 0, sizeof(double), 1, r, path, trans, &result);
    +    return result;
     }
     
     Py::Object
     _path_module::point_in_path(const Py::Tuple& args)
     {
    -    args.verify_length(5);
    -
         double x = Py::Float(args[0]);
         double y = Py::Float(args[1]);
         double r = Py::Float(args[2]);
         PathIterator path(args[3]);
         agg::trans_affine trans = py_to_agg_transformation_matrix(args[4].ptr(), false);
     
    -    if (::point_in_path(x, y, r, path, trans))
    -    {
    +    if (::point_in_path(x, y, r, path, trans)) {
             return Py::Int(1);
         }
         return Py::Int(0);
     }
     
     Py::Object
    -_path_module::point_on_path(const Py::Tuple& args)
    +_path_module::points_in_path(const Py::Tuple& args)
     {
    -    args.verify_length(5);
    +    args.verify_length(4);
    +
    +    npy_intp n;
    +    PyArrayObject* points_array;
    +    points_array = (PyArrayObject*)PyArray_FromObject(args[0].ptr(), PyArray_DOUBLE, 2, 2);
    +    if (points_array == NULL || PyArray_DIM(points_array, 1) != 2) {
    +        throw Py::TypeError(
    +            "Argument 0 to points_in_path must be an Nx2 numpy array");
    +
    +    }
    +    double r = Py::Float(args[1]);
    +    PathIterator path(args[2]);
    +    agg::trans_affine trans = py_to_agg_transformation_matrix(args[3].ptr(), false);
    +
    +    n = PyArray_DIM(points_array, 0);
    +    PyObject* result = PyArray_ZEROS(1, &n, PyArray_BOOL, 0);
    +    if (result == NULL) {
    +        throw Py::MemoryError("Could not allocate memory for result");
    +    }
    +
    +    ::points_in_path(PyArray_DATA(points_array),
    +                     PyArray_STRIDE(points_array, 0),
    +                     PyArray_STRIDE(points_array, 1),
    +                     n, r, path, trans,
    +                     (npy_bool *)PyArray_DATA(result));
    +    Py_DECREF(points_array);
    +
    +    return Py::Object(result, true);;
    +}
     
    +Py::Object
    +_path_module::point_on_path(const Py::Tuple& args)
    +{
         double x = Py::Float(args[0]);
         double y = Py::Float(args[1]);
         double r = Py::Float(args[2]);
    @@ -393,7 +490,7 @@
                 "Must pass Bbox object as arg 3 of update_path_extents");
         }
         Py::Object minpos_obj = args[3];
    -    bool ignore = bool(Py::Int(args[4]));
    +    bool ignore = Py::Boolean(args[4]);
     
         double xm, ym;
         PyArrayObject* input_minpos = NULL;
    @@ -613,7 +710,7 @@
         Py::SeqBase transforms_obj   = args[5];
         Py::SeqBase offsets_obj      = args[6];
         agg::trans_affine       offset_trans     = py_to_agg_transformation_matrix(args[7].ptr());
    -    bool                    filled           = Py::Int(args[8]);
    +    bool                    filled           = Py::Boolean(args[8]);
     
         PyArrayObject* offsets = (PyArrayObject*)PyArray_FromObject(
             offsets_obj.ptr(), PyArray_DOUBLE, 0, 2);
    @@ -942,7 +1039,7 @@
     
         PathIterator path(args[0]);
         Py::Object bbox_obj = args[1];
    -    bool inside = Py::Int(args[2]);
    +    bool inside = Py::Boolean(args[2]);
     
         double x0, y0, x1, y1;
         if (!py_convert_bbox(bbox_obj.ptr(), x0, y0, x1, y1))
    @@ -1499,7 +1596,7 @@
     
         Py::Object clip_obj = args[2];
         bool do_clip;
    -    agg::rect_base clip_rect;
    +    agg::rect_base clip_rect(0, 0, 0, 0);
         if (clip_obj.isNone() || !clip_obj.isTrue())
         {
             do_clip = false;
    @@ -1596,18 +1693,29 @@
             --wait;
         }
     
    +    #if PY3K
    +    PyObject* result = PyUnicode_FromStringAndSize(buffer, p - buffer);
    +    #else
         PyObject* result = PyString_FromStringAndSize(buffer, p - buffer);
    +    #endif
         free(buffer);
     
         return Py::Object(result, true);
     }
     
    -extern "C"
    -    DL_EXPORT(void)
    -    init_path(void)
    +PyMODINIT_FUNC
    +#if PY3K
    +PyInit__path(void)
    +#else
    +init_path(void)
    +#endif
     {
         static _path_module* _path = NULL;
         _path = new _path_module;
     
         import_array();
    +
    +    #if PY3K
    +    return _path->module().ptr();
    +    #endif
     }
    diff -Nru matplotlib-1.1.1/ttconv/pprdrv_tt2.cpp matplotlib-1.2.0/ttconv/pprdrv_tt2.cpp
    --- matplotlib-1.1.1/ttconv/pprdrv_tt2.cpp	2012-06-30 18:47:51.000000000 +0000
    +++ matplotlib-1.2.0/ttconv/pprdrv_tt2.cpp	2012-10-31 00:11:14.000000000 +0000
    @@ -58,9 +58,6 @@
         int num_pts, num_ctr;               /* number of points, number of coutours */
         FWord *xcoor, *ycoor;               /* arrays of x and y coordinates */
         BYTE *tt_flags;                     /* array of TrueType flags */
    -    double *area_ctr;
    -    char *check_ctr;
    -    int *ctrset;                /* in contour index followed by out contour index */
     
         int stack_depth;            /* A book-keeping variable for keeping track of the depth of the PS stack */
     
    @@ -70,10 +67,6 @@
         void stack(TTStreamWriter& stream, int new_elem);
         void stack_end(TTStreamWriter& stream);
         void PSConvert(TTStreamWriter& stream);
    -    int nextinctr(int co, int ci);
    -    int nextoutctr(int co);
    -    int nearout(int ci);
    -    double intest(int co, int ci);
         void PSCurveto(TTStreamWriter& stream,
                        FWord x0, FWord y0,
                        FWord x1, FWord y1,
    @@ -148,64 +141,17 @@
     } /* end of stack_end() */
     
     /*
    -** Find the area of a contour?
    -*/
    -double area(FWord *x, FWord *y, int n)
    -{
    -    int i;
    -    double sum;
    -
    -    sum=x[n-1]*y[0]-y[n-1]*x[0];
    -    for (i=0; i<=n-2; i++) sum += x[i]*y[i+1] - y[i]*x[i+1];
    -    return sum;
    -}
    -
    -/*
     ** We call this routine to emmit the PostScript code
     ** for the character we have loaded with load_char().
     */
     void GlyphToType3::PSConvert(TTStreamWriter& stream)
     {
    -    int i,j,k;
    -
    -    assert(area_ctr == NULL);
    -    area_ctr=(double*)calloc(num_ctr, sizeof(double));
    -    memset(area_ctr, 0, (num_ctr*sizeof(double)));
    -    assert(check_ctr == NULL);
    -    check_ctr=(char*)calloc(num_ctr, sizeof(char));
    -    memset(check_ctr, 0, (num_ctr*sizeof(char)));
    -    assert(ctrset == NULL);
    -    ctrset=(int*)calloc(num_ctr, 2*sizeof(int));
    -    memset(ctrset, 0, (num_ctr*2*sizeof(int)));
    -
    -    check_ctr[0]=1;
    -    area_ctr[0]=area(xcoor, ycoor, epts_ctr[0]+1);
    -
    -    for (i=1; i0)
    -        {
    -            ctrset[2*i]=i;
    -            ctrset[2*i+1]=nearout(i);
    -        }
    -        else
    -        {
    -            ctrset[2*i]=-1;
    -            ctrset[2*i+1]=-1;
    -        }
    -    }
    -
    -    /* Step thru the coutours. */
    -    /* I believe that a contour is a detatched */
    -    /* set of curves and lines. */
    -    for(i = j = k = 0;
    -        i != NOMOREOUTCTR && i < num_ctr;
    -        k = nextinctr(i, k), (k == NOMOREINCTR && (i = k = nextoutctr(i))))
    +    /* Step thru the contours.
    +     * j = index to xcoor, ycoor, tt_flags (point data)
    +     * k = index to epts_ctr (which points belong to the same contour) */
    +    for(j = k = 0; k < num_ctr; k++)
         {
             // A TrueType contour consists of on-path and off-path points.
             // Two consecutive on-path points are to be joined with a
    @@ -294,126 +240,8 @@
         /* Now, we can fill the whole thing. */
         stack(stream, 1);
         stream.puts( pdf_mode ? "f" : "_cl" );
    -
    -    /* Free our work arrays. */
    -    free(area_ctr);
    -    free(check_ctr);
    -    free(ctrset);
    -    area_ctr = NULL;
    -    check_ctr = NULL;
    -    ctrset = NULL;
     } /* end of PSConvert() */
     
    -int GlyphToType3::nextoutctr(int co)
    -{
    -    int j;
    -
    -    for (j=0; ja1)
    -            {
    -                k=co;
    -                a1=a;
    -            }
    -        }
    -    }
    -
    -    return k;
    -} /* end of nearout() */
    -
    -double GlyphToType3::intest(int co, int ci)
    -{
    -    int i, j, start, end;
    -    double r1, r2, a;
    -    FWord xi[3], yi[3];
    -
    -    j=start=(co==0)?0:(epts_ctr[co-1]+1);
    -    end=epts_ctr[co];
    -    i=(ci==0)?0:(epts_ctr[ci-1]+1);
    -    xi[0] = xcoor[i];
    -    yi[0] = ycoor[i];
    -    r1=sqr(xcoor[start] - xi[0]) + sqr(ycoor[start] - yi[0]);
    -
    -    for (i=start; i<=end; i++)
    -    {
    -        r2 = sqr(xcoor[i] - xi[0])+sqr(ycoor[i] - yi[0]);
    -        if (r2 < r1)
    -        {
    -            r1=r2;
    -            j=i;
    -        }
    -    }
    -    if (j==start)
    -    {
    -        xi[1]=xcoor[end];
    -        yi[1]=ycoor[end];
    -    }
    -    else
    -    {
    -        xi[1]=xcoor[j-1];
    -        yi[1]=ycoor[j-1];
    -    }
    -    if (j==end)
    -    {
    -        xi[2]=xcoor[start];
    -        yi[2]=ycoor[start];
    -    }
    -    else
    -    {
    -        xi[2]=xcoor[j+1];
    -        yi[2]=ycoor[j+1];
    -    }
    -    a=area(xi, yi, 3);
    -
    -    return a;
    -} /* end of intest() */
    -
     void GlyphToType3::PSMoveto(TTStreamWriter& stream, int x, int y)
     {
         stream.printf(pdf_mode ? "%d %d m\n" : "%d %d _m\n",
    @@ -466,11 +294,6 @@
         free(xcoor);               /* The X coordinates */
         free(ycoor);               /* The Y coordinates */
         free(epts_ctr);            /* The array of contour endpoints */
    -    // These last three should be NULL.  Just
    -    // free'ing them for safety.
    -    free(area_ctr);
    -    free(check_ctr);
    -    free(ctrset);
     }
     
     /*
    @@ -754,9 +577,6 @@
         xcoor = NULL;
         ycoor = NULL;
         epts_ctr = NULL;
    -    area_ctr = NULL;
    -    check_ctr = NULL;
    -    ctrset = NULL;
         stack_depth = 0;
         pdf_mode = font->target_type < 0;