pyvista / pyvista-support

[moved] Please head over to the Discussions tab of the PyVista repository
https://github.com/pyvista/pyvista/discussions
59 stars 4 forks source link

Plot Truss-like FEA solution with cylinders #494

Closed supergra closed 2 years ago

supergra commented 2 years ago

Specific question: How do I plot connections between points in 3D as cylinders, colored by some scalar?

Screen Shot 2021-08-27 at 09 22 27

Context: I am trying to move over from MayaVi, after one two many frustrations with the documentation and painfully slow processing times. I'm delighted at how snappy PyVista is on the examples, but I'm stymied about how to get started with my current project.

Here is some sample code from MayaVi that I'm trying to port. It doesn't need to look exactly like this, I just want to understand how to go about creating something that roughly conveys this same information. Even a pointer to the right place in the API would be helpful. I found many useful functions for surface meshes, but no examples in the gallery that look quite like this.

import random
from mayavi import mlab

nodes = [
    [0.0, 0.0, 0.0],
    [0.0, 1.0, 0.0],
    [4.0, 3.0, 0.0],
    [4.0, 0.0, 0.0],
    [0.0, 1.0, 2.0],
    [4.0, 1.0, 2.0],
    [4.0, 3.0, 2.0]
    ]

edges = [
    [0, 4],
    [1, 4],
    [3, 4],
    [5, 4],
    [6, 4],
    [3, 5],
    [2, 5],
    [5, 6],
    [2, 6],
    ]

mfig = mlab.figure()

for iA, iB in edges:
    xs, ys, zs = zip(nodes[iA], nodes[iB])

    # (Color would come from a nice scalar)
    col = (random.random(),random.random(),random.random())

    mlab.plot3d(xs, ys, zs,  color=col, figure=mfig, tube_radius=0.1)

mlab.show()
akaszynski commented 2 years ago
import numpy as np
import pyvista

nodes = [
    [0.0, 0.0, 0.0],
    [0.0, 1.0, 0.0],
    [4.0, 3.0, 0.0],
    [4.0, 0.0, 0.0],
    [0.0, 1.0, 2.0],
    [4.0, 1.0, 2.0],
    [4.0, 3.0, 2.0]
    ]

edges = np.array([
    [0, 4],
    [1, 4],
    [3, 4],
    [5, 4],
    [6, 4],
    [3, 5],
    [2, 5],
    [5, 6],
    [2, 6],
    ])

# We must "pad" the edges to indicate to vtk how many points per edge
edges_w_padding = np.vstack((np.ones(edges.shape[0], int)*2, edges.T)).T

# this is the same as:
edges_w_padding = np.array([
    [2, 0, 4],
    [2, 1, 4],
    [2, 3, 4],
    [2, 5, 4],
    [2, 6, 4],
    [2, 3, 5],
    [2, 2, 5],
    [2, 5, 6],
    [2, 2, 6],
    ])

mesh = pyvista.PolyData(nodes, edges_w_padding)

colors = np.random.random(edges.shape[0])
mesh.plot(scalars=colors,
          render_lines_as_tubes=True,
          style='wireframe',
          line_width=10,
          cmap='jet',
          show_scalar_bar=False,
          background='w')

sc

I'd love it if you could provide (or at least setup) a PR converting from mayavi to pyvista.

supergra commented 2 years ago

Terrific, that's much easier than expected! Thank you for taking the time.

FWIW, I don't know whether a general conversion guide from MayaVi would've helped me in this particular case. You can't really do a 1-1 map of the entire API, and that's perhaps not even the right way to think about things, like trying to translating a language word-by-word. What I mostly needed was simply more items in the examples/gallery (which admittedly already has lots of examples!).

akaszynski commented 2 years ago

We can then just add this as an example.