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

opacity for different mesh/actor #304

Closed dansand closed 3 years ago

dansand commented 3 years ago

Thanks to all the developers/contributors for this terrific package.

I want to plot a scalar field (from a 2d FEM simulation) with some opacity (e.g. 0.5), and then plot contours with no opacity. What seems to happen is that the contour opacity inherits the value I set in the scalar field.

Here is the example code ( I can provide input files and/or screenshots if that's needed):

vtk_data = pv.read(vtk_file)

contours = vtk_data.contour(isosurfaces=[295, 873,973], 
                             scalars='T')

p = pv.Plotter( window_size = (800, 250), border=True, border_color='black', border_width=2.0)

p.add_mesh(vtk_data, scalars = 'stress_xx', cmap=stress_cm, opacity = 0.5,
           clim  = [-50e6, 50e6], stitle='$\sigma_{xx}$ (MPa)', show_scalar_bar=True)

p.add_mesh(contours, color="black", line_width=2, opacity = 1.0)

p.view_xy()
github-actions[bot] commented 3 years ago

Hi and welcome! Thanks for posting your first issue in the PyVista project! Someone from @pyvista/developers will chime in before too long. If your question is support related, it may be automatically transferred to https://github.com/pyvista/pyvista-support

banesullivan commented 3 years ago

What seems to happen is that the contour opacity inherits the value I set in the scalar field.

This definitely shouldn't be happening. Can you share the mesh and a screenshot?


Here is an example similar to what I think you are trying to do:

import pyvista as pv
from pyvista import examples

vtk_data = examples.download_st_helens()
contours = vtk_data.contour()

p = pv.Plotter()
p.add_mesh(vtk_data, opacity=0.5)    
p.add_mesh(contours, color="black", line_width=2, opacity=1.0)
p.view_xy()
p.show()

download

The contours have no opacity, however, they are shown intersecting the original mesh which might add some distortion in your data (perhaps the "haze" you see over the contours from the other mesh being transparent).

There are a few mitigation techniques if this is the case

  1. Move the points in the z-direction so they are on top of the transparent mesh: contours.points[:, -1] += 0.001
  2. special VTK intersection mapping parameters
  3. depth peeling: p.enable_depth_peeling()
dansand commented 3 years ago

Thanks for getting back to me. I think you're right that this is a "haze" issue. When you further decrease the opacity on the other mesh, the contours stand out much more clearly:

opacity_test

dansand commented 3 years ago

import pyvista as pv
pv.set_plot_theme("document")

vtk_file =  'temperature_0.vtu'
vtk_data = pv.read(vtk_file)

contours = vtk_data.contour(isosurfaces=[295, 873,973], 
                             scalars='T')

###################################

p = pv.Plotter( window_size = (1600, 500), border=True, border_color='black', border_width=2.0)

p.add_mesh(vtk_data, scalars = 'T', stitle = 'Temperature',  cmap='viridis', 
          clim = [273, 1500],
           scalar_bar_args = dict(title_font_size=48),
           opacity=0.75)

p.add_mesh(contours, color="black", line_width=6,
           opacity=1.0)

p.camera_position = [(416.0689376056465, 92366.4072261825, -37740.71276357017),
 (416.0689376056465, 92366.4072261825, 0.0),
 (0.0, 1.0, 0.0)]

p.add_text("temperature \n opacity 75%", 
           position = 'lower_left', font_size=22, shadow=True)

p.screenshot('./detachment_paper/opacity_test/opacity_75%.png') 

p.render()
p.show()
dansand commented 3 years ago

temperature_0.zip

dansand commented 3 years ago

Moving the points in the z-direction seems to be the best workaround from the suggestions provided.

Thanks!