Speed measurement

Here we will compare the speed of plotting UnfoldMakie with MNE (Python) and EEGLAB (MATLAB).

Three cases are measured:

  • Single topoplot
  • Topoplot series with 50 topoplots
  • Topoplott animation with 50 timestamps

Note that the results of benchmarking on your computer and on Github may differ.

using UnfoldMakie
using TopoPlots
using BenchmarkTools
using Observables
using CairoMakie
using Statistics
using PythonPlot;
using PyMNE;
    CondaPkg Found dependencies: /home/runner/.julia/packages/CondaPkg/8GjrP/CondaPkg.toml
    CondaPkg Found dependencies: /home/runner/.julia/packages/PyMNE/cNGDN/CondaPkg.toml
    CondaPkg Found dependencies: /home/runner/.julia/packages/PythonCall/83z4q/CondaPkg.toml
    CondaPkg Found dependencies: /home/runner/.julia/packages/PythonPlot/oS8x4/CondaPkg.toml
    CondaPkg Resolving changes
             + libstdcxx
             + libstdcxx-ng
             + matplotlib
             + mne (pip)
             + openssl
             + python
             + uv
    CondaPkg Creating environment
             │ /home/runner/.julia/artifacts/43005ee838d3b9ab9b3f1d790fa2e43bd62e6912/bin/micromamba
             │ -r /home/runner/.julia/scratchspaces/0b3b1443-0f03-428d-bdfb-f27f9c1191ea/root
             │ create
             │ -y
             │ -p /home/runner/work/UnfoldMakie.jl/UnfoldMakie.jl/docs/.CondaPkg/env
             │ --override-channels
             │ libstdcxx[version='>=3.4,<15.0']
             │ libstdcxx-ng[version='>=3.4,<15.0']
             │ matplotlib[version='>=1']
             │ openssl[version='>=3, <3.6']
             │ python[version='>=3.10,!=3.14.0,!=3.14.1,<4, >=3.4,<4',channel='conda-forge',build='*cp*']
             │ uv[version='>=0.4']
             │ -c conda-forge
             └ -c anaconda


Transaction

  Prefix: /home/runner/work/UnfoldMakie.jl/UnfoldMakie.jl/docs/.CondaPkg/env

  Updating specs:

   - libstdcxx[version=">=3.4,<15.0"]
   - libstdcxx-ng[version=">=3.4,<15.0"]
   - matplotlib>=1
   - openssl[version=">=3,<3.6"]
   - conda-forge::python[version=">=3.10,(!=3.14.0,(!=3.14.1,(<4,(>=3.4,<4))))",build="*cp*"]
   - uv>=0.4


  Package                           Version  Build                 Channel           Size
───────────────────────────────────────────────────────────────────────────────────────────
  Install:
───────────────────────────────────────────────────────────────────────────────────────────

  + _openmp_mutex                       4.5  20_gnu                conda-forge     Cached
  + alsa-lib                       1.2.15.3  hb03c661_0            conda-forge     Cached
  + brotli                            1.2.0  hed03a55_1            conda-forge     Cached
  + brotli-bin                        1.2.0  hb03c661_1            conda-forge     Cached
  + bzip2                             1.0.8  hda65f42_9            conda-forge     Cached
  + ca-certificates               2026.2.25  hbd8a1cb_0            conda-forge     Cached
  + cairo                            1.18.4  he90730b_1            conda-forge     Cached
  + contourpy                         1.3.3  py314h97ea11e_4       conda-forge     Cached
  + cycler                           0.12.1  pyhcf101f3_2          conda-forge     Cached
  + cyrus-sasl                       2.1.28  hac629b4_1            conda-forge     Cached
  + dbus                             1.16.2  h24cb091_1            conda-forge     Cached
  + double-conversion                 3.4.0  hecca717_0            conda-forge     Cached
  + font-ttf-dejavu-sans-mono          2.37  hab24e00_0            conda-forge     Cached
  + font-ttf-inconsolata              3.000  h77eed37_0            conda-forge     Cached
  + font-ttf-source-code-pro          2.038  h77eed37_0            conda-forge     Cached
  + font-ttf-ubuntu                    0.83  h77eed37_3            conda-forge     Cached
  + fontconfig                       2.17.1  h27c8c51_0            conda-forge     Cached
  + fonts-conda-ecosystem                 1  0                     conda-forge     Cached
  + fonts-conda-forge                     1  hc364b38_1            conda-forge     Cached
  + fonttools                        4.62.0  pyh7db6752_0          conda-forge      838kB
  + freetype                         2.14.2  ha770c72_0            conda-forge     Cached
  + graphite2                        1.3.14  hecca717_2            conda-forge     Cached
  + harfbuzz                         12.3.2  h6083320_0            conda-forge     Cached
  + icu                                78.2  h33c6efd_0            conda-forge     Cached
  + keyutils                          1.6.3  hb9d3cd8_0            conda-forge     Cached
  + kiwisolver                        1.5.0  py314h97ea11e_0       conda-forge       77kB
  + krb5                             1.22.2  ha1258a1_0            conda-forge     Cached
  + lcms2                              2.18  h0c24ade_0            conda-forge     Cached
  + ld_impl_linux-64                 2.45.1  default_hbd61a6d_101  conda-forge     Cached
  + lerc                              4.1.0  hdb68285_0            conda-forge      262kB
  + libblas                          3.11.0  5_h4a7cf45_openblas   conda-forge     Cached
  + libbrotlicommon                   1.2.0  hb03c661_1            conda-forge     Cached
  + libbrotlidec                      1.2.0  hb03c661_1            conda-forge     Cached
  + libbrotlienc                      1.2.0  hb03c661_1            conda-forge     Cached
  + libcblas                         3.11.0  5_h0358290_openblas   conda-forge     Cached
  + libclang-cpp22.1                 22.1.0  default_h99862b1_0    conda-forge     Cached
  + libclang13                       22.1.0  default_h746c552_0    conda-forge     Cached
  + libcups                           2.3.3  h7a8fb5f_6            conda-forge     Cached
  + libdeflate                         1.25  h17f619e_0            conda-forge     Cached
  + libdrm                          2.4.125  hb03c661_1            conda-forge     Cached
  + libedit                    3.1.20250104  pl5321h7949ede_0      conda-forge     Cached
  + libegl                            1.7.0  ha4b6fd6_2            conda-forge     Cached
  + libexpat                          2.7.4  hecca717_0            conda-forge     Cached
  + libffi                            3.5.2  h3435931_0            conda-forge     Cached
  + libfreetype                      2.14.2  ha770c72_0            conda-forge     Cached
  + libfreetype6                     2.14.2  h73754d4_0            conda-forge     Cached
  + libgcc                           14.3.0  he0feb66_18           conda-forge     Cached
  + libgcc-ng                        14.3.0  h69a702a_18           conda-forge     Cached
  + libgfortran                      14.3.0  h69a702a_18           conda-forge     Cached
  + libgfortran5                     14.3.0  hda2acac_18           conda-forge     Cached
  + libgl                             1.7.0  ha4b6fd6_2            conda-forge     Cached
  + libglib                          2.86.4  h6548e54_1            conda-forge     Cached
  + libglvnd                          1.7.0  ha4b6fd6_2            conda-forge     Cached
  + libglx                            1.7.0  ha4b6fd6_2            conda-forge     Cached
  + libgomp                          14.3.0  he0feb66_18           conda-forge     Cached
  + libiconv                           1.18  h3b78370_2            conda-forge     Cached
  + libjpeg-turbo                     3.1.2  hb03c661_0            conda-forge     Cached
  + liblapack                        3.11.0  5_h47877c9_openblas   conda-forge     Cached
  + libllvm22                        22.1.0  hf7376ad_0            conda-forge     Cached
  + liblzma                           5.8.2  hb03c661_0            conda-forge     Cached
  + libmpdec                          4.0.0  hb03c661_1            conda-forge     Cached
  + libntlm                             1.8  hb9d3cd8_0            conda-forge     Cached
  + libopenblas                      0.3.30  pthreads_h94d23a6_4   conda-forge     Cached
  + libopengl                         1.7.0  ha4b6fd6_2            conda-forge     Cached
  + libpciaccess                       0.18  hb9d3cd8_0            conda-forge     Cached
  + libpng                           1.6.55  h421ea60_0            conda-forge     Cached
  + libpq                              18.3  h9abb657_0            conda-forge     Cached
  + libsqlite                        3.52.0  hf4e2dac_0            conda-forge     Cached
  + libstdcxx                        14.3.0  h934c35e_18           conda-forge     Cached
  + libstdcxx-ng                     14.3.0  hdf11a46_18           conda-forge     Cached
  + libtiff                           4.7.1  h9d88235_1            conda-forge     Cached
  + libuuid                          2.41.3  h5347b49_0            conda-forge     Cached
  + libvulkan-loader              1.4.341.0  h5279c79_0            conda-forge     Cached
  + libwebp-base                      1.6.0  hd42ef1d_0            conda-forge     Cached
  + libxcb                           1.17.0  h8a09558_0            conda-forge     Cached
  + libxcrypt                        4.4.36  hd590300_1            conda-forge     Cached
  + libxkbcommon                     1.13.1  hca5e8e5_0            conda-forge     Cached
  + libxml2                          2.15.2  he237659_0            conda-forge     Cached
  + libxml2-16                       2.15.2  hca6bf5a_0            conda-forge     Cached
  + libxslt                          1.1.43  h711ed8c_1            conda-forge     Cached
  + libzlib                           1.3.1  hb9d3cd8_2            conda-forge     Cached
  + matplotlib                       3.10.8  py314hdafbbf9_0       conda-forge     Cached
  + matplotlib-base                  3.10.8  py314h1194b4b_0       conda-forge     Cached
  + munkres                           1.1.4  pyhd8ed1ab_1          conda-forge     Cached
  + ncurses                             6.5  h2d0b736_3            conda-forge     Cached
  + numpy                             2.4.2  py314h2b28147_1       conda-forge     Cached
  + openjpeg                          2.5.4  h55fea9a_0            conda-forge     Cached
  + openldap                         2.6.10  hbde042b_1            conda-forge     Cached
  + openssl                           3.5.5  h35e630c_1            conda-forge     Cached
  + packaging                          26.0  pyhcf101f3_0          conda-forge     Cached
  + pcre2                             10.47  haa7fec5_0            conda-forge     Cached
  + pillow                           12.1.1  py314h8ec4b1a_0       conda-forge     Cached
  + pip                              26.0.1  pyh145f28c_0          conda-forge     Cached
  + pixman                           0.46.4  h54a6638_1            conda-forge     Cached
  + pthread-stubs                       0.4  hb9d3cd8_1002         conda-forge     Cached
  + pyparsing                         3.3.2  pyhcf101f3_0          conda-forge     Cached
  + pyside6                          6.10.2  py314hf36963e_0       conda-forge     Cached
  + python                           3.14.3  h32b2ec7_101_cp314    conda-forge     Cached
  + python-dateutil             2.9.0.post0  pyhe01879c_2          conda-forge     Cached
  + python_abi                         3.14  8_cp314               conda-forge     Cached
  + qhull                            2020.2  h434a139_5            conda-forge     Cached
  + qt6-main                         6.10.2  h17e89b9_5            conda-forge     Cached
  + readline                            8.3  h853b02a_0            conda-forge     Cached
  + six                              1.17.0  pyhe01879c_1          conda-forge     Cached
  + tk                               8.6.13  noxft_h366c992_103    conda-forge     Cached
  + tornado                           6.5.4  py314h7b0bd38_0       conda-forge     Cached
  + tzdata                            2025c  hc9c84f9_1            conda-forge     Cached
  + unicodedata2                     17.0.1  py314h5bd0f2a_0       conda-forge     Cached
  + uv                               0.10.9  h6dd6661_0            conda-forge     Cached
  + wayland                          1.24.0  hd6090a7_1            conda-forge     Cached
  + xcb-util                          0.4.1  h4f16b4b_2            conda-forge     Cached
  + xcb-util-cursor                   0.1.6  hb03c661_0            conda-forge     Cached
  + xcb-util-image                    0.4.0  hb711507_2            conda-forge     Cached
  + xcb-util-keysyms                  0.4.1  hb711507_0            conda-forge     Cached
  + xcb-util-renderutil              0.3.10  hb711507_0            conda-forge     Cached
  + xcb-util-wm                       0.4.2  hb711507_0            conda-forge     Cached
  + xkeyboard-config                   2.47  hb03c661_0            conda-forge     Cached
  + xorg-libice                       1.1.2  hb9d3cd8_0            conda-forge     Cached
  + xorg-libsm                        1.2.6  he73a12e_0            conda-forge     Cached
  + xorg-libx11                      1.8.13  he1eb515_0            conda-forge     Cached
  + xorg-libxau                      1.0.12  hb03c661_1            conda-forge     Cached
  + xorg-libxcomposite                0.4.7  hb03c661_0            conda-forge     Cached
  + xorg-libxcursor                   1.2.3  hb9d3cd8_0            conda-forge     Cached
  + xorg-libxdamage                   1.1.6  hb9d3cd8_0            conda-forge     Cached
  + xorg-libxdmcp                     1.1.5  hb03c661_1            conda-forge     Cached
  + xorg-libxext                      1.3.7  hb03c661_0            conda-forge     Cached
  + xorg-libxfixes                    6.0.2  hb03c661_0            conda-forge     Cached
  + xorg-libxi                        1.8.2  hb9d3cd8_0            conda-forge     Cached
  + xorg-libxrandr                    1.5.5  hb03c661_0            conda-forge     Cached
  + xorg-libxrender                  0.9.12  hb9d3cd8_0            conda-forge     Cached
  + xorg-libxtst                      1.2.5  hb9d3cd8_3            conda-forge     Cached
  + xorg-libxxf86vm                   1.1.7  hb03c661_0            conda-forge     Cached
  + zlib-ng                           2.3.3  hceb46e0_1            conda-forge     Cached
  + zstd                              1.5.7  hb78ec9c_6            conda-forge     Cached

  Summary:

  Install: 134 packages

  Total download: 1MB

───────────────────────────────────────────────────────────────────────────────────────────



Transaction starting
Linking python_abi-3.14-8_cp314
Linking tzdata-2025c-hc9c84f9_1
Linking ca-certificates-2026.2.25-hbd8a1cb_0
Linking font-ttf-ubuntu-0.83-h77eed37_3
Linking font-ttf-dejavu-sans-mono-2.37-hab24e00_0
Linking font-ttf-inconsolata-3.000-h77eed37_0
Linking font-ttf-source-code-pro-2.038-h77eed37_0
Linking fonts-conda-forge-1-hc364b38_1
Linking fonts-conda-ecosystem-1-0
Linking libgomp-14.3.0-he0feb66_18
Linking libglvnd-1.7.0-ha4b6fd6_2
Linking _openmp_mutex-4.5-20_gnu
Linking libopengl-1.7.0-ha4b6fd6_2
Linking libegl-1.7.0-ha4b6fd6_2
Linking libgcc-14.3.0-he0feb66_18
Linking libpciaccess-0.18-hb9d3cd8_0
Linking libffi-3.5.2-h3435931_0
Linking libntlm-1.8-hb9d3cd8_0
Linking libgfortran5-14.3.0-hda2acac_18
Linking libwebp-base-1.6.0-hd42ef1d_0
Linking alsa-lib-1.2.15.3-hb03c661_0
Linking libbrotlicommon-1.2.0-hb03c661_1
Linking xorg-libice-1.1.2-hb9d3cd8_0
Linking libdeflate-1.25-h17f619e_0
Linking libjpeg-turbo-3.1.2-hb03c661_0
Linking xorg-libxdmcp-1.1.5-hb03c661_1
Linking pthread-stubs-0.4-hb9d3cd8_1002
Linking xorg-libxau-1.0.12-hb03c661_1
Linking libiconv-1.18-h3b78370_2
Linking libgcc-ng-14.3.0-h69a702a_18
Linking keyutils-1.6.3-hb9d3cd8_0
Linking ncurses-6.5-h2d0b736_3
Linking libzlib-1.3.1-hb9d3cd8_2
Linking libmpdec-4.0.0-hb03c661_1
Linking libexpat-2.7.4-hecca717_0
Linking bzip2-1.0.8-hda65f42_9
Linking libuuid-2.41.3-h5347b49_0
Linking liblzma-5.8.2-hb03c661_0
Linking openssl-3.5.5-h35e630c_1
Linking libstdcxx-14.3.0-h934c35e_18
Linking libdrm-2.4.125-hb03c661_1
Linking libgfortran-14.3.0-h69a702a_18
Linking libbrotlienc-1.2.0-hb03c661_1
Linking libbrotlidec-1.2.0-hb03c661_1
Linking libxcb-1.17.0-h8a09558_0
Linking libxcrypt-4.4.36-hd590300_1
Linking libedit-3.1.20250104-pl5321h7949ede_0
Linking readline-8.3-h853b02a_0
Linking tk-8.6.13-noxft_h366c992_103
Linking libpng-1.6.55-h421ea60_0
Linking zstd-1.5.7-hb78ec9c_6
Linking pcre2-10.47-haa7fec5_0
Linking xorg-libsm-1.2.6-he73a12e_0
Linking lerc-4.1.0-hdb68285_0
Linking wayland-1.24.0-hd6090a7_1
Linking double-conversion-3.4.0-hecca717_0
Linking pixman-0.46.4-h54a6638_1
Linking graphite2-1.3.14-hecca717_2
Linking zlib-ng-2.3.3-hceb46e0_1
Linking icu-78.2-h33c6efd_0
Linking uv-0.10.9-h6dd6661_0
Linking libstdcxx-ng-14.3.0-hdf11a46_18
Linking libopenblas-0.3.30-pthreads_h94d23a6_4
Linking brotli-bin-1.2.0-hb03c661_1
Linking xcb-util-0.4.1-h4f16b4b_2
Linking xcb-util-wm-0.4.2-hb711507_0
Linking xcb-util-keysyms-0.4.1-hb711507_0
Linking xcb-util-renderutil-0.3.10-hb711507_0
Linking xorg-libx11-1.8.13-he1eb515_0
Linking krb5-1.22.2-ha1258a1_0
Linking libfreetype6-2.14.2-h73754d4_0
Linking ld_impl_linux-64-2.45.1-default_hbd61a6d_101
Linking libglib-2.86.4-h6548e54_1
Linking libtiff-4.7.1-h9d88235_1
Linking libsqlite-3.52.0-hf4e2dac_0
Linking libxml2-16-2.15.2-hca6bf5a_0
Linking qhull-2020.2-h434a139_5
Linking libblas-3.11.0-5_h4a7cf45_openblas
Linking brotli-1.2.0-hed03a55_1
Linking xcb-util-image-0.4.0-hb711507_2
Linking xkeyboard-config-2.47-hb03c661_0
Linking xorg-libxfixes-6.0.2-hb03c661_0
Linking libglx-1.7.0-ha4b6fd6_2
Linking xorg-libxrender-0.9.12-hb9d3cd8_0
Linking xorg-libxext-1.3.7-hb03c661_0
Linking cyrus-sasl-2.1.28-hac629b4_1
Linking libcups-2.3.3-h7a8fb5f_6
Linking libfreetype-2.14.2-ha770c72_0
Linking dbus-1.16.2-h24cb091_1
Linking openjpeg-2.5.4-h55fea9a_0
Linking lcms2-2.18-h0c24ade_0
Linking python-3.14.3-h32b2ec7_101_cp314
Linking libxml2-2.15.2-he237659_0
Linking libcblas-3.11.0-5_h0358290_openblas
Linking liblapack-3.11.0-5_h47877c9_openblas
Linking xcb-util-cursor-0.1.6-hb03c661_0
Linking xorg-libxcomposite-0.4.7-hb03c661_0
Linking libgl-1.7.0-ha4b6fd6_2
Linking xorg-libxcursor-1.2.3-hb9d3cd8_0
Linking xorg-libxi-1.8.2-hb9d3cd8_0
Linking xorg-libxdamage-1.1.6-hb9d3cd8_0
Linking xorg-libxxf86vm-1.1.7-hb03c661_0
Linking xorg-libxrandr-1.5.5-hb03c661_0
Linking openldap-2.6.10-hbde042b_1
Linking freetype-2.14.2-ha770c72_0
Linking fontconfig-2.17.1-h27c8c51_0
Linking libxkbcommon-1.13.1-hca5e8e5_0
Linking libxslt-1.1.43-h711ed8c_1
Linking libllvm22-22.1.0-hf7376ad_0
Linking xorg-libxtst-1.2.5-hb9d3cd8_3
Linking libvulkan-loader-1.4.341.0-h5279c79_0
Linking libpq-18.3-h9abb657_0
Linking cairo-1.18.4-he90730b_1
Linking libclang-cpp22.1-22.1.0-default_h99862b1_0
Linking libclang13-22.1.0-default_h746c552_0
Linking harfbuzz-12.3.2-h6083320_0
Linking qt6-main-6.10.2-h17e89b9_5
Linking pip-26.0.1-pyh145f28c_0
Linking munkres-1.1.4-pyhd8ed1ab_1
Linking six-1.17.0-pyhe01879c_1
Linking pyparsing-3.3.2-pyhcf101f3_0
Linking packaging-26.0-pyhcf101f3_0
Linking cycler-0.12.1-pyhcf101f3_2
Linking python-dateutil-2.9.0.post0-pyhe01879c_2
Linking unicodedata2-17.0.1-py314h5bd0f2a_0
Linking pillow-12.1.1-py314h8ec4b1a_0
Linking numpy-2.4.2-py314h2b28147_1
Linking kiwisolver-1.5.0-py314h97ea11e_0
Linking tornado-6.5.4-py314h7b0bd38_0
Linking pyside6-6.10.2-py314hf36963e_0
Linking contourpy-1.3.3-py314h97ea11e_4
Linking fonttools-4.62.0-pyh7db6752_0
Linking matplotlib-base-3.10.8-py314h1194b4b_0
Linking matplotlib-3.10.8-py314hdafbbf9_0

Transaction finished


To activate this environment, use:

    micromamba activate /home/runner/work/UnfoldMakie.jl/UnfoldMakie.jl/docs/.CondaPkg/env

Or to execute a single command in this environment, use:

    micromamba run -p /home/runner/work/UnfoldMakie.jl/UnfoldMakie.jl/docs/.CondaPkg/env mycommand

    CondaPkg Installing Pip packages
             │ /home/runner/work/UnfoldMakie.jl/UnfoldMakie.jl/docs/.CondaPkg/env/bin/uv
             │ pip
             │ install
             └ mne >=1.4
Using Python 3.14.3 environment at: /home/runner/work/UnfoldMakie.jl/UnfoldMakie.jl/docs/.CondaPkg/env
Resolved 25 packages in 120ms
Downloading scipy (33.6MiB)
Downloading mne (7.1MiB)
 Downloaded mne
 Downloaded scipy
Prepared 14 packages in 561ms
Installed 14 packages in 37ms
 + certifi==2026.2.25
 + charset-normalizer==3.4.5
 + decorator==5.2.1
 + idna==3.11
 + jinja2==3.1.6
 + lazy-loader==0.5
 + markupsafe==3.0.3
 + mne==1.11.0
 + platformdirs==4.9.4
 + pooch==1.9.0
 + requests==2.32.5
 + scipy==1.17.1
 + tqdm==4.67.3
 + urllib3==2.6.3

Data input

dat, positions = TopoPlots.example_data()
df = UnfoldMakie.eeg_array_to_dataframe(dat[:, :, 1], string.(1:length(positions)));

Topoplots

UnfoldMakie.jl

@benchmark plot_topoplot(dat[:, 320, 1]; positions = positions)
BenchmarkTools.Trial: 102 samples with 1 evaluation per sample.
 Range (minmax):  44.132 ms310.265 ms   GC (min … max): 0.00% … 83.43%
 Time  (median):     45.991 ms                GC (median):    0.00%
 Time  (mean ± σ):   48.944 ms ±  26.180 ms   GC (mean ± σ):  5.18% ±  8.26%

      ▃ ▃  ▃    ▃                      
  ▅▄▅▁█▇█▇▅█▄▇▇███▇█▅▄▄▅▁▅▄▄▅▁▁▄▄▁▇▄▁▄▄▁▄▄▁▁▄▅▇▁▁▅▁▄▁▁▁▁▁▁▁▄ ▄
  44.1 ms         Histogram: frequency by time         51.3 ms <

 Memory estimate: 11.82 MiB, allocs estimate: 194614.

UnfoldMakie.jl with DelaunayMesh

@benchmark plot_topoplot(
    dat[:, 320, 1];
    positions = positions,
    topo_interpolation = (; interpolation = DelaunayMesh()),
)
BenchmarkTools.Trial: 97 samples with 1 evaluation per sample.
 Range (minmax):  45.663 ms335.939 ms   GC (min … max): 0.00% … 84.16%
 Time  (median):     49.047 ms                GC (median):    0.00%
 Time  (mean ± σ):   51.650 ms ±  29.216 ms   GC (mean ± σ):  5.64% ±  8.55%

      ▁    ▁  ▃       ▁                     ▆     ▃▁   █▁ ▁    
  ▄▇▄▄█▇▁▄▄█▄▇█▄▇▇▁▄▄▇█▁▄▄▄▇▄▄▄▁▄▁▁▇▁▇▁▇▄▇▇▄█▄▄▇▄▄██▇▄▄██▁█▇▄ ▁
  45.7 ms         Histogram: frequency by time         51.3 ms <

 Memory estimate: 11.82 MiB, allocs estimate: 194621.

MNE

posmat = collect(reduce(hcat, [[p[1], p[2]] for p in positions])')
pypos = Py(posmat).to_numpy()
pydat = Py(dat[:, 320, 1])

@benchmark begin
    f = PythonPlot.figure()
    PyMNE.viz.plot_topomap(
        pydat,
        pypos,
        sphere = 1.1,
        extrapolate = "box",
        cmap = "RdBu_r",
        sensors = false,
        contours = 6,
    )
    f.show()
end
BenchmarkTools.Trial: 406 samples with 1 evaluation per sample.
 Range (minmax):  11.620 ms174.932 ms   GC (min … max): 0.00% … 0.00%
 Time  (median):     11.775 ms                GC (median):    0.00%
 Time  (mean ± σ):   12.323 ms ±   8.253 ms   GC (mean ± σ):  0.00% ± 0.00%

  ▃▆██▅▄▃▁                                                     
  █████████▆▄▄▁▄▁▁▁▁▁▁▁▁▁▁▁▄▁▁▁▁▄▁▁▁▄▁▁▁▄▁▄▁▁▁▁▁▁▁▁▄▁▁▁▁▁▁▁▄ ▇
  11.6 ms       Histogram: log(frequency) by time      14.2 ms <

 Memory estimate: 3.30 KiB, allocs estimate: 98.

Topoplot series

Note that UnfoldMakie and MNE have different defaults for displaying topoplot series. UnfoldMakie in plot_topoplot averages over time samples. MNE in plot_topopmap displays single samples without averaging.

UnfoldMakie.jl

@benchmark begin
    plot_topoplotseries(
        df;
        bin_num = 50,
        positions = positions,
        axis = (; xlabel = "Time windows [s]"),
    )
end
BenchmarkTools.Trial: 3 samples with 1 evaluation per sample.
 Range (minmax):  2.106 s  2.177 s   GC (min … max): 0.00% … 0.00%
 Time  (median):     2.147 s               GC (median):    0.00%
 Time  (mean ± σ):   2.143 s ± 35.930 ms   GC (mean ± σ):  0.00% ± 0.00%

                                 █                       █  
  ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█ ▁
  2.11 s         Histogram: frequency by time        2.18 s <

 Memory estimate: 342.18 MiB, allocs estimate: 4920364.

MNE

easycap_montage = PyMNE.channels.make_standard_montage("standard_1020")
ch_names = pyconvert(Vector{String}, easycap_montage.ch_names)[1:64]
info = PyMNE.create_info(PyList(ch_names), ch_types = "eeg", sfreq = 1)
info.set_montage(easycap_montage)
simulated_epochs = PyMNE.EvokedArray(Py(dat[:, :, 1]), info)

@benchmark simulated_epochs.plot_topomap(1:50)
BenchmarkTools.Trial: 8 samples with 1 evaluation per sample.
 Range (minmax):  671.754 ms696.650 ms   GC (min … max): 0.00% … 0.00%
 Time  (median):     676.848 ms                GC (median):    0.00%
 Time  (mean ± σ):   678.959 ms ±   8.307 ms   GC (mean ± σ):  0.00% ± 0.00%

  █ ██    █       ██             █                            █  
  █▁██▁▁▁▁█▁▁▁▁▁▁██▁▁▁▁▁▁▁▁▁▁▁▁█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█ ▁
  672 ms           Histogram: frequency by time          697 ms <

 Memory estimate: 2.39 KiB, allocs estimate: 69.

MATLAB

Running MATLAB on a GitHub Action is not easy. So we benchmarked three consecutive executions (on a screenshot) on a server with an AMD EPYC 7452 32-core processor. Note that Github and the server we used for MATLAB benchmarking are two different computers, which can give different timing results.

Animation

The main advantage of Julia is the speed with which the figures are updated.

timestamps = range(1, 50, step = 1)
framerate = 50
50

UnfoldMakie with .gif

vals = vec(dat[:, :, 1])
p01, p99 = quantile(vals, [0.01, 0.99])
m = max(abs(p01), abs(p99))
cr = Float32.((-m, m))
@benchmark begin
    f = Makie.Figure()
    dat_obs = Observable(dat[:, 1, 1])
    plot_topoplot!(f[1, 1], dat_obs, positions = positions, visual = (; contours = false, colorrange = cr),)
    record(f, "topoplot_animation_UM.gif", timestamps; framerate = framerate) do t
        dat_obs[] = @view(dat[:, t, 1])
    end
end
BenchmarkTools.Trial: 3 samples with 1 evaluation per sample.
 Range (minmax):  1.958 s  1.986 s   GC (min … max): 0.00% … 0.00%
 Time  (median):     1.982 s               GC (median):    0.00%
 Time  (mean ± σ):   1.975 s ± 15.399 ms   GC (mean ± σ):  0.00% ± 0.00%

                                                 █       █  
  ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█▁▁▁▁▁▁▁█ ▁
  1.96 s         Histogram: frequency by time        1.99 s <

 Memory estimate: 120.33 MiB, allocs estimate: 416766.

MNE with .gif

@benchmark begin
    fig, anim = simulated_epochs.animate_topomap(
        times = Py(timestamps),
        frame_rate = framerate,
        blit = false,
        image_interp = "cubic", # same as CloughTocher
    )
    anim.save("topomap_animation_mne.gif", writer = "ffmpeg", fps = framerate)
end
BenchmarkTools.Trial: 1 sample with 1 evaluation per sample.
 Single result which took 9.221 s (0.00% GC) to evaluate,
 with a memory estimate of 3.03 KiB, over 96 allocations.

Note, that due to some bugs in (probably) PythonCall topoplot is black and white.


This page was generated using Literate.jl.