以下代码:
import pyvista as pv
import numpy as np
def test_pyvista_layers():
"""Test how PyVista handles multiple mesh layers with NaN values and opacity settings"""
# Create a simple sphere
sphere = pv.Sphere(radius=1.0)
total_points = sphere.n_points
# Create three meshes with known patterns
mesh1 = sphere.copy()
mesh2 = sphere.copy()
mesh3 = sphere.copy()
# Test 1: Basic overlap with different values and NaN
values1 = np.full(total_points, np.nan) # Initialize with NaN
values1[:total_points//3] = 1 # Set first third to 1
values2 = np.full(total_points, np.nan) # Initialize with NaN
values2[total_points//3:2*total_points//3] = 2 # Set middle third to 2
values3 = np.full(total_points, np.nan) # Initialize with NaN
values3[2*total_points//3:] = 3 # Set final third to 3
# Validate NaN counts and non-overlap
nan_count1 = np.sum(np.isnan(values1))
nan_count2 = np.sum(np.isnan(values2))
nan_count3 = np.sum(np.isnan(values3))
print(f"\nNaN Counts:")
print(f"Layer 1: {nan_count1} NaN values ({(nan_count1/total_points)*100:.1f}% of points)")
print(f"Layer 2: {nan_count2} NaN values ({(nan_count2/total_points)*100:.1f}% of points)")
print(f"Layer 3: {nan_count3} NaN values ({(nan_count3/total_points)*100:.1f}% of points)")
# Check for overlap between non-NaN regions
overlap_12 = np.sum(~np.isnan(values1) & ~np.isnan(values2))
overlap_23 = np.sum(~np.isnan(values2) & ~np.isnan(values3))
overlap_13 = np.sum(~np.isnan(values1) & ~np.isnan(values3))
print("\nOverlap Check:")
print(f"Overlap between layers 1-2: {overlap_12} points")
print(f"Overlap between layers 2-3: {overlap_23} points")
print(f"Overlap between layers 1-3: {overlap_13} points")
# Validate complete coverage
total_coverage = np.sum(~np.isnan(values1) | ~np.isnan(values2) | ~np.isnan(values3))
print(f"\nTotal Coverage: {total_coverage} points ({(total_coverage/total_points)*100:.1f}% of surface)")
plotter = pv.Plotter()
# Add meshes with point data and NaN handling
mesh1.point_data['values'] = values1
mesh2.point_data['values'] = values2
mesh3.point_data['values'] = values3
# Add meshes with nan_opacity=0 to make NaN values completely transparent
plotter.add_mesh(mesh1, color='red', opacity=1.0, label='Layer 1', nan_opacity=0.0)
plotter.add_mesh(mesh2, color='blue', opacity=1.0, label='Layer 2', nan_opacity=0.0)
plotter.add_mesh(mesh3, color='green', opacity=1.0, label='Layer 3', nan_opacity=0.0)
return plotter
test_plotter = test_pyvista_layers()
test_plotter.show()
生成附加图像(绿色球体)而不是预期的三部分球体。我的理解是 nan_opacity=0.0 应该使球体的其余部分透明??
它还会打印以下输出,确认这些点确实是 NaN。
NaN 计数: 第 1 层:562 个 NaN 值(66.7% 的点) 第 2 层:561 个 NaN 值(占点的 66.6%) 第 3 层:561 个 NaN 值(66.6% 的点)
重叠检查: 第 1-2 层之间的重叠:0 分 第 2-3 层之间的重叠:0 分 第 1-3 层之间的重叠:0 分
总覆盖范围:842 点(表面的 100.0%)
我尝试了许多不同的方法来呈现它,并浏览了文档,但没有任何效果。有关如何处理此问题的建议表示赞赏!
问题是您为网格请求特定的颜色,这会覆盖每个网格上的任何标量,这反过来会影响映射(有效地禁用任何依赖于标量的内容)。您可以尝试将
show_scalar_bar=True
传递给 add_mesh()
并看到它没有执行任何操作。
最简单的解决方案是使用 颜色图 与您想要作为分类数据的颜色相匹配:
cmap = ['red', 'blue', 'green']
plotter.add_mesh(mesh1, label='Layer 1', nan_opacity=0.0, cmap=cmap)
plotter.add_mesh(mesh2, label='Layer 2', nan_opacity=0.0, cmap=cmap)
plotter.add_mesh(mesh3, label='Layer 3', nan_opacity=0.0, cmap=cmap)
请注意,我删除了默认的
opacity=1.0
和 color=...
,它允许每个网格上的标量显现。
唯一奇怪的是这些碎片现在是半透明的。我不知道为什么会发生这种情况。这似乎是纳米不透明度的副作用,因为将其更改为 1.0 也会使网格的其余部分变得不透明。也许这是一个错误。