Difference between revisions of "Documentation/Labs/VTKPLOT"

From Slicer Wiki
Jump to: navigation, search
(Created page with "<noinclude>{{documentation/versioncheck}}</noinclude> <gallery widths=400px heights=225px> Image:SlicerRT-0.2 screenshot.png|Charting in radiation therapy. Image:3D Slicer 4.0...")
 
Line 1: Line 1:
 
<noinclude>{{documentation/versioncheck}}</noinclude>
 
<noinclude>{{documentation/versioncheck}}</noinclude>
<gallery widths=400px heights=225px>
 
Image:SlicerRT-0.2 screenshot.png|Charting in radiation therapy.
 
Image:3D Slicer 4.0.1.2012-02-03 180.png|Charting regional statistics.
 
</gallery>
 
 
{{Clear|right}}{{TOC right}}
 
{{Clear|right}}{{TOC right}}
  
= Slicer Charting Overview =  
+
= Slicer Plotting Overview =  
Slicer provides Charting facilities that include a special Chart 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 chart as well as nodes to represent the display properties of the data and the chart itself. Charts can be serialized with the MRML scene, including the chart data and display properties.
+
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 Plot view is connected to the Table Module and Views and it is possible to plot array from the table with a simple click.
  
 
= Chart capabilities =
 
