1

Given a list looking like this:

triangels =  [
((1,1,1),(2,2,2),(1,3,4)),
((2,3,4),(9,9,9),(3,4,5)),
]

What is the fastest way to plot both triangles in 3D using pyplot? I do not find any way doing this, there is a 2D implementation.

Thank you!

This is not a duplicate since I asked how to convert the given list into triangles, I did not ask for a solution where the input is already manipulated.

2 Answers2

4

Here is a simpler way to do it

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection

triangles =  [
((1,1,1),(2,2,2),(1,3,4)),
((2,3,4),(9,9,9),(3,4,5)),
]


ax = plt.gca(projection="3d")

ax.add_collection(Poly3DCollection(triangles))

ax.set_xlim([0,10])
ax.set_ylim([0,10])
ax.set_zlim([0,10])

plt.show()

enter image description here

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
1

Here is a simple way to do that:

from itertools import chain
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

triangles =  [
    ((1, 1, 1), (2, 2, 2), (1, 3, 4)),
    ((2, 3, 4), (9, 9, 9), (3, 4, 5)),
]

# Convert the list of triangles into a "flat" list of points
tri_points = list(chain.from_iterable(triangles))
# Get the X, Y and Z coordinates of each point
x, y, z = zip(*tri_points)
# Make list of triangle indices ([(0, 1, 2), (3, 4, 5), ...])
tri_idx = [(3 * i, 3 * i + 1, 3 * i + 2) for i in range(len(triangles))]
# Make 3D axes
ax = plt.figure().gca(projection='3d')
# Plot triangles
ax.plot_trisurf(x, y, z, triangles=tri_idx)

Result:

Result

jdehesa
  • 58,456
  • 7
  • 77
  • 121
  • Exactly what I was looking for! Thank you! – Niclas Schwalbe Jul 16 '19 at 11:50
  • Do you know a way to color each triangle with a random color? – Niclas Schwalbe Jul 16 '19 at 12:03
  • @NiclasSchwalbe The simpler answer by [ImportanceOfBeingErnest](https://stackoverflow.com/users/4124317) is actually better for that too. You can simply make random colors with something like `tri_color = [(random.random(), random.random(), random.random()) for i in range(len(triangles))]` (or `np.random.rand(len(triangles), 3)` with NumPy) and then `ax.add_collection(Poly3DCollection(triangles, facecolors=tri_color))`. – jdehesa Jul 16 '19 at 12:44
  • (per-triangle colors in `plot_trisurf` is currently an [open issue](https://github.com/matplotlib/matplotlib/issues/9535)) – jdehesa Jul 16 '19 at 12:46