pyvista / pyvista-support

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

Issue when using the slicing in the z direction #378

Open lllangWV-zz opened 3 years ago

lllangWV-zz commented 3 years ago

Hello!

I am currently trying to make a slice of my vtk object, but when I slice in the z direction the coloring becomes wrong. Then when I move the widget, the coloring becomes white. It is odd because slices in the x and y direction produce the right coloring and the widget works as expected.

Do you know what could be the cause?

Thank you if you are able to help out!

Logan Lang

Here is my script and I have attached a zip file containing the vtk object and the test script

import pyvista as pv

vol = pv.read('MgB2_fermi.vtk')
p = pv.Plotter()

# Produces wrong coloring. Moving the widget cause color to turn white
p.add_mesh_slice(vol, normal = 'z')

# Produces right coloring. Moving the widget keeps coloring
# p.add_mesh_slice(vol, normal = 'x')

# Produces right coloring. Moving the widget keeps coloring
# p.add_mesh_slice(vol, normal = 'y')

p.add_mesh(vol,opacity = 0.25)
p.show()

MgB2_fermi.zip

adeak commented 3 years ago

First of all, I can reproduce what you see. (I believe there was a mistake in the third comment; I've edited it in your original issue comment so please check if I got it right: y is also "right coloring".) It's enough to click on the plane widget's boundary to trigger the switch to white in the pathological direction.

Second of all, I have no idea what's going on.

Third of all, I believe rather than a bug for the z direction, the issue is related to your mesh. If you rotate your Fermi surface 90 degrees around the x axis (so that z becomes y) suddenly it's the y axis that's pathological

vol.rotate_x(90)
p.add_mesh_slice(vol, normal='y')
p.show()

So this suggests that there's some feature of your data that breaks the plane widget. I've already checked that your scalars contain no nans or infs.

I also checked that asking for static slices along the z direction (with unrotated mesh) gives reasonable colours, however the slices around z=0 show the same colour artifacts as the initial state of the plane widget with normal along z:

import pyvista as pv

vol = pv.read('MgB2_fermi.vtk')

p = pv.Plotter()
p.add_mesh(vol.slice_along_axis(axis='z', n=21))
p.add_mesh(vol, opacity=0.25)
p.show(auto_close=False, screenshot='slices_along_z.png')

slices along z with some colour artifacts Note the yellow sections on the middle right of the central purple column, and the purple sections on the top left of the yellow rings. I don't think those should look like that, and I don't know where those can come from (perhaps noise in your raw data). I also don't see how this could break the plane widget, but admittedly I'm not familiar with how that works anyway.

akaszynski commented 3 years ago

Played around with this as well and got the same bug. I think it's a VTK issue and isn't necessarily a pyvista issue. Looking at the raw data in the Z direction, I'm not seeing any indication of why the color suddenly dispersal. The values are all still valid and non-zero and numeric.

lllangWV-zz commented 3 years ago

Sorry for the late response, my schedule is crazy at the moment. Thank you both so much for looking into this behavior.

If it is an issue on VTK end, how would I go about fixing that issue? I would like to fix this because cross sections of fermi surfaces are very useful plot for experimentalists and it would be a very neat feature for users.

akaszynski commented 3 years ago

I'd try using a different version of VTK, or not start with an exact Z slice (have a slight offset to your plane).

adeak commented 3 years ago

I still don't know what's going on, but I've found half a workaround.

Initialize your plane widget along a different axis, then a posteriori orient it toward the z axis:

p.add_mesh_slice(vol, normal='x')
widg = p.plane_widgets[0]
widg.SetNormal(0, 0, 1)

Unfortunately I couldn't find a way to update the initial slice along the different normal. As far as I can tell the algorithm and callbacks needed to achieve that are not accessible from the outside (@akaszynski might verify or disprove this).

But if you click on the plane's boundary once or interact with it in some other way the slice will update and the colours will be preserved, it seems.

lllangWV-zz commented 3 years ago

I have tried akaszynski solution of using an exact z slice with having a slight offset, but that produced wrong coloring on the rings.

I think adeak solution could work, but I agree the we would need a way to update the widget to update the widget before using p.show().