ECoG Movement decoding example#

This example notebook read openly accessible data from the publication Electrocorticography is superior to subthalamic local field potentials for movement decoding in Parkinson’s disease (Merk et al. 2022 <https://elifesciences.org/articles/75126>_). The dataset is available here.

For simplicity one example subject is automatically shipped within this repo at the py_neuromodulation/data folder, stored in iEEG BIDS format.

from sklearn import metrics, model_selection, linear_model
import matplotlib.pyplot as plt

import py_neuromodulation as nm
from py_neuromodulation import (
    nm_analysis,
    nm_decode,
    nm_define_nmchannels,
    nm_IO,
    nm_plots,
    nm_settings,
)

Let’s read the example using mne_bids. The resulting raw object is of type mne.RawArray. We can use the properties such as sampling frequency, channel names, channel types all from the mne array and create the nm_channels DataFrame:

(
    RUN_NAME,
    PATH_RUN,
    PATH_BIDS,
    PATH_OUT,
    datatype,
) = nm_IO.get_paths_example_data()

(
    raw,
    data,
    sfreq,
    line_noise,
    coord_list,
    coord_names,
) = nm_IO.read_BIDS_data(
    PATH_RUN=PATH_RUN, BIDS_PATH=PATH_BIDS, datatype=datatype
)

nm_channels = nm_define_nmchannels.set_channels(
    ch_names=raw.ch_names,
    ch_types=raw.get_channel_types(),
    reference="default",
    bads=raw.info["bads"],
    new_names="default",
    used_types=("ecog", "dbs", "seeg"),
    target_keywords=["MOV_RIGHT"],
)

nm_channels
Extracting parameters from /home/docs/checkouts/readthedocs.org/user_builds/py-neuromodulation/envs/latest/lib/python3.11/site-packages/py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.vhdr...
Setting channel info structure...
Reading channel info from /home/docs/checkouts/readthedocs.org/user_builds/py-neuromodulation/envs/latest/lib/python3.11/site-packages/py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_channels.tsv.
Reading electrode coords from /home/docs/checkouts/readthedocs.org/user_builds/py-neuromodulation/envs/latest/lib/python3.11/site-packages/py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_space-mni_electrodes.tsv.
name rereference used target type status new_name
0 LFP_RIGHT_0 LFP_RIGHT_2 1 0 dbs good LFP_RIGHT_0-LFP_RIGHT_2
1 LFP_RIGHT_1 LFP_RIGHT_0 1 0 dbs good LFP_RIGHT_1-LFP_RIGHT_0
2 LFP_RIGHT_2 LFP_RIGHT_1 1 0 dbs good LFP_RIGHT_2-LFP_RIGHT_1
3 ECOG_RIGHT_0 average 1 0 ecog good ECOG_RIGHT_0-avgref
4 ECOG_RIGHT_1 average 1 0 ecog good ECOG_RIGHT_1-avgref
5 ECOG_RIGHT_2 average 1 0 ecog good ECOG_RIGHT_2-avgref
6 ECOG_RIGHT_3 average 1 0 ecog good ECOG_RIGHT_3-avgref
7 ECOG_RIGHT_4 average 1 0 ecog good ECOG_RIGHT_4-avgref
8 ECOG_RIGHT_5 average 1 0 ecog good ECOG_RIGHT_5-avgref
9 MOV_RIGHT None 0 1 misc good MOV_RIGHT


This example contains the grip force movement traces, we’ll use the MOV_RIGHT channel as a decoding target channel. Let’s check some of the raw feature and time series traces:

plt.figure(figsize=(12, 4), dpi=300)
plt.subplot(121)
plt.plot(raw.times, data[-1, :])
plt.xlabel("Time [s]")
plt.ylabel("a.u.")
plt.title("Movement label")
plt.xlim(0, 20)

plt.subplot(122)
for idx, ch_name in enumerate(nm_channels.query("used == 1").name):
    plt.plot(raw.times, data[idx, :] + idx * 300, label=ch_name)
plt.legend(bbox_to_anchor=(1, 0.5), loc="center left")
plt.title("ECoG + STN-LFP time series")
plt.xlabel("Time [s]")
plt.ylabel("Voltage a.u.")
plt.xlim(0, 20)
Movement label, ECoG + STN-LFP time series
(0.0, 20.0)
settings = nm_settings.get_default_settings()
settings = nm_settings.set_settings_fast_compute(settings)

settings["features"]["welch"] = True
settings["features"]["fft"] = True
settings["features"]["bursts"] = True
settings["features"]["sharpwave_analysis"] = True
settings["features"]["coherence"] = True
settings["coherence"]["channels"] = [["LFP_RIGHT_0", "ECOG_RIGHT_0"]]
settings["coherence"]["frequency_bands"] = ["high beta", "low gamma"]
settings["sharpwave_analysis_settings"]["estimator"]["mean"] = []
for sw_feature in list(
    settings["sharpwave_analysis_settings"]["sharpwave_features"].keys()
):
    settings["sharpwave_analysis_settings"]["sharpwave_features"][
        sw_feature
    ] = True
    settings["sharpwave_analysis_settings"]["estimator"]["mean"].append(
        sw_feature
    )
features = stream.run(
    data=data,
    out_path_root=PATH_OUT,
    folder_name=RUN_NAME,
)
Last batch took: 0.09 seconds
1.0 seconds of data processed
Last batch took: 0.09 seconds
1.1 seconds of data processed
Last batch took: 0.1 seconds
1.2 seconds of data processed
Last batch took: 0.1 seconds
1.3 seconds of data processed
Last batch took: 0.1 seconds
1.4 seconds of data processed
Last batch took: 0.1 seconds
1.5 seconds of data processed
Last batch took: 0.1 seconds
1.6 seconds of data processed
Last batch took: 0.1 seconds
1.7 seconds of data processed
Last batch took: 0.1 seconds
1.8 seconds of data processed
Last batch took: 0.1 seconds
1.9 seconds of data processed
Last batch took: 0.1 seconds
2.0 seconds of data processed
Last batch took: 0.1 seconds
2.1 seconds of data processed
Last batch took: 0.1 seconds
2.2 seconds of data processed
Last batch took: 0.1 seconds
2.3 seconds of data processed
Last batch took: 0.1 seconds
2.4 seconds of data processed
Last batch took: 0.1 seconds
2.5 seconds of data processed
Last batch took: 0.1 seconds
2.6 seconds of data processed
Last batch took: 0.1 seconds
2.7 seconds of data processed
Last batch took: 0.11 seconds
2.8 seconds of data processed
Last batch took: 0.11 seconds
2.9 seconds of data processed
Last batch took: 0.11 seconds
3.0 seconds of data processed
Last batch took: 0.11 seconds
3.1 seconds of data processed
Last batch took: 0.11 seconds
3.2 seconds of data processed
Last batch took: 0.12 seconds
3.3 seconds of data processed
Last batch took: 0.12 seconds
3.4 seconds of data processed
Last batch took: 0.12 seconds
3.5 seconds of data processed
Last batch took: 0.12 seconds
3.6 seconds of data processed
Last batch took: 0.12 seconds
3.7 seconds of data processed
Last batch took: 0.12 seconds
3.8 seconds of data processed
Last batch took: 0.12 seconds
3.9 seconds of data processed
Last batch took: 0.12 seconds
4.0 seconds of data processed
Last batch took: 0.12 seconds
4.1 seconds of data processed
Last batch took: 0.12 seconds
4.2 seconds of data processed
Last batch took: 0.11 seconds
4.3 seconds of data processed
Last batch took: 0.11 seconds
4.4 seconds of data processed
Last batch took: 0.11 seconds
4.5 seconds of data processed
Last batch took: 0.11 seconds
4.6 seconds of data processed
Last batch took: 0.11 seconds
4.7 seconds of data processed
Last batch took: 0.11 seconds
4.8 seconds of data processed
Last batch took: 0.11 seconds
4.9 seconds of data processed
Last batch took: 0.11 seconds
5.0 seconds of data processed
Last batch took: 0.1 seconds
5.1 seconds of data processed
Last batch took: 0.1 seconds
5.2 seconds of data processed
Last batch took: 0.1 seconds
5.3 seconds of data processed
Last batch took: 0.1 seconds
5.4 seconds of data processed
Last batch took: 0.1 seconds
5.5 seconds of data processed
Last batch took: 0.1 seconds
5.6 seconds of data processed
Last batch took: 0.1 seconds
5.7 seconds of data processed
Last batch took: 0.1 seconds
5.8 seconds of data processed
Last batch took: 0.1 seconds
5.9 seconds of data processed
Last batch took: 0.1 seconds
6.0 seconds of data processed
Last batch took: 0.1 seconds
6.1 seconds of data processed
Last batch took: 0.11 seconds
6.2 seconds of data processed
Last batch took: 0.1 seconds
6.3 seconds of data processed
Last batch took: 0.11 seconds
6.4 seconds of data processed
Last batch took: 0.11 seconds
6.5 seconds of data processed
Last batch took: 0.11 seconds
6.6 seconds of data processed
Last batch took: 0.1 seconds
6.7 seconds of data processed
Last batch took: 0.1 seconds
6.8 seconds of data processed
Last batch took: 0.1 seconds
6.9 seconds of data processed
Last batch took: 0.1 seconds
7.0 seconds of data processed
Last batch took: 0.1 seconds
7.1 seconds of data processed
Last batch took: 0.1 seconds
7.2 seconds of data processed
Last batch took: 0.1 seconds
7.3 seconds of data processed
Last batch took: 0.1 seconds
7.4 seconds of data processed
Last batch took: 0.1 seconds
7.5 seconds of data processed
Last batch took: 0.1 seconds
7.6 seconds of data processed
Last batch took: 0.1 seconds
7.7 seconds of data processed
Last batch took: 0.1 seconds
7.8 seconds of data processed
Last batch took: 0.1 seconds
7.9 seconds of data processed
Last batch took: 0.11 seconds
8.0 seconds of data processed
Last batch took: 0.11 seconds
8.1 seconds of data processed
Last batch took: 0.1 seconds
8.2 seconds of data processed
Last batch took: 0.11 seconds
8.3 seconds of data processed
Last batch took: 0.11 seconds
8.4 seconds of data processed
Last batch took: 0.11 seconds
8.5 seconds of data processed
Last batch took: 0.11 seconds
8.6 seconds of data processed
Last batch took: 0.11 seconds
8.7 seconds of data processed
Last batch took: 0.11 seconds
8.8 seconds of data processed
Last batch took: 0.11 seconds
8.9 seconds of data processed
Last batch took: 0.11 seconds
9.0 seconds of data processed
Last batch took: 0.11 seconds
9.1 seconds of data processed
Last batch took: 0.11 seconds
9.2 seconds of data processed
Last batch took: 0.11 seconds
9.3 seconds of data processed
Last batch took: 0.11 seconds
9.4 seconds of data processed
Last batch took: 0.11 seconds
9.5 seconds of data processed
Last batch took: 0.11 seconds
9.6 seconds of data processed
Last batch took: 0.11 seconds
9.7 seconds of data processed
Last batch took: 0.11 seconds
9.8 seconds of data processed
Last batch took: 0.11 seconds
9.9 seconds of data processed
Last batch took: 0.11 seconds
10.0 seconds of data processed
Last batch took: 0.11 seconds
10.1 seconds of data processed
Last batch took: 0.11 seconds
10.2 seconds of data processed
Last batch took: 0.11 seconds
10.3 seconds of data processed
Last batch took: 0.11 seconds
10.4 seconds of data processed
Last batch took: 0.11 seconds
10.5 seconds of data processed
Last batch took: 0.11 seconds
10.6 seconds of data processed
Last batch took: 0.11 seconds
10.7 seconds of data processed
Last batch took: 0.11 seconds
10.8 seconds of data processed
Last batch took: 0.11 seconds
10.9 seconds of data processed
Last batch took: 0.11 seconds
11.0 seconds of data processed
Last batch took: 0.11 seconds
11.1 seconds of data processed
Last batch took: 0.11 seconds
11.2 seconds of data processed
Last batch took: 0.11 seconds
11.3 seconds of data processed
Last batch took: 0.11 seconds
11.4 seconds of data processed
Last batch took: 0.11 seconds
11.5 seconds of data processed
Last batch took: 0.11 seconds
11.6 seconds of data processed
Last batch took: 0.11 seconds
11.7 seconds of data processed
Last batch took: 0.11 seconds
11.8 seconds of data processed
Last batch took: 0.11 seconds
11.9 seconds of data processed
Last batch took: 0.11 seconds
12.0 seconds of data processed
Last batch took: 0.11 seconds
12.1 seconds of data processed
Last batch took: 0.11 seconds
12.2 seconds of data processed
Last batch took: 0.11 seconds
12.3 seconds of data processed
Last batch took: 0.1 seconds
12.4 seconds of data processed
Last batch took: 0.1 seconds
12.5 seconds of data processed
Last batch took: 0.1 seconds
12.6 seconds of data processed
Last batch took: 0.1 seconds
12.7 seconds of data processed
Last batch took: 0.1 seconds
12.8 seconds of data processed
Last batch took: 0.1 seconds
12.9 seconds of data processed
Last batch took: 0.1 seconds
13.0 seconds of data processed
Last batch took: 0.1 seconds
13.1 seconds of data processed
Last batch took: 0.1 seconds
13.2 seconds of data processed
Last batch took: 0.1 seconds
13.3 seconds of data processed
Last batch took: 0.1 seconds
13.4 seconds of data processed
Last batch took: 0.1 seconds
13.5 seconds of data processed
Last batch took: 0.1 seconds
13.6 seconds of data processed
Last batch took: 0.1 seconds
13.7 seconds of data processed
Last batch took: 0.1 seconds
13.8 seconds of data processed
Last batch took: 0.1 seconds
13.9 seconds of data processed
Last batch took: 0.1 seconds
14.0 seconds of data processed
Last batch took: 0.1 seconds
14.1 seconds of data processed
Last batch took: 0.1 seconds
14.2 seconds of data processed
Last batch took: 0.11 seconds
14.3 seconds of data processed
Last batch took: 0.1 seconds
14.4 seconds of data processed
Last batch took: 0.1 seconds
14.5 seconds of data processed
Last batch took: 0.11 seconds
14.6 seconds of data processed
Last batch took: 0.11 seconds
14.7 seconds of data processed
Last batch took: 0.12 seconds
14.8 seconds of data processed
Last batch took: 0.13 seconds
14.9 seconds of data processed
Last batch took: 0.11 seconds
15.0 seconds of data processed
Last batch took: 0.11 seconds
15.1 seconds of data processed
Last batch took: 0.11 seconds
15.2 seconds of data processed
Last batch took: 0.11 seconds
15.3 seconds of data processed
Last batch took: 0.11 seconds
15.4 seconds of data processed
Last batch took: 0.11 seconds
15.5 seconds of data processed
Last batch took: 0.11 seconds
15.6 seconds of data processed
Last batch took: 0.11 seconds
15.7 seconds of data processed
Last batch took: 0.11 seconds
15.8 seconds of data processed
Last batch took: 0.11 seconds
15.9 seconds of data processed
Last batch took: 0.11 seconds
16.0 seconds of data processed
Last batch took: 0.11 seconds
16.1 seconds of data processed
Last batch took: 0.11 seconds
16.2 seconds of data processed
Last batch took: 0.11 seconds
16.3 seconds of data processed
Last batch took: 0.11 seconds
16.4 seconds of data processed
Last batch took: 0.11 seconds
16.5 seconds of data processed
Last batch took: 0.11 seconds
16.6 seconds of data processed
Last batch took: 0.11 seconds
16.7 seconds of data processed
Last batch took: 0.11 seconds
16.8 seconds of data processed
Last batch took: 0.1 seconds
16.9 seconds of data processed
Last batch took: 0.1 seconds
17.0 seconds of data processed
Last batch took: 0.1 seconds
17.1 seconds of data processed
Last batch took: 0.1 seconds
17.2 seconds of data processed
Last batch took: 0.1 seconds
17.3 seconds of data processed
Last batch took: 0.1 seconds
17.4 seconds of data processed
Last batch took: 0.1 seconds
17.5 seconds of data processed
Last batch took: 0.1 seconds
17.6 seconds of data processed
Last batch took: 0.1 seconds
17.7 seconds of data processed
Last batch took: 0.1 seconds
17.8 seconds of data processed
Last batch took: 0.1 seconds
17.9 seconds of data processed
Last batch took: 0.1 seconds
18.0 seconds of data processed
Last batch took: 0.1 seconds
18.1 seconds of data processed
Last batch took: 0.1 seconds
18.2 seconds of data processed
Last batch took: 0.1 seconds
18.3 seconds of data processed
Last batch took: 0.1 seconds
18.4 seconds of data processed
Last batch took: 0.1 seconds
18.5 seconds of data processed
Last batch took: 0.11 seconds
18.6 seconds of data processed
Last batch took: 0.11 seconds
18.7 seconds of data processed
Last batch took: 0.11 seconds
18.8 seconds of data processed
Last batch took: 0.11 seconds
18.9 seconds of data processed
Last batch took: 0.11 seconds
19.0 seconds of data processed
_SIDECAR.json saved to /home/docs/checkouts/readthedocs.org/user_builds/py-neuromodulation/envs/latest/lib/python3.11/site-packages/py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_SIDECAR.json
FEATURES.csv saved to /home/docs/checkouts/readthedocs.org/user_builds/py-neuromodulation/envs/latest/lib/python3.11/site-packages/py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_FEATURES.csv
settings.json saved to /home/docs/checkouts/readthedocs.org/user_builds/py-neuromodulation/envs/latest/lib/python3.11/site-packages/py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_SETTINGS.json
nm_channels.csv saved to /home/docs/checkouts/readthedocs.org/user_builds/py-neuromodulation/envs/latest/lib/python3.11/site-packages/py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_nm_channels.csv

Feature Analysis Movement#

The obtained performances can now be read and visualized using the nm_analysis.Feature_Reader.

# initialize analyzer
feature_reader = nm_analysis.Feature_Reader(
    feature_dir=PATH_OUT,
    feature_file=RUN_NAME,
)
feature_reader.label_name = "MOV_RIGHT"
feature_reader.label = feature_reader.feature_arr["MOV_RIGHT"]
icoh_LFP_RIGHT_0_to_ECOG_RIGHT_0_max_fband_high beta icoh_LFP_RIGHT_0_to_ECOG_RIGHT_0_mean_fband_low gamma icoh_LFP_RIGHT_0_to_ECOG_RIGHT_0_max_fband_low gamma icoh_LFP_RIGHT_0_to_ECOG_RIGHT_0_max_allfbands_low gamma time MOV_RIGHT
100 -0.434049 0.640233 -0.041695 0.836483 11000 -0.150107
101 0.514665 1.558333 1.234896 0.829533 11100 -0.280238
102 0.592526 0.723595 -0.162748 0.822752 11200 -0.305062
103 0.418552 0.609162 0.244190 0.816135 11300 -0.312851
104 1.698498 -0.090110 0.603308 0.809676 11400 -0.305154
105 -0.627310 1.502582 2.957540 0.803367 11500 -0.305200
106 -0.137041 0.814290 1.368967 0.797203 11600 -0.311440
107 -0.508566 1.812638 3.000000 0.791180 11700 -0.306840


(181, 552)
feature_reader._get_target_ch()
'MOV_RIGHT'
feature_reader.plot_target_averaged_channel(
    ch="ECOG_RIGHT_0",
    list_feature_keywords=None,
    epoch_len=4,
    threshold=0.5,
    ytick_labelsize=7,
    figsize_x=12,
    figsize_y=12,
)
Movement aligned features channel: ECOG_RIGHT_0, MOV_RIGHT
Feature epoch average figure saved to: /home/docs/checkouts/readthedocs.org/user_builds/py-neuromodulation/envs/latest/lib/python3.11/site-packages/py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/MOV_aligned_features_ch_ECOG_RIGHT_0_all.png
feature_reader.plot_all_features(
    ytick_labelsize=6,
    clim_low=-2,
    clim_high=2,
    ch_used="ECOG_RIGHT_0",
    time_limit_low_s=0,
    time_limit_high_s=20,
    normalize=True,
    save=True,
)
Feature Plot sub-testsub_ses-EphysMedOff_task-gripforce_run-0
nm_plots.plot_corr_matrix(
    feature=feature_reader.feature_arr.filter(regex="ECOG_RIGHT_0"),
    ch_name="ECOG_RIGHT_0-avgref",
    feature_names=feature_reader.feature_arr.filter(
        regex="ECOG_RIGHT_0-avgref"
    ).columns,
    feature_file=feature_reader.feature_file,
    show_plot=True,
    figsize=(15, 15),
)
Correlation matrix features channel: ECOG_RIGHT_0-avgref
<Axes: title={'center': 'Correlation matrix features channel: ECOG_RIGHT_0-avgref'}>

Decoding#

The main focus of the py_neuromodulation pipeline is feature estimation. Nevertheless, the user can also use the pipeline for machine learning decoding. It can be used for regression and classification problems and also dimensionality reduction such as PCA and CCA.

Here, we show an example using the XGBOOST classifier. The used labels came from a continuous grip force movement target, named “MOV_RIGHT”.

First we initialize the Decoder class, which the specified validation method, here being a simple 3-fold cross validation, the evaluation metric, used machine learning model, and the channels we want to evaluate performances for.

There are many more implemented methods, but we will here limit it to the ones presented.

model = linear_model.LinearRegression()

feature_reader.decoder = nm_decode.Decoder(
    features=feature_reader.feature_arr,
    label=feature_reader.label,
    label_name=feature_reader.label_name,
    used_chs=feature_reader.used_chs,
    model=model,
    eval_method=metrics.r2_score,
    cv_method=model_selection.KFold(n_splits=3, shuffle=True),
)
performances = feature_reader.run_ML_model(
    estimate_channels=True,
    estimate_gridpoints=False,
    estimate_all_channels_combined=True,
    save_results=True,
)
model being saved to: /home/docs/checkouts/readthedocs.org/user_builds/py-neuromodulation/envs/latest/lib/python3.11/site-packages/py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_LM_ML_RES.p

The performances are a dictionary that can be transformed into a DataFrame:

df_per = feature_reader.get_dataframe_performances(performances)

df_per
performance_test performance_train sub ch ch_type
0 0.283831 0.830209 testsub LFP_RIGHT_0-LFP_RIGHT_2 electrode ch
1 0.034972 0.648565 testsub LFP_RIGHT_1-LFP_RIGHT_0 electrode ch
2 0.000000 0.661909 testsub LFP_RIGHT_2-LFP_RIGHT_1 electrode ch
3 0.023575 0.734424 testsub ECOG_RIGHT_0-avgref electrode ch
4 0.000000 0.708712 testsub ECOG_RIGHT_1-avgref electrode ch
5 0.074092 0.740414 testsub ECOG_RIGHT_2-avgref electrode ch
6 0.000000 0.740436 testsub ECOG_RIGHT_3-avgref electrode ch
7 0.000000 0.764974 testsub ECOG_RIGHT_4-avgref electrode ch
8 0.000000 0.761067 testsub ECOG_RIGHT_5-avgref electrode ch
9 0.374079 1.000000 testsub all_ch_combined all ch combinded


ax = nm_plots.plot_df_subjects(
    df_per,
    x_col="sub",
    y_col="performance_test",
    hue="ch_type",
    PATH_SAVE=PATH_OUT / RUN_NAME / (RUN_NAME + "_decoding_performance.png"),
    figsize_tuple=(8, 5),
)
ax.set_ylabel(r"$R^2$ Correlation")
ax.set_xlabel("Subject 000")
ax.set_title("Performance comparison Movement decoding")
plt.tight_layout()
Performance comparison Movement decoding

Total running time of the script: (0 minutes 27.049 seconds)

Gallery generated by Sphinx-Gallery