From db4badb99ccbef8b55373f7691974532db4604d3 Mon Sep 17 00:00:00 2001 From: "Thomas S. Binns" Date: Mon, 27 Jan 2025 21:25:53 +0000 Subject: [PATCH 1/8] Improve decomposition axes plotting param --- mne_connectivity/decoding/decomposition.py | 4 +++- mne_connectivity/utils/docs.py | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/mne_connectivity/decoding/decomposition.py b/mne_connectivity/decoding/decomposition.py index cff12cdc..0cd503bf 100644 --- a/mne_connectivity/decoding/decomposition.py +++ b/mne_connectivity/decoding/decomposition.py @@ -714,6 +714,8 @@ def _plot_filters_patterns( _validate_type(info, Info, "`info`", "mne.Info") if components is None: components = np.arange(self.n_components) + if axes is not None: + _check_option("axes", len(axes), [2], " length") # plot seeds and targets figs = [] @@ -749,7 +751,7 @@ def _plot_filters_patterns( colorbar=colorbar, cbar_fmt=cbar_fmt, units=units, - axes=axes, + axes=axes[group_idx] if axes is not None else None, time_format=f"{self._conn_estimator.name}%01d" if name_format is None else name_format, diff --git a/mne_connectivity/utils/docs.py b/mne_connectivity/utils/docs.py index eb1b8332..8b318704 100644 --- a/mne_connectivity/utils/docs.py +++ b/mne_connectivity/utils/docs.py @@ -434,9 +434,11 @@ """ docdict["axes_topomap"] = """ -axes : matplotlib.axes.Axes | list of matplotlib.axes.Axes | None (default None) +axes : list of list of matplotlib.axes.Axes | None (default None) The axes to plot to. If `None`, a new figure will be created with the correct number - of axes. If not `None`, the number of axes must match ``components``. + of axes. If not `None`, there must be two lists containing the axes for the seeds + and targets, respectively. In each of these two lists, the number of axes must match + ``components`` if ``colorbar=False``, or ``components * 2`` if ``colorbar=True``. """ docdict["name_format_topomap"] = r""" From 4ea1e961073d7512464540c957f8907a7739275f Mon Sep 17 00:00:00 2001 From: "Thomas S. Binns" Date: Mon, 27 Jan 2025 21:26:53 +0000 Subject: [PATCH 2/8] Misc improvements --- mne_connectivity/decoding/decomposition.py | 2 +- mne_connectivity/utils/docs.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mne_connectivity/decoding/decomposition.py b/mne_connectivity/decoding/decomposition.py index 0cd503bf..bbc37270 100644 --- a/mne_connectivity/decoding/decomposition.py +++ b/mne_connectivity/decoding/decomposition.py @@ -604,7 +604,7 @@ def plot_filters( """Plot topographic filters of components. The filters are used to extract discriminant neural sources from the measured - data (a.k.a. the backward model). :footcite:`HaufeEtAl2014`. + data (a.k.a. the backward model) :footcite:`HaufeEtAl2014`. Seed and target filters are plotted separately. diff --git a/mne_connectivity/utils/docs.py b/mne_connectivity/utils/docs.py index 8b318704..14e2eee5 100644 --- a/mne_connectivity/utils/docs.py +++ b/mne_connectivity/utils/docs.py @@ -443,7 +443,7 @@ docdict["name_format_topomap"] = r""" name_format : str | None (default None) - The string format for axes titles. If `None`, uses ``f"{method}%%01d"``, i.e. the + The string format for axes titles. If `None`, uses ``f"{method}%01d"``, i.e. the method name followed by the component number. """ From 928d08db0427d18d0a8a06f840714959c7d0ef34 Mon Sep 17 00:00:00 2001 From: "Thomas S. Binns" Date: Mon, 27 Jan 2025 21:27:14 +0000 Subject: [PATCH 3/8] Add tests --- mne_connectivity/decoding/tests/test_decomposition.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mne_connectivity/decoding/tests/test_decomposition.py b/mne_connectivity/decoding/tests/test_decomposition.py index dfd61d89..d4fc0769 100644 --- a/mne_connectivity/decoding/tests/test_decomposition.py +++ b/mne_connectivity/decoding/tests/test_decomposition.py @@ -715,3 +715,7 @@ def test_spectral_decomposition_error_catch(method, mode): for plot in (decomp_class.plot_filters, decomp_class.plot_patterns): with pytest.raises(TypeError, match="`info` must be an instance of mne.Info"): plot({"info": epochs.info}) + with pytest.raises(ValueError, match="Invalid value for the 'axes' parameter"): + plot(epochs.info, axes=[None]) + with pytest.raises(ValueError, match="Invalid value for the 'axes' parameter"): + plot(epochs.info, axes=[None, None, None]) From bcc809bc1cc69c336e595aa316dde8d0c613cb12 Mon Sep 17 00:00:00 2001 From: "Thomas S. Binns" Date: Mon, 27 Jan 2025 21:27:22 +0000 Subject: [PATCH 4/8] Add changelog entry --- doc/whats_new.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/whats_new.rst b/doc/whats_new.rst index 223707a6..ff659291 100644 --- a/doc/whats_new.rst +++ b/doc/whats_new.rst @@ -23,9 +23,10 @@ Enhancements ~~~~~~~~~~~~ - Add a new :class:`~mne_connectivity.decoding.CoherencyDecomposition` class for decomposing connectivity sources using multivariate coherency-based methods, by `Thomas Binns`_ (:pr:`193`). -- Add new plotting methods :meth:`CoherencyDecomposition.plot_filters() ` and :meth:`CoherencyDecomposition.plot_patterns() ` for visualising the decomposed connectivity sources, by `Thomas Binns`_ (:pr:`208`). +- Add new plotting methods :meth:`CoherencyDecomposition.plot_filters() ` and :meth:`CoherencyDecomposition.plot_patterns() ` for visualising the decomposed connectivity sources, by `Thomas Binns`_ (:pr:`208`) and (:pr:`279`). - Add support for computing multiple components of multivariate connectivity in the :func:`~mne_connectivity.spectral_connectivity_epochs` and :func:`~mne_connectivity.spectral_connectivity_time` functions and :class:`~mne_connectivity.decoding.CoherencyDecomposition` class, and add support for storing data with a components dimension in all :class:`~mne_connectivity.Connectivity` classes, by `Thomas Binns`_ and `Eric Larson`_ (:pr:`213`). - Add support for :class:`mne.time_frequency.EpochsSpectrum` objects to be passed as data to the :func:`~mne_connectivity.spectral_connectivity_epochs` function, by `Thomas Binns`_ and `Eric Larson`_ (:pr:`220`). +- Add support for :class:`mne.time_frequency.EpochsTFR` objects to be passed as data to the :func:`~mne_connectivity.spectral_connectivity_epochs` and :func:`~mne_connectivity.spectral_connectivity_time` functions, by `Thomas Binns`_ and `Daniel McCloy`_ (:pr:`232`). - Update the cross-references for relevant functions and classes and make data types more explicit throughout the documentation, by `Thomas Binns`_ (:pr:`214`). Bug From 12161471a23673f6c90296f29da3bd5c029c4a91 Mon Sep 17 00:00:00 2001 From: "Thomas S. Binns" Date: Mon, 27 Jan 2025 21:58:14 +0000 Subject: [PATCH 5/8] Update changelog entry --- doc/whats_new.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/whats_new.rst b/doc/whats_new.rst index ff659291..de03ce61 100644 --- a/doc/whats_new.rst +++ b/doc/whats_new.rst @@ -23,7 +23,7 @@ Enhancements ~~~~~~~~~~~~ - Add a new :class:`~mne_connectivity.decoding.CoherencyDecomposition` class for decomposing connectivity sources using multivariate coherency-based methods, by `Thomas Binns`_ (:pr:`193`). -- Add new plotting methods :meth:`CoherencyDecomposition.plot_filters() ` and :meth:`CoherencyDecomposition.plot_patterns() ` for visualising the decomposed connectivity sources, by `Thomas Binns`_ (:pr:`208`) and (:pr:`279`). +- Add new plotting methods :meth:`CoherencyDecomposition.plot_filters() ` and :meth:`CoherencyDecomposition.plot_patterns() ` for visualising the decomposed connectivity sources, by `Thomas Binns`_ (:pr:`208` and :pr:`280`). - Add support for computing multiple components of multivariate connectivity in the :func:`~mne_connectivity.spectral_connectivity_epochs` and :func:`~mne_connectivity.spectral_connectivity_time` functions and :class:`~mne_connectivity.decoding.CoherencyDecomposition` class, and add support for storing data with a components dimension in all :class:`~mne_connectivity.Connectivity` classes, by `Thomas Binns`_ and `Eric Larson`_ (:pr:`213`). - Add support for :class:`mne.time_frequency.EpochsSpectrum` objects to be passed as data to the :func:`~mne_connectivity.spectral_connectivity_epochs` function, by `Thomas Binns`_ and `Eric Larson`_ (:pr:`220`). - Add support for :class:`mne.time_frequency.EpochsTFR` objects to be passed as data to the :func:`~mne_connectivity.spectral_connectivity_epochs` and :func:`~mne_connectivity.spectral_connectivity_time` functions, by `Thomas Binns`_ and `Daniel McCloy`_ (:pr:`232`). From fb4afb120af696c89fa875657695ee87d707c9e6 Mon Sep 17 00:00:00 2001 From: "Thomas S. Binns" Date: Mon, 27 Jan 2025 22:16:13 +0000 Subject: [PATCH 6/8] Change axes typehint --- mne_connectivity/utils/docs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mne_connectivity/utils/docs.py b/mne_connectivity/utils/docs.py index 14e2eee5..c6c44dee 100644 --- a/mne_connectivity/utils/docs.py +++ b/mne_connectivity/utils/docs.py @@ -434,7 +434,7 @@ """ docdict["axes_topomap"] = """ -axes : list of list of matplotlib.axes.Axes | None (default None) +axes : length-2 tuple of list of matplotlib.axes.Axes | None (default None) The axes to plot to. If `None`, a new figure will be created with the correct number of axes. If not `None`, there must be two lists containing the axes for the seeds and targets, respectively. In each of these two lists, the number of axes must match From 7a50f90083792dd2cfb2b6a93dbc1c3bf4badb2a Mon Sep 17 00:00:00 2001 From: "Thomas S. Binns" Date: Mon, 27 Jan 2025 23:09:38 +0000 Subject: [PATCH 7/8] Update axis and plot naming --- mne_connectivity/decoding/decomposition.py | 9 +++++---- mne_connectivity/utils/docs.py | 6 ++++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/mne_connectivity/decoding/decomposition.py b/mne_connectivity/decoding/decomposition.py index bbc37270..78284d16 100644 --- a/mne_connectivity/decoding/decomposition.py +++ b/mne_connectivity/decoding/decomposition.py @@ -727,6 +727,10 @@ def _plot_filters_patterns( # create Evoked object evoked = EvokedArray(plot_data[group_idx], group_info, tmin=0) # then call plot_topomap + if name_format is None: + group_name_format = f"{self._conn_estimator.name}%01d_{group_name}" + else: + group_name_format = name_format + f"_{group_name}" figs.append( evoked.plot_topomap( times=components, @@ -752,15 +756,12 @@ def _plot_filters_patterns( cbar_fmt=cbar_fmt, units=units, axes=axes[group_idx] if axes is not None else None, - time_format=f"{self._conn_estimator.name}%01d" - if name_format is None - else name_format, + time_format=group_name_format, nrows=nrows, ncols=ncols, show=False, # set Seeds/Targets suptitle first ) ) - figs[-1].suptitle(group_name) # differentiate seeds from targets plt_show(show=show, fig=figs[-1]) return figs diff --git a/mne_connectivity/utils/docs.py b/mne_connectivity/utils/docs.py index c6c44dee..e8f62ab1 100644 --- a/mne_connectivity/utils/docs.py +++ b/mne_connectivity/utils/docs.py @@ -443,8 +443,10 @@ docdict["name_format_topomap"] = r""" name_format : str | None (default None) - The string format for axes titles. If `None`, uses ``f"{method}%01d"``, i.e. the - method name followed by the component number. + The string format for axes titles. If `None`, uses ``f"{method}%01d_{group}"``, + i.e., the method name followed by the component number and the group being plotted + (seeds or targets). If not `None`, it must contain a formatting specifier for the + component number, and the group will be appended to the end. """ docdict["nrows_topomap"] = """ From f8a0ef3c950d82fd08eabd8c55b675f11d369958 Mon Sep 17 00:00:00 2001 From: "Thomas S. Binns" Date: Tue, 28 Jan 2025 19:32:39 +0000 Subject: [PATCH 8/8] Change group name --- mne_connectivity/decoding/decomposition.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mne_connectivity/decoding/decomposition.py b/mne_connectivity/decoding/decomposition.py index 78284d16..b119ccee 100644 --- a/mne_connectivity/decoding/decomposition.py +++ b/mne_connectivity/decoding/decomposition.py @@ -719,7 +719,7 @@ def _plot_filters_patterns( # plot seeds and targets figs = [] - for group_idx, group_name in zip([0, 1], ["Seeds", "Targets"]): + for group_idx, group_name in zip([0, 1], ["seeds", "targets"]): # create info for seeds/targets group_info = pick_info(info, self.indices[group_idx]) with group_info._unlock(): @@ -728,9 +728,9 @@ def _plot_filters_patterns( evoked = EvokedArray(plot_data[group_idx], group_info, tmin=0) # then call plot_topomap if name_format is None: - group_name_format = f"{self._conn_estimator.name}%01d_{group_name}" + group_name_format = f"{self._conn_estimator.name}%01d ({group_name})" else: - group_name_format = name_format + f"_{group_name}" + group_name_format = name_format + f" ({group_name})" figs.append( evoked.plot_topomap( times=components, @@ -759,7 +759,7 @@ def _plot_filters_patterns( time_format=group_name_format, nrows=nrows, ncols=ncols, - show=False, # set Seeds/Targets suptitle first + show=False, ) ) plt_show(show=show, fig=figs[-1])