Skip to content

Chart Enhancements

dcbr requested to merge dcbr/vtk:master into master

While working with the VTK Charts API for the pyvista project (Charts PR), I noticed a couple of inconsistencies and bugs that I would like to address in this PR. I included some code fragments to reproduce the problems I encountered (using pyvista for code brevity) and 'before' and 'after' visualizations.

Fixes:

  • Chart backgrounds take borders correctly into account (resolves #18238 (closed)).
  • Fix ChartXY.SetAxis leaving references to old axis.
Example
import pyvista
chart = pyvista.Chart2D()
plot = chart.line([0, 1, 2], [2, 1, 3])
old_axis = chart.x_axis
new_axis = pyvista.charts.Axis("Custom x")
chart.SetAxis(new_axis.BOTTOM, new_axis)		# Below prints are False before these changes, True afterwards.
print(plot.GetXAxis().__this__ == new_axis.__this__)	# Plots still referenced old axis instead of the new.
print(not old_axis.HasObserver(chart.UpdateRange))	# Old axis still had an active AxisRangeListener.
  • ChartPie properly apply Brush while painting.
Example
Code Before & After
import pyvista
bg_chart = pyvista.ChartPie([1,1,1], labels=["A","B","C"])
bg_chart._background.SetVisible(False)  # Disable chart background, which patches this bug
bg_chart.plot.GetBrush().SetOpacity(0)  # Set a low opacity for the background chart, which
chart = pyvista.ChartPie([1,2,3])	# will leak into the foreground chart.
chart._background.SetVisible(False)	# Disable chart background, which patches this bug
pl = pyvista.Plotter()
pl.add_chart(bg_chart, chart)
pl.show()
image
  • ChartPie legend is correctly replaced when any of the labels change.
Example
Code Before & After
import pyvista
chart = pyvista.ChartPie([1,2,3])
chart.show()	# Paint chart such that geometry is properly set
chart.plot.labels = ["A","B","C"]
chart.show()	# Paint chart again after changing the labels
image
  • Fix ChartXY graphical glitch and vtkMath::Jacobi warning when using an axis with log scale.
Example
Code Before & After
import pyvista
chart = pyvista.Chart2D()
chart.line([0, 1], [-10, 10]) # Plot for which log scale cannot be enabled
axis = chart.y_axis
axis.SetRange(2, 5)
axis.SetLogScale(True)
chart.show() # Results in "vtkMath::Jacobi: Error extracting eigenfunctions" warning before changes
image
import pyvista
chart = pyvista.Chart2D()
chart.line([0, 1], [-10, 10]) # Plot for which log scale cannot be enabled
axis = chart.y_axis
axis.SetRange(2, 5)
axis.SetBehavior(axis.FIXED)
axis.SetLogScale(True)
chart.show()
image

Enhancements:

  • ChartPie and ChartBox can have a custom size and location now (previously always filled the entire scene).
Example
Code Before & After
import pyvista
from vtkmodules.vtkCommonDataModel import vtkRectf
ws = pyvista.global_theme.window_size
# Create a half-sized pie chart, centered in the middle of the scene.
chart = pyvista.ChartPie([5, 4, 3])
chart.SetAutoSize(False)
chart.SetSize(vtkRectf(ws[0]/4, ws[1]/4, ws[0]/2, ws[1]/2))
chart.show()
image
import pyvista
from vtkmodules.vtkCommonDataModel import vtkRectf
ws = pyvista.global_theme.window_size
# Create a half-sized box chart, centered in the middle of the scene.
chart = pyvista.ChartBox([[0, 1, 1, 2, 3, 3, 4]])
chart.SetAutoSize(False)
chart.SetSize(vtkRectf(ws[0]/4, ws[1]/4, ws[0]/2, ws[1]/2))
chart.show()
image
  • ChartPie.SetPlot can be used now to set a custom PlotPie instance (like ChartBox.SetPlot).
Example
import pyvista
chart = pyvista.ChartPie([1,2,3])
plot = pyvista.charts.PiePlot([1,1,1])  # We can specify a custom vtkPiePlot instance now, which was previously impossible.
chart.SetPlot(plot)
chart.show()
  • Axis.SetPen and Axis.SetGridPen methods.
Example
import pyvista
chart = pyvista.Chart2D()
chart.line([0, 1, 2], [2, 1, 3])
pen = pyvista.charts.Pen('r')
grid_pen = pyvista.charts.Pen('b')
chart.x_axis.SetPen(pen)	# We can specify a custom Pen instance now, which was previously impossible.
chart.y_axis.SetGridPen(grid_pen)
chart.show()
  • Increased ClipBox of ChartXY to properly display lines/points near the edge of the chart's patch.
Example
Code Before & After
import pyvista
chart = pyvista.Chart2D()
chart.plot([-1, 0, 1, 1, 1, 0, -1, -1, -1], [1, 1, 1, 0, -1, -1, -1, 0, 1], "-o")
chart.hide_axes()
chart.show()
image
Edited by dcbr

Merge request reports