ChartXY log scale warning and wrong plot
Following the discussion in !8693 (merged), I analyzed the log scale behaviour of ChartXY in more depth. Let me start by saying my initial attempt at a fix in !8618 (merged) was a bit overkill, as the actual issue is related to a peculiar combination of a custom axis range, axis behavior and an enabled log scale (while I initially thought it was only related to this log scale). I will use the below script and table to illustrate the problem.
Python code to reproduce plots below
import vtk
from vtkmodules.util.numpy_support import vtk_to_numpy
from PIL import Image
def save_render(data_column, y_range, y_behavior, name):
width, height = 400, 400
renwin = vtk.vtkRenderWindow()
renwin.SetOffScreenRendering(1)
renwin.SetSize(width, height)
renderer = vtk.vtkRenderer()
renderer.SetBackground([1, 1, 1])
renwin.AddRenderer(renderer)
chart_scene = vtk.vtkContextScene()
chart_actor = vtk.vtkContextActor()
chart_actor.SetScene(chart_scene)
renderer.AddActor(chart_actor)
chart_scene.SetRenderer(renderer)
chart = vtk.vtkChartXY()
chart_scene.AddItem(chart)
table = vtk.vtkTable()
arrX = vtk.vtkFloatArray()
arrX.SetName('X Axis')
arrN = vtk.vtkFloatArray()
arrN.SetName('Negative Line')
arrP = vtk.vtkFloatArray()
arrP.SetName('Positive Line')
table.AddColumn(arrX)
table.AddColumn(arrN)
table.AddColumn(arrP)
numPoints = 101
table.SetNumberOfRows(numPoints)
for i in range(numPoints):
x = i / (numPoints - 1)
table.SetValue(i, 0, x)
table.SetValue(i, 1, 20*x - 10)
table.SetValue(i, 2, 10*x + 1e-6)
points = chart.AddPlot(vtk.vtkChart.LINE)
points.SetInputData(table, 0, data_column)
points.SetColor(0, 0, 255, 255)
points.SetWidth(1.0)
if y_range is not None:
points.GetYAxis().SetRange(*y_range)
points.GetYAxis().SetBehavior(y_behavior)
points.GetYAxis().SetLogScale(True)
renwin.SetMultiSamples(0)
renwin.Render()
arr = vtk.vtkUnsignedCharArray()
renwin.GetRGBACharPixelData(0, 0, width - 1, height - 1, 0, arr)
data = vtk_to_numpy(arr).reshape(height, width, -1)[::-1]
Image.fromarray(data).save(f"{name}.png")
# These behave correctly:
save_render(2, [-5, 10], vtk.vtkAxis.FIXED, "Dpos_Rneg_Bfixed")
save_render(2, [-5, 10], vtk.vtkAxis.AUTO, "Dpos_Rneg_Bauto")
save_render(2, [5, 10], vtk.vtkAxis.FIXED, "Dpos_Rpos_Bfixed")
save_render(2, [5, 10], vtk.vtkAxis.AUTO, "Dpos_Rpos_Bauto")
# Following three behave correctly:
save_render(1, [-5, 10], vtk.vtkAxis.FIXED, "Dneg_Rneg_Bfixed")
save_render(1, [-5, 10], vtk.vtkAxis.AUTO, "Dneg_Rneg_Bauto")
save_render(1, [5, 10], vtk.vtkAxis.FIXED, "Dneg_Rpos_Bfixed")
# This one gives a "vtkMath::Jacobi: Error extracting eigenfunctions" warning and is not correctly drawn
save_render(1, [5, 10], vtk.vtkAxis.AUTO, "Dneg_Rpos_Bauto")
In summary, the code creates a ChartXY with a line plot of a linear function (with negative and positive values if data_column
is 1 and only positive values when data_column
is 2). The Y axis range is set to either [-5, 10]
(i.e. both negative and positive values) or [5, 10]
(i.e. only positive values). The Y axis behaviour is set to be either fixed (following the custom range) or auto (discarding the custom range).
Resulting plots
The problematic combination is the last one (negative data, positive range, auto behavior). This leads to the following vtkMath warning WARN| vtkMath::Jacobi: Error extracting eigenfunctions
. I assume this has something to do with NaNs arising by taking the log of negative values. Even though this shouldn't be happening, as the log scale should be disabled because of the auto behavior (but this isn't happening either, as nothing is drawn in this case).
@mwestphal and @yohann.bearzi your thoughts and comments would be appreciated. Let me know if my interpretation of these results is wrong.
Edit: Only the last combination seems to be causing trouble, the rest is fine.