Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a Triangulation for use in Matplotlib's plot_trisurf with matplotlib.tri.Triangulation

I am a trying to use matplotlib.tri.Triangulation to generate the triangles for a matplotlibs plot_trisurf. I want to specify the triangles rather than letting the Delaunay triangulation which matplotlib.tri.Triangulation uses because it does not work for some cases such as triangles in in the xz or yz plane. I am not sure if this specifying the triangles myself will solve the problem but I seems like a good thing to try.

The issue is that the triangulation requires a (n,3) array with n being the number of triangles. To quote the page on matplotlib.org "For each triangle, the indices of the three points that make up the triangle, ordered in an anticlockwise manner." https://matplotlib.org/api/tri_api.html#matplotlib.tri.Triangulation . I cannot discern how to create the array in the right form and that is were I would like help. I appreciate any help.

I have tried a few things so far but here is what my last try looks like:

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.tri as mtri

fig = plt.figure()
ax = fig.gca(projection='3d')

x1=0
x2=1
x3=1
x4=0

y1=0
y2=0
y3=2
y4=2

x=[]
y=[]
x.append(x1)
x.append(x2)
x.append(x3)
x.append(x4)
y.append(y1)
y.append(y2)
y.append(y3)
y.append(y4)
z=np.zeros(8)

triang = mtri.Triangulation(x, y, triangles=[[[x1,y1],[x2,y2],[x3,y3]],[[x3,y3],[x4,y4],[x2,y2]]])

ax.plot_trisurf(triang, z, linewidth=0.2, antialiased=True)

ax.view_init(45,-90)
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
ax.set_aspect("equal")

fig.set_size_inches(8,8)

plt.show()
like image 569
Alex Santelle Avatar asked Jan 29 '23 23:01

Alex Santelle


1 Answers

There is an example on the matplotlib page that shows how to use points and triangles to create a matplotlib.tri.Triangulation. As this may be unnecessarily complicated, we may simplify even further.

Let's take 4 points, which should create 2 triangles. The triangles argument would specify the corners of the triangles in form of the indices of the points. As the documentation says,

triangles : integer array_like of shape (ntri, 3), optional
For each triangle, the indices of the three points that make up the triangle, ordered in an anticlockwise manner. [..]

Consider this code, where we have a (4,2) array, specifying the point coordinates, having the x and y coordinates for each point in a row. We then create triangles from them by using the indizes of the points that should constitute the triangle in an anti-clockwise manner.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.tri as mtri

xy = [[0.3,0.5],
      [0.6,0.8],
      [0.5,0.1],
      [0.1,0.2]]
xy = np.array(xy)

triangles = [[0,2,1],
             [2,0,3]]

triang = mtri.Triangulation(xy[:,0], xy[:,1], triangles=triangles)
plt.triplot(triang, marker="o")

plt.show()

The first triangle is made up of points 0, 2, 1 and the second of 2,0,3. The following graphics shows visualizes that code.

enter image description here

We may then create a list of z values and plot the same in 3D.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.tri as mtri
from mpl_toolkits.mplot3d import Axes3D

xy = [[0.3,0.5],
      [0.6,0.8],
      [0.5,0.1],
      [0.1,0.2]]
xy = np.array(xy)

triangles = [[0,2,1],
             [2,0,3]]

triang = mtri.Triangulation(xy[:,0], xy[:,1], triangles=triangles)

z = [0.1,0.2,0.3,0.4]

fig, ax = plt.subplots(subplot_kw =dict(projection="3d"))
ax.plot_trisurf(triang, z)

plt.show()

enter image description here

like image 134
ImportanceOfBeingErnest Avatar answered Feb 02 '23 08:02

ImportanceOfBeingErnest