## matplotlib-users

 [Matplotlib-users] plot a triangular mesh From: Ondrej Certik - 2009-05-22 02:32:04 Attachments: mpl1.png mayavi.png ```Hi, I have a set of vertices in 2D as triples (x, y, val), where the x, y are 2D coordinates and "val" is the scalar value of the finite element solution, here is an example: In [54]: l.get_vertices() Out[54]: array([[ 0.00000000e+00, -1.00000000e+00, -2.22396971e-17], [ 1.00000000e+00, -1.00000000e+00, -1.64798730e-17], [ -1.00000000e+00, 0.00000000e+00, 8.09899023e-17], ..., [ 1.48437500e-01, -1.56250000e-02, 1.62359362e-01], [ 1.32812500e-01, 0.00000000e+00, 1.56012622e-01], [ 1.32812500e-01, -1.56250000e-02, 1.50562411e-01]]) and I also have a set of triangles that connect those points, here is an example: In [55]: l.get_triangles() Out[55]: array([[ 3, 5448, 29], [ 27, 5445, 28], [ 29, 28, 26], ..., [5499, 5498, 5479], [5510, 5493, 5491], [5513, 5508, 5491]], dtype=int32) The triangles define the 2D domain. What is the best way to get this plotted with mpl? Should I write a loop using the "plot" command, or is there a better alternative? So far, I am using the contour command and I feed it just with the vertices, here is the code: vert = lin.get_vertices() from numpy import min, max, linspace from matplotlib.mlab import griddata import matplotlib.pyplot as plt # make up data. #npts = int(raw_input('enter # of random points to plot:')) npts = 200 x = vert[:, 0] y = vert[:, 1] z = vert[:, 2] # define grid. xi = linspace(min(x), max(x), 100) yi = linspace(min(y), max(y), 100) # grid the data. zi = griddata(x,y,z,xi,yi) # contour the gridded data, plotting dots at the nonuniform data points. CS = plt.contour(xi,yi,zi,15,linewidths=0.5,colors='k') CS = plt.contourf(xi,yi,zi,15,cmap=plt.cm.jet) plt.colorbar() # draw colorbar plt.title('Solution (%d points)' % npts) The output of which is attached. It looks ugly, because mpl doesn't have enough information about the domain. Mayavi can use this information with this script: vert = lin.get_vertices() triangles = lin.get_triangles() from numpy import zeros from enthought.mayavi import mlab x = vert[:, 0] y = vert[:, 1] z = zeros(len(y)) t = vert[:, 2] # the off screen rendering properly works only with VTK-5.2 or above: mlab.options.offscreen = True s = mlab.triangular_mesh(x, y, z, triangles, scalars=t) mlab.view(azimuth=90, elevation=180) the output of which is attached. Mayavi is good, but it's a little overkill for this purpose, as it takes a while to start etc. I want to use it inside the Sage notebook, where matplotlib is faster and takes less memory. Also it's way easier to install (e.g. no vtk, and fiddling with os mesa). Thanks for any ideas. Ondrej ```
 Re: [Matplotlib-users] plot a triangular mesh From: John Hunter - 2009-05-22 14:06:12 ```On Thu, May 21, 2009 at 9:31 PM, Ondrej Certik wrote: > Hi, > > I have a set of vertices in 2D as triples (x, y, val), where the x, y > are 2D coordinates and "val" is the scalar value of the finite element > solution, here is an example: > > In [54]: l.get_vertices() > Out[54]: > array([[ 0.00000000e+00, -1.00000000e+00, -2.22396971e-17], > [ 1.00000000e+00, -1.00000000e+00, -1.64798730e-17], > [ -1.00000000e+00, 0.00000000e+00, 8.09899023e-17], > ..., > [ 1.48437500e-01, -1.56250000e-02, 1.62359362e-01], > [ 1.32812500e-01, 0.00000000e+00, 1.56012622e-01], > [ 1.32812500e-01, -1.56250000e-02, 1.50562411e-01]]) > > > and I also have a set of triangles that connect those points, here is > an example: > > In [55]: l.get_triangles() > Out[55]: > array([[ 3, 5448, 29], > [ 27, 5445, 28], > [ 29, 28, 26], > ..., > [5499, 5498, 5479], > [5510, 5493, 5491], > [5513, 5508, 5491]], dtype=int32) > > > The triangles define the 2D domain. What is the best way to get this > plotted with mpl? Should I write a loop using the "plot" command, or > is there a better alternative? So far, I am using the contour command > and I feed it just with the vertices, here is the code: The best way is to define your triangles as an n length list of triangle vertices verts = [ ( (x00, y00), (x01, y01), (x02, y02)), (x10, y10), (x11, y11), (x12, y12)), ... ] and have an equal length array of intensities for color mapping. vals = np.array(N_color_intensities) Then create a PolyCollection: import matplotlib.cm as cm import matplotlib.collections as collections col = collections.PolyCollection(verts) col.set_array(val) col.set_cmap(cm.hot) ax.add_collection(col) add_collection doesn't get the autoscaling limits, if I recall correctly, so you will probably want to do ax.set_xlim(xmin, xmax) ax.set_ylim(ymin,. ymax) See also: http://matplotlib.sourceforge.net/api/collections_api.html#matplotlib.collections.PolyCollection http://matplotlib.sourceforge.net/search.html?q=codex+PolyCollection Unfortunately, we do not currently have support for interpolating between adjacent polys in a PolyCollection, so the result may not look as nice as mayavis. JDH ```
 Re: [Matplotlib-users] plot a triangular mesh From: Ondrej Certik - 2009-05-22 22:37:35 ```On Fri, May 22, 2009 at 7:06 AM, John Hunter wrote: > On Thu, May 21, 2009 at 9:31 PM, Ondrej Certik wrote: >> Hi, >> >> I have a set of vertices in 2D as triples (x, y, val), where the x, y >> are 2D coordinates and "val" is the scalar value of the finite element >> solution, here is an example: >> >> In [54]: l.get_vertices() >> Out[54]: >> array([[  0.00000000e+00,  -1.00000000e+00,  -2.22396971e-17], >>       [  1.00000000e+00,  -1.00000000e+00,  -1.64798730e-17], >>       [ -1.00000000e+00,   0.00000000e+00,   8.09899023e-17], >>       ..., >>       [  1.48437500e-01,  -1.56250000e-02,   1.62359362e-01], >>       [  1.32812500e-01,   0.00000000e+00,   1.56012622e-01], >>       [  1.32812500e-01,  -1.56250000e-02,   1.50562411e-01]]) >> >> >> and I also have a set of triangles that connect those points, here is >> an example: >> >> In [55]: l.get_triangles() >> Out[55]: >> array([[   3, 5448,   29], >>       [  27, 5445,   28], >>       [  29,   28,   26], >>       ..., >>       [5499, 5498, 5479], >>       [5510, 5493, 5491], >>       [5513, 5508, 5491]], dtype=int32) >> >> >> The triangles define the 2D domain. What is the best way to get this >> plotted with mpl? Should I write a loop using the "plot" command, or >> is there a better alternative? So far, I am using the contour command >> and I feed it just with the vertices, here is the code: > > The best way is to define your triangles as an n length list of > triangle vertices > >  verts = [ ( (x00, y00), (x01, y01),  (x02, y02)), >                 (x10, y10), (x11, y11),  (x12, y12)), >                 ... >    ] > > and have an equal length array of intensities for color mapping. > >  vals = np.array(N_color_intensities) > > Then create a PolyCollection: > >  import matplotlib.cm as cm >  import matplotlib.collections as collections >  col = collections.PolyCollection(verts) >  col.set_array(val) >  col.set_cmap(cm.hot) >  ax.add_collection(col) > > add_collection doesn't get the autoscaling limits, if I recall > correctly, so you will probably want to do > >  ax.set_xlim(xmin, xmax) >  ax.set_ylim(ymin,. ymax) > > See also: > >  http://matplotlib.sourceforge.net/api/collections_api.html#matplotlib.collections.PolyCollection >  http://matplotlib.sourceforge.net/search.html?q=codex+PolyCollection > > > Unfortunately, we do not currently have support for interpolating > between adjacent polys in a PolyCollection, so the result may not look > as nice as mayavis. Thanks a lot John. I tried that and it does what I want. I just need to convert and probably average my 3 different values at the 3 vertices of the triangle and color the triangle with that color. When I get it working, I'll send you a picture. :) On Fri, May 22, 2009 at 7:32 AM, Eric Carlson wrote: > Here is an example using matplotlib.delaunay, which automatically > returns the edges and triangules: Thanks, that works too -- but it only plots the edges, right? I will use that to plot the mesh, I need that as well. For the FE solution, I'll use John's approach. Ondrej ```
 Re: [Matplotlib-users] plot a triangular mesh From: Ondrej Certik - 2009-05-22 23:22:25 Attachments: mpl2.png ```On Fri, May 22, 2009 at 3:37 PM, Ondrej Certik wrote: > Thanks a lot John. I tried that and it does what I want. I just need > to convert and probably average my 3 different values at the 3 > vertices of the triangle and color the triangle with that color. When > I get it working, I'll send you a picture. :) Ok, I made a progress, it seems it's working. Script and picture attached. You can compare to the mayavi plot above, it's almost identical now. It took my some time playing with different parameters of mpl to get here and I think it looks quite good. Still one can see the artefacts though as John predicted, due to mpl not interpolating the triangles. Maybe I should use some graphics library directly, like Cairo, or something similar? The mpl is also quite slow, I know that if I use opengl directly, the plot is instant, so there must be some way (unless the opengl is using the hardware to plot the triangles, which it may well be). Ondrej ```
 Re: [Matplotlib-users] plot a triangular mesh From: Ondrej Certik - 2009-05-22 23:23:01 Attachments: t.py ```> Ok, I made a progress, it seems it's working. Script and picture Forgot to attach the script. Ondrej ```
 Re: [Matplotlib-users] plot a triangular mesh From: Eric Carlson - 2009-05-23 22:17:42 Attachments: tinterp.py ```I should read entire posts before sending people down the wrong pathways. I just happened to be working on a Python equivalent to MATLAB "triplot" stuff when I read your subject line and made the wrong assumptions. That program does just plot the edges, as you noted. I have attached a python program, much of which is a translation of a program I found at M*B central, contributed from the outside. Given a triangulation, it allows you to interpolate on a regular rectangular grid (dx=constant, dy=another constant). In your case, it should allow you to use your original triangulation, and should avoid the convex hull artifacts of your original griddata plot. I do not know if this new program will give you a figure that will look as good as your latest based on John's suggestion or not. Just a few warnings: 1. I use an environment that (like matlab but very unpythonic) imports everything, so the attached may need to import one or two more routines 2. I have only tested with generated data, using triangulations created with delaunay, but it worked okay as long as my random points did not lead to bad triangles. 3. The routines use a lot of loops, so they are relatively slow - should be an ideal program for Cython though. 3. method='linear' uses linear interp,and is very stable. It should not be influenced in any way by convexity. method='quadratic' uses a quadratic method, which does well except in the presence of very thin triangles. I suspect that derivative estimation at the vertices has problems on the edges and may very well be influenced by the convexity. linear on a fine grid will probably look pretty good for you. 4. to get something as nice as the mayavi sample, you will probably need a fine rectangular mesh (maybe 200x200). I tested the tinterp program in octave for a number of problems and found that the quadratic option gave nice results when I did not have functional discontinuities, and when I had good triangulations. I have been meaning to translate this to Python, so thanks for the motivation. At the very least, this program may help you appreciate John's suggestions more. Cheers, Eric Ondrej Certik wrote: >> Ok, I made a progress, it seems it's working. Script and picture > > Forgot to attach the script. > > Ondrej > > > ------------------------------------------------------------------------ > > ------------------------------------------------------------------------------ > Register Now for Creativity and Technology (CaT), June 3rd, NYC. CaT > is a gathering of tech-side developers & brand creativity professionals. Meet > the minds behind Google Creative Lab, Visual Complexity, Processing, & > iPhoneDevCamp asthey present alongside digital heavyweights like Barbarian > Group, R/GA, & Big Spaceship. http://www.creativitycat.com > > > ------------------------------------------------------------------------ > > _______________________________________________ > Matplotlib-users mailing list > Matplotlib-users@... > https://lists.sourceforge.net/lists/listinfo/matplotlib-users ```
 Re: [Matplotlib-users] plot a triangular mesh From: Robert Kern - 2009-05-23 22:31:29 ```On 2009-05-23 17:17, Eric Carlson wrote: > I should read entire posts before sending people down the wrong > pathways. I just happened to be working on a Python equivalent to MATLAB > "triplot" stuff when I read your subject line and made the wrong > assumptions. That program does just plot the edges, as you noted. > > I have attached a python program, much of which is a translation of a > program I found at M*B central, contributed from the outside. Given a > triangulation, it allows you to interpolate on a regular rectangular > grid (dx=constant, dy=another constant). In your case, it should allow > you to use your original triangulation, and should avoid the convex hull > artifacts of your original griddata plot. I do not know if this new > program will give you a figure that will look as good as your latest > based on John's suggestion or not. delaunay has a linear interpolator implemented in C++ that could be used for this purpose, too. The natural neighbor interpolator is only for Delaunay triangulations, but the linear interpolator should be usable for general triangulations. -- 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 ```
 Re: [Matplotlib-users] plot a triangular mesh From: Eric Carlson - 2009-05-24 02:35:44 ```Hello Robert, I studied delaunay and mlab.griddata a bit while converting tinterp and saw the """ tri = delaunay.Triangulation(x,y) # interpolate data interp = tri.nn_interpolator(z) zo = interp(xi,yi) """ stuff. In studying delaunay, however, it was/is not clear to me how to set up the "triangulation" for delaunay.LinearInterpolator(triangulation, z, default_value=-1.#IND) without going through delaunay. Any chance you could give an example of using delaunay to linearly interpolate on mesh x,y assuming data_pts, triangles, f_at_data_points are already given? Best Regards, Eric Robert Kern wrote: > > delaunay has a linear interpolator implemented in C++ that could be used for > this purpose, too. The natural neighbor interpolator is only for Delaunay > triangulations, but the linear interpolator should be usable for general > triangulations. > ```
 Re: [Matplotlib-users] plot a triangular mesh From: Robert Kern - 2009-05-26 16:03:50 ```On 2009-05-23 21:35, Eric Carlson wrote: > Hello Robert, > I studied delaunay and mlab.griddata a bit while converting tinterp and > saw the > > """ > tri = delaunay.Triangulation(x,y) > # interpolate data > interp = tri.nn_interpolator(z) > zo = interp(xi,yi) > """ > stuff. In studying delaunay, however, it was/is not clear to me how to > set up the "triangulation" for > > delaunay.LinearInterpolator(triangulation, z, default_value=-1.#IND) > > without going through delaunay. Any chance you could give an example of > using delaunay to linearly interpolate on mesh x,y assuming data_pts, > triangles, f_at_data_points are already given? Hmm, true. I violated my own principle of trying not to do too much in the constructor. However, you should be able to figure out how to use the underlying utility functions compute_planes() and linear_interpolate_grid() from the LinearInterpolator code and Triangulation's docstring to describe its attributes. -- 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 ```
 Re: [Matplotlib-users] plot a triangular mesh From: Eric Carlson - 2009-05-22 14:45:10 ```Here is an example using matplotlib.delaunay, which automatically returns the edges and triangules: import matplotlib.delaunay as delaunay import matplotlib.pyplot as pp #generate points npts=41 xpt=sp.random.random_sample(npts) ypt=sp.random.random_sample(npts) #create triangulation circumcenters,edges,tri_points,tri_neighbors=delaunay.delaunay(xpt, ypt) #plot using edges pp.plot(xpt[edges.T],ypt[edges.T],'b-') #following extracts same edges from triangles # but does not worry about repeating edges from numpy import vstack my_edges=vstack( (tri_points[:,0:2], tri_points[:,1:], tri_points[:,2::-2]) ) #plot the edges extracted (possibly multiple times) from triangles pp.plot(xpt[my_edges.T],ypt[my_edges.T],'r--') ```
 Re: [Matplotlib-users] plot a triangular mesh From: Robert Cimrman - 2009-05-25 08:04:58 ```Ondrej Certik wrote: > On Fri, May 22, 2009 at 3:37 PM, Ondrej Certik wrote: >> Thanks a lot John. I tried that and it does what I want. I just need >> to convert and probably average my 3 different values at the 3 >> vertices of the triangle and color the triangle with that color. When >> I get it working, I'll send you a picture. :) > > Ok, I made a progress, it seems it's working. Script and picture > attached. You can compare to the mayavi plot above, it's almost > identical now. It took my some time playing with different parameters > of mpl to get here and I think it looks quite good. Still one can see > the artefacts though as John predicted, due to mpl not interpolating > the triangles. Nice! Just to prod you a bit: If you want to get rid of the hard mayavi dependence of femhub for 3D plots too, you could hack a (perspective/whatever) projection of 3D surface to 2D, remove invisible faces (normal points backwards) and plot the rest by the painter's algorithm (far faces first). r. ```
 Re: [Matplotlib-users] plot a triangular mesh From: Ondrej Certik - 2009-05-25 08:41:13 ```On Mon, May 25, 2009 at 1:03 AM, Robert Cimrman wrote: > Ondrej Certik wrote: >> >> On Fri, May 22, 2009 at 3:37 PM, Ondrej Certik wrote: >>> >>> Thanks a lot John. I tried that and it does what I want. I just need >>> to convert and probably average my 3 different values at the 3 >>> vertices of the triangle and color the triangle with that color. When >>> I get it working, I'll send you a picture. :) >> >> Ok, I made a progress, it seems it's working. Script and picture >> attached. You can compare to the mayavi plot above, it's almost >> identical now. It took my some time playing with different parameters >> of mpl to get here and I think it looks quite good. Still one can see >> the artefacts though as John predicted, due to mpl not interpolating >> the triangles. > > Nice! > > Just to prod you a bit: If you want to get rid of the hard mayavi dependence > of femhub for 3D plots too, you could hack a (perspective/whatever) > projection of 3D surface to 2D, remove invisible faces (normal points > backwards) and plot the rest by the painter's algorithm (far faces first). Well, I spent one afternoon playing with cairo, trying to implement the triangle interpolation and the result was slower than matplotlib. So gave up and I'll just use what can be done with mpl currently. As to mayavi, I'd rather make it easier to install. The only tough dependency is VTK, that takes lots of time to build, we already got rid of all the others, so that's good. Ondrej ```

JavaScript is required for this form.

No, thanks