Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add full featured plot_3d function #2634

Open
jgostick opened this issue Nov 30, 2022 · 3 comments
Open

Add full featured plot_3d function #2634

jgostick opened this issue Nov 30, 2022 · 3 comments

Comments

@jgostick
Copy link
Member

The pyvista package has come VERY far since the last time I checked. It's now very simple to create a 3D interactive plot of a network inside jupyter, with proper glyphs:

import numpy as np
import openpnm as op
import pyvista as pv

pn = op.network.Cubic([5, 5, 5])
pn.add_model_collection(op.models.collections.geometry.spheres_and_cylinders)
pn.regenerate_models()


def plot_3d(network, size_by=None):
    x, y, z = network.coords.T

    # Create and structured surface
    grid = pv.StructuredGrid(x, y, z)
    if size_by is None:
        size_by = network['pore.diameter']
    grid.point_data['size'] = size_by

    # generate glyphs with varying size
    sphere = pv.Sphere()
    spheres = grid.glyph(scale='size', geom=sphere, orient=False)

    spheres.plot(show_scalar_bar=False)
    return spheres


p = plot_3d(pn)  # Call function and catch result
# p.plot()  # Show plot if not already visible
# p.save('test.vtk', binary=False)  # Write to paraview compatible file
@jgostick
Copy link
Member Author

It is also possible to add oriented cylindrical glyphs for the throats, but I have not quite figured that out yet. I also expect it'd be possible to use a wider variety of glyphs beyond what Paraview offers. For instance, boxes with some aspect ratio, or maybe pyramids?

@ma-sadeghi ma-sadeghi changed the title Add full featured "plot_3d" function Add full featured plot_3d function Dec 1, 2022
@jgostick
Copy link
Member Author

jgostick commented Dec 3, 2022

Someone on the pyvista Discussion has already answered a quesiton which I think pertains to us: pyvista/pyvista#2635

@jgostick
Copy link
Member Author

jgostick commented Dec 3, 2022

This works, but the throat diameter's cannot be scaled independently:

import numpy as np
import openpnm as op
import pyvista as pv

pn = op.network.Cubic([5, 5, 5])
pn.add_model_collection(op.models.collections.geometry.spheres_and_cylinders)
pn.add_model('throat.coords', op.models.geometry.throat_centroid.pore_coords)
pn.add_model('throat.vector', op.models.geometry.throat_vector.pore_to_pore)
pn.regenerate_models()

# %% Create and structured surface
grid = pv.StructuredGrid(*pn.coords.T)
grid.point_data['size'] = pn['pore.diameter']
sphere = pv.Sphere(phi_resolution=180, theta_resolution=180, radius=1)
pores = grid.glyph(scale='size', geom=sphere, orient=False)


# %% Generate throat cylinders
edges_w_padding = np.vstack((np.ones(pn.conns.shape[0], int)*2, pn.conns.T)).T
throats = pv.PolyData(pn.coords, edges_w_padding)
size_by = pn['pore.diameter']


# %% Add both meshes to a plotte object
plotter = pv.Plotter()
plotter.add_mesh(
    pores,
    lighting=True,
    cmap="jet",
    show_scalar_bar=False,
    opacity=0.5)
plotter.add_mesh(
    throats,
    lighting=True,
    scalars=pn['throat.diameter'],
    render_lines_as_tubes=True,
    style='wireframe',
    line_width=10,
    cmap='jet',
    show_scalar_bar=False,
)
plotter.show_axes()
plotter.show()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant