cannot plot into matplotlib subfigure
维护者通常 1 天内回复
评估
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 新手友好度
- 35/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- python
调研方向
The failure comes from _get_event_channel in mne/viz/ui_events.py, which runs a _validate_type check in mne/utils/check.py that accepts only Figure, Brain or EvokedField. Reproduce with the snippet in the issue, then read how plot_evoked in mne/viz/evoked.py passes the figure to subscribe. Pull request #14485 is already open against this issue, so review it before starting. Done means evoked.plot(axes=ax) works on an axes inside a SubFigure and the existing viz tests still pass.
由索引模型根据 Issue 内容生成。
描述
Description of the problem
evoked.plot() cannot plot into an axes within a matplotlib subfigure
Steps to reproduce
import matplotlib.pyplot as plt
import mne
import numpy as np
info = mne.create_info(["EEG1", "EEG2", "EEG3"], sfreq=100.0, ch_types="eeg")
data = np.zeros((3, 100))
evoked = mne.EvokedArray(data, info)
fig = plt.figure(layout="constrained")
subfig = fig.subfigures(1, 2)[0]
ax = subfig.subplots()
evoked.plot(axes=ax)
# TypeError: fig must be an instance of Figure, Brain, or EvokedField, got <class 'matplotlib.figure.SubFigure'> instead.
Link to data
used synthetic data, see above
Expected results
can plot into subfigure axes
Actual results
TypeError: fig must be an instance of Figure, Brain, or EvokedField, got <class 'matplotlib.figure.SubFigure'> instead.
full traceback
---------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[5], line 4
2 subfig = fig.subfigures(1, 2)[0]
3 ax = subfig.subplots()
----> 4 evoked.plot(axes=ax)
File /opt/mne/python/mne/evoked.py:889, in Evoked.plot(self, picks, exclude, unit, show, ylim, xlim, proj, hline, units, scalings, titles, axes, gfp, window_title, spatial_colors, zorder, selectable, noise_cov, time_unit, sphere, highlight, verbose)
695 """Plot evoked data using butterfly plots.
696
697 Left click to a line shows the channel name. Selecting an area by clicking
(...) 885 .. versionadded:: 1.13.0
886 """ # noqa: E501
887 from .viz import plot_evoked
--> 889 return plot_evoked(
890 self,
891 picks=picks,
892 exclude=exclude,
893 unit=unit,
894 show=show,
895 ylim=ylim,
896 proj=proj,
897 xlim=xlim,
898 hline=hline,
899 units=units,
900 scalings=scalings,
901 titles=titles,
902 axes=axes,
903 gfp=gfp,
904 window_title=window_title,
905 spatial_colors=spatial_colors,
906 zorder=zorder,
907 selectable=selectable,
908 noise_cov=noise_cov,
909 time_unit=time_unit,
910 sphere=sphere,
911 highlight=highlight,
912 verbose=verbose,
913 )
File <decorator-gen-154>:12, in plot_evoked(evoked, picks, exclude, unit, show, ylim, xlim, proj, hline, units, scalings, titles, axes, gfp, window_title, spatial_colors, zorder, selectable, noise_cov, time_unit, sphere, highlight, verbose)
File /opt/mne/python/mne/viz/evoked.py:1269, in plot_evoked(evoked, picks, exclude, unit, show, ylim, xlim, proj, hline, units, scalings, titles, axes, gfp, window_title, spatial_colors, zorder, selectable, noise_cov, time_unit, sphere, highlight, verbose)
1041 @verbose_static(
1042 "picks_all",
1043 "evoked_ylim_plot",
(...) 1073 verbose=None,
1074 ):
1075 """Plot evoked data using butterfly plots.
1076
1077 Left click to a line shows the channel name. Selecting an area by clicking
(...) 1267 .. versionadded:: 1.13.0
1268 """ # noqa: E501
-> 1269 return _plot_evoked(
1270 evoked=evoked,
1271 picks=picks,
1272 exclude=exclude,
1273 unit=unit,
1274 show=show,
1275 ylim=ylim,
1276 proj=proj,
1277 xlim=xlim,
1278 hline=hline,
1279 units=units,
1280 scalings=scalings,
1281 titles=titles,
1282 axes=axes,
1283 plot_type="butterfly",
1284 gfp=gfp,
1285 window_title=window_title,
1286 spatial_colors=spatial_colors,
1287 selectable=selectable,
1288 zorder=zorder,
1289 noise_cov=noise_cov,
1290 time_unit=time_unit,
1291 sphere=sphere,
1292 highlight=highlight,
1293 )
File /opt/mne/python/mne/viz/evoked.py:467, in _plot_evoked(evoked, picks, exclude, unit, show, ylim, proj, xlim, hline, units, scalings, titles, axes, plot_type, cmap, gfp, window_title, spatial_colors, selectable, zorder, noise_cov, colorbar, mask, mask_style, mask_cmap, mask_alpha, time_unit, show_names, group_by, sphere, highlight, draw)
464 evoked = evoked.reconstruct_proj(origin=sphere[:3])
466 if plot_type == "butterfly":
--> 467 _plot_lines(
468 evoked.data,
469 info,
470 picks,
471 fig,
472 axes,
473 spatial_colors,
474 unit,
475 units,
476 scalings,
477 hline,
478 gfp,
479 types,
480 zorder,
481 xlim,
482 ylim,
483 times,
484 bad_ch_idx,
485 titles,
486 ch_types_used,
487 selectable,
488 False,
489 line_alpha=1.0,
490 nave=evoked.nave,
491 time_unit=time_unit,
492 sphere=sphere,
493 highlight=highlight,
494 )
495 plt.setp(axes, xlabel=f"Time ({time_unit})")
497 elif plot_type == "image":
File /opt/mne/python/mne/viz/evoked.py:917, in _plot_lines(data, info, picks, fig, axes, spatial_colors, unit, units, scalings, hline, gfp, types, zorder, xlim, ylim, times, bad_ch_idx, titles, ch_types_used, selectable, psd, line_alpha, nave, time_unit, sphere, highlight, linewidth, label_props)
914 line.set_xdata([event.time, event.time])
915 blit_manager.update()
--> 917 subscribe(fig, "time_change", on_time_change)
919 return lines
File <decorator-gen-140>:12, in subscribe(fig, event_name, callback, verbose)
File /opt/mne/python/mne/viz/ui_events.py:447, in subscribe(fig, event_name, callback, verbose)
424 @verbose_static()
425 def subscribe(fig, event_name, callback, *, verbose=None):
426 """Subscribe to an event on a figure's event channel.
427
428 Parameters
(...) 445 is published.
446 """
--> 447 channel = _get_event_channel(fig)
448 logger.debug(f"Subscribing to channel {channel}")
449 if event_name not in channel:
File /opt/mne/python/mne/viz/ui_events.py:368, in _get_event_channel(fig)
360 weakfig = weakref.ref(fig)
362 # When the figure is closed, its associated event channel should be
363 # deleted. This is a good time to set this up.
364
365 # Hook up the above callback function to the close event of the figure
366 # window. How this is done exactly depends on the various figure types
367 # MNE-Python has.
--> 368 _validate_type(fig, (matplotlib.figure.Figure, Brain, EvokedField), "fig")
369 this_delete_event_channel = partial(_delete_event_channel, weakfig=weakfig)
370 if isinstance(fig, matplotlib.figure.Figure):
File /opt/mne/python/mne/utils/check.py:709, in _validate_type(item, types, item_name, type_name, extra)
707 _item_name = "Item" if item_name is None else item_name
708 _item_type = type(item) if item is not None else item
--> 709 raise TypeError(
710 f"{_item_name} must be an instance of {type_name}{extra}, "
711 f"got {_item_type} instead."
712 )
TypeError: fig must be an instance of Figure, Brain, or EvokedField, got <class 'matplotlib.figure.SubFigure'> instead.
Additional information
Platform Linux-7.0.0-38-generic-x86_64-with-glibc2.43 (X11)
Python 3.14.10 | packaged by conda-forge | (main, Oct 26 2026, 11:35:38) [GCC 15.3.0]
Executable /opt/mne/pixi/.pixi/envs/default/bin/python3.14
CPU Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz (16 cores)
Memory 125.7 GiB
Core
├☑ mne 1.14.0.dev121+gf3e0db815 (development, latest release is 1.13.2)
├☑ numpy 2.5.3 (OpenBLAS 0.3.34 with 4 threads via pthreads)
├☑ scipy 1.17.1
└☑ matplotlib 3.11.1 (backend=qtagg)
Numerical (optional)
├☑ scikit-learn 1.9.1
├☑ threadpoolctl 3.6.0
├☑ numba 0.67.0
├☑ nibabel 5.4.2
├☑ nilearn 0.14.1
├☑ dipy 1.12.1
├☑ openmeeg 2.5.16
├☑ jamica 0.3.0
├☑ cupy 14.2.0
├☑ pandas 3.0.5
├☑ h5io 0.2.5
├☑ h5py 3.16.0
└☐ unavailable python-picard
Visualization (optional)
├☑ pyvista 0.48.4 (OpenGL 4.5.0 NVIDIA 595.99.02 via NVIDIA GeForce RTX 2060/PCIe/SSE2)
├☑ pyvistaqt 0.13.1
├☑ vtk 9.6.2
├☑ qtpy 2.4.3 (PySide6=6.11.2)
├☑ ipympl 0.10.0
├☑ pyqtgraph 0.14.0
├☑ mne-qt-browser 0.8.0.dev12+g34026bf8e
├☑ ipywidgets 8.1.9
├☑ trame 3.13.2
├☑ trame_client 3.13.2
├☑ trame_server 3.12.5
├☑ trame_pyvista 0.1.7
├☑ trame_vtk 2.11.16
└☑ trame_vuetify 3.2.5
Ecosystem (optional)
├☑ mne-bids 0.21.0.dev6+gcd32e35ff
├☑ mne-nirs 0.8.0.dev17+g1a3ede196
├☑ mne-connectivity 0.10.0.dev45+g03495d310
├☑ mne-icalabel 0.9.0
├☑ mne-bids-pipeline 1.11.0.dev86+ge2a34cf44.d20261020
├☑ autoreject 0.5.0
├☑ neo 0.14.5
├☑ eeglabio 0.1.3
├☑ edfio 0.4.17.dev4+g74788f24c
├☑ curryreader 0.1.2
├☑ mffpy 0.11.0
├☑ pybv 0.8.1
├☑ pymef 1.4.8
├☑ antio 0.7.1
├☑ defusedxml 0.7.1
└☐ unavailable mne-features
- 主要语言
- Python
- 星标
- 3.6k
- 派生
- 1.6k
- 平均合并
- 1 天 18 小时
- 30 天内合并 PR
- 74
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
mne-tools/mne-python 的其他 Issue
-
`output="complex"` for Welch method should only allow `average=None`可能已有人在做 关联的 PR 仍在进行中或已合并。 未关闭BUG
难度 2/5 1-3 小时 新手友好度 74/100
mne-tools/mne-python#14495 ·
维护者通常 1 天内回复
-
Incorrect scaling of complex multitaper coefficients with `normalization="full"`可能已有人在做 关联的 PR 仍在进行中或已合并。 未关闭BUG
难度 2/5 1-3 小时 新手友好度 74/100
mne-tools/mne-python#14493 ·
维护者通常 1 天内回复
-
`compute_average_dev_head_t` averages head rotation with squared time weights (translation uses linear weights)可能已有人在做 关联的 PR 仍在进行中或已合并。 未关闭BUG
难度 2/5 1-3 小时 新手友好度 66/100
mne-tools/mne-python#14478 · 2 条评论 ·
维护者通常 1 天内回复
-
`mne.stats.f_oneway` returns wrong (even negative) F for small integer dtypes可能已有人在做 @darshpatel1052 于 2 天前认领。 未关闭BUG
难度 2/5 1-3 小时 新手友好度 82/100
mne-tools/mne-python#14477 · 2 条评论 ·
维护者通常 1 天内回复
-
ENH: Add `description` filter parameter to `Raw.crop_by_annotations()`可能已有人在做 @aman-coder03 于 212 天前认领。 未关闭ENH
难度 2/5 1-3 小时 新手友好度 72/100
mne-tools/mne-python#13743 · 2 条评论 ·
维护者通常 1 天内回复
查看 mne-tools/mne-python 的全部 Issue
相似的 Issue
-
follow-up needs-triage S3: minor
难度 2/5 1-3 小时 新手友好度 72/100
manaflow-ai/cmux#36856 · 1 条评论 ·
维护者通常 1 天内回复
-
documentation good first issue help wanted
难度 1/5 1-3 小时 新手友好度 90/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 73/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
-
Shell framework build fails at "copy the shader libraries": the iOS shader libraries are now one file b-<chain>.img可能已有人在做 @xiaofeng-han 今天认领。 未关闭build ios
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复