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'],
)
# 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:
And this is the output I would expect, displayed by paraview.
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
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'],
)
# 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:
And this is the output I would expect, displayed by paraview.
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
Share Improve this question edited Mar 20 at 20:44 bue asked Mar 19 at 13:43 buebue 6534 silver badges16 bronze badges1 Answer
Reset to default 1To solve the coloring issue map the atype string values to numeric values. then configure the vtk mapper to use this numeric array. I highlighted the changes in the code bellow using ####:
# 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'],
)
# 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')
#################################################################################
atype_mapping = {atype: idx for idx, atype in enumerate(df_cell['atype'].unique())}
numeric_atype = vtk.vtkIntArray()
numeric_atype.SetName('atype_numeric')
for atype in df_cell['atype']:
numeric_atype.InsertNextValue(atype_mapping[atype])
vug_data.GetPointData().AddArray(numeric_atype)
################################################################################
# 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.SetScalarModeToUsePointFieldData()
vpdm_data.SelectColorArray('atype_numeric')
vpdm_data.SetScalarRange(0, 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()