Embedding time-series plot of mne-qt-browser into our own GUI?

:question: If you have a question or issue with MNE-Python, please include the following info:

  • MNE version: 1.1+
  • operating system: macOS 12 / Windows 10 / Ubuntu 18.04

:page_facing_up: Please also provide relevant code snippets – ideally a minimal working example (MWE).

Hi,

I am interested in embedding an ICA component time-series plot into our own GUI. We would like the robust characteristics of the current mne-qt-browser.

  1. Is it possible to use mne-qt-browser to plot an ICA time series?
  2. Is it possible to extract a Widget from mne-qt-browser that contains the ICA time-series dynamic plot that we can then stick into our own GUI?
  3. If it is possible, any idea how we would do this? :stuck_out_tongue:

Reference code WIP: [ENH] Draft GUI for labeling components by adam2392 · Pull Request #66 · mne-tools/mne-icalabel · GitHub

cc: @mscheltienne @Richard @marsipu @larsoner who might know some.

Have you read

?

1 Like

I have not, but the first issue’s simple 3 liner looks promising!!

Thanks for linking :slight_smile:

Hey Adam,

do you mean ICA.plot_sources with ICA time series? That should be already implemented.

Extracting the Plot-Widget should be also possible too but maybe not straight-forward since it is embedded into the MNEQtBrowser with all its functions.

But this weekend in fact I wanted to work on separating the core data-plot from the other elements to facilitate independent usage.

Best wishes

Martin

1 Like

@adam2392 is this maybe something we should even have in the Qt browser proper?

Hi @marsipu

Yes all I would like to do is add a single ICA time series at a time. Say there are 15 components, then I would like to show only 1 at a time.

Is the following 3 lines you mention here sufficient for that?

I guess there’s no easy way to render a single time-trace dynamically from a set of traces, so I would possibly need to “reconstruct” an ICA object in the background to plot again each time.

Sorry what do you mean here? What’s QTBrowser “proper”?

Is the following 3 lines you mention here sufficient for that?

To add MNEQtBrowser to another Application this should suffice. Though there will still be all other UI-elements (toolbar, scrollbars) visible. Just the plot would be self.mne.view (instance of BrowserView). But I don’t think you can create it without MNEQtBrowser at the moment.

I guess there’s no easy way to render a single time-trace dynamically from a set of traces, so I would possibly need to “reconstruct” an ICA object in the background to plot again each time.

Yes, that would probably the easiest way, while a more hackier solution involving modifying all relevant parameters and adding traces dynamically should be possible too but also more work.
Maybe if we refactor the plot BrowserView out of MNEQtBrowser we could also expose some developer API for adding traces, modifying number of shown channels, etc. … .
Since I am working on a similar project, I might suggest a PR about that in the next days.

Hi @marsipu and @larsoner I was just wondering if it is possible to extract only the time-series trace in the MNEQtBrowser?

In [ENH] Draft GUI for labeling components by adam2392 · Pull Request #66 · mne-tools/mne-icalabel · GitHub, we are able to embed the time-series trace, but it only works on the first time-series plotted. Afterwards, when we select other ICA components, the plots begin plotting in new windows.

See also: [ENH] Draft GUI for labeling components by adam2392 · Pull Request #66 · mne-tools/mne-icalabel · GitHub.

class TimeSeriesFig(FigureCanvasQTAgg):
     """Dummy time-series figure widget."""

     def __init__(self, width=4, height=4, dpi=100):
         self.fig = Figure(figsize=(width, height), dpi=dpi)
         self.axes = self.fig.subplots()
         self.fig.subplots_adjust(bottom=0, left=0, right=1, top=1, wspace=0, hspace=0)
         # clean up excess plot text, invert
         self.axes.set_xticks([])
         self.axes.set_yticks([])
         super().__init__(self.fig)

class ICAComponentLabeler(QMainWindow):
       ...
       # this is the main widget
       self.central_widget = QWidget(self)
       
      # we want to embed the ICA source plot for the current selected ICA component.
      # but it does not work properly...
        self.central_widget.layout().replaceWidget(
             self.widget_timeSeries,
             self._ica.plot_sources(self._inst, picks=[self._current_ic]),
         )

Hi @adam2393,
I think you mainly face two problems at the moment:

Change data dynamcially

In [ENH] Draft GUI for labeling components by adam2392 · Pull Request #66 · mne-tools/mne-icalabel · GitHub, we are able to embed the time-series trace, but it only works on the first time-series plotted. Afterwards, when we select other ICA components, the plots begin plotting in new windows.

Yes, this is unfortunately the expected behavoir right now. Currently there are no methods for MNEQtBrowser to receive raw/ica etc. data on it’s own and change it dynamically for an existing instance of MNEQtBrowser. So currently the only way to plot new data (without hacking into the private methods of the Plot) is by initializing a new instance of MNEQtBrowser. This is partly due to the effort during development to keep initialization of MNEQtBrowser as similar as possible to the matplotlib-pendant MNEBrowseFigure.

I think with some (mainly refactoring)-effort it is possible to add methods like for example:

  • MNEQtBrowser().replace_raw()
  • MNEQtBrowser().replace_ica()

That could maybe even be done to BrowserBase on mne-side, to make this feature also available to the matplotlib-backend.

Detach Plot from MNEQtBrowser-Layout

It is currently probably not straightforward to extract the Plot from all the GUI-elements around it, because it is integrated into MNEQtBrowser as a subclass of QMainWindow. I tried showing just the BrowserView which is the plot taking an instance of MNEQtBrowser, but I found no quick work around. So here we would need to detach the BrowserView that it could be shown as itself without MNEQtBrowser.

I’m quite a novice when it comes to the visualization API in Python. But I do like the sound of this:

Made an issue within the MNEQtBrowser repo: Add the ability to replace raw and replace ICA traces in plot · Issue #133 · mne-tools/mne-qt-browser · GitHub