|
From: <and...@us...> - 2008-08-13 22:27:21
|
Revision: 8642
http://plplot.svn.sourceforge.net/plplot/?rev=8642&view=rev
Author: andrewross
Date: 2008-08-13 22:27:30 +0000 (Wed, 13 Aug 2008)
Log Message:
-----------
Add python support for plimagefr.
Update example 20 to use this (consistent with C version).
Modified Paths:
--------------
trunk/bindings/python/plplot.py.Numeric
trunk/bindings/python/plplot.py.numpy
trunk/bindings/python/plplotcmodule.i
trunk/bindings/swig-support/plplotcapi.i
trunk/examples/python/xw20.py
Modified: trunk/bindings/python/plplot.py.Numeric
===================================================================
--- trunk/bindings/python/plplot.py.Numeric 2008-08-13 16:02:19 UTC (rev 8641)
+++ trunk/bindings/python/plplot.py.Numeric 2008-08-13 22:27:30 UTC (rev 8642)
@@ -1,4 +1,5 @@
# Copyright 2002 Gary Bishop and Alan W. Irwin
+# Copyright 2008 Andrew Ross
# This file is part of PLplot.
# PLplot is free software; you can redistribute it and/or modify
@@ -251,6 +252,99 @@
_plvect(u, v, scaling, pltr, pltr_data)
plvect.__doc__ = _plvect.__doc__
+# Redefine plimagefr to have the user-friendly interface
+# Allowable syntaxes:
+
+# plimagefr( img, xmin, xmax, ymin, ymax, zmin, zmax, valuemin, valuemax, [pltr, [pltr_data] or [xg, yg, [wrap]]])
+_plimagefr = plimagefr
+def plimagefr(img, *args):
+ img = Numeric.asarray(img)
+
+ if len(img.shape) != 2:
+ raise ValueError, "Expected 2D img array"
+
+ if len(args) >= 8 :
+ for i in range(8) :
+ if (type(args[i]) != types.FloatType and type(args[i]) != types.IntType) :
+ raise ValueError, "Expected 8 numbers for xmin, xmax, ymin, ymax, zmin, zmax, valuemin, valuemax"
+ else:
+ # These 8 args are xmin, xmax, ymin, ymax, zmin, zmax, valuemin, valuemax
+ xmin, xmax, ymin, ymax, zmin, zmax, valuemin, valuemax = args[0:8]
+ args = args[8:]
+ else:
+ raise ValueError, "Expected 8 numbers for xmin, xmax, ymin, ymax, zmin, zmax, valuemin, valuemax"
+
+ if len(args) > 0 and ( \
+ type(args[0]) == types.StringType or \
+ type(args[0]) == types.FunctionType or \
+ type(args[0]) == types.BuiltinFunctionType):
+ pltr = args[0]
+ # Handle the string names for the callbacks though specifying the
+ # built-in function name directly (without the surrounding quotes)
+ # or specifying any user-defined transformation function
+ # (following above rules) works fine too.
+ if type(pltr) == types.StringType:
+ if pltr == "pltr0":
+ pltr = pltr0
+ elif pltr == "pltr1":
+ pltr = pltr1
+ elif pltr == "pltr2":
+ pltr = pltr2
+ else:
+ raise ValueError, "pltr string is unrecognized"
+
+ args = args[1:]
+ # Handle pltr_data or separate xg, yg, [wrap]
+ if len(args) == 0:
+ # Default pltr_data
+ pltr_data = None
+ elif len(args) == 1:
+ #Must be pltr_data
+ pltr_data = args[0]
+ args = args[1:]
+ elif len(args) >= 2:
+ xg = Numeric.asarray(args[0])
+ if len(xg.shape) < 1 or len(xg.shape) > 2:
+ raise ValueError, "xg must be 1D or 2D array"
+ yg = Numeric.asarray(args[1])
+ if len(yg.shape) != len(xg.shape):
+ raise ValueError, "yg must have same number of dimensions as xg"
+ args = args[2:]
+ # wrap only relevant if xg and yg specified.
+ if len(args) > 0:
+ if type(args[0]) == types.IntType:
+ wrap = args[0]
+ args = args[1:]
+ if len(xg.shape) == 2 and len(yg.shape) == 2 and \
+ img.shape[0] == xg.shape[0]-1 and img.shape[1] == xg.shape[1]-1:
+ # handle wrap
+ if wrap == 1:
+ img = Numeric.resize(img, (img.shape[0]+1, u.shape[1]))
+ xg = Numeric.resize(xg, (xg.shape[0]+1, xg.shape[1]))
+ yg = Numeric.resize(yg, (yg.shape[0]+1, yg.shape[1]))
+ elif wrap == 2:
+ img = Numeric.transpose(Numeric.resize( \
+ Numeric.transpose(img), (img.shape[1]+1, img.shape[0])))
+ xg = Numeric.transpose(Numeric.resize( \
+ Numeric.transpose(xg), (xg.shape[1]+1, xg.shape[0])))
+ yg = Numeric.transpose(Numeric.resize( \
+ Numeric.transpose(yg), (yg.shape[1]+1, yg.shape[0])))
+ elif wrap != 0:
+ raise ValueError, "Invalid wrap specifier, must be 0, 1 or 2."
+ elif wrap != 0:
+ raise ValueError, "Non-zero wrap specified and xg and yg are not 2D arrays"
+ else:
+ raise ValueError, "Specified wrap is not an integer"
+ pltr_data = (xg, yg)
+ else:
+ # default is identity transformation
+ pltr = pltr0
+ pltr_data = None
+ if len(args) > 0:
+ raise ValueError, "Too many arguments for plimagefr"
+ _plimagefr(img, xmin, xmax, ymin, ymax, zmin, zmax, valuemin, valuemax, pltr, pltr_data)
+plimagefr.__doc__ = _plimagefr.__doc__
+
# Redefine plshades to have the user-friendly interface
# Allowable syntaxes:
Modified: trunk/bindings/python/plplot.py.numpy
===================================================================
--- trunk/bindings/python/plplot.py.numpy 2008-08-13 16:02:19 UTC (rev 8641)
+++ trunk/bindings/python/plplot.py.numpy 2008-08-13 22:27:30 UTC (rev 8642)
@@ -1,4 +1,5 @@
# Copyright 2002 Gary Bishop and Alan W. Irwin
+# Copyright 2008 Andrew Ross
# This file is part of PLplot.
# PLplot is free software; you can redistribute it and/or modify
@@ -251,6 +252,101 @@
_plvect(u, v, scaling, pltr, pltr_data)
plvect.__doc__ = _plvect.__doc__
+# Redefine plimagefr to have the user-friendly interface
+# Allowable syntaxes:
+
+# plimagefr( img, xmin, xmax, ymin, ymax, zmin, zmax, valuemin, valuemax, [pltr, [pltr_data] or [xg, yg, [wrap]]])
+_plimagefr = plimagefr
+def plimagefr(img, *args):
+ img = numpy.asarray(img)
+
+ if len(img.shape) != 2:
+ raise ValueError, "Expected 2D img array"
+
+ if len(args) >= 8 :
+ for i in range(8) :
+ if (type(args[i]) != types.FloatType and \
+ type(args[i]) != numpy.float64 and \
+ type(args[i]) != types.IntType) :
+ raise ValueError, "Expected 8 numbers for xmin, xmax, ymin, ymax, zmin, zmax, valuemin, valuemax"
+ else:
+ # These 8 args are xmin, xmax, ymin, ymax, zmin, zmax, valuemin, valuemax
+ xmin, xmax, ymin, ymax, zmin, zmax, valuemin, valuemax = args[0:8]
+ args = args[8:]
+ else:
+ raise ValueError, "Expected 8 numbers for xmin, xmax, ymin, ymax, zmin, zmax, valuemin, valuemax"
+
+ if len(args) > 0 and ( \
+ type(args[0]) == types.StringType or \
+ type(args[0]) == types.FunctionType or \
+ type(args[0]) == types.BuiltinFunctionType):
+ pltr = args[0]
+ # Handle the string names for the callbacks though specifying the
+ # built-in function name directly (without the surrounding quotes)
+ # or specifying any user-defined transformation function
+ # (following above rules) works fine too.
+ if type(pltr) == types.StringType:
+ if pltr == "pltr0":
+ pltr = pltr0
+ elif pltr == "pltr1":
+ pltr = pltr1
+ elif pltr == "pltr2":
+ pltr = pltr2
+ else:
+ raise ValueError, "pltr string is unrecognized"
+
+ args = args[1:]
+ # Handle pltr_data or separate xg, yg, [wrap]
+ if len(args) == 0:
+ # Default pltr_data
+ pltr_data = None
+ elif len(args) == 1:
+ #Must be pltr_data
+ pltr_data = args[0]
+ args = args[1:]
+ elif len(args) >= 2:
+ xg = numpy.asarray(args[0])
+ if len(xg.shape) < 1 or len(xg.shape) > 2:
+ raise ValueError, "xg must be 1D or 2D array"
+ yg = numpy.asarray(args[1])
+ if len(yg.shape) != len(xg.shape):
+ raise ValueError, "yg must have same number of dimensions as xg"
+ args = args[2:]
+ # wrap only relevant if xg and yg specified.
+ if len(args) > 0:
+ if type(args[0]) == types.IntType:
+ wrap = args[0]
+ args = args[1:]
+ if len(xg.shape) == 2 and len(yg.shape) == 2 and \
+ img.shape[0] == xg.shape[0]-1 and img.shape[1] == xg.shape[1]-1:
+ # handle wrap
+ if wrap == 1:
+ img = numpy.resize(img, (img.shape[0]+1, u.shape[1]))
+ xg = numpy.resize(xg, (xg.shape[0]+1, xg.shape[1]))
+ yg = numpy.resize(yg, (yg.shape[0]+1, yg.shape[1]))
+ elif wrap == 2:
+ img = numpy.transpose(numpy.resize( \
+ numpy.transpose(img), (img.shape[1]+1, img.shape[0])))
+ xg = numpy.transpose(numpy.resize( \
+ numpy.transpose(xg), (xg.shape[1]+1, xg.shape[0])))
+ yg = numpy.transpose(numpy.resize( \
+ numpy.transpose(yg), (yg.shape[1]+1, yg.shape[0])))
+ elif wrap != 0:
+ raise ValueError, "Invalid wrap specifier, must be 0, 1 or 2."
+ elif wrap != 0:
+ raise ValueError, "Non-zero wrap specified and xg and yg are not 2D arrays"
+ else:
+ raise ValueError, "Specified wrap is not an integer"
+ pltr_data = (xg, yg)
+ else:
+ # default is identity transformation
+ pltr = pltr0
+ pltr_data = None
+ if len(args) > 0:
+ raise ValueError, "Too many arguments for plimagefr"
+ _plimagefr(img, xmin, xmax, ymin, ymax, zmin, zmax, valuemin, valuemax, pltr, pltr_data)
+plimagefr.__doc__ = _plimagefr.__doc__
+
# Redefine plshades to have the user-friendly interface
# Allowable syntaxes:
@@ -265,10 +361,10 @@
raise ValueError, "Expected 2D z array"
if len(args) > 4 and \
- (type(args[0]) == types.FloatType or type(args[0]) == types.IntType) and \
- (type(args[1]) == types.FloatType or type(args[1]) == types.IntType) and \
- (type(args[2]) == types.FloatType or type(args[2]) == types.IntType) and \
- (type(args[3]) == types.FloatType or type(args[3]) == types.IntType):
+ (type(args[0]) == types.FloatType or type(args[0]) == numpy.float64 or type(args[0]) == types.IntType) and \
+ (type(args[1]) == types.FloatType or type(args[1]) == numpy.float64 or type(args[1]) == types.IntType) and \
+ (type(args[2]) == types.FloatType or type(args[2]) == numpy.float64 or type(args[2]) == types.IntType) and \
+ (type(args[3]) == types.FloatType or type(args[3]) == numpy.float64 or type(args[3]) == types.IntType):
# These 4 args are xmin, xmax, ymin, ymax
xmin, xmax, ymin, ymax = args[0:4]
args = args[4:]
Modified: trunk/bindings/python/plplotcmodule.i
===================================================================
--- trunk/bindings/python/plplotcmodule.i 2008-08-13 16:02:19 UTC (rev 8641)
+++ trunk/bindings/python/plplotcmodule.i 2008-08-13 22:27:30 UTC (rev 8642)
@@ -489,7 +489,7 @@
static PLcGrid tmpGrid1;
static PLcGrid2 tmpGrid2;
- PLcGrid* marshal_PLcGrid1(PyObject* input) {
+ PLcGrid* marshal_PLcGrid1(PyObject* input, int isimg) {
/* fprintf(stderr, "marshal PLcGrid1\n"); */
if(!PySequence_Check(input) || PySequence_Size(input) != 2) {
PyErr_SetString(PyExc_ValueError, "Expected a sequence of two arrays.");
@@ -505,10 +505,18 @@
}
tmpGrid1.nx = pltr_xg->dimensions[0];
tmpGrid1.ny = pltr_yg->dimensions[0];
- if(Xlen != tmpGrid1.nx || Ylen != tmpGrid1.ny) {
- PyErr_SetString(PyExc_ValueError, "pltr arguments must have X and Y dimensions of first arg.");
- return NULL;
+ if (isimg == 0) {
+ if(Xlen != tmpGrid1.nx || Ylen != tmpGrid1.ny) {
+ PyErr_SetString(PyExc_ValueError, "pltr arguments must have X and Y dimensions of first arg.");
+ return NULL;
+ }
}
+ else {
+ if(Xlen != tmpGrid1.nx-1 || Ylen != tmpGrid1.ny-1) {
+ PyErr_SetString(PyExc_ValueError, "pltr arguments must have X and Y dimensions of first arg + 1.");
+ return NULL;
+ }
+ }
tmpGrid1.xg = (PLFLT*)pltr_xg->data;
tmpGrid1.yg = (PLFLT*)pltr_yg->data;
return &tmpGrid1;
@@ -520,7 +528,7 @@
Py_DECREF(pltr_yg);
}
- PLcGrid2* marshal_PLcGrid2(PyObject* input) {
+ PLcGrid2* marshal_PLcGrid2(PyObject* input, int isimg) {
int i, size;
/* fprintf(stderr, "marshal PLcGrid2\n"); */
if(!PySequence_Check(input) || PySequence_Size(input) != 2) {
@@ -542,10 +550,18 @@
}
tmpGrid2.nx = pltr_xg->dimensions[0];
tmpGrid2.ny = pltr_xg->dimensions[1];
- if(Xlen != tmpGrid2.nx || Ylen != tmpGrid2.ny) {
- PyErr_SetString(PyExc_ValueError, "pltr arguments must have X and Y dimensions of first arg.");
- return NULL;
+ if (isimg == 0) {
+ if(Xlen != tmpGrid2.nx || Ylen != tmpGrid2.ny) {
+ PyErr_SetString(PyExc_ValueError, "pltr arguments must have X and Y dimensions of first arg.");
+ return NULL;
+ }
}
+ else {
+ if(Xlen != tmpGrid2.nx-1 || Ylen != tmpGrid2.ny-1) {
+ PyErr_SetString(PyExc_ValueError, "pltr arguments must have X and Y dimensions of first arg + 1.");
+ return NULL;
+ }
+ }
size = sizeof(PLFLT)*tmpGrid2.ny;
tmpGrid2.xg = (PLFLT**)malloc(sizeof(PLFLT*)*tmpGrid2.nx);
for(i=0; i<tmpGrid2.nx; i++)
@@ -566,7 +582,7 @@
%}
%typemap(in) PLcGrid* cgrid {
- $1 = marshal_PLcGrid1($input);
+ $1 = marshal_PLcGrid1($input,0);
if(!$1)
return NULL;
}
@@ -582,7 +598,7 @@
structure that pltr2 expects */
%typemap(in) PLcGrid2* cgrid {
- $1 = marshal_PLcGrid2($input);
+ $1 = marshal_PLcGrid2($input,0);
if(!$1)
return NULL;
}
@@ -775,18 +791,18 @@
python_pltr = 0;
}
- PLPointer marshal_PLPointer(PyObject* input) {
+ PLPointer marshal_PLPointer(PyObject* input,int isimg) {
PLPointer result = NULL;
switch(pltr_type) {
case CB_0:
break;
case CB_1:
if(input != Py_None)
- result = marshal_PLcGrid1(input);
+ result = marshal_PLcGrid1(input,isimg);
break;
case CB_2:
if(input != Py_None)
- result = marshal_PLcGrid2(input);
+ result = marshal_PLcGrid2(input,isimg);
break;
case CB_Python:
Py_XINCREF(input);
@@ -844,7 +860,7 @@
if($input == Py_None)
$1 = NULL;
else {
- $1 = marshal_PLPointer($input);
+ $1 = marshal_PLPointer($input,0);
}
}
%typemap(freearg) PLPointer PYOBJECT_DATA {
@@ -856,6 +872,23 @@
$1 = NULL;
}
+/* convert an arbitrary Python object into the void* pointer they want */
+%typemap(in) PLPointer PYOBJECT_DATA_img {
+ if($input == Py_None)
+ $1 = NULL;
+ else {
+ $1 = marshal_PLPointer($input,1);
+ }
+}
+%typemap(freearg) PLPointer PYOBJECT_DATA_img {
+ cleanup_PLPointer();
+}
+
+/* you can omit the data too */
+%typemap(default) PLPointer PYOBJECT_DATA_img {
+ $1 = NULL;
+}
+
/* marshall the f2eval function pointer argument */
%typemap(in) f2eval_func f2eval {
/* it must be a callable */
Modified: trunk/bindings/swig-support/plplotcapi.i
===================================================================
--- trunk/bindings/swig-support/plplotcapi.i 2008-08-13 16:02:19 UTC (rev 8641)
+++ trunk/bindings/swig-support/plplotcapi.i 2008-08-13 22:27:30 UTC (rev 8642)
@@ -171,7 +171,7 @@
#ifdef SWIG_PYTHON
#define SWIG_OBJECT_DATA PYOBJECT_DATA
-#define SWIG_OBJECT_DATA_img PYOBJECT_DATA
+#define SWIG_OBJECT_DATA_img PYOBJECT_DATA_img
#define pltr_img pltr
#else
#define SWIG_OBJECT_DATA OBJECT_DATA
Modified: trunk/examples/python/xw20.py
===================================================================
--- trunk/examples/python/xw20.py 2008-08-13 16:02:19 UTC (rev 8641)
+++ trunk/examples/python/xw20.py 2008-08-13 22:27:30 UTC (rev 8642)
@@ -4,9 +4,6 @@
from plplot_py_demos import *
-import os.path
-import sys
-
XDIM = 260
YDIM = 220
@@ -152,7 +149,16 @@
else: # Driver has no xormod capability, just do nothing
return [0, xi, xe, yi, ye]
+
+def mypltr(x, y, stretch):
+ x0 = (stretch[0] + stretch[1])*0.5
+ y0 = (stretch[2] + stretch[3])*0.5
+ dy = (stretch[3] - stretch[2])*0.5
+ result0 = x0 + multiply.outer((x0-x),(1.0 - stretch[4]*cos((y-y0)/dy*pi*0.5)))
+ result1 = multiply.outer(ones(len(x)),y)
+ return array((result0, result1))
+
# main
#
#
@@ -190,9 +196,9 @@
r = sqrt( multiply.outer(x*x,ones(YDIM)) + multiply.outer(ones(XDIM),y*y)) + 1e-3
z = sin(r) / r
- pllab("No, an amplitude clipped \"sombrero\"", "", "Saturn?");
- plptex(2., 2., 3., 4., 0., "Transparent image");
- plimage(z, 0., 2.*pi, 0, 3.*pi, 0.05, 1.,0., 2.*pi, 0, 3.*pi);
+ pllab("No, an amplitude clipped \"sombrero\"", "", "Saturn?")
+ plptex(2., 2., 3., 4., 0., "Transparent image")
+ plimage(z, 0., 2.*pi, 0, 3.*pi, 0.05, 1.,0., 2.*pi, 0, 3.*pi)
# Save the plot
if (f_name != ""):
@@ -249,8 +255,34 @@
plenv(xi, xe, ye, yi, 1, -1)
plimage(img, 1., width, 1., height, 0., 0., xi, xe, ye, yi)
pladv(0)
- plend()
- sys.exit(0)
+ # Base the dynamic range on the image contents.
+ img_min = min(img.flat)
+ img_max = max(img.flat)
+
+ # Draw a saturated version of the original image. Only use the middle 50%
+ # of the image's full dynamic range.
+ plcol0(2)
+ plenv(0, width, 0, height, 1, -1)
+ pllab("", "", "Reduced dynamic range image example")
+ plimagefr(img, 0., width, 0., height, 0., 0., img_min + img_max * 0.25, \
+ img_max - img_max * 0.25)
+
+ # Draw a distorted version of the original image, showing its full dynamic range.
+ plenv(0, width, 0, height, 1, -1)
+ pllab("", "", "Distorted image example")
+
+ stretch = zeros(5)
+ stretch[1] = width
+ stretch[3] = height
+ stretch[4] = 0.5
+
+ xg = mypltr(arange(width+1),arange(height+1),stretch)[0]
+ yg = mypltr(arange(width+1),arange(height+1),stretch)[1]
+ plimagefr(img, 0., width, 0., height, 0., 0., img_min, img_max, \
+ pltr2, xg, yg)
+ pladv(0)
+
+
main()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|