= Chart capabilities =
* Charts are represented in the MRML scene
+
* Plot are represented in the MRML scene
* Charts can be serialized with the MRML scene
+
* Multiple Plot Views can be in a layout
* Multiple Chart Views can be in a layout
+
* Each Plot View can display any Plot in the MRML scene
* Each Chart View can display any Chart in the MRML scene
+
* Each Plot can display multiple Arrays of data from a Table or more Tables
* Each Chart can display multiple Arrays of data
+
* Plot Views can [[#Signals|emit signals]] back to the application as the user interacts with a Chart
* Chart Views can [[#Signals|emit signals]] back to the application as the user interacts with a Chart
+
* Multiple plots types (Line, Bar, Scatter)
* Multiple chart types (Line, Bar, Scatter)
 
* Data can be quantitative or categorical
 
 
* Zooming using the mouse
 
* Zooming using the mouse
* Highlighting data points under the mouse
+
* Interactively select data (regions or click and drag).
 
* Axis labels
 
* Axis labels
 
* Legends
 
* Legends
* Color tables can be used to define the cycle of colors assigned to arrays in a chart
 
* Colors can be assigned individually to each Array in a Chart
 
* [[#Bar charts with categorical data | Bar charts with categorical data]] can use a color table to define colors and labels for each data point in the chart.
 
  
 
=Architecture=
 
=Architecture=
== Chart View ==  
+
== Plot View ==  
  
; [{{doxygen-class-url|qMRMLChartWidget}} qMRMLChartWidget]
+
; [{{doxygen-class-url|qMRMLPlotWidget}} qMRMLPlotWidget]
: The toplevel charting widget that is packed in layout. Subclass of qMRMLWidget. Contains a qMRMLChartView and a qMRMLChartViewControllerWidget. There can be several Chart Widgets in a single layout.
+
: The toplevel plotting widget that is packed in layout. Subclass of qMRMLWidget. Contains a qMRMLPlotView and a qMRMLPlotViewControllerWidget.
; [{{doxygen-class-url|qMRMLChartView}} qMRMLChartView]
+
; [{{doxygen-class-url|qMRMLPlotView}} qMRMLPlotView]
: Display canvas of the chart. This is currently a subclass of QWebView as the charting facilities is based on a [http://jquery.com jQuery] library called [http://www.jqplot.com jqPlot].
+
: 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|qMRMLChartViewControllerWidget}} qMRMLChartViewControllerWidget]
+
; [{{doxygen-class-url|qMRMLPlotViewControllerWidget}} qMRMLPlotViewControllerWidget]
: Widget to control the content and display of a chart.
+
: Widget to control the content and display of a plot.
  
 
== MRML Nodes ==
 
== MRML Nodes ==
; [{{doxygen-class-url|vtkMRMLChartViewNode}} vtkMRMLChartViewNode]
+
; [{{doxygen-class-url|vtkMRMLPlotViewNode}} vtkMRMLPlotViewNode]
: Node associated with a Chart View. Keeps track of which chart to display in a Chart View. There can be multiple charts in a scene and a given Chart View can display any of the charts.
+
: Node associated with a Plot View. Keeps track of which plot to display in a Plot View. There can be multiple plots in a scene and a given Plot View can display any of the plots.
; [{{doxygen-class-url|vtkMRMLChartNode}} vtkMRMLChartNode]
+
; [{{doxygen-class-url|vtkMRMLPlotLayoutNode}} vtkMRMLPlotLayoutNode]
: Represents the content and properties of a chart.  Manages a list of Array Nodes to display in the chart. Provides methods to set the properties of a chart or the properties of each Array Node.  
+
: Represents the content and properties of a plot.  Manages a list of Plot Nodes to display in the plot. Provides methods to set the properties of a plot and of the frame.  
; [{{doxygen-class-url|vtkMRMLDoubleArrayNode}} vtkMRMLDoubleArrayNode]
+
; [{{doxygen-class-url|vtkMRMLPlotNode}} vtkMRMLPlotNode]
: Represents the data that can be displayed in a chart.  Array nodes contain a series of 3-tuples representing the (X, Y, Error) measurement values.
+
: Represents the vtkPlot (the data) that can be displayed in a plot.
  
 
= Constructing a chart =  
 
= Constructing a chart =  
Below is an example in python to construct and display a chart communicating completely at the level of MRML.
+
Below is an example in python to construct and display a plot communicating completely at the level of MRML.
 
<pre lang="python">
 
<pre lang="python">
 
import slicer
 
import slicer
Line 54: Line 45:
 
lns.InitTraversal()
 
lns.InitTraversal()
 
ln = lns.GetNextItemAsObject()
 
ln = lns.GetNextItemAsObject()
ln.SetViewArrangement(24)
+
ln.SetViewArrangement(39)
  
 
# Get the Chart View Node
 
# Get the Chart View Node
cvns = slicer.mrmlScene.GetNodesByClass('vtkMRMLChartViewNode')
+
pvns = slicer.mrmlScene.GetNodesByClass('vtkMRMLPlotViewNode')
cvns.InitTraversal()
+
pvns.InitTraversal()
cvn = cvns.GetNextItemAsObject()
+
pvn = pvns.GetNextItemAsObject()
  
 
# Create an Array Node and add some data
 
# Create an Array Node and add some data
dn = slicer.mrmlScene.AddNode(slicer.vtkMRMLDoubleArrayNode())
+
pn = slicer.mrmlScene.AddNode(slicer.vtkMRMLPlotNode())
 
a = dn.GetArray()
 
a = dn.GetArray()
 
a.SetNumberOfTuples(600)
 
a.SetNumberOfTuples(600)
Line 103: Line 94:
  
 
= Properties =
 
= Properties =
Properties can be assigned to a Chart or to a specific Array in the Chart.  The API for setting a property on a Chart Node is
 
  void SetProperty(const char *arrname, const char *property, const char *value);
 
The first argument is a string for the name of the Array to apply the property.  This name was established when the array was added to the Chart using the <tt>AddArray(name, array)</tt> method. The array name <tt>'default'</tt> is used to specify (1) properties that apply to the Chart and not to an Array, and (2) to establish a default setting for a property for all Arrays. Default properties assigned to Arrays can be overridden by properties assigned to a specific array.
 
  
==Chart level properties==
+
Individual properties (such as the color) of a plot
;type: Line, Bar, Scatter
+
can be changed calling the vtkPlot stored in a vtkMRMLPlotNode
;title: title displayed on the chart
+
;showTitle: show title "on" or "off"
+
In addition a set of properties regarding the "frame" are available for a PlotLayout.
;xAxisLabel: label displayed on the x-axis
+
These are stored as Attributes of PlotLayoutNode.
;showXAxisLabel: show x-axis label "on" or "off"
+
Available properties are:
;xAxisType: type of data on x-axis, "quantitative", "categorical", "date"
+
 
;yAxisLabel: label displayed on the y-axis
+
"Type" - "Line", "Line and Scatter", "Scatter", "Bar"
;showYAxisLabel: show y-axis label "on" or "off"
+
"TitleName" - title ploted on the PlotLayout
;yAxisType: type of data on y-axis, "quantitative", "categorical", "date"
+
"ShowTitle" - show title "on" or "off"
;showGrid: show grid "on" or "off"
+
"XAxisLabelName" - label ploted on the x-axis
;showLegend: show legend "on" or "off"
+
"ShowXAxisLabel" - show x-axis label "on" or "off"
;lookupTable: MRMLID of a ColorNode to use to color series
+
"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"
  
==Array level properties==
 
Array level properties (can be assigned to "default" to apply to entire chart.
 
;showLines: show lines "on" or "off"
 
;showMarkers: show markers "on" or "off"
 
;color: color to use for the array lines and points (#RRGGBB)
 
;lookupTable: MRMLID of a ColorNode to use to color individual bars in bar chart (useful with categorical data)
 
;size: size of the markers for the scatter plot represented by an integer
 
;linePattern: can be "solid", "dashed", "dotted", "dashed-dotted"
 
;lineWidth: line width represented by an integer
 
  
 
= Signals =
 
= Signals =
Chart Views provide signals that allow Slicer to respond to user interactions with the Chart canvas.
+
Plot Views provide signals that allow Slicer to respond to user interactions with the Chart canvas.
  
;void dataMouseOver(const char *mrmlArrayID, int pointidx, double x, double y)
+
;void dataSelected(vtkStringArray* mrmlPlotIDs, vtkCollection* selectionCol)
:Signal emitted when the mouse moves over a data point. Returns the id of the MRMLDoubleArrayNode, the index of the point, and the values.
+
:Signal emitted when a data point or more has been selected. Returns the MRMLPlotNodes IDs and the correspective arrays with the data points ids (vtkIdTypeArray).
; void dataPointClicked(const char *mrmlArrayID, int pointidx, double x, double y)
 
:Signal emitted when a data point has been clicked. Returns the id of the MRMLDoubleArrayNode, the index of the point, and the values.
 
 
 
= Bar charts with categorical data =
 
When the x-axis data in an Array is categorical, for example when the Array represents the average intensity of an image region under specific labels in a label map, a bar chart of the Array can extract information automatically from a color table assigned as a property of the Array in the Chart. Here, the Charting will interpret the x-axis values in the Array as "labels" and cross-reference the "labels" in the color table to extract the label as well as the color assigned to each bar in the chart.
 
 
 
<pre>
 
chartNode.SetProperty('default', 'type', 'Bar')
 
chartNode.SetProperty('default', 'xAxisType', 'categorical')
 
chartNode.SetProperty('My Array', 'lookupTable', colorNodeID)
 
</pre>
 
 
 
[[Image:BarChartWithCategoricalData.png|400px|Bar chart with categorical data]]
 
 
 
Currently, this capability is not provided for line charts.
 
 
 
= Under the hood =
 
The architecture of the Charting is divided into two layers.  The first layer is the public layer available to Slicer developers consisting of the MRML nodes and associated Widgets.  This layer can be used by module writers to construct charts and orchestrate their display. The second layer is the rendering architecture for the Chart.  The rendering of Chart utilizes a  [http://jquery.com jQuery] library called [http://www.jqplot.com jqPlot] to generate a plot.  The Chart View is actually a QWebView Widget that displays a web page that is generated on the fly by Slicer to display a Chart.
 
 
 
The method qMRMLChartViewPrivate::updateWidgetFromMRML() generates the HTML and javascript to display a Chart, passes the generated code to the QWebView, calls the QWebView::show() method, and then exposes a Qt object to the javascript layer to support signals and slots. The HTML and javascript generation includes
 
* HTML page header, css, javascript
 
* Div element to hold the chart
 
* Script element for the chart
 
* Conversion of the Array nodes to javascript arrays suitable for jqPlot
 
* Construction of the jqPlot options from the Chart properties
 
* Call to jqPlot to generate the plot
 
* Slots and hooks for resizing the Chart and handling the mouse over and data point click signals
 
* HTML page postscript, additional javascript references
 
 
 
==Resources==
 
jqPlot is package into the Slicer executable as Qt Resources.  The generated HTML pages reference the javascript and css files from the Qt Resource, not from a web server. Only the jqPlot and jQuery javascript and css files needed to implement the current features are embedded as Qt Resources.  If additional jqPlot or jQuery features are needed in the future (for instance, different jqPlot renderers), the associated javascript and css files will need to be added to the Qt Resources. See [http://viewvc.slicer.org/viewvc.cgi/Slicer4/trunk/Libs/MRML/Widgets/Resources/jqPlot.qrc.in?view=markup jqPlot.qrc.in].
 
 
 
==Build process==
 
jqPlot is downloaded and installed locally in the Slicer build tree as part of the SuperBuild process.
 
 
 
= To do =
 
* Refactor the generation of the javascript representation of the chart to allow data to be modified without recreating the page.
 
* Line styles
 
* Add more signals
 
* Write a bar chart renderer, improving the layout.
 
* Add error bars
 
* Add tags to Array nodes specify a "label" which will allow line plots to be automatically colored based on a color table. Similar to how bar charts can automatically color the bars in a plot when the x-axis data is categorical.
 
* Presentation quality printing
 

Revision as of 15:27, 25 August 2017

Home < Documentation < Labs < VTKPLOT


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


Slicer Plotting Overview

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 Plot view is connected to the Table Module and Views and it is possible to plot array from the table with a simple click.

Chart 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 Chart
  • Multiple plots types (Line, Bar, Scatter)
  • Zooming using the mouse
  • Interactively select data (regions or click and drag).
  • Axis labels
  • Legends

Architecture

Plot View

[[[
Template:Documentation/Labs/doxygen-class-url]] qMRMLPlotWidget]
The toplevel plotting widget that is packed in layout. Subclass of qMRMLWidget. Contains a qMRMLPlotView and a qMRMLPlotViewControllerWidget.
[[[
Template:Documentation/Labs/doxygen-class-url]] qMRMLPlotView]
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).
[[[
Template:Documentation/Labs/doxygen-class-url]] qMRMLPlotViewControllerWidget]
Widget to control the content and display of a plot.

MRML Nodes

[[[
Template:Documentation/Labs/doxygen-class-url]] vtkMRMLPlotViewNode]
Node associated with a Plot View. Keeps track of which plot to display in a Plot View. There can be multiple plots in a scene and a given Plot View can display any of the plots.
[[[
Template:Documentation/Labs/doxygen-class-url]] vtkMRMLPlotLayoutNode]
Represents the content and properties of a plot. Manages a list of Plot Nodes to display in the plot. Provides methods to set the properties of a plot and of the frame.
[[[
Template:Documentation/Labs/doxygen-class-url]] vtkMRMLPlotNode]
Represents the vtkPlot (the data) that can be displayed in a plot.

Constructing a chart

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 (24) that contains a Chart View to initiate the construction of the widget and Chart View Node
lns = slicer.mrmlScene.GetNodesByClass('vtkMRMLLayoutNode')
lns.InitTraversal()
ln = lns.GetNextItemAsObject()
ln.SetViewArrangement(39)

# Get the Chart View Node
pvns = slicer.mrmlScene.GetNodesByClass('vtkMRMLPlotViewNode')
pvns.InitTraversal()
pvn = pvns.GetNextItemAsObject()

# Create an Array Node and add some data
pn = slicer.mrmlScene.AddNode(slicer.vtkMRMLPlotNode())
a = dn.GetArray()
a.SetNumberOfTuples(600)
x = range(0, 600)
for i in range(len(x)):
    a.SetComponent(i, 0, x[i]/50.0)
    a.SetComponent(i, 1, math.sin(x[i]/50.0))
    a.SetComponent(i, 2, 0)

# Create a second Array node
dn2 = slicer.mrmlScene.AddNode(slicer.vtkMRMLDoubleArrayNode())
a = dn2.GetArray()
a.SetNumberOfTuples(600)
x = range(0, 600)
for i in range(len(x)):
    a.SetComponent(i, 0, x[i]/50.0)
    a.SetComponent(i, 1, math.cos(x[i]/50.0))
    a.SetComponent(i, 2, 0)

# Create a Chart Node.
cn = slicer.mrmlScene.AddNode(slicer.vtkMRMLChartNode())

# Add the Array Nodes to the Chart. The first argument is a string used for the legend and to refer to the Array when setting properties.
cn.AddArray('A double array', dn.GetID())
cn.AddArray('Another double array', dn2.GetID())

# Set a few properties on the Chart. The first argument is a string identifying which Array to assign the property. 
# 'default' is used to assign a property to the Chart itself (as opposed to an Array Node).
cn.SetProperty('default', 'title', 'A simple chart with 2 curves')
cn.SetProperty('default', 'xAxisLabel', 'Something in x')
cn.SetProperty('default', 'yAxisLabel', 'Something in y')

# Tell the Chart View which Chart to display
cvn.SetChartNodeID(cn.GetID())

This code produces the chart below.

A simple chart.

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 PlotLayoutNode. 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"


Signals

Plot Views provide signals that allow Slicer to respond to user interactions with the Chart canvas.

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