Plot Nodes in Slicer

Hi everyone,

I am working on a module to generate a 2D Visualization of the Brain Connectome Network.

I am trying to understand all the 2D plot options in Slicer with Python. So my question is the following:
What are all the node classes that can be added in slicer.mrmlScene.AddNewNodeByClass( ? ) ?

Also, if I would like to plot a vtkSpiderPlot() in an existing window of Slicer, would that be possible? Until now I’ve only managed to plot it in a pop up window that uses the OpenGL Visualization ToolKit.

Thank you all in advance!

Currently line, scatter, and bar plots are available via the GUI. To show spider plots, you would need to do some Python scripting. I would recommend to show this plot first in a plain VTK render window. Once you have that working, then I can help with making that window show up in the view layout.

Thank you for your reply Andras.

I am pretty new to VTK and Slicer.

I have generated the spider plot in a plain VTK render window, which is the pop up window I was talking about before. To do so I used vtkRenderer(), vtkRenderWindow(), vtkRenderWindowInteractor().

So as I would like to make that window show up in Slicer you suggest me to use the view layout.
Should I look at the slicer.app.layoutManager() ? If so, could you help me understand how that should be implemented and what vtkMRML Node to use?

@Sunderlandkyl could you advise how the view class that you recently added to Slicer could be used for this? Thank you.

You can add your vtkRenderWindow to a QVTKWidget, and then add that widget to a layout using qSlicerSingletonViewFactory.

Ex.

  • Add view factory to layout manager:

      singletonViewFactory = slicer.qSlicerSingletonViewFactory()
      singletonViewFactory.setTag("yourtagname")
      singletonViewFactory.setWidget(yourWidget)
      slicer.app.layoutManager().registerViewFactory(singletonViewFactory)
    
  • Add custom layout to layout manager:

      yourLayoutID = 1234
      layoutManager = slicer.app.layoutManager()
      layout = (
        "<layout type=\"horizontal\">"
        " <item>"
        "  <yourtagname></yourtagname>"
        " </item>"
        "</layout>"
      )
      layoutNode = slicer.app.layoutManager().layoutLogic().GetLayoutNode()
      layoutNode.AddLayoutDescription(
        yourLayoutID, layout)
    
  • Switch to layout with custom widget:

    slicer.app.layoutManager().setLayout(yourLayoutID)
1 Like

Hi @Sunderlandkyl,

Thank you for your response.

I think I am close. I just can’t access QVTKWidget or QVTKRenderWindowInteractor.
I am using 3D Slicer version 4.10.1-2019-01-16. with qt5.
Do you know how I can access those ?
I tried calling defining it like this :

qWidget = vtk.QVTKWidget()

But I get:

AttributeError: ‘module’ object has no attribute ‘QVTKWidget’

@lassoan Do you know of an alternative to QVTKWidget that is wrapped in python?

Alternatively, is there a better way to embed a vtkRenderWindow() in a QWidget?

ctkVTKOpenGLNativeWidget can be used for this.

1 Like

hi, lassoan, When I use ctkVTKOpenGLNativeWidget in python, I encounter a problem. Show “AttributeError: ctkVTKOpenGLNativeWidget has no
attribute named ‘setRenderWindow’”. Here is a screenshot below.
(U4$A74Z}7LN~NF45~E1M
But i noticed that it has been used like this in the ctk source code.


And, when I was reviewing the source code in ctk,
i found that ctkVTKOpenGLNativeWidget may inherit from three classes, and all of the parent classes has a public function setRenderWindow or SetRenderWindow .
So, I wonder to know if it is not obtainable in python .I am not familiar with python’s wrapper. Thanks a lot.

@lassoan In addition, i used slicer version is 5.2.2. I can get ctkVTKOpenGLNativeWidget’s setRenderWindow function in a c++ loadable module.

The generic Python-wrapped Qt widget for VTK rendering is ctk.ctkVTKRenderView(). A complete example:

widget = ctk.ctkVTKRenderView()
renderer = widget.renderWindow().GetRenderers().GetFirstRenderer()

cylinder = vtk.vtkCylinderSource()
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(cylinder.GetOutputPort())
actor = vtk.vtkActor()
actor.SetMapper(mapper)
renderer.AddActor(actor)

renderer.ResetCamera()
widget.show()
1 Like

Thank you, I’ll try it.