You can subscribe to this list here.
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(115) |
Aug
(120) |
Sep
(137) |
Oct
(170) |
Nov
(461) |
Dec
(263) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2008 |
Jan
(120) |
Feb
(74) |
Mar
(35) |
Apr
(74) |
May
(245) |
Jun
(356) |
Jul
(240) |
Aug
(115) |
Sep
(78) |
Oct
(225) |
Nov
(98) |
Dec
(271) |
2009 |
Jan
(132) |
Feb
(84) |
Mar
(74) |
Apr
(56) |
May
(90) |
Jun
(79) |
Jul
(83) |
Aug
(296) |
Sep
(214) |
Oct
(76) |
Nov
(82) |
Dec
(66) |
2010 |
Jan
(46) |
Feb
(58) |
Mar
(51) |
Apr
(77) |
May
(58) |
Jun
(126) |
Jul
(128) |
Aug
(64) |
Sep
(50) |
Oct
(44) |
Nov
(48) |
Dec
(54) |
2011 |
Jan
(68) |
Feb
(52) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
|
|
1
(3) |
2
(2) |
3
(5) |
4
(1) |
5
|
6
|
7
(6) |
8
(3) |
9
(7) |
10
(6) |
11
(14) |
12
(6) |
13
(10) |
14
(6) |
15
|
16
|
17
(15) |
18
(6) |
19
(1) |
20
(4) |
21
(8) |
22
(9) |
23
(12) |
24
(35) |
25
(21) |
26
(14) |
27
(11) |
28
(9) |
29
(11) |
30
(6) |
31
(9) |
|
|
Revision: 5816 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5816&view=rev Author: jswhit Date: 2008年07月23日 01:15:52 +0000 (2008年7月23日) Log Message: ----------- add __version__ Modified Paths: -------------- trunk/toolkits/natgrid/lib/mpl_toolkits/natgrid/__init__.py Modified: trunk/toolkits/natgrid/lib/mpl_toolkits/natgrid/__init__.py =================================================================== --- trunk/toolkits/natgrid/lib/mpl_toolkits/natgrid/__init__.py 2008年07月23日 01:15:22 UTC (rev 5815) +++ trunk/toolkits/natgrid/lib/mpl_toolkits/natgrid/__init__.py 2008年07月23日 01:15:52 UTC (rev 5816) @@ -0,0 +1,4 @@ +__version__ = 0.1 +__docstring__ = """ +Python interface to NCAR natgrid library. If installed, used +by matplotlib griddata function.""" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5815 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5815&view=rev Author: jswhit Date: 2008年07月23日 01:15:22 +0000 (2008年7月23日) Log Message: ----------- implement some of JDH's suggestions for griddata. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/delaunay/__init__.py trunk/matplotlib/lib/matplotlib/mlab.py Modified: trunk/matplotlib/lib/matplotlib/delaunay/__init__.py =================================================================== --- trunk/matplotlib/lib/matplotlib/delaunay/__init__.py 2008年07月23日 00:24:55 UTC (rev 5814) +++ trunk/matplotlib/lib/matplotlib/delaunay/__init__.py 2008年07月23日 01:15:22 UTC (rev 5815) @@ -8,3 +8,4 @@ from matplotlib._delaunay import delaunay from triangulate import * from interpolate import * +__version__ = "0.1" Modified: trunk/matplotlib/lib/matplotlib/mlab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mlab.py 2008年07月23日 00:24:55 UTC (rev 5814) +++ trunk/matplotlib/lib/matplotlib/mlab.py 2008年07月23日 01:15:22 UTC (rev 5815) @@ -89,6 +89,7 @@ import numpy as np +from matplotlib import verbose import matplotlib.nxutils as nxutils import matplotlib.cbook as cbook @@ -2715,13 +2716,23 @@ that is not redistributable under a BSD-compatible license. When installed, this function will use the mpl_toolkits.natgrid algorithm, otherwise it will use the built-in matplotlib.delaunay package. + + The natgrid matplotlib toolkit can be checked out through SVN with the + following command: + + svn co https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/trunk/toolkits/natgrid natgrid """ try: - from mpl_toolkits.natgrid import _natgrid + from mpl_toolkits.natgrid import _natgrid, __version__ _use_natgrid = True except ImportError: import matplotlib.delaunay as delaunay + from matplotlib.delaunay import __version__ _use_natgrid = False + if _use_natgrid: + verbose.report('using natgrid version %s' % __version__) + else: + verbose.report('using delaunay version %s' % __version__) if xi.ndim != yi.ndim: raise TypeError("inputs xi and yi must have same number of dimensions (1 or 2)") if xi.ndim != 1 and xi.ndim != 2: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5814 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5814&view=rev Author: jswhit Date: 2008年07月23日 00:24:55 +0000 (2008年7月23日) Log Message: ----------- add griddata to pylab, add griddata docstrings to mlab and pylab module docstrings. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/mlab.py trunk/matplotlib/lib/matplotlib/pylab.py Modified: trunk/matplotlib/lib/matplotlib/mlab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mlab.py 2008年07月22日 19:47:04 UTC (rev 5813) +++ trunk/matplotlib/lib/matplotlib/mlab.py 2008年07月23日 00:24:55 UTC (rev 5814) @@ -14,6 +14,8 @@ * find - Return the indices where some condition is true; numpy.nonzero is similar but more general. + * griddata - interpolate irregularly distributed data to a + regular grid. * prctile - find the percentiles of a sequence @@ -90,12 +92,6 @@ import matplotlib.nxutils as nxutils import matplotlib.cbook as cbook -try: - from mpl_toolkits.natgrid import _natgrid - _use_natgrid = True -except ImportError: - import matplotlib.delaunay as delaunay - _use_natgrid = False # set is a new builtin function in 2.4; delete the following when # support for 2.3 is dropped. @@ -2720,6 +2716,12 @@ this function will use the mpl_toolkits.natgrid algorithm, otherwise it will use the built-in matplotlib.delaunay package. """ + try: + from mpl_toolkits.natgrid import _natgrid + _use_natgrid = True + except ImportError: + import matplotlib.delaunay as delaunay + _use_natgrid = False if xi.ndim != yi.ndim: raise TypeError("inputs xi and yi must have same number of dimensions (1 or 2)") if xi.ndim != 1 and xi.ndim != 2: Modified: trunk/matplotlib/lib/matplotlib/pylab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/pylab.py 2008年07月22日 19:47:04 UTC (rev 5813) +++ trunk/matplotlib/lib/matplotlib/pylab.py 2008年07月23日 00:24:55 UTC (rev 5814) @@ -184,6 +184,7 @@ _Other angle - the angle of a complex array + griddata - interpolate irregularly distributed data to a regular grid load - load ASCII data into array polyfit - fit x, y to an n-th order polynomial polyval - evaluate an n-th order polynomial @@ -219,7 +220,7 @@ from matplotlib.mlab import window_hanning, window_none,\ conv, detrend, detrend_mean, detrend_none, detrend_linear,\ - polyfit, polyval, entropy, normpdf,\ + polyfit, polyval, entropy, normpdf, griddata,\ levypdf, find, trapz, prepca, fix, rem, norm, orth, rank,\ sqrtm, prctile, center_matrix, rk4, exp_safe, amap,\ sum_flat, mean_flat, rms_flat, l1norm, l2norm, norm, frange,\ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5813 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5813&view=rev Author: astraw Date: 2008年07月22日 19:47:04 +0000 (2008年7月22日) Log Message: ----------- minor docstring fix Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/axes.py Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2008年07月22日 18:43:38 UTC (rev 5812) +++ trunk/matplotlib/lib/matplotlib/axes.py 2008年07月22日 19:47:04 UTC (rev 5813) @@ -4724,7 +4724,7 @@ arguments will be used only if *c* is an array of floats. *cmap*: [ None | Colormap ] - A :class:`matplotlib.cm.Colormap` instance. If *None*, + A :class:`matplotlib.colors.Colormap` instance. If *None*, defaults to rc ``image.cmap``. *cmap* is only used if *c* is an array of floats. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5812 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5812&view=rev Author: efiring Date: 2008年07月22日 18:43:38 +0000 (2008年7月22日) Log Message: ----------- Moved unmasked_index_ranges from lines.py to cbook.py Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/cbook.py Modified: trunk/matplotlib/lib/matplotlib/cbook.py =================================================================== --- trunk/matplotlib/lib/matplotlib/cbook.py 2008年07月22日 18:05:32 UTC (rev 5811) +++ trunk/matplotlib/lib/matplotlib/cbook.py 2008年07月22日 18:43:38 UTC (rev 5812) @@ -1244,7 +1244,57 @@ margs[i] = x.filled() return margs +def unmasked_index_ranges(mask, compressed = True): + ''' + Find index ranges where *mask* is *False*. + *mask* will be flattened if it is not already 1-D. + + Returns Nx2 :class:`numpy.ndarray` with each row the start and stop + indices for slices of the compressed :class:`numpy.ndarray` + corresponding to each of *N* uninterrupted runs of unmasked + values. If optional argument *compressed* is *False*, it returns + the start and stop indices into the original :class:`numpy.ndarray`, + not the compressed :class:`numpy.ndarray`. Returns *None* if there + are no unmasked values. + + Example:: + + y = ma.array(np.arange(5), mask = [0,0,1,0,0]) + ii = unmasked_index_ranges(ma.getmaskarray(y)) + # returns array [[0,2,] [2,4,]] + + y.compressed()[ii[1,0]:ii[1,1]] + # returns array [3,4,] + + ii = unmasked_index_ranges(ma.getmaskarray(y), compressed=False) + # returns array [[0, 2], [3, 5]] + + y.filled()[ii[1,0]:ii[1,1]] + # returns array [3,4,] + + Prior to the transforms refactoring, this was used to support + masked arrays in Line2D. + + ''' + mask = mask.reshape(mask.size) + m = np.concatenate(((1,), mask, (1,))) + indices = np.arange(len(mask) + 1) + mdif = m[1:] - m[:-1] + i0 = np.compress(mdif == -1, indices) + i1 = np.compress(mdif == 1, indices) + assert len(i0) == len(i1) + if len(i1) == 0: + return None # Maybe this should be np.zeros((0,2), dtype=int) + if not compressed: + return np.concatenate((i0[:, np.newaxis], i1[:, np.newaxis]), axis=1) + seglengths = i1 - i0 + breakpoints = np.cumsum(seglengths) + ic0 = np.concatenate(((0,), breakpoints[:-1])) + ic1 = breakpoints + return np.concatenate((ic0[:, np.newaxis], ic1[:, np.newaxis]), axis=1) + + # a dict to cross-map linestyle arguments _linestyles = [('-', 'solid'), ('--', 'dashed'), This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5811 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5811&view=rev Author: efiring Date: 2008年07月22日 18:05:32 +0000 (2008年7月22日) Log Message: ----------- Add deprecation warning to cbook.popd Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/cbook.py Modified: trunk/matplotlib/lib/matplotlib/cbook.py =================================================================== --- trunk/matplotlib/lib/matplotlib/cbook.py 2008年07月22日 18:00:49 UTC (rev 5810) +++ trunk/matplotlib/lib/matplotlib/cbook.py 2008年07月22日 18:05:32 UTC (rev 5811) @@ -743,6 +743,8 @@ val = popd(d, key, default) """ + warnings.warn("Use native python dict.pop method", DeprecationWarning) + # warning added 2008年07月22日 if len(args)==1: key = args[0] val = d[key] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5810 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5810&view=rev Author: efiring Date: 2008年07月22日 18:00:49 +0000 (2008年7月22日) Log Message: ----------- Cleanup in delete_masked_points Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/cbook.py Modified: trunk/matplotlib/lib/matplotlib/cbook.py =================================================================== --- trunk/matplotlib/lib/matplotlib/cbook.py 2008年07月22日 11:23:49 UTC (rev 5809) +++ trunk/matplotlib/lib/matplotlib/cbook.py 2008年07月22日 18:00:49 UTC (rev 5810) @@ -1187,7 +1187,7 @@ Masks are obtained from all arguments of the correct length in categories 1, 2, and 4; a point is bad if masked in a masked array or if it is a nan or inf. No attempt is made to - extract a mask from categories 2, 3, and 4 if *np.isfinite()* + extract a mask from categories 2, 3, and 4 if :meth:`np.isfinite` does not yield a Boolean array. All input arguments that are not passed unchanged are returned @@ -1236,11 +1236,7 @@ if len(igood) < nrecs: for i, x in enumerate(margs): if seqlist[i]: - if (hasattr(x, 'get_compressed_copy')): - compressed_x = x.get_compressed_copy(~mask) - else: - compressed_x = x.take(igood, axis=0) - margs[i] = compressed_x + margs[i] = x.take(igood, axis=0) for i, x in enumerate(margs): if seqlist[i] and ma.isMA(x): margs[i] = x.filled() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5809 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5809&view=rev Author: jswhit Date: 2008年07月22日 11:23:49 +0000 (2008年7月22日) Log Message: ----------- update docstring for griddata to reflect the fact that mpl_toolkits.natgrid will be used if installed. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/mlab.py Modified: trunk/matplotlib/lib/matplotlib/mlab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mlab.py 2008年07月22日 11:12:50 UTC (rev 5808) +++ trunk/matplotlib/lib/matplotlib/mlab.py 2008年07月22日 11:23:49 UTC (rev 5809) @@ -2710,6 +2710,15 @@ hull defined by input data (no extrapolation is done). Uses natural neighbor interpolation based on Delaunay triangulation. + By default, this algorithm is provided by the matplotlib.delaunay + package, written by Robert Kern. The triangulation algorithm in this + package is known to fail on some nearly pathological cases. For + this reason, a separate toolkit (mpl_tookits.natgrid) has been created + that provides a more robust algorithm fof triangulation and interpolation. + This toolkit is based on the NCAR natgrid library, which contains code + that is not redistributable under a BSD-compatible license. When installed, + this function will use the mpl_toolkits.natgrid algorithm, otherwise it + will use the built-in matplotlib.delaunay package. """ if xi.ndim != yi.ndim: raise TypeError("inputs xi and yi must have same number of dimensions (1 or 2)") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5808 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5808&view=rev Author: jswhit Date: 2008年07月22日 11:12:50 +0000 (2008年7月22日) Log Message: ----------- initial checkin of natgrid toolkit. Added Paths: ----------- trunk/toolkits/natgrid/ trunk/toolkits/natgrid/Copyright.txt trunk/toolkits/natgrid/README trunk/toolkits/natgrid/lib/ trunk/toolkits/natgrid/lib/mpl_toolkits/ trunk/toolkits/natgrid/lib/mpl_toolkits/__init__.py trunk/toolkits/natgrid/lib/mpl_toolkits/natgrid/ trunk/toolkits/natgrid/lib/mpl_toolkits/natgrid/__init__.py trunk/toolkits/natgrid/setup.py trunk/toolkits/natgrid/setupegg.py trunk/toolkits/natgrid/src/ trunk/toolkits/natgrid/src/_natgrid.c trunk/toolkits/natgrid/src/_natgrid.pyx trunk/toolkits/natgrid/src/natgrid.c trunk/toolkits/natgrid/src/natgridd.c trunk/toolkits/natgrid/src/natgrids.c trunk/toolkits/natgrid/src/nnchead.h trunk/toolkits/natgrid/src/nncheadd.h trunk/toolkits/natgrid/src/nncheads.h trunk/toolkits/natgrid/src/nncrunch.c trunk/toolkits/natgrid/src/nncrunchd.c trunk/toolkits/natgrid/src/nncrunchs.c trunk/toolkits/natgrid/src/nnerror.c trunk/toolkits/natgrid/src/nnexver.h trunk/toolkits/natgrid/src/nnghead.h trunk/toolkits/natgrid/src/nngheadd.h trunk/toolkits/natgrid/src/nngheads.h trunk/toolkits/natgrid/src/nnmhead.h trunk/toolkits/natgrid/src/nntpvrs.h trunk/toolkits/natgrid/src/nntypes.h trunk/toolkits/natgrid/src/nnuhead.h trunk/toolkits/natgrid/src/nnuheadd.h trunk/toolkits/natgrid/src/nnuheads.h trunk/toolkits/natgrid/src/nnuser.c trunk/toolkits/natgrid/src/nnuserd.c trunk/toolkits/natgrid/src/nnusers.c trunk/toolkits/natgrid/test.py Added: trunk/toolkits/natgrid/Copyright.txt =================================================================== --- trunk/toolkits/natgrid/Copyright.txt (rev 0) +++ trunk/toolkits/natgrid/Copyright.txt 2008年07月22日 11:12:50 UTC (rev 5808) @@ -0,0 +1,37 @@ +NCL - UNIX Version 5.0.0 +Copyright (C) 2007 +University Corporation for Atmospheric Research + +NCL Source Code License + +Copyright (c) 2007 University Corporation for Atmospheric Research +(UCAR). All rights reserved. Developed by NCAR's Computational and +Information Systems Laboratory, UCAR, www.cisl.ucar.edu, with the +following contributions: + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +Neither the names of NCAR's Computational and Information Systems +Laboratory, the University Corporation for Atmospheric Research, nor +the names of its contributors may be used to endorse or promote +products derived from this Software without specific prior written +permission. + +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 below in the +documentation and/or other materials provided with the distribution. + +THIS 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 CONTRIBUTORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL 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 WITH THE +SOFTWARE. Added: trunk/toolkits/natgrid/README =================================================================== --- trunk/toolkits/natgrid/README (rev 0) +++ trunk/toolkits/natgrid/README 2008年07月22日 11:12:50 UTC (rev 5808) @@ -0,0 +1,35 @@ +Python interface to NCAR natgrid library +(http://www.ncarg.ucar.edu//ngmath/natgrid/nnhome.html). + +When installed, will be used by the matplotlib.mlab griddata function. + +Not otherwise intended for public consumption. + +*LICENSE* + +NCAR natgrid source code licensed under the terms given in Copyright.txt, +except for code in the file src/nncrunch.c, which is based on code written and +copyrighted (C) by Dave Watson. Dr. Watson retains the copyright to his +original code. + +The Python interface (src/_natgrid.pyx and src/_natgrid.c) are made available +under the following license: + +copyright (c) 2007 by Jeffrey Whitaker. + +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 notices appear in all copies and that +both the copyright notices and this permission notice appear in +supporting documentation. +THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO +EVENT SHALL 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. + +*Contact* + +Jeff Whitaker <jeffrey.s.whitaker@noaa,gov> Added: trunk/toolkits/natgrid/lib/mpl_toolkits/__init__.py =================================================================== --- trunk/toolkits/natgrid/lib/mpl_toolkits/__init__.py (rev 0) +++ trunk/toolkits/natgrid/lib/mpl_toolkits/__init__.py 2008年07月22日 11:12:50 UTC (rev 5808) @@ -0,0 +1,4 @@ +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + pass # must not have setuptools Added: trunk/toolkits/natgrid/setup.py =================================================================== --- trunk/toolkits/natgrid/setup.py (rev 0) +++ trunk/toolkits/natgrid/setup.py 2008年07月22日 11:12:50 UTC (rev 5808) @@ -0,0 +1,27 @@ +import glob +from distutils.core import setup, Extension +deps = glob.glob('src/*.c') +packages = ['mpl_toolkits','mpl_toolkits.natgrid'] +package_dirs = {'':'lib'} +extensions = [Extension("mpl_toolkits.natgrid._natgrid",deps,include_dirs = ['src'],)] +setup( + name = "natgrid", + version = "0.1", + description = "Python interface to NCAR natgrid library", + url = "http://matplotlib.sourceforge.net/toolkits.html", + download_url = "http://sourceforge.net/projects/matplotlib", + author = "Jeff Whitaker", + author_email = "jef...@no...", + platforms = ["any"], + license = "Restricted", + keywords = ["python","plotting","plots","graphs","charts","GIS","mapping","map projections","maps"], + classifiers = ["Development Status :: 4 - Beta", + "Intended Audience :: Science/Research", + "License :: OSI Approved", + "Topic :: Scientific/Engineering :: Visualization", + "Topic :: Software Development :: Libraries :: Python Modules", + "Operating System :: OS Independent"], + packages = packages, + package_dir = package_dirs, + ext_modules = extensions, + ) Added: trunk/toolkits/natgrid/setupegg.py =================================================================== --- trunk/toolkits/natgrid/setupegg.py (rev 0) +++ trunk/toolkits/natgrid/setupegg.py 2008年07月22日 11:12:50 UTC (rev 5808) @@ -0,0 +1,8 @@ +""" +Poor man's setuptools script... +""" + +from setuptools import setup +execfile('setup.py', + {'additional_params' : + {'namespace_packages' : ['mpl_toolkits']}}) Added: trunk/toolkits/natgrid/src/_natgrid.c =================================================================== --- trunk/toolkits/natgrid/src/_natgrid.c (rev 0) +++ trunk/toolkits/natgrid/src/_natgrid.c 2008年07月22日 11:12:50 UTC (rev 5808) @@ -0,0 +1,1112 @@ +/* Generated by Cython 0.9.6.12 on Sun Jul 20 11:01:12 2008 */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#include "structmember.h" +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#if PY_VERSION_HEX < 0x02050000 + typedef int Py_ssize_t; + #define PY_SSIZE_T_MAX INT_MAX + #define PY_SSIZE_T_MIN INT_MIN + #define PyInt_FromSsize_t(z) PyInt_FromLong(z) + #define PyInt_AsSsize_t(o) PyInt_AsLong(o) + #define PyNumber_Index(o) PyNumber_Int(o) + #define PyIndex_Check(o) PyNumber_Check(o) +#endif +#if PY_VERSION_HEX < 0x02040000 + #define METH_COEXIST 0 +#endif +#ifndef WIN32 + #define __stdcall + #define __cdecl +#endif +#ifdef __cplusplus +#define __PYX_EXTERN_C extern "C" +#else +#define __PYX_EXTERN_C extern +#endif +#include <math.h> + + +#ifdef __GNUC__ +#define INLINE __inline__ +#elif _WIN32 +#define INLINE __inline +#else +#define INLINE +#endif + +typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/ +typedef struct {PyObject **p; char *s; long n; int is_unicode;} __Pyx_StringTabEntry; /*proto*/ + + + +static int __pyx_skip_dispatch = 0; + + +/* Type Conversion Predeclarations */ + +#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False)) +static INLINE int __Pyx_PyObject_IsTrue(PyObject* x); +static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x); +static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x); +static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b); + +#define __pyx_PyInt_AsLong(x) (PyInt_CheckExact(x) ? PyInt_AS_LONG(x) : PyInt_AsLong(x)) +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) + +static INLINE unsigned char __pyx_PyInt_unsigned_char(PyObject* x); +static INLINE unsigned short __pyx_PyInt_unsigned_short(PyObject* x); +static INLINE char __pyx_PyInt_char(PyObject* x); +static INLINE short __pyx_PyInt_short(PyObject* x); +static INLINE int __pyx_PyInt_int(PyObject* x); +static INLINE long __pyx_PyInt_long(PyObject* x); +static INLINE signed char __pyx_PyInt_signed_char(PyObject* x); +static INLINE signed short __pyx_PyInt_signed_short(PyObject* x); +static INLINE signed int __pyx_PyInt_signed_int(PyObject* x); +static INLINE signed long __pyx_PyInt_signed_long(PyObject* x); +static INLINE long double __pyx_PyInt_long_double(PyObject* x); +#ifdef __GNUC__ +/* Test for GCC > 2.95 */ +#if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)) +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) +#else /* __GNUC__ > 2 ... */ +#define likely(x) (x) +#define unlikely(x) (x) +#endif /* __GNUC__ > 2 ... */ +#else /* __GNUC__ */ +#define likely(x) (x) +#define unlikely(x) (x) +#endif /* __GNUC__ */ + +static PyObject *__pyx_m; +static PyObject *__pyx_b; +static PyObject *__pyx_empty_tuple; +static int __pyx_lineno; +static char *__pyx_filename; +static char **__pyx_f; + +static char __pyx_mdoc[] = "\nPyrex wrapper for NCAR natgrid library for interpolation\nof irregularly spaced data to a grid.\n\ncopyright (c) 2007 by Jeffrey Whitaker.\n\nPermission to use, copy, modify, and distribute this software and its\ndocumentation for any purpose and without fee is hereby granted,\nprovided that the above copyright notices appear in all copies and that\nboth the copyright notices and this permission notice appear in\nsupporting documentation.\nTHE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,\nINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO\nEVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR\nCONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF\nUSE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n"; + +static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/ + +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/ + +static int __Pyx_InternStrings(__Pyx_InternTabEntry *t); /*proto*/ + +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/ + +static void __Pyx_AddTraceback(char *funcname); /*proto*/ + +/* Declarations from _natgrid */ + +__PYX_EXTERN_C DL_EXPORT(void) c_nnseti(char *, int); /*proto*/ +__PYX_EXTERN_C DL_EXPORT(double) *c_natgridd(int, double *, double *, double *, int, int, double *, double *, int *); /*proto*/ +__PYX_EXTERN_C DL_EXPORT(void) c_nnsetr(char *, float); /*proto*/ + + +/* Implementation of _natgrid */ + +/* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":32 + * char *PyString_AsString(object) + * + * def seti(name, value): # <<<<<<<<<<<<<< + * cdef char *pnam + * cdef int ival + */ + +static PyObject *__pyx_pf_8_natgrid_seti(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyObject *__pyx_pf_8_natgrid_seti(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_name = 0; + PyObject *__pyx_v_value = 0; + char *__pyx_v_pnam; + int __pyx_v_ival; + PyObject *__pyx_r; + char *__pyx_1; + int __pyx_2; + static char *__pyx_argnames[] = {"name","value",0}; + if (likely(!__pyx_kwds) && likely(PyTuple_GET_SIZE(__pyx_args) == 2)) { + __pyx_v_name = PyTuple_GET_ITEM(__pyx_args, 0); + __pyx_v_value = PyTuple_GET_ITEM(__pyx_args, 1); + } + else { + if (unlikely(!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "OO", __pyx_argnames, &__pyx_v_name, &__pyx_v_value))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; goto __pyx_L2;} + } + goto __pyx_L3; + __pyx_L2:; + return NULL; + __pyx_L3:; + Py_INCREF(__pyx_v_name); + Py_INCREF(__pyx_v_value); + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":35 + * cdef char *pnam + * cdef int ival + * pnam = name; ival = value # <<<<<<<<<<<<<< + * c_nnseti(pnam, ival) + * + */ + __pyx_1 = PyString_AsString(__pyx_v_name); if (unlikely((!__pyx_1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; goto __pyx_L1;} + __pyx_v_pnam = __pyx_1; + __pyx_2 = __pyx_PyInt_int(__pyx_v_value); if (unlikely((__pyx_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; goto __pyx_L1;} + __pyx_v_ival = __pyx_2; + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":36 + * cdef int ival + * pnam = name; ival = value + * c_nnseti(pnam, ival) # <<<<<<<<<<<<<< + * + * def setr(name, value): + */ + c_nnseti(__pyx_v_pnam, __pyx_v_ival); + + __pyx_r = Py_None; Py_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1:; + __Pyx_AddTraceback("_natgrid.seti"); + __pyx_r = NULL; + __pyx_L0:; + Py_DECREF(__pyx_v_name); + Py_DECREF(__pyx_v_value); + return __pyx_r; +} + +/* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":38 + * c_nnseti(pnam, ival) + * + * def setr(name, value): # <<<<<<<<<<<<<< + * cdef char *pnam + * cdef float fval + */ + +static PyObject *__pyx_pf_8_natgrid_setr(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyObject *__pyx_pf_8_natgrid_setr(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_name = 0; + PyObject *__pyx_v_value = 0; + char *__pyx_v_pnam; + float __pyx_v_fval; + PyObject *__pyx_r; + char *__pyx_1; + float __pyx_2; + static char *__pyx_argnames[] = {"name","value",0}; + if (likely(!__pyx_kwds) && likely(PyTuple_GET_SIZE(__pyx_args) == 2)) { + __pyx_v_name = PyTuple_GET_ITEM(__pyx_args, 0); + __pyx_v_value = PyTuple_GET_ITEM(__pyx_args, 1); + } + else { + if (unlikely(!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "OO", __pyx_argnames, &__pyx_v_name, &__pyx_v_value))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; goto __pyx_L2;} + } + goto __pyx_L3; + __pyx_L2:; + return NULL; + __pyx_L3:; + Py_INCREF(__pyx_v_name); + Py_INCREF(__pyx_v_value); + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":41 + * cdef char *pnam + * cdef float fval + * pnam = name; fval = value # <<<<<<<<<<<<<< + * c_nnsetr(pnam, fval) + * + */ + __pyx_1 = PyString_AsString(__pyx_v_name); if (unlikely((!__pyx_1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; goto __pyx_L1;} + __pyx_v_pnam = __pyx_1; + __pyx_2 = __pyx_PyFloat_AsDouble(__pyx_v_value); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; goto __pyx_L1;} + __pyx_v_fval = __pyx_2; + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":42 + * cdef float fval + * pnam = name; fval = value + * c_nnsetr(pnam, fval) # <<<<<<<<<<<<<< + * + * def natgridd(x, y, z, xo, yo, zo): + */ + c_nnsetr(__pyx_v_pnam, __pyx_v_fval); + + __pyx_r = Py_None; Py_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1:; + __Pyx_AddTraceback("_natgrid.setr"); + __pyx_r = NULL; + __pyx_L0:; + Py_DECREF(__pyx_v_name); + Py_DECREF(__pyx_v_value); + return __pyx_r; +} + +/* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":44 + * c_nnsetr(pnam, fval) + * + * def natgridd(x, y, z, xo, yo, zo): # <<<<<<<<<<<<<< + * cdef int npnts, numxout, numyout, ier + * cdef Py_ssize_t buflenx, bufleny, buflenz, buflenxo, buflenyo, buflenzo + */ + +static PyObject *__pyx_n_RuntimeError; + +static PyObject *__pyx_k_1p; +static PyObject *__pyx_k_2p; +static PyObject *__pyx_k_3p; +static PyObject *__pyx_k_4p; +static PyObject *__pyx_k_5p; +static PyObject *__pyx_k_6p; +static PyObject *__pyx_k_7p; + +static PyObject *__pyx_builtin_RuntimeError; + +static char __pyx_k_1[] = "error getting buffer for x"; +static char __pyx_k_2[] = "error getting buffer for y"; +static char __pyx_k_3[] = "error getting buffer for z"; +static char __pyx_k_4[] = "error getting buffer for x"; +static char __pyx_k_5[] = "error getting buffer for y"; +static char __pyx_k_6[] = "error getting buffer for z"; +static char __pyx_k_7[] = "error in natgridd - ier ="; + +static PyObject *__pyx_pf_8_natgrid_natgridd(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyObject *__pyx_pf_8_natgrid_natgridd(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_x = 0; + PyObject *__pyx_v_y = 0; + PyObject *__pyx_v_z = 0; + PyObject *__pyx_v_xo = 0; + PyObject *__pyx_v_yo = 0; + PyObject *__pyx_v_zo = 0; + int __pyx_v_npnts; + int __pyx_v_numxout; + int __pyx_v_numyout; + int __pyx_v_ier; + Py_ssize_t __pyx_v_buflenx; + Py_ssize_t __pyx_v_bufleny; + Py_ssize_t __pyx_v_buflenz; + Py_ssize_t __pyx_v_buflenxo; + Py_ssize_t __pyx_v_buflenyo; + Py_ssize_t __pyx_v_buflenzo; + void *__pyx_v_xp; + void *__pyx_v_yp; + void *__pyx_v_zp; + void *__pyx_v_xop; + void *__pyx_v_yop; + void *__pyx_v_zop; + double *__pyx_v_xd; + double *__pyx_v_yd; + double *__pyx_v_zd; + double *__pyx_v_xod; + double *__pyx_v_yod; + double *__pyx_v_zod; + double *__pyx_v_out; + PyObject *__pyx_v_i; + PyObject *__pyx_r; + Py_ssize_t __pyx_1 = 0; + int __pyx_2; + PyObject *__pyx_3 = 0; + PyObject *__pyx_4 = 0; + long __pyx_5; + Py_ssize_t __pyx_6 = 0; + Py_ssize_t __pyx_7 = 0; + static char *__pyx_argnames[] = {"x","y","z","xo","yo","zo",0}; + if (likely(!__pyx_kwds) && likely(PyTuple_GET_SIZE(__pyx_args) == 6)) { + __pyx_v_x = PyTuple_GET_ITEM(__pyx_args, 0); + __pyx_v_y = PyTuple_GET_ITEM(__pyx_args, 1); + __pyx_v_z = PyTuple_GET_ITEM(__pyx_args, 2); + __pyx_v_xo = PyTuple_GET_ITEM(__pyx_args, 3); + __pyx_v_yo = PyTuple_GET_ITEM(__pyx_args, 4); + __pyx_v_zo = PyTuple_GET_ITEM(__pyx_args, 5); + } + else { + if (unlikely(!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "OOOOOO", __pyx_argnames, &__pyx_v_x, &__pyx_v_y, &__pyx_v_z, &__pyx_v_xo, &__pyx_v_yo, &__pyx_v_zo))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; goto __pyx_L2;} + } + goto __pyx_L3; + __pyx_L2:; + return NULL; + __pyx_L3:; + Py_INCREF(__pyx_v_x); + Py_INCREF(__pyx_v_y); + Py_INCREF(__pyx_v_z); + Py_INCREF(__pyx_v_xo); + Py_INCREF(__pyx_v_yo); + Py_INCREF(__pyx_v_zo); + __pyx_v_i = Py_None; Py_INCREF(Py_None); + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":49 + * cdef void *xp, *yp, *zp, *xop, *yop, *zop + * cdef double *xd, *yd, *zd, *xod, *yod, *zod, *out + * npnts = len(x) # <<<<<<<<<<<<<< + * numxout = len(xo) + * numyout = len(yo) + */ + __pyx_1 = PyObject_Length(__pyx_v_x); if (unlikely(__pyx_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; goto __pyx_L1;} + __pyx_v_npnts = __pyx_1; + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":50 + * cdef double *xd, *yd, *zd, *xod, *yod, *zod, *out + * npnts = len(x) + * numxout = len(xo) # <<<<<<<<<<<<<< + * numyout = len(yo) + * if PyObject_AsWriteBuffer(x, &xp, &buflenx) <> 0: + */ + __pyx_1 = PyObject_Length(__pyx_v_xo); if (unlikely(__pyx_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; goto __pyx_L1;} + __pyx_v_numxout = __pyx_1; + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":51 + * npnts = len(x) + * numxout = len(xo) + * numyout = len(yo) # <<<<<<<<<<<<<< + * if PyObject_AsWriteBuffer(x, &xp, &buflenx) <> 0: + * raise RuntimeError('error getting buffer for x') + */ + __pyx_1 = PyObject_Length(__pyx_v_yo); if (unlikely(__pyx_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; goto __pyx_L1;} + __pyx_v_numyout = __pyx_1; + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":52 + * numxout = len(xo) + * numyout = len(yo) + * if PyObject_AsWriteBuffer(x, &xp, &buflenx) <> 0: # <<<<<<<<<<<<<< + * raise RuntimeError('error getting buffer for x') + * if PyObject_AsWriteBuffer(y, &yp, &bufleny) <> 0: + */ + __pyx_2 = (PyObject_AsWriteBuffer(__pyx_v_x, (&__pyx_v_xp), (&__pyx_v_buflenx)) != 0); + if (__pyx_2) { + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":53 + * numyout = len(yo) + * if PyObject_AsWriteBuffer(x, &xp, &buflenx) <> 0: + * raise RuntimeError('error getting buffer for x') # <<<<<<<<<<<<<< + * if PyObject_AsWriteBuffer(y, &yp, &bufleny) <> 0: + * raise RuntimeError('error getting buffer for y') + */ + __pyx_3 = PyTuple_New(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; goto __pyx_L1;} + Py_INCREF(__pyx_k_1p); + PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k_1p); + __pyx_4 = PyObject_Call(__pyx_builtin_RuntimeError, __pyx_3, NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; goto __pyx_L1;} + Py_DECREF(__pyx_3); __pyx_3 = 0; + __Pyx_Raise(__pyx_4, 0, 0); + Py_DECREF(__pyx_4); __pyx_4 = 0; + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; goto __pyx_L1;} + goto __pyx_L4; + } + __pyx_L4:; + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":54 + * if PyObject_AsWriteBuffer(x, &xp, &buflenx) <> 0: + * raise RuntimeError('error getting buffer for x') + * if PyObject_AsWriteBuffer(y, &yp, &bufleny) <> 0: # <<<<<<<<<<<<<< + * raise RuntimeError('error getting buffer for y') + * if PyObject_AsWriteBuffer(z, &zp, &buflenz) <> 0: + */ + __pyx_2 = (PyObject_AsWriteBuffer(__pyx_v_y, (&__pyx_v_yp), (&__pyx_v_bufleny)) != 0); + if (__pyx_2) { + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":55 + * raise RuntimeError('error getting buffer for x') + * if PyObject_AsWriteBuffer(y, &yp, &bufleny) <> 0: + * raise RuntimeError('error getting buffer for y') # <<<<<<<<<<<<<< + * if PyObject_AsWriteBuffer(z, &zp, &buflenz) <> 0: + * raise RuntimeError('error getting buffer for z') + */ + __pyx_3 = PyTuple_New(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; goto __pyx_L1;} + Py_INCREF(__pyx_k_2p); + PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k_2p); + __pyx_4 = PyObject_Call(__pyx_builtin_RuntimeError, __pyx_3, NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; goto __pyx_L1;} + Py_DECREF(__pyx_3); __pyx_3 = 0; + __Pyx_Raise(__pyx_4, 0, 0); + Py_DECREF(__pyx_4); __pyx_4 = 0; + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; goto __pyx_L1;} + goto __pyx_L5; + } + __pyx_L5:; + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":56 + * if PyObject_AsWriteBuffer(y, &yp, &bufleny) <> 0: + * raise RuntimeError('error getting buffer for y') + * if PyObject_AsWriteBuffer(z, &zp, &buflenz) <> 0: # <<<<<<<<<<<<<< + * raise RuntimeError('error getting buffer for z') + * xd = <double *>xp + */ + __pyx_2 = (PyObject_AsWriteBuffer(__pyx_v_z, (&__pyx_v_zp), (&__pyx_v_buflenz)) != 0); + if (__pyx_2) { + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":57 + * raise RuntimeError('error getting buffer for y') + * if PyObject_AsWriteBuffer(z, &zp, &buflenz) <> 0: + * raise RuntimeError('error getting buffer for z') # <<<<<<<<<<<<<< + * xd = <double *>xp + * yd = <double *>yp + */ + __pyx_3 = PyTuple_New(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; goto __pyx_L1;} + Py_INCREF(__pyx_k_3p); + PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k_3p); + __pyx_4 = PyObject_Call(__pyx_builtin_RuntimeError, __pyx_3, NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; goto __pyx_L1;} + Py_DECREF(__pyx_3); __pyx_3 = 0; + __Pyx_Raise(__pyx_4, 0, 0); + Py_DECREF(__pyx_4); __pyx_4 = 0; + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; goto __pyx_L1;} + goto __pyx_L6; + } + __pyx_L6:; + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":58 + * if PyObject_AsWriteBuffer(z, &zp, &buflenz) <> 0: + * raise RuntimeError('error getting buffer for z') + * xd = <double *>xp # <<<<<<<<<<<<<< + * yd = <double *>yp + * zd = <double *>zp + */ + __pyx_v_xd = ((double *)__pyx_v_xp); + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":59 + * raise RuntimeError('error getting buffer for z') + * xd = <double *>xp + * yd = <double *>yp # <<<<<<<<<<<<<< + * zd = <double *>zp + * if PyObject_AsWriteBuffer(xo, &xop, &buflenxo) <> 0: + */ + __pyx_v_yd = ((double *)__pyx_v_yp); + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":60 + * xd = <double *>xp + * yd = <double *>yp + * zd = <double *>zp # <<<<<<<<<<<<<< + * if PyObject_AsWriteBuffer(xo, &xop, &buflenxo) <> 0: + * raise RuntimeError('error getting buffer for x') + */ + __pyx_v_zd = ((double *)__pyx_v_zp); + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":61 + * yd = <double *>yp + * zd = <double *>zp + * if PyObject_AsWriteBuffer(xo, &xop, &buflenxo) <> 0: # <<<<<<<<<<<<<< + * raise RuntimeError('error getting buffer for x') + * if PyObject_AsWriteBuffer(yo, &yop, &buflenyo) <> 0: + */ + __pyx_2 = (PyObject_AsWriteBuffer(__pyx_v_xo, (&__pyx_v_xop), (&__pyx_v_buflenxo)) != 0); + if (__pyx_2) { + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":62 + * zd = <double *>zp + * if PyObject_AsWriteBuffer(xo, &xop, &buflenxo) <> 0: + * raise RuntimeError('error getting buffer for x') # <<<<<<<<<<<<<< + * if PyObject_AsWriteBuffer(yo, &yop, &buflenyo) <> 0: + * raise RuntimeError('error getting buffer for y') + */ + __pyx_3 = PyTuple_New(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; goto __pyx_L1;} + Py_INCREF(__pyx_k_4p); + PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k_4p); + __pyx_4 = PyObject_Call(__pyx_builtin_RuntimeError, __pyx_3, NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; goto __pyx_L1;} + Py_DECREF(__pyx_3); __pyx_3 = 0; + __Pyx_Raise(__pyx_4, 0, 0); + Py_DECREF(__pyx_4); __pyx_4 = 0; + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; goto __pyx_L1;} + goto __pyx_L7; + } + __pyx_L7:; + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":63 + * if PyObject_AsWriteBuffer(xo, &xop, &buflenxo) <> 0: + * raise RuntimeError('error getting buffer for x') + * if PyObject_AsWriteBuffer(yo, &yop, &buflenyo) <> 0: # <<<<<<<<<<<<<< + * raise RuntimeError('error getting buffer for y') + * if PyObject_AsWriteBuffer(zo, &zop, &buflenzo) <> 0: + */ + __pyx_2 = (PyObject_AsWriteBuffer(__pyx_v_yo, (&__pyx_v_yop), (&__pyx_v_buflenyo)) != 0); + if (__pyx_2) { + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":64 + * raise RuntimeError('error getting buffer for x') + * if PyObject_AsWriteBuffer(yo, &yop, &buflenyo) <> 0: + * raise RuntimeError('error getting buffer for y') # <<<<<<<<<<<<<< + * if PyObject_AsWriteBuffer(zo, &zop, &buflenzo) <> 0: + * raise RuntimeError('error getting buffer for z') + */ + __pyx_3 = PyTuple_New(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; goto __pyx_L1;} + Py_INCREF(__pyx_k_5p); + PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k_5p); + __pyx_4 = PyObject_Call(__pyx_builtin_RuntimeError, __pyx_3, NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; goto __pyx_L1;} + Py_DECREF(__pyx_3); __pyx_3 = 0; + __Pyx_Raise(__pyx_4, 0, 0); + Py_DECREF(__pyx_4); __pyx_4 = 0; + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; goto __pyx_L1;} + goto __pyx_L8; + } + __pyx_L8:; + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":65 + * if PyObject_AsWriteBuffer(yo, &yop, &buflenyo) <> 0: + * raise RuntimeError('error getting buffer for y') + * if PyObject_AsWriteBuffer(zo, &zop, &buflenzo) <> 0: # <<<<<<<<<<<<<< + * raise RuntimeError('error getting buffer for z') + * xod = <double *>xop + */ + __pyx_2 = (PyObject_AsWriteBuffer(__pyx_v_zo, (&__pyx_v_zop), (&__pyx_v_buflenzo)) != 0); + if (__pyx_2) { + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":66 + * raise RuntimeError('error getting buffer for y') + * if PyObject_AsWriteBuffer(zo, &zop, &buflenzo) <> 0: + * raise RuntimeError('error getting buffer for z') # <<<<<<<<<<<<<< + * xod = <double *>xop + * yod = <double *>yop + */ + __pyx_3 = PyTuple_New(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; goto __pyx_L1;} + Py_INCREF(__pyx_k_6p); + PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k_6p); + __pyx_4 = PyObject_Call(__pyx_builtin_RuntimeError, __pyx_3, NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; goto __pyx_L1;} + Py_DECREF(__pyx_3); __pyx_3 = 0; + __Pyx_Raise(__pyx_4, 0, 0); + Py_DECREF(__pyx_4); __pyx_4 = 0; + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; goto __pyx_L1;} + goto __pyx_L9; + } + __pyx_L9:; + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":67 + * if PyObject_AsWriteBuffer(zo, &zop, &buflenzo) <> 0: + * raise RuntimeError('error getting buffer for z') + * xod = <double *>xop # <<<<<<<<<<<<<< + * yod = <double *>yop + * zod = <double *>zop + */ + __pyx_v_xod = ((double *)__pyx_v_xop); + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":68 + * raise RuntimeError('error getting buffer for z') + * xod = <double *>xop + * yod = <double *>yop # <<<<<<<<<<<<<< + * zod = <double *>zop + * # output overwrites zo. + */ + __pyx_v_yod = ((double *)__pyx_v_yop); + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":69 + * xod = <double *>xop + * yod = <double *>yop + * zod = <double *>zop # <<<<<<<<<<<<<< + * # output overwrites zo. + * out = c_natgridd(npnts, yd, xd, zd, numyout, numxout, yod, xod, &ier) + */ + __pyx_v_zod = ((double *)__pyx_v_zop); + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":71 + * zod = <double *>zop + * # output overwrites zo. + * out = c_natgridd(npnts, yd, xd, zd, numyout, numxout, yod, xod, &ier) # <<<<<<<<<<<<<< + * for i from 0 <= i < buflenzo/8: + * zod[i] = out[i] + */ + __pyx_v_out = c_natgridd(__pyx_v_npnts, __pyx_v_yd, __pyx_v_xd, __pyx_v_zd, __pyx_v_numyout, __pyx_v_numxout, __pyx_v_yod, __pyx_v_xod, (&__pyx_v_ier)); + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":72 + * # output overwrites zo. + * out = c_natgridd(npnts, yd, xd, zd, numyout, numxout, yod, xod, &ier) + * for i from 0 <= i < buflenzo/8: # <<<<<<<<<<<<<< + * zod[i] = out[i] + * if ier != 0: + */ + __pyx_1 = (__pyx_v_buflenzo / 8); + for (__pyx_5 = 0; __pyx_5 < __pyx_1; __pyx_5++) { + __pyx_3 = PyInt_FromLong(__pyx_5); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; goto __pyx_L1;} + Py_DECREF(__pyx_v_i); + __pyx_v_i = __pyx_3; + __pyx_3 = 0; + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":73 + * out = c_natgridd(npnts, yd, xd, zd, numyout, numxout, yod, xod, &ier) + * for i from 0 <= i < buflenzo/8: + * zod[i] = out[i] # <<<<<<<<<<<<<< + * if ier != 0: + * raise RuntimeError('error in natgridd - ier ='%ier) + */ + __pyx_6 = __pyx_PyIndex_AsSsize_t(__pyx_v_i); if (unlikely((__pyx_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; goto __pyx_L1;} + __pyx_7 = __pyx_PyIndex_AsSsize_t(__pyx_v_i); if (unlikely((__pyx_7 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; goto __pyx_L1;} + (__pyx_v_zod[__pyx_7]) = (__pyx_v_out[__pyx_6]); + } + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":74 + * for i from 0 <= i < buflenzo/8: + * zod[i] = out[i] + * if ier != 0: # <<<<<<<<<<<<<< + * raise RuntimeError('error in natgridd - ier ='%ier) + */ + __pyx_2 = (__pyx_v_ier != 0); + if (__pyx_2) { + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":75 + * zod[i] = out[i] + * if ier != 0: + * raise RuntimeError('error in natgridd - ier ='%ier) # <<<<<<<<<<<<<< + */ + __pyx_4 = PyInt_FromLong(__pyx_v_ier); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; goto __pyx_L1;} + __pyx_3 = PyNumber_Remainder(__pyx_k_7p, __pyx_4); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; goto __pyx_L1;} + Py_DECREF(__pyx_4); __pyx_4 = 0; + __pyx_4 = PyTuple_New(1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; goto __pyx_L1;} + PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3); + __pyx_3 = 0; + __pyx_3 = PyObject_Call(__pyx_builtin_RuntimeError, __pyx_4, NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; goto __pyx_L1;} + Py_DECREF(__pyx_4); __pyx_4 = 0; + __Pyx_Raise(__pyx_3, 0, 0); + Py_DECREF(__pyx_3); __pyx_3 = 0; + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; goto __pyx_L1;} + goto __pyx_L12; + } + __pyx_L12:; + + __pyx_r = Py_None; Py_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1:; + Py_XDECREF(__pyx_3); + Py_XDECREF(__pyx_4); + __Pyx_AddTraceback("_natgrid.natgridd"); + __pyx_r = NULL; + __pyx_L0:; + Py_DECREF(__pyx_v_i); + Py_DECREF(__pyx_v_x); + Py_DECREF(__pyx_v_y); + Py_DECREF(__pyx_v_z); + Py_DECREF(__pyx_v_xo); + Py_DECREF(__pyx_v_yo); + Py_DECREF(__pyx_v_zo); + return __pyx_r; +} + +static __Pyx_InternTabEntry __pyx_intern_tab[] = { + {&__pyx_n_RuntimeError, "RuntimeError"}, + {0, 0} +}; + +static __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_k_1p, __pyx_k_1, sizeof(__pyx_k_1), 0}, + {&__pyx_k_2p, __pyx_k_2, sizeof(__pyx_k_2), 0}, + {&__pyx_k_3p, __pyx_k_3, sizeof(__pyx_k_3), 0}, + {&__pyx_k_4p, __pyx_k_4, sizeof(__pyx_k_4), 0}, + {&__pyx_k_5p, __pyx_k_5, sizeof(__pyx_k_5), 0}, + {&__pyx_k_6p, __pyx_k_6, sizeof(__pyx_k_6), 0}, + {&__pyx_k_7p, __pyx_k_7, sizeof(__pyx_k_7), 0}, + {0, 0, 0, 0} +}; + +static struct PyMethodDef __pyx_methods[] = { + {"seti", (PyCFunction)__pyx_pf_8_natgrid_seti, METH_VARARGS|METH_KEYWORDS, 0}, + {"setr", (PyCFunction)__pyx_pf_8_natgrid_setr, METH_VARARGS|METH_KEYWORDS, 0}, + {"natgridd", (PyCFunction)__pyx_pf_8_natgrid_natgridd, METH_VARARGS|METH_KEYWORDS, 0}, + {0, 0, 0, 0} +}; + +static void __pyx_init_filenames(void); /*proto*/ + +PyMODINIT_FUNC init_natgrid(void); /*proto*/ +PyMODINIT_FUNC init_natgrid(void) { + /*--- Libary function declarations ---*/ + __pyx_init_filenames(); + /*--- Module creation code ---*/ + __pyx_m = Py_InitModule4("_natgrid", __pyx_methods, __pyx_mdoc, 0, PYTHON_API_VERSION); + if (!__pyx_m) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; goto __pyx_L1;}; + __pyx_b = PyImport_AddModule("__builtin__"); + if (!__pyx_b) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; goto __pyx_L1;}; + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; goto __pyx_L1;}; + /*--- Intern code ---*/ + if (__Pyx_InternStrings(__pyx_intern_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; goto __pyx_L1;}; + /*--- String init code ---*/ + if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; goto __pyx_L1;}; + /*--- Builtin init code ---*/ + __pyx_builtin_RuntimeError = __Pyx_GetName(__pyx_b, __pyx_n_RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; goto __pyx_L1;} + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; goto __pyx_L1;} + __pyx_skip_dispatch = 0; + /*--- Global init code ---*/ + /*--- Function export code ---*/ + /*--- Function import code ---*/ + /*--- Type init code ---*/ + /*--- Type import code ---*/ + /*--- Execution code ---*/ + + /* "/Users/jwhitaker/python/matplotlib/lib/natgrid/src/_natgrid.pyx":44 + * c_nnsetr(pnam, fval) + * + * def natgridd(x, y, z, xo, yo, zo): # <<<<<<<<<<<<<< + * cdef int npnts, numxout, numyout, ier + * cdef Py_ssize_t buflenx, bufleny, buflenz, buflenxo, buflenyo, buflenzo + */ + return; + __pyx_L1:; + __Pyx_AddTraceback("_natgrid"); +} + +static char *__pyx_filenames[] = { + "_natgrid.pyx", +}; + +/* Runtime support code */ + +static void __pyx_init_filenames(void) { + __pyx_f = __pyx_filenames; +} + +static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) { + PyObject *result; + result = PyObject_GetAttr(dict, name); + if (!result) + PyErr_SetObject(PyExc_NameError, name); + return result; +} + +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) { + Py_XINCREF(type); + Py_XINCREF(value); + Py_XINCREF(tb); + /* First, check the traceback argument, replacing None with NULL. */ + if (tb == Py_None) { + Py_DECREF(tb); + tb = 0; + } + else if (tb != NULL && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto raise_error; + } + /* Next, replace a missing value with None */ + if (value == NULL) { + value = Py_None; + Py_INCREF(value); + } + #if PY_VERSION_HEX < 0x02050000 + if (!PyClass_Check(type)) + #else + if (!PyType_Check(type)) + #endif + { + /* Raising an instance. The value should be a dummy. */ + if (value != Py_None) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto raise_error; + } + /* Normalize to raise <class>, <instance> */ + Py_DECREF(value); + value = type; + #if PY_VERSION_HEX < 0x02050000 + if (PyInstance_Check(type)) { + type = (PyObject*) ((PyInstanceObject*)type)->in_class; + Py_INCREF(type); + } + else { + PyErr_SetString(PyExc_TypeError, + "raise: exception must be an old-style class or instance"); + goto raise_error; + } + #else + type = (PyObject*) type->ob_type; + Py_INCREF(type); + if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto raise_error; + } + #endif + } + PyErr_Restore(type, value, tb); + return; +raise_error: + Py_XDECREF(value); + Py_XDECREF(type); + Py_XDECREF(tb); + return; +} + +static int __Pyx_InternStrings(__Pyx_InternTabEntry *t) { + while (t->p) { + *t->p = PyString_InternFromString(t->s); + if (!*t->p) + return -1; + ++t; + } + return 0; +} + +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { + while (t->p) { + if (t->is_unicode) { + *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); + } else { + *t->p = PyString_FromStringAndSize(t->s, t->n - 1); + } + if (!*t->p) + return -1; + ++t; + } + return 0; +} + +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" + +static void __Pyx_AddTraceback(char *funcname) { + PyObject *py_srcfile = 0; + PyObject *py_funcname = 0; + PyObject *py_globals = 0; + PyObject *empty_string = 0; + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + + py_srcfile = PyString_FromString(__pyx_filename); + if (!py_srcfile) goto bad; + py_funcname = PyString_FromString(funcname); + if (!py_funcname) goto bad; + py_globals = PyModule_GetDict(__pyx_m); + if (!py_globals) goto bad; + empty_string = PyString_FromString(""); + if (!empty_string) goto bad; + py_code = PyCode_New( + 0, /*int argcount,*/ + 0, /*int nlocals,*/ + 0, /*int stacksize,*/ + 0, /*int flags,*/ + empty_string, /*PyObject *code,*/ + __pyx_empty_tuple, /*PyObject *consts,*/ + __pyx_empty_tuple, /*PyObject *names,*/ + __pyx_empty_tuple, /*PyObject *varnames,*/ + __pyx_empty_tuple, /*PyObject *freevars,*/ + __pyx_empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + __pyx_lineno, /*int firstlineno,*/ + empty_string /*PyObject *lnotab*/ + ); + if (!py_code) goto bad; + py_frame = PyFrame_New( + PyThreadState_Get(), /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + py_globals, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + py_frame->f_lineno = __pyx_lineno; + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_srcfile); + Py_XDECREF(py_funcname); + Py_XDECREF(empty_string); + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} + +/* Type Conversion Functions */ + +static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject* x = PyNumber_Index(b); + if (!x) return -1; + ival = PyInt_AsSsize_t(x); + Py_DECREF(x); + return ival; +} + +static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + if (x == Py_True) return 1; + else if (x == Py_False) return 0; + else return PyObject_IsTrue(x); +} + +static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x) { + if (PyInt_CheckExact(x)) { + return PyInt_AS_LONG(x); + } + else if (PyLong_CheckExact(x)) { + return PyLong_AsLongLong(x); + } + else { + PY_LONG_LONG val; + PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1; + val = __pyx_PyInt_AsLongLong(tmp); + Py_DECREF(tmp); + return val; + } +} + +static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x) { + if (PyInt_CheckExact(x)) { + long val = PyInt_AS_LONG(x); + if (unlikely(val < 0)) { + PyErr_SetString(PyExc_TypeError, "Negative assignment to unsigned type."); + return (unsigned PY_LONG_LONG)-1; + } + return val; + } + else if (PyLong_CheckExact(x)) { + return PyLong_AsUnsignedLongLong(x); + } + else { + PY_LONG_LONG val; + PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1; + val = __pyx_PyInt_AsUnsignedLongLong(tmp); + Py_DECREF(tmp); + return val; + } +} + + +static INLINE unsigned char __pyx_PyInt_unsigned_char(PyObject* x) { + if (sizeof(unsigned char) < sizeof(long)) { + long long_val = __pyx_PyInt_AsLong(x); + unsigned char val = (unsigned char)long_val; + if (unlikely((val != long_val) || (long_val < 0))) { + PyErr_SetString(PyExc_OverflowError, "value too large to convert to unsigned char"); + return (unsigned char)-1; + } + return val; + } + else { + return __pyx_PyInt_AsLong(x); + } +} + +static INLINE unsigned short __pyx_PyInt_unsigned_short(PyObject* x) { + if (sizeof(unsigned short) < sizeof(long)) { + long long_val = __pyx_PyInt_AsLong(x); + unsigned short val = (unsigned short)long_val; + if (unlikely((val != long_val) || (long_val < 0))) { + PyErr_SetString(PyExc_OverflowError, "value too large to convert to unsigned short"); + return (unsigned short)-1; + } + return val; + } + else { + return __pyx_PyInt_AsLong(x); + } +} + +static INLINE char __pyx_PyInt_char(PyObject* x) { + if (sizeof(char) < sizeof(long)) { + long long_val = __pyx_PyInt_AsLong(x); + char val = (char)long_val; + if (unlikely((val != long_val) )) { + PyErr_SetString(PyExc_OverflowError, "value too large to convert to char"); + return (char)-1; + } + return val; + } + else { + return __pyx_PyInt_AsLong(x); + } +} + +static INLINE short __pyx_PyInt_short(PyObject* x) { + if (sizeof(short) < sizeof(long)) { + long long_val = __pyx_PyInt_AsLong(x); + short val = (short)long_val; + if (unlikely((val != long_val) )) { + PyErr_SetString(PyExc_OverflowError, "value too large to convert to short"); + return (short)-1; + } + return val; + } + else { + return __pyx_PyInt_AsLong(x); + } +} + +static INLINE int __pyx_PyInt_int(PyObject* x) { + if (sizeof(int) < sizeof(long)) { + long long_val = __pyx_PyInt_AsLong(x); + int val = (int)long_val; + if (unlikely((val != long_val) )) { + PyErr_SetString(PyExc_OverflowError, "value too large to convert to int"); + return (int)-1; + } + return val; + } + else { + return __pyx_PyInt_AsLong(x); + } +} + +static INLINE long __pyx_PyInt_long(PyObject* x) { + if (sizeof(long) < sizeof(long)) { + long long_val = __pyx_PyInt_AsLong(x); + long val = (long)long_val; + if (unlikely((val != long_val) )) { + PyErr_SetString(PyExc_OverflowError, "value too large to convert to long"); + return (long)-1; + } + return val; + } + else { + return __pyx_PyInt_AsLong(x); + } +} + +static INLINE signed char __pyx_PyInt_signed_char(PyObject* x) { + if (sizeof(signed char) < sizeof(long)) { + long long_val = __pyx_PyInt_AsLong(x); + signed char val = (signed char)long_val; + if (unlikely((val != long_val) )) { + PyErr_SetString(PyExc_OverflowError, "value too large to convert to signed char"); + return (signed char)-1; + } + return val; + } + else { + return __pyx_PyInt_AsLong(x); + } +} + +static INLINE signed short __pyx_PyInt_signed_short(PyObject* x) { + if (sizeof(signed short) < sizeof(long)) { + long long_val = __pyx_PyInt_AsLong(x); + signed short val = (signed short)long_val; + if (unlikely((val != long_val) )) { + PyErr_SetString(PyExc_OverflowError, "value too large to convert to signed short"); + return (signed short)-1; + } + return val; + } + else { + return __pyx_PyInt_AsLong(x); + } +} + +static INLINE signed int __pyx_PyInt_signed_int(PyObject* x) { + if (sizeof(signed int) < sizeof(long)) { + long long_val = __pyx_PyInt_AsLong(x); + signed int val = (signed int)long_val; + if (unlikely((val != long_val) )) { + PyErr_SetString(PyExc_OverflowError, "value too large to convert to signed int"); + return (signed int)-1; + } + return val; + } + else { + return __pyx_PyInt_AsLong(x); + } +} + +static INLINE signed long __pyx_PyInt_signed_long(PyObject* x) { + if (sizeof(signed long) < sizeof(long)) { + long long_val = __pyx_PyInt_AsLong(x); + signed long val = (signed long)long_val; + if (unlikely((val != long_val) )) { + PyErr_SetString(PyExc_OverflowError, "value too large to convert to signed long"); + return (signed long)-1; + } + return val; + } + else { + return __pyx_PyInt_AsLong(x); + } +} + +static INLINE long double __pyx_PyInt_long_double(PyObject* x) { + if (sizeof(long double) < sizeof(long)) { + long long_val = __pyx_PyInt_AsLong(x); + long double val = (long double)long_val; + if (unlikely((val != long_val) )) { + PyErr_SetString(PyExc_OverflowError, "value too large to convert to long double"); + return (long double)-1; + } + return val; + } + else { + return __pyx_PyInt_AsLong(x); + } +} Added: trunk/toolkits/natgrid/src/_natgrid.pyx =================================================================== --- trunk/toolkits/natgrid/src/_natgrid.pyx (rev 0) +++ trunk/toolkits/natgrid/src/_natgrid.pyx 2008年07月22日 11:12:50 UTC (rev 5808) @@ -0,0 +1,75 @@ +""" +Pyrex wrapper for NCAR natgrid library for interpolation +of irregularly spaced data to a grid. + +copyright (c) 2007 by Jeffrey Whitaker. + +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 notices appear in all copies and that +both the copyright notices and this permission notice appear in +supporting documentation. +THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO +EVENT SHALL 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. +""" + +# Pyrex generates nnint.c from this file, so make changes here +# and re-create nnint.c with "pyrexc nnint.pyx". + +cdef extern void c_nnseti(char *pnam, int ival) +cdef extern double *c_natgridd(int n, double *x, double *y, double *z, int numxout, int numyout, double *xo, double *yo, int *ier) +cdef extern void c_nnsetr(char *pnam, float fval) + +cdef extern from "Python.h": + int PyObject_AsWriteBuffer(object, void **rbuf, Py_ssize_t *len) + char *PyString_AsString(object) + +def seti(name, value): + cdef char *pnam + cdef int ival + pnam = name; ival = value + c_nnseti(pnam, ival) + +def setr(name, value): + cdef char *pnam + cdef float fval + pnam = name; fval = value + c_nnsetr(pnam, fval) + +def natgridd(x, y, z, xo, yo, zo): + cdef int npnts, numxout, numyout, ier + cdef Py_ssize_t buflenx, bufleny, buflenz, buflenxo, buflenyo, buflenzo + cdef void *xp, *yp, *zp, *xop, *yop, *zop + cdef double *xd, *yd, *zd, *xod, *yod, *zod, *out + npnts = len(x) + numxout = len(xo) + numyout = len(yo) + if PyObject_AsWriteBuffer(x, &xp, &buflenx) <> 0: + raise RuntimeError('error getting buffer for x') + if PyObject_AsWriteBuffer(y, &yp, &bufleny) <> 0: + raise RuntimeError('error getting buffer for y') + if PyObject_AsWriteBuffer(z, &zp, &buflenz) <> 0: + raise RuntimeError('error getting buffer for z') + xd = <double *>xp + yd = <double *>yp + zd = <double *>zp + if PyObject_AsWriteBuffer(xo, &xop, &buflenxo) <> 0: + raise RuntimeError('error getting buffer for x') + if PyObject_AsWriteBuffer(yo, &yop, &buflenyo) <> 0: + raise RuntimeError('error getting buffer for y') + if PyObject_AsWriteBuffer(zo, &zop, &buflenzo) <> 0: + raise RuntimeError('error getting buffer for z') + xod = <double *>xop + yod = <double *>yop + zod = <double *>zop + # output overwrites zo. + out = c_natgridd(npnts, yd, xd, zd, numyout, numxout, yod, xod, &ier) + for i from 0 <= i < buflenzo/8: + zod[i] = out[i] + if ier != 0: + raise RuntimeError('error in natgridd - ier ='%ier) Property changes on: trunk/toolkits/natgrid/src/_natgrid.pyx ___________________________________________________________________ Added: svn:executable + * Added: trunk/toolkits/natgrid/src/natgrid.c =================================================================== --- trunk/toolkits/natgrid/src/natgrid.c (rev 0) +++ trunk/toolkits/natgrid/src/natgrid.c 2008年07月22日 11:12:50 UTC (rev 5808) @@ -0,0 +1,69 @@ +/* + * This file contains the settings for most of the + * global variables by way of including nnmhead.h . + */ + +#include "nnmhead.h" +#include "nnghead.h" +#include "nntypes.h" +#include "nntpvrs.h" +#include "nnexver.h" + +void Terminate() +{ + struct simp *tmp,*tmp0; + struct datum *dtmp,*dtmp0; + struct neig *ntmp,*ntmp0; + struct temp *ttmp,*ttmp0; + tmp = rootsimp; + while(tmp!=NULL) { + tmp0 =tmp->nextsimp; + free(tmp); + tmp = tmp0; + } + rootsimp = cursimp = holdsimp = lastsimp = prevsimp = NULL; + dtmp = rootdat; + while(dtmp!=NULL) { + dtmp0 =dtmp->nextdat; + free(dtmp); + dtmp = dtmp0; + } + rootdat = curdat = holddat = NULL; + ntmp = rootneig; + while(ntmp!=NULL) { + ntmp0 =ntmp->nextneig; + free(ntmp); + ntmp = ntmp0; + } + rootneig = curneig = lastneig = NULL; + ttmp = roottemp; + while(ttmp!=NULL) { + ttmp0 =ttmp->nexttemp; + free(ttmp); + ttmp = ttmp0; + } + roottemp = curtemp = lasttemp= prevtemp= NULL; + + if(points!=NULL) { + FreeMatrixd(points); + points = NULL; + } + if(joints!=NULL) { + FreeMatrixd(joints); + joints = NULL; + } + if(jndx != NULL) { + FreeVecti(jndx); + jndx = NULL; + } + if(wts != NULL) { + free(wts); + } + if(nbrs != NULL) { + free(nbrs); + } + + magx = magx_orig; + magy = magy_orig; + magz = magz_orig; +} Added: trunk/toolkits/natgrid/src/natgridd.c =================================================================== --- trunk/toolkits/natgrid/src/natgridd.c (rev 0) +++ trunk/toolkits/natgrid/src/natgridd.c 2008年07月22日 11:12:50 UTC (rev 5808) @@ -0,0 +1,166 @@ +#include "nnghead.h" +#include "nngheadd.h" + +double *c_natgridd(int n, double x[], double y[], double z[], + int nxi, int nyi, double xi[], double yi[], int *ier) +{ + double **data_out=NULL, *rtrn_val=NULL; + + *ier = 0; + + if (single_point == 0) + { + asflag = 1; + Initialized(n, x, y, nxi, nyi, xi, yi); + + if (ReadDatad(n,x,y,z) != 0) + { + *ier = error_status; + return ( (double *) NULL); + } + } + + if (adf) + { + CircOut(); + if (error_status) + { + *ier = error_status; + return ( (double *) NULL); + } + } + if (igrad) + { + Gradient(); + if (error_status) + { + *ier = error_status; + return ( (double *) NULL); + } + } + + data_out = MakeGridd(nxi, nyi, xi, yi); + if (error_status) + { + if((data_out !=NULL)&&(data_out[0]!=NULL)) { + free(data_out[0]); + free(data_out); + } + *ier = error_status; + return ( (double *) NULL); + } + + if (single_point == 0) + { + Terminate(); + } + + horilap = -1.; + vertlap = -1.; + + rtrn_val = data_out[0]; + free(data_out); + return (rtrn_val); +} +void Initialized(int n, double x[], double y[], int nxi, int nyi, + double xi[], double yi[]) +{ + + double xil, xir, yib, yit; + +/* + * Reserve memory for returning natural neighbor indices + * and associated weights when requested in single point + * mode for linear interpolation. + */ + nbrs = (int *) calloc(n,sizeof(int)); + wts = (double *) calloc(n,sizeof(double)); + + error_status = 0; + datcnt = 0; + magx_orig = magx; + magy_orig = magy; + magz_orig = magz; + iscale = 0; + magx_auto = 1.; + magy_auto = 1.; + magz_auto = 1.; + +/* + * Find the limits of the output array. + */ + xstart = armind(nxi, xi); + xend = armaxd(nxi, xi); + ystart = armind(nyi, yi); + yend = armaxd(nyi, yi); + +/* + * Find the limits of the input array. + */ + xil = armind(n, x); + xir = armaxd(n, x); + yib = armind(n, y); + yit = armaxd(n, y); + +/* + * As the default (that is, unless horizontal and vertical overlaps + * have been specifically set by the user) choose the overlap values + * as the smallest values that will make all input data points included + * in the overlap region. + */ + if (horilap EQ -1.) { + if ( (xstart >= xil) && (xend <= xir) ) { + horilap = 1.01 * (((xstart-xil) < (xir-xend)) ? + (xir-xend) : (xstart-xil)); + } + else if ( (xstart >= xil) && (xend >= xir) ) { + horilap = 1.01 * (xstart-xil); + } + else if ( (xstart <= xil) && (xend <= xir) ) { + horilap = 1.01 * (xir-xend); + } + else if ( (xstart <= xil) && (xir <= xend) ) { + horilap = 0.; + } + } + if (horilap <= EPSILON) { + horilap = 0.01 * (xend - xstart); + } + if (vertlap EQ -1.) { + if ( (yib <= ystart) && (yend <= yit) ) { + vertlap = 1.01 * (((ystart-yib) < (yit-yend)) ? + (yit-yend) : (ystart-yib)); + } + else if ( (ystart <= yib) && (yend <= yit) ) { + vertlap = 1.01 * (yit-yend); + } + else if ( (yib <= ystart) && (yit <= yend) ) { + vertlap = 1.01 * (ystart-yib); + } + else if ( (ystart <= yib) && (yit <= yend) ) { + vertlap = 0.; + } + } + if (vertlap <= EPSILON) { + vertlap = 0.01 * (yend - ystart); + } +} + +double armind(int num, double *x) +{ + int i; + float amin; + amin = x[0]; + for (i = 1 ; i < num ; i++) + if (x[i] < amin) amin = x[i]; + return(amin); +} +double armaxd(int num, double *x) +{ + int i; + float amax; + amax = x[0]; + for (i = 1 ; i < num ; i++) + if (x[i] > amax) amax = x[i]; + return(amax); +} Added: trunk/toolkits/natgrid/src/natgrids.c =================================================================== --- trunk/toolkits/natgrid/src/natgrids.c (rev 0) +++ trunk/toolkits/natgrid/src/natgrids.c 2008年07月22日 11:12:50 UTC (rev 5808) @@ -0,0 +1,168 @@ +#include <stdlib.h> +#include "nnghead.h" +#include "nngheads.h" +#include "nnexver.h" + +float *c_natgrids(int n, float x[], float y[], float z[], + int nxi, int nyi, float xi[], flo... [truncated message content]
Revision: 5807 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5807&view=rev Author: jswhit Date: 2008年07月22日 02:47:02 +0000 (2008年7月22日) Log Message: ----------- fix typo in as yet nonexistent natgrid import. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/mlab.py Modified: trunk/matplotlib/lib/matplotlib/mlab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mlab.py 2008年07月22日 02:17:09 UTC (rev 5806) +++ trunk/matplotlib/lib/matplotlib/mlab.py 2008年07月22日 02:47:02 UTC (rev 5807) @@ -91,7 +91,7 @@ import matplotlib.nxutils as nxutils import matplotlib.cbook as cbook try: - import mpl_tookits._natgrid as _natgrid + from mpl_toolkits.natgrid import _natgrid _use_natgrid = True except ImportError: import matplotlib.delaunay as delaunay This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5806 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5806&view=rev Author: jswhit Date: 2008年07月22日 02:17:09 +0000 (2008年7月22日) Log Message: ----------- added griddata function (left out in previous commit) Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/mlab.py Modified: trunk/matplotlib/lib/matplotlib/mlab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mlab.py 2008年07月22日 01:52:12 UTC (rev 5805) +++ trunk/matplotlib/lib/matplotlib/mlab.py 2008年07月22日 02:17:09 UTC (rev 5806) @@ -90,6 +90,12 @@ import matplotlib.nxutils as nxutils import matplotlib.cbook as cbook +try: + import mpl_tookits._natgrid as _natgrid + _use_natgrid = True +except ImportError: + import matplotlib.delaunay as delaunay + _use_natgrid = False # set is a new builtin function in 2.4; delete the following when # support for 2.3 is dropped. @@ -2691,3 +2697,55 @@ in zip(funcs, row, rowmask, mvals)]) if opened: fh.close() + +def griddata(x,y,z,xi,yi): + """ + zi = griddata(x,y,z,xi,yi) fits a surface of the form z = f(x,y) + to the data in the (usually) nonuniformly spaced vectors (x,y,z). + griddata interpolates this surface at the points specified by (xi,yi) + to produce zi. xi and yi must describe a regular grid, can be + either 1D or 2D, but must be monotonically increasing. + + A masked array is returned if any grid points are outside convex + hull defined by input data (no extrapolation is done). + + Uses natural neighbor interpolation based on Delaunay triangulation. + """ + if xi.ndim != yi.ndim: + raise TypeError("inputs xi and yi must have same number of dimensions (1 or 2)") + if xi.ndim != 1 and xi.ndim != 2: + raise TypeError("inputs xi and yi must be 1D or 2D.") + if _use_natgrid: # use natgrid toolkit if available. + if xi.ndim == 2: + xi = xi[0,:] + yi = yi[:,0] + # override default natgrid internal parameters. + _natgrid.seti('ext',0) + _natgrid.setr('nul',np.nan) + # cast input arrays to doubles (this makes a copy) + x = x.astype(np.float) + y = y.astype(np.float) + z = z.astype(np.float) + 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' + # 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) + else: # use Robert Kern's delaunay package from scikits (default) + if xi.ndim != yi.ndim: + raise TypeError("inputs xi and yi must have same number of dimensions (1 or 2)") + if xi.ndim != 1 and xi.ndim != 2: + raise TypeError("inputs xi and yi must be 1D or 2D.") + if xi.ndim == 1: + xi,yi = np.meshgrid(xi,yi) + # triangulate data + tri = delaunay.Triangulation(x,y) + # interpolate data + interp = tri.nn_interpolator(z) + zo = interp(xi,yi) + # mask points on grid outside convex hull of input data. + if np.any(np.isnan(zo)): + zo = np.ma.masked_where(np.isnan(zo),zo) + return zo This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5805 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5805&view=rev Author: jswhit Date: 2008年07月22日 01:52:12 +0000 (2008年7月22日) Log Message: ----------- added scikits.delaunay as matplotlib.delaunay, added griddata function to mlab. Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/examples/tests/backend_driver.py trunk/matplotlib/setup.py trunk/matplotlib/setupext.py Added Paths: ----------- trunk/matplotlib/examples/pylab_examples/griddata_demo.py trunk/matplotlib/lib/matplotlib/delaunay/ trunk/matplotlib/lib/matplotlib/delaunay/VoronoiDiagramGenerator.cpp trunk/matplotlib/lib/matplotlib/delaunay/VoronoiDiagramGenerator.h trunk/matplotlib/lib/matplotlib/delaunay/__init__.py trunk/matplotlib/lib/matplotlib/delaunay/_delaunay.cpp trunk/matplotlib/lib/matplotlib/delaunay/delaunay_utils.cpp trunk/matplotlib/lib/matplotlib/delaunay/delaunay_utils.h trunk/matplotlib/lib/matplotlib/delaunay/interpolate.py trunk/matplotlib/lib/matplotlib/delaunay/natneighbors.cpp trunk/matplotlib/lib/matplotlib/delaunay/natneighbors.h trunk/matplotlib/lib/matplotlib/delaunay/testfuncs.py trunk/matplotlib/lib/matplotlib/delaunay/triangulate.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2008年07月21日 22:42:52 UTC (rev 5804) +++ trunk/matplotlib/CHANGELOG 2008年07月22日 01:52:12 UTC (rev 5805) @@ -1,3 +1,8 @@ +2008年07月21日 Added scikits.delaunay as matplotlib.delaunay. Added griddata + function in matplotlib.mlab, with example (griddata_demo.py) in + pylab_examples. griddata function will use mpl_toolkits._natgrid + if installed (haven't yet created the toolkit). - JSW + 2008年07月21日 Re-introduced offset_copy that works in the context of the new transforms. - MGD Added: trunk/matplotlib/examples/pylab_examples/griddata_demo.py =================================================================== --- trunk/matplotlib/examples/pylab_examples/griddata_demo.py (rev 0) +++ trunk/matplotlib/examples/pylab_examples/griddata_demo.py 2008年07月22日 01:52:12 UTC (rev 5805) @@ -0,0 +1,40 @@ +from numpy.random import uniform, seed +from matplotlib.mlab import griddata +import matplotlib.pyplot as plt +import numpy as np +# make up data. +#npts = int(raw_input('enter # of random points to plot:')) +seed(-1) +npts = 200 +x = uniform(-2,2,npts) +y = uniform(-2,2,npts) +z = x*np.exp(-x**2-y**2) +# define grid. +xi = np.linspace(-2.1,2.1,100) +yi = np.linspace(-2.1,2.1,100) +# grid the data. +zi = griddata(x,y,z,xi,yi) +# 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) +plt.colorbar() # draw colorbar +# plot data points. +plt.scatter(x,y,marker='o',c='b',s=5) +plt.xlim(-2,2) +plt.ylim(-2,2) +plt.title('griddata test (%d points)' % npts) +plt.show() + +# test case that scikits.delaunay fails on, but natgrid passes.. +#data = np.array([[-1, -1], [-1, 0], [-1, 1], +# [ 0, -1], [ 0, 0], [ 0, 1], +# [ 1, -1 - np.finfo(np.float_).eps], [ 1, 0], [ 1, 1], +# ]) +#x = data[:,0] +#y = data[:,1] +#z = x*np.exp(-x**2-y**2) +## define grid. +#xi = np.linspace(-1.1,1.1,100) +#yi = np.linspace(-1.1,1.1,100) +## grid the data. +#zi = griddata(x,y,z,xi,yi) Modified: trunk/matplotlib/examples/tests/backend_driver.py =================================================================== --- trunk/matplotlib/examples/tests/backend_driver.py 2008年07月21日 22:42:52 UTC (rev 5804) +++ trunk/matplotlib/examples/tests/backend_driver.py 2008年07月22日 01:52:12 UTC (rev 5805) @@ -41,6 +41,7 @@ 'contour_demo.py', 'contour_label_demo.py', 'contourf_demo.py', + 'griddata_demo.py', 'csd_demo.py', 'custom_ticker1.py', 'customize_rc.py', Added: trunk/matplotlib/lib/matplotlib/delaunay/VoronoiDiagramGenerator.cpp =================================================================== --- trunk/matplotlib/lib/matplotlib/delaunay/VoronoiDiagramGenerator.cpp (rev 0) +++ trunk/matplotlib/lib/matplotlib/delaunay/VoronoiDiagramGenerator.cpp 2008年07月22日 01:52:12 UTC (rev 5805) @@ -0,0 +1,1152 @@ +/* + * 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. 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. + */ + +/* + * Subsequently, Robert Kern modified it to yield Python objects. + * Copyright 2005 Robert Kern <rob...@gm...> + * See LICENSE.txt in the scipy source directory. + */ + +#include "VoronoiDiagramGenerator.h" + +VoronoiDiagramGenerator::VoronoiDiagramGenerator() +{ + siteidx = 0; + sites = 0; + + allMemoryList = new FreeNodeArrayList; + allMemoryList->memory = 0; + allMemoryList->next = 0; + currentMemoryBlock = allMemoryList; + allEdges = 0; + allEdgeList = 0; + iteratorEdges = 0; + iterEdgeList = 0; + minDistanceBetweenSites = 0; +} + +VoronoiDiagramGenerator::~VoronoiDiagramGenerator() +{ + cleanupEdgeList(); + cleanup(); + cleanupEdges(); + + if(allMemoryList != 0) + delete allMemoryList; +} + + + +bool VoronoiDiagramGenerator::generateVoronoi(double *xValues, double *yValues, int numPoints, double minX, double maxX, double minY, double maxY, double minDist) +{ + cleanupEdgeList(); + cleanup(); + cleanupEdges(); + int i; + + minDistanceBetweenSites = minDist; + + nsites=numPoints; + plot = 0; + triangulate = 0; + debug = 1; + sorted = 0; + freeinit(&sfl, sizeof (Site)); + + sites = (struct Site *) myalloc(nsites*sizeof( *sites)); + + if(sites == 0) + return false; + + xmin = xValues[0]; + ymin = yValues[0]; + xmax = xValues[0]; + ymax = yValues[0]; + + for(i = 0; i< nsites; i++) + { + sites[i].coord.x = xValues[i]; + sites[i].coord.y = yValues[i]; + sites[i].sitenbr = i; + sites[i].refcnt = 0; + + if(xValues[i] < xmin) + xmin = xValues[i]; + else if(xValues[i] > xmax) + xmax = xValues[i]; + + if(yValues[i] < ymin) + ymin = yValues[i]; + else if(yValues[i] > ymax) + ymax = yValues[i]; + + //printf("\n%f %f\n",xValues[i],yValues[i]); + } + + qsort(sites, nsites, sizeof (*sites), scomp); + + siteidx = 0; + geominit(); + double temp = 0; + if(minX > maxX) + { + temp = minX; + minX = maxX; + maxX = temp; + } + if(minY > maxY) + { + temp = minY; + minY = maxY; + maxY = temp; + } + borderMinX = minX; + borderMinY = minY; + borderMaxX = maxX; + borderMaxY = maxY; + + siteidx = 0; + + voronoi(triangulate); + + return true; +} + +bool VoronoiDiagramGenerator::ELinitialize() +{ + int i; + freeinit(&hfl, sizeof **ELhash); + ELhashsize = 2 * sqrt_nsites; + ELhash = (struct Halfedge **) myalloc ( sizeof *ELhash * ELhashsize); + + if(ELhash == 0) + return false; + + for(i=0; i<ELhashsize; i +=1) ELhash[i] = (struct Halfedge *)NULL; + ELleftend = HEcreate( (struct Edge *)NULL, 0); + ELrightend = HEcreate( (struct Edge *)NULL, 0); + ELleftend -> ELleft = (struct Halfedge *)NULL; + ELleftend -> ELright = ELrightend; + ELrightend -> ELleft = ELleftend; + ELrightend -> ELright = (struct Halfedge *)NULL; + ELhash[0] = ELleftend; + ELhash[ELhashsize-1] = ELrightend; + + return true; +} + + +struct Halfedge* VoronoiDiagramGenerator::HEcreate(struct Edge *e,int pm) +{ + struct Halfedge *answer; + answer = (struct Halfedge *) getfree(&hfl); + answer -> ELedge = e; + answer -> ELpm = pm; + answer -> PQnext = (struct Halfedge *) NULL; + answer -> vertex = (struct Site *) NULL; + answer -> ELrefcnt = 0; + return(answer); +} + + +void VoronoiDiagramGenerator::ELinsert(struct Halfedge *lb, struct Halfedge *newHe) +{ + newHe -> ELleft = lb; + newHe -> ELright = lb -> ELright; + (lb -> ELright) -> ELleft = newHe; + lb -> ELright = newHe; +} + +/* Get entry from hash table, pruning any deleted nodes */ +struct Halfedge * VoronoiDiagramGenerator::ELgethash(int b) +{ + struct Halfedge *he; + + if(b<0 || b>=ELhashsize) + return((struct Halfedge *) NULL); + he = ELhash[b]; + if (he == (struct Halfedge *) NULL || he->ELedge != (struct Edge *) DELETED ) + return (he); + + /* Hash table points to deleted half edge. Patch as necessary. */ + ELhash[b] = (struct Halfedge *) NULL; + if ((he -> ELrefcnt -= 1) == 0) + makefree((Freenode*)he, &hfl); + return ((struct Halfedge *) NULL); +} + +struct Halfedge * VoronoiDiagramGenerator::ELleftbnd(struct Point *p) +{ + int i, bucket; + struct Halfedge *he; + + /* Use hash table to get close to desired halfedge */ + bucket = (int)((p->x - xmin)/deltax * ELhashsize); //use the hash function to find the place in the hash map that this HalfEdge should be + + if(bucket<0) bucket =0; //make sure that the bucket position in within the range of the hash array + if(bucket>=ELhashsize) bucket = ELhashsize - 1; + + he = ELgethash(bucket); + if(he == (struct Halfedge *) NULL) //if the HE isn't found, search backwards and forwards in the hash map for the first non-null entry + { + for(i=1; 1 ; i += 1) + { + if ((he=ELgethash(bucket-i)) != (struct Halfedge *) NULL) + break; + if ((he=ELgethash(bucket+i)) != (struct Halfedge *) NULL) + break; + }; + totalsearch += i; + }; + ntry += 1; + /* Now search linear list of halfedges for the correct one */ + if (he==ELleftend || (he != ELrightend && right_of(he,p))) + { + do + { + he = he -> ELright; + } while (he!=ELrightend && right_of(he,p)); //keep going right on the list until either the end is reached, or you find the 1st edge which the point + he = he -> ELleft; //isn't to the right of + } + else //if the point is to the left of the HalfEdge, then search left for the HE just to the left of the point + do + { + he = he -> ELleft; + } while (he!=ELleftend && !right_of(he,p)); + + /* Update hash table and reference counts */ + if(bucket > 0 && bucket <ELhashsize-1) + { + if(ELhash[bucket] != (struct Halfedge *) NULL) + { + ELhash[bucket] -> ELrefcnt -= 1; + } + ELhash[bucket] = he; + ELhash[bucket] -> ELrefcnt += 1; + }; + return (he); +} + + +/* This delete routine can't reclaim node, since pointers from hash +table may be present. */ +void VoronoiDiagramGenerator::ELdelete(struct Halfedge *he) +{ + (he -> ELleft) -> ELright = he -> ELright; + (he -> ELright) -> ELleft = he -> ELleft; + he -> ELedge = (struct Edge *)DELETED; +} + + +struct Halfedge * VoronoiDiagramGenerator::ELright(struct Halfedge *he) +{ + return (he -> ELright); +} + +struct Halfedge * VoronoiDiagramGenerator::ELleft(struct Halfedge *he) +{ + return (he -> ELleft); +} + + +struct Site * VoronoiDiagramGenerator::leftreg(struct Halfedge *he) +{ + if(he -> ELedge == (struct Edge *)NULL) + return(bottomsite); + return( he -> ELpm == le ? + he -> ELedge -> reg[le] : he -> ELedge -> reg[re]); +} + +struct Site * VoronoiDiagramGenerator::rightreg(struct Halfedge *he) +{ + if(he -> ELedge == (struct Edge *)NULL) //if this halfedge has no edge, return the bottom site (whatever that is) + return(bottomsite); + + //if the ELpm field is zero, return the site 0 that this edge bisects, otherwise return site number 1 + return( he -> ELpm == le ? he -> ELedge -> reg[re] : he -> ELedge -> reg[le]); +} + +void VoronoiDiagramGenerator::geominit() +{ + double sn; + + freeinit(&efl, sizeof(Edge)); + nvertices = 0; + nedges = 0; + sn = (double)nsites+4; + sqrt_nsites = (int)sqrt(sn); + deltay = ymax - ymin; + deltax = xmax - xmin; +} + + +struct Edge * VoronoiDiagramGenerator::bisect(struct Site *s1, struct Site *s2) +{ + double dx,dy,adx,ady; + struct Edge *newedge; + + newedge = (struct Edge *) getfree(&efl); + + newedge -> reg[0] = s1; //store the sites that this edge is bisecting + newedge -> reg[1] = s2; + ref(s1); + ref(s2); + newedge -> ep[0] = (struct Site *) NULL; //to begin with, there are no endpoints on the bisector - it goes to infinity + newedge -> ep[1] = (struct Site *) NULL; + + dx = s2->coord.x - s1->coord.x; //get the difference in x dist between the sites + dy = s2->coord.y - s1->coord.y; + adx = dx>0 ? dx : -dx; //make sure that the difference in positive + ady = dy>0 ? dy : -dy; + newedge -> c = (double)(s1->coord.x * dx + s1->coord.y * dy + (dx*dx + dy*dy)*0.5);//get the slope of the line + + if (adx>ady) + { + newedge -> a = 1.0; newedge -> b = dy/dx; newedge -> c /= dx;//set formula of line, with x fixed to 1 + } + else + { + newedge -> b = 1.0; newedge -> a = dx/dy; newedge -> c /= dy;//set formula of line, with y fixed to 1 + }; + + newedge -> edgenbr = nedges; + + //printf("\nbisect(%d) ((%f,%f) and (%f,%f)",nedges,s1->coord.x,s1->coord.y,s2->coord.x,s2->coord.y); + + nedges += 1; + return(newedge); +} + +//create a new site where the HalfEdges el1 and el2 intersect - note that the Point in the argument list is not used, don't know why it's there +struct Site * VoronoiDiagramGenerator::intersect(struct Halfedge *el1, struct Halfedge *el2, struct Point *p) +{ + struct Edge *e1,*e2, *e; + struct Halfedge *el; + double d, xint, yint; + int right_of_site; + struct Site *v; + + e1 = el1 -> ELedge; + e2 = el2 -> ELedge; + if(e1 == (struct Edge*)NULL || e2 == (struct Edge*)NULL) + return ((struct Site *) NULL); + + //if the two edges bisect the same parent, return null + if (e1->reg[1] == e2->reg[1]) + return ((struct Site *) NULL); + + d = e1->a * e2->b - e1->b * e2->a; + if (-1.0e-10<d && d<1.0e-10) + return ((struct Site *) NULL); + + xint = (e1->c*e2->b - e2->c*e1->b)/d; + yint = (e2->c*e1->a - e1->c*e2->a)/d; + + if( (e1->reg[1]->coord.y < e2->reg[1]->coord.y) || + (e1->reg[1]->coord.y == e2->reg[1]->coord.y && + e1->reg[1]->coord.x < e2->reg[1]->coord.x) ) + { + el = el1; + e = e1; + } + else + { + el = el2; + e = e2; + }; + + right_of_site = xint >= e -> reg[1] -> coord.x; + if ((right_of_site && el -> ELpm == le) || (!right_of_site && el -> ELpm == re)) + return ((struct Site *) NULL); + + //create a new site at the point of intersection - this is a new vector event waiting to happen + v = (struct Site *) getfree(&sfl); + v -> refcnt = 0; + v -> coord.x = xint; + v -> coord.y = yint; + return(v); +} + +/* returns 1 if p is to right of halfedge e */ +int VoronoiDiagramGenerator::right_of(struct Halfedge *el,struct Point *p) +{ + struct Edge *e; + struct Site *topsite; + int right_of_site, above, fast; + double dxp, dyp, dxs, t1, t2, t3, yl; + + e = el -> ELedge; + topsite = e -> reg[1]; + right_of_site = p -> x > topsite -> coord.x; + if(right_of_site && el -> ELpm == le) return(1); + if(!right_of_site && el -> ELpm == re) return (0); + + if (e->a == 1.0) + { dyp = p->y - topsite->coord.y; + dxp = p->x - topsite->coord.x; + fast = 0; + if ((!right_of_site & (e->b<0.0)) | (right_of_site & (e->b>=0.0)) ) + { above = dyp>= e->b*dxp; + fast = above; + } + else + { above = p->x + p->y*e->b > e-> c; + if(e->b<0.0) above = !above; + if (!above) fast = 1; + }; + if (!fast) + { dxs = topsite->coord.x - (e->reg[0])->coord.x; + above = e->b * (dxp*dxp - dyp*dyp) < + dxs*dyp*(1.0+2.0*dxp/dxs + e->b*e->b); + if(e->b<0.0) above = !above; + }; + } + else /*e->b==1.0 */ + { yl = e->c - e->a*p->x; + t1 = p->y - yl; + t2 = p->x - topsite->coord.x; + t3 = yl - topsite->coord.y; + above = t1*t1 > t2*t2 + t3*t3; + }; + return (el->ELpm==le ? above : !above); +} + + +void VoronoiDiagramGenerator::endpoint(struct Edge *e,int lr,struct Site * s) +{ + e -> ep[lr] = s; + ref(s); + if(e -> ep[re-lr]== (struct Site *) NULL) + return; + + clip_line(e); + + deref(e->reg[le]); + deref(e->reg[re]); + makefree((Freenode*)e, &efl); +} + + +double VoronoiDiagramGenerator::dist(struct Site *s,struct Site *t) +{ + double dx,dy; + dx = s->coord.x - t->coord.x; + dy = s->coord.y - t->coord.y; + return (double)(sqrt(dx*dx + dy*dy)); +} + + +void VoronoiDiagramGenerator::makevertex(struct Site *v) +{ + v -> sitenbr = nvertices; + nvertices += 1; + out_vertex(v); +} + + +void VoronoiDiagramGenerator::deref(struct Site *v) +{ + v -> refcnt -= 1; + if (v -> refcnt == 0 ) + makefree((Freenode*)v, &sfl); +} + +void VoronoiDiagramGenerator::ref(struct Site *v) +{ + v -> refcnt += 1; +} + +//push the HalfEdge into the ordered linked list of vertices +void VoronoiDiagramGenerator::PQinsert(struct Halfedge *he,struct Site * v, double offset) +{ + struct Halfedge *last, *next; + + he -> vertex = v; + ref(v); + he -> ystar = (double)(v -> coord.y + offset); + last = &PQhash[PQbucket(he)]; + while ((next = last -> PQnext) != (struct Halfedge *) NULL && + (he -> ystar > next -> ystar || + (he -> ystar == next -> ystar && v -> coord.x > next->vertex->coord.x))) + { + last = next; + }; + he -> PQnext = last -> PQnext; + last -> PQnext = he; + PQcount += 1; +} + +//remove the HalfEdge from the list of vertices +void VoronoiDiagramGenerator::PQdelete(struct Halfedge *he) +{ + struct Halfedge *last; + + if(he -> vertex != (struct Site *) NULL) + { + last = &PQhash[PQbucket(he)]; + while (last -> PQnext != he) + last = last -> PQnext; + + last -> PQnext = he -> PQnext; + PQcount -= 1; + deref(he -> vertex); + he -> vertex = (struct Site *) NULL; + }; +} + +int VoronoiDiagramGenerator::PQbucket(struct Halfedge *he) +{ + int bucket; + + bucket = (int)((he->ystar - ymin)/deltay * PQhashsize); + if (bucket<0) bucket = 0; + if (bucket>=PQhashsize) bucket = PQhashsize-1 ; + if (bucket < PQmin) PQmin = bucket; + return(bucket); +} + + + +int VoronoiDiagramGenerator::PQempty() +{ + return(PQcount==0); +} + + +struct Point VoronoiDiagramGenerator::PQ_min() +{ + struct Point answer; + + while(PQhash[PQmin].PQnext == (struct Halfedge *)NULL) {PQmin += 1;}; + answer.x = PQhash[PQmin].PQnext -> vertex -> coord.x; + answer.y = PQhash[PQmin].PQnext -> ystar; + return (answer); +} + +struct Halfedge * VoronoiDiagramGenerator::PQextractmin() +{ + struct Halfedge *curr; + + curr = PQhash[PQmin].PQnext; + PQhash[PQmin].PQnext = curr -> PQnext; + PQcount -= 1; + return(curr); +} + + +bool VoronoiDiagramGenerator::PQinitialize() +{ + int i; + + PQcount = 0; + PQmin = 0; + PQhashsize = 4 * sqrt_nsites; + PQhash = (struct Halfedge *) myalloc(PQhashsize * sizeof *PQhash); + + if(PQhash == 0) + return false; + + for(i=0; i<PQhashsize; i+=1) PQhash[i].PQnext = (struct Halfedge *)NULL; + + return true; +} + + +void VoronoiDiagramGenerator::freeinit(struct Freelist *fl,int size) +{ + fl -> head = (struct Freenode *) NULL; + fl -> nodesize = size; +} + +char * VoronoiDiagramGenerator::getfree(struct Freelist *fl) +{ + int i; + struct Freenode *t; + + if(fl->head == (struct Freenode *) NULL) + { + t = (struct Freenode *) myalloc(sqrt_nsites * fl->nodesize); + + if(t == 0) + return 0; + + currentMemoryBlock->next = new FreeNodeArrayList; + currentMemoryBlock = currentMemoryBlock->next; + currentMemoryBlock->memory = t; + currentMemoryBlock->next = 0; + + for(i=0; i<sqrt_nsites; i+=1) + makefree((struct Freenode *)((char *)t+i*fl->nodesize), fl); + }; + t = fl -> head; + fl -> head = (fl -> head) -> nextfree; + return((char *)t); +} + + + +void VoronoiDiagramGenerator::makefree(struct Freenode *curr,struct Freelist *fl) +{ + curr -> nextfree = fl -> head; + fl -> head = curr; +} + +void VoronoiDiagramGenerator::cleanup() +{ + if(sites != 0) + { + free(sites); + sites = 0; + } + + FreeNodeArrayList* current=0, *prev = 0; + + current = prev = allMemoryList; + + while(current->next != 0) + { + prev = current; + current = current->next; + free(prev->memory); + delete prev; + prev = 0; + } + + if(current != 0 && current->memory != 0) + { + free(current->memory); + delete current; + } + + allMemoryList = new FreeNodeArrayList; + allMemoryList->next = 0; + allMemoryList->memory = 0; + currentMemoryBlock = allMemoryList; +} + +void VoronoiDiagramGenerator::cleanupEdges() +{ + GraphEdge* geCurrent = 0, *gePrev = 0; + geCurrent = gePrev = allEdges; + + while(geCurrent != 0 && geCurrent->next != 0) + { + gePrev = geCurrent; + geCurrent = geCurrent->next; + delete gePrev; + } + + allEdges = 0; + +} + +void VoronoiDiagramGenerator::cleanupEdgeList() +{ + EdgeList* elCurrent = 0, *elPrev = 0; + elCurrent = elPrev = allEdgeList; + + while (elCurrent != 0 && elCurrent->next != 0) + { + elPrev = elCurrent; + elCurrent = elCurrent->next; + delete elPrev; + } + + allEdgeList = 0; +} + +void VoronoiDiagramGenerator::pushGraphEdge(double x1, double y1, double x2, double y2) +{ + GraphEdge* newEdge = new GraphEdge; + newEdge->next = allEdges; + allEdges = newEdge; + newEdge->x1 = x1; + newEdge->y1 = y1; + newEdge->x2 = x2; + newEdge->y2 = y2; +} + +void VoronoiDiagramGenerator::pushEdgeList(Edge *e) +{ + EdgeList* newEdge = new EdgeList; + newEdge->next = allEdgeList; + allEdgeList = newEdge; + newEdge->a = e->a; + newEdge->b = e->b; + newEdge->c = e->c; + if (e->ep[0]) { + newEdge->ep0nbr = e->ep[0]->sitenbr; + newEdge->ep0x = e->ep[0]->coord.x; + newEdge->ep0y = e->ep[0]->coord.y; + } else { + newEdge->ep0nbr = -1; + } + if (e->ep[1]) { + newEdge->ep1nbr = e->ep[1]->sitenbr; + newEdge->ep1x = e->ep[1]->coord.x; + newEdge->ep1y = e->ep[1]->coord.y; + } else { + newEdge->ep1nbr = -1; + } + newEdge->reg0nbr = e->reg[0]->sitenbr; + newEdge->reg1nbr = e->reg[1]->sitenbr; + newEdge->edgenbr = e->edgenbr; +} + +char * VoronoiDiagramGenerator::myalloc(unsigned n) +{ + char *t=0; + t=(char*)malloc(n); + total_alloc += n; + return(t); +} + + +/* for those who don't have Cherry's plot */ +/* #include <plot.h> */ +void VoronoiDiagramGenerator::openpl(){} +void VoronoiDiagramGenerator::line(double x1, double y1, double x2, double y2) +{ + pushGraphEdge(x1,y1,x2,y2); + +} +void VoronoiDiagramGenerator::circle(double x, double y, double radius){} +void VoronoiDiagramGenerator::range(double minX, double minY, double maxX, double maxY){} + + + +void VoronoiDiagramGenerator::out_bisector(struct Edge *e) +{ + + +} + + +void VoronoiDiagramGenerator::out_ep(struct Edge *e) +{ + + +} + +void VoronoiDiagramGenerator::out_vertex(struct Site *v) +{ + +} + + +void VoronoiDiagramGenerator::out_site(struct Site *s) +{ + if(!triangulate & plot & !debug) + circle (s->coord.x, s->coord.y, cradius); + +} + + +void VoronoiDiagramGenerator::out_triple(struct Site *s1, struct Site *s2,struct Site * s3) +{ + +} + + + +void VoronoiDiagramGenerator::plotinit() +{ +// double dx,dy,d; +// +// dy = ymax - ymin; +// dx = xmax - xmin; +// d = (double)(( dx > dy ? dx : dy) * 1.1); +// pxmin = (double)(xmin - (d-dx)/2.0); +// pxmax = (double)(xmax + (d-dx)/2.0); +// pymin = (double)(ymin - (d-dy)/2.0); +// pymax = (double)(ymax + (d-dy)/2.0); +// cradius = (double)((pxmax - pxmin)/350.0); +// openpl(); +// range(pxmin, pymin, pxmax, pymax); +} + + +void VoronoiDiagramGenerator::clip_line(struct Edge *e) +{ +// struct Site *s1, *s2; +// double x1=0,x2=0,y1=0,y2=0; + + pushEdgeList(e); + +// x1 = e->reg[0]->coord.x; +// x2 = e->reg[1]->coord.x; +// y1 = e->reg[0]->coord.y; +// y2 = e->reg[1]->coord.y; +// +// //if the distance between the two points this line was created from is less than +// //the square root of 2, then ignore it +// if(sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))) < minDistanceBetweenSites) +// { +// return; +// } +// pxmin = borderMinX; +// pxmax = borderMaxX; +// pymin = borderMinY; +// pymax = borderMaxY; +// +// if(e -> a == 1.0 && e ->b >= 0.0) +// { +// s1 = e -> ep[1]; +// s2 = e -> ep[0]; +// } +// else +// { +// s1 = e -> ep[0]; +// s2 = e -> ep[1]; +// }; +// +// if(e -> a == 1.0) +// { +// y1 = pymin; +// if (s1!=(struct Site *)NULL && s1->coord.y > pymin) +// { +// y1 = s1->coord.y; +// } +// if(y1>pymax) +// { +// // printf("\nClipped (1) y1 = %f to %f",y1,pymax); +// y1 = pymax; +// //return; +// } +// x1 = e -> c - e -> b * y1; +// y2 = pymax; +// if (s2!=(struct Site *)NULL && s2->coord.y < pymax) +// y2 = s2->coord.y; +// +// if(y2<pymin) +// { +// //printf("\nClipped (2) y2 = %f to %f",y2,pymin); +// y2 = pymin; +// //return; +// } +// x2 = (e->c) - (e->b) * y2; +// if (((x1> pxmax) & (x2>pxmax)) | ((x1<pxmin)&(x2<pxmin))) +// { +// //printf("\nClipLine jumping out(3), x1 = %f, pxmin = %f, pxmax = %f",x1,pxmin,pxmax); +// return; +// } +// if(x1> pxmax) +// { x1 = pxmax; y1 = (e -> c - x1)/e -> b;}; +// if(x1<pxmin) +// { x1 = pxmin; y1 = (e -> c - x1)/e -> b;}; +// if(x2>pxmax) +// { x2 = pxmax; y2 = (e -> c - x2)/e -> b;}; +// if(x2<pxmin) +// { x2 = pxmin; y2 = (e -> c - x2)/e -> b;}; +// } +// else +// { +// x1 = pxmin; +// if (s1!=(struct Site *)NULL && s1->coord.x > pxmin) +// x1 = s1->coord.x; +// if(x1>pxmax) +// { +// //printf("\nClipped (3) x1 = %f to %f",x1,pxmin); +// //return; +// x1 = pxmax; +// } +// y1 = e -> c - e -> a * x1; +// x2 = pxmax; +// if (s2!=(struct Site *)NULL && s2->coord.x < pxmax) +// x2 = s2->coord.x; +// if(x2<pxmin) +// { +// //printf("\nClipped (4) x2 = %f to %f",x2,pxmin); +// //return; +// x2 = pxmin; +// } +// y2 = e -> c - e -> a * x2; +// if (((y1> pymax) & (y2>pymax)) | ((y1<pymin)&(y2<pymin))) +// { +// //printf("\nClipLine jumping out(6), y1 = %f, pymin = %f, pymax = %f",y2,pymin,pymax); +// return; +// } +// if(y1> pymax) +// { y1 = pymax; x1 = (e -> c - y1)/e -> a;}; +// if(y1<pymin) +// { y1 = pymin; x1 = (e -> c - y1)/e -> a;}; +// if(y2>pymax) +// { y2 = pymax; x2 = (e -> c - y2)/e -> a;}; +// if(y2<pymin) +// { y2 = pymin; x2 = (e -> c - y2)/e -> a;}; +// }; +// +// //printf("\nPushing line (%f,%f,%f,%f)",x1,y1,x2,y2); +// line(x1,y1,x2,y2); +} + + +/* implicit parameters: nsites, sqrt_nsites, xmin, xmax, ymin, ymax, +deltax, deltay (can all be estimates). +Performance suffers if they are wrong; better to make nsites, +deltax, and deltay too big than too small. (?) */ + +bool VoronoiDiagramGenerator::voronoi(int triangulate) +{ + struct Site *newsite, *bot, *top, *temp, *p; + struct Site *v; + struct Point newintstar; + int pm; + struct Halfedge *lbnd, *rbnd, *llbnd, *rrbnd, *bisector; + struct Edge *e; + + PQinitialize(); + bottomsite = nextone(); + out_site(bottomsite); + bool retval = ELinitialize(); + + if(!retval) + return false; + + newsite = nextone(); + while(1) + { + + if(!PQempty()) + newintstar = PQ_min(); + + //if the lowest site has a smaller y value than the lowest vector intersection, process the site + //otherwise process the vector intersection + + if (newsite != (struct Site *)NULL && (PQempty() || newsite -> coord.y < newintstar.y + || (newsite->coord.y == newintstar.y && newsite->coord.x < newintstar.x))) + {/* new site is smallest - this is a site event*/ + out_site(newsite); //output the site + lbnd = ELleftbnd(&(newsite->coord)); //get the first HalfEdge to the LEFT of the new site + rbnd = ELright(lbnd); //get the first HalfEdge to the RIGHT of the new site + bot = rightreg(lbnd); //if this halfedge has no edge, , bot = bottom site (whatever that is) + e = bisect(bot, newsite); //create a new edge that bisects + bisector = HEcreate(e, le); //create a new HalfEdge, setting its ELpm field to 0 + ELinsert(lbnd, bisector); //insert this new bisector edge between the left and right vectors in a linked list + + if ((p = intersect(lbnd, bisector)) != (struct Site *) NULL) //if the new bisector intersects with the left edge, remove the left edge's vertex, and put in the new one + { + PQdelete(lbnd); + PQinsert(lbnd, p, dist(p,newsite)); + }; + lbnd = bisector; + bisector = HEcreate(e, re); //create a new HalfEdge, setting its ELpm field to 1 + ELinsert(lbnd, bisector); //insert the new HE to the right of the original bisector earlier in the IF stmt + + if ((p = intersect(bisector, rbnd)) != (struct Site *) NULL) //if this new bisector intersects with the + { + PQinsert(bisector, p, dist(p,newsite)); //push the HE into the ordered linked list of vertices + }; + newsite = nextone(); + } + else if (!PQempty()) /* intersection is smallest - this is a vector event */ + { + lbnd = PQextractmin(); //pop the HalfEdge with the lowest vector off the ordered list of vectors + llbnd = ELleft(lbnd); //get the HalfEdge to the left of the above HE + rbnd = ELright(lbnd); //get the HalfEdge to the right of the above HE + rrbnd = ELright(rbnd); //get the HalfEdge to the right of the HE to the right of the lowest HE + bot = leftreg(lbnd); //get the Site to the left of the left HE which it bisects + top = rightreg(rbnd); //get the Site to the right of the right HE which it bisects + + out_triple(bot, top, rightreg(lbnd)); //output the triple of sites, stating that a circle goes through them + + v = lbnd->vertex; //get the vertex that caused this event + makevertex(v); //set the vertex number - couldn't do this earlier since we didn't know when it would be processed + endpoint(lbnd->ELedge,lbnd->ELpm,v); //set the endpoint of the left HalfEdge to be this vector + endpoint(rbnd->ELedge,rbnd->ELpm,v); //set the endpoint of the right HalfEdge to be this vector + ELdelete(lbnd); //mark the lowest HE for deletion - can't delete yet because there might be pointers to it in Hash Map + PQdelete(rbnd); //remove all vertex events to do with the right HE + ELdelete(rbnd); //mark the right HE for deletion - can't delete yet because there might be pointers to it in Hash Map + pm = le; //set the pm variable to zero + + if (bot->coord.y > top->coord.y) //if the site to the left of the event is higher than the Site + { //to the right of it, then swap them and set the 'pm' variable to 1 + temp = bot; + bot = top; + top = temp; + pm = re; + } + e = bisect(bot, top); //create an Edge (or line) that is between the two Sites. This creates + //the formula of the line, and assigns a line number to it + bisector = HEcreate(e, pm); //create a HE from the Edge 'e', and make it point to that edge with its ELedge field + ELinsert(llbnd, bisector); //insert the new bisector to the right of the left HE + endpoint(e, re-pm, v); //set one endpoint to the new edge to be the vector point 'v'. + //If the site to the left of this bisector is higher than the right + //Site, then this endpoint is put in position 0; otherwise in pos 1 + deref(v); //delete the vector 'v' + + //if left HE and the new bisector don't intersect, then delete the left HE, and reinsert it + if((p = intersect(llbnd, bisector)) != (struct Site *) NULL) + { + PQdelete(llbnd); + PQinsert(llbnd, p, dist(p,bot)); + }; + + //if right HE and the new bisector don't intersect, then reinsert it + if ((p = intersect(bisector, rrbnd)) != (struct Site *) NULL) + { + PQinsert(bisector, p, dist(p,bot)); + }; + } + else break; + }; + + + + + for(lbnd=ELright(ELleftend); lbnd != ELrightend; lbnd=ELright(lbnd)) + { + e = lbnd -> ELedge; + + clip_line(e); + + }; + + cleanup(); + + return true; + +} + + +int scomp(const void *p1,const void *p2) +{ + struct Point *s1 = (Point*)p1, *s2=(Point*)p2; + if(s1 -> y < s2 -> y) return(-1); + if(s1 -> y > s2 -> y) return(1); + if(s1 -> x < s2 -> x) return(-1); + if(s1 -> x > s2 -> x) return(1); + return(0); +} + +/* return a single in-storage site */ +struct Site * VoronoiDiagramGenerator::nextone() +{ + struct Site *s; + if(siteidx < nsites) + { + s = &sites[siteidx]; + siteidx += 1; + return(s); + } + else + return( (struct Site *)NULL); +} + +bool VoronoiDiagramGenerator::getNextDelaunay(int& ep0, double& ep0x, double& ep0y, + int& ep1, double& ep1x, double& ep1y, + int& reg0, int& reg1) +{ + if (iterEdgeList == 0) + return false; + + ep0 = iterEdgeList->ep0nbr; + ep0x = iterEdgeList->ep0x; + ep0y = iterEdgeList->ep0y; + ep1 = iterEdgeList->ep1nbr; + ep1x = iterEdgeList->ep1x; + ep1y = iterEdgeList->ep1y; + reg0 = iterEdgeList->reg0nbr; + reg1 = iterEdgeList->reg1nbr; + + iterEdgeList = iterEdgeList->next; + + return true; +} + +//PyObject* VoronoiDiagramGenerator::_getMesh() +//{ +// PyObject *vlist, *dlist, *tlist; +// PyObject *temp, *faces, *face; +// int tri0, tri1, reg0, reg1; +// double tri0x, tri0y, tri1x, tri1y; +// int length, numtri, i; +// +// length = nedges; +// numtri = nvertices; +// +// dlist = PyList_New(length); +// if (!dlist) goto fail; +// vlist = PyList_New(numtri); +// if (!vlist) goto fail; +// tlist = PyList_New(numtri); +// if (!tlist) goto fail; +// +// for (i=0; i<numtri; i++) { +// faces = PyList_New(0); +// if (!faces) goto fail; +// PyList_SET_ITEM(tlist, i, faces); +// } +// +// resetEdgeListIter(); +// i = -1; +// while (getNextDelaunay(tri0, tri0x, tri0y, tri1, tri1x, tri1y, reg0, reg1)) { +// i++; +// face = Py_BuildValue("(ii)", reg0, reg1); +// if (!face) goto fail; +// PyList_SET_ITEM(dlist, i, face); +// if (tri0 > -1) { +// temp = PyList_GET_ITEM(vlist, tri0); +// if (!temp) { +// temp = Py_BuildValue("(dd)", tri0x, tri0y); +// PyList_SET_ITEM(vlist, tri0, temp); +// } +// faces = PyList_GET_ITEM(tlist, tri0); +// if (PyList_Append(faces, face) < 0) goto fail; +// } +// if (tri1 > -1) { +// temp = PyList_GET_ITEM(vlist, tri1); +// if (!temp) { +// temp = Py_BuildValue("(dd)", tri1x, tri1y); +// PyList_SET_ITEM(vlist, tri1, temp); +// } +// faces = PyList_GET_ITEM(tlist, tri1); +// if (PyList_Append(faces, face) < 0) goto fail; +// } +// } +// +// temp = PyTuple_Pack(3, vlist, dlist, tlist); +// if (!temp) goto fail; +// +// Py_DECREF(vlist); +// Py_DECREF(dlist); +// Py_DECREF(tlist); +// +// return temp; +// +//fail: +// Py_XDECREF(vlist); +// Py_XDECREF(dlist); +// Py_XDECREF(temp); +// Py_XDECREF(faces); +// Py_XDECREF(face); +// return NULL; +//} + + Added: trunk/matplotlib/lib/matplotlib/delaunay/VoronoiDiagramGenerator.h =================================================================== --- trunk/matplotlib/lib/matplotlib/delaunay/VoronoiDiagramGenerator.h (rev 0) +++ trunk/matplotlib/lib/matplotlib/delaunay/VoronoiDiagramGenerator.h 2008年07月22日 01:52:12 UTC (rev 5805) @@ -0,0 +1,283 @@ +/* +* 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. +*/ + +#ifndef VORONOI_DIAGRAM_GENERATOR +#define VORONOI_DIAGRAM_GENERATOR + +#include "Python.h" +#include "numpy/arrayobject.h" + +#include <math.h> +#include <stdlib.h> +#include <string.h> +#include <iostream> + + +#ifndef NULL +#define NULL 0 +#endif +#define DELETED -2 + +#define le 0 +#define re 1 + +#ifndef MAX +#define MAX(x, y) (x > y ? x: y) +#endif + +struct Freenode +{ + struct Freenode *nextfree; +}; + +struct FreeNodeArrayList +{ + struct Freenode* memory; + struct FreeNodeArrayList* next; + +}; + +struct Freelist +{ + struct Freenode *head; + int nodesize; +}; + +struct Point +{ + double x,y; +}; + +// structure used both for sites and for vertices +struct Site +{ + struct Point coord; + int sitenbr; + int refcnt; +}; + + + +struct Edge +{ + double a,b,c; + struct Site *ep[2]; + struct Site *reg[2]; + int edgenbr; +}; + +struct EdgeList +{ + double a,b,c; + int ep0nbr; + double ep0x, ep0y; + int ep1nbr; + double ep1x, ep1y; + int reg0nbr; + int reg1nbr; + int edgenbr; + struct EdgeList *next; +}; + +struct GraphEdge +{ + double x1,y1,x2,y2; + struct GraphEdge* next; +}; + + + + +struct Halfedge +{ + struct Halfedge *ELleft, *ELright; + struct Edge *ELedge; + int ELrefcnt; + char ELpm; + struct Site *vertex; + double ystar; + struct Halfedge *PQnext; +}; + + + + +class VoronoiDiagramGenerator +{ +public: + VoronoiDiagramGenerator(); + ~VoronoiDiagramGenerator(); + + bool generateVoronoi(double *xValues, double *yValues, int numPoints, double minX, double maxX, double minY, double maxY, double minDist=0); + + void resetIterator() + { + iteratorEdges = allEdges; + } + + bool getNext(double& x1, double& y1, double& x2, double& y2) + { + if(iteratorEdges == 0) + return false; + + x1 = iteratorEdges->x1; + x2 = iteratorEdges->x2; + y1 = iteratorEdges->y1; + y2 = iteratorEdges->y2; + + iteratorEdges = iteratorEdges->next; + + return true; + } + + void resetEdgeListIter() + { + iterEdgeList = allEdgeList; + } + + bool getNextDelaunay(int& ep0, double& ep0x, double& ep0y, + int& ep1, double& ep1x, double& ep1y, + int& reg0, int& reg1); + + void getNumbers(int& edges, int& vertices) { + edges = nedges; + vertices = nvertices; + } + +private: + void cleanup(); + void cleanupEdgeList(); + void cleanupEdges(); + char *getfree(struct Freelist *fl); + struct Halfedge *PQfind(); + int PQempty(); + + + struct Halfedge **ELhash; + struct Halfedge *HEcreate(), *ELleft(), *ELright(), *ELleftbnd(); + struct Halfedge *HEcreate(struct Edge *e,int pm); + + + struct Point PQ_min(); + struct Halfedge *PQextractmin(); + void freeinit(struct Freelist *fl,int size); + void makefree(struct Freenode *curr,struct Freelist *fl); + void geominit(); + void plotinit(); + bool voronoi(int triangulate); + void ref(struct Site *v); + void deref(struct Site *v); + void endpoint(struct Edge *e,int lr,struct Site * s); + + void ELdelete(struct Halfedge *he); + struct Halfedge *ELleftbnd(struct Point *p); + struct Halfedge *ELright(struct Halfedge *he); + void makevertex(struct Site *v); + void out_triple(struct Site *s1, struct Site *s2,struct Site * s3); + + void PQinsert(struct Halfedge *he,struct Site * v, double offset); + void PQdelete(struct Halfedge *he); + bool ELinitialize(); + void ELinsert(struct Halfedge *lb, struct Halfedge *newHe); + struct Halfedge *ELgethash(int b); + struct Halfedge *ELleft(struct Halfedge *he); + struct Site *leftreg(struct Halfedge *he); + void out_site(struct Site *s); + bool PQinitialize(); + int PQbucket(struct Halfedge *he); + void clip_line(struct Edge *e); + char *myalloc(unsigned n); + int right_of(struct Halfedge *el,struct Point *p); + + struct Site *rightreg(struct Halfedge *he); + struct Edge *bisect(struct Site *s1, struct Site *s2); + double dist(struct Site *s,struct Site *t); + struct Site *intersect(struct Halfedge *el1, struct Halfedge *el2, struct Point *p=0); + + void out_bisector(struct Edge *e); + void out_ep(struct Edge *e); + void out_vertex(struct Site *v); + struct Site *nextone(); + + void pushGraphEdge(double x1, double y1, double x2, double y2); + void pushEdgeList(Edge *e); + + void openpl(); + void line(double x1, double y1, double x2, double y2); + void circle(double x, double y, double radius); + void range(double minX, double minY, double maxX, double maxY); + + + struct Freelist hfl; + struct Halfedge *ELleftend, *ELrightend; + int ELhashsize; + + int triangulate, sorted, plot, debug; + double xmin, xmax, ymin, ymax, deltax, deltay; + + struct Site *sites; + int nsites; + int siteidx; + int sqrt_nsites; + int nvertices; + struct Freelist sfl; + struct Site *bottomsite; + + int nedges; + struct Freelist efl; + int PQhashsize; + struct Halfedge *PQhash; + int PQcount; + int PQmin; + + int ntry, totalsearch; + double pxmin, pxmax, pymin, pymax, cradius; + int total_alloc; + + double borderMinX, borderMaxX, borderMinY, borderMaxY; + + FreeNodeArrayList* allMemoryList; + FreeNodeArrayList* currentMemoryBlock; + + GraphEdge* allEdges; + GraphEdge* iteratorEdges; + + EdgeList* allEdgeList; + EdgeList* iterEdgeList; + + double minDistanceBetweenSites; + +}; + +int scomp(const void *p1, const void *p2); + + +#endif + + Added: trunk/matplotlib/lib/matplotlib/delaunay/__init__.py =================================================================== --- trunk/matplotlib/lib/matplotlib/delaunay/__init__.py (rev 0) +++ trunk/matplotlib/lib/matplotlib/delaunay/__init__.py 2008年07月22日 01:52:12 UTC (rev 5805) @@ -0,0 +1,10 @@ +"""Delaunay triangulation and interpolation tools. + +:Author: Robert Kern <rob...@gm...> +:Copyright: Copyright 2005 Robert Kern. +:License: BSD-style license. See LICENSE.txt in the scipy source directory. +""" + +from matplotlib._delaunay import delaunay +from triangulate import * +from interpolate import * Added: trunk/matplotlib/lib/matplotlib/delaunay/_delaunay.cpp =================================================================== --- trunk/matplotlib/lib/matplotlib/delaunay/_delaunay.cpp (rev 0) +++ trunk/matplotlib/lib/matplotlib/delaunay/_delaunay.cpp 2008年07月22日 01:52:12 UTC (rev 5805) @@ -0,0 +1,741 @@ +#include "Python.h" +#include <stdlib.h> +#include <map> +#include <iostream> + +#include "VoronoiDiagramGenerator.h" +#include "delaunay_utils.h" +#include "natneighbors.h" +#include "numpy/noprefix.h" + +using namespace std; + +extern "C" { + +static void reorder_edges(int npoints, int ntriangles, + double *x, double *y, + int *edge_db, int *tri_edges, int *tri_nbrs) +{ + int neighbors[3], nodes[3]; + int i, tmp; + int case1, case2; + + for (i=0; i<ntriangles; i++) { + nodes[0] = INDEX2(edge_db, INDEX3(tri_edges,i,0), 0); + nodes[1] = INDEX2(edge_db, INDEX3(tri_edges,i,0), 1); + tmp = INDEX2(edge_db, INDEX3(tri_edges,i,1), 0); + if (tmp == nodes[0]) { + case1 = 1; + nodes[2] = INDEX2(edge_db, INDEX3(tri_edges,i,1), 1); + } else if (tmp == nodes[1]) { + case1 = 0; + nodes[2] = INDEX2(edge_db, INDEX3(tri_edges,i,1), 1); + } else if (INDEX2(edge_db, INDEX3(tri_edges,i,1), 1) == nodes[0]) { + case1 = 1; + nodes[2] = tmp; + } else { + case1 = 0; + nodes[2] = tmp; + } + + if (ONRIGHT(x[nodes[0]], y[nodes[0]], + x[nodes[1]], y[nodes[1]], + x[nodes[2]], y[nodes[2]])) { + // flip to make counter-clockwise + tmp = nodes[2]; + nodes[2] = nodes[1]; + nodes[1] = tmp; + case2 = 1; + } else case2 = 0; + + // I worked it out on paper. You're just gonna have to trust me on this. + if (!case1 && !case2) { + neighbors[0] = INDEX3(tri_nbrs, i, 1); + neighbors[1] = INDEX3(tri_nbrs, i, 2); + neighbors[2] = INDEX3(tri_nbrs, i, 0); + } else if (case1 && !case2) { + neighbors[0] = INDEX3(tri_nbrs, i, 2); + neighbors[1] = INDEX3(tri_nbrs, i, 1); + neighbors[2] = INDEX3(tri_nbrs, i, 0); + } else if (!case1 && case2) { + neighbors[0] = INDEX3(tri_nbrs, i, 1); + neighbors[1] = INDEX3(tri_nbrs, i, 0); + neighbors[2] = INDEX3(tri_nbrs, i, 2); + } else { + neighbors[0] = INDEX3(tri_nbrs, i, 2); + neighbors[1] = INDEX3(tri_nbrs, i, 0); + neighbors[2] = INDEX3(tri_nbrs, i, 1); + } + + // Not trusting me? Okay, let's go through it: + // We have three edges to deal with and three nodes. Without loss + // of generality, let's label the nodes A, B, and C with (A, B) + // forming the first edge in the order they arrive on input. + // Then there are eight possibilities as to how the other edge-tuples + // may be labeled, but only two variations that are going to affect the + // output: + // + // AB AB + // BC (CB) AC (CA) + // CA (AC) BC (CB) + // + // The distinction is whether A is in the second edge or B is. + // This is the test "case1" above. + // + // The second test we need to perform is for counter-clockwiseness. + // Again, there are only two variations that will affect the outcome: + // either ABC is counter-clockwise, or it isn't. In the former case, + // we're done setting the node order, we just need to associate the + // appropriate neighbor triangles with their opposite nodes, something + // which can be done by inspection. In the latter case, to order the + // nodes counter-clockwise, we only have to switch B and C to get + // nodes ACB. Then we simply set the neighbor list by inspection again. + // + // CCW CW + // AB + // BC 120 102 -+ + // CA | + // +- neighbor order + // AB | + // AC 210 201 -+ + // BC + // ABC ACB -+- node order + + + INDEX3(tri_edges,i,0) = nodes[0]; + INDEX3(tri_edges,i,1) = nodes[1]; + INDEX3(tri_edges,i,2) = nodes[2]; + INDEX3(tri_nbrs,i,0) = neighbors[0]; + INDEX3(tri_nbrs,i,1) = neighbors[1]; + INDEX3(tri_nbrs,i,2) = neighbors[2]; + } +} + +static PyObject* getMesh(int npoints, double *x, double *y) +{ + PyObject *vertices, *edge_db, *tri_edges, *tri_nbrs; + PyObject *temp; + int tri0, tri1, reg0, reg1; + double tri0x, tri0y, tri1x, tri1y; + int length, numtri, i, j; + intp dim[MAX_DIMS]; + int *edge_db_ptr, *tri_edges_ptr, *tri_nbrs_ptr; + double *vertices_ptr; + VoronoiDiagramGenerator vdg; + + vdg.generateVoronoi(x, y, npoints, -100, 100, -100, 100, 0); + vdg.getNumbers(length, numtri); + + // Count the actual number of edges + i = 0; + vdg.resetEdgeListIter(); + while (vdg.getNextDelaunay(tri0, tri0x, tri0y, tri1, tri1x, tri1y, reg0, reg1)) + i++; + length = i; + + dim[0] = length; + dim[1] = 2; + edge_db = PyArray_SimpleNew(2, dim, PyArray_INT); + if (!edge_db) goto fail; + edge_db_ptr = (int*)PyArray_DATA(edge_db); + + dim[0] = numtri; + vertices = PyArray_SimpleNew(2, dim, PyArray_DOUBLE); + if (!vertices) goto fail; + vertices_ptr = (double*)PyArray_DATA(vertices); + + dim[1] = 3; + tri_edges = PyArray_SimpleNew(2, dim, PyArray_INT); + if (!tri_edges) goto fail; + tri_edges_ptr = (int*)PyArray_DATA(tri_edges); + + tri_nbrs = PyArray_SimpleNew(2, dim, PyArray_INT); + if (!tri_nbrs) goto fail; + tri_nbrs_ptr = (int*)PyArray_DATA(tri_nbrs); + + for (i=0; i<(3*numtri); i++) { + tri_edges_ptr[i] = tri_nbrs_ptr[i] = -1; + } + + vdg.resetEdgeListIter(); + i = -1; + while (vdg.getNextDelaunay(tri0, tri0x, tri0y, tri1, tri1x, tri1y, reg0, reg1)) { + i++; + INDEX2(edge_db_ptr,i,0) = reg0; + INDEX2(edge_db_ptr,i,1) = reg1; + if (tri0 > -1) { + INDEX2(vertices_ptr,tri0,0) = tri0x; + INDEX2(vertices_ptr,tri0,1) = tri0y; + for (j=0; j<3; j++) { + if (INDEX3(tri_edges_ptr,tri0,j) == i) break; + if (INDEX3(tri_edges_ptr,tri0,j) == -1) { + INDEX3(tri_edges_ptr,tri0,j) = i; + INDEX3(tri_nbrs_ptr,tri0,j) = tri1; + break; + } + } + } + if (tri1 > -1) { + INDEX2(vertices_ptr,tri1,0) = tri1x; + INDEX2(vertices_ptr,tri1,1) = tri1y; + for (j=0; j<3; j++) { + if (INDEX3(tri_edges_ptr,tri1,j) == i) break; + if (INDEX3(tri_edges_ptr,tri1,j) == -1) { + INDEX3(tri_edges_ptr,tri1,j) = i; + INDEX3(tri_nbrs_ptr,tri1,j) = tri0; + break; + } + } + } + } + + // tri_edges contains lists of edges; convert to lists of nodes in + // counterclockwise order and reorder tri_nbrs to match. Each node + // corresponds to the edge opposite it in the triangle. + reorder_edges(npoints, numtri, x, y, edge_db_ptr, tri_edges_ptr, + tri_nbrs_ptr); + + temp = Py_BuildValue("(OOOO)", vertices, edge_db, tri_edges, tri_nbrs); + if (!temp) goto fail; + + Py_DECREF(vertices); + Py_DECREF(edge_db); + Py_DECREF(tri_edges); + Py_DECREF(tri_nbrs); + + return temp; + +fail: + Py_XDECREF(vertices); + Py_XDECREF(edge_db); + Py_XDECREF(tri_edges); + Py_XDECREF(tri_nbrs); + return NULL; +} + +static PyObject *linear_planes(int ntriangles, double *x, double *y, double *z, + int *nodes) +{ + intp dims[2]; + PyObject *planes; + int i; + double *planes_ptr; + double x02, y02, z02, x12, y12, z12, xy0212; + + dims[0] = ntriangles; + dims[1] = 3; + planes = PyArray_SimpleNew(2, dims, PyArray_DOUBLE); + if (!planes) return NULL; + planes_ptr = (double *)PyArray_DATA(planes); + + for (i=0; i<ntriangles; i++) { + x02 = x[INDEX3(nodes,i,0)] - x[INDEX3(nodes,i,2)]; + y02 = y[INDEX3(nodes,i,0)] - y[INDEX3(nodes,i,2)]; + z02 = z[INDEX3(nodes,i,0)] - z[INDEX3(nodes,i,2)]; + x12 = x[INDEX3(nodes,i,1)] - x[INDEX3(nodes,i,2)]; + y12 = y[INDEX3(nodes,i,1)] - y[INDEX3(nodes,i,2)]; + z12 = z[INDEX3(nodes,i,1)] - z[INDEX3(nodes,i,2)]; + + if (y12 != 0.0) { + xy0212 = y02/y12; + INDEX3(planes_ptr,i,0) = (z02 - z12 * xy0212) / (x02 - x12 * xy0212); + INDEX3(planes_ptr,i,1) = (z12 - INDEX3(planes_ptr,i,0)*x12) / y12; + INDEX3(planes_ptr,i,2) = (z[INDEX3(nodes,i,2)] - + INDEX3(planes_ptr,i,0)*x[INDEX3(nodes,i,2)] - + INDEX3(planes_ptr,i,1)*y[INDEX3(nodes,i,2)]); + } else { + xy0212 = x02/x12; + INDEX3(planes_ptr,i,1) = (z02 - z12 * xy0212) / (y02 - y12 * xy0212); + INDEX3(planes_ptr,i,0) = (z12 - INDEX3(planes_ptr,i,1)*y12) / x12; + INDEX3(planes_ptr,i,2) = (z[INDEX3(nodes,i,2)] - + INDEX3(planes_ptr,i,0)*x[INDEX3(nodes,i,2)] - + INDEX3(planes_ptr,i,1)*y[INDEX3(nodes,i,2)]); + } + } + + return (PyObject*)planes; +} + +static double linear_interpolate_single(double targetx, double targety, + double *x, double *y, int *nodes, int *neighbors, + PyObject *planes, double defvalue, int start_triangle, int *end_triangle) +{ + double *planes_ptr; + planes_ptr = (double*)PyArray_DATA(planes); + if (start_triangle == -1) start_triangle = 0; + *end_triangle = walking_triangles(start_triangle, targetx, targety, + x, y, nodes, neighbors); + if (*end_triangle == -1) return defvalue; + return (targetx*INDEX3(planes_ptr,*end_triangle,0) + + targety*INDEX3(planes_ptr,*end_triangle,1) + + INDEX3(planes_ptr,*end_triangle,2)); +} + +static PyObject *linear_interpolate_grid(double x0, double x1, int xsteps, + double y0, double y1, int ysteps, + PyObject *planes, double defvalue, + int npoints, double *x, double *y, int *nodes, int *neighbors) +{ + int ix, iy; + double dx, dy, targetx, targety; + int rowtri, coltri, tri; + PyObject *z; + double *z_ptr; + intp dims[2]; + + dims[0] = ysteps; + dims[1] = xsteps; + z = PyArray_SimpleNew(2, dims, PyArray_DOUBLE); + if (!z) return NULL; + z_ptr = (double*)PyArray_DATA(z); + + dx = (x1 - x0) / (xsteps-1); + dy = (y1 - y0) / (ysteps-1); + + rowtri = 0; + for (iy=0; iy<ysteps; iy++) { + targety = y0 + dy*iy; + rowtri = walking_triangles(rowtri, x0, targety, x, y, nodes, neighbors); + tri = rowtri; + for (ix=0; ix<xsteps; ix++) { + targetx = x0 + dx*ix; + INDEXN(z_ptr, xsteps, iy, ix) = linear_interpolate_single( + targetx, targety, + x, y, nodes, neighbors, planes, defvalue, tri, &coltri); + if (coltri != -1) tri = coltri; + } + } + + return z; +} + +static PyObject *compute_planes_method(PyObject *self, PyObject *args) +{ + PyObject *pyx, *pyy, *pyz, *pynodes; + PyObject *x, *y, *z, *nodes; + int npoints, ntriangles; + + PyObject *planes; + + if (!PyArg_ParseTuple(args, "OOOO", &pyx, &pyy, &pyz, &pynodes)) { + return NULL; + } + x = PyArray_FROMANY(pyx, PyArray_DOUBLE, 1, 1, NPY_IN_ARRAY); + if (!x) { + PyErr_SetString(PyExc_ValueError, "x must be a 1-D array of floats"); + goto fail; + } + y = PyArray_FROMANY(pyy, PyArray_DOUBLE, 1, 1, NPY_IN_ARRAY); + if (!y) { + PyErr_SetString(PyExc_ValueError, "y must be a 1-D array of floats"); + goto fail; + } + z = PyArray_FROMANY(pyz, PyArray_DOUBLE, 1, 1, NPY_IN_ARRAY); + if (!z) { + PyErr_SetString(PyExc_ValueError, "z must be a 1-D array of floats"); + goto fail; + } + npoints = PyArray_DIM(x, 0); + if ((PyArray_DIM(y, 0) != npoints) || (PyArray_DIM(z, 0) != npoints)) { + PyErr_SetString(PyExc_ValueError, "x,y,z arrays must be of equal length"); + goto fail; + } + nodes = PyArray_FROMANY(pynodes, PyA... [truncated message content]
Revision: 5804 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5804&view=rev Author: mdboom Date: 2008年07月21日 22:42:52 +0000 (2008年7月21日) Log Message: ----------- Re-introduce offset_copy Modified Paths: -------------- trunk/matplotlib/API_CHANGES trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/transforms.py Modified: trunk/matplotlib/API_CHANGES =================================================================== --- trunk/matplotlib/API_CHANGES 2008年07月21日 19:39:12 UTC (rev 5803) +++ trunk/matplotlib/API_CHANGES 2008年07月21日 22:42:52 UTC (rev 5804) @@ -130,8 +130,6 @@ Transform.inverse_xy_tup(points) Transform.inverted().transform(points) - offset_copy(trans, x, y) trans + Affine2D().translate(x, y) - axes.py Axes.get_position() Axes.get_position() [Axes.get_position() used to return a list of points, not it Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2008年07月21日 19:39:12 UTC (rev 5803) +++ trunk/matplotlib/CHANGELOG 2008年07月21日 22:42:52 UTC (rev 5804) @@ -1,3 +1,6 @@ +2008年07月21日 Re-introduced offset_copy that works in the context of the + new transforms. - MGD + 2008年07月21日 Committed patch by Ryan May to add get_offsets and set_offsets to Collections base class - EF Modified: trunk/matplotlib/lib/matplotlib/transforms.py =================================================================== --- trunk/matplotlib/lib/matplotlib/transforms.py 2008年07月21日 19:39:12 UTC (rev 5803) +++ trunk/matplotlib/lib/matplotlib/transforms.py 2008年07月21日 22:42:52 UTC (rev 5804) @@ -2144,6 +2144,27 @@ ((a < b) and (a < val and b > val)) or (b < val and a > val)) +def offset_copy(trans, fig, x=0.0, y=0.0, units='inches'): + ''' + Return a new transform with an added offset. + args: + trans is any transform + kwargs: + fig is the current figure; it can be None if units are 'dots' + x, y give the offset + units is 'inches', 'points' or 'dots' + ''' + if units == 'dots': + return trans + Affine2D().translate(x, y) + if fig is None: + raise ValueError('For units of inches or points a fig kwarg is needed') + if units == 'points': + x /= 72.0 + y /= 72.0 + elif not units == 'inches': + raise ValueError('units must be dots, points, or inches') + return trans + ScaledTranslation(x, y, fig.dpi_scale_trans) + if __name__ == '__main__': import copy from random import random This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5803 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5803&view=rev Author: efiring Date: 2008年07月21日 19:39:12 +0000 (2008年7月21日) Log Message: ----------- Add get_offsets, set_offsets to Collection (Ryan Kraus) Modified Paths: -------------- trunk/matplotlib/API_CHANGES trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/collections.py Modified: trunk/matplotlib/API_CHANGES =================================================================== --- trunk/matplotlib/API_CHANGES 2008年07月21日 19:08:29 UTC (rev 5802) +++ trunk/matplotlib/API_CHANGES 2008年07月21日 19:39:12 UTC (rev 5803) @@ -1,6 +1,9 @@ Changes for 0.98.x ================== +* Methods get_offsets and set_offsets added to Collections base + class. + * Figure.figurePatch renamed Figure.patch, Axes.axesPatch renamed Axes.patch, Axes.axesFrame renamed Axes.frame, Axes.get_frame, which returns Axes.patch, is deprecated. Examples and users guide updated Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2008年07月21日 19:08:29 UTC (rev 5802) +++ trunk/matplotlib/CHANGELOG 2008年07月21日 19:39:12 UTC (rev 5803) @@ -1,3 +1,6 @@ +2008年07月21日 Committed patch by Ryan May to add get_offsets and + set_offsets to Collections base class - EF + 2008年07月21日 Changed the "asarray" strategy in image.py so that colormapping of masked input should work for all image types (thanks Klaus Zimmerman) - EF Modified: trunk/matplotlib/lib/matplotlib/collections.py =================================================================== --- trunk/matplotlib/lib/matplotlib/collections.py 2008年07月21日 19:08:29 UTC (rev 5802) +++ trunk/matplotlib/lib/matplotlib/collections.py 2008年07月21日 19:39:12 UTC (rev 5803) @@ -218,6 +218,32 @@ def set_pickradius(self,pickradius): self.pickradius = 5 def get_pickradius(self): return self.pickradius + def set_offsets(self, offsets): + """ + Set the offsets for the collection. *offsets* can be a scalar + or a sequence. + + ACCEPTS: float or sequence of floats + """ + offsets = np.asarray(offsets, np.float_) + if len(offsets.shape) == 1: + offsets = offsets[np.newaxis,:] # Make it Nx2. + #This decision is based on how they are initialized above + if self._uniform_offsets is None: + self._offsets = offsets + else: + self._uniform_offsets = offsets + + def get_offsets(self): + """ + Return the offsets for the collection. + """ + #This decision is based on how they are initialized above in __init__() + if self._uniform_offsets is None: + return self._offsets + else: + return self._uniform_offsets + def set_linewidths(self, lw): """ Set the linewidth(s) for the collection. *lw* can be a scalar This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5802 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5802&view=rev Author: efiring Date: 2008年07月21日 19:08:29 +0000 (2008年7月21日) Log Message: ----------- In image.py, ensure input can be ndarray or MaskedArray (Klaus Zimmerman). Masked 2-D arrays are handled automatically by the color mapping framework, so they need to be passed through; but there is no point in converting 3-D arrays into masked arrays because there is no support for dealing with a mask in that case. Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/image.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2008年07月21日 12:58:53 UTC (rev 5801) +++ trunk/matplotlib/CHANGELOG 2008年07月21日 19:08:29 UTC (rev 5802) @@ -1,3 +1,7 @@ +2008年07月21日 Changed the "asarray" strategy in image.py so that + colormapping of masked input should work for all + image types (thanks Klaus Zimmerman) - EF + 2008年07月20日 Rewrote cbook.delete_masked_points and corresponding unit test to support rgb color array inputs, datetime inputs, etc. - EF Modified: trunk/matplotlib/lib/matplotlib/image.py =================================================================== --- trunk/matplotlib/lib/matplotlib/image.py 2008年07月21日 12:58:53 UTC (rev 5801) +++ trunk/matplotlib/lib/matplotlib/image.py 2008年07月21日 19:08:29 UTC (rev 5802) @@ -272,10 +272,11 @@ ACCEPTS: numpy/PIL Image A""" # check if data is PIL Image without importing Image if hasattr(A,'getpixel'): - X = pil_to_array(A) + self._A = pil_to_array(A) + elif ma.isMA(A): + self._A = A else: - X = ma.asarray(A) # assume array - self._A = X + self._A = np.asarray(A) # assume array self._imcache =None self._rgbacache = None @@ -408,7 +409,8 @@ def set_data(self, x, y, A): x = np.asarray(x,np.float32) y = np.asarray(y,np.float32) - A = np.asarray(A) + if not ma.isMA(A): + A = np.asarray(A) if len(x.shape) != 1 or len(y.shape) != 1\ or A.shape[0:2] != (y.shape[0], x.shape[0]): raise TypeError("Axes don't match array shape") @@ -535,7 +537,8 @@ def set_data(self, x, y, A): - A = ma.asarray(A) + if not ma.isMA(A): + A = np.asarray(A) if x is None: x = np.arange(0, A.shape[1]+1, dtype=np.float64) else: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5801 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5801&view=rev Author: dmkaplan Date: 2008年07月21日 12:58:53 +0000 (2008年7月21日) Log Message: ----------- Fixing minor documentation problems in contour.py Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/contour.py Modified: trunk/matplotlib/lib/matplotlib/contour.py =================================================================== --- trunk/matplotlib/lib/matplotlib/contour.py 2008年07月21日 12:55:42 UTC (rev 5800) +++ trunk/matplotlib/lib/matplotlib/contour.py 2008年07月21日 12:58:53 UTC (rev 5801) @@ -85,7 +85,7 @@ """ - """" + """ NOTES on how this all works: clabel basically takes the input arguments and uses them to @@ -103,7 +103,7 @@ Once these attributes are set, clabel passes control to the labels method (case of automatic label placement) or - BlockingContourLabeler (case of manual label placement. + BlockingContourLabeler (case of manual label placement). """ fontsize = kwargs.get('fontsize', None) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5800 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5800&view=rev Author: dmkaplan Date: 2008年07月21日 12:55:42 +0000 (2008年7月21日) Log Message: ----------- Minor ginput_manual_clabel.py changes Modified Paths: -------------- trunk/matplotlib/examples/pylab_examples/ginput_manual_clabel.py Modified: trunk/matplotlib/examples/pylab_examples/ginput_manual_clabel.py =================================================================== --- trunk/matplotlib/examples/pylab_examples/ginput_manual_clabel.py 2008年07月21日 12:26:35 UTC (rev 5799) +++ trunk/matplotlib/examples/pylab_examples/ginput_manual_clabel.py 2008年07月21日 12:55:42 UTC (rev 5800) @@ -4,8 +4,10 @@ waitforbuttonpress and manual clabel placement. This script must be run interactively using a backend that has a -graphical user interface (for example, from inside ipython using -GTKAgg backend, but not PS backend). +graphical user interface (for example, using GTKAgg backend, but not +PS backend). + +See also ginput_demo.py """ import time import matplotlib @@ -86,3 +88,6 @@ pts = np.sort(pts,axis=0) plt.axis( pts.T.ravel() ) + +tellme('All Done!') +plt.show() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5799 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5799&view=rev Author: dmkaplan Date: 2008年07月21日 12:26:35 +0000 (2008年7月21日) Log Message: ----------- Recommitting my changes to clabel to allow for manual labeling after fixing problems with indexing identified by Eric Firing on 19 July 2008. In addition, I have made the following changes: 1) Placed more comments in contour.py with the intention of eventually doing a rewrite or restructuring of that code. 2) Added two pylab_examples: contour_label_demo.py that tests out some of the more advanced things that can now be done with contour labeling, and ginput_manual_clabel.py that demonstrates some uses of ginput, waitforbuttonpress, and clabel(...,manual=True). The first of these has been integrated into backend_driver.py, but the second cannot be because it requires interaction. Modified Paths: -------------- trunk/matplotlib/examples/tests/backend_driver.py trunk/matplotlib/lib/matplotlib/blocking_input.py trunk/matplotlib/lib/matplotlib/contour.py Added Paths: ----------- trunk/matplotlib/examples/pylab_examples/contour_label_demo.py trunk/matplotlib/examples/pylab_examples/ginput_manual_clabel.py Added: trunk/matplotlib/examples/pylab_examples/contour_label_demo.py =================================================================== --- trunk/matplotlib/examples/pylab_examples/contour_label_demo.py (rev 0) +++ trunk/matplotlib/examples/pylab_examples/contour_label_demo.py 2008年07月21日 12:26:35 UTC (rev 5799) @@ -0,0 +1,74 @@ +#!/usr/bin/env python +""" +Illustrate some of the more advanced things that one can do with +contour labels. + +See also contour_demo.py. +""" +import matplotlib +import numpy as np +import matplotlib.cm as cm +import matplotlib.mlab as mlab +import matplotlib.pyplot as plt + +matplotlib.rcParams['xtick.direction'] = 'out' +matplotlib.rcParams['ytick.direction'] = 'out' + +################################################## +# Define our surface +################################################## +delta = 0.025 +x = np.arange(-3.0, 3.0, delta) +y = np.arange(-2.0, 2.0, delta) +X, Y = np.meshgrid(x, y) +Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) +Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1) +# difference of Gaussians +Z = 10.0 * (Z2 - Z1) + +################################################## +# Make contour labels using creative float classes +# Follows suggestion of Manuel Metz +################################################## +plt.figure() + +# Basic contour plot +CS = plt.contour(X, Y, Z) + +# Define a class that forces representation of float to look a certain way +# This remove trailing zero so '1.0' becomes '1' +class nf(float): + def __repr__(self): + str = '%.1f' % (self.__float__(),) + if str[-1]=='0': + return '%.0f' % self.__float__() + else: + return '%.1f' % self.__float__() + +# Recast levels to new class +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) + +################################################## +# Label contours with arbitrary strings using a +# dictionary +################################################## +plt.figure() + +# Basic contour plot +CS = plt.contour(X, Y, Z) + +fmt = {} +strs = [ 'first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh' ] +for l,s in zip( CS.levels, strs ): + fmt[l] = s + +# Label every other level using strings +plt.clabel(CS,CS.levels[::2],inline=True,fmt=fmt,fontsize=10) + +################################################## +# Show the hole thing +################################################## +plt.show() Added: trunk/matplotlib/examples/pylab_examples/ginput_manual_clabel.py =================================================================== --- trunk/matplotlib/examples/pylab_examples/ginput_manual_clabel.py (rev 0) +++ trunk/matplotlib/examples/pylab_examples/ginput_manual_clabel.py 2008年07月21日 12:26:35 UTC (rev 5799) @@ -0,0 +1,88 @@ +#!/usr/bin/env python +""" +This provides examples of uses of interactive functions, such as ginput, +waitforbuttonpress and manual clabel placement. + +This script must be run interactively using a backend that has a +graphical user interface (for example, from inside ipython using +GTKAgg backend, but not PS backend). +""" +import time +import matplotlib +import numpy as np +import matplotlib.cm as cm +import matplotlib.mlab as mlab +import matplotlib.pyplot as plt + +def tellme(s): + print s + plt.title(s,fontsize=16) + plt.draw() + +################################################## +# Define a triangle by clicking three points +################################################## +plt.clf() +plt.axis([-1.,1.,-1.,1.]) +plt.setp(plt.gca(),autoscale_on=False) + +tellme('You will define a triangle, click to begin') + +plt.waitforbuttonpress() + +happy = False +while not happy: + pts = [] + while len(pts) < 3: + tellme('Select 3 corners with mouse') + pts = np.asarray( plt.ginput(3,timeout=-1) ) + if len(pts) < 3: + tellme('Too few points, starting over') + time.sleep(1) # Wait a second + + ph = plt.fill( pts[:,0], pts[:,1], 'r', lw=2 ) + + tellme('Happy? Key click for yes, mouse click for no') + + happy = plt.waitforbuttonpress() + + # Get rid of fill + if not happy: + for p in ph: p.remove() + +################################################## +# Now contour according to distance from triangle +# corners - just an example +################################################## + +# Define a nice function of distance from individual pts +def f(x,y,pts): + z = np.zeros_like(x) + for p in pts: + z = z + 1/(np.sqrt((x-p[0])**2+(y-p[1])**2)) + return 1/z + +X,Y = np.meshgrid( np.linspace(-1,1,51), np.linspace(-1,1,51) ) +Z = f(X,Y,pts) + +CS = plt.contour( X, Y, Z, 20 ) + +tellme( 'Use mouse to select contour label locations, middle button to finish' ) +CL = plt.clabel( CS, manual=True ) + +################################################## +# Now do a zoom +################################################## +tellme( 'Now do a nested zoom, click to begin' ) +plt.waitforbuttonpress() + +happy = False +while not happy: + tellme( 'Select two corners of zoom, middle mouse button to finish' ) + pts = np.asarray( plt.ginput(2,timeout=-1) ) + + happy = len(pts) < 2 + if happy: break + + pts = np.sort(pts,axis=0) + plt.axis( pts.T.ravel() ) Modified: trunk/matplotlib/examples/tests/backend_driver.py =================================================================== --- trunk/matplotlib/examples/tests/backend_driver.py 2008年07月21日 09:50:36 UTC (rev 5798) +++ trunk/matplotlib/examples/tests/backend_driver.py 2008年07月21日 12:26:35 UTC (rev 5799) @@ -39,6 +39,7 @@ 'color_demo.py', 'cohere_demo.py', 'contour_demo.py', + 'contour_label_demo.py', 'contourf_demo.py', 'csd_demo.py', 'custom_ticker1.py', Modified: trunk/matplotlib/lib/matplotlib/blocking_input.py =================================================================== --- trunk/matplotlib/lib/matplotlib/blocking_input.py 2008年07月21日 09:50:36 UTC (rev 5798) +++ trunk/matplotlib/lib/matplotlib/blocking_input.py 2008年07月21日 12:26:35 UTC (rev 5799) @@ -5,11 +5,11 @@ 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` @@ -46,7 +46,7 @@ # This will extract info from events self.post_event() - + # Check if we have enough events already if len(self.events) >= self.n and self.n > 0: self.done = True @@ -84,7 +84,7 @@ """ Blocking call to retrieve n events """ - + assert isinstance(n, int), "Requires an integer argument" self.n = n @@ -94,7 +94,7 @@ # Ensure that the figure is shown self.fig.show() - + # 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) ) @@ -124,7 +124,7 @@ blocking way. """ def __init__(self, fig): - BlockingInput.__init__(self, fig=fig, + BlockingInput.__init__(self, fig=fig, eventslist=('button_press_event',) ) def post_event(self): @@ -194,7 +194,7 @@ """ self.clicks.append((event.xdata,event.ydata)) - verbose.report("input %i: %f,%f" % + verbose.report("input %i: %f,%f" % (len(self.clicks),event.xdata, event.ydata)) # If desired plot up click @@ -209,7 +209,7 @@ removing the last click. """ self.clicks.pop(index) - + if self.show_clicks: mark = self.marks.pop(index) mark.remove() @@ -234,7 +234,7 @@ # Call base class to remove callbacks BlockingInput.cleanup(self) - + def __call__(self, n=1, timeout=30, show_clicks=True): """ Blocking call to retrieve n coordinate pairs through mouse @@ -261,11 +261,18 @@ This will be called if an event involving a button other than 2 or 3 occcurs. This will add a label to a contour. """ - if event.inaxes == self.cs.ax: - conmin,segmin,imin,xmin,ymin = self.cs.find_nearest_contour( - event.x, event.y)[:5] - paths = self.cs.collections[conmin].get_paths() + # Shorthand + cs = self.cs + + if event.inaxes == cs.ax: + conmin,segmin,imin,xmin,ymin = cs.find_nearest_contour( + event.x, event.y, cs.label_indices)[:5] + + # Get index of nearest level in subset of levels used for labeling + lmin = cs.label_indices.index(conmin) + + paths = cs.collections[conmin].get_paths() lc = paths[segmin].vertices # Figure out label rotation. This is very cludgy. @@ -287,15 +294,15 @@ if rotation < -90: rotation = 180 + rotation - self.cs.add_label(xmin,ymin,rotation,conmin) + cs.add_label(xmin,ymin,rotation,cs.label_levels[lmin], + cs.label_cvalues[lmin]) if self.inline: # Get label width for breaking contours - lw = self.cs.get_label_width(self.cs.label_levels[conmin], - self.cs.fmt, - self.cs.fslist[conmin]) + lw = cs.get_label_width(cs.label_levels[lmin], + cs.fmt, cs.fslist[lmin]) # Break contour - new=self.cs.break_linecontour(lc,rotation,lw,imin) + new=cs.break_linecontour(lc,rotation,lw,imin) if len(new[0]): paths[segmin] = path.Path(new[0]) if len(new[1]): @@ -304,7 +311,7 @@ self.fig.canvas.draw() else: # Remove event if not valid BlockingInput.pop(self) - + def button3(self,event): """ This will be called if button 3 is clicked. This will remove Modified: trunk/matplotlib/lib/matplotlib/contour.py =================================================================== --- trunk/matplotlib/lib/matplotlib/contour.py 2008年07月21日 09:50:36 UTC (rev 5798) +++ trunk/matplotlib/lib/matplotlib/contour.py 2008年07月21日 12:26:35 UTC (rev 5799) @@ -17,6 +17,9 @@ import matplotlib.text as text import matplotlib.cbook as cbook +# Import needed for adding manual selection capability to clabel +from matplotlib.blocking_input import BlockingContourLabeler + # We can't use a single line collection for contour because a line # collection can have only a single line style, and we want to be able to have # dashed negative contours, for example, and solid positive contours. @@ -68,16 +71,49 @@ *fmt*: a format string for the label. Default is '%1.3f' + Alternatively, this can be a dictionary matching contour + levels with arbitrary strings to use for each contour level + (i.e., fmt[level]=string) + *manual*: + if *True*, contour labels will be placed manually using + mouse clicks. Click the first button near a contour to + add a label, click the second button (or potentially both + mouse buttons at once) to finish adding labels. The third + button can be used to remove the last label added, but + only if labels are not inline. """ + + """" + NOTES on how this all works: + + clabel basically takes the input arguments and uses them to + add a list of "label specific" attributes to the ContourSet + object. These attributes currently include: label_indices, + label_levels, label_cvalues, fp (font properties), fslist + (fontsize list), label_mappable, cl (list of text objects of + labels), cl_xy (coordinates of labels), cl_cvalues (color + values of the actual labels). + + Note that these property names do not conform to the standards + set for coding matplotlib and I (DMK) eventually plan on + changing them so that they are clearer and conform to + standards. + + Once these attributes are set, clabel passes control to the + labels method (case of automatic label placement) or + BlockingContourLabeler (case of manual label placement. + """ + fontsize = kwargs.get('fontsize', None) inline = kwargs.get('inline', 1) self.fmt = kwargs.get('fmt', '%1.3f') _colors = kwargs.get('colors', None) + # Detect if manual selection is desired and remove from argument list + self.manual_select=kwargs.get('manual',False) - if len(args) == 0: levels = self.levels indices = range(len(self.levels)) @@ -126,10 +162,16 @@ #self.cl_cvalues = [] # same self.cl_xy = [] - self.labels(inline) + if self.manual_select: + 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.' - for label in self.cl: - self.ax.add_artist(label) + blocking_contour_labeler = BlockingContourLabeler(self) + blocking_contour_labeler(inline) + else: + self.labels(inline) self.label_list = cbook.silent_list('text.Text', self.cl) return self.label_list @@ -141,10 +183,10 @@ if lcsize > 10 * labelwidth: return 1 - xmax = np.amax(np.array(linecontour)[:,0]) - xmin = np.amin(np.array(linecontour)[:,0]) - ymax = np.amax(np.array(linecontour)[:,1]) - ymin = np.amin(np.array(linecontour)[:,1]) + xmax = np.amax(linecontour[:,0]) + xmin = np.amin(linecontour[:,0]) + ymax = np.amax(linecontour[:,1]) + ymin = np.amin(linecontour[:,1]) lw = labelwidth if (xmax - xmin) > 1.2* lw or (ymax - ymin) > 1.2 * lw: @@ -180,12 +222,10 @@ if self.too_close(x,y, lw): continue else: - self.cl_xy.append((x,y)) return x,y, ind ind = adist[0] x, y = XX[ind][hysize], YY[ind][hysize] - self.cl_xy.append((x,y)) return x,y, ind def get_label_width(self, lev, fmt, fsize): @@ -193,7 +233,7 @@ if cbook.is_string_like(lev): lw = (len(lev)) * fsize else: - lw = (len(fmt%lev)) * fsize + lw = (len(self.get_text(lev,fmt))) * fsize return lw @@ -210,9 +250,11 @@ if cbook.is_string_like(lev): return lev else: - return fmt%lev + if isinstance(fmt,dict): + return fmt[lev] + else: + return fmt%lev - def break_linecontour(self, linecontour, rot, labelwidth, ind): "break a contour in two contours at the location of the label" lcsize = len(linecontour) @@ -226,8 +268,8 @@ slc = trans.transform(linecontour) x,y = slc[ind] - xx= np.asarray(slc)[:,0].copy() - yy=np.asarray(slc)[:,1].copy() + xx=slc[:,0].copy() + yy=slc[:,1].copy() #indices which are under the label inds, = np.nonzero(((xx < x+xlabel) & (xx > x-xlabel)) & @@ -308,8 +350,8 @@ else: ysize = labelwidth - XX = np.resize(np.asarray(linecontour)[:,0],(xsize, ysize)) - YY = np.resize(np.asarray(linecontour)[:,1],(xsize, ysize)) + XX = np.resize(linecontour[:,0],(xsize, ysize)) + YY = np.resize(linecontour[:,1],(xsize, ysize)) #I might have fouled up the following: yfirst = YY[:,0].reshape(xsize, 1) ylast = YY[:,-1].reshape(xsize, 1) @@ -335,19 +377,38 @@ return x,y, rotation, dind + def add_label(self,x,y,rotation,lev,cvalue): + dx,dy = self.ax.transData.inverted().transform_point((x,y)) + t = text.Text(dx, dy, rotation = rotation, + horizontalalignment='center', + verticalalignment='center') + + color = self.label_mappable.to_rgba(cvalue,alpha=self.alpha) + + _text = self.get_text(lev,self.fmt) + self.set_label_props(t, _text, color) + self.cl.append(t) + self.cl_cvalues.append(cvalue) + self.cl_xy.append((x,y)) + + # Add label to plot here - useful for manual mode label selection + self.ax.add_artist(t) + + def pop_label(self,index=-1): + '''Defaults to removing last label, but any index can be supplied''' + self.cl_cvalues.pop(index) + t = self.cl.pop(index) + t.remove() + def labels(self, inline): - levels = self.label_levels - fslist = self.fslist - trans = self.ax.transData - _colors = self.label_mappable.to_rgba(self.label_cvalues, - alpha=self.alpha) - fmt = self.fmt - for icon, lev, color, cvalue, fsize in zip(self.label_indices, - self.label_levels, - _colors, - self.label_cvalues, fslist): + trans = self.ax.transData # A bit of shorthand + + for icon, lev, fsize, cvalue in zip( + self.label_indices, self.label_levels, self.fslist, + self.label_cvalues ): + con = self.collections[icon] - lw = self.get_label_width(lev, fmt, fsize) + lw = self.get_label_width(lev, self.fmt, fsize) additions = [] paths = con.get_paths() for segNum, linepath in enumerate(paths): @@ -356,28 +417,27 @@ # avoid division by zero if np.all(linecontour[0] == linecontour[-1]): linecontour = np.concatenate((linecontour, - linecontour[1][np.newaxis,:])) + linecontour[1][np.newaxis,:])) #linecontour.append(linecontour[1]) # transfer all data points to screen coordinates slc = trans.transform(linecontour) if self.print_label(slc,lw): x,y, rotation, ind = self.locate_label(slc, lw) - # transfer the location of the label back to - # data coordinates - dx,dy = trans.inverted().transform_point((x,y)) - t = text.Text(dx, dy, rotation = rotation, - horizontalalignment='center', - verticalalignment='center') - _text = self.get_text(lev,fmt) - self.set_label_props(t, _text, color) - self.cl.append(t) - self.cl_cvalues.append(cvalue) + + # Actually add the label + self.add_label(x,y,rotation,lev,cvalue) + + # Use break_linecontour to split contours for inlining if inline: - new = self.break_linecontour(linecontour, rotation, lw, ind) + new = self.break_linecontour(linecontour, rotation, + lw, ind) if len(new[0]): paths[segNum] = path.Path(new[0]) if len(new[1]): additions.append(path.Path(new[1])) + + # After looping over all segments on a contour, append + # new paths to existing paths.extend(additions) @@ -802,19 +862,8 @@ Use keyword args to control colors, linewidth, origin, cmap ... see below for more details. - *X*, *Y*, and *Z* may be arrays all with the same 2-D shape, or - *X* and *Y* can be 1-D while *Z* is 2-D. In the latter - case, the following must be true: + *X*, *Y*, and *Z* must be arrays with the same dimensions. - :: - - Z.shape == len(Y), len(X) - - Note that the first index of *Z*, the row number, corresponds - to the vertical coordinate on the page, while the second - index, the column number, corresponds to the horizontal - coordinate on the page. - *Z* may be a masked array, but filled contouring may not handle internal masked regions correctly. @@ -908,3 +957,70 @@ .. plot:: contour_demo.py """ + + def find_nearest_contour( self, x, y, indices=None, pixel=True ): + """ + Finds contour that is closest to a point. Defaults to + measuring distance in pixels (screen space - useful for manual + contour labeling), but this can be controlled via a keyword + argument. + + Returns a tuple containing the contour, segment, index of + segment, x & y of segment point and distance to minimum point. + + Call signature:: + + conmin,segmin,imin,xmin,ymin,dmin = find_nearest_contour( + self, x, y, indices=None, pixel=True ) + + Optional keyword arguments:: + + *indices*: + Indexes of contour levels to consider when looking for + nearest point. Defaults to using all levels. + + *pixel*: + If *True*, measure distance in pixel space, if not, measure + distance in axes space. Defaults to *True*. + + """ + + # This function uses a method that is probably quite + # inefficient based on converting each contour segment to + # pixel coordinates and then comparing the given point to + # those coordinates for each contour. This will probably be + # quite slow for complex contours, but for normal use it works + # sufficiently well that the time is not noticeable. + # Nonetheless, improvements could probably be made. + + if indices==None: + indices = range(len(self.levels)) + + dmin = 1e10 + conmin = None + segmin = None + xmin = None + ymin = None + + for icon in indices: + con = self.collections[icon] + paths = con.get_paths() + for segNum, linepath in enumerate(paths): + lc = linepath.vertices + + # transfer all data points to screen coordinates if desired + if pixel: + lc = self.ax.transData.transform(lc) + + ds = (lc[:,0]-x)**2 + (lc[:,1]-y)**2 + d = min( ds ) + if d < dmin: + dmin = d + conmin = icon + segmin = segNum + imin = mpl.mlab.find( ds == d )[0] + xmin = lc[imin,0] + ymin = lc[imin,1] + + return (conmin,segmin,imin,xmin,ymin,dmin) + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5798 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5798&view=rev Author: jdh2358 Date: 2008年07月21日 09:50:36 +0000 (2008年7月21日) Log Message: ----------- Added Gael's backend fallback patch Modified Paths: -------------- trunk/matplotlib/examples/pylab_examples/scatter_demo.py trunk/matplotlib/lib/matplotlib/backends/__init__.py trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py trunk/matplotlib/lib/matplotlib/pyplot.py trunk/matplotlib/lib/matplotlib/rcsetup.py trunk/matplotlib/matplotlibrc.template Modified: trunk/matplotlib/examples/pylab_examples/scatter_demo.py =================================================================== --- trunk/matplotlib/examples/pylab_examples/scatter_demo.py 2008年07月21日 00:22:19 UTC (rev 5797) +++ trunk/matplotlib/examples/pylab_examples/scatter_demo.py 2008年07月21日 09:50:36 UTC (rev 5798) @@ -6,5 +6,6 @@ y = 0.9*rand(N) area = pi*(10 * rand(N))**2 # 0 to 10 point radiuses scatter(x,y,s=area, marker='^', c='r') - +savefig('test.ps') +savefig('test.pdf') show() Modified: trunk/matplotlib/lib/matplotlib/backends/__init__.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/__init__.py 2008年07月21日 00:22:19 UTC (rev 5797) +++ trunk/matplotlib/lib/matplotlib/backends/__init__.py 2008年07月21日 09:50:36 UTC (rev 5798) @@ -23,7 +23,9 @@ # Things we pull in from all backends new_figure_manager = backend_mod.new_figure_manager - + # image backends like pdf, agg or svg do not need to do anything + # for "show" or "draw_if_interactive", so if they are not defined + # by the backend, just do nothing def do_nothing(*args, **kwargs): pass backend_version = getattr(backend_mod,'backend_version', 'unknown') show = getattr(backend_mod, 'show', do_nothing) Modified: trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py 2008年07月21日 00:22:19 UTC (rev 5797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py 2008年07月21日 09:50:36 UTC (rev 5798) @@ -67,7 +67,8 @@ for manager in Gcf.get_all_fig_managers(): manager.window.show() - if mainloop and gtk.main_level() == 0: + if mainloop and gtk.main_level() == 0 and \ + len(Gcf.get_all_fig_managers())>0: gtk.main() def new_figure_manager(num, *args, **kwargs): Modified: trunk/matplotlib/lib/matplotlib/pyplot.py =================================================================== --- trunk/matplotlib/lib/matplotlib/pyplot.py 2008年07月21日 00:22:19 UTC (rev 5797) +++ trunk/matplotlib/lib/matplotlib/pyplot.py 2008年07月21日 09:50:36 UTC (rev 5798) @@ -1,12 +1,13 @@ import sys import matplotlib -from matplotlib import _pylab_helpers +from matplotlib import _pylab_helpers, interactive from matplotlib.cbook import dedent, silent_list, is_string_like, is_numlike from matplotlib.figure import Figure, figaspect from matplotlib.backend_bases import FigureCanvasBase from matplotlib.image import imread as _imread from matplotlib import rcParams, rcParamsDefault, get_backend +from matplotlib.rcsetup import interactive_bk as _interactive_bk from matplotlib.artist import getp, get, Artist from matplotlib.artist import setp as _setp from matplotlib.axes import Axes @@ -32,7 +33,42 @@ MaxNLocator +## Backend detection ## +def _backend_selection(): + """ If rcParams['backend_fallback'] is true, check to see if the + current backend is compatible with the current running event + loop, and if not switches to a compatible one. + """ + backend = rcParams['backend'] + if not rcParams['backend_fallback'] or \ + backend not in _interactive_bk: + return + is_agg_backend = rcParams['backend'].endswith('Agg') + if 'wx' in sys.modules and not backend in ('WX', 'WXAgg'): + import wx + if wx.App.IsMainLoopRunning(): + rcParams['backend'] = 'wx' + 'Agg' * is_agg_backend + elif 'qt' in sys.modules and not backend == 'QtAgg': + import qt + if not qt.qApp.startingUp(): + # The mainloop is running. + rcParams['backend'] = 'qtAgg' + elif 'PyQt4.QtCore' in sys.modules and not backend == 'Qt4Agg': + import PyQt4.QtGui + if not PyQt4.QtGui.qApp.startingUp(): + # The mainloop is running. + rcParams['backend'] = 'qt4Agg' + elif 'gtk' in sys.modules and not backend in ('GTK', 'GTKAgg', + 'GTKCairo'): + import gobject + if gobject.MainLoop().is_running(): + rcParams['backend'] = 'gtk' + 'Agg' * is_agg_backend + elif 'Tkinter' in sys.modules and not backend == 'TkAgg': + #import Tkinter + pass #what if anything do we need to do for tkinter? +_backend_selection() + ## Global ## from matplotlib.backends import pylab_setup Modified: trunk/matplotlib/lib/matplotlib/rcsetup.py =================================================================== --- trunk/matplotlib/lib/matplotlib/rcsetup.py 2008年07月21日 00:22:19 UTC (rev 5797) +++ trunk/matplotlib/lib/matplotlib/rcsetup.py 2008年07月21日 09:50:36 UTC (rev 5798) @@ -305,6 +305,7 @@ # a map from key -> value, converter defaultParams = { 'backend' : ['Agg', validate_backend], # agg is certainly present + 'backend_fallback' : [True, validate_bool], # agg is certainly present 'numerix' : ['numpy', validate_numerix], 'maskedarray' : [False, validate_bool], 'toolbar' : ['toolbar2', validate_toolbar], Modified: trunk/matplotlib/matplotlibrc.template =================================================================== --- trunk/matplotlib/matplotlibrc.template 2008年07月21日 00:22:19 UTC (rev 5797) +++ trunk/matplotlib/matplotlibrc.template 2008年07月21日 09:50:36 UTC (rev 5798) @@ -26,6 +26,11 @@ # to the module name (which must be in the PYTHONPATH) as # 'module://my_backend' backend : %(backend)s + +# if you are runing pyplot inside a GUI and your backend choice +# conflicts, we will automatically try and find a compatible one for +# you if backend_fallback is True +#backend_fallback: True numerix : %(numerix)s # numpy, Numeric or numarray #maskedarray : False # True to use external maskedarray module # instead of numpy.ma; this is a temporary This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5797 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5797&view=rev Author: efiring Date: 2008年07月21日 00:22:19 +0000 (2008年7月21日) Log Message: ----------- Expanded delete_masked_points to handle more types of argument Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/cbook.py trunk/matplotlib/lib/matplotlib/collections.py trunk/matplotlib/unit/cbook_unit.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2008年07月20日 18:21:11 UTC (rev 5796) +++ trunk/matplotlib/CHANGELOG 2008年07月21日 00:22:19 UTC (rev 5797) @@ -1,3 +1,6 @@ +2008年07月20日 Rewrote cbook.delete_masked_points and corresponding + unit test to support rgb color array inputs, datetime + inputs, etc. - EF 2008年07月20日 Renamed unit/axes_unit.py to cbook_unit.py and modified in accord with Ryan's move of delete_masked_points from Modified: trunk/matplotlib/lib/matplotlib/cbook.py =================================================================== --- trunk/matplotlib/lib/matplotlib/cbook.py 2008年07月20日 18:21:11 UTC (rev 5796) +++ trunk/matplotlib/lib/matplotlib/cbook.py 2008年07月21日 00:22:19 UTC (rev 5797) @@ -6,7 +6,7 @@ import re, os, errno, sys, StringIO, traceback, locale, threading, types import time, datetime import numpy as np -from numpy import ma +import numpy.ma as ma from weakref import ref major, minor1, minor2, s, tmp = sys.version_info @@ -1168,41 +1168,82 @@ def delete_masked_points(*args): """ - Find all masked points in a set of arguments, and return - the arguments with only the unmasked points remaining. + Find all masked and/or non-finite points in a set of arguments, + and return the arguments with only the unmasked points remaining. - This will also delete any points that are not finite (nan or inf). + Arguments can be in any of 5 categories: - The overall mask is calculated from any masks that are present. - If a mask is found, any argument that does not have the same - dimensions is left unchanged; therefore the argument list may - include arguments that can take string or array values, for - example. + 1) 1-D masked arrays + 2) 1-D ndarrays + 3) ndarrays with more than one dimension + 4) other non-string iterables + 5) anything else - Array arguments must have the same length; masked arguments must - be one-dimensional. + The first argument must be in one of the first four categories; + any argument with a length differing from that of the first + argument (and hence anything in category 5) then will be + passed through unchanged. - Written as a helper for scatter, but may be more generally - useful. + Masks are obtained from all arguments of the correct length + in categories 1, 2, and 4; a point is bad if masked in a masked + array or if it is a nan or inf. No attempt is made to + extract a mask from categories 2, 3, and 4 if *np.isfinite()* + does not yield a Boolean array. + + All input arguments that are not passed unchanged are returned + as ndarrays after removing the points or rows corresponding to + masks in any of the arguments. + + A vastly simpler version of this function was originally + written as a helper for Axes.scatter(). + """ - masks = [ma.getmaskarray(x) for x in args if hasattr(x, 'mask')] - isfinite = [np.isfinite(x) for x in args] - masks.extend( [~x for x in isfinite if not isinstance(x,types.NotImplementedType)] ) - if len(masks) == 0: - return args - mask = reduce(np.logical_or, masks) + if not len(args): + return () + if (is_string_like(args[0]) or not iterable(args[0])): + raise ValueError("First argument must be a sequence") + nrecs = len(args[0]) margs = [] - for x in args: - if (not is_string_like(x) - and iterable(x) - and len(x) == len(mask)): - if (hasattr(x, 'get_compressed_copy')): - compressed_x = x.get_compressed_copy(mask) + seqlist = [False] * len(args) + for i, x in enumerate(args): + if (not is_string_like(x)) and iterable(x) and len(x) == nrecs: + seqlist[i] = True + if ma.isMA(x): + if x.ndim > 1: + raise ValueError("Masked arrays must be 1-D") else: - compressed_x = ma.masked_array(x, mask=mask).compressed() - margs.append(compressed_x) - else: - margs.append(x) + x = np.asarray(x) + margs.append(x) + masks = [] # list of masks that are True where good + for i, x in enumerate(margs): + if seqlist[i]: + if x.ndim > 1: + continue # Don't try to get nan locations unless 1-D. + if ma.isMA(x): + masks.append(~ma.getmaskarray(x)) # invert the mask + xd = x.data + else: + xd = x + try: + mask = np.isfinite(xd) + if isinstance(mask, np.ndarray): + masks.append(mask) + except: #Fixme: put in tuple of possible exceptions? + pass + if len(masks): + mask = reduce(np.logical_and, masks) + igood = mask.nonzero()[0] + if len(igood) < nrecs: + for i, x in enumerate(margs): + if seqlist[i]: + if (hasattr(x, 'get_compressed_copy')): + compressed_x = x.get_compressed_copy(~mask) + else: + compressed_x = x.take(igood, axis=0) + margs[i] = compressed_x + for i, x in enumerate(margs): + if seqlist[i] and ma.isMA(x): + margs[i] = x.filled() return margs Modified: trunk/matplotlib/lib/matplotlib/collections.py =================================================================== --- trunk/matplotlib/lib/matplotlib/collections.py 2008年07月20日 18:21:11 UTC (rev 5796) +++ trunk/matplotlib/lib/matplotlib/collections.py 2008年07月21日 00:22:19 UTC (rev 5797) @@ -90,7 +90,7 @@ self._uniform_offsets = None self._offsets = np.array([], np.float_) if offsets is not None: - offsets = np.asarray(offsets, np.float_) + offsets = np.asarray(offsets) if len(offsets.shape) == 1: offsets = offsets[np.newaxis,:] # Make it Nx2. if transOffset is not None: Modified: trunk/matplotlib/unit/cbook_unit.py =================================================================== --- trunk/matplotlib/unit/cbook_unit.py 2008年07月20日 18:21:11 UTC (rev 5796) +++ trunk/matplotlib/unit/cbook_unit.py 2008年07月21日 00:22:19 UTC (rev 5797) @@ -1,62 +1,52 @@ import unittest +from datetime import datetime + import numpy as np import matplotlib.cbook as cbook +import matplotlib.colors as mcolors -class TestAxes(unittest.TestCase): - def test_delete_masked_points_arrays(self): - input = ( [1,2,3,np.nan,5], - np.array((1,2,3,4,5)), - ) - expected = [np.array((1,2,3,5))]*2 - actual = cbook.delete_masked_points(*input) - assert np.allclose(actual, expected) +from matplotlib.cbook import delete_masked_points as dmp - input = ( np.ma.array( [1,2,3,4,5], mask=[False,False,False,True,False] ), - np.array((1,2,3,4,5)), - ) - expected = [np.array((1,2,3,5))]*2 - actual = cbook.delete_masked_points(*input) - assert np.allclose(actual, expected) +class Test_delete_masked_points(unittest.TestCase): + def setUp(self): + self.mask1 = [False, False, True, True, False, False] + self.arr0 = np.arange(1.0,7.0) + self.arr1 = [1,2,3,np.nan,np.nan,6] + self.arr2 = np.array(self.arr1) + self.arr3 = np.ma.array(self.arr2, mask=self.mask1) + self.arr_s = ['a', 'b', 'c', 'd', 'e', 'f'] + self.arr_s2 = np.array(self.arr_s) + self.arr_dt = [datetime(2008, 1, 1), datetime(2008, 1, 2), + datetime(2008, 1, 3), datetime(2008, 1, 4), + datetime(2008, 1, 5), datetime(2008, 1, 6)] + self.arr_dt2 = np.array(self.arr_dt) + self.arr_colors = ['r', 'g', 'b', 'c', 'm', 'y'] + self.arr_rgba = mcolors.colorConverter.to_rgba_array(self.arr_colors) - input = ( [1,2,3,np.nan,5], - np.ma.array( [1,2,3,4,5], mask=[False,False,False,True,False] ), - np.array((1,2,3,4,5)), - ) - expected = [np.array((1,2,3,5))]*3 - actual = cbook.delete_masked_points(*input) - assert np.allclose(actual, expected) + def test_bad_first_arg(self): + self.assertRaises(ValueError, dmp, 'a string', self.arr0) - input = () - expected = () - actual = cbook.delete_masked_points(*input) - assert np.allclose(actual, expected) + def test_string_seq(self): + actual = dmp(self.arr_s, self.arr1) + ind = [0, 1, 2, 5] + expected = (self.arr_s2.take(ind), self.arr2.take(ind)) + def test_datetime(self): + actual = dmp(self.arr_dt, self.arr3) + ind = [0, 1, 5] + expected = (self.arr_dt2.take(ind), + self.arr3.take(ind).compressed()) + self.assert_(np.all(actual[0] == expected[0]) and + np.all(actual[1] == expected[1])) - input = ( [1,2,3,np.nan,5], - ) - expected = [np.array((1,2,3,5))]*1 - actual = cbook.delete_masked_points(*input) - assert np.allclose(actual, expected) + def test_rgba(self): + actual = dmp(self.arr3, self.arr_rgba) + ind = [0, 1, 5] + expected = (self.arr3.take(ind).compressed(), + self.arr_rgba.take(ind, axis=0)) + self.assert_(np.all(actual[0] == expected[0]) and + np.all(actual[1] == expected[1])) - input = ( np.array((1,2,3,4,5)), - ) - expected = [np.array((1,2,3,4,5))]*1 - actual = cbook.delete_masked_points(*input) - assert np.allclose(actual, expected) - def test_delete_masked_points_strings(self): - input = ( 'hello', - ) - expected = ('hello',) - actual = cbook.delete_masked_points(*input) - assert actual == expected - - input = ( u'hello', - ) - expected = (u'hello',) - actual = cbook.delete_masked_points(*input) - assert actual == expected - - if __name__=='__main__': unittest.main() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5796 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5796&view=rev Author: efiring Date: 2008年07月20日 18:21:11 +0000 (2008年7月20日) Log Message: ----------- Moved and modified axes_unit.py to cbook_unit.py. At present it is only testing delete_masked_points, which was moved from axes to cbook. Modified Paths: -------------- trunk/matplotlib/CHANGELOG Added Paths: ----------- trunk/matplotlib/unit/cbook_unit.py Removed Paths: ------------- trunk/matplotlib/unit/axes_unit.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2008年07月20日 07:14:46 UTC (rev 5795) +++ trunk/matplotlib/CHANGELOG 2008年07月20日 18:21:11 UTC (rev 5796) @@ -1,8 +1,13 @@ + +2008年07月20日 Renamed unit/axes_unit.py to cbook_unit.py and modified + in accord with Ryan's move of delete_masked_points from + axes to cbook. - EF + 2008年07月18日 Check for nan and inf in axes.delete_masked_points(). - This should help hexbin and scatter deal with nans. - ADS + This should help hexbin and scatter deal with nans. - ADS 2008年07月17日 Added ability to manually select contour label locations. - Also added a waitforbuttonpress function. - DMK + Also added a waitforbuttonpress function. - DMK 2008年07月17日 Fix bug with NaNs at end of path (thanks, Andrew Straw for the report) - MGD Deleted: trunk/matplotlib/unit/axes_unit.py =================================================================== --- trunk/matplotlib/unit/axes_unit.py 2008年07月20日 07:14:46 UTC (rev 5795) +++ trunk/matplotlib/unit/axes_unit.py 2008年07月20日 18:21:11 UTC (rev 5796) @@ -1,62 +0,0 @@ -import unittest -import numpy as np -import matplotlib.axes as axes - -class TestAxes(unittest.TestCase): - def test_delete_masked_points_arrays(self): - input = ( [1,2,3,np.nan,5], - np.array((1,2,3,4,5)), - ) - expected = [np.array((1,2,3,5))]*2 - actual = axes.delete_masked_points(*input) - assert np.allclose(actual, expected) - - input = ( np.ma.array( [1,2,3,4,5], mask=[False,False,False,True,False] ), - np.array((1,2,3,4,5)), - ) - expected = [np.array((1,2,3,5))]*2 - actual = axes.delete_masked_points(*input) - assert np.allclose(actual, expected) - - input = ( [1,2,3,np.nan,5], - np.ma.array( [1,2,3,4,5], mask=[False,False,False,True,False] ), - np.array((1,2,3,4,5)), - ) - expected = [np.array((1,2,3,5))]*3 - actual = axes.delete_masked_points(*input) - assert np.allclose(actual, expected) - - input = () - expected = () - actual = axes.delete_masked_points(*input) - assert np.allclose(actual, expected) - - - input = ( [1,2,3,np.nan,5], - ) - expected = [np.array((1,2,3,5))]*1 - actual = axes.delete_masked_points(*input) - assert np.allclose(actual, expected) - - input = ( np.array((1,2,3,4,5)), - ) - expected = [np.array((1,2,3,4,5))]*1 - actual = axes.delete_masked_points(*input) - assert np.allclose(actual, expected) - - def test_delete_masked_points_strings(self): - input = ( 'hello', - ) - expected = ('hello',) - actual = axes.delete_masked_points(*input) - assert actual == expected - - input = ( u'hello', - ) - expected = (u'hello',) - actual = axes.delete_masked_points(*input) - assert actual == expected - - -if __name__=='__main__': - unittest.main() Copied: trunk/matplotlib/unit/cbook_unit.py (from rev 5795, trunk/matplotlib/unit/axes_unit.py) =================================================================== --- trunk/matplotlib/unit/cbook_unit.py (rev 0) +++ trunk/matplotlib/unit/cbook_unit.py 2008年07月20日 18:21:11 UTC (rev 5796) @@ -0,0 +1,62 @@ +import unittest +import numpy as np +import matplotlib.cbook as cbook + +class TestAxes(unittest.TestCase): + def test_delete_masked_points_arrays(self): + input = ( [1,2,3,np.nan,5], + np.array((1,2,3,4,5)), + ) + expected = [np.array((1,2,3,5))]*2 + actual = cbook.delete_masked_points(*input) + assert np.allclose(actual, expected) + + input = ( np.ma.array( [1,2,3,4,5], mask=[False,False,False,True,False] ), + np.array((1,2,3,4,5)), + ) + expected = [np.array((1,2,3,5))]*2 + actual = cbook.delete_masked_points(*input) + assert np.allclose(actual, expected) + + input = ( [1,2,3,np.nan,5], + np.ma.array( [1,2,3,4,5], mask=[False,False,False,True,False] ), + np.array((1,2,3,4,5)), + ) + expected = [np.array((1,2,3,5))]*3 + actual = cbook.delete_masked_points(*input) + assert np.allclose(actual, expected) + + input = () + expected = () + actual = cbook.delete_masked_points(*input) + assert np.allclose(actual, expected) + + + input = ( [1,2,3,np.nan,5], + ) + expected = [np.array((1,2,3,5))]*1 + actual = cbook.delete_masked_points(*input) + assert np.allclose(actual, expected) + + input = ( np.array((1,2,3,4,5)), + ) + expected = [np.array((1,2,3,4,5))]*1 + actual = cbook.delete_masked_points(*input) + assert np.allclose(actual, expected) + + def test_delete_masked_points_strings(self): + input = ( 'hello', + ) + expected = ('hello',) + actual = cbook.delete_masked_points(*input) + assert actual == expected + + input = ( u'hello', + ) + expected = (u'hello',) + actual = cbook.delete_masked_points(*input) + assert actual == expected + + +if __name__=='__main__': + unittest.main() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5795 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5795&view=rev Author: efiring Date: 2008年07月20日 07:14:46 +0000 (2008年7月20日) Log Message: ----------- In collections draw methods, use get_facecolor and get_edgecolor. The logic for edgecolors='face' is moved into get_edgecolor so that it will return the color(s) that will actually be used. Using the getters means that a derived class can override them to add more logic to the choice of colors. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/collections.py Modified: trunk/matplotlib/lib/matplotlib/collections.py =================================================================== --- trunk/matplotlib/lib/matplotlib/collections.py 2008年07月20日 02:59:00 UTC (rev 5794) +++ trunk/matplotlib/lib/matplotlib/collections.py 2008年07月20日 07:14:46 UTC (rev 5795) @@ -184,16 +184,12 @@ offsets = transOffset.transform_non_affine(offsets) transOffset = transOffset.get_affine() - if self._edgecolors == 'face': - edgecolors = self._facecolors - else: - edgecolors = self._edgecolors renderer.draw_path_collection( transform.frozen(), self.clipbox, clippath, clippath_trans, paths, self.get_transforms(), offsets, transOffset, - self._facecolors, edgecolors, self._linewidths, + self.get_facecolor(), self.get_edgecolor(), self._linewidths, self._linestyles, self._antialiaseds) renderer.close_group(self.__class__.__name__) @@ -315,7 +311,10 @@ get_facecolors = get_facecolor def get_edgecolor(self): - return self._edgecolors + if self._edgecolors == 'face': + return self.get_facecolors() + else: + return self._edgecolors get_edgecolors = get_edgecolor def set_edgecolor(self, c): @@ -534,7 +533,7 @@ renderer.draw_quad_mesh( transform.frozen(), self.clipbox, clippath, clippath_trans, self._meshWidth, self._meshHeight, coordinates, - offsets, transOffset, self._facecolors, self._antialiased, + offsets, transOffset, self.get_facecolor(), self._antialiased, self._showedges) renderer.close_group(self.__class__.__name__) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5794 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5794&view=rev Author: ryanmay Date: 2008年07月20日 02:59:00 +0000 (2008年7月20日) Log Message: ----------- Move delete_masked_points() from axes.py to cbook.py so that it's available to more places. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/axes.py trunk/matplotlib/lib/matplotlib/cbook.py Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2008年07月20日 00:57:41 UTC (rev 5793) +++ trunk/matplotlib/lib/matplotlib/axes.py 2008年07月20日 02:59:00 UTC (rev 5794) @@ -1,5 +1,5 @@ from __future__ import division, generators -import math, sys, warnings, datetime, new, types +import math, sys, warnings, datetime, new import numpy as np from numpy import ma @@ -31,45 +31,6 @@ is_string_like = cbook.is_string_like -def delete_masked_points(*args): - """ - Find all masked points in a set of arguments, and return - the arguments with only the unmasked points remaining. - - This will also delete any points that are not finite (nan or inf). - - The overall mask is calculated from any masks that are present. - If a mask is found, any argument that does not have the same - dimensions is left unchanged; therefore the argument list may - include arguments that can take string or array values, for - example. - - Array arguments must have the same length; masked arguments must - be one-dimensional. - - Written as a helper for scatter, but may be more generally - useful. - """ - masks = [ma.getmaskarray(x) for x in args if hasattr(x, 'mask')] - isfinite = [np.isfinite(x) for x in args] - masks.extend( [~x for x in isfinite if not isinstance(x,types.NotImplementedType)] ) - if len(masks) == 0: - return args - mask = reduce(np.logical_or, masks) - margs = [] - for x in args: - if (not is_string_like(x) - and iterable(x) - and len(x) == len(mask)): - if (hasattr(x, 'get_compressed_copy')): - compressed_x = x.get_compressed_copy(mask) - else: - compressed_x = ma.masked_array(x, mask=mask).compressed() - margs.append(compressed_x) - else: - margs.append(x) - return margs - def _process_plot_format(fmt): """ Process a matlab(TM) style color/line style format string. Return a @@ -4827,7 +4788,7 @@ self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs) - x, y, s, c = delete_masked_points(x, y, s, c) + x, y, s, c = cbook.delete_masked_points(x, y, s, c) # The inherent ambiguity is resolved in favor of color # mapping, not interpretation as rgb or rgba. @@ -5091,7 +5052,7 @@ self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs) - x, y = delete_masked_points(x, y) + x, y = cbook.delete_masked_points(x, y) # Set the size of the hexagon grid if iterable(gridsize): Modified: trunk/matplotlib/lib/matplotlib/cbook.py =================================================================== --- trunk/matplotlib/lib/matplotlib/cbook.py 2008年07月20日 00:57:41 UTC (rev 5793) +++ trunk/matplotlib/lib/matplotlib/cbook.py 2008年07月20日 02:59:00 UTC (rev 5794) @@ -3,9 +3,10 @@ from the Python Cookbook -- hence the name cbook """ from __future__ import generators -import re, os, errno, sys, StringIO, traceback, locale, threading +import re, os, errno, sys, StringIO, traceback, locale, threading, types import time, datetime import numpy as np +from numpy import ma from weakref import ref major, minor1, minor2, s, tmp = sys.version_info @@ -1165,8 +1166,46 @@ else: os.remove(path) +def delete_masked_points(*args): + """ + Find all masked points in a set of arguments, and return + the arguments with only the unmasked points remaining. + This will also delete any points that are not finite (nan or inf). + The overall mask is calculated from any masks that are present. + If a mask is found, any argument that does not have the same + dimensions is left unchanged; therefore the argument list may + include arguments that can take string or array values, for + example. + + Array arguments must have the same length; masked arguments must + be one-dimensional. + + Written as a helper for scatter, but may be more generally + useful. + """ + masks = [ma.getmaskarray(x) for x in args if hasattr(x, 'mask')] + isfinite = [np.isfinite(x) for x in args] + masks.extend( [~x for x in isfinite if not isinstance(x,types.NotImplementedType)] ) + if len(masks) == 0: + return args + mask = reduce(np.logical_or, masks) + margs = [] + for x in args: + if (not is_string_like(x) + and iterable(x) + and len(x) == len(mask)): + if (hasattr(x, 'get_compressed_copy')): + compressed_x = x.get_compressed_copy(mask) + else: + compressed_x = ma.masked_array(x, mask=mask).compressed() + margs.append(compressed_x) + else: + margs.append(x) + return margs + + # a dict to cross-map linestyle arguments _linestyles = [('-', 'solid'), ('--', 'dashed'), This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5793 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5793&view=rev Author: efiring Date: 2008年07月20日 00:57:41 +0000 (2008年7月20日) Log Message: ----------- Reverting clabel-related change in contour.py to 5689. contour_demo.py was broken. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/contour.py Modified: trunk/matplotlib/lib/matplotlib/contour.py =================================================================== --- trunk/matplotlib/lib/matplotlib/contour.py 2008年07月19日 07:05:43 UTC (rev 5792) +++ trunk/matplotlib/lib/matplotlib/contour.py 2008年07月20日 00:57:41 UTC (rev 5793) @@ -17,9 +17,6 @@ import matplotlib.text as text import matplotlib.cbook as cbook -# Import needed for adding manual selection capability to clabel -from matplotlib.blocking_input import BlockingContourLabeler - # We can't use a single line collection for contour because a line # collection can have only a single line style, and we want to be able to have # dashed negative contours, for example, and solid positive contours. @@ -71,17 +68,7 @@ *fmt*: a format string for the label. Default is '%1.3f' - Alternatively, this can be a dictionary matching contour - levels with arbitrary strings to use for each contour level - (i.e., fmt[level]=string) - *manual*: - if *True*, contour labels will be placed manually using - mouse clicks. Click the first button near a contour to - add a label, click the second button (or potentially both - mouse buttons at once) to finish adding labels. The third - button can be used to remove the last label added, but - only if labels are not inline. """ fontsize = kwargs.get('fontsize', None) @@ -89,9 +76,8 @@ self.fmt = kwargs.get('fmt', '%1.3f') _colors = kwargs.get('colors', None) - # Detect if manual selection is desired and remove from argument list - self.manual_select=kwargs.get('manual',False) + if len(args) == 0: levels = self.levels indices = range(len(self.levels)) @@ -140,16 +126,10 @@ #self.cl_cvalues = [] # same self.cl_xy = [] - if self.manual_select: - 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.' + self.labels(inline) - blocking_contour_labeler = BlockingContourLabeler(self) - blocking_contour_labeler(inline) - else: - self.labels(inline) + for label in self.cl: + self.ax.add_artist(label) self.label_list = cbook.silent_list('text.Text', self.cl) return self.label_list @@ -161,10 +141,10 @@ if lcsize > 10 * labelwidth: return 1 - xmax = np.amax(linecontour[:,0]) - xmin = np.amin(linecontour[:,0]) - ymax = np.amax(linecontour[:,1]) - ymin = np.amin(linecontour[:,1]) + xmax = np.amax(np.array(linecontour)[:,0]) + xmin = np.amin(np.array(linecontour)[:,0]) + ymax = np.amax(np.array(linecontour)[:,1]) + ymin = np.amin(np.array(linecontour)[:,1]) lw = labelwidth if (xmax - xmin) > 1.2* lw or (ymax - ymin) > 1.2 * lw: @@ -213,7 +193,7 @@ if cbook.is_string_like(lev): lw = (len(lev)) * fsize else: - lw = (len(self.get_text(lev,fmt))) * fsize + lw = (len(fmt%lev)) * fsize return lw @@ -230,11 +210,9 @@ if cbook.is_string_like(lev): return lev else: - if isinstance(fmt,dict): - return fmt[lev] - else: - return fmt%lev + return fmt%lev + def break_linecontour(self, linecontour, rot, labelwidth, ind): "break a contour in two contours at the location of the label" lcsize = len(linecontour) @@ -248,8 +226,8 @@ slc = trans.transform(linecontour) x,y = slc[ind] - xx=slc[:,0].copy() - yy=slc[:,1].copy() + xx= np.asarray(slc)[:,0].copy() + yy=np.asarray(slc)[:,1].copy() #indices which are under the label inds, = np.nonzero(((xx < x+xlabel) & (xx > x-xlabel)) & @@ -330,8 +308,8 @@ else: ysize = labelwidth - XX = np.resize(linecontour[:,0],(xsize, ysize)) - YY = np.resize(linecontour[:,1],(xsize, ysize)) + XX = np.resize(np.asarray(linecontour)[:,0],(xsize, ysize)) + YY = np.resize(np.asarray(linecontour)[:,1],(xsize, ysize)) #I might have fouled up the following: yfirst = YY[:,0].reshape(xsize, 1) ylast = YY[:,-1].reshape(xsize, 1) @@ -357,85 +335,19 @@ return x,y, rotation, dind - def add_label(self,x,y,rotation,icon): - dx,dy = self.ax.transData.inverted().transform_point((x,y)) - t = text.Text(dx, dy, rotation = rotation, - horizontalalignment='center', - verticalalignment='center') - - color = self.label_mappable.to_rgba(self.label_cvalues[icon], - alpha=self.alpha) - - _text = self.get_text(self.label_levels[icon],self.fmt) - self.set_label_props(t, _text, color) - self.cl.append(t) - self.cl_cvalues.append(self.label_cvalues[icon]) - - # Add label to plot here - useful for manual mode label selection - self.ax.add_artist(t) - - def pop_label(self,index=-1): - '''Defaults to removing last label, but any index can be supplied''' - self.cl_cvalues.pop(index) - t = self.cl.pop(index) - t.remove() - - def find_nearest_contour( self, x, y, pixel=True ): - """ - Finds contour that is closest to a point. Defaults to - measuring distance in pixels (screen space - useful for manual - contour labeling), but this can be controlled via a keyword - argument. - - Returns a tuple containing the contour, segment, index of - segment, x & y of segment point and distance to minimum point. - """ - - # This function uses a method that is probably quite - # inefficient based on converting each contour segment to - # pixel coordinates and then comparing the given point to - # those coordinates for each contour. This will probably be - # quite slow for complex contours, but for normal use it works - # sufficiently well that the time is not noticeable. - # Nonetheless, improvements could probably be made. - - dmin = 1e10 - conmin = None - segmin = None - xmin = None - ymin = None - - for icon in self.label_indices: - con = self.collections[icon] - paths = con.get_paths() - for segNum, linepath in enumerate(paths): - lc = linepath.vertices - - # transfer all data points to screen coordinates if desired - if pixel: - lc = self.ax.transData.transform(lc) - - ds = (lc[:,0]-x)**2 + (lc[:,1]-y)**2 - d = min( ds ) - if d < dmin: - dmin = d - conmin = icon - segmin = segNum - imin = mpl.mlab.find( ds == d )[0] - xmin = lc[imin,0] - ymin = lc[imin,1] - - return (conmin,segmin,imin,xmin,ymin,dmin) - def labels(self, inline): levels = self.label_levels fslist = self.fslist trans = self.ax.transData - - for icon, lev, fsize in zip(self.label_indices, - self.label_levels, fslist): + _colors = self.label_mappable.to_rgba(self.label_cvalues, + alpha=self.alpha) + fmt = self.fmt + for icon, lev, color, cvalue, fsize in zip(self.label_indices, + self.label_levels, + _colors, + self.label_cvalues, fslist): con = self.collections[icon] - lw = self.get_label_width(lev, self.fmt, fsize) + lw = self.get_label_width(lev, fmt, fsize) additions = [] paths = con.get_paths() for segNum, linepath in enumerate(paths): @@ -450,8 +362,16 @@ slc = trans.transform(linecontour) if self.print_label(slc,lw): x,y, rotation, ind = self.locate_label(slc, lw) - self.add_label(x,y,rotation,icon) - + # transfer the location of the label back to + # data coordinates + dx,dy = trans.inverted().transform_point((x,y)) + t = text.Text(dx, dy, rotation = rotation, + horizontalalignment='center', + verticalalignment='center') + _text = self.get_text(lev,fmt) + self.set_label_props(t, _text, color) + self.cl.append(t) + self.cl_cvalues.append(cvalue) if inline: new = self.break_linecontour(linecontour, rotation, lw, ind) if len(new[0]): @@ -882,8 +802,19 @@ Use keyword args to control colors, linewidth, origin, cmap ... see below for more details. - *X*, *Y*, and *Z* must be arrays with the same dimensions. + *X*, *Y*, and *Z* may be arrays all with the same 2-D shape, or + *X* and *Y* can be 1-D while *Z* is 2-D. In the latter + case, the following must be true: + :: + + Z.shape == len(Y), len(X) + + Note that the first index of *Z*, the row number, corresponds + to the vertical coordinate on the page, while the second + index, the column number, corresponds to the horizontal + coordinate on the page. + *Z* may be a masked array, but filled contouring may not handle internal masked regions correctly. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Revision: 5792 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5792&view=rev Author: fer_perez Date: 2008年07月19日 07:05:43 +0000 (2008年7月19日) Log Message: ----------- Add a new f2py example that uses F90 (it's still very simple). Added Paths: ----------- trunk/py4science/examples/numpy_wrap/f2py/example4/ trunk/py4science/examples/numpy_wrap/f2py/example4/Makefile trunk/py4science/examples/numpy_wrap/f2py/example4/README.txt trunk/py4science/examples/numpy_wrap/f2py/example4/setup.cfg trunk/py4science/examples/numpy_wrap/f2py/example4/setup.py trunk/py4science/examples/numpy_wrap/f2py/example4/simple.f90 trunk/py4science/examples/numpy_wrap/f2py/example4/simple.pyf trunk/py4science/examples/numpy_wrap/f2py/example4/test_simple.py Added: trunk/py4science/examples/numpy_wrap/f2py/example4/Makefile =================================================================== --- trunk/py4science/examples/numpy_wrap/f2py/example4/Makefile (rev 0) +++ trunk/py4science/examples/numpy_wrap/f2py/example4/Makefile 2008年07月19日 07:05:43 UTC (rev 5792) @@ -0,0 +1,39 @@ +# Python wrappers for a simple Fortran 90 library + +# Build the actual library using a standard Python setup.py script +build: simple.so + +simple.so: simple.f90 simple.pyf setup.py + ./setup.py config_fc build_ext --inplace + +# Build the library in place via a direct call to f2py, using the manually +# modified simple.pyf file. +libpyf: simple.f90 simple.pyf + f2py -c --fcompiler=gnu95 simple.pyf simple.f90 + +# Build the 'raw' library by hand, without any tweaks to the python interface +# of any function. Note that this will NOT pass the tests, since the tests +# expect the modified interface. +libraw: simple.f90 + f2py -c --fcompiler=gnu95 -m simple simple.f90 + +# Run a very simple test. +test: build + python test_simple.py + +# If you have nose installed, the test above can be run as a proper unittest. +nose: build + nosetests test_simple.py + +# Build the .pyf file. Note that the supplied file simple.pyf has been +# manually modified from the auto-generated one. It's a good idea to +# auto-generate one with a different name if you intend to manually edit yours +# later, to help prevent an accidental clobbering. +pyf: simple.f90 + f2py -h simple_auto.pyf -m simple simple.f90 + +clean: + rm -rf *~ *module.c *.pyc *-f2pywrappers*.f90 build + +cleanall: clean + rm -rf *.so Added: trunk/py4science/examples/numpy_wrap/f2py/example4/README.txt =================================================================== --- trunk/py4science/examples/numpy_wrap/f2py/example4/README.txt (rev 0) +++ trunk/py4science/examples/numpy_wrap/f2py/example4/README.txt 2008年07月19日 07:05:43 UTC (rev 5792) @@ -0,0 +1,24 @@ +================================================== + Very simple Fortran 90 wrapping example via f2py +================================================== + +This small, self-contained directory shows how to build an extension for Python +based on Fortran 90 code. You can do it both by directly calling f2py and via +a small setup.py file. + +See the accompanying makefile for the actual targets provided, but if you are +impatient and have gfortran installed, simply type:: + + make test + +which should run the build and a simple test. If no errors are printed at the +end, you're fine. If you have nose installed (highly recommended and needed to +test numpy and scipy, see +http://www.somethingaboutorange.com/mrl/projects/nose/) you can try instead:: + + make nose + +This will run the same test files but as proper tests, indicating number of +tests, errors/failures, etc. There is currently only one test provided, but +using this in your projects will get you going with proper testing practices +from the start. Added: trunk/py4science/examples/numpy_wrap/f2py/example4/setup.cfg =================================================================== --- trunk/py4science/examples/numpy_wrap/f2py/example4/setup.cfg (rev 0) +++ trunk/py4science/examples/numpy_wrap/f2py/example4/setup.cfg 2008年07月19日 07:05:43 UTC (rev 5792) @@ -0,0 +1,2 @@ +[config_fc] +fcompiler = gnu95 Added: trunk/py4science/examples/numpy_wrap/f2py/example4/setup.py =================================================================== --- trunk/py4science/examples/numpy_wrap/f2py/example4/setup.py (rev 0) +++ trunk/py4science/examples/numpy_wrap/f2py/example4/setup.py 2008年07月19日 07:05:43 UTC (rev 5792) @@ -0,0 +1,32 @@ +#!/usr/bin/env python +"""Setup script for f2py-wrapped library. +""" + +# Third-party modules +from numpy.distutils.core import setup +from numpy.distutils.extension import Extension + +# Build the extension module object +extmod = Extension( name = 'simple', + # List here the interface (.pyf) file, plus any sources + # that need to be explicitly compiled into the wrapped + # module (i.e., not already part of one of the fortran + # libraries listed below): + sources = ['simple.pyf', + 'simple.f90' + ], + + # Additional libraries required by our extension modules + libraries = [], + + # Add '--debug-capi' for verbose debugging of low-level + # calls + #f2py_options = ['--debug-capi'], + ) + +# Make the actual distutils setup call +setup(name = 'simple', # name of the generated extension (.so) + description = 'Segmentation library', + author = 'Felipe Arrate', + ext_modules = [extmod], + ) Property changes on: trunk/py4science/examples/numpy_wrap/f2py/example4/setup.py ___________________________________________________________________ Added: svn:executable + * Added: trunk/py4science/examples/numpy_wrap/f2py/example4/simple.f90 =================================================================== --- trunk/py4science/examples/numpy_wrap/f2py/example4/simple.f90 (rev 0) +++ trunk/py4science/examples/numpy_wrap/f2py/example4/simple.f90 2008年07月19日 07:05:43 UTC (rev 5792) @@ -0,0 +1,29 @@ + +! Matlab-like linspace() +Subroutine linspace(x,y,lin,n) +Integer n,i +Real(8) lin(n) +Real x,y + +!write(6,*) "x",x,"y",y,"n",n ! dbg + +Do i=1,n-1 + lin(i)=x+(i-1)*(y-x)/(n-1) +End Do +lin(n)=y; +END Subroutine linspace + +! An identical copy of the above, simply to demo in the python wrapping a +! different way to expose the API for instructional purposes. +Subroutine linspace2(x,y,lin,n) +Integer n,i +Real(8) lin(n) +Real x,y + +!write(6,*) "x",x,"y",y,"n",n ! dbg + +Do i=1,n-1 + lin(i)=x+(i-1)*(y-x)/(n-1) +End Do +lin(n)=y; +END Subroutine linspace2 Added: trunk/py4science/examples/numpy_wrap/f2py/example4/simple.pyf =================================================================== --- trunk/py4science/examples/numpy_wrap/f2py/example4/simple.pyf (rev 0) +++ trunk/py4science/examples/numpy_wrap/f2py/example4/simple.pyf 2008年07月19日 07:05:43 UTC (rev 5792) @@ -0,0 +1,30 @@ +! -*- f90 -*- +! Note: the context of this file is case sensitive. + +! NOTE: This file HAS BEEN MODIFIED! An auto-generated f2py interface was used +! as a starting point and then modified. If you overwrite it, you'll lose all +! changes. + +python module simple ! in + interface ! in :simple + + ! Default interface produced by 'f2py -h simple.pyf simple.f90' + subroutine linspace(x,y,lin,n) ! in :simple:simple.f90 + real :: x + real :: y + real(kind=8) dimension(n) :: lin + integer optional,check(len(lin)>=n),depend(lin) :: n=len(lin) + end subroutine linspace + + ! Modified interface: linspace2 is identical to linspace in Fortran, but + ! here we change its interface to a simpler that doesn't require the + ! external allocation of the output array. + subroutine linspace2(x,y,lin,n) ! in :simple:simple.f90 + real :: x + real :: y + integer :: n + real(kind=8) dimension(n),intent(out),depend(n) :: lin + end subroutine linspace2 + + end interface +end python module simple Added: trunk/py4science/examples/numpy_wrap/f2py/example4/test_simple.py =================================================================== --- trunk/py4science/examples/numpy_wrap/f2py/example4/test_simple.py (rev 0) +++ trunk/py4science/examples/numpy_wrap/f2py/example4/test_simple.py 2008年07月19日 07:05:43 UTC (rev 5792) @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +import numpy as np + +import simple + +def test_linspace(): + """Test both versions of linspace for consistency.""" + n,x,y = 5, 0, 2.0 + a = np.empty(n) + + simple.linspace(x,y,a) + print a + + b = simple.linspace2(x,y,n) + print b + + np.testing.assert_almost_equal(a,b,15) + +if __name__ == '__main__': + test_linspace() Property changes on: trunk/py4science/examples/numpy_wrap/f2py/example4/test_simple.py ___________________________________________________________________ Added: svn:executable + * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.