Tutorial 2: Using multiple datasets#

We extend the previous example to a case where we want to analyze the score of a classifier with three different MI datasets instead of just one. As before, we begin by importing all relevant libraries.

# Authors: Pedro L. C. Rodrigues, Sylvain Chevallier
#
# https://github.com/plcrodrigues/Workshop-MOABB-BCI-Graz-2019

import warnings

import matplotlib.pyplot as plt
import mne
import seaborn as sns
from mne.decoding import CSP
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
from sklearn.pipeline import make_pipeline

import moabb
from moabb.datasets import BNCI2014_001, Zhou2016
from moabb.evaluations import WithinSessionEvaluation
from moabb.paradigms import LeftRightImagery


moabb.set_log_level("info")
mne.set_log_level("CRITICAL")
warnings.filterwarnings("ignore")
/home/runner/work/moabb/moabb/.venv/lib/python3.10/site-packages/optuna/integration/sklearn.py:14: FutureWarning: `optuna.integration.sklearn` has been deprecated in v4.9.0. This feature will be removed in v6.0.0. See https://github.com/optuna/optuna/releases/tag/v4.9.0. Use `optuna_integration.sklearn` instead.
  optuna_warn(f"{msg} Use `optuna_integration.sklearn` instead.", FutureWarning)

Initializing Datasets#

We instantiate the two different datasets that follow the MI paradigm (with left-hand/right-hand classes) but were recorded with different number of electrodes, different number of trials, etc.

The following lines go exactly as in the previous example, where we end up obtaining a pandas dataframe containing the results of the evaluation. We could set overwrite to False to cache the results, avoiding to restart all the evaluation from scratch if a problem occurs.

[codecarbon WARNING @ 11:52:29] Multiple instances of codecarbon are allowed to run at the same time.
2026-06-29 11:54:52,381 INFO MainThread moabb.evaluations.base csp+lda | Zhou2016 | 3 | 2: Score 0.984
2026-06-29 11:54:52,381 INFO MainThread moabb.evaluations.base csp+lda | Zhou2016 | 3 | 0: Score 0.986
2026-06-29 11:54:52,381 INFO MainThread moabb.evaluations.base csp+lda | Zhou2016 | 3 | 1: Score 0.978
2026-06-29 11:54:52,381 INFO MainThread moabb.evaluations.base csp+lda | Zhou2016 | 2 | 1: Score 0.699
2026-06-29 11:54:52,381 INFO MainThread moabb.evaluations.base csp+lda | Zhou2016 | 2 | 0: Score 0.884
2026-06-29 11:54:52,381 INFO MainThread moabb.evaluations.base csp+lda | Zhou2016 | 2 | 2: Score 0.890
2026-06-29 11:54:52,381 INFO MainThread moabb.evaluations.base csp+lda | Zhou2016 | 1 | 1: Score 0.888
2026-06-29 11:54:52,381 INFO MainThread moabb.evaluations.base csp+lda | Zhou2016 | 1 | 0: Score 0.889
2026-06-29 11:54:52,382 INFO MainThread moabb.evaluations.base csp+lda | Zhou2016 | 1 | 2: Score 0.942

Plotting Results#

We plot the results using the seaborn library. Note how easy it is to plot the results from the three datasets with just one line.

results["subj"] = [str(resi).zfill(2) for resi in results["subject"]]
g = sns.catplot(
    kind="bar",
    x="score",
    y="subj",
    col="dataset",
    data=results,
    orient="h",
    palette="viridis",
)
plt.show()
dataset = Zhou2016, dataset = BNCI2014-001
2026-06-29 11:54:52,512 INFO MainThread matplotlib.category Using categorical units to plot a list of strings that are all parsable as floats or dates. If these strings should be plotted as numbers, cast to the appropriate data type before plotting.
2026-06-29 11:54:52,519 INFO MainThread matplotlib.category Using categorical units to plot a list of strings that are all parsable as floats or dates. If these strings should be plotted as numbers, cast to the appropriate data type before plotting.

Total running time of the script: (2 minutes 30.136 seconds)

Gallery generated by Sphinx-Gallery