Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jupyter yields: 'NoneType' object has no attribute '_get_renderer' #11799

Closed
gael-vanderlee opened this issue Jul 13, 2023 · 16 comments
Closed
Labels

Comments

@gael-vanderlee
Copy link

gael-vanderlee commented Jul 13, 2023

Description of the problem

When trying to visualize mne data in a jupyter notebook, I get the following error:
'NoneType' object has no attribute '_get_renderer'

Steps to reproduce

So this is a strange one, everything was working perfectly and then I tried to get pyqt to work and now I can't have the normal matplotlib inline experience in jupyter notebooks.
The code runs fine and the plots show normally in a python script, but crashes in a jupyter notebook.
I was unable to reproduce it on the sample datasets, I'm providing a snippet of my dataset.

In a notebook, load the data and try to visualize evoked data.

import mne
raw = mne.io.read_raw_fif("demo-data.fif", preload=True)
events, event_dict = mne.events_from_annotations(raw)
epochs = mne.Epochs(
    raw,
    events,
    event_id=event_dict,
    tmin=-.5,
    tmax=1,
)
epochs[["Test Trial"]].average().plot()

Link to data

https://drive.google.com/file/d/1hAVBZaxg1ZVorf5djqbDB8mdhAtdkf5v/view?usp=sharing

Expected results

I should see the plot

Actual results

I get the following stack trace:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
File ~\AppData\Local\pypoetry\Cache\virtualenvs\pythonproject-lFcWie39-py3.10\lib\site-packages\IPython\core\formatters.py:340, in BaseFormatter.__call__(self, obj)
    338     pass
    339 else:
--> 340     return printer(obj)
    341 # Finally look for special method names
    342 method = get_real_method(obj, self.print_method)

File ~\AppData\Local\pypoetry\Cache\virtualenvs\pythonproject-lFcWie39-py3.10\lib\site-packages\IPython\core\pylabtools.py:152, in print_figure(fig, fmt, bbox_inches, base64, **kwargs)
    149     from matplotlib.backend_bases import FigureCanvasBase
    150     FigureCanvasBase(fig)
--> 152 fig.canvas.print_figure(bytes_io, **kw)
    153 data = bytes_io.getvalue()
    154 if fmt == 'svg':

File ~\AppData\Local\pypoetry\Cache\virtualenvs\pythonproject-lFcWie39-py3.10\lib\site-packages\matplotlib\backend_bases.py:2353, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
   2350         bbox_inches = bbox_inches.padded(pad_inches)
   2352     # call adjust_bbox to save only the given area
-> 2353     restore_bbox = _tight_bbox.adjust_bbox(
   2354         self.figure, bbox_inches, self.figure.canvas.fixed_dpi)
   2356     _bbox_inches_restore = (bbox_inches, restore_bbox)
   2357 else:

File ~\AppData\Local\pypoetry\Cache\virtualenvs\pythonproject-lFcWie39-py3.10\lib\site-packages\matplotlib\_tight_bbox.py:28, in adjust_bbox(fig, bbox_inches, fixed_dpi)
     26 locator = ax.get_axes_locator()
     27 if locator is not None:
---> 28     ax.apply_aspect(locator(ax, None))
     29 locator_list.append(locator)
     30 current_pos = ax.get_position(original=False).frozen()

File ~\AppData\Local\pypoetry\Cache\virtualenvs\pythonproject-lFcWie39-py3.10\lib\site-packages\mpl_toolkits\axes_grid1\inset_locator.py:73, in AnchoredLocatorBase.__call__(self, ax, renderer)
     71 def __call__(self, ax, renderer):
     72     self.axes = ax
---> 73     bbox = self.get_window_extent(renderer)
     74     px, py = self.get_offset(bbox.width, bbox.height, 0, 0, renderer)
     75     bbox_canvas = Bbox.from_bounds(px, py, bbox.width, bbox.height)

File ~\AppData\Local\pypoetry\Cache\virtualenvs\pythonproject-lFcWie39-py3.10\lib\site-packages\matplotlib\offsetbox.py:399, in OffsetBox.get_window_extent(self, renderer)
    396 def get_window_extent(self, renderer=None):
    397     # docstring inherited
    398     if renderer is None:
--> 399         renderer = self.figure._get_renderer()
    400     bbox = self.get_bbox(renderer)
    401     try:  # Some subclasses redefine get_offset to take no args.

AttributeError: 'NoneType' object has no attribute '_get_renderer'

Additional information

I've tried uninstalling and reinstalling all packages, adding and removing all visualization packages as well. I can get the plots to show on sample data in a notebook and even on my data but not in notebooks.
I've been able to reproduce it in a fresh project and in a fresh env, with only mne installed.

mne.sys_info()

Platform             Windows-10-10.0.19044-SP0
Python               3.10.4 (tags/v3.10.4:9d38120, Mar 23 2022, 23:13:41) [MSC v.1929 64 bit (AMD64)]
Executable           C:\Users\\AppData\Local\pypoetry\Cache\virtualenvs\pythonproject-lFcWie39-py3.10\Scripts\python.exe
CPU                  Intel64 Family 6 Model 140 Stepping 1, GenuineIntel (8 cores)
Memory               31.7 GB

Core
├☑ mne               1.4.2
├☑ numpy             1.25.1 (unknown linalg bindings (threadpoolctl module not found: No module named 'threadpoolctl'))
├☑ scipy             1.11.1
├☑ matplotlib        3.7.2 (backend=module://matplotlib_inline.backend_inline)
├☑ pooch             1.7.0
└☑ jinja2            3.1.2

Numerical (optional)
└☐ unavailable       sklearn, numba, nibabel, nilearn, dipy, openmeeg, cupy, pandas

Visualization (optional)
└☐ unavailable       pyvista, pyvistaqt, ipyvtklink, vtk, qtpy, ipympl, pyqtgraph, mne-qt-browser

Ecosystem (optional)
└☐ unavailable       mne-bids, mne-nirs, mne-features, mne-connectivity, mne-icalabel, mne-bids-pipeline

poetry show

(pythonproject-py3.10) C:\Users\\PycharmProjects\pythonProject>poetry show 
certifi            2023.5.7 Python package for providing Mozilla's CA Bundle.
charset-normalizer 3.2.0    The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet.
colorama           0.4.6    Cross-platform colored terminal text.
contourpy          1.1.0    Python library for calculating contours of 2D quadrilateral grids
cycler             0.11.0   Composable style cycles
decorator          5.1.1    Decorators for Humans
fonttools          4.41.0   Tools to manipulate font files
idna               3.4      Internationalized Domain Names in Applications (IDNA)
jinja2             3.1.2    A very fast and expressive template engine.
kiwisolver         1.4.4    A fast implementation of the Cassowary constraint solver
markupsafe         2.1.3    Safely add untrusted strings to HTML/XML markup.
matplotlib         3.7.2    Python plotting package
mne                1.4.2    MNE-Python project for MEG and EEG data analysis.
numpy              1.25.1   Fundamental package for array computing in Python
packaging          23.1     Core utilities for Python packages
pillow             10.0.0   Python Imaging Library (Fork)
platformdirs       3.8.1    A small Python package for determining appropriate platform-specific dirs, e.g. a "user data dir".
pooch              1.7.0    "Pooch manages your Python library's sample data files: it automatically downloads and stores them in a local directory, with support for versioning and corruption checks."
pyparsing          3.0.9    pyparsing module - Classes and methods to define and execute parsing grammars
python-dateutil    2.8.2    Extensions to the standard Python datetime module
requests           2.31.0   Python HTTP for Humans.
scipy              1.9.3    Fundamental algorithms for scientific computing in Python
six                1.16.0   Python 2 and 3 compatibility utilities
tqdm               4.65.0   Fast, Extensible Progress Meter
urllib3            2.0.3    HTTP library with thread-safe connection pooling, file post, and more.

Thanks in advance !

@welcome
Copy link

welcome bot commented Jul 13, 2023

Hello! 👋 Thanks for opening your first issue here! ❤️ We will try to get back to you soon. 🚴

@agramfort
Copy link
Member

agramfort commented Jul 13, 2023 via email

@gael-vanderlee
Copy link
Author

gael-vanderlee commented Jul 13, 2023

Yes, the issue persists whether it is there or not. I've tried %matplotlib notebook and it yields
blank figures

@drammock
Copy link
Member

Try installing ipympl

@gael-vanderlee
Copy link
Author

Issue persists with ipympl.
This might be linked to #8271

@drammock
Copy link
Member

drammock commented Jul 14, 2023

OK looking a bit closer, I'm confused by your poetry show output --- it doesn't list ipython or jupyter at all. Which I think means that you're running Jupyter from outside your poetry environment. I'm not very familiar with poetry but all kinds of things can go awry if you launch python/ipython from one conda/mamba env and then rely on installations of MNE, etc in another environment.

If it were me, I'd create a fresh env that has everything I need (python, ipython, jupyter, matplotlib, mne, ...) and make sure when starting the notebook that it's the version of jupyter in that environment (command line would be where jupyter; if you're launching from start menu or anaconda navigator then within the notebook itself you can do

import jupyter
print(jupyter.__file__)

to see the path to the jupyter installation being used. (sometimes Help > About can also indicate environment mismatches, but IIRC it only shows python/ipython version strings, not full executable paths)

You can do similar import X; print(X.__file__) tricks for other packages too, if necessary.

@gael-vanderlee
Copy link
Author

gael-vanderlee commented Jul 16, 2023

Indeed, it seems that I forgot to terminate the Jupyter notebook when I created a fresh environment for testing.
I went back to my project and environment (freshly created to pin down the issue), and managed to replicate the issue with only mne and jupyter (and their dependencies) installed. Here is the poetry show:

(test-py3.10) C:\Users\\PycharmProjects\test>poetry show 
anyio                     3.7.1    High level compatibility layer for multiple asynchronous event loop implementations
argon2-cffi               21.3.0   The secure Argon2 password hashing algorithm.
argon2-cffi-bindings      21.2.0   Low-level CFFI bindings for Argon2
arrow                     1.2.3    Better dates & times for Python
asttokens                 2.2.1    Annotate AST trees with source code positions
attrs                     23.1.0   Classes Without Boilerplate
backcall                  0.2.0    Specifications for callback functions passed in to an API
beautifulsoup4            4.12.2   Screen-scraping library
bleach                    6.0.0    An easy safelist-based HTML-sanitizing tool.
certifi                   2023.5.7 Python package for providing Mozilla's CA Bundle.
cffi                      1.15.1   Foreign Function Interface for Python calling C code.
charset-normalizer        3.2.0    The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet.
colorama                  0.4.6    Cross-platform colored terminal text.
comm                      0.1.3    Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc.
contourpy                 1.1.0    Python library for calculating contours of 2D quadrilateral grids
cycler                    0.11.0   Composable style cycles
debugpy                   1.6.7    An implementation of the Debug Adapter Protocol for Python
decorator                 5.1.1    Decorators for Humans
defusedxml                0.7.1    XML bomb protection for Python stdlib modules
exceptiongroup            1.1.2    Backport of PEP 654 (exception groups)
executing                 1.2.0    Get the currently executing AST node of a frame, and other information
fastjsonschema            2.17.1   Fastest Python implementation of JSON schema
fonttools                 4.41.0   Tools to manipulate font files
fqdn                      1.5.1    Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers
idna                      3.4      Internationalized Domain Names in Applications (IDNA)
ipykernel                 6.24.0   IPython Kernel for Jupyter
ipython                   8.14.0   IPython: Productive Interactive Computing
ipython-genutils          0.2.0    Vestigial utilities from IPython
ipywidgets                8.0.7    Jupyter interactive widgets
isoduration               20.11.0  Operations with ISO 8601 durations
jedi                      0.18.2   An autocompletion tool for Python that can be used for text editors.
jinja2                    3.1.2    A very fast and expressive template engine.
jsonpointer               2.4      Identify specific nodes in a JSON document (RFC 6901)
jsonschema                4.18.3   An implementation of JSON Schema validation for Python
jsonschema-specifications 2023.6.1 The JSON Schema meta-schemas and vocabularies, exposed as a Registry
jupyter                   1.0.0    Jupyter metapackage. Install all the Jupyter components in one go.
jupyter-client            8.3.0    Jupyter protocol implementation and client libraries
jupyter-console           6.6.3    Jupyter terminal console
jupyter-core              5.3.1    Jupyter core package. A base package on which Jupyter projects rely.
jupyter-events            0.6.3    Jupyter Event System library
jupyter-server            2.7.0    The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications.
jupyter-server-terminals  0.4.4    A Jupyter Server Extension Providing Terminals.
jupyterlab-pygments       0.2.2    Pygments theme using JupyterLab CSS variables
jupyterlab-widgets        3.0.8    Jupyter interactive widgets for JupyterLab
kiwisolver                1.4.4    A fast implementation of the Cassowary constraint solver
markupsafe                2.1.3    Safely add untrusted strings to HTML/XML markup.
matplotlib                3.7.2    Python plotting package
matplotlib-inline         0.1.6    Inline Matplotlib backend for Jupyter
mistune                   3.0.1    A sane and fast Markdown parser with useful plugins and renderers
mne                       1.4.2    MNE-Python project for MEG and EEG data analysis.
nbclassic                 1.0.0    Jupyter Notebook as a Jupyter Server extension.
nbclient                  0.8.0    A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor.
nbconvert                 7.6.0    Converting Jupyter Notebooks
nbformat                  5.9.1    The Jupyter Notebook format
nest-asyncio              1.5.6    Patch asyncio to allow nested event loops
notebook                  6.5.4    A web-based notebook environment for interactive computing
notebook-shim             0.2.3    A shim layer for notebook traits and config
numpy                     1.25.1   Fundamental package for array computing in Python
overrides                 7.3.1    A decorator to automatically detect mismatch when overriding a method.
packaging                 23.1     Core utilities for Python packages
pandocfilters             1.5.0    Utilities for writing pandoc filters in python
parso                     0.8.3    A Python Parser
pickleshare               0.7.5    Tiny 'shelve'-like database with concurrency support
pillow                    10.0.0   Python Imaging Library (Fork)
platformdirs              3.9.1    A small Python package for determining appropriate platform-specific dirs, e.g. a "user data dir".
pooch                     1.7.0    "Pooch manages your Python library's sample data files: it automatically downloads and stores them in a local directory, with support for versioning and corruption checks."
prometheus-client         0.17.1   Python client for the Prometheus monitoring system.
prompt-toolkit            3.0.39   Library for building powerful interactive command lines in Python
psutil                    5.9.5    Cross-platform lib for process and system monitoring in Python.
pure-eval                 0.2.2    Safely evaluate AST nodes without side effects
pycparser                 2.21     C parser in Python
pygments                  2.15.1   Pygments is a syntax highlighting package written in Python.
pyparsing                 3.0.9    pyparsing module - Classes and methods to define and execute parsing grammars
python-dateutil           2.8.2    Extensions to the standard Python datetime module
python-json-logger        2.0.7    A python library adding a json log formatter
pywin32                   306      Python for Window Extensions
pywinpty                  2.0.11   Pseudo terminal support for Windows from Python.
pyyaml                    6.0      YAML parser and emitter for Python
pyzmq                     25.1.0   Python bindings for 0MQ
qtconsole                 5.4.3    Jupyter Qt console
qtpy                      2.3.1    Provides an abstraction layer on top of the various Qt bindings (PyQt5/6 and PySide2/6).
tinycss2                  1.2.1    A tiny CSS parser
tornado                   6.3.2    Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.
tqdm                      4.65.0   Fast, Extensible Progress Meter
traitlets                 5.9.0    Traitlets Python configuration system
uri-template              1.3.0    RFC 6570 URI Template Processor
urllib3                   2.0.3    HTTP library with thread-safe connection pooling, file post, and more.
wcwidth                   0.2.6    Measures the displayed width of unicode strings in a terminal
webcolors                 1.13     A library for working with the color formats defined by HTML and CSS.
webencodings              0.5.1    Character encoding aliases for legacy web content
websocket-client          1.6.1    WebSocket client for Python with low level API options
widgetsnbextension        4.0.8    Jupyter interactive widgets for Jupyter Notebook
print(jupyter.__file__)

Correctly shows the path to my test env.
However, the issue persists. I was also able to replicate this issue in a brand new project on another machine (M1 Macbook Pro).

@drammock
Copy link
Member

ok... I notice PycharmProjects in your path. Are you running the jupyter notebook from within Pycharm, or is it launching from a terminal and running in a browser? If you are running the notebook within PyCharm can you try doing it in terminal/browser instead?

I don't personally use PyCharm but IIRC they do some things to wrap matplotlib (capture plots and stick them in a separate pane? or something...) maybe @hoechenberger or @cbrnr know?

@gael-vanderlee
Copy link
Author

gael-vanderlee commented Jul 17, 2023

I've tried both in Pycharm and in browser. I've also tried starting Jupyter from Pycharm and starting Jupyter from terminal. Same error every time.

@cbrnr
Copy link
Contributor

cbrnr commented Jul 17, 2023

I don't use PyCharm anymore, but this doesn't seem to be the issue. I don't use Jupyter notebooks either, but I could replicate your issue.

I could fix it with:

%matplotlib notebook

at the top of the notebook.

@hoechenberger
Copy link
Member

Hello, @cbrnr and I just hosted an MNE workshop where we used Jupyter Notebook and this problem did not occur. Users were asked to install MNE-Python through our installers. Can you try with one of our installers?

Also:

and then I tried to get pyqt to work

what does that mean, what did you do?

@drammock
Copy link
Member

argh. OK I'm back at my desk now and I can reproduce it locally (on linux, in terminal/browser). My next thought was "system python used as kernel" so I installed nb_conda_kernels and ran with the kernel from my new env, and I still get the error. Adding %matplotlib inline doesn't help.

I won't have more time today to debug unfortunately, but will try tomorrow unless someone beats me to it.

reproducer:

mamba create -n test mne jupyter nb_conda_kernels
jupyter notebook

then copy-paste this into the notebook:

%matplotlib inline
import mne
raw = mne.io.read_raw_fif("demo-data.fif", preload=True)
events, event_dict = mne.events_from_annotations(raw)
epochs = mne.Epochs(
    raw,
    events,
    event_id=event_dict,
    tmin=-.5,
    tmax=1,
)
epochs[["Test Trial"]].average().plot()

@cbrnr
Copy link
Contributor

cbrnr commented Jul 17, 2023

Try %matplotlib notebook instead of %matplotlib inline.

@drammock
Copy link
Member

If I force matplotlib=3.7.1 in my environment install then the problem goes away. Looks like we need to file an upstream bug. @Gvanderl can you confirm that it works with matplotlib 3.7.1 for you?

@gael-vanderlee
Copy link
Author

@drammock Yes it works with matplotlib 3.7.1 !
@cbrnr I was able to get matplotlib %notebook to work also on the condition that I downgrade tornado to version 6.1 and jupyter-client to 7.3.2

Jupyter probably updated when I installed pyqt, 3.7.2 was released 2 weeks ago. It seems that mne, matplotlib and jupyter don't mesh well with this latest update.

Thanks for helping me troubleshoot the issue, not sure if the issue lies with matplotlib or mne then. Either way, downgrading matplotlib works for now, I'm closing the issue.

@drammock
Copy link
Member

just a note that this Matplotlib bug is already fixed upstream and should land in version 3.7.3

issue: matplotlib/matplotlib#26287

pr: matplotlib/matplotlib#26291

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants