PyVista NaN 不透明度错误?

问题描述 投票:0回答:1

以下代码:

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%)

我尝试了许多不同的方法来呈现它,并浏览了文档,但没有任何效果。有关如何处理此问题的建议表示赞赏!

debugging visualization pyvista
1个回答
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=...
,它允许每个网格上的标量显现。

结果如下: Sphere with three distjoint translucent lobes in three distinct colours: red, blue and green. In the bottom right there is a colour bar indicating the same three colours.

唯一奇怪的是这些碎片现在是半透明的。我不知道为什么会发生这种情况。这似乎是纳米不透明度的副作用,因为将其更改为 1.0 也会使网格的其余部分变得不透明。也许是一个错误。

© www.soinside.com 2019 - 2024. All rights reserved.