[Python] Coloring Python VTK PolyData by additional attribute values in the dataset

Discussão em 'Python' iniciado por Stack, Março 19, 2025.

  1. Stack

    Stack Membro Participativo

    Utilizing the vtk python library I am trying to color vtk polydata by a defined attribute (atype). So far I did not succeed. The renderer does not color by the specified attribute (atype) but instead by other date specified (position_and_radii).

    Checking with paraview, all the data is around, and in paraview I can easily color by the requested attribute.

    There is something I miss and I cannot figure out what ...

    This is a simple code example.

    # libraries
    import vtk
    import pandas as pd

    # generate data
    df_cell = pd.DataFrame(
    [[1,1,1,1,0.1,'abc'],[2,2,2,2,0.2,'def'],[3,3,3,3,0.3,'def'],[4,4,4,4,0.4,'abc']],
    columns=['ID','position_x','position_y','position_z','radius','atype'],
    )
    df_cell.index = range(1,5)

    # generate VTK instances to fill for positions and radii
    vp_points = vtk.vtkPoints()
    vfa_radii = vtk.vtkFloatArray()
    vfa_radii.SetName('radius')

    # fill VTK instance with positions and radii
    for i in df_cell.index:
    vp_points.InsertNextPoint(
    df_cell.loc[i, 'position_x'],
    df_cell.loc[i, 'position_y'],
    df_cell.loc[i, 'position_z']
    )
    vfa_radii.InsertNextValue(df_cell.loc[i, 'radius'])

    # generate data instances
    vfa_data = vtk.vtkFloatArray()
    vfa_data.SetNumberOfComponents(2)
    vfa_data.SetNumberOfTuples(df_cell.shape[0])
    vfa_data.CopyComponent(0, vfa_radii, 0)
    vfa_data.SetName('positions_and_radii')

    # generate unstructred grid for data
    vug_data = vtk.vtkUnstructuredGrid()
    vug_data.SetPoints(vp_points)
    vug_data.GetPointData().AddArray(vfa_data)
    vug_data.GetPointData().SetActiveScalars('positions_and_radii')

    # fill this grid with given attributes
    voa_data = vtk.vtkStringArray()
    voa_data.SetName('atype')
    for i in df_cell.index:
    voa_data.InsertNextValue(df_cell.loc[i, 'atype'])
    vug_data.GetPointData().AddArray(voa_data)

    # generate sphere source
    vss_data = vtk.vtkSphereSource()
    vss_data.SetRadius(1.0)
    vss_data.SetPhiResolution(16)
    vss_data.SetThetaResolution(32)

    # generate Glyph to save
    vg_data = vtk.vtkGlyph3D()
    vg_data.SetInputData(vug_data)
    vg_data.SetSourceConnection(vss_data.GetOutputPort())

    # define important preferences for VTK
    vg_data.ClampingOff()
    vg_data.SetScaleModeToScaleByScalar()
    vg_data.SetScaleFactor(1.0)
    vg_data.SetColorModeToColorByScalar()
    vg_data.Update()

    # build VTKLooktupTable (color scheme)
    vlt_color = vtk.vtkLookupTable()
    vlt_color.SetNumberOfTableValues(256)
    vlt_color.SetHueRange(9/12, 0/12) # rainbow heat map
    vlt_color.Build()

    # set up the mapper
    vpdm_data = vtk.vtkPolyDataMapper()
    vpdm_data.SetInputConnection(vg_data.GetOutputPort())
    vpdm_data.ScalarVisibilityOn()
    vpdm_data.SetLookupTable(vlt_color)
    vpdm_data.ColorByArrayComponent('atype', 1)

    # set up the actor
    actor = vtk.vtkActor()
    actor.SetMapper(vpdm_data)

    # do renderer setup
    ren = vtk.vtkRenderer()
    renWin = vtk.vtkRenderWindow()
    renWin.AddRenderer(ren)
    renWin.SetSize(800, 600)
    iren = vtk.vtkRenderWindowInteractor()
    iren.SetRenderWindow(renWin)

    # add the actor to the renderer
    #ren.ResetCamera()
    ren.SetBackground(1/3, 1/3, 1/3) # gray
    ren.AddActor(actor)

    # render
    iren.Initialize()
    renWin.Render()
    iren.Start()

    # write VTK
    vw_writer = vtk.vtkXMLPolyDataWriter()
    vw_writer.SetFileName('vtkpoly.vtp')
    vw_writer.SetInputData(vg_data.GetOutput())
    vw_writer.Write()


    This is the output I get: [​IMG]

    And this is the output I would expect, displayed by paraview.

    [​IMG]

    Additionaly, does anyone know by heart, how it is possible to add a colorbar with legend to the rendered image (as viewable in the paraview image)?

    Thank you, Elmar

    Continue reading...

Compartilhe esta Página