Show ECG curve plot

Hi Robin,
it has been a while but was this ever solved? I am wondering the same thing.

I have a 4D cardiac dataset and I also have ECG voltage tracings for a cardiac cycle. I would like to enable playback through my 4D cardiac dataset while showing where on the ECG voltage tracing we are. I figured this might be achieved through qMRMLPlotWidgets in my UI, but can’t figure out how to plot to them…

You can read the ECG signals to a table node. See for example how it is done in the UltrasoundImage3D reader:

You can find some more plotting examples in the script repository and more explanations in the documentation (user guide, developer guide).

If you want to display a view outside the view layout (I would not recommend that, because it is probably better to choose or create an appropriate view layout instead) then you can follow this example:

There is also a simpler example in the script repository.

To display a marker on the signal, I would recommend to add a series that has a single point or vertical line segment and add that to the chart.

Thank you Dr. Lasso for the help! I guess my question is specific to the qMRMLPlotWidget, or something equivalent so that I can plot the ECG waveform within my extension UI. For example, using the QT designer I have added 3 qMRMLPlotWidgets to my UI, with the intent of plotting a 3-lead ECG overlaid with my playback tools:

What I’m looking for is something similar to this line of code, except to plot a vtkMRMLPlotChartNode into my UI rather than the standard Slicer Plotting Layout.
slicer.modules.plots.logic().ShowChartInLayout(plotChartNode)

I’ve tried to pull the equivalent of what I’m running within my extension:


viewNode = self.logic.createECGPlotNode()
self.ui.qMRMLPlotWidget1.setMRMLPlotViewNode(viewNode) #This is what doesn't seem to be working

def createECGPlotNode():

    #Create Dummy Data
    lead1 = np.random.randint(1,100,2000)
    lead1ecg = np.array(lead1)
    t_step = 0.01 #10ms steps
    t = np.linspace(0,len(lead1)*t_step,len(lead1))

    data_to_plot = np.column_stack((t,lead1ecg))

    tableNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLTableNode", "ECGTable")
    slicer.util.updateTableFromArray(tableNode, data_to_plot)
    tableNode.GetTable().GetColumn(0).SetName("Time")
    tableNode.GetTable().GetColumn(1).SetName("Voltage")
    
    plotSeriesNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLPlotSeriesNode", "PlotSeriesNode")
    plotSeriesNode.SetAndObserveTableNodeID(tableNode.GetID())
    plotSeriesNode.SetXColumnName("Time")
    plotSeriesNode.SetYColumnName("Voltage")
    plotSeriesNode.SetPlotType(plotSeriesNode.PlotTypeScatter)
    
    plotChartNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLPlotChartNode")
    plotChartNode.AddAndObservePlotSeriesNodeID(plotSeriesNode.GetID())

    viewNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLPlotViewNode","ViewNode")
    viewNode.SetPlotChartNodeID(plotChartNode.GetID())

    #If I put slicer.modules.plots.logic().ShowChartInLayout(plotChartNode) here, then it plots properly to usual display

    return viewNode

You need to make sure the layout manager does own your view nodes. See example in the script repository.