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

Plotting PolyData slices with Matplotlib #70

Closed
banesullivan opened this issue Oct 17, 2019 · 4 comments
Closed

Plotting PolyData slices with Matplotlib #70

banesullivan opened this issue Oct 17, 2019 · 4 comments
Labels
example There's a good/reusable example in here! plotting General plotting/rendering topics tips

Comments

@banesullivan
Copy link
Member

banesullivan commented Oct 17, 2019

It's possible to plot pyvista.PolyData (vtkPolyData) with matplotlib, so I thought I'd share a snippet to do just that!

In this example, I take a slice that has a Z normal which makes extracting the planar data for Matplotlib very straightforward. In the case where the slice does not have a normal along a cartesian axis, you'd have to rotate the mesh such that it does. I don't have an immediate solution for that so I'll try to post that in the comments below later. If anyone else knows how to rotate meshes from a best-fitting plane to the XY plane, please share! But note that it would mess up the axis labeling for Matplotlib

Adapted from https://perso.univ-rennes1.fr/pierre.navaro/read-vtk-with-python.html

import matplotlib.pyplot as plt
import pyvista as pv
import numpy as np
from pyvista import examples

# Some dataset
mesh = examples.load_uniform()

# Slice and triangulate
#-Note that this slice is on the XY plane
#-for any other orientation, we'd have to rotate it
#-to have a Z normal
#-also note that this requires the data to be on the nodes, not cells
data = mesh.ctp().slice("z", generate_triangles=True)

# Grab data for Matplotlib
x = data.points
tri = data.faces.reshape((-1,4))[:, 1:]
u = data.active_scalar

# Plot it yo!
plt.tricontourf(x[:,0], x[:,1], tri, u)
plt.gca().set_aspect('equal')

download

@banesullivan
Copy link
Member Author

banesullivan commented Oct 17, 2019

And here is another interesitng way to plot orthographic slices with Matplotlib. The axes alignments and scaling could use some work.

import matplotlib.pyplot as plt
import pyvista as pv
import numpy as np
from pyvista import examples

def slice_ortho(mesh, x=None, y=None, z=None, scalars=None,
                fig=None):
    mesh.set_active_scalar(scalars)
    # order: YZ, XZ, XY
    slices = mesh.ctp().slice_orthogonal(x=x, y=y, z=z, 
                                   generate_triangles=True, 
                                   contour=False)
    
    p = pv.Plotter(off_screen=True, notebook=False)
    p.add_mesh(slices)
    _, perspective = p.show(screenshot=True)
    
    def plot_mpl(ax, slc, u, v):
        pts = slc.points
        tri = slc.faces.reshape((-1,4))[:, 1:]
        val = slc.active_scalar
        
        ax.tricontourf(pts[:,u], pts[:,v], tri, val)
        return
        
    axii = [(1,2), (0,2), (0,1)]
    
    if fig is None:
        fig = plt.figure()
    
    ax1 = fig.add_subplot(2, 2, 1)
    #ax1.set_aspect('equal')
    ax2 = fig.add_subplot(2, 2, 2, sharey=ax1)
    ax3 = fig.add_subplot(2, 2, 3, sharex=ax1)
    plts = [ax1, ax2, ax3]

    for i, slc in enumerate(slices):
        plot_mpl(plts[i], slc, *axii[i])
        
    ax4 = fig.add_subplot(2, 2, 4, )
    ax4.imshow(perspective)
    ax4.get_xaxis().set_visible(False)
    ax4.get_yaxis().set_visible(False)
        
    return fig


mesh = examples.load_channels()

fig = plt.figure(figsize=(10,6))
slice_ortho(mesh, fig=fig)
plt.tight_layout()
plt.show()

download

@banesullivan
Copy link
Member Author

banesullivan commented Oct 17, 2019

I imagine that we could easily take @prisae's awesome Matplotlib slicer tool in discretize and add callbacks to the slice method in PyVista for an interactive, matplotlib based orthographic slicer of any PyVista dataset

@banesullivan banesullivan added example There's a good/reusable example in here! plotting General plotting/rendering topics tips labels Oct 17, 2019
@banesullivan
Copy link
Member Author

banesullivan commented Oct 17, 2019

So I just created a hacked version of your slicer, @prisae. It's over in https://github.com/banesullivan/pyvista-mpl-slicer

The callbacks don't seem to be working.... not sure what exactly is broken, but it's mostly there!

@prisae
Copy link
Member

prisae commented Oct 17, 2019

Awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
example There's a good/reusable example in here! plotting General plotting/rendering topics tips
Projects
None yet
Development

No branches or pull requests

2 participants