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:

image

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.

Dear Sir,
once the 4D data was loaded into slicer, how to reference the data using python script?

especially the source ? We don’t need to reload the data as the example .

What file format did you load your data from?

The example above was for Image3dAPI reader, which has that source object. You don’t need to use that object because the reader creates a table node from the ECG data that you can easily visualize using Plots module.

If you are interested in showing ECG then you may join @connorh at the upcoming project week to work on cardiac data reading and visualization.

The DICOM file exported by QLab, and patched in Slicer.
thanks, I will try to focus on the project week.

Unfortunately, the Cartesian images exported by QLab do not contain any ECG data.