Difference between revisions of "Documentation/Nightly/Developers/Plots"

From Slicer Wiki
Jump to: navigation, search
(Created page with "<noinclude>{{documentation/versioncheck}}</noinclude> {{Clear|right}}{{TOC right}} = Slicer Plotting Overview and Acknowledgements = Slicer provides Plotting facilities that...")
 
Line 183: Line 183:
 
* Add categorical and date labels to the Bar plotting (analogous to the CHART infrastructure)
 
* Add categorical and date labels to the Bar plotting (analogous to the CHART infrastructure)
 
* More signals?
 
* More signals?
 +
* Add 3D Plots (vtkChartXYZ)

Revision as of 14:52, 20 September 2017

Home < Documentation < Nightly < Developers < Plots


For the latest Slicer documentation, visit the read-the-docs.


Slicer Plotting Overview and Acknowledgements

Slicer provides Plotting facilities that include a Plot View that can be packed in the layout, similar to the Slice Views and 3D Views. The architecture also includes nodes that represent the data to be displayed in the plot as well as nodes to represent the display properties of the data and the plot itself. Plot can be serialized with the MRML scene, including the plot data and display properties. In Addition, the PlotView is connected with the Table Module and Views allowing the plotting of arrays with a simple click.

Author:
Davide Punzo (Kapteyn Astronomical Institute, University of Groningen)

Contributors:
Andras Lasso (PerkLab, Queen's)
Jean-Christophe Fillion-Robin (Kitware)
Steve Pieper (Isomics)

Acknowledgements:
This work was supported by the European Research Council under the European Union's Seventh Framework Programme (FP/2007-2013)/ERC Grant Agreement nr. 291-531.

European Research Council Kapteyn Astronomical Institute

Contacts:

  • Davide Punzo, <email>punzodavide@hotmail.it</email>; <email>D.Punzo@astro.rug.nl</email>

Plot capabilities

  • Plot are represented in the MRML scene
  • Multiple Plot Views can be in a layout
  • Each Plot View can display any Plot in the MRML scene
  • Each Plot can display multiple Arrays of data from a Table or more Tables
  • Plot Views can emit signals back to the application as the user interacts with a Plot
  • Multiple plots types (Line, Bar, Scatter)
  • Zooming using the mouse
  • Interactively select data (regions or click and drag).
  • Axis labels
  • Legends

Shortcuts and Interactions

The Plot infrastructure allow the following interaction:

"Left Click" - selections: rectangular, lasso and Click and Drag (Key_S to change the selection mode)
"Middle Click" - pan
"Middle Scroll" - zoom
"Right Click" - zoom in a rectangular selection
"Key_S" - change selection mode
"Key_R" - restore axis and frame zoom
"Key_Shift + Left click" - pan
"Key_Shift + Middle click" - selections: rectangular, lasso and Click and Drag (Key_S to change the selection mode)

Architecture

Plot View

[qMRMLPlotWidget]
The toplevel plotting widget that is packed in layout. Subclass of qMRMLWidget. Contains a qMRMLPlotView and a qMRMLPlotViewControllerWidget.
[qMRMLPlotViewWidget]
Display canvas of the plot. This is currently a subclass of ctkVTKChartView. This allow 2D plotting (for 3D plotting it will require to update and factorize the ctkVTKChartView).
[qMRMLPlotViewControllerWidget]
Widget to control the content and display of a plot.

MRML Nodes

[vtkMRMLPlotViewNode]
Node associated with a PlotViewWidget. This is a 1-to-1 Node class connected with a PlotViewWidget. This class can not be created or copied unless is connected with a PlotWidget.
[vtkMRMLPlotChartNode]
Node keeps track of which plot (PlotDataNode) to display in a PlotView. There can be multiple PlotChart in a scene and a given PlotView can display any of the PlotChart.
[vtkMRMLPlotDataNode]
Represents the vtkPlot (the data) that can be displayed in a PlotView.

Constructing a plot

Below is an example in python to construct and display a plot communicating completely at the level of MRML.

import slicer
import math

# Switch to a layout (39) that contains a Plot View to initiate the construction of the widget and Plot View Node
lns = slicer.mrmlScene.GetNodesByClass('vtkMRMLLayoutNode')
lns.InitTraversal()
ln = lns.GetNextItemAsObject()
ln.SetViewArrangement(39)

# Create a vtkTable
table = vtk.vtkTable()

# Fill the table
arrX = vtk.vtkFloatArray()
arrX.SetName("X Axis")
table.AddColumn(arrX)

arrC = vtk.vtkFloatArray()
arrC.SetName("Cosine")
table.AddColumn(arrC)

arrS = vtk.vtkFloatArray()
arrS.SetName("Sine")
table.AddColumn(arrS)

# Fill in the table with some example values
numPoints = 69
inc = 7.5 / (numPoints - 1)
table.SetNumberOfRows(numPoints)
for i in range(numPoints):
   table.SetValue(i, 0, i * inc )
   table.SetValue(i, 1, math.cos(i * inc))
   table.SetValue(i, 2, math.sin(i * inc))

# Create a MRMLTableNode
TableNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTableNode())
TableNode.SetAndObserveTable(table)

# Create two plotNodes
plotDataNode1 = slicer.mrmlScene.AddNode(slicer.vtkMRMLPlotDataNode())
plotDataNode2 = slicer.mrmlScene.AddNode(slicer.vtkMRMLPlotDataNode())

# Set and Observe the MRMLTableNodeID
plotDataNode1.SetName(arrC.GetName())
plotDataNode1.SetAndObserveTableNodeID(TableNode.GetID());
plotDataNode2.SetName(arrS.GetName())
plotDataNode2.SetAndObserveTableNodeID(TableNode.GetID());
plotDataNode2.SetYColumnIndex(2);

# Create a PlotLayout node
plotChartNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLPlotChartNode())
# Add and Observe plots IDs in PlotLayout
plotChartNode.AddAndObservePlotDataNodeID(plotDataNode1.GetID());
plotChartNode.AddAndObservePlotDataNodeID(plotDataNode2.GetID());

# Create PlotView node
pvns = slicer.mrmlScene.GetNodesByClass('vtkMRMLPlotViewNode')
pvns.InitTraversal()
plotViewNode = pvns.GetNextItemAsObject()
# Set plotLayout ID in PlotView
plotViewNode.SetPlotChartNodeID(plotChartNode.GetID());

# Set a few properties on the Plot.
plotChartNode.SetAttribute('TitleName', 'A simple plot with 2 curves')
plotChartNode.SetAttribute('XAxisLabelName', 'Something in x')
plotChartNode.SetAttribute('YAxisLabelName', 'Something in y')
plotChartNode.SetPlotType('Scatter')

This code produces the chart below.

A simple plot.

Properties

Individual properties (such as the color) of a plot can be changed calling the vtkPlot stored in a vtkMRMLPlotNode

In addition a set of properties regarding the "frame" are available for a PlotLayout. These are stored as Attributes of PlotChartNode. Available properties are:

"Type" - "Line", "Line and Scatter", "Scatter", "Bar"
"TitleName" - title ploted on the PlotLayout
"ShowTitle" - show title "on" or "off"
"XAxisLabelName" - label ploted on the x-axis
"ShowXAxisLabel" - show x-axis label "on" or "off"
"ClickAndDragAlongX" - set the action along x-axis "on" or "off"
"ClickAndDragAlongY" - set the action along y-axis "on" or "off"
"YAxisLabelName" - label ploted on the y-axis
"ShowYAxisLabel" - show y-axis label "on" or "off"
"ShowGrid" - show grid "on" or "off"
"ShowLegend" - show legend "on" or "off"
"FontType" - global Font for the PlotLayout: "Arial", "Times", "Courier"
"TitleFontSize" - default: "20"
"AxisTitleFontSize" - default: "16"
"AxisLabelFontSize" - default: "12"
"LookupTable" colorNodeID default: "NULL"

NOTE: Setting the attribute Type will not update the Type of the PlotDataNode referenced by PlotChartNode. The method SetPlotType() has to be used.

Signals

PlotViews provide signals that allow Slicer to respond to user interactions with the Plot canvas:

void dataSelected(vtkStringArray* mrmlPlotDataIDs, vtkCollection* selectionCol)
Signal emitted when a data point or more has been selected. Returns the MRMLPlotDataNodes IDs and the correspective arrays with the data points ids (vtkIdTypeArray).

Future Work

  • Adding to VTKPlots the possibility to plot errors.
  • Add categorical and date labels to the Bar plotting (analogous to the CHART infrastructure)
  • More signals?
  • Add 3D Plots (vtkChartXYZ)