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

From Slicer Wiki
Jump to: navigation, search
(moved to readthedocs)
Tags: 2017 source edit, Replaced
 
(11 intermediate revisions by 3 users not shown)
Line 1: Line 1:
<noinclude>{{documentation/versioncheck}}</noinclude>
+
<noinclude>{{documentation/versioncheck}}
{{Clear}}{{TOC right}}
+
</noinclude>
  
= Slicer plotting overview and acknowledgements =
+
{{documentation/banner
 
+
| text  = [https://slicer.readthedocs.io/en/latest/user_guide/modules/plots.html This page has been moved to read-the-docs.]
Slicer provides Plotting facilities that include a plot view that can be displayed in the view layout, similarly to slice 3D views. Plot data is stored in table nodes, and plot series, chart, and view nodes define which table column need to be displayed and how. Plot can be serialized with the MRML scene, including the plot data and display properties. Plot series and charts can be created and edited in Plots module and plots can be also generated directly from Tables module by a single click.
+
| background-color = 8FBC8F }}
 
 
Authors:<br>
 
<b>Davide Punzo</b> (Kapteyn Astronomical Institute, University of Groningen) <br>
 
<b>Andras Lasso</b> (PerkLab, Queen's University) <br>
 
 
 
Contributors: <br>
 
<b>Jean-Christophe Fillion-Robin</b> (Kitware) <br>
 
<b>Steve Pieper</b> (Isomics) <br> <br>
 
 
 
Acknowledgements: <br>
 
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.<br> <br>
 
<!-- ---------------------------- -->
 
[[File:ERCIcon.png|300px|European Research Council]]
 
[[File:Kapteyn logo1.png|500px|Kapteyn Astronomical Institute]]
 
<!-- ---------------------------- -->
 
 
 
Contacts:
 
* Davide Punzo, <email>punzodavide@hotmail.it</email>; <email>D.Punzo@astro.rug.nl</email>
 
 
 
= Plot capabilities =
 
* Multiple plots types (Line, Bar, Scatter, Scatter bar), shown in standard view layouts.
 
* Configurable chart and axis title, legend, grid lines.
 
* Use indexes (0, 1, 2, ...) or a table column for X axis values.
 
* Multiple plot series can be added to a single plot chart (even showing data from different tables, with different types - plot, bar), and the same series can be added to multiple charts. The same plot chart can be shown in any plot views (even simultaneously).
 
* Label can be assigned to each data point (shown in tooltip when hovering over a data point).
 
* Interactive editing of data points by drag-and-drop (data in referenced table nodes is updated).
 
* Interactive selection of data points (rectangular or free-hand selection).
 
* Plot data and display properties are stored in the MRML scene.
 
* Plot view can be embedded into module user interfaces. Plot views can [[#Signals|emit signals]] back to the application as the user interacts with a plot, which allows modules to perform additional processing on the selected data points.
 
 
 
What is the difference between Slicer Plot and Chart?
 
[[Documentation/{{documentation/version}}/Developers/FAQ#What_is_the_difference_between_Slicer_Plot_and_Chart_.3F | See FAQ.]]
 
 
 
= Shortcuts and Interactions =
 
The Plot infrastructure allow the following interaction:
 
 
 
* Left mouse button: depends on interaction mode of the view
 
** Pan view: pan view
 
** Select points: select points using rectangular selection
 
** Freehand select points: select points using free-form selection
 
** Move points: move data points by drag-and-drop; this changes values in the referenced table node
 
- Middle mouse button: pan view (except in pan view mode; in that case it zooms to selected rectangular region)
 
- Right mouse button: zoom in/out along X and Y axes
 
* S: switch interaction mode (pan/select points/.../move points)
 
* R: reset view to show all data series
 
 
 
=Architecture=
 
 
 
== Plot View ==
 
 
 
; [{{doxygen-class-url|qMRMLPlotWidget}} qMRMLPlotWidget]
 
: The toplevel plotting widget that is packed in layout. Subclass of qMRMLWidget. Contains a qMRMLPlotView and a qMRMLPlotViewControllerWidget.
 
; [{{doxygen-class-url|qMRMLPlotViewWidget}} 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).
 
; [{{doxygen-class-url|qMRMLPlotViewControllerWidget}} qMRMLPlotViewControllerWidget]
 
: Widget to control the content and display of a plot.
 
 
 
== MRML Nodes ==
 
 
 
; [{{doxygen-class-url|vtkMRMLPlotViewNode}} 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.
 
; [{{doxygen-class-url|vtkMRMLPlotChartNode}} 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.
 
; [{{doxygen-class-url|vtkMRMLPlotDataNode}} 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.
 
<pre lang="python">
 
import slicer
 
import math
 
 
 
# Switch to a layout (OneUpPlotView) 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(ln.SlicerLayoutOneUpPlotView)
 
 
 
# 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 PlotDataNodes
 
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());
 
plotDataNode1.SetXColumnName(TableNode.GetColumnName(0));
 
plotDataNode1.SetYColumnName(TableNode.GetColumnName(1));
 
 
 
plotDataNode2.SetName(arrS.GetName())
 
plotDataNode2.SetAndObserveTableNodeID(TableNode.GetID());
 
plotDataNode2.SetXColumnName(TableNode.GetColumnName(0));
 
plotDataNode2.SetYColumnName(TableNode.GetColumnName(2));
 
 
 
# Create a PlotChart node
 
plotChartNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLPlotChartNode())
 
# Add and Observe plots IDs in PlotChart
 
plotChartNode.AddAndObservePlotDataNodeID(plotDataNode1.GetID());
 
plotChartNode.AddAndObservePlotDataNodeID(plotDataNode2.GetID());
 
 
 
# Create PlotView node
 
pvns = slicer.mrmlScene.GetNodesByClass('vtkMRMLPlotViewNode')
 
pvns.InitTraversal()
 
plotViewNode = pvns.GetNextItemAsObject()
 
# Set plotChart ID in PlotView
 
plotViewNode.SetPlotChartNodeID(plotChartNode.GetID());
 
 
 
# Set a few properties of the Plot.
 
plotChartNode.SetAttribute('TitleName', 'A simple plot with 2 curves')
 
plotChartNode.SetAttribute('XAxisLabelName', 'Something in x')
 
plotChartNode.SetAttribute('YAxisLabelName', 'Something in y')
 
plotChartNode.SetAttribute('Type', 'Scatter')
 
 
 
# End
 
</pre>
 
 
 
This code produces the plot below.
 
 
 
[[Image:VtkPlot.png|A simple plot.|1200px]]
 
 
 
= Properties =
 
 
 
A set of properties are available for a PlotChart.
 
These are stored as Attributes of PlotChartNode.
 
The properties are:
 
 
 
  "TitleName" - title ploted on the PlotChart
 
  "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 PlotChart: "Arial", "Times", "Courier"
 
  "TitleFontSize" - default: "20"
 
  "AxisTitleFontSize" - default: "16"
 
  "AxisLabelFontSize" - default: "12"
 
  "LookupTable" colorNodeID default: NULL
 
 
 
Further attributes of PlotChartNode are connected with
 
the PlotDataProperties. If their value is "Custom"
 
then each PlotDataNode has its individual value. If another
 
value is chosen, all the PlotDataNodes referenced by the
 
PlotChartNode will be updated with the new value.
 
 
 
  "Type" - Set Type for all the plots. Default: "Custom". Other values: "Line", "Scatter", "Bar"
 
  "XAxis" - Set XAxis for all the plots. Default: "Custom". Other values: "..." (list of Columns)
 
  "Markers" - Show markers for all the plots. Default: "Custom". Other values: "Cross", "Plus", "Square", "Circle", "Diamond"
 
 
 
= 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 errorbars.
 
* Add categorical and date labels to the Bar plotting (analogous to the CHART infrastructure)
 
* More signals?
 
* Add 3D Plots (vtkChartXYZ)
 
* Add Click and Drag action for multiple selected points
 

Latest revision as of 22:12, 17 April 2022

Home < Documentation < Nightly < Developers < Plots