1

I would like to plot a 3D finite element mesh using MATPLOTLIB. I have some problems using MAYAVI, so this kind of solution does not apply.

I need something like Matlab "patch" function, as shown below:

x = [0.0, 1.0, 0.0];
y = [0.0, 0.0, 1.0];
z = [0.0, 1.0, 1.0];
v = 100.0;
view(3)
patch(x, y, z, v)
hold on;
x = [1.0, 1.0, 0.0];
y = [0.0, 1.0, 1.0];
z = [1.0, 0.0, 1.0];
v = 50.0;
patch(x, y, z, v)

in this code, "v" is the scalar field evaluated at the center of each triangle. It produces the image below. Matlab pathc for 3D data.

Gabs
  • 292
  • 5
  • 23
  • I think [this](https://stackoverflow.com/questions/4622057/plotting-3d-polygons-in-python-matplotlib) is exactly what you need and so a possible duplicate question. –  Jul 04 '18 at 00:35
  • No, it is not. In [this](https://stackoverflow.com/questions/4622057/plotting-3d-polygons-in-python-matplotlib) post, only the surface is plotted. I need to use color gradients to represent the scalar vector. – Gabs Jul 04 '18 at 00:38
  • The OP in his question has included an updated answer which has added color `tri.set_color(colors.rgb2hex(sp.rand(3)))`. –  Jul 04 '18 at 00:53

1 Answers1

2

enter image description here

The following code produces similar results, but you'll want to play around with some of the parameters (colormap, normalization range (vmin, vmax), view angle, axis tick locations) to get exactly what you want:

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


def patch(ax, x, y, z, v, vmin=0, vmax=100, cmap_name='viridis'):
    cmap = mpl.cm.get_cmap(cmap_name)               # Get colormap by name
    c = cmap(mpl.colors.Normalize(vmin, vmax)(v))   # Normalize value and get color
    pc = Poly3DCollection([list(zip(x,y,z))])       # Create PolyCollection from coords
    pc.set_facecolor(c)                             # Set facecolor to mapped value
    pc.set_edgecolor('k')                           # Set edgecolor to black
    ax.add_collection3d(pc)                         # Add PolyCollection to axes
    return pc

def view(ax, code):
    if code == 2: #view(2) sets the default two-dimensional view, az = 0, el = 90.
        ax.view_init(90, 0)     # (args are reversed from MATLAB)

    if code == 3: #view(3) sets the default three-dimensional view, az = –37.5, el = 30.
        ax.view_init(30, -37.5)


fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

x = [0.0, 1.0, 0.0];
y = [0.0, 0.0, 1.0];
z = [0.0, 1.0, 1.0];
v = 100.0;

patch(ax, x, y, z, v)

x = [1.0, 1.0, 0.0];
y = [0.0, 1.0, 1.0];
z = [1.0, 0.0, 1.0];
v = 50.0;
patch(ax, x, y, z, v)

view(ax, 3)
plt.show()

Produces:

enter image description here

(The image at the top of the answer is rotated to get a similar view to yours in the question, because something seems off).

jedwards
  • 29,432
  • 3
  • 65
  • 92