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
|
|
From: <js...@us...> - 2009-01-16 16:12:29
|
Revision: 6787
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6787&view=rev
Author: jswhit
Date: 2009-01-16 16:12:27 +0000 (Fri, 16 Jan 2009)
Log Message:
-----------
apply Michiel's patch to macosx backend to fix rounding bug - closes
sf bug 2508440.
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/src/_macosx.m
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2009-01-16 15:39:17 UTC (rev 6786)
+++ trunk/matplotlib/CHANGELOG 2009-01-16 16:12:27 UTC (rev 6787)
@@ -1,3 +1,6 @@
+2009-01-16 Applied Michiel's patch for macosx backend to fix rounding
+ bug. Closed sf bug 2508440 - JSW
+
2009-01-10 Fix bug in pan/zoom with log coordinates. - EF
2009-01-10 Applied Michiel's hatch patch for macosx backend and
Modified: trunk/matplotlib/src/_macosx.m
===================================================================
--- trunk/matplotlib/src/_macosx.m 2009-01-16 15:39:17 UTC (rev 6786)
+++ trunk/matplotlib/src/_macosx.m 2009-01-16 16:12:27 UTC (rev 6787)
@@ -17,7 +17,24 @@
#define CGFloat float
#endif
+/* This is the same as CGAffineTransform, except that the data members are
+ * doubles rather than CGFloats.
+ * Matrix structure:
+ * [ a b 0]
+ * [ c d 0]
+ * [ tx ty 1]
+ */
+typedef struct
+{
+ double a;
+ double b;
+ double c;
+ double d;
+ double tx;
+ double ty;
+} AffineTransform;
+
/* Various NSApplicationDefined event subtypes */
#define STDIN_READY 0
#define SIGINT_CALLED 1
@@ -169,6 +186,19 @@
return 1;
}
+static AffineTransform
+AffineTransformConcat(AffineTransform t1, AffineTransform t2)
+{
+ AffineTransform t;
+ t.a = t1.a * t2.a + t1.b * t2.c;
+ t.b = t1.a * t2.b + t1.b * t2.d;
+ t.c = t1.c * t2.a + t1.d * t2.c;
+ t.d = t1.c * t2.b + t1.d * t2.d;
+ t.tx = t1.tx * t2.a + t1.ty * t2.c + t2.tx;
+ t.ty = t1.tx * t2.b + t1.ty * t2.d + t2.ty;
+ return t;
+}
+
static int _init_atsui(void)
{
OSStatus status;
@@ -208,9 +238,10 @@
}
static int
-_draw_path(CGContextRef cr, PyObject* path, CGAffineTransform affine)
+_draw_path(CGContextRef cr, PyObject* path, AffineTransform affine)
{
- CGPoint point;
+ double x1, y1, x2, y2, x3, y3;
+ CGFloat fx1, fy1, fx2, fy2, fx3, fy3;
PyObject* vertices = PyObject_GetAttrString(path, "vertices");
if (vertices==NULL)
@@ -271,22 +302,23 @@
npy_uint8 code = MOVETO;
for (i = 0; i < n; i++)
{
- point.x = (CGFloat)(*(double*)PyArray_GETPTR2(coordinates, i, 0));
- point.y = (CGFloat)(*(double*)PyArray_GETPTR2(coordinates, i, 1));
- if (isnan(point.x) || isnan(point.y))
+ x1 = *(double*)PyArray_GETPTR2(coordinates, i, 0);
+ y1 = *(double*)PyArray_GETPTR2(coordinates, i, 1);
+ if (isnan(x1) || isnan(y1))
{
code = MOVETO;
}
else
{
- point = CGPointApplyAffineTransform(point, affine);
+ fx1 = (CGFloat)(affine.a*x1 + affine.c*y1 + affine.tx);
+ fy1 = (CGFloat)(affine.b*x1 + affine.d*y1 + affine.ty);
switch (code)
{
case MOVETO:
- CGContextMoveToPoint(cr, point.x, point.y);
+ CGContextMoveToPoint(cr, fx1, fy1);
break;
case LINETO:
- CGContextAddLineToPoint(cr, point.x, point.y);
+ CGContextAddLineToPoint(cr, fx1, fy1);
break;
}
code = LINETO;
@@ -298,7 +330,6 @@
npy_intp i = 0;
BOOL was_nan = false;
npy_uint8 code;
- CGFloat x1, y1, x2, y2, x3, y3;
while (i < n)
{
code = *(npy_uint8*)PyArray_GETPTR1(codelist, i);
@@ -315,8 +346,8 @@
{
if (code==CURVE3) i++;
else if (code==CURVE4) i+=2;
- x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
- y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+ x1 = *(double*)PyArray_GETPTR2(coordinates, i, 0);
+ y1 = *(double*)PyArray_GETPTR2(coordinates, i, 1);
i++;
if (isnan(x1) || isnan(y1))
{
@@ -324,17 +355,16 @@
}
else
{
- point.x = x1;
- point.y = y1;
- point = CGPointApplyAffineTransform(point, affine);
- CGContextMoveToPoint(cr, point.x, point.y);
+ fx1 = (CGFloat) (affine.a*x1 + affine.c*y1 + affine.tx);
+ fy1 = (CGFloat) (affine.b*x1 + affine.d*y1 + affine.ty);
+ CGContextMoveToPoint(cr, fx1, fy1);
was_nan = false;
}
}
else if (code==MOVETO)
{
- x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
- y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+ x1 = *(double*)PyArray_GETPTR2(coordinates, i, 0);
+ y1 = *(double*)PyArray_GETPTR2(coordinates, i, 1);
i++;
if (isnan(x1) || isnan(y1))
{
@@ -342,17 +372,16 @@
}
else
{
- point.x = x1;
- point.y = y1;
- point = CGPointApplyAffineTransform(point, affine);
- CGContextMoveToPoint(cr, point.x, point.y);
+ fx1 = (CGFloat) (affine.a*x1 + affine.c*y1 + affine.tx);
+ fy1 = (CGFloat) (affine.b*x1 + affine.d*y1 + affine.ty);
+ CGContextMoveToPoint(cr, fx1, fy1);
was_nan = false;
}
}
else if (code==LINETO)
{
- x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
- y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+ x1 = *(double*)PyArray_GETPTR2(coordinates, i, 0);
+ y1 = *(double*)PyArray_GETPTR2(coordinates, i, 1);
i++;
if (isnan(x1) || isnan(y1))
{
@@ -360,20 +389,19 @@
}
else
{
- point.x = x1;
- point.y = y1;
- point = CGPointApplyAffineTransform(point, affine);
- CGContextAddLineToPoint(cr, point.x, point.y);
+ fx1 = (CGFloat) (affine.a*x1 + affine.c*y1 + affine.tx);
+ fy1 = (CGFloat) (affine.b*x1 + affine.d*y1 + affine.ty);
+ CGContextAddLineToPoint(cr, fx1, fy1);
was_nan = false;
}
}
else if (code==CURVE3)
{
- x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
- y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+ x1 = *(double*)PyArray_GETPTR2(coordinates, i, 0);
+ y1 = *(double*)PyArray_GETPTR2(coordinates, i, 1);
i++;
- x2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
- y2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+ x2 = *(double*)PyArray_GETPTR2(coordinates, i, 0);
+ y2 = *(double*)PyArray_GETPTR2(coordinates, i, 1);
i++;
if (isnan(x1) || isnan(y1) || isnan(x2) || isnan(y2))
{
@@ -381,30 +409,24 @@
}
else
{
- point.x = x1;
- point.y = y1;
- point = CGPointApplyAffineTransform(point, affine);
- x1 = point.x;
- y1 = point.y;
- point.x = x2;
- point.y = y2;
- point = CGPointApplyAffineTransform(point, affine);
- x2 = point.x;
- y2 = point.y;
- CGContextAddQuadCurveToPoint(cr, x1, y1, x2, y2);
+ fx1 = (CGFloat) (affine.a*x1 + affine.c*y1 + affine.tx);
+ fy1 = (CGFloat) (affine.b*x1 + affine.d*y1 + affine.ty);
+ fx2 = (CGFloat) (affine.a*x2 + affine.c*y2 + affine.tx);
+ fy2 = (CGFloat) (affine.b*x2 + affine.d*y2 + affine.ty);
+ CGContextAddQuadCurveToPoint(cr, fx1, fy1, fx2, fy2);
was_nan = false;
}
}
else if (code==CURVE4)
{
- x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
- y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+ x1 = *(double*)PyArray_GETPTR2(coordinates, i, 0);
+ y1 = *(double*)PyArray_GETPTR2(coordinates, i, 1);
i++;
- x2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
- y2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+ x2 = *(double*)PyArray_GETPTR2(coordinates, i, 0);
+ y2 = *(double*)PyArray_GETPTR2(coordinates, i, 1);
i++;
- x3 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
- y3 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+ x3 = *(double*)PyArray_GETPTR2(coordinates, i, 0);
+ y3 = *(double*)PyArray_GETPTR2(coordinates, i, 1);
i++;
if (isnan(x1) || isnan(y1) || isnan(x2) || isnan(y2) || isnan(x3) || isnan(y3))
{
@@ -412,22 +434,13 @@
}
else
{
- point.x = x1;
- point.y = y1;
- point = CGPointApplyAffineTransform(point, affine);
- x1 = point.x;
- y1 = point.y;
- point.x = x2;
- point.y = y2;
- point = CGPointApplyAffineTransform(point, affine);
- x2 = point.x;
- y2 = point.y;
- point.x = x3;
- point.y = y3;
- point = CGPointApplyAffineTransform(point, affine);
- x3 = point.x;
- y3 = point.y;
- CGContextAddCurveToPoint(cr, x1, y1, x2, y2, x3, y3);
+ fx1 = (CGFloat) (affine.a*x1 + affine.c*y1 + affine.tx);
+ fy1 = (CGFloat) (affine.b*x1 + affine.d*y1 + affine.ty);
+ fx2 = (CGFloat) (affine.a*x2 + affine.c*y2 + affine.tx);
+ fy2 = (CGFloat) (affine.b*x2 + affine.d*y2 + affine.ty);
+ fx3 = (CGFloat) (affine.a*x3 + affine.c*y3 + affine.tx);
+ fy3 = (CGFloat) (affine.b*x3 + affine.d*y3 + affine.ty);
+ CGContextAddCurveToPoint(cr, fx1, fy1, fx2, fy2, fx3, fy3);
was_nan = false;
}
}
@@ -442,8 +455,7 @@
static void _draw_hatch (void *info, CGContextRef cr)
{
PyObject* hatchpath = (PyObject*)info;
- CGAffineTransform affine = CGAffineTransformMakeScale(HATCH_SIZE, HATCH_SIZE);
-
+ AffineTransform affine = {HATCH_SIZE, 0, 0, HATCH_SIZE, 0, 0};
int n = _draw_path(cr, hatchpath, affine);
if (n < 0)
{
@@ -1061,9 +1073,9 @@
}
static int
-_convert_affine_transform(PyObject* object, CGAffineTransform* transform)
-/* Reads a Numpy affine transformation matrix and returns
- * a CGAffineTransform.
+_convert_affine_transform(PyObject* object, AffineTransform* transform)
+/* Reads a Numpy affine transformation matrix and returns an
+ * AffineTransform structure
*/
{
PyArrayObject* matrix = NULL;
@@ -1093,17 +1105,16 @@
char* row0 = PyArray_BYTES(matrix);
char* row1 = row0 + stride0;
- double a = *(double*)(row0);
+ transform->a = *(double*)(row0);
row0 += stride1;
- double c = *(double*)(row0);
+ transform->c = *(double*)(row0);
row0 += stride1;
- double e = *(double*)(row0);
- double b = *(double*)(row1);
+ transform->tx = *(double*)(row0);
+ transform->b = *(double*)(row1);
row1 += stride1;
- double d = *(double*)(row1);
+ transform->d = *(double*)(row1);
row1 += stride1;
- double f = *(double*)(row1);
- *transform = CGAffineTransformMake(a, b, c, d, e, f);
+ transform->ty = *(double*)(row1);
Py_DECREF(matrix);
return 1;
@@ -1133,7 +1144,7 @@
if(rgbFace==Py_None) rgbFace = NULL;
- CGAffineTransform affine;
+ AffineTransform affine;
ok = _convert_affine_transform(transform, &affine);
if (!ok) return NULL;
@@ -1223,6 +1234,7 @@
int ok;
float r, g, b;
+ double x, y;
CGContextRef cr = self->cr;
@@ -1251,11 +1263,11 @@
CGContextSetRGBFillColor(cr, r, g, b, 1.0);
}
- CGAffineTransform affine;
+ AffineTransform affine;
ok = _convert_affine_transform(transform, &affine);
if (!ok) return NULL;
- CGAffineTransform marker_affine;
+ AffineTransform marker_affine;
ok = _convert_affine_transform(marker_transform, &marker_affine);
if (!ok) return NULL;
@@ -1285,17 +1297,15 @@
npy_intp i;
npy_intp n = PyArray_DIM(coordinates, 0);
- CGPoint point;
- CGAffineTransform t;
+ AffineTransform t;
int m = 0;
for (i = 0; i < n; i++)
{
- point.x = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
- point.y = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
- point = CGPointApplyAffineTransform(point, affine);
+ x = *(double*)PyArray_GETPTR2(coordinates, i, 0);
+ y = *(double*)PyArray_GETPTR2(coordinates, i, 1);
t = marker_affine;
- t.tx += point.x;
- t.ty += point.y;
+ t.tx += affine.a*x + affine.c*y + affine.tx;
+ t.ty += affine.b*x + affine.d*y + affine.ty;
m = _draw_path(cr, marker_path, t);
if (m > 0)
@@ -1391,10 +1401,10 @@
CGContextSaveGState(cr);
- CGAffineTransform transform;
- CGAffineTransform master_transform;
- CGAffineTransform offset_transform;
- CGAffineTransform* transforms = NULL;
+ AffineTransform transform;
+ AffineTransform master_transform;
+ AffineTransform offset_transform;
+ AffineTransform* transforms = NULL;
if (!_convert_affine_transform(master_transform_obj, &master_transform)) return NULL;
if (!_convert_affine_transform(offset_transform_obj, &offset_transform)) return NULL;
@@ -1496,18 +1506,18 @@
/* Convert all of the transforms up front */
if (Ntransforms > 0)
{
- transforms = malloc(Ntransforms*sizeof(CGAffineTransform));
+ transforms = malloc(Ntransforms*sizeof(AffineTransform));
if (!transforms) goto error;
for (i = 0; i < Ntransforms; i++)
{
PyObject* transform_obj = PySequence_ITEM(transforms_obj, i);
if(!_convert_affine_transform(transform_obj, &transforms[i])) goto error;
- transforms[i] = CGAffineTransformConcat(transforms[i], master_transform);
+ transforms[i] = AffineTransformConcat(transforms[i], master_transform);
}
}
- CGPoint offset;
PyObject* path;
+ double x, y;
/* Preset graphics context properties if possible */
if (Naa==1)
@@ -1574,11 +1584,10 @@
if (Noffsets)
{
- offset.x = (CGFloat) (*(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0));
- offset.y = (CGFloat) (*(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1));
- offset = CGPointApplyAffineTransform(offset, offset_transform);
- transform.tx += offset.x;
- transform.ty += offset.y;
+ x = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0);
+ y = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1);
+ transform.tx += offset_transform.a*x + offset_transform.c*y + offset_transform.tx;
+ transform.ty += offset_transform.b*x + offset_transform.d*y + offset_transform.ty;
}
if (Naa > 1)
@@ -1703,9 +1712,9 @@
PyArrayObject* offsets = NULL;
PyArrayObject* facecolors = NULL;
- CGAffineTransform transform;
- CGAffineTransform master_transform;
- CGAffineTransform offset_transform;
+ AffineTransform transform;
+ AffineTransform master_transform;
+ AffineTransform offset_transform;
if (!_convert_affine_transform(master_transform_obj, &master_transform))
return NULL;
@@ -1772,8 +1781,6 @@
size_t iw = 0;
size_t ih = 0;
- CGPoint offset;
-
/* Preset graphics context properties if possible */
if (antialiased) CGContextSetShouldAntialias(cr, true);
else CGContextSetShouldAntialias(cr, false);
@@ -1798,6 +1805,7 @@
CGContextSetRGBStrokeColor(cr, 0, 0, 0, 1);
}
+ double x, y;
for (ih = 0; ih < meshHeight; ih++)
{
for (iw = 0; iw < meshWidth; iw++, i++)
@@ -1807,35 +1815,38 @@
if (Noffsets)
{
- offset.x = (CGFloat) (*(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0));
- offset.y = (CGFloat) (*(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1));
- offset = CGPointApplyAffineTransform(offset, offset_transform);
- transform.tx += offset.x;
- transform.ty += offset.y;
+ x = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0);
+ y = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1);
+ transform.tx += offset_transform.a*x + offset_transform.c*y + offset_transform.tx;
+ transform.ty += offset_transform.b*x + offset_transform.d*y + offset_transform.ty;
}
- CGPoint p;
+ double x, y;
CGPoint points[4];
- p.x = (CGFloat)(*(double*)PyArray_GETPTR3(coordinates, ih, iw, 0));
- p.y = (CGFloat)(*(double*)PyArray_GETPTR3(coordinates, ih, iw, 1));
- if (isnan(p.x) || isnan(p.y)) continue;
- points[0] = CGPointApplyAffineTransform(p, transform);
+ x = *(double*)PyArray_GETPTR3(coordinates, ih, iw, 0);
+ y = *(double*)PyArray_GETPTR3(coordinates, ih, iw, 1);
+ if (isnan(x) || isnan(y)) continue;
+ points[0].x = (CGFloat)(transform.a*x + transform.c*y + transform.tx);
+ points[0].y = (CGFloat)(transform.b*x + transform.d*y + transform.ty);
- p.x = (CGFloat)(*(double*)PyArray_GETPTR3(coordinates, ih, iw+1, 0));
- p.y = (CGFloat)(*(double*)PyArray_GETPTR3(coordinates, ih, iw+1, 1));
- if (isnan(p.x) || isnan(p.y)) continue;
- points[1] = CGPointApplyAffineTransform(p, transform);
+ x = *(double*)PyArray_GETPTR3(coordinates, ih, iw+1, 0);
+ y = *(double*)PyArray_GETPTR3(coordinates, ih, iw+1, 1);
+ if (isnan(x) || isnan(y)) continue;
+ points[1].x = (CGFloat)(transform.a*x + transform.c*y + transform.tx);
+ points[1].y = (CGFloat)(transform.b*x + transform.d*y + transform.ty);
- p.x = (CGFloat)(*(double*)PyArray_GETPTR3(coordinates, ih+1, iw+1, 0));
- p.y = (CGFloat)(*(double*)PyArray_GETPTR3(coordinates, ih+1, iw+1, 1));
- if (isnan(p.x) || isnan(p.y)) continue;
- points[2] = CGPointApplyAffineTransform(p, transform);
+ x = *(double*)PyArray_GETPTR3(coordinates, ih+1, iw+1, 0);
+ y = *(double*)PyArray_GETPTR3(coordinates, ih+1, iw+1, 1);
+ if (isnan(x) || isnan(y)) continue;
+ points[2].x = (CGFloat)(transform.a*x + transform.c*y + transform.tx);
+ points[2].y = (CGFloat)(transform.b*x + transform.d*y + transform.ty);
- p.x = (CGFloat)(*(double*)PyArray_GETPTR3(coordinates, ih+1, iw, 0));
- p.y = (CGFloat)(*(double*)PyArray_GETPTR3(coordinates, ih+1, iw, 1));
- if (isnan(p.x) || isnan(p.y)) continue;
- points[3] = CGPointApplyAffineTransform(p, transform);
+ x = *(double*)PyArray_GETPTR3(coordinates, ih+1, iw, 0);
+ y = *(double*)PyArray_GETPTR3(coordinates, ih+1, iw, 1);
+ if (isnan(x) || isnan(y)) continue;
+ points[3].x = (CGFloat)(transform.a*x + transform.c*y + transform.tx);
+ points[3].y = (CGFloat)(transform.b*x + transform.d*y + transform.ty);
CGContextMoveToPoint(cr, points[3].x, points[3].y);
CGContextAddLines(cr, points, 4);
@@ -2491,7 +2502,7 @@
if (!_clip(cr, cliprect)) ok = false;
else if (clippath!=Py_None)
{
- CGAffineTransform transform;
+ AffineTransform transform;
if (!_convert_affine_transform(clippath_transform, &transform))
{
ok = false;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-01-16 15:39:22
|
Revision: 6786
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6786&view=rev
Author: jdh2358
Date: 2009-01-16 15:39:17 +0000 (Fri, 16 Jan 2009)
Log Message:
-----------
added Tom Krauss' wx fourier demo
Added Paths:
-----------
trunk/matplotlib/examples/user_interfaces/fourier_demo_wx.py
Added: trunk/matplotlib/examples/user_interfaces/fourier_demo_wx.py
===================================================================
--- trunk/matplotlib/examples/user_interfaces/fourier_demo_wx.py (rev 0)
+++ trunk/matplotlib/examples/user_interfaces/fourier_demo_wx.py 2009-01-16 15:39:17 UTC (rev 6786)
@@ -0,0 +1,214 @@
+import numpy as np
+import wx
+
+import matplotlib
+matplotlib.interactive(False)
+matplotlib.use('WXAgg')
+from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
+from matplotlib.figure import Figure
+from matplotlib.pyplot import gcf, setp
+
+
+class Knob:
+ """
+ Knob - simple class with a "setKnob" method.
+ A Knob instance is attached to a Param instance, e.g. param.attach(knob)
+ Base class is for documentation purposes.
+ """
+ def setKnob(self, value):
+ pass
+
+
+class Param:
+ """
+ The idea of the "Param" class is that some parameter in the GUI may have
+ several knobs that both control it and reflect the parameter's state, e.g.
+ a slider, text, and dragging can all change the value of the frequency in
+ the waveform of this example.
+ The class allows a cleaner way to update/"feedback" to the other knobs when
+ one is being changed. Also, this class handles min/max constraints for all
+ the knobs.
+ Idea - knob list - in "set" method, knob object is passed as well
+ - the other knobs in the knob list have a "set" method which gets
+ called for the others.
+ """
+ def __init__(self, initialValue=None, minimum=0., maximum=1.):
+ self.minimum = minimum
+ self.maximum = maximum
+ if initialValue != self.constrain(initialValue):
+ raise ValueError('illegal initial value')
+ self.value = initialValue
+ self.knobs = []
+
+ def attach(self, knob):
+ self.knobs += [knob]
+
+ def set(self, value, knob=None):
+ self.value = value
+ self.value = self.constrain(value)
+ for feedbackKnob in self.knobs:
+ if feedbackKnob != knob:
+ feedbackKnob.setKnob(self.value)
+ return self.value
+
+ def constrain(self, value):
+ if value <= self.minimum:
+ value = self.minimum
+ if value >= self.maximum:
+ value = self.maximum
+ return value
+
+
+class SliderGroup(Knob):
+ def __init__(self, parent, label, param):
+ self.sliderLabel = wx.StaticText(parent, label=label)
+ self.sliderText = wx.TextCtrl(parent, -1, style=wx.TE_PROCESS_ENTER)
+ self.slider = wx.Slider(parent, -1)
+ self.slider.SetMax(param.maximum*1000)
+ self.setKnob(param.value)
+
+ sizer = wx.BoxSizer(wx.HORIZONTAL)
+ sizer.Add(self.sliderLabel, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=2)
+ sizer.Add(self.sliderText, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=2)
+ sizer.Add(self.slider, 1, wx.EXPAND)
+ self.sizer = sizer
+
+ self.slider.Bind(wx.EVT_SLIDER, self.sliderHandler)
+ self.sliderText.Bind(wx.EVT_TEXT_ENTER, self.sliderTextHandler)
+
+ self.param = param
+ self.param.attach(self)
+
+ def sliderHandler(self, evt):
+ value = evt.GetInt() / 1000.
+ self.param.set(value)
+
+ def sliderTextHandler(self, evt):
+ value = float(self.sliderText.GetValue())
+ self.param.set(value)
+
+ def setKnob(self, value):
+ self.sliderText.SetValue('%g'%value)
+ self.slider.SetValue(value*1000)
+
+
+class FourierDemoFrame(wx.Frame):
+ def __init__(self, *args, **kwargs):
+ wx.Frame.__init__(self, *args, **kwargs)
+
+ self.fourierDemoWindow = FourierDemoWindow(self)
+ self.frequencySliderGroup = SliderGroup(self, label='Frequency f0:', \
+ param=self.fourierDemoWindow.f0)
+ self.amplitudeSliderGroup = SliderGroup(self, label=' Amplitude a:', \
+ param=self.fourierDemoWindow.A)
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer.Add(self.fourierDemoWindow, 1, wx.EXPAND)
+ sizer.Add(self.frequencySliderGroup.sizer, 0, \
+ wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=5)
+ sizer.Add(self.amplitudeSliderGroup.sizer, 0, \
+ wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=5)
+ self.SetSizer(sizer)
+
+
+class FourierDemoWindow(wx.Window, Knob):
+ def __init__(self, *args, **kwargs):
+ wx.Window.__init__(self, *args, **kwargs)
+ self.lines = []
+ self.figure = Figure()
+ self.canvas = FigureCanvasWxAgg(self, -1, self.figure)
+ self.canvas.callbacks.connect('button_press_event', self.mouseDown)
+ self.canvas.callbacks.connect('motion_notify_event', self.mouseMotion)
+ self.canvas.callbacks.connect('button_release_event', self.mouseUp)
+ self.state = ''
+ self.mouseInfo = (None, None, None, None)
+ self.f0 = Param(2., minimum=0., maximum=6.)
+ self.A = Param(1., minimum=0.01, maximum=2.)
+ self.draw()
+
+ # Not sure I like having two params attached to the same Knob,
+ # but that is what we have here... it works but feels kludgy -
+ # although maybe it's not too bad since the knob changes both params
+ # at the same time (both f0 and A are affected during a drag)
+ self.f0.attach(self)
+ self.A.attach(self)
+ self.Bind(wx.EVT_SIZE, self.sizeHandler)
+
+ def sizeHandler(self, *args, **kwargs):
+ self.canvas.SetSize(self.GetSize())
+
+ def mouseDown(self, evt):
+ if self.lines[0] in self.figure.hitlist(evt):
+ self.state = 'frequency'
+ elif self.lines[1] in self.figure.hitlist(evt):
+ self.state = 'time'
+ else:
+ self.state = ''
+ self.mouseInfo = (evt.xdata, evt.ydata, max(self.f0.value, .1), self.A.value)
+
+ def mouseMotion(self, evt):
+ if self.state == '':
+ return
+ x, y = evt.xdata, evt.ydata
+ if x is None: # outside the axes
+ return
+ x0, y0, f0Init, AInit = self.mouseInfo
+ self.A.set(AInit+(AInit*(y-y0)/y0), self)
+ if self.state == 'frequency':
+ self.f0.set(f0Init+(f0Init*(x-x0)/x0))
+ elif self.state == 'time':
+ if (x-x0)/x0 != -1.:
+ self.f0.set(1./(1./f0Init+(1./f0Init*(x-x0)/x0)))
+
+ def mouseUp(self, evt):
+ self.state = ''
+
+ def draw(self):
+ if not hasattr(self, 'subplot1'):
+ self.subplot1 = self.figure.add_subplot(211)
+ self.subplot2 = self.figure.add_subplot(212)
+ x1, y1, x2, y2 = self.compute(self.f0.value, self.A.value)
+ color = (1., 0., 0.)
+ self.lines += self.subplot1.plot(x1, y1, color=color, linewidth=2)
+ self.lines += self.subplot2.plot(x2, y2, color=color, linewidth=2)
+ #Set some plot attributes
+ self.subplot1.set_title("Click and drag waveforms to change frequency and amplitude", fontsize=12)
+ self.subplot1.set_ylabel("Frequency Domain Waveform X(f)", fontsize = 8)
+ self.subplot1.set_xlabel("frequency f", fontsize = 8)
+ self.subplot2.set_ylabel("Time Domain Waveform x(t)", fontsize = 8)
+ self.subplot2.set_xlabel("time t", fontsize = 8)
+ self.subplot1.set_xlim([-6, 6])
+ self.subplot1.set_ylim([0, 1])
+ self.subplot2.set_xlim([-2, 2])
+ self.subplot2.set_ylim([-2, 2])
+ self.subplot1.text(0.05, .95, r'$X(f) = \mathcal{F}\{x(t)\}$', \
+ verticalalignment='top', transform = self.subplot1.transAxes)
+ self.subplot2.text(0.05, .95, r'$x(t) = a \cdot \cos(2\pi f_0 t) e^{-\pi t^2}$', \
+ verticalalignment='top', transform = self.subplot2.transAxes)
+
+ def compute(self, f0, A):
+ f = np.arange(-6., 6., 0.02)
+ t = np.arange(-2., 2., 0.01)
+ x = A*np.cos(2*np.pi*f0*t)*np.exp(-np.pi*t**2)
+ X = A/2*(np.exp(-np.pi*(f-f0)**2) + np.exp(-np.pi*(f+f0)**2))
+ return f, X, t, x
+
+ def repaint(self):
+ self.canvas.draw()
+
+ def setKnob(self, value):
+ # Note, we ignore value arg here and just go by state of the params
+ x1, y1, x2, y2 = self.compute(self.f0.value, self.A.value)
+ setp(self.lines[0], xdata=x1, ydata=y1)
+ setp(self.lines[1], xdata=x2, ydata=y2)
+ self.repaint()
+
+
+class App(wx.App):
+ def OnInit(self):
+ self.frame1 = FourierDemoFrame(parent=None, title="Fourier Demo", size=(640, 480))
+ self.frame1.Show()
+ return True
+
+app = App()
+app.MainLoop()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <js...@us...> - 2009-01-15 23:22:26
|
Revision: 6785
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6785&view=rev
Author: jswhit
Date: 2009-01-15 22:47:44 +0000 (Thu, 15 Jan 2009)
Log Message:
-----------
updated to work with recent versions of autoconf
Modified Paths:
--------------
trunk/toolkits/basemap/geos-2.2.3/configure.in
Modified: trunk/toolkits/basemap/geos-2.2.3/configure.in
===================================================================
--- trunk/toolkits/basemap/geos-2.2.3/configure.in 2009-01-15 19:41:52 UTC (rev 6784)
+++ trunk/toolkits/basemap/geos-2.2.3/configure.in 2009-01-15 22:47:44 UTC (rev 6785)
@@ -77,7 +77,21 @@
dnl check for libraries ---------------------------------------------------
dnl things to substitute in output ----------------------------------------
-AC_SUBST(VERSION VERSION_MAJOR VERSION_MINOR VERSION_PATCH INTERFACE_CURRENT INTERFACE_REVISION INTERFACE_AGE JTS_PORT CAPI_VERSION CAPI_VERSION_MAJOR CAPI_VERSION_MINOR CAPI_VERSION_PATCH CAPI_INTERFACE_CURRENT CAPI_INTERFACE_REVISION CAPI_INTERFACE_AGE)
+AC_SUBST(VERSION)
+AC_SUBST(VERSION_MAJOR)
+AC_SUBST(VERSION_MINOR)
+AC_SUBST(VERSION_PATCH)
+AC_SUBST(INTERFACE_CURRENT)
+AC_SUBST(INTERFACE_REVISION)
+AC_SUBST(INTERFACE_AGE)
+AC_SUBST(JTS_PORT)
+AC_SUBST(CAPI_VERSION)
+AC_SUBST(CAPI_VERSION_MAJOR)
+AC_SUBST(CAPI_VERSION_MINOR)
+AC_SUBST(CAPI_VERSION_PATCH)
+AC_SUBST(CAPI_INTERFACE_CURRENT)
+AC_SUBST(CAPI_INTERFACE_REVISION)
+AC_SUBST(CAPI_INTERFACE_AGE)
dnl output stuff ----------------------------------------------------------
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2009-01-15 19:41:57
|
Revision: 6784
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6784&view=rev
Author: mdboom
Date: 2009-01-15 19:41:52 +0000 (Thu, 15 Jan 2009)
Log Message:
-----------
[ 2502384 ] Typo in Documentation
Linestyle strings are literal-quoted to prevent Sphinx from converting the characters within them.
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/axes.py
Modified: trunk/matplotlib/lib/matplotlib/axes.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/axes.py 2009-01-14 17:54:36 UTC (rev 6783)
+++ trunk/matplotlib/lib/matplotlib/axes.py 2009-01-15 19:41:52 UTC (rev 6784)
@@ -3216,32 +3216,32 @@
================ ===============================
character description
================ ===============================
- '-' solid line style
- '--' dashed line style
- '-.' dash-dot line style
- ':' dotted line style
- '.' point marker
- ',' pixel marker
- 'o' circle marker
- 'v' triangle_down marker
- '^' triangle_up marker
- '<' triangle_left marker
- '>' triangle_right marker
- '1' tri_down marker
- '2' tri_up marker
- '3' tri_left marker
- '4' tri_right marker
- 's' square marker
- 'p' pentagon marker
- '*' star marker
- 'h' hexagon1 marker
- 'H' hexagon2 marker
- '+' plus marker
- 'x' x marker
- 'D' diamond marker
- 'd' thin_diamond marker
- '|' vline marker
- '_' hline marker
+ ``'-'`` solid line style
+ ``'--'`` dashed line style
+ ``'-.'`` dash-dot line style
+ ``':'`` dotted line style
+ ``'.'`` point marker
+ ``','`` pixel marker
+ ``'o'`` circle marker
+ ``'v'`` triangle_down marker
+ ``'^'`` triangle_up marker
+ ``'<'`` triangle_left marker
+ ``'>'`` triangle_right marker
+ ``'1'`` tri_down marker
+ ``'2'`` tri_up marker
+ ``'3'`` tri_left marker
+ ``'4'`` tri_right marker
+ ``'s'`` square marker
+ ``'p'`` pentagon marker
+ ``'*'`` star marker
+ ``'h'`` hexagon1 marker
+ ``'H'`` hexagon2 marker
+ ``'+'`` plus marker
+ ``'x'`` x marker
+ ``'D'`` diamond marker
+ ``'d'`` thin_diamond marker
+ ``'|'`` vline marker
+ ``'_'`` hline marker
================ ===============================
@@ -5348,10 +5348,10 @@
self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs)
-
+
x, y, C = cbook.delete_masked_points(x, y, C)
-
+
# Set the size of the hexagon grid
if iterable(gridsize):
nx, ny = gridsize
@@ -5561,7 +5561,7 @@
else:
thismax = thismin + np.diff(coarse)[-1]
- if not valid[i]: continue
+ if not valid[i]: continue
verts.append([(thismin, 0), (thismin, 0.05), (thismax, 0.05), (thismax, 0)])
values.append(val)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-01-14 17:54:43
|
Revision: 6783
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6783&view=rev
Author: jdh2358
Date: 2009-01-14 17:54:36 +0000 (Wed, 14 Jan 2009)
Log Message:
-----------
added Paul Ivanov's gui independent pong example
Added Paths:
-----------
trunk/matplotlib/examples/event_handling/pipong.py
trunk/matplotlib/examples/event_handling/pong_gtk.py
trunk/matplotlib/examples/event_handling/pong_qt.py
Added: trunk/matplotlib/examples/event_handling/pipong.py
===================================================================
--- trunk/matplotlib/examples/event_handling/pipong.py (rev 0)
+++ trunk/matplotlib/examples/event_handling/pipong.py 2009-01-14 17:54:36 UTC (rev 6783)
@@ -0,0 +1,257 @@
+#!/usr/bin/env python
+# A matplotlib based game of Pong illustrating one way to write interactive
+# animation which are easily ported to multiply backends
+# pipong.py was written by Paul Ivanov <http://pirsquared.org>
+
+import numpy as np
+import matplotlib.pyplot as plt
+from numpy.random import randn, randint
+
+instructions = """
+Player A: Player B:
+ 'e' up 'i'
+ 'd' down 'k'
+
+press 't' -- close these instructions
+ (animation will be much faster)
+press 'a' -- add a puck
+press 'A' -- remove a puck
+press '1' -- slow down all pucks
+press '2' -- speed up all pucks
+press '3' -- slow down distractors
+press '4' -- speed up distractors
+press ' ' -- reset the first puck
+press 'n' -- toggle distractors on/off
+press 'g' -- toggle the game on/off
+
+ """
+
+class Pad(object):
+ def __init__(self, disp,x,y,type='l'):
+ self.disp = disp
+ self.x = x
+ self.y = y
+ self.w = .3
+ self.score = 0
+ self.xoffset = 0.3
+ self.yoffset = 0.1
+ if type=='r':
+ self.xoffset *= -1.0
+
+ if type=='l' or type=='r':
+ self.signx = -1.0
+ self.signy = 1.0
+ else:
+ self.signx = 1.0
+ self.signy = -1.0
+ def contains(self, loc):
+ return self.disp.get_bbox().contains(loc.x,loc.y)
+
+class Puck(object):
+ def __init__(self, disp, pad, field):
+ self.vmax= .2
+ self.disp = disp
+ self.field = field
+ self._reset(pad)
+ def _reset(self,pad):
+ self.x = pad.x + pad.xoffset
+ if pad.y < 0:
+ self.y = pad.y + pad.yoffset
+ else:
+ self.y = pad.y - pad.yoffset
+ self.vx = pad.x - self.x
+ self.vy = pad.y + pad.w/2 - self.y
+ self._speedlimit()
+ self._slower()
+ self._slower()
+ def update(self,pads):
+ self.x += self.vx
+ self.y += self.vy
+ for pad in pads:
+ if pad.contains(self):
+ self.vx *= 1.2 *pad.signx
+ self.vy *= 1.2 *pad.signy
+ fudge = .001
+ #probably cleaner with something like...if not self.field.contains(self.x, self.y):
+ if self.x < 0+fudge:
+ #print "player A loses"
+ pads[1].score += 1;
+ self._reset(pads[0])
+ return True
+ if self.x > 7-fudge:
+ #print "player B loses"
+ pads[0].score += 1;
+ self._reset(pads[1])
+ return True
+ if self.y < -1+fudge or self.y > 1-fudge:
+ self.vy *= -1.0
+ # add some randomness, just to make it interesting
+ self.vy -= (randn()/300.0 + 1/300.0) * np.sign(self.vy)
+ self._speedlimit()
+ return False
+ def _slower(self):
+ self.vx /= 5.0
+ self.vy /= 5.0
+ def _faster(self):
+ self.vx *= 5.0
+ self.vy *= 5.0
+ def _speedlimit(self):
+ if self.vx > self.vmax:
+ self.vx = self.vmax
+ if self.vx < -self.vmax:
+ self.vx = -self.vmax
+
+ if self.vy > self.vmax:
+ self.vy = self.vmax
+ if self.vy < -self.vmax:
+ self.vy = -self.vmax
+
+class Game(object):
+
+ def __init__(self, ax):
+ # create the initial line
+ self.ax = ax
+ padAx = padBx= .50
+ padAy = padBy= .30
+ padBx+=6.3
+ pA, = self.ax.barh(padAy,.2, height=.3,color='k', alpha=.5, edgecolor='b',lw=2,label="Player B", animated=True)
+ pB, = self.ax.barh(padBy,.2, height=.3, left=padBx, color='k',alpha=.5, edgecolor='r',lw=2,label="Player A",animated=True)
+
+ # distractors
+ self.x = np.arange(0,2.22*np.pi,0.01)
+ self.line, = self.ax.plot(self.x, np.sin(self.x),"r", animated=True, lw=4)
+ self.line2, = self.ax.plot(self.x, np.cos(self.x),"g", animated=True, lw=4)
+ self.line3, = self.ax.plot(self.x, np.cos(self.x),"g", animated=True, lw=4)
+ self.line4, = self.ax.plot(self.x, np.cos(self.x),"r", animated=True, lw=4)
+ self.centerline,= self.ax.plot([3.5,3.5], [1,-1],'k',alpha=.5, animated=True, lw=8)
+ self.puckdisp = self.ax.scatter([1],[1],label='_nolegend_', s=200,c='g',alpha=.9,animated=True)
+
+ self.canvas = self.ax.figure.canvas
+ self.background = None
+ self.cnt = 0
+ self.distract = True
+ self.res = 100.0
+ self.on = False
+ self.inst = True # show instructions from the beginning
+ self.background = None
+ self.pads = []
+ self.pads.append( Pad(pA,0,padAy))
+ self.pads.append( Pad(pB,padBx,padBy,'r'))
+ self.pucks =[]
+ self.i = self.ax.annotate(instructions,(.5,0.5),
+ name='monospace',
+ verticalalignment='center',
+ horizontalalignment='center',
+ multialignment='left',
+ textcoords='axes fraction',animated=True )
+ self.canvas.mpl_connect('key_press_event', self.key_press)
+
+ def draw(self, evt):
+ draw_artist = self.ax.draw_artist
+ if self.background is None:
+ self.background = self.canvas.copy_from_bbox(self.ax.bbox)
+
+ # restore the clean slate background
+ self.canvas.restore_region(self.background)
+
+ # show the distractors
+ if self.distract:
+ self.line.set_ydata(np.sin(self.x+self.cnt/self.res))
+ self.line2.set_ydata(np.cos(self.x-self.cnt/self.res))
+ self.line3.set_ydata(np.tan(self.x+self.cnt/self.res))
+ self.line4.set_ydata(np.tan(self.x-self.cnt/self.res))
+ draw_artist(self.line)
+ draw_artist(self.line2)
+ draw_artist(self.line3)
+ draw_artist(self.line4)
+
+ # show the instructions - this is very slow
+ if self.inst:
+ self.ax.draw_artist(self.i)
+
+ # pucks and pads
+ if self.on:
+ self.ax.draw_artist(self.centerline)
+ for pad in self.pads:
+ pad.disp.set_y(pad.y)
+ pad.disp.set_x(pad.x)
+ self.ax.draw_artist(pad.disp)
+
+ for puck in self.pucks:
+ if puck.update(self.pads):
+ # we only get here if someone scored
+ self.pads[0].disp.set_label(" "+ str(self.pads[0].score))
+ self.pads[1].disp.set_label(" "+ str(self.pads[1].score))
+ self.ax.legend(loc='center')
+ self.leg = self.ax.get_legend()
+ #self.leg.draw_frame(False) #don't draw the legend border
+ self.leg.get_frame().set_alpha(.2)
+ plt.setp(self.leg.get_texts(),fontweight='bold',fontsize='xx-large')
+ self.leg.get_frame().set_facecolor('0.2')
+ self.background = None
+ self.ax.draw()
+ return True
+ puck.disp.set_offsets([puck.x,puck.y])
+ self.ax.draw_artist(puck.disp)
+
+
+ # just redraw the axes rectangle
+ self.canvas.blit(self.ax.bbox)
+
+ if self.cnt==50000:
+ # just so we don't get carried away
+ print "...and you've been playing for too long!!!"
+ plt.close()
+
+ self.cnt += 1
+ return True
+
+ def key_press(self,event):
+ if event.key == '3':
+ self.res *= 5.0
+ if event.key == '4':
+ self.res /= 5.0
+
+ if event.key == 'e':
+ self.pads[0].y += .1
+ if self.pads[0].y > 1 - .3:
+ self.pads[0].y = 1-.3
+ if event.key == 'd':
+ self.pads[0].y -= .1
+ if self.pads[0].y < -1:
+ self.pads[0].y = -1
+
+ if event.key == 'i':
+ self.pads[1].y += .1
+ if self.pads[1].y > 1 - .3:
+ self.pads[1].y = 1-.3
+ if event.key == 'k':
+ self.pads[1].y -= .1
+ if self.pads[1].y < -1:
+ self.pads[1].y = -1
+
+ if event.key == 'a':
+ self.pucks.append(Puck(self.puckdisp,self.pads[randint(2)],self.ax.bbox))
+ if event.key == 'A' and len(self.pucks):
+ self.pucks.pop()
+ if event.key == ' ' and len(self.pucks):
+ self.pucks[0]._reset(self.pads[randint(2)])
+ if event.key == '1':
+ for p in self.pucks:
+ p._slower()
+ if event.key == '2':
+ for p in self.pucks:
+ p._faster()
+
+ if event.key == 'n':
+ self.distract = not self.distract
+
+ if event.key == 'g':
+ #self.ax.clear()
+ #self.ax.grid() # seems to be necessary for qt backend
+ self.on = not self.on
+ if event.key == 't':
+ self.inst = not self.inst
+ self.i.set_visible(self.i.get_visible())
+ if event.key == 'q':
+ plt.close()
Added: trunk/matplotlib/examples/event_handling/pong_gtk.py
===================================================================
--- trunk/matplotlib/examples/event_handling/pong_gtk.py (rev 0)
+++ trunk/matplotlib/examples/event_handling/pong_gtk.py 2009-01-14 17:54:36 UTC (rev 6783)
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+
+# For detailed comments on animation and the techniques used here, see
+# the wiki entry
+# http://www.scipy.org/wikis/topical_software/MatplotlibAnimation
+import time
+
+import gtk, gobject
+
+import matplotlib
+matplotlib.use('GTKAgg')
+
+import numpy as np
+import matplotlib.pyplot as plt
+import pipong
+from numpy.random import randn, randint
+
+
+fig = plt.figure()
+ax = fig.add_subplot(111)
+canvas = ax.figure.canvas
+
+
+def start_anim(event):
+ gobject.idle_add(animation.draw,animation)
+ canvas.mpl_disconnect(start_anim.cid)
+
+animation = pipong.Game(ax)
+start_anim.cid = canvas.mpl_connect('draw_event', start_anim)
+
+
+tstart = time.time()
+plt.grid() # to ensure proper background restore
+plt.show()
+print 'FPS:' , animation.cnt/(time.time()-tstart)
Added: trunk/matplotlib/examples/event_handling/pong_qt.py
===================================================================
--- trunk/matplotlib/examples/event_handling/pong_qt.py (rev 0)
+++ trunk/matplotlib/examples/event_handling/pong_qt.py 2009-01-14 17:54:36 UTC (rev 6783)
@@ -0,0 +1,42 @@
+# For detailed comments on animation and the techniqes used here, see
+# the wiki entry http://www.scipy.org/Cookbook/Matplotlib/Animations
+
+import os, sys
+import matplotlib
+matplotlib.use('QtAgg') # qt3 example
+
+from qt import *
+# Note: color-intensive applications may require a different color allocation
+# strategy.
+QApplication.setColorSpec(QApplication.NormalColor)
+
+TRUE = 1
+FALSE = 0
+ITERS = 1000
+
+import pylab as p
+import matplotlib.pyplot as plt
+import numpy as np
+import time
+import pipong
+from numpy.random import randn, randint
+
+class BlitQT(QObject):
+ def __init__(self):
+ QObject.__init__(self, None, "app")
+
+ self.ax = plt.subplot(111)
+ self.animation = pipong.Game(self.ax)
+
+ def timerEvent(self, evt):
+ self.animation.draw(evt)
+
+plt.grid() # to ensure proper background restore
+
+app = BlitQT()
+# for profiling
+app.tstart = time.time()
+app.startTimer(0)
+
+plt.show()
+print 'FPS:' , app.animation.cnt/(time.time()-app.tstart)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ef...@us...> - 2009-01-13 02:45:35
|
Revision: 6782
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6782&view=rev
Author: efiring
Date: 2009-01-13 02:45:22 +0000 (Tue, 13 Jan 2009)
Log Message:
-----------
merge 6781 from v0_98_5_maint
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/axes.py
trunk/matplotlib/lib/matplotlib/collections.py
Property Changed:
----------------
trunk/matplotlib/
trunk/matplotlib/doc/pyplots/README
trunk/matplotlib/doc/sphinxext/gen_gallery.py
trunk/matplotlib/doc/sphinxext/gen_rst.py
Property changes on: trunk/matplotlib
___________________________________________________________________
Modified: svnmerge-integrated
- /branches/v0_91_maint:1-6428 /branches/v0_98_5_maint:1-6774
+ /branches/v0_91_maint:1-6428 /branches/v0_98_5_maint:1-6781
Modified: svn:mergeinfo
- /branches/v0_91_maint:5753-5771
/branches/v0_98_5_maint:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673,6714-6715,6717-6732,6752-6754,6761-6773
+ /branches/v0_91_maint:5753-5771
/branches/v0_98_5_maint:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673,6714-6715,6717-6732,6752-6754,6761-6773,6781
Property changes on: trunk/matplotlib/doc/pyplots/README
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/v0_98_5_maint/doc/pyplots/README:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673,6714-6715,6717-6732,6752-6754,6761-6773
+ /branches/v0_98_5_maint/doc/pyplots/README:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673,6714-6715,6717-6732,6752-6754,6761-6773,6781
Property changes on: trunk/matplotlib/doc/sphinxext/gen_gallery.py
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/v0_91_maint/doc/_templates/gen_gallery.py:5753-5771
/branches/v0_98_5_maint/doc/sphinxext/gen_gallery.py:6660-6662,6672-6673,6714-6715,6717-6732,6752-6754,6761-6773
+ /branches/v0_91_maint/doc/_templates/gen_gallery.py:5753-5771
/branches/v0_98_5_maint/doc/sphinxext/gen_gallery.py:6660-6662,6672-6673,6714-6715,6717-6732,6752-6754,6761-6773,6781
Property changes on: trunk/matplotlib/doc/sphinxext/gen_rst.py
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/v0_91_maint/doc/examples/gen_rst.py:5753-5771
/branches/v0_98_5_maint/doc/sphinxext/gen_rst.py:6714-6715,6717-6732,6752-6754,6761-6773
+ /branches/v0_91_maint/doc/examples/gen_rst.py:5753-5771
/branches/v0_98_5_maint/doc/sphinxext/gen_rst.py:6714-6715,6717-6732,6752-6754,6761-6773,6781
Modified: trunk/matplotlib/lib/matplotlib/axes.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/axes.py 2009-01-13 02:40:47 UTC (rev 6781)
+++ trunk/matplotlib/lib/matplotlib/axes.py 2009-01-13 02:45:22 UTC (rev 6782)
@@ -5057,6 +5057,8 @@
}
self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs)
+ x = self.convert_xunits(x)
+ y = self.convert_yunits(y)
x, y, s, c = cbook.delete_masked_points(x, y, s, c)
Modified: trunk/matplotlib/lib/matplotlib/collections.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/collections.py 2009-01-13 02:40:47 UTC (rev 6781)
+++ trunk/matplotlib/lib/matplotlib/collections.py 2009-01-13 02:45:22 UTC (rev 6782)
@@ -175,8 +175,8 @@
ys = self.convert_yunits(ys)
paths.append(mpath.Path(zip(xs, ys), path.codes))
if len(self._offsets):
- xs = self.convert_xunits(self._offsets[:0])
- ys = self.convert_yunits(self._offsets[:1])
+ xs = self.convert_xunits(self._offsets[:,0])
+ ys = self.convert_yunits(self._offsets[:,1])
offsets = zip(xs, ys)
offsets = np.asarray(offsets, np.float_)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ef...@us...> - 2009-01-13 02:40:53
|
Revision: 6781
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6781&view=rev
Author: efiring
Date: 2009-01-13 02:40:47 +0000 (Tue, 13 Jan 2009)
Log Message:
-----------
Fix units handling in scatter
Modified Paths:
--------------
branches/v0_98_5_maint/lib/matplotlib/axes.py
branches/v0_98_5_maint/lib/matplotlib/collections.py
Modified: branches/v0_98_5_maint/lib/matplotlib/axes.py
===================================================================
--- branches/v0_98_5_maint/lib/matplotlib/axes.py 2009-01-12 12:59:13 UTC (rev 6780)
+++ branches/v0_98_5_maint/lib/matplotlib/axes.py 2009-01-13 02:40:47 UTC (rev 6781)
@@ -5021,6 +5021,8 @@
}
self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs)
+ x = self.convert_xunits(x)
+ y = self.convert_yunits(y)
x, y, s, c = cbook.delete_masked_points(x, y, s, c)
Modified: branches/v0_98_5_maint/lib/matplotlib/collections.py
===================================================================
--- branches/v0_98_5_maint/lib/matplotlib/collections.py 2009-01-12 12:59:13 UTC (rev 6780)
+++ branches/v0_98_5_maint/lib/matplotlib/collections.py 2009-01-13 02:40:47 UTC (rev 6781)
@@ -174,8 +174,8 @@
ys = self.convert_yunits(ys)
paths.append(mpath.Path(zip(xs, ys), path.codes))
if len(self._offsets):
- xs = self.convert_xunits(self._offsets[:0])
- ys = self.convert_yunits(self._offsets[:1])
+ xs = self.convert_xunits(self._offsets[:,0])
+ ys = self.convert_yunits(self._offsets[:,1])
offsets = zip(xs, ys)
offsets = np.asarray(offsets, np.float_)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <js...@us...> - 2009-01-12 12:59:17
|
Revision: 6780
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6780&view=rev
Author: jswhit
Date: 2009-01-12 12:59:13 +0000 (Mon, 12 Jan 2009)
Log Message:
-----------
release 0.99.3 svn revision 6780
Revision Links:
--------------
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6780&view=rev
Modified Paths:
--------------
trunk/toolkits/basemap/Changelog
Modified: trunk/toolkits/basemap/Changelog
===================================================================
--- trunk/toolkits/basemap/Changelog 2009-01-12 12:22:11 UTC (rev 6779)
+++ trunk/toolkits/basemap/Changelog 2009-01-12 12:59:13 UTC (rev 6780)
@@ -1,4 +1,4 @@
-version 0.99.3 (not yet released)
+version 0.99.3 (svn revision 6780)
* if upper right/lower left corners nor width/height given for
azimuthal equidistant ('aeqd') the whole world is drawn in
a circle (only works for perfect spheres, not ellipsoids).
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-01-12 12:22:16
|
Revision: 6779
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6779&view=rev
Author: jdh2358
Date: 2009-01-12 12:22:11 +0000 (Mon, 12 Jan 2009)
Log Message:
-----------
Added TJ's hexbin mincnt patch; made marginals False by default
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/axes.py
Modified: trunk/matplotlib/lib/matplotlib/axes.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/axes.py 2009-01-12 09:04:57 UTC (rev 6778)
+++ trunk/matplotlib/lib/matplotlib/axes.py 2009-01-12 12:22:11 UTC (rev 6779)
@@ -5219,7 +5219,7 @@
xscale = 'linear', yscale = 'linear',
cmap=None, norm=None, vmin=None, vmax=None,
alpha=1.0, linewidths=None, edgecolors='none',
- reduce_C_function = np.mean, mincnt=None, marginals=True,
+ reduce_C_function = np.mean, mincnt=None, marginals=False,
**kwargs):
"""
call signature::
@@ -5395,9 +5395,6 @@
d1 = (x-ix1)**2 + 3.0 * (y-iy1)**2
d2 = (x-ix2-0.5)**2 + 3.0 * (y-iy2-0.5)**2
bdist = (d1<d2)
- if mincnt is None:
- mincnt = 0
-
if C is None:
accum = np.zeros(n)
# Create appropriate views into "accum" array.
@@ -5411,7 +5408,25 @@
lattice1[ix1[i], iy1[i]]+=1
else:
lattice2[ix2[i], iy2[i]]+=1
+
+ # threshold
+ if mincnt is not None:
+ for i in xrange(nx1):
+ for j in xrange(ny1):
+ if lattice1[i,j]<mincnt:
+ lattice1[i,j] = np.nan
+ for i in xrange(nx2):
+ for j in xrange(ny2):
+ if lattice2[i,j]<mincnt:
+ lattice2[i,j] = np.nan
+ accum = np.hstack((
+ lattice1.astype(float).ravel(), lattice2.astype(float).ravel()))
+ good_idxs = ~np.isnan(accum)
+
else:
+ if mincnt is None:
+ mincnt = 0
+
# create accumulation arrays
lattice1 = np.empty((nx1,ny1),dtype=object)
for i in xrange(nx1):
@@ -5457,10 +5472,9 @@
polygons[:,nx1*ny1:,0] = np.repeat(np.arange(nx2) + 0.5, ny2)
polygons[:,nx1*ny1:,1] = np.tile(np.arange(ny2), nx2) + 0.5
- if C is not None:
- # remove accumulation bins with no data
- polygons = polygons[:,good_idxs,:]
- accum = accum[good_idxs]
+ # remove accumulation bins with no data
+ polygons = polygons[:,good_idxs,:]
+ accum = accum[good_idxs]
polygons = np.transpose(polygons, axes=[1,0,2])
polygons[:,:,0] *= sx
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <lee...@us...> - 2009-01-12 09:05:02
|
Revision: 6778
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6778&view=rev
Author: leejjoon
Date: 2009-01-12 09:04:57 +0000 (Mon, 12 Jan 2009)
Log Message:
-----------
axes_divider.py example updated, again.
Modified Paths:
--------------
trunk/matplotlib/examples/pylab_examples/axes_divider.py
Modified: trunk/matplotlib/examples/pylab_examples/axes_divider.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/axes_divider.py 2009-01-12 07:58:27 UTC (rev 6777)
+++ trunk/matplotlib/examples/pylab_examples/axes_divider.py 2009-01-12 09:04:57 UTC (rev 6778)
@@ -638,28 +638,31 @@
ax2.imshow(Z, extent=extent, interpolation="nearest")
plt.setp(ax2.get_yticklabels(), visible=False)
plt.draw()
+ plt.show()
+
def demo_fixed_size_axes():
import matplotlib.pyplot as plt
- fig1 = plt.figure(1, (6, 6))
+ fig2 = plt.figure(2, (6, 6))
# The first items are for padding and the second items are for the axes.
# sizes are in inch.
- h = [Size.Fixed(1.0), Size.Fixed(5.)]
- v = [Size.Fixed(0.7), Size.Fixed(6.)]
+ h = [Size.Fixed(1.0), Size.Fixed(4.5)]
+ v = [Size.Fixed(0.7), Size.Fixed(5.)]
- divider = Divider(fig1, (0.0, 0.0, 1., 1.), h, v, aspect=False)
+ divider = Divider(fig2, (0.0, 0.0, 1., 1.), h, v, aspect=False)
# the width and height of the rectangle is ignored.
- ax = LocatableAxes(fig1, divider.get_position())
+ ax = LocatableAxes(fig2, divider.get_position())
ax.set_axes_locator(divider.new_locator(nx=1, ny=1))
- fig1.add_axes(ax)
+ fig2.add_axes(ax)
ax.plot([1,2,3])
plt.draw()
+ plt.show()
#plt.colorbar(im, cax=ax_cb)
@@ -668,4 +671,4 @@
if __name__ == "__main__":
demo_locatable_axes()
- #demo_fixed_size_axes()
+ demo_fixed_size_axes()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <lee...@us...> - 2009-01-12 07:58:32
|
Revision: 6777
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6777&view=rev
Author: leejjoon
Date: 2009-01-12 07:58:27 +0000 (Mon, 12 Jan 2009)
Log Message:
-----------
axes_divider.py example updated
Modified Paths:
--------------
trunk/matplotlib/examples/pylab_examples/axes_divider.py
Modified: trunk/matplotlib/examples/pylab_examples/axes_divider.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/axes_divider.py 2009-01-10 20:52:16 UTC (rev 6776)
+++ trunk/matplotlib/examples/pylab_examples/axes_divider.py 2009-01-12 07:58:27 UTC (rev 6777)
@@ -169,8 +169,11 @@
rs_sum += rs
as_sum += as
- k = (total_size - as_sum) / rs_sum
- return k
+ if rs_sum != 0.:
+ k = (total_size - as_sum) / rs_sum
+ return k
+ else:
+ return 0.
@staticmethod
@@ -257,23 +260,25 @@
k = min(k_h, k_v)
ox = self._calc_offsets(self._horizontal, k, renderer)
oy = self._calc_offsets(self._vertical, k, renderer)
+
+ ww = (ox[-1] - ox[0])/figW
+ hh = (oy[-1] - oy[0])/figH
+ pb = mtransforms.Bbox.from_bounds(x, y, w, h)
+ pb1 = mtransforms.Bbox.from_bounds(x, y, ww, hh)
+ pb1_anchored = pb1.anchored(self.get_anchor(), pb)
+ x0, y0 = pb1_anchored.x0, pb1_anchored.y0
+
else:
ox = self._calc_offsets(self._horizontal, k_h, renderer)
oy = self._calc_offsets(self._vertical, k_v, renderer)
+ x0, y0 = x, y
- ww = (ox[-1] - ox[0])/figW
- hh = (oy[-1] - oy[0])/figH
- pb = mtransforms.Bbox.from_bounds(x, y, w, h)
- pb1 = mtransforms.Bbox.from_bounds(x, y, ww, hh)
- pb1_anchored = pb1.anchored(self.get_anchor(), pb)
-
if nx1 is None:
nx1=nx+1
if ny1 is None:
ny1=ny+1
- x0, y0 = pb1_anchored.x0, pb1_anchored.y0
x1, w1 = x0 + ox[nx]/figW, (ox[nx1] - ox[nx])/figW
y1, h1 = y0 + oy[ny]/figH, (oy[ny1] - oy[ny])/figH
@@ -563,9 +568,9 @@
im = ax.imshow(Z, extent=extent, interpolation="nearest")
cb = plt.colorbar(im)
plt.setp(cb.ax.get_yticklabels(), visible=False)
-
- ## PLOT 2
+
+ ## PLOT 2
# image and colorbar whose location is adjusted in the drawing time.
# a hard way
@@ -611,7 +616,7 @@
ax = fig1.add_subplot(2, 2, 3)
divider = make_axes_locatable(ax)
-
+
ax_cb = divider.new_horizontal(size="5%", pad=0.05)
fig1.add_axes(ax_cb)
@@ -634,5 +639,33 @@
plt.setp(ax2.get_yticklabels(), visible=False)
plt.draw()
+def demo_fixed_size_axes():
+ import matplotlib.pyplot as plt
+
+ fig1 = plt.figure(1, (6, 6))
+
+ # The first items are for padding and the second items are for the axes.
+ # sizes are in inch.
+ h = [Size.Fixed(1.0), Size.Fixed(5.)]
+ v = [Size.Fixed(0.7), Size.Fixed(6.)]
+
+ divider = Divider(fig1, (0.0, 0.0, 1., 1.), h, v, aspect=False)
+ # the width and height of the rectangle is ignored.
+
+ ax = LocatableAxes(fig1, divider.get_position())
+ ax.set_axes_locator(divider.new_locator(nx=1, ny=1))
+
+ fig1.add_axes(ax)
+
+ ax.plot([1,2,3])
+
+ plt.draw()
+ #plt.colorbar(im, cax=ax_cb)
+
+
+
+
+
if __name__ == "__main__":
demo_locatable_axes()
+ #demo_fixed_size_axes()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-01-10 20:52:20
|
Revision: 6776
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6776&view=rev
Author: jdh2358
Date: 2009-01-10 20:52:16 +0000 (Sat, 10 Jan 2009)
Log Message:
-----------
Merged revisions 6761,6773-6774 via svnmerge from
https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/branches/v0_98_5_maint
........
r6774 | jdh2358 | 2009-01-10 14:44:07 -0600 (Sat, 10 Jan 2009) | 1 line
fixed unit and autoscaling behavior of the ax line/span funcs
........
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/axes.py
Property Changed:
----------------
trunk/matplotlib/
Property changes on: trunk/matplotlib
___________________________________________________________________
Modified: svnmerge-integrated
- /branches/v0_91_maint:1-6428 /branches/v0_98_5_maint:1-6773
+ /branches/v0_91_maint:1-6428 /branches/v0_98_5_maint:1-6774
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2009-01-10 20:48:49 UTC (rev 6775)
+++ trunk/matplotlib/CHANGELOG 2009-01-10 20:52:16 UTC (rev 6776)
@@ -4,6 +4,8 @@
draw_idle patch for qt. Closes sf patched 2497785 and
2468809 - JDH
+2009-01-10 Fix bug in pan/zoom with log coordinates. - EF
+
2009-01-06 Fix bug in setting of dashed negative contours. - EF
2009-01-06 Be fault tolerant when len(linestyles)>NLev in contour. - MM
Modified: trunk/matplotlib/lib/matplotlib/axes.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/axes.py 2009-01-10 20:48:49 UTC (rev 6775)
+++ trunk/matplotlib/lib/matplotlib/axes.py 2009-01-10 20:52:16 UTC (rev 6776)
@@ -2830,6 +2830,7 @@
# We need to strip away the units for comparison with
# non-unitized bounds
+ self._process_unit_info( ydata=y, kwargs=kwargs )
yy = self.convert_yunits( y )
scaley = (yy<ymin) or (yy>ymax)
@@ -2890,6 +2891,7 @@
# We need to strip away the units for comparison with
# non-unitized bounds
+ self._process_unit_info( xdata=x, kwargs=kwargs )
xx = self.convert_xunits( x )
scalex = (xx<xmin) or (xx>xmax)
@@ -2956,6 +2958,7 @@
p.set_transform(trans)
p.x_isdata = False
self.add_patch(p)
+ self.autoscale_view(scalex=False)
return p
axhspan.__doc__ = cbook.dedent(axhspan.__doc__) % martist.kwdocd
@@ -3012,6 +3015,7 @@
p.set_transform(trans)
p.y_isdata = False
self.add_patch(p)
+ self.autoscale_view(scaley=False)
return p
axvspan.__doc__ = cbook.dedent(axvspan.__doc__) % martist.kwdocd
@@ -3057,9 +3061,11 @@
'list of Line2D to draw; see API_CHANGES')
# We do the conversion first since not all unitized data is uniform
+ # process the unit information
+ self._process_unit_info( [xmin, xmax], y, kwargs=kwargs )
y = self.convert_yunits( y )
- xmin = self.convert_xunits( xmin )
- xmax = self.convert_xunits( xmax )
+ xmin = self.convert_xunits(xmin)
+ xmax = self.convert_xunits(xmax)
if not iterable(y): y = [y]
if not iterable(xmin): xmin = [xmin]
@@ -3133,7 +3139,7 @@
'collections.LineCollection and not a '
'list of Line2D to draw; see API_CHANGES')
- self._process_unit_info(xdata=x, ydata=ymin, kwargs=kwargs)
+ self._process_unit_info(xdata=x, ydata=[ymin, ymax], kwargs=kwargs)
# We do the conversion first since not all unitized data is uniform
x = self.convert_xunits( x )
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ef...@us...> - 2009-01-10 20:48:56
|
Revision: 6775
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6775&view=rev
Author: efiring
Date: 2009-01-10 20:48:49 +0000 (Sat, 10 Jan 2009)
Log Message:
-----------
svnmerge 6773 from v0_98_5_maint
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/axes.py
Property Changed:
----------------
trunk/matplotlib/
trunk/matplotlib/doc/pyplots/README
trunk/matplotlib/doc/sphinxext/gen_gallery.py
trunk/matplotlib/doc/sphinxext/gen_rst.py
Property changes on: trunk/matplotlib
___________________________________________________________________
Modified: svnmerge-integrated
- /branches/v0_91_maint:1-6428 /branches/v0_98_5_maint:1-6754
+ /branches/v0_91_maint:1-6428 /branches/v0_98_5_maint:1-6773
Modified: svn:mergeinfo
- /branches/v0_91_maint:5753-5771
/branches/v0_98_5_maint:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673,6714-6715,6717-6732,6752-6754
+ /branches/v0_91_maint:5753-5771
/branches/v0_98_5_maint:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673,6714-6715,6717-6732,6752-6754,6761-6773
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2009-01-10 20:44:07 UTC (rev 6774)
+++ trunk/matplotlib/CHANGELOG 2009-01-10 20:48:49 UTC (rev 6775)
@@ -1,3 +1,5 @@
+2009-01-10 Fix bug in pan/zoom with log coordinates. - EF
+
2009-01-10 Applied Michiel's hatch patch for macosx backend and
draw_idle patch for qt. Closes sf patched 2497785 and
2468809 - JDH
Property changes on: trunk/matplotlib/doc/pyplots/README
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/v0_98_5_maint/doc/pyplots/README:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673,6714-6715,6717-6732,6752-6754
+ /branches/v0_98_5_maint/doc/pyplots/README:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673,6714-6715,6717-6732,6752-6754,6761-6773
Property changes on: trunk/matplotlib/doc/sphinxext/gen_gallery.py
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/v0_91_maint/doc/_templates/gen_gallery.py:5753-5771
/branches/v0_98_5_maint/doc/sphinxext/gen_gallery.py:6660-6662,6672-6673,6714-6715,6717-6732,6752-6754
+ /branches/v0_91_maint/doc/_templates/gen_gallery.py:5753-5771
/branches/v0_98_5_maint/doc/sphinxext/gen_gallery.py:6660-6662,6672-6673,6714-6715,6717-6732,6752-6754,6761-6773
Property changes on: trunk/matplotlib/doc/sphinxext/gen_rst.py
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/v0_91_maint/doc/examples/gen_rst.py:5753-5771
/branches/v0_98_5_maint/doc/sphinxext/gen_rst.py:6714-6715,6717-6732,6752-6754
+ /branches/v0_91_maint/doc/examples/gen_rst.py:5753-5771
/branches/v0_98_5_maint/doc/sphinxext/gen_rst.py:6714-6715,6717-6732,6752-6754,6761-6773
Modified: trunk/matplotlib/lib/matplotlib/axes.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/axes.py 2009-01-10 20:44:07 UTC (rev 6774)
+++ trunk/matplotlib/lib/matplotlib/axes.py 2009-01-10 20:48:49 UTC (rev 6775)
@@ -2402,10 +2402,11 @@
dy = dx
alpha = np.power(10.0, (dx, dy))
- start = p.trans_inverse.transform_point((p.x, p.y))
- lim_points = p.lim.get_points()
- result = start + alpha * (lim_points - start)
- result = mtransforms.Bbox(result)
+ start = np.array([p.x, p.y])
+ oldpoints = p.lim.transformed(p.trans)
+ newpoints = start + alpha * (oldpoints - start)
+ result = mtransforms.Bbox(newpoints) \
+ .transformed(p.trans_inverse)
except OverflowError:
warnings.warn('Overflow while panning')
return
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-01-10 20:44:10
|
Revision: 6774
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6774&view=rev
Author: jdh2358
Date: 2009-01-10 20:44:07 +0000 (Sat, 10 Jan 2009)
Log Message:
-----------
fixed unit and autoscaling behavior of the ax line/span funcs
Modified Paths:
--------------
branches/v0_98_5_maint/lib/matplotlib/axes.py
Modified: branches/v0_98_5_maint/lib/matplotlib/axes.py
===================================================================
--- branches/v0_98_5_maint/lib/matplotlib/axes.py 2009-01-10 20:34:28 UTC (rev 6773)
+++ branches/v0_98_5_maint/lib/matplotlib/axes.py 2009-01-10 20:44:07 UTC (rev 6774)
@@ -2802,6 +2802,7 @@
# We need to strip away the units for comparison with
# non-unitized bounds
+ self._process_unit_info( ydata=y, kwargs=kwargs )
yy = self.convert_yunits( y )
scaley = (yy<ymin) or (yy>ymax)
@@ -2861,6 +2862,7 @@
# We need to strip away the units for comparison with
# non-unitized bounds
+ self._process_unit_info( xdata=x, kwargs=kwargs )
xx = self.convert_xunits( x )
scalex = (xx<xmin) or (xx>xmax)
@@ -2927,6 +2929,7 @@
p.set_transform(trans)
p.x_isdata = False
self.add_patch(p)
+ self.autoscale_view(scalex=False)
return p
axhspan.__doc__ = cbook.dedent(axhspan.__doc__) % martist.kwdocd
@@ -2982,6 +2985,7 @@
p.set_transform(trans)
p.y_isdata = False
self.add_patch(p)
+ self.autoscale_view(scaley=False)
return p
axvspan.__doc__ = cbook.dedent(axvspan.__doc__) % martist.kwdocd
@@ -3027,9 +3031,11 @@
'list of Line2D to draw; see API_CHANGES')
# We do the conversion first since not all unitized data is uniform
+ # process the unit information
+ self._process_unit_info( [xmin, xmax], y, kwargs=kwargs )
y = self.convert_yunits( y )
- xmin = self.convert_xunits( xmin )
- xmax = self.convert_xunits( xmax )
+ xmin = self.convert_xunits(xmin)
+ xmax = self.convert_xunits(xmax)
if not iterable(y): y = [y]
if not iterable(xmin): xmin = [xmin]
@@ -3103,7 +3109,7 @@
'collections.LineCollection and not a '
'list of Line2D to draw; see API_CHANGES')
- self._process_unit_info(xdata=x, ydata=ymin, kwargs=kwargs)
+ self._process_unit_info(xdata=x, ydata=[ymin, ymax], kwargs=kwargs)
# We do the conversion first since not all unitized data is uniform
x = self.convert_xunits( x )
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ef...@us...> - 2009-01-10 20:34:36
|
Revision: 6773
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6773&view=rev
Author: efiring
Date: 2009-01-10 20:34:28 +0000 (Sat, 10 Jan 2009)
Log Message:
-----------
Fix bug in pan/zoom with log coordinates.
The zoom calculations need to be done in display coordinates.
Thanks to David Trem for bug report.
Modified Paths:
--------------
branches/v0_98_5_maint/CHANGELOG
branches/v0_98_5_maint/lib/matplotlib/axes.py
Modified: branches/v0_98_5_maint/CHANGELOG
===================================================================
--- branches/v0_98_5_maint/CHANGELOG 2009-01-10 20:05:24 UTC (rev 6772)
+++ branches/v0_98_5_maint/CHANGELOG 2009-01-10 20:34:28 UTC (rev 6773)
@@ -1,3 +1,5 @@
+2009-01-10 Fix bug in pan/zoom with log coordinates. - EF
+
2009-01-06 Fix bug in setting of dashed negative contours. - EF
2009-01-06 Be fault tolerant when len(linestyles)>NLev in contour. - MM
Modified: branches/v0_98_5_maint/lib/matplotlib/axes.py
===================================================================
--- branches/v0_98_5_maint/lib/matplotlib/axes.py 2009-01-10 20:05:24 UTC (rev 6772)
+++ branches/v0_98_5_maint/lib/matplotlib/axes.py 2009-01-10 20:34:28 UTC (rev 6773)
@@ -2378,10 +2378,11 @@
dy = dx
alpha = np.power(10.0, (dx, dy))
- start = p.trans_inverse.transform_point((p.x, p.y))
- lim_points = p.lim.get_points()
- result = start + alpha * (lim_points - start)
- result = mtransforms.Bbox(result)
+ start = np.array([p.x, p.y])
+ oldpoints = p.lim.transformed(p.trans)
+ newpoints = start + alpha * (oldpoints - start)
+ result = mtransforms.Bbox(newpoints) \
+ .transformed(p.trans_inverse)
except OverflowError:
warnings.warn('Overflow while panning')
return
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-01-10 20:05:26
|
Revision: 6772
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6772&view=rev
Author: jdh2358
Date: 2009-01-10 20:05:24 +0000 (Sat, 10 Jan 2009)
Log Message:
-----------
michiel's backend qt draw idle patch - sf id 2468809
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2009-01-10 20:03:59 UTC (rev 6771)
+++ trunk/matplotlib/CHANGELOG 2009-01-10 20:05:24 UTC (rev 6772)
@@ -1,5 +1,6 @@
-2009-01-10 Applied Michiel's hatch patch for macosx backend. Closes
- sf patch 2497785 - JDH
+2009-01-10 Applied Michiel's hatch patch for macosx backend and
+ draw_idle patch for qt. Closes sf patched 2497785 and
+ 2468809 - JDH
2009-01-06 Fix bug in setting of dashed negative contours. - EF
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py 2009-01-10 20:03:59 UTC (rev 6771)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py 2009-01-10 20:05:24 UTC (rev 6772)
@@ -37,7 +37,7 @@
if matplotlib.is_interactive():
figManager = Gcf.get_active()
if figManager != None:
- figManager.canvas.draw()
+ figManager.canvas.draw_idle()
def _create_qApp():
"""
@@ -97,6 +97,7 @@
FigureCanvasBase.__init__( self, figure )
self.figure = figure
self.setMouseTracking( True )
+ self._idle = True
# hide until we can test and fix
#self.startTimer(backend_IdleEvent.milliseconds)
w,h = self.get_width_height()
@@ -198,6 +199,15 @@
FigureCanvasBase.stop_event_loop_default(self)
stop_event_loop.__doc__=FigureCanvasBase.stop_event_loop_default.__doc__
+ def draw_idle(self):
+ 'update drawing area only if idle'
+ d = self._idle
+ self._idle = False
+ def idle_draw(*args):
+ self.draw()
+ self._idle = True
+ if d: QtCore.QTimer.singleShot(0, idle_draw)
+
class FigureManagerQT( FigureManagerBase ):
"""
Public attributes
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-01-10 20:04:03
|
Revision: 6771
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6771&view=rev
Author: jdh2358
Date: 2009-01-10 20:03:59 +0000 (Sat, 10 Jan 2009)
Log Message:
-----------
applied michiel's hatch patch for macosx sf id 2497785
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/examples/pylab_examples/hatch_demo.py
trunk/matplotlib/lib/matplotlib/backends/backend_macosx.py
trunk/matplotlib/src/_macosx.m
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2009-01-08 22:11:09 UTC (rev 6770)
+++ trunk/matplotlib/CHANGELOG 2009-01-10 20:03:59 UTC (rev 6771)
@@ -1,3 +1,6 @@
+2009-01-10 Applied Michiel's hatch patch for macosx backend. Closes
+ sf patch 2497785 - JDH
+
2009-01-06 Fix bug in setting of dashed negative contours. - EF
2009-01-06 Be fault tolerant when len(linestyles)>NLev in contour. - MM
Modified: trunk/matplotlib/examples/pylab_examples/hatch_demo.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/hatch_demo.py 2009-01-08 22:11:09 UTC (rev 6770)
+++ trunk/matplotlib/examples/pylab_examples/hatch_demo.py 2009-01-10 20:03:59 UTC (rev 6771)
@@ -6,10 +6,6 @@
fig = plt.figure()
ax1 = fig.add_subplot(121)
-ax1.annotate("Hatch is only supported in the PS, PDF, SVG and Agg backends", (1, 1),
- xytext=(0, 5),
- xycoords="axes fraction", textcoords="offset points", ha="center"
- )
ax1.bar(range(1,5), range(1,5), color='red', edgecolor='black', hatch="/")
ax1.bar(range(1,5), [6] * 4, bottom=range(1,5), color='blue', edgecolor='black', hatch='//')
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_macosx.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_macosx.py 2009-01-08 22:11:09 UTC (rev 6770)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_macosx.py 2009-01-10 20:03:59 UTC (rev 6771)
@@ -77,6 +77,7 @@
def new_gc(self):
self.gc.reset()
+ self.gc.set_hatch(None)
return self.gc
def draw_image(self, x, y, im, bbox, clippath=None, clippath_trans=None):
@@ -166,10 +167,14 @@
_macosx.GraphicsContext.__init__(self)
def set_foreground(self, fg, isRGB=False):
- if not isRGB:
- fg = colorConverter.to_rgb(fg)
- _macosx.GraphicsContext.set_foreground(self, fg)
+ GraphicsContextBase.set_foreground(self, fg, isRGB)
+ rgb = self.get_rgb()
+ _macosx.GraphicsContext.set_foreground(self, rgb[:3])
+ def set_graylevel(self, fg):
+ GraphicsContextBase.set_graylevel(self, fg)
+ _macosx.GraphicsContext.set_graylevel(self, fg)
+
def set_clip_rectangle(self, box):
GraphicsContextBase.set_clip_rectangle(self, box)
if not box: return
Modified: trunk/matplotlib/src/_macosx.m
===================================================================
--- trunk/matplotlib/src/_macosx.m 2009-01-08 22:11:09 UTC (rev 6770)
+++ trunk/matplotlib/src/_macosx.m 2009-01-10 20:03:59 UTC (rev 6771)
@@ -31,6 +31,10 @@
#define CURVE3 3
#define CURVE4 4
#define CLOSEPOLY 5
+
+/* Hatching */
+#define HATCH_SIZE 72
+
/* -------------------------- Helper function ---------------------------- */
static void stdin_ready(CFReadStreamRef readStream, CFStreamEventType eventType, void* context)
@@ -203,6 +207,269 @@
PyErr_WarnEx(PyExc_RuntimeWarning, "ATSUDisposeTextLayout failed", 1);
}
+static int
+_draw_path(CGContextRef cr, PyObject* path, CGAffineTransform affine)
+{
+ CGPoint point;
+
+ PyObject* vertices = PyObject_GetAttrString(path, "vertices");
+ if (vertices==NULL)
+ {
+ PyErr_SetString(PyExc_AttributeError, "path has no vertices");
+ return -1;
+ }
+ Py_DECREF(vertices); /* Don't keep a reference here */
+
+ PyObject* codes = PyObject_GetAttrString(path, "codes");
+ if (codes==NULL)
+ {
+ PyErr_SetString(PyExc_AttributeError, "path has no codes");
+ return -1;
+ }
+ Py_DECREF(codes); /* Don't keep a reference here */
+
+ PyArrayObject* coordinates;
+ coordinates = (PyArrayObject*)PyArray_FromObject(vertices,
+ NPY_DOUBLE, 2, 2);
+ if (!coordinates)
+ {
+ PyErr_SetString(PyExc_ValueError, "failed to convert vertices array");
+ return -1;
+ }
+
+ if (PyArray_NDIM(coordinates) != 2 || PyArray_DIM(coordinates, 1) != 2)
+ {
+ Py_DECREF(coordinates);
+ PyErr_SetString(PyExc_ValueError, "invalid vertices array");
+ return -1;
+ }
+
+ npy_intp n = PyArray_DIM(coordinates, 0);
+
+ if (n==0) /* Nothing to do here */
+ {
+ Py_DECREF(coordinates);
+ return 0;
+ }
+
+ PyArrayObject* codelist = NULL;
+ if (codes != Py_None)
+ {
+ codelist = (PyArrayObject*)PyArray_FromObject(codes,
+ NPY_UINT8, 1, 1);
+ if (!codelist)
+ {
+ Py_DECREF(coordinates);
+ PyErr_SetString(PyExc_ValueError, "invalid codes array");
+ return -1;
+ }
+ }
+
+ if (codelist==NULL)
+ {
+ npy_intp i;
+ npy_uint8 code = MOVETO;
+ for (i = 0; i < n; i++)
+ {
+ point.x = (CGFloat)(*(double*)PyArray_GETPTR2(coordinates, i, 0));
+ point.y = (CGFloat)(*(double*)PyArray_GETPTR2(coordinates, i, 1));
+ if (isnan(point.x) || isnan(point.y))
+ {
+ code = MOVETO;
+ }
+ else
+ {
+ point = CGPointApplyAffineTransform(point, affine);
+ switch (code)
+ {
+ case MOVETO:
+ CGContextMoveToPoint(cr, point.x, point.y);
+ break;
+ case LINETO:
+ CGContextAddLineToPoint(cr, point.x, point.y);
+ break;
+ }
+ code = LINETO;
+ }
+ }
+ }
+ else
+ {
+ npy_intp i = 0;
+ BOOL was_nan = false;
+ npy_uint8 code;
+ CGFloat x1, y1, x2, y2, x3, y3;
+ while (i < n)
+ {
+ code = *(npy_uint8*)PyArray_GETPTR1(codelist, i);
+ if (code == CLOSEPOLY)
+ {
+ CGContextClosePath(cr);
+ i++;
+ }
+ else if (code == STOP)
+ {
+ break;
+ }
+ else if (was_nan)
+ {
+ if (code==CURVE3) i++;
+ else if (code==CURVE4) i+=2;
+ x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
+ y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+ i++;
+ if (isnan(x1) || isnan(y1))
+ {
+ was_nan = true;
+ }
+ else
+ {
+ point.x = x1;
+ point.y = y1;
+ point = CGPointApplyAffineTransform(point, affine);
+ CGContextMoveToPoint(cr, point.x, point.y);
+ was_nan = false;
+ }
+ }
+ else if (code==MOVETO)
+ {
+ x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
+ y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+ i++;
+ if (isnan(x1) || isnan(y1))
+ {
+ was_nan = true;
+ }
+ else
+ {
+ point.x = x1;
+ point.y = y1;
+ point = CGPointApplyAffineTransform(point, affine);
+ CGContextMoveToPoint(cr, point.x, point.y);
+ was_nan = false;
+ }
+ }
+ else if (code==LINETO)
+ {
+ x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
+ y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+ i++;
+ if (isnan(x1) || isnan(y1))
+ {
+ was_nan = true;
+ }
+ else
+ {
+ point.x = x1;
+ point.y = y1;
+ point = CGPointApplyAffineTransform(point, affine);
+ CGContextAddLineToPoint(cr, point.x, point.y);
+ was_nan = false;
+ }
+ }
+ else if (code==CURVE3)
+ {
+ x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
+ y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+ i++;
+ x2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
+ y2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+ i++;
+ if (isnan(x1) || isnan(y1) || isnan(x2) || isnan(y2))
+ {
+ was_nan = true;
+ }
+ else
+ {
+ point.x = x1;
+ point.y = y1;
+ point = CGPointApplyAffineTransform(point, affine);
+ x1 = point.x;
+ y1 = point.y;
+ point.x = x2;
+ point.y = y2;
+ point = CGPointApplyAffineTransform(point, affine);
+ x2 = point.x;
+ y2 = point.y;
+ CGContextAddQuadCurveToPoint(cr, x1, y1, x2, y2);
+ was_nan = false;
+ }
+ }
+ else if (code==CURVE4)
+ {
+ x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
+ y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+ i++;
+ x2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
+ y2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+ i++;
+ x3 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
+ y3 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
+ i++;
+ if (isnan(x1) || isnan(y1) || isnan(x2) || isnan(y2) || isnan(x3) || isnan(y3))
+ {
+ was_nan = true;
+ }
+ else
+ {
+ point.x = x1;
+ point.y = y1;
+ point = CGPointApplyAffineTransform(point, affine);
+ x1 = point.x;
+ y1 = point.y;
+ point.x = x2;
+ point.y = y2;
+ point = CGPointApplyAffineTransform(point, affine);
+ x2 = point.x;
+ y2 = point.y;
+ point.x = x3;
+ point.y = y3;
+ point = CGPointApplyAffineTransform(point, affine);
+ x3 = point.x;
+ y3 = point.y;
+ CGContextAddCurveToPoint(cr, x1, y1, x2, y2, x3, y3);
+ was_nan = false;
+ }
+ }
+ }
+ }
+
+ Py_DECREF(coordinates);
+ Py_XDECREF(codelist);
+ return n;
+}
+
+static void _draw_hatch (void *info, CGContextRef cr)
+{
+ PyObject* hatchpath = (PyObject*)info;
+ CGAffineTransform affine = CGAffineTransformMakeScale(HATCH_SIZE, HATCH_SIZE);
+
+ int n = _draw_path(cr, hatchpath, affine);
+ if (n < 0)
+ {
+ PyGILState_STATE gstate = PyGILState_Ensure();
+ PyErr_Print();
+ PyGILState_Release(gstate);
+ return;
+ }
+ else if (n==0)
+ {
+ return;
+ }
+ else
+ {
+ CGContextSetLineWidth(cr, 1.0);
+ CGContextSetLineCap(cr, kCGLineCapSquare);
+ CGContextDrawPath(cr, kCGPathFillStroke);
+ }
+}
+
+static void _release_hatch(void* info)
+{
+ PyObject* hatchpath = (PyObject*)info;
+ Py_DECREF(hatchpath);
+}
+
/* ---------------------------- Cocoa classes ---------------------------- */
@@ -274,7 +541,6 @@
typedef struct {
PyObject_HEAD
CGContextRef cr;
- CGPatternRef pattern; /* For drawing hatches */
} GraphicsContext;
static PyObject*
@@ -283,7 +549,6 @@
GraphicsContext* self = (GraphicsContext*)type->tp_alloc(type, 0);
if (!self) return NULL;
self->cr = NULL;
- self->pattern = NULL;
if (ngc==0)
{
@@ -301,8 +566,6 @@
static void
GraphicsContext_dealloc(GraphicsContext *self)
{
- CGPatternRelease(self->pattern);
-
ngc--;
if (ngc==0) _dealloc_atsui();
@@ -325,12 +588,6 @@
return NULL;
}
- if (self->pattern)
- {
- CGPatternRelease(self->pattern);
- self->pattern = NULL;
- }
-
CGContextRestoreGState(cr);
CGContextSaveGState(cr);
Py_INCREF(Py_None);
@@ -431,10 +688,6 @@
PyErr_SetString(PyExc_RuntimeError, "CGContextRef is NULL");
return NULL;
}
-#ifdef BUH
- CGContextRestoreGState(cr); /* FIXME */
- CGContextSaveGState(cr); /* FIXME */
-#endif
PyObject* path;
@@ -759,116 +1012,7 @@
return Py_None;
}
-static void _draw_hatch (void *info, CGContextRef cr)
-{
- int i;
-
- PyObject* string = (PyObject*)info;
- char* hatches = PyString_AS_STRING(string);
-
- int frequency[4] = {0, 0, 0, 0};
- float position, distance;
-
- const float size = 12.0;
- const int n = strlen(hatches);
-
- for (i = 0; i < n; i++)
- {
- switch(hatches[i])
- {
- case '/': frequency[3]++; break;
- case '\\': frequency[2]++; break;
- case '|': frequency[1]++; break;
- case '-': frequency[0]++; break;
- case '+': frequency[0]++; frequency[1]++; break;
- case 'x': frequency[2]++; frequency[3]++; break;
- }
- }
-
- distance = size / frequency[0];
- position = distance / 2.0;
- for (i = 0; i < frequency[0]; i++, position += distance)
- {
- CGContextMoveToPoint(cr, 0.0, position);
- CGContextAddLineToPoint(cr, size, position);
- }
- distance = size / frequency[1];
- position = distance / 2.0;
- for (i = 0; i < frequency[1]; i++, position += distance)
- {
- CGContextMoveToPoint(cr, position, 0.0);
- CGContextAddLineToPoint(cr, position, size);
- }
- distance = size / frequency[2];
- position = distance / 2.0;
- for (i = 0; i < frequency[2]; i++, position += distance)
- {
- CGContextMoveToPoint(cr, position, 0.0);
- CGContextAddLineToPoint(cr, 0.0, position);
- CGContextMoveToPoint(cr, position, size);
- CGContextAddLineToPoint(cr, size, position);
- }
- distance = size / frequency[3];
- position = distance / 2.0;
- for (i = 0; i < frequency[3]; i++, position += distance)
- {
- CGContextMoveToPoint(cr, position, 0.0);
- CGContextAddLineToPoint(cr, size, size-position);
- CGContextMoveToPoint(cr, position, size);
- CGContextAddLineToPoint(cr, 0.0, size-position);
- }
- CGContextSetLineWidth(cr, 2.0);
- CGContextSetLineCap(cr, kCGLineCapSquare);
- CGContextStrokePath(cr);
-
- Py_DECREF(string);
-}
-
-static void _release_hatch(void* info)
-{
- PyObject* hatches = info;
- Py_DECREF(hatches);
-}
-
static PyObject*
-GraphicsContext_set_hatch(GraphicsContext* self, PyObject* args)
-{ PyObject* hatches;
-
- const float size = 12.0;
- static const CGPatternCallbacks callbacks = {0,
- &_draw_hatch,
- &_release_hatch};
-
- CGContextRef cr = self->cr;
- if (!cr)
- {
- PyErr_SetString(PyExc_RuntimeError, "CGContextRef is NULL");
- return NULL;
- }
-
- if(!PyArg_ParseTuple(args, "O", &hatches)) return NULL;
- if(!PyString_Check(hatches)) return NULL;
-
- Py_INCREF(hatches);
-
- CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();
- CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(baseSpace);
- CGColorSpaceRelease(baseSpace);
- CGContextSetFillColorSpace(cr, patternSpace);
- CGColorSpaceRelease(patternSpace);
-
- self->pattern = CGPatternCreate((void*)hatches,
- CGRectMake(0, 0, size, size),
- CGAffineTransformIdentity, size, size,
- kCGPatternTilingNoDistortion,
- false,
- &callbacks);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject*
GraphicsContext_set_linewidth (GraphicsContext* self, PyObject* args)
{
float width;
@@ -965,238 +1109,6 @@
return 1;
}
-static int
-_draw_path(CGContextRef cr, PyObject* path, CGAffineTransform affine)
-{
- CGPoint point;
-
- PyObject* vertices = PyObject_GetAttrString(path, "vertices");
- if (vertices==NULL)
- {
- PyErr_SetString(PyExc_AttributeError, "path has no vertices");
- return -1;
- }
- Py_DECREF(vertices); /* Don't keep a reference here */
-
- PyObject* codes = PyObject_GetAttrString(path, "codes");
- if (codes==NULL)
- {
- PyErr_SetString(PyExc_AttributeError, "path has no codes");
- return -1;
- }
- Py_DECREF(codes); /* Don't keep a reference here */
-
- PyArrayObject* coordinates;
- coordinates = (PyArrayObject*)PyArray_FromObject(vertices,
- NPY_DOUBLE, 2, 2);
- if (!coordinates)
- {
- PyErr_SetString(PyExc_ValueError, "failed to convert vertices array");
- return -1;
- }
-
- if (PyArray_NDIM(coordinates) != 2 || PyArray_DIM(coordinates, 1) != 2)
- {
- Py_DECREF(coordinates);
- PyErr_SetString(PyExc_ValueError, "invalid vertices array");
- return -1;
- }
-
- npy_intp n = PyArray_DIM(coordinates, 0);
-
- if (n==0) /* Nothing to do here */
- {
- Py_DECREF(coordinates);
- return 0;
- }
-
- PyArrayObject* codelist = NULL;
- if (codes != Py_None)
- {
- codelist = (PyArrayObject*)PyArray_FromObject(codes,
- NPY_UINT8, 1, 1);
- if (!codelist)
- {
- Py_DECREF(coordinates);
- PyErr_SetString(PyExc_ValueError, "invalid codes array");
- return -1;
- }
- }
-
- if (codelist==NULL)
- {
- npy_intp i;
- npy_uint8 code = MOVETO;
- for (i = 0; i < n; i++)
- {
- point.x = (CGFloat)(*(double*)PyArray_GETPTR2(coordinates, i, 0));
- point.y = (CGFloat)(*(double*)PyArray_GETPTR2(coordinates, i, 1));
- if (isnan(point.x) || isnan(point.y))
- {
- code = MOVETO;
- }
- else
- {
- point = CGPointApplyAffineTransform(point, affine);
- switch (code)
- {
- case MOVETO:
- CGContextMoveToPoint(cr, point.x, point.y);
- break;
- case LINETO:
- CGContextAddLineToPoint(cr, point.x, point.y);
- break;
- }
- code = LINETO;
- }
- }
- }
- else
- {
- npy_intp i = 0;
- BOOL was_nan = false;
- npy_uint8 code;
- CGFloat x1, y1, x2, y2, x3, y3;
- while (i < n)
- {
- code = *(npy_uint8*)PyArray_GETPTR1(codelist, i);
- if (code == CLOSEPOLY)
- {
- CGContextClosePath(cr);
- i++;
- }
- else if (code == STOP)
- {
- break;
- }
- else if (was_nan)
- {
- if (code==CURVE3) i++;
- else if (code==CURVE4) i+=2;
- x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
- y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
- i++;
- if (isnan(x1) || isnan(y1))
- {
- was_nan = true;
- }
- else
- {
- point.x = x1;
- point.y = y1;
- point = CGPointApplyAffineTransform(point, affine);
- CGContextMoveToPoint(cr, point.x, point.y);
- was_nan = false;
- }
- }
- else if (code==MOVETO)
- {
- x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
- y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
- i++;
- if (isnan(x1) || isnan(y1))
- {
- was_nan = true;
- }
- else
- {
- point.x = x1;
- point.y = y1;
- point = CGPointApplyAffineTransform(point, affine);
- CGContextMoveToPoint(cr, point.x, point.y);
- was_nan = false;
- }
- }
- else if (code==LINETO)
- {
- x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
- y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
- i++;
- if (isnan(x1) || isnan(y1))
- {
- was_nan = true;
- }
- else
- {
- point.x = x1;
- point.y = y1;
- point = CGPointApplyAffineTransform(point, affine);
- CGContextAddLineToPoint(cr, point.x, point.y);
- was_nan = false;
- }
- }
- else if (code==CURVE3)
- {
- x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
- y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
- i++;
- x2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
- y2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
- i++;
- if (isnan(x1) || isnan(y1) || isnan(x2) || isnan(y2))
- {
- was_nan = true;
- }
- else
- {
- point.x = x1;
- point.y = y1;
- point = CGPointApplyAffineTransform(point, affine);
- x1 = point.x;
- y1 = point.y;
- point.x = x2;
- point.y = y2;
- point = CGPointApplyAffineTransform(point, affine);
- x2 = point.x;
- y2 = point.y;
- CGContextAddQuadCurveToPoint(cr, x1, y1, x2, y2);
- was_nan = false;
- }
- }
- else if (code==CURVE4)
- {
- x1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
- y1 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
- i++;
- x2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
- y2 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
- i++;
- x3 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 0));
- y3 = (CGFloat) (*(double*)PyArray_GETPTR2(coordinates, i, 1));
- i++;
- if (isnan(x1) || isnan(y1) || isnan(x2) || isnan(y2) || isnan(x3) || isnan(y3))
- {
- was_nan = true;
- }
- else
- {
- point.x = x1;
- point.y = y1;
- point = CGPointApplyAffineTransform(point, affine);
- x1 = point.x;
- y1 = point.y;
- point.x = x2;
- point.y = y2;
- point = CGPointApplyAffineTransform(point, affine);
- x2 = point.x;
- y2 = point.y;
- point.x = x3;
- point.y = y3;
- point = CGPointApplyAffineTransform(point, affine);
- x3 = point.x;
- y3 = point.y;
- CGContextAddCurveToPoint(cr, x1, y1, x2, y2, x3, y3);
- was_nan = false;
- }
- }
- }
- }
-
- Py_DECREF(coordinates);
- Py_XDECREF(codelist);
- return n;
-}
-
static PyObject*
GraphicsContext_draw_path (GraphicsContext* self, PyObject* args)
{
@@ -1230,6 +1142,7 @@
if (n > 0)
{
+ PyObject* hatchpath;
if(rgbFace)
{
float r, g, b;
@@ -1239,22 +1152,60 @@
return NULL;
}
CGContextSaveGState(cr);
- if(self->pattern)
- {
- float components[4];
- components[0] = r;
- components[1] = g;
- components[2] = b;
- components[3] = 1.0;
- CGContextSetFillPattern(cr, self->pattern, components);
- CGPatternRelease(self->pattern);
- self->pattern = nil;
- }
- else CGContextSetRGBFillColor(cr, r, g, b, 1.0);
+ CGContextSetRGBFillColor(cr, r, g, b, 1.0);
CGContextDrawPath(cr, kCGPathFillStroke);
CGContextRestoreGState(cr);
}
else CGContextStrokePath(cr);
+
+ hatchpath = PyObject_CallMethod((PyObject*)self, "get_hatch_path", "");
+ if (!hatchpath)
+ {
+ return NULL;
+ }
+ else if (hatchpath==Py_None)
+ {
+ Py_DECREF(hatchpath);
+ }
+ else
+ {
+ float color[4] = {0, 0, 0, 1};
+ CGPatternRef pattern;
+ static const CGPatternCallbacks callbacks = {0,
+ &_draw_hatch,
+ &_release_hatch};
+ PyObject* rgb = PyObject_CallMethod((PyObject*)self, "get_rgb", "");
+ if (!rgb)
+ {
+ Py_DECREF(hatchpath);
+ return NULL;
+ }
+ ok = PyArg_ParseTuple(rgb, "ffff", &color[0], &color[1], &color[2], &color[3]);
+ Py_DECREF(rgb);
+ if (!ok)
+ {
+ Py_DECREF(hatchpath);
+ return NULL;
+ }
+
+ CGColorSpaceRef baseSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+ CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(baseSpace);
+ CGColorSpaceRelease(baseSpace);
+ CGContextSetFillColorSpace(cr, patternSpace);
+ CGColorSpaceRelease(patternSpace);
+
+ pattern = CGPatternCreate((void*)hatchpath,
+ CGRectMake(0, 0, HATCH_SIZE, HATCH_SIZE),
+ CGAffineTransformIdentity,
+ HATCH_SIZE, HATCH_SIZE,
+ kCGPatternTilingNoDistortion,
+ false,
+ &callbacks);
+ CGContextSetFillPattern(cr, pattern, color);
+ CGPatternRelease(pattern);
+ _draw_path(cr, path, affine);
+ CGContextFillPath(cr);
+ }
}
Py_INCREF(Py_None);
@@ -1297,18 +1248,7 @@
{
return NULL;
}
- if(self->pattern)
- {
- float components[4];
- components[0] = r;
- components[1] = g;
- components[2] = b;
- components[3] = 1.0;
- CGContextSetFillPattern(cr, self->pattern, components);
- CGPatternRelease(self->pattern);
- self->pattern = nil;
- }
- else CGContextSetRGBFillColor(cr, r, g, b, 1.0);
+ CGContextSetRGBFillColor(cr, r, g, b, 1.0);
}
CGAffineTransform affine;
@@ -2516,7 +2456,7 @@
const size_t nComponents = 4; /* red, green, blue, alpha */
const size_t bitsPerPixel = bitsPerComponent * nComponents;
const size_t bytesPerRow = nComponents * bytesPerComponent * ncols;
- CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
+ CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
Py_INCREF(image);
n = PyString_GET_SIZE(image);
@@ -2627,22 +2567,6 @@
METH_VARARGS,
"Sets the current stroke and fill color to a value in the DeviceGray color space."
},
- {"set_hatch",
- (PyCFunction)GraphicsContext_set_hatch,
- METH_VARARGS,
- "\n"
- " hatch can be one of:\n"
- " / - diagonal hatching\n"
- " \\ - back diagonal\n"
- " | - vertical\n"
- " - - horizontal\n"
- " # - crossed\n"
- " X - crossed diagonal\n"
- " letters can be combined, in which case all the specified\n"
- " hatchings are done\n"
- " if same letter repeats, it increases the density of hatching\n"
- " in that direction\n"
- },
{"set_linewidth",
(PyCFunction)GraphicsContext_set_linewidth,
METH_VARARGS,
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ef...@us...> - 2009-01-08 22:11:14
|
Revision: 6770
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6770&view=rev
Author: efiring
Date: 2009-01-08 22:11:09 +0000 (Thu, 08 Jan 2009)
Log Message:
-----------
Fix bugs introduced in 6769
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/contour.py
Modified: trunk/matplotlib/lib/matplotlib/contour.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/contour.py 2009-01-08 19:58:26 UTC (rev 6769)
+++ trunk/matplotlib/lib/matplotlib/contour.py 2009-01-08 22:11:09 UTC (rev 6770)
@@ -849,7 +849,7 @@
if len(linewidths) < Nlev:
nreps = int(np.ceil(Nlev/len(linewidths)))
linewidths = linewidths * nreps
- elif len(linewidths) > Nlev:
+ if len(linewidths) > Nlev:
linewidths = linewidths[:Nlev]
tlinewidths = [(w,) for w in linewidths]
return tlinewidths
@@ -872,7 +872,7 @@
if len(tlinestyles) < Nlev:
nreps = int(np.ceil(Nlev/len(linestyles)))
tlinestyles = tlinestyles * nreps
- elif len(tlinestyles) > Nlev:
+ if len(tlinestyles) > Nlev:
tlinestyles = tlinestyles[:Nlev]
else:
raise ValueError("Unrecognized type for linestyles kwarg")
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mme...@us...> - 2009-01-08 19:58:31
|
Revision: 6769
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6769&view=rev
Author: mmetz_bn
Date: 2009-01-08 19:58:26 +0000 (Thu, 08 Jan 2009)
Log Message:
-----------
Minor code cleanup in contour
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/contour.py
Modified: trunk/matplotlib/lib/matplotlib/contour.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/contour.py 2009-01-08 19:55:06 UTC (rev 6768)
+++ trunk/matplotlib/lib/matplotlib/contour.py 2009-01-08 19:58:26 UTC (rev 6769)
@@ -840,15 +840,16 @@
linewidths = self.linewidths
Nlev = len(self.levels)
if linewidths is None:
- tlinewidths = [(mpl.rcParams['lines.linewidth'],)] *Nlev
+ tlinewidths = [(mpl.rcParams['lines.linewidth'],)] * Nlev
else:
if not cbook.iterable(linewidths):
linewidths = [linewidths] * Nlev
else:
linewidths = list(linewidths)
if len(linewidths) < Nlev:
- linewidths = linewidths * int(np.ceil(Nlev/len(linewidths)))
- if len(linewidths) > Nlev:
+ nreps = int(np.ceil(Nlev/len(linewidths)))
+ linewidths = linewidths * nreps
+ elif len(linewidths) > Nlev:
linewidths = linewidths[:Nlev]
tlinewidths = [(w,) for w in linewidths]
return tlinewidths
@@ -871,7 +872,7 @@
if len(tlinestyles) < Nlev:
nreps = int(np.ceil(Nlev/len(linestyles)))
tlinestyles = tlinestyles * nreps
- if len(tlinestyles) > Nlev:
+ elif len(tlinestyles) > Nlev:
tlinestyles = tlinestyles[:Nlev]
else:
raise ValueError("Unrecognized type for linestyles kwarg")
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mme...@us...> - 2009-01-08 19:55:13
|
Revision: 6768
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6768&view=rev
Author: mmetz_bn
Date: 2009-01-08 19:55:06 +0000 (Thu, 08 Jan 2009)
Log Message:
-----------
Handle ValueError is val is a string
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/collections.py
Modified: trunk/matplotlib/lib/matplotlib/collections.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/collections.py 2009-01-08 19:44:07 UTC (rev 6767)
+++ trunk/matplotlib/lib/matplotlib/collections.py 2009-01-08 19:55:06 UTC (rev 6768)
@@ -111,6 +111,7 @@
if cbook.iterable(val) and len(val):
try: float(val[0])
except TypeError: pass # raise below
+ except ValueError: pass
else: return val
raise TypeError('val must be a float or nonzero sequence of floats')
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-01-08 19:44:12
|
Revision: 6767
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6767&view=rev
Author: jdh2358
Date: 2009-01-08 19:44:07 +0000 (Thu, 08 Jan 2009)
Log Message:
-----------
enhanced tests and moved numpy method into pyx module
Modified Paths:
--------------
trunk/py4science/examples/pyrex/nnbf/nnbf.pyx
Modified: trunk/py4science/examples/pyrex/nnbf/nnbf.pyx
===================================================================
--- trunk/py4science/examples/pyrex/nnbf/nnbf.pyx 2009-01-08 19:42:15 UTC (rev 6766)
+++ trunk/py4science/examples/pyrex/nnbf/nnbf.pyx 2009-01-08 19:44:07 UTC (rev 6767)
@@ -86,9 +86,6 @@
cdef np.ndarray[double, ndim=1] pp
# avoid python array indexing in the inner loop
- #cdef np.ndarray[double, ndim=1] row
- cdef double * dataptr
- dataptr = <double*> self.data.data
if len(point)!=self.n:
raise ValueError('Expected a length %d vector'%self.n)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-01-08 19:42:21
|
Revision: 6766
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6766&view=rev
Author: jdh2358
Date: 2009-01-08 19:42:15 +0000 (Thu, 08 Jan 2009)
Log Message:
-----------
enhanced tests and moved numpy method into pyx module
Modified Paths:
--------------
trunk/py4science/examples/pyrex/nnbf/nnbf.pyx
trunk/py4science/examples/pyrex/nnbf/test_nnbf.py
Modified: trunk/py4science/examples/pyrex/nnbf/nnbf.pyx
===================================================================
--- trunk/py4science/examples/pyrex/nnbf/nnbf.pyx 2009-01-08 19:17:15 UTC (rev 6765)
+++ trunk/py4science/examples/pyrex/nnbf/nnbf.pyx 2009-01-08 19:42:15 UTC (rev 6766)
@@ -38,8 +38,8 @@
self.n = n
- self.numrows = 100
- # XXX how to create mepty as contiguous w/o copy?
+ self.numrows = 10000
+ # XXX how to create empty as contiguous w/o copy?
data = np.empty((self.numrows, self.n), dtype=np.float)
self.data = np.ascontiguousarray(data, dtype=np.float)
inner_data = self.data
@@ -53,7 +53,7 @@
"""
cdef np.ndarray[double, ndim=2] inner_data
cdef np.ndarray[double, ndim=1] pp
- pp = np.asarray(point).astype(np.float)
+ pp = np.array(point).astype(np.float)
self.data[self.numpoints] = pp
@@ -67,8 +67,8 @@
self.data = np.ascontiguousarray(newdata, dtype=np.float)
inner_data = self.data
self.raw_data = <double*>inner_data.data
- #self.raw_data = <double*>inner_data.data
+
def get_data(NNBF self):
"""
return a copy of data added so far as a numpoints x n array
@@ -99,16 +99,11 @@
# don't do a python lookup inside the loop
n = self.n
-
+
for i in range(self.numpoints):
- # XXX : is there a more efficient way to access the row
- # data? Can/should we be using raw_data here?
- #row = self.data[i]
neighbor = is_neighbor(
n,
- #(<double*>self.data.data)+i*n,
self.raw_data + i*n,
- #dataptr + i*n,
<double*>pp.data,
d2max)
@@ -119,4 +114,19 @@
return neighbors
+ def find_neighbors_numpy(self, point, radius):
+ """
+ do a plain ol numpy lookup to compare performance and output
+ *data* is a numpoints x numdims array
+ *point* is a numdims length vector
+ radius is the max distance distance
+
+ return an array of indices into data which are within radius
+ """
+ data = self.get_data()
+ distance = data - point
+ r = np.sqrt((distance*distance).sum(axis=1))
+ return np.nonzero(r<=radius)[0]
+
+
Modified: trunk/py4science/examples/pyrex/nnbf/test_nnbf.py
===================================================================
--- trunk/py4science/examples/pyrex/nnbf/test_nnbf.py 2009-01-08 19:17:15 UTC (rev 6765)
+++ trunk/py4science/examples/pyrex/nnbf/test_nnbf.py 2009-01-08 19:42:15 UTC (rev 6766)
@@ -4,18 +4,10 @@
import numpy.testing as nptest
-from nnbf_proto import find_neighbors_numpy
-# the pure python prototype
-
-
-#import nnbf_proto as nnbf
-
-# the cython extension
import nnbf
-
-def jdh_add_data():
+def test_add_data():
nn = nnbf.NNBF(6)
for i in range(202):
@@ -38,14 +30,13 @@
ind = nn.find_neighbors(x, radius)
data = nn.get_data()
- indnumpy = find_neighbors_numpy(data, x, radius)
+ indnumpy = nn.find_neighbors_numpy(x, radius)
nptest.assert_equal((ind==indnumpy), True)
-if 1:
-#def test_performance():
+def test_performance():
NUMDIM = 6
nn = nnbf.NNBF(NUMDIM)
@@ -61,27 +52,32 @@
print 'testing nnbf...'
times = np.zeros(10)
- for i in range(len(times)):
+ for i in range(len(times)):
start = time.clock()
ind = nn.find_neighbors(x, radius)
end = time.clock()
times[i] = end-start
- print ' 10 trials: mean=%1.4f, min=%1.4f'%(times.mean(), times.min())
+ munn = times.mean()
+ print ' 10 trials: mean=%1.4f, min=%1.4f'%(munn, times.min())
+
print 'testing numpy...'
- for i in range(len(times)):
+ for i in range(len(times)):
start = time.clock()
- ind = find_neighbors_numpy(data, x, radius)
- end = time.clock()
+ ind = nn.find_neighbors_numpy(x, radius)
+ end = time.clock()
times[i] = end-start
- print ' 10 trials: mean=%1.4f, min=%1.4f'%(times.mean(), times.min())
+ munumpy = times.mean()
+ print ' 10 trials: mean=%1.4f, min=%1.4f'%(munumpy, times.min())
+ # nn should be at least 3 times faster
+ nptest.assert_equal((3*munn < munumpy), True)
if __name__=='__main__':
- #nose.runmodule(argv=['-s','--with-doctest'], exit=False)
+ nose.runmodule(argv=['-s','--with-doctest'], exit=False)
pass
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-01-08 19:17:24
|
Revision: 6765
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6765&view=rev
Author: jdh2358
Date: 2009-01-08 19:17:15 +0000 (Thu, 08 Jan 2009)
Log Message:
-----------
fixed pointer arithmetic in nnbf
Modified Paths:
--------------
trunk/py4science/examples/pyrex/nnbf/nnbf.pyx
trunk/py4science/examples/pyrex/nnbf/nnbf_v2.pyx
trunk/py4science/examples/pyrex/nnbf/test_nnbf.py
Modified: trunk/py4science/examples/pyrex/nnbf/nnbf.pyx
===================================================================
--- trunk/py4science/examples/pyrex/nnbf/nnbf.pyx 2009-01-08 03:23:42 UTC (rev 6764)
+++ trunk/py4science/examples/pyrex/nnbf/nnbf.pyx 2009-01-08 19:17:15 UTC (rev 6765)
@@ -27,22 +27,23 @@
cdef class NNBF:
cdef readonly object data
- #cdef double* raw_data
+ cdef double* raw_data
cdef readonly int n, numrows, numpoints
def __init__(self, n):
"""
create a buffer to hold n dimensional points
"""
- #cdef np.ndarray[double, ndim=2] inner_data
+ cdef np.ndarray[double, ndim=2] inner_data
self.n = n
self.numrows = 100
# XXX how to create mepty as contiguous w/o copy?
- self.data = np.empty((self.numrows, self.n), dtype=np.float)
- #inner_data = self.data
- #self.raw_data = <double*>inner_data.data
+ data = np.empty((self.numrows, self.n), dtype=np.float)
+ self.data = np.ascontiguousarray(data, dtype=np.float)
+ inner_data = self.data
+ self.raw_data = <double*>inner_data.data
self.numpoints = 0
@@ -50,7 +51,7 @@
"""
add a point to the buffer, grow if necessary
"""
- #cdef np.ndarray[double, ndim=2] inner_data
+ cdef np.ndarray[double, ndim=2] inner_data
cdef np.ndarray[double, ndim=1] pp
pp = np.asarray(point).astype(np.float)
@@ -63,7 +64,9 @@
self.numrows *= 2
newdata = np.empty((self.numrows, self.n), np.float)
newdata[:self.numpoints] = self.data
- self.data = newdata
+ self.data = np.ascontiguousarray(newdata, dtype=np.float)
+ inner_data = self.data
+ self.raw_data = <double*>inner_data.data
#self.raw_data = <double*>inner_data.data
def get_data(NNBF self):
@@ -96,15 +99,16 @@
# don't do a python lookup inside the loop
n = self.n
-
+
for i in range(self.numpoints):
# XXX : is there a more efficient way to access the row
# data? Can/should we be using raw_data here?
#row = self.data[i]
neighbor = is_neighbor(
n,
- #<double*>row.data,
- dataptr + i,
+ #(<double*>self.data.data)+i*n,
+ self.raw_data + i*n,
+ #dataptr + i*n,
<double*>pp.data,
d2max)
Modified: trunk/py4science/examples/pyrex/nnbf/nnbf_v2.pyx
===================================================================
--- trunk/py4science/examples/pyrex/nnbf/nnbf_v2.pyx 2009-01-08 03:23:42 UTC (rev 6764)
+++ trunk/py4science/examples/pyrex/nnbf/nnbf_v2.pyx 2009-01-08 19:17:15 UTC (rev 6765)
@@ -27,22 +27,23 @@
cdef class NNBF:
cdef readonly object data
- #cdef double* raw_data
+ cdef double* raw_data
cdef readonly int n, numrows, numpoints
def __init__(self, n):
"""
create a buffer to hold n dimensional points
"""
- #cdef np.ndarray[double, ndim=2] inner_data
+ cdef np.ndarray[double, ndim=2] inner_data
self.n = n
self.numrows = 100
# XXX how to create mepty as contiguous w/o copy?
- self.data = np.empty((self.numrows, self.n), dtype=np.float)
- #inner_data = self.data
- #self.raw_data = <double*>inner_data.data
+ data = np.empty((self.numrows, self.n), dtype=np.float)
+ self.data = np.ascontiguousarray(data, dtype=np.float)
+ inner_data = self.data
+ self.raw_data = <double*>inner_data.data
self.numpoints = 0
@@ -50,7 +51,7 @@
"""
add a point to the buffer, grow if necessary
"""
- #cdef np.ndarray[double, ndim=2] inner_data
+ cdef np.ndarray[double, ndim=2] inner_data
cdef np.ndarray[double, ndim=1] pp
pp = np.asarray(point).astype(np.float)
@@ -63,7 +64,9 @@
self.numrows *= 2
newdata = np.empty((self.numrows, self.n), np.float)
newdata[:self.numpoints] = self.data
- self.data = newdata
+ self.data = np.ascontiguousarray(newdata, dtype=np.float)
+ inner_data = self.data
+ self.raw_data = <double*>inner_data.data
#self.raw_data = <double*>inner_data.data
def get_data(NNBF self):
@@ -96,15 +99,16 @@
# don't do a python lookup inside the loop
n = self.n
-
+
for i in range(self.numpoints):
# XXX : is there a more efficient way to access the row
# data? Can/should we be using raw_data here?
#row = self.data[i]
neighbor = is_neighbor(
n,
- #<double*>row.data,
- dataptr + i,
+ #(<double*>self.data.data)+i*n,
+ self.raw_data + i*n,
+ #dataptr + i*n,
<double*>pp.data,
d2max)
Modified: trunk/py4science/examples/pyrex/nnbf/test_nnbf.py
===================================================================
--- trunk/py4science/examples/pyrex/nnbf/test_nnbf.py 2009-01-08 03:23:42 UTC (rev 6764)
+++ trunk/py4science/examples/pyrex/nnbf/test_nnbf.py 2009-01-08 19:17:15 UTC (rev 6765)
@@ -44,7 +44,6 @@
-
if 1:
#def test_performance():
NUMDIM = 6
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-01-08 03:23:46
|
Revision: 6764
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6764&view=rev
Author: jdh2358
Date: 2009-01-08 03:23:42 +0000 (Thu, 08 Jan 2009)
Log Message:
-----------
added erics simple loop optimiztions
Modified Paths:
--------------
trunk/py4science/examples/pyrex/nnbf/nnbf.pyx
Added Paths:
-----------
trunk/py4science/examples/pyrex/nnbf/nnbf_v2.pyx
Modified: trunk/py4science/examples/pyrex/nnbf/nnbf.pyx
===================================================================
--- trunk/py4science/examples/pyrex/nnbf/nnbf.pyx 2009-01-08 02:50:18 UTC (rev 6763)
+++ trunk/py4science/examples/pyrex/nnbf/nnbf.pyx 2009-01-08 03:23:42 UTC (rev 6764)
@@ -36,7 +36,7 @@
"""
#cdef np.ndarray[double, ndim=2] inner_data
-
+
self.n = n
self.numrows = 100
# XXX how to create mepty as contiguous w/o copy?
@@ -78,30 +78,36 @@
return a list of indices into data which are within radius
from point
"""
- cdef int i, neighbor
+ cdef int i, neighbor, n
cdef double d2max
cdef np.ndarray[double, ndim=1] pp
- cdef np.ndarray[double, ndim=1] row
+ # avoid python array indexing in the inner loop
+ #cdef np.ndarray[double, ndim=1] row
+ cdef double * dataptr
+ dataptr = <double*> self.data.data
if len(point)!=self.n:
raise ValueError('Expected a length %d vector'%self.n)
-
+
pp = np.asarray(point).astype(np.float)
d2max = radius*radius
neighbors = []
+ # don't do a python lookup inside the loop
+ n = self.n
for i in range(self.numpoints):
# XXX : is there a more efficient way to access the row
# data? Can/should we be using raw_data here?
- row = self.data[i]
+ #row = self.data[i]
neighbor = is_neighbor(
- self.n,
- <double*>row.data,
+ n,
+ #<double*>row.data,
+ dataptr + i,
<double*>pp.data,
d2max)
-
+
# if the number of points in the cluster is small, the
# python list performance should not kill us
if neighbor:
Added: trunk/py4science/examples/pyrex/nnbf/nnbf_v2.pyx
===================================================================
--- trunk/py4science/examples/pyrex/nnbf/nnbf_v2.pyx (rev 0)
+++ trunk/py4science/examples/pyrex/nnbf/nnbf_v2.pyx 2009-01-08 03:23:42 UTC (rev 6764)
@@ -0,0 +1,118 @@
+"""
+A brute force nearest neighbor routine with incremental add. The
+internal array data structure grows as you add points
+"""
+
+import numpy as np
+cimport numpy as np
+
+cdef extern from "math.h":
+ float sqrt(float)
+
+cdef inline int is_neighbor(int n, double*row, double*pp, double d2max):
+ """
+ return 1 if the sum-of-squares of n length array row[j]-pp[j] <= d2max
+ """
+ cdef int j
+ cdef double d, d2
+
+ d2 = 0.
+
+ for j in range(n):
+ d = row[j] - pp[j]
+ d2 += d*d
+ if d2>d2max:
+ return 0
+ return 1
+
+cdef class NNBF:
+ cdef readonly object data
+ #cdef double* raw_data
+ cdef readonly int n, numrows, numpoints
+
+ def __init__(self, n):
+ """
+ create a buffer to hold n dimensional points
+ """
+ #cdef np.ndarray[double, ndim=2] inner_data
+
+
+ self.n = n
+ self.numrows = 100
+ # XXX how to create mepty as contiguous w/o copy?
+ self.data = np.empty((self.numrows, self.n), dtype=np.float)
+ #inner_data = self.data
+ #self.raw_data = <double*>inner_data.data
+ self.numpoints = 0
+
+
+ def add(NNBF self, object point):
+ """
+ add a point to the buffer, grow if necessary
+ """
+ #cdef np.ndarray[double, ndim=2] inner_data
+ cdef np.ndarray[double, ndim=1] pp
+ pp = np.asarray(point).astype(np.float)
+
+
+ self.data[self.numpoints] = pp
+ self.numpoints += 1
+ if self.numpoints==self.numrows:
+ ## XXX do I need to do memory management here, eg free
+ ## raw_data if I were using it?
+ self.numrows *= 2
+ newdata = np.empty((self.numrows, self.n), np.float)
+ newdata[:self.numpoints] = self.data
+ self.data = newdata
+ #self.raw_data = <double*>inner_data.data
+
+ def get_data(NNBF self):
+ """
+ return a copy of data added so far as a numpoints x n array
+ """
+ return self.data[:self.numpoints]
+
+
+ def find_neighbors(NNBF self, object point, double radius):
+ """
+ return a list of indices into data which are within radius
+ from point
+ """
+ cdef int i, neighbor, n
+ cdef double d2max
+ cdef np.ndarray[double, ndim=1] pp
+
+ # avoid python array indexing in the inner loop
+ #cdef np.ndarray[double, ndim=1] row
+ cdef double * dataptr
+ dataptr = <double*> self.data.data
+ if len(point)!=self.n:
+ raise ValueError('Expected a length %d vector'%self.n)
+
+ pp = np.asarray(point).astype(np.float)
+
+ d2max = radius*radius
+ neighbors = []
+
+ # don't do a python lookup inside the loop
+ n = self.n
+
+ for i in range(self.numpoints):
+ # XXX : is there a more efficient way to access the row
+ # data? Can/should we be using raw_data here?
+ #row = self.data[i]
+ neighbor = is_neighbor(
+ n,
+ #<double*>row.data,
+ dataptr + i,
+ <double*>pp.data,
+ d2max)
+
+ # if the number of points in the cluster is small, the
+ # python list performance should not kill us
+ if neighbor:
+ neighbors.append(i)
+
+ return neighbors
+
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-01-08 02:50:23
|
Revision: 6763
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6763&view=rev
Author: jdh2358
Date: 2009-01-08 02:50:18 +0000 (Thu, 08 Jan 2009)
Log Message:
-----------
added a nearest neighbor cython search example
Added Paths:
-----------
trunk/py4science/examples/pyrex/nnbf/
trunk/py4science/examples/pyrex/nnbf/nnbf.pyx
trunk/py4science/examples/pyrex/nnbf/nnbf_proto.py
trunk/py4science/examples/pyrex/nnbf/nnbf_v1.pyx
trunk/py4science/examples/pyrex/nnbf/setup.py
trunk/py4science/examples/pyrex/nnbf/test_nnbf.py
Added: trunk/py4science/examples/pyrex/nnbf/nnbf.pyx
===================================================================
--- trunk/py4science/examples/pyrex/nnbf/nnbf.pyx (rev 0)
+++ trunk/py4science/examples/pyrex/nnbf/nnbf.pyx 2009-01-08 02:50:18 UTC (rev 6763)
@@ -0,0 +1,112 @@
+"""
+A brute force nearest neighbor routine with incremental add. The
+internal array data structure grows as you add points
+"""
+
+import numpy as np
+cimport numpy as np
+
+cdef extern from "math.h":
+ float sqrt(float)
+
+cdef inline int is_neighbor(int n, double*row, double*pp, double d2max):
+ """
+ return 1 if the sum-of-squares of n length array row[j]-pp[j] <= d2max
+ """
+ cdef int j
+ cdef double d, d2
+
+ d2 = 0.
+
+ for j in range(n):
+ d = row[j] - pp[j]
+ d2 += d*d
+ if d2>d2max:
+ return 0
+ return 1
+
+cdef class NNBF:
+ cdef readonly object data
+ #cdef double* raw_data
+ cdef readonly int n, numrows, numpoints
+
+ def __init__(self, n):
+ """
+ create a buffer to hold n dimensional points
+ """
+ #cdef np.ndarray[double, ndim=2] inner_data
+
+
+ self.n = n
+ self.numrows = 100
+ # XXX how to create mepty as contiguous w/o copy?
+ self.data = np.empty((self.numrows, self.n), dtype=np.float)
+ #inner_data = self.data
+ #self.raw_data = <double*>inner_data.data
+ self.numpoints = 0
+
+
+ def add(NNBF self, object point):
+ """
+ add a point to the buffer, grow if necessary
+ """
+ #cdef np.ndarray[double, ndim=2] inner_data
+ cdef np.ndarray[double, ndim=1] pp
+ pp = np.asarray(point).astype(np.float)
+
+
+ self.data[self.numpoints] = pp
+ self.numpoints += 1
+ if self.numpoints==self.numrows:
+ ## XXX do I need to do memory management here, eg free
+ ## raw_data if I were using it?
+ self.numrows *= 2
+ newdata = np.empty((self.numrows, self.n), np.float)
+ newdata[:self.numpoints] = self.data
+ self.data = newdata
+ #self.raw_data = <double*>inner_data.data
+
+ def get_data(NNBF self):
+ """
+ return a copy of data added so far as a numpoints x n array
+ """
+ return self.data[:self.numpoints]
+
+
+ def find_neighbors(NNBF self, object point, double radius):
+ """
+ return a list of indices into data which are within radius
+ from point
+ """
+ cdef int i, neighbor
+ cdef double d2max
+ cdef np.ndarray[double, ndim=1] pp
+ cdef np.ndarray[double, ndim=1] row
+
+ if len(point)!=self.n:
+ raise ValueError('Expected a length %d vector'%self.n)
+
+ pp = np.asarray(point).astype(np.float)
+
+ d2max = radius*radius
+ neighbors = []
+
+
+ for i in range(self.numpoints):
+ # XXX : is there a more efficient way to access the row
+ # data? Can/should we be using raw_data here?
+ row = self.data[i]
+ neighbor = is_neighbor(
+ self.n,
+ <double*>row.data,
+ <double*>pp.data,
+ d2max)
+
+ # if the number of points in the cluster is small, the
+ # python list performance should not kill us
+ if neighbor:
+ neighbors.append(i)
+
+ return neighbors
+
+
Added: trunk/py4science/examples/pyrex/nnbf/nnbf_proto.py
===================================================================
--- trunk/py4science/examples/pyrex/nnbf/nnbf_proto.py (rev 0)
+++ trunk/py4science/examples/pyrex/nnbf/nnbf_proto.py 2009-01-08 02:50:18 UTC (rev 6763)
@@ -0,0 +1,102 @@
+"""
+A brute force nearest neighbor routine
+"""
+import math
+import numpy as np
+
+class NNBF:
+ def __init__(self, n):
+ """
+ create a buffer to hold n dimensional points
+ """
+ self.n = n
+ self.numrows = 100
+ self.data = np.empty((self.numrows, self.n), np.float)
+ self.numpoints = 0
+
+ def add(self, point):
+ self.data[self.numpoints] = point
+ self.numpoints += 1
+ if self.numpoints==self.numrows:
+ self.numrows *= 2
+ newdata = np.empty((self.numrows, self.n), np.float)
+ newdata[:self.numpoints] = self.data
+ self.data = newdata
+
+ def get_data(self):
+ """
+ return a copy of data added so far
+ """
+ return self.data[:self.numpoints]
+
+
+ def find_neighbors(self, point, radius):
+ """
+ return a list of indices into data which are within radius
+ from point
+ """
+ data = self.get_data()
+ neighbors = []
+ for i in range(self.numpoints):
+ row = data[i]
+ fail = False
+ d2 = 0.
+ for j in range(self.n):
+ rowval = row[j]
+ pntval = point[j]
+ d = rowval-pntval
+ if d>radius:
+ fail = True
+ break
+ d2 += d*d
+
+ if fail: continue
+
+ r = math.sqrt(d2)
+ if r<=radius:
+ neighbors.append(i)
+
+ return neighbors
+
+ def find_neighbors_numpy(self, point, radius):
+ """
+ Use plain ol numpy to find neighbors
+ """
+ data = self.get_data()
+ neighbors = []
+ for i in range(self.numpoints):
+ row = data[i]
+ fail = False
+ d2 = 0.
+ for j in range(self.n):
+ rowval = row[j]
+ pntval = point[j]
+ d = rowval-pntval
+ if d>radius:
+ fail = True
+ break
+ d2 += d*d
+
+ if fail: continue
+
+ r = math.sqrt(d2)
+ if r<=radius:
+ neighbors.append(i)
+
+ return neighbors
+
+def find_neighbors_numpy(data, point, radius):
+ """
+ do a plain ol numpy lookup to compare performance and output
+
+ *data* is a numpoints x numdims array
+ *point* is a numdims length vector
+ radius is the max distance distance
+
+ return an array of indices into data which are within radius
+ """
+ numpoints, n = data.shape
+
+ distance = data - point
+ r = np.sqrt((distance*distance).sum(axis=1))
+ return np.nonzero(r<=radius)[0]
Added: trunk/py4science/examples/pyrex/nnbf/nnbf_v1.pyx
===================================================================
--- trunk/py4science/examples/pyrex/nnbf/nnbf_v1.pyx (rev 0)
+++ trunk/py4science/examples/pyrex/nnbf/nnbf_v1.pyx 2009-01-08 02:50:18 UTC (rev 6763)
@@ -0,0 +1,112 @@
+"""
+A brute force nearest neighbor routine with incremental add. The
+internal array data structure grows as you add points
+"""
+
+import numpy as np
+cimport numpy as np
+
+cdef extern from "math.h":
+ float sqrt(float)
+
+cdef inline int is_neighbor(int n, double*row, double*pp, double d2max):
+ """
+ return 1 if the sum-of-squares of n length array row[j]-pp[j] <= d2max
+ """
+ cdef int j
+ cdef double d, d2
+
+ d2 = 0.
+
+ for j in range(n):
+ d = row[j] - pp[j]
+ d2 += d*d
+ if d2>d2max:
+ return 0
+ return 1
+
+cdef class NNBF:
+ cdef readonly object data
+ #cdef double* raw_data
+ cdef readonly int n, numrows, numpoints
+
+ def __init__(self, n):
+ """
+ create a buffer to hold n dimensional points
+ """
+ #cdef np.ndarray[double, ndim=2] inner_data
+
+
+ self.n = n
+ self.numrows = 100
+ # XXX how to create mepty as contiguous w/o copy?
+ self.data = np.empty((self.numrows, self.n), dtype=np.float)
+ #inner_data = self.data
+ #self.raw_data = <double*>inner_data.data
+ self.numpoints = 0
+
+
+ def add(NNBF self, object point):
+ """
+ add a point to the buffer, grow if necessary
+ """
+ #cdef np.ndarray[double, ndim=2] inner_data
+ cdef np.ndarray[double, ndim=1] pp
+ pp = np.asarray(point).astype(np.float)
+
+
+ self.data[self.numpoints] = pp
+ self.numpoints += 1
+ if self.numpoints==self.numrows:
+ ## XXX do I need to do memory management here, eg free
+ ## raw_data if I were using it?
+ self.numrows *= 2
+ newdata = np.empty((self.numrows, self.n), np.float)
+ newdata[:self.numpoints] = self.data
+ self.data = newdata
+ #self.raw_data = <double*>inner_data.data
+
+ def get_data(NNBF self):
+ """
+ return a copy of data added so far as a numpoints x n array
+ """
+ return self.data[:self.numpoints]
+
+
+ def find_neighbors(NNBF self, object point, double radius):
+ """
+ return a list of indices into data which are within radius
+ from point
+ """
+ cdef int i, neighbor
+ cdef double d2max
+ cdef np.ndarray[double, ndim=1] pp
+ cdef np.ndarray[double, ndim=1] row
+
+ if len(point)!=self.n:
+ raise ValueError('Expected a length %d vector'%self.n)
+
+ pp = np.asarray(point).astype(np.float)
+
+ d2max = radius*radius
+ neighbors = []
+
+
+ for i in range(self.numpoints):
+ # XXX : is there a more efficient way to access the row
+ # data? Can/should we be using raw_data here?
+ row = self.data[i]
+ neighbor = is_neighbor(
+ self.n,
+ <double*>row.data,
+ <double*>pp.data,
+ d2max)
+
+ # if the number of points in the cluster is small, the
+ # python list performance should not kill us
+ if neighbor:
+ neighbors.append(i)
+
+ return neighbors
+
+
Added: trunk/py4science/examples/pyrex/nnbf/setup.py
===================================================================
--- trunk/py4science/examples/pyrex/nnbf/setup.py (rev 0)
+++ trunk/py4science/examples/pyrex/nnbf/setup.py 2009-01-08 02:50:18 UTC (rev 6763)
@@ -0,0 +1,29 @@
+
+from distutils.core import setup
+
+import os
+from distutils.core import setup
+from distutils.extension import Extension
+from Cython.Distutils import build_ext
+import numpy
+
+
+nnbf = Extension('nnbf',
+ ['nnbf.pyx'],
+ include_dirs = [numpy.get_include()])
+
+packages = [
+ 'nnbf'
+ ]
+
+
+setup ( name = "nnbf",
+ version = "0.0000",
+ description = "incremental nearest neighbor brute force",
+ author = "John Hunter",
+ author_email = "jd...@gm...",
+ packages = packages,
+ ext_modules = [nnbf],
+ cmdclass = {'build_ext': build_ext},
+
+ )
Added: trunk/py4science/examples/pyrex/nnbf/test_nnbf.py
===================================================================
--- trunk/py4science/examples/pyrex/nnbf/test_nnbf.py (rev 0)
+++ trunk/py4science/examples/pyrex/nnbf/test_nnbf.py 2009-01-08 02:50:18 UTC (rev 6763)
@@ -0,0 +1,88 @@
+import time
+import numpy as np
+import nose, nose.tools as nt
+import numpy.testing as nptest
+
+
+from nnbf_proto import find_neighbors_numpy
+# the pure python prototype
+
+
+#import nnbf_proto as nnbf
+
+# the cython extension
+import nnbf
+
+
+
+def jdh_add_data():
+ nn = nnbf.NNBF(6)
+
+ for i in range(202):
+ x = np.random.rand(6)
+ nn.add(x)
+ data = nn.get_data()
+ nptest.assert_equal((x==data[-1]).all(), True)
+ nptest.assert_equal(len(data), i+1)
+
+def test_neighbors():
+ NUMDIM = 4
+ nn = nnbf.NNBF(NUMDIM)
+
+ for i in range(2000):
+ x = np.random.rand(NUMDIM)
+ nn.add(x)
+
+ radius = 0.2
+ x = np.random.rand(NUMDIM)
+ ind = nn.find_neighbors(x, radius)
+ data = nn.get_data()
+
+ indnumpy = find_neighbors_numpy(data, x, radius)
+
+ nptest.assert_equal((ind==indnumpy), True)
+
+
+
+
+if 1:
+#def test_performance():
+ NUMDIM = 6
+ nn = nnbf.NNBF(NUMDIM)
+
+ print 'loading data... this could take a while'
+ # this could take a while
+ for i in range(200000):
+ x = np.random.rand(NUMDIM)
+ nn.add(x)
+
+ x = np.random.rand(NUMDIM)
+ radius = 0.2
+ data = nn.get_data()
+
+ print 'testing nnbf...'
+ times = np.zeros(10)
+ for i in range(len(times)):
+ start = time.clock()
+ ind = nn.find_neighbors(x, radius)
+ end = time.clock()
+ times[i] = end-start
+ print ' 10 trials: mean=%1.4f, min=%1.4f'%(times.mean(), times.min())
+
+ print 'testing numpy...'
+ for i in range(len(times)):
+ start = time.clock()
+ ind = find_neighbors_numpy(data, x, radius)
+ end = time.clock()
+ times[i] = end-start
+ print ' 10 trials: mean=%1.4f, min=%1.4f'%(times.mean(), times.min())
+
+
+
+
+
+if __name__=='__main__':
+
+ #nose.runmodule(argv=['-s','--with-doctest'], exit=False)
+ pass
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|