http://matplotlib.sourceforge.net/mpl_toolkits/mplot3d/tutorial.html
The problem I have is that none of the example source code is based on working
with numbers from actual data. The only thing I could find that addresses this
issue is at the very bottom of this page under the heading "Another Example":
http://www.scipy.org/Cookbook/Matplotlib/mplot3D
I've tried to duplicate this method but I get errors, and I don't really
understand it anyway. The place I get lost is here:
Z = numpy.zeros((len(Y), len(X)), 'Float32')
for d in data:
x, y, z = d
ix = int(x * 10)
iy = int(y * 10)
Z[iy, ix] = z
I don't understand how ix and iy are supposed to give me valid indeces for the Z
array (and Python doesn't seem to understand it either, it gives me an error at
that last line).
Can someone either explain this method to me, or point me in a different
direction?
_______________________________________________
SciPy-User mailing list
SciPy...@scipy.org
http://mail.scipy.org/mailman/listinfo/scipy-user
This is my usual criticism to most of the scipy documentation which is
written to mathematicians not for users (check this in my blog
http://www.tabula0rasa.org/2008/07/crazy-matplotlib-tutorial/ )
In anycase -
here is any example with hydraulic head data which is easy to understand
http://www.tabula0rasa.org/2009/05/3d-plots-with-matplotlib/
let me know if the example works for you or not (I didn't check it for a while)
--
Oz Nahum
Graduate Student
Zentrum für Angewandte Geologie
Universität Tübingen
---
Imagine there's no countries
it isn't hard to do
Nothing to kill or die for
And no religion too
Imagine all the people
Living life in peace
And then it plot a lovely diamond ;-)
Joe-
This is exactly what I'm looking for, thanks. The problem is that when I read
in my data I get these errors:
Traceback (most recent call last):
File "C:\Python26\Lib\site-packages\xy\plotscript_griddata.py", line 33, in
<module>
spline = sp.interpolate.Rbf(xlist,ylist,zlist,function='thin-plate')
File "C:\Python26\lib\site-packages\scipy\interpolate\rbf.py", line 138, in
__init__
self.nodes = linalg.solve(self.A, self.di)
File "C:\Python26\lib\site-packages\scipy\linalg\basic.py", line 151, in solve
raise LinAlgError, "singular matrix"
LinAlgError: singular matrix
The data I'm using is 2560 x,y,z grid points representing an anatomical contour
exported from a medical imaging program. None of the values are zero and it's
not some crazy shape - basically it looks like a kidney, so no spike or holes or
anything. I've found that if I chop the data down to 144 lines it will then
work (not that 144 is the exact cutoff, I just kept deleting chunks of lines
from the data file until it worked). This tells me that I've successfully
adapted your code and that I'm reading in the data properly as numpy arrays - I
was worried that I might just have some formatting problems.
Any idea why I can't run this with my entire data set? This is just a test run,
I will potentially need to process much larger datasets in the future.
P.S. Sorry for the bottom-post, the website won't let me submit unless I post my
message below yours. Seems stupid to me, I think it makes a lot more sense to
see the new information at the top instead of having to scroll through a bunch
of stuff I've already read.
pydoc scipy.interpolate.Rbf says
| smooth : float, optional
| Values greater than zero increase the smoothness of the
| approximation. 0 is for interpolation (default), the function
will
| always go through the nodal points in this case.
I have no idea if "smooth=1" is reasonable, but 0 is not a good
default -- Joe ?
cheers
-- denis
>
>
> No worries about the bottom post. I actually think I'm breaking protocol by
top-posting, but I use gmail, and it's just more natural to top-post.Anyway, I
think your problem is coming from the fact that you're working with an
isosurface that fully encloses a volume. I assumed that you had scattered data
points (say, elevation measurements) that you needed to interpolate between.
The interpolation example I posted implicitly assumes that z = f(x,y). In other
words, that there is only one z value for any given x and y. If you're working
with a 3D kidney-shape, this is clearly not the case. Therefore, you're getting
a singluar matrix when you try to interpolate (more than one value of z for
identical rows of x and y in the matrix).The good news is that this may make the
problem much simpler. (Your data is already in some sort of triangle-strip
format if it's been exported from an imaging program. No need to
interpolate.)What happens when you just do:fig = plt.figure()ax =
Axes3D(fig)ax.plot_surface(x,y,z)plt.show()Where x,y,z are your raw data?
There's a reasonable chance that the program you used to export the x,y,z
isosurface left the verticies in the order that plot_surface expects them
in...On a side note, you might also look into Mayavi's mlab module for 3D
plotting. I prefer it to matplotlib's native 3D plotting. If you have it
installed, you'd just do:from enthought.mayavi import mlabs = mlab.mesh(x, y,
z)mlab.show()Hope that helps some,
> -Joe
I get these errors:
Traceback (most recent call last):
File "C:\Python26\Lib\site-packages\xy\plotscript_griddata.py", line 61, in
<module>
ax.plot_surface(x,y,z)
File "C:\Python26\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py", line 573,
in plot_surface
rows, cols = Z.shape
ValueError: need more than 1 value to unpack
Maybe Mayavi is the way to go, I did come across it while researching this
problem. I was worried that I couldn't install it alongside my current
installation, these things always seems to conflict with each other when I try
to have multiple packages installed.
"it's just more natural to top-post" - I completely agree. I am using the web
interface to post so the admins have more control over what I'm doing. Maybe I
should start using an email interface.
On Tue, Feb 16, 2010 at 9:23 AM, Joe Kington <jkin...@wisc.edu> wrote:
> The interpolation example I posted implicitly assumes that z = f(x,y). In
> other words, that there is only one z value for any given x and y. If
> you're working with a 3D kidney-shape, this is clearly not the case.
>
I too have some data that has multiple z values in the x,y domain.
Worse, my data is not remotely arranged in a proper grid as it is
temporal trajectory data from a 3D ODE that winds itself round and
round the surface, like a very carefully wrapped mummy. I.e., it
doesn't wrap back over itself.
I'm not familiar with 3D plotting techniques and trying to set up the
plot of my surface in mayavi or matplotlib is not working along the
lines of standard cookbook examples. I cannot find appropriate
information online on how to plot the surface if I can't run the
interpolator for data that's not a function of (x,y) and my data needs
"alignment".
But maybe I'm looking in the wrong place. Could you provide any pointers please?
-Rob
> I'm not familiar with 3D plotting techniques and trying to set up the
> plot of my surface in mayavi or matplotlib is not working along the
> lines of standard cookbook examples. I cannot find appropriate
> information online on how to plot the surface if I can't run the
> interpolator for data that's not a function of (x,y) and my data needs
> "alignment".
Would this example help:
http://code.enthought.com/projects/mayavi/docs/development/html/mayavi/auto/example_surface_from_irregular_data.html
Gaël
>
>
> No worries about the bottom post. I actually think I'm breaking protocol by
top-posting, but I use gmail, and it's just more natural to top-post.Anyway, I
think your problem is coming from the fact that you're working with an
isosurface that fully encloses a volume. I assumed that you had scattered data
points (say, elevation measurements) that you needed to interpolate between.
The interpolation example I posted implicitly assumes that z = f(x,y). In other
words, that there is only one z value for any given x and y. If you're working
with a 3D kidney-shape, this is clearly not the case. Therefore, you're getting
a singluar matrix when you try to interpolate (more than one value of z for
identical rows of x and y in the matrix).The good news is that this may make the
problem much simpler. (Your data is already in some sort of triangle-strip
format if it's been exported from an imaging program. No need to
interpolate.)What happens when you just do:fig = plt.figure()ax =
Axes3D(fig)ax.plot_surface(x,y,z)plt.show()Where x,y,z are your raw data?
There's a reasonable chance that the program you used to export the x,y,z
isosurface left the verticies in the order that plot_surface expects them
in...On a side note, you might also look into Mayavi's mlab module for 3D
plotting. I prefer it to matplotlib's native 3D plotting. If you have it
installed, you'd just do:from enthought.mayavi import mlabs = mlab.mesh(x, y,
z)mlab.show()Hope that helps some,
> -Joe
I understand what you mean about assuming that z is a proper function of x and
y, but after looking again at the examples on the tutorial page
(http://matplotlib.sourceforge.net/mpl_toolkits/mplot3d/tutorial.html#getting-started)
I remember why I thought plot_surface was the proper function: the second
example under the plot_surface heading shows a spherical surface, so I figured
plot_surface didn't assume a 1-to-1 relationship.
-Rob
Yes, the example I point to shows how to reconstruct a surface from
unconnected point, so I would think that it applies to your problem.
HTH,
Gaël
> -Rob
> On Tue, Feb 16, 2010 at 11:07 AM, Gael Varoquaux
> <gael.va...@normalesup.org> wrote:
> > On Tue, Feb 16, 2010 at 10:19:32AM -0500, Rob Clewley wrote:
> >> I too have some data that has multiple z values in the x,y domain.
> >> Worse, my data is not remotely arranged in a proper grid as it is
> >> temporal trajectory data from a 3D ODE that winds itself round and
> >> round the surface, like a very carefully wrapped mummy. I.e., it
> >> doesn't wrap back over itself.
> >> I'm not familiar with 3D plotting techniques and trying to set up the
> >> plot of my surface in mayavi or matplotlib is not working along the
> >> lines of standard cookbook examples. I cannot find appropriate
> >> information online on how to plot the surface if I can't run the
> >> interpolator for data that's not a function of (x,y) and my data needs
> >> "alignment".
> > Would this example help:
> > http://code.enthought.com/projects/mayavi/docs/development/html/mayavi/auto/example_surface_from_irregular_data.html
_______________________________________________
Correct me if I'm wrong, but as I read it you've got a number of x,y,z points which lie on the surface of a 3D volume, rather than on an essentially 2D 'rubber sheet'. In this case the 2D triangulation is not going to give you what you want, but you could apply the same principle and do a 3D triangularisation, which should give you triangles on the surface of your object. The problem is that it'll also give you triangles covering the surface of the entire convex hull and on the inside of the object, which you're somehow going to need to cull. This could be as simple as just culling everything which is larger than a certain cutoff. After this you're still left with the problem of displaying the triangles somehow (there's probably a patch function in matplotlib axes3d, and you're almost certain to be able to get triangles into mayavi.
I'm not sure if mayavi has 3D triangularisation, but there's a python wrapper around qhull which does. If you want to go this route I've got some code using qhull which does the triangularisation, large face culling, and internal face culling, as well as some very limited opengl code to draw the triangles. It's slow (practically limited to a couple of thousand points), poorly commented, buggy, and somewhat application specific, but might be useful as a template to try and write something better. It's definitely not a ready solution, but drop me a line if you want to give it a try.
cheers,
David
It has, or rather VTK has, thus Mayavi has. It's just a question of
replacing the call to Delaunay2D by one to Delaunay3D. However, if a
surface is wanted, I believe that 2D triangulation is the way to go.
My 2 cents,
So I guess I will try using Delauney3D. Thanks for the tips. I (or
rather my student who is doing this mostly) will look into this more
closely to see if we can leverage these examples more than previous
ones. I'll be back on this thread if I get stuck, so look out :)
Thanks,
Rob
I think we are having a communication problem here (but I may be wrong).
When you say a 3D surface, you mean a 2D surface embedded in a 3D space,
or a 3D volume? If it is the later, you will need Delaunay3D, as it
creates volumes. If it is the former, Delaunay2D is what you are looking
for : it creates 2D surfaces embedded in a 3D world by connecting dots
with 3D coordinnates using triangles.
Gaël
> Thanks,
> Rob
> > cheers,
> > David
> > -Rob
--
Gael Varoquaux
Research Fellow, INRIA
Laboratoire de Neuro-Imagerie Assistee par Ordinateur
NeuroSpin/CEA Saclay , Bat 145, 91191 Gif-sur-Yvette France
++ 33-1-69-08-78-35
http://gael-varoquaux.info
No, this is not true. Delaunay2D ignores the Z coordinate and returns
the 2D Delaunay triangulation of just the X,Y coordinates. When you
have an z=f(x,y) functional relationship, this usually does what you
want. It does not solve Rob's problem or that of the OP.
http://www.vtk.org/doc/release/5.4/html/a00404.html
Instead, they need the SurfaceReconstructionFilter:
http://www.vtk.org/doc/release/5.4/html/a01651.html
--
Robert Kern
"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
-- Umberto Eco
> http://www.vtk.org/doc/release/5.4/html/a00404.html
Wow, I am bluffed. I was pretty sure of the contrary and didn't check.
> Instead, they need the SurfaceReconstructionFilter:
> http://www.vtk.org/doc/release/5.4/html/a01651.html
Rob and David, you can use it by replacing the call to
mlab.pipeline.delaunay2d by a call to:
mlab.pipeline.user_defined(obj, filter='SurfaceReconstructionFilter'),
as in the following example:
http://code.enthought.com/projects/mayavi/docs/development/html/mayavi/auto/example_image_cursor_filter.html
Thanks for the details, Robert.
Gaël
That said, I suspect the surface reconstruction filter might be a better way to go.
>
>
> No worries about the bottom post. I actually think I'm breaking protocol by
top-posting, but I use gmail, and it's just more natural to top-post.Anyway, I
think your problem is coming from the fact that you're working with an
isosurface that fully encloses a volume. I assumed that you had scattered data
points (say, elevation measurements) that you needed to interpolate between.
The interpolation example I posted implicitly assumes that z = f(x,y). In other
words, that there is only one z value for any given x and y. If you're working
with a 3D kidney-shape, this is clearly not the case. Therefore, you're getting
a singluar matrix when you try to interpolate (more than one value of z for
identical rows of x and y in the matrix).The good news is that this may make the
problem much simpler. (Your data is already in some sort of triangle-strip
format if it's been exported from an imaging program. No need to
interpolate.)What happens when you just do:fig = plt.figure()ax =
Axes3D(fig)ax.plot_surface(x,y,z)plt.show()Where x,y,z are your raw data?
There's a reasonable chance that the program you used to export the x,y,z
isosurface left the verticies in the order that plot_surface expects them
in...On a side note, you might also look into Mayavi's mlab module for 3D
plotting. I prefer it to matplotlib's native 3D plotting. If you have it
installed, you'd just do:from enthought.mayavi import mlabs = mlab.mesh(x, y,
z)mlab.show()Hope that helps some,
> -Joe
> On Tue, Feb 16, 2010 at 6:00 AM, URI <zallen <at>
urologicresearchinstitute.org> wrote:
> >Joe Kington <jkington <at> wisc.edu> writes:
>
> >
I tried using mlab.mesh from mayavi but apparently the x y z components need to
be 2D arrays (see
http://code.enthought.com/projects/mayavi/docs/development/html/mayavi/auto/mlab_helper_functions.html#enthought.mayavi.mlab.mesh).
I don't understand this, how can my list of the x-positions of the vertices be a
2D array?
I did try to use mlab.plot3d (see
http://code.enthought.com/projects/mayavi/docs/development/html/mayavi/auto/mlab_helper_functions.html#enthought.mayavi.mlab.plot3d)
and it gave me a nice line drawing of my shape, but an actual surface would be
much nicer.
> I tried using mlab.mesh from mayavi but apparently the x y z components need to
> be 2D arrays (see
> http://code.enthought.com/projects/mayavi/docs/development/html/mayavi/auto/mlab_helper_functions.html#enthought.mayavi.mlab.mesh).
>
> I don't understand this, how can my list of the x-positions of the vertices be a
> 2D array?
It is for rectilinear grids of z=f(x,y) surfaces only.
> I did try to use mlab.plot3d (see
> http://code.enthought.com/projects/mayavi/docs/development/html/mayavi/auto/mlab_helper_functions.html#enthought.mayavi.mlab.plot3d)
> and it gave me a nice line drawing of my shape, but an actual surface would be
> much nicer.
Please see the previous posts about using the SurfaceReconstructionFilter.
--
Robert Kern
"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
-- Umberto Eco
I don't understand this, how can my list of the x-positions of the vertices be a
2D array?