vtkLookupTable.SetNanColor fails when called after SetTableValue (Python, VTK 7.1.*)
When making a vtkLookupTable
, setting the desired color for NaN data points using SetNanColor
works fine if called as the first thing, before using SetTableValue
.
However, SetNanColor
fails if done after setting up the other colors using SetTableValue
. The specified color is not used to display NaN data points. Instead, the default reddish brown NaN color is used (or the color specified in a SetNanColor
call placed before any SetTableValue
calls). Oddly, GetNancolor
still correctly returns the color supplied to SetNanColor
.
This bug was seemingly introduced in VTK 7.1.0 and is still present in 7.1.1. Observed in Python 3.5 and 3.6.
Code to reproduce:
from __future__ import print_function
import vtk
import numpy
def main():
"""
:return: The render window interactor.
"""
chessboard_resolution = 5
n_lut_colors = 256
data_max_value = 1
# Provide some geometry
chessboard = vtk.vtkPlaneSource()
chessboard.SetXResolution(chessboard_resolution)
chessboard.SetYResolution(chessboard_resolution)
num_squares = chessboard_resolution * chessboard_resolution
# Force an update so we can set cell data
chessboard.Update()
# Make some arbitrary data to show on the chessboard geometry
data = vtk.vtkFloatArray()
for i in range(num_squares):
if i == 4:
# This square should in principle light up with color given by SetNanColor below
data.InsertNextTuple1(numpy.nan)
else:
thing = (i * data_max_value) / (num_squares - 1)
data.InsertNextTuple1(thing)
# Make a LookupTable
lut = vtk.vtkLookupTable()
lut.SetNumberOfColors(n_lut_colors)
lut.Build()
lut.SetTableRange(0, data_max_value)
lut.SetNanColor(.1, .5, .99, 1.0) # <------ This color gets used (light blue). If comment out, default reddish brown gets used.
for i in range(n_lut_colors):
# Fill it with arbitrary colors, e.g. grayscale
x = data_max_value*i/(n_lut_colors-1)
lut.SetTableValue(i, x, x, x, 1.0)
lut.SetNanColor(.99, .99, .1, 1.0) # <----- This color (yellow) gets ignored! ...except by GetNanColor
print(lut.GetNanColor()) # <-- Prints the color set by the last SetNanColor call above!
chessboard.GetOutput().GetCellData().SetScalars(data)
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(chessboard.GetOutputPort())
mapper.SetScalarRange(0, data_max_value)
mapper.SetLookupTable(lut)
mapper.Update()
actor = vtk.vtkActor()
actor.SetMapper(mapper)
renderer = vtk.vtkRenderer()
ren_win = vtk.vtkRenderWindow()
ren_win.AddRenderer(renderer)
renderer.SetBackground(vtk.vtkNamedColors().GetColor3d('MidnightBlue'))
renderer.AddActor(actor)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(ren_win)
ren_win.Render()
return iren
if __name__ == '__main__':
iren = main()
iren.Start()