# 'NoneType' object has no attribute '\_widget

**URL:** <https://mne.discourse.group/t/nonetype-object-has-no-attribute-widget/7751>\
**Category:** Support & Discussions\
**Tags:** visualization\
**Created:** [October 26, 2023, 1:48pm UTC](https://mne.discourse.group/t/nonetype-object-has-no-attribute-widget/7751 "2023-10-26T13:48:03Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jiahui](https://avatars.discourse-cdn.com/v4/letter/j/a88e57/32.png) [@Jiahui](https://mne.discourse.group/u/Jiahui)\
**Post date:** [October 26, 2023, 1:48pm UTC](https://mne.discourse.group/t/nonetype-object-has-no-attribute-widget/7751/1 "2023-10-26T13:48:03Z")

</div>

- MNE version: e.g. 1.3.0
- operating system: Windows 10

Hi there, I am now using the following code

```python
brain = plot_glm_surface_projection(raw_haemo.copy().pick("hbo").pick(significant_channels), model_df, colorbar=True)

brain.add_sensors(raw_haemo.info, trans='fsaverage', fnirs=['channels', 'pairs', 'sources', 'detectors'])

```

to plot my significant result on scalp, but I always get this error. I have tried different types of backend, including: qt, tk, webAgg, notebook etc., none of them are working, I got the same error message with this function. It would be super helpful if you could provide me the solution how to fix it! Thank you.

```python
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[47], line 3
      1 # Plot the projection and sensor locations
      2 get_ipython().run_line_magic('matplotlib', 'inline')
----> 3 brain = plot_glm_surface_projection(raw_haemo.copy().pick("hbo").pick(significant_channels), model_df, colorbar=True)
      5 brain.add_sensors(raw_haemo.info, trans='fsaverage', fnirs=['channels', 'pairs', 'sources', 'detectors'])
      7 # mark the premotor cortex in red

File <decorator-gen-610>:10, in plot_glm_surface_projection(inst, statsmodel_df, picks, value, background, figure, clim, mode, colormap, surface, hemi, size, view, colorbar, distance, subjects_dir, src, verbose)

File D:\Anaconda\envs\fnirs\lib\site-packages\mne_nirs\visualisation\_plot_GLM_surface_projection.py:97, in plot_glm_surface_projection(inst, statsmodel_df, picks, value, background, figure, clim, mode, colormap, surface, hemi, size, view, colorbar, distance, subjects_dir, src, verbose)
     90 raise RuntimeError('MNE data structure does not match dataframe '
     91 f'results.\nMNE = {info.ch_names}.\n'
     92 f'GLM = {list(statsmodel_df["ch_name"].values)}')
     94 ea = EvokedArray(np.tile(statsmodel_df[value].values.T, (1, 1)).T,
     95 info.copy())
---> 97 return _plot_3d_evoked_array(inst, ea, picks=picks,
     98 value=value,
     99 background=background, figure=figure,
    100 clim=clim,
    101 mode=mode, colormap=colormap,
    102 surface=surface, hemi=hemi, size=size,
    103 view=view, colorbar=colorbar,
    104 distance=distance,
    105 subjects_dir=subjects_dir, src=src,
    106 verbose=verbose)

File D:\Anaconda\envs\fnirs\lib\site-packages\mne_nirs\visualisation\_plot_GLM_surface_projection.py:142, in _plot_3d_evoked_array(inst, ea, picks, value, background, figure, clim, mode, colormap, surface, hemi, size, view, colorbar, distance, subjects_dir, src, verbose)
    139 stc = stc_near_sensors(picks=picks, **kwargs, verbose=verbose)
    141 # Produce brain plot
--> 142 brain = stc.plot(src=src, subjects_dir=subjects_dir, hemi=hemi,
    143 surface=surface, initial_time=0, clim=clim, size=size,
    144 colormap=colormap, figure=figure, background=background,
    145 colorbar=colorbar, verbose=verbose)
    146 if view is not None:
    147 brain.show_view(view)

File D:\Anaconda\envs\fnirs\lib\site-packages\mne\source_estimate.py:650, in _BaseSourceEstimate.plot(self, subject, surface, hemi, colormap, time_label, smoothing_steps, transparent, alpha, time_viewer, subjects_dir, figure, views, colorbar, clim, cortex, size, background, foreground, initial_time, time_unit, backend, spacing, title, show_traces, src, volume_options, view_layout, add_data_kwargs, brain_kwargs, verbose)
    639 @copy_function_doc_to_method_doc(plot_source_estimates)
    640 def plot(self, subject=None, surface='inflated', hemi='lh',
    641 colormap='auto', time_label='auto', smoothing_steps=10,
   (...)
    648 src=None, volume_options=1., view_layout='vertical',
    649 add_data_kwargs=None, brain_kwargs=None, verbose=None):
--> 650 brain = plot_source_estimates(
    651 self, subject, surface=surface, hemi=hemi, colormap=colormap,
    652 time_label=time_label, smoothing_steps=smoothing_steps,
    653 transparent=transparent, alpha=alpha, time_viewer=time_viewer,
    654 subjects_dir=subjects_dir, figure=figure, views=views,
    655 colorbar=colorbar, clim=clim, cortex=cortex, size=size,
    656 background=background, foreground=foreground,
    657 initial_time=initial_time, time_unit=time_unit, backend=backend,
    658 spacing=spacing, title=title, show_traces=show_traces,
    659 src=src, volume_options=volume_options, view_layout=view_layout,
    660 add_data_kwargs=add_data_kwargs, brain_kwargs=brain_kwargs,
    661 verbose=verbose)
    662 return brain

File <decorator-gen-125>:10, in plot_source_estimates(stc, subject, surface, hemi, colormap, time_label, smoothing_steps, transparent, alpha, time_viewer, subjects_dir, figure, views, colorbar, clim, cortex, size, background, foreground, initial_time, time_unit, backend, spacing, title, show_traces, src, volume_options, view_layout, add_data_kwargs, brain_kwargs, verbose)

File D:\Anaconda\envs\fnirs\lib\site-packages\mne\viz\_3d.py:1987, in plot_source_estimates(stc, subject, surface, hemi, colormap, time_label, smoothing_steps, transparent, alpha, time_viewer, subjects_dir, figure, views, colorbar, clim, cortex, size, background, foreground, initial_time, time_unit, backend, spacing, title, show_traces, src, volume_options, view_layout, add_data_kwargs, brain_kwargs, verbose)
   1985 else:
   1986 with use_3d_backend(backend):
-> 1987 return _plot_stc(
   1988 stc, overlay_alpha=alpha, brain_alpha=alpha,
   1989 vector_alpha=alpha, cortex=cortex, foreground=foreground,
   1990 size=size, scale_factor=None, show_traces=show_traces,
   1991 src=src, volume_options=volume_options,
   1992 view_layout=view_layout, add_data_kwargs=add_data_kwargs,
   1993 brain_kwargs=brain_kwargs, **kwargs)

File D:\Anaconda\envs\fnirs\lib\site-packages\mne\viz\_3d.py:2110, in _plot_stc(stc, subject, surface, hemi, colormap, time_label, smoothing_steps, subjects_dir, views, clim, figure, initial_time, time_unit, background, time_viewer, colorbar, transparent, brain_alpha, overlay_alpha, vector_alpha, cortex, foreground, size, scale_factor, show_traces, src, volume_options, view_layout, add_data_kwargs, brain_kwargs)
   2107 del kwargs
   2109 if time_viewer:
-> 2110 brain.setup_time_viewer(time_viewer=time_viewer,
   2111 show_traces=show_traces)
   2112 else:
   2113 brain.show()

File D:\Anaconda\envs\fnirs\lib\site-packages\mne\viz\_brain\_brain.py:523, in Brain.setup_time_viewer( ***failed resolving arguments*** )
    521 self._configure_menu()
    522 self._configure_status_bar()
--> 523 self._configure_playback()
    524 self._configure_help()
    525 # show everything at the end

File D:\Anaconda\envs\fnirs\lib\site-packages\mne\viz\_brain\_brain.py:1004, in Brain._configure_playback(self)
   1003 def _configure_playback(self):
-> 1004 self._renderer._playback_initialize(
   1005 func=self._play,
   1006 timeout=self.refresh_rate_ms,
   1007 value=self._data['time_idx'],
   1008 rng=[0, len(self._data['time']) - 1],
   1009 time_widget=self.widgets["time"],
   1010 play_widget=self.widgets["play"],
   1011 )

File D:\Anaconda\envs\fnirs\lib\site-packages\mne\viz\backends\_notebook.py:1227, in _IpyPlayback._playback_initialize(self, func, timeout, value, rng, time_widget, play_widget)
   1225 play.max = rng[1]
   1226 play.value = value
-> 1227 slider = time_widget._widget
   1228 jsdlink((play, 'value'), (slider, 'value'))
   1229 jsdlink((slider, 'value'), (play, 'value'))

AttributeError: 'NoneType' object has no attribute '_widget

```

---

<div class="post-metadata">

**Author:** ![PuddleJumper2018](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/puddlejumper2018/32/2645_2.png) [@PuddleJumper2018](https://mne.discourse.group/u/PuddleJumper2018)\
**Post date:** [December 1, 2023, 6:17pm UTC](https://mne.discourse.group/t/nonetype-object-has-no-attribute-widget/7751/2 "2023-12-01T18:17:09Z")

</div>

Hi, I wonder if you’ve found the solution to this issue? I’m having the same problem working on Mac Sonoma with MNE 1.5.1.

---

<div class="post-metadata">

**Author:** ![drammock](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/drammock/32/4_2.png) [@drammock](https://mne.discourse.group/u/drammock)\
**Post date:** [December 1, 2023, 7:36pm UTC](https://mne.discourse.group/t/nonetype-object-has-no-attribute-widget/7751/3 "2023-12-01T19:36:36Z")

</div>

hi @Jiahui, I’ve edited your post to format the code and traceback as “preformatted text” so it’s easier to read.

If possible, can you (or @PuddleJumper2018) post a _complete_ reproducible example (i.e., one that any user could copy-paste into a python terminal and generate the same error you’re seeing)? Ideally it would use one of our [example datasets](https://mne.tools/stable/documentation/datasets.html) and include all necessary imports. Given the nature of @Jiahui’s example code above, I’m guessing the [fnirs motor](https://mne.tools/stable/documentation/datasets.html#fnirs-motor) dataset would be the place to start.

---

<div class="post-metadata">

**Author:** ![PuddleJumper2018](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/puddlejumper2018/32/2645_2.png) [@PuddleJumper2018](https://mne.discourse.group/u/PuddleJumper2018)\
**Post date:** [December 6, 2023, 4:15pm UTC](https://mne.discourse.group/t/nonetype-object-has-no-attribute-widget/7751/4 "2023-12-06T16:15:08Z")

</div>

Hi @drammock , I’ll do my best. I tried on tapping example from [here](https://mne.tools/mne-nirs/stable/auto_examples/general/plot_70_visualise_brain.html).

My OS: Sonoma 14.1.1  
MNE-NIRS version: 0.5.0  
MNE version: 1.5.1  
Python: 3.10.12  
Should probably add I work in conda environment.  
If there’s something I missed let me know.

Thank you!

```python
import numpy as np
import pandas as pd

import mne
from mne.preprocessing.nirs import optical_density, beer_lambert_law

import statsmodels.formula.api as smf

from mne_bids import BIDSPath, read_raw_bids, get_entity_vals
import mne_nirs

from mne_nirs.experimental_design import make_first_level_design_matrix
from mne_nirs.statistics import run_glm, statsmodels_to_results
from mne_nirs.channels import get_long_channels, get_short_channels
from mne_nirs.io.fold import fold_landmark_specificity
from mne_nirs.visualisation import plot_nirs_source_detector, plot_glm_surface_projection
from mne_nirs.datasets import fnirs_motor_group

def individual_analysis(bids_path, ID):

    raw_intensity = read_raw_bids(bids_path=bids_path, verbose=False)
    raw_intensity.annotations.delete(raw_intensity.annotations.description == '15.0')
     # sanitize event names
    raw_intensity.annotations.description[:] = [
        d.replace('/', '_') for d in raw_intensity.annotations.description]

    # Convert signal to haemoglobin and resample
    raw_od = optical_density(raw_intensity)
    raw_haemo = beer_lambert_law(raw_od, ppf=0.1)
    raw_haemo.resample(0.3)

    # Cut out just the short channels for creating a GLM repressor
    sht_chans = get_short_channels(raw_haemo)
    raw_haemo = get_long_channels(raw_haemo)

    # Create a design matrix
    design_matrix = make_first_level_design_matrix(raw_haemo, stim_dur=5.0)

    # Append short channels mean to design matrix
    design_matrix["ShortHbO"] = np.mean(sht_chans.copy().pick(picks="hbo").get_data(), axis=0)
    design_matrix["ShortHbR"] = np.mean(sht_chans.copy().pick(picks="hbr").get_data(), axis=0)

    # Run GLM
    glm_est = run_glm(raw_haemo, design_matrix)

    # Extract channel metrics
    cha = glm_est.to_dataframe()

    # Add the participant ID to the dataframes
    cha["ID"] = ID

    # Convert to uM for nicer plotting below.
    cha["theta"] = [t * 1.e6 for t in cha["theta"]]

    return raw_haemo, cha

# Get dataset details
root = fnirs_motor_group.data_path()
dataset = BIDSPath(root=root, task="tapping",
                   datatype="nirs", suffix="nirs", extension=".snirf")
subjects = get_entity_vals(root, 'subject')

df_cha = pd.DataFrame() # To store channel level results
for sub in subjects: # Loop from first to fifth subject

    # Create path to file based on experiment info
    bids_path = dataset.update(subject=sub)

    # Analyse data and return both ROI and channel results
    raw_haemo, channel = individual_analysis(bids_path, sub)

    # Append individual results to all participants
    df_cha = pd.concat([df_cha, channel], ignore_index=True)

ch_summary = df_cha.query("Condition in ['Tapping_Right']")
assert len(ch_summary)
ch_summary = ch_summary.query("Chroma in ['hbo']")
ch_model = smf.mixedlm("theta ~ -1 + ch_name", ch_summary,
                       groups=ch_summary["ID"]).fit(method='nm')
model_df = statsmodels_to_results(ch_model, order=raw_haemo.copy().pick("hbo").ch_names)

# Plot the projection and sensor locations
brain = plot_glm_surface_projection(raw_haemo.copy().pick("hbo"), model_df, colorbar=True)
brain.add_sensors(raw_haemo.info, trans='fsaverage', fnirs=['channels', 'pairs', 'sources', 'detectors'])

# mark the premotor cortex in green
aud_label = [label for label in labels_combined if label.name == 'Premotor Cortex-lh'][0]
brain.add_label(aud_label, borders=True, color='green')

# mark the auditory association cortex in blue
aud_label = [label for label in labels_combined if label.name == 'Auditory Association Cortex-lh'][0]
brain.add_label(aud_label, borders=True, color='blue')

brain.show_view(azimuth=160, elevation=60, distance=400)

```

Which seems to work:

```python
Using default location ~/mne_data for fnirs_motor_group...
Downloading file 'BIDS-NIRS-Tapping-master.zip' from 'https://github.com/rob-luke/BIDS-NIRS-Tapping/archive/v0.1.0.zip' to '/Users/xxxx/mne_data'.
0.00B [00:00, ?B/s]     
Unzipping contents of '/Users/xxxxx/mne_data/BIDS-NIRS-Tapping-master.zip' to '/Users/xxxxx/mne_data/./fNIRS-motor-group'
Download complete in 06s (41.7 MB)
Reading 0 ... 23238 = 0.000 ... 2974.464 secs...
Reading 0 ... 18877 = 0.000 ... 2416.256 secs...
Reading 0 ... 18874 = 0.000 ... 2415.872 secs...
Reading 0 ... 23120 = 0.000 ... 2959.360 secs...
Reading 0 ... 23006 = 0.000 ... 2944.768 secs...
/Users/xxxxx/anaconda3/envs/svwm/lib/python3.10/site-packages/mne_nirs/statistics/_statsmodels.py:114: FutureWarning: Series. __getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`
  sdf[jj, 1] = np.sqrt(model.scale) * model.bse[model.k_fe + jj]

```

Until I get error on plot\_glm\_surface\_projection here’s the error I get

```python
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Untitled-1.ipynb Cell 5 line 2
      1 # Plot the projection and sensor locations
----> 2 brain = plot_glm_surface_projection(raw_haemo.copy().pick("hbo"), model_df, colorbar=True)
      3 brain.add_sensors(raw_haemo.info, trans='fsaverage', fnirs=['channels', 'pairs', 'sources', 'detectors'])
      5 # mark the premotor cortex in green

File <decorator-gen-651>:10, in plot_glm_surface_projection(inst, statsmodel_df, picks, value, background, figure, clim, mode, colormap, surface, hemi, size, view, colorbar, distance, subjects_dir, src, verbose)

File ~/anaconda3/envs/svwm/lib/python3.10/site-packages/mne_nirs/visualisation/_plot_GLM_surface_projection.py:97, in plot_glm_surface_projection(inst, statsmodel_df, picks, value, background, figure, clim, mode, colormap, surface, hemi, size, view, colorbar, distance, subjects_dir, src, verbose)
     90 raise RuntimeError('MNE data structure does not match dataframe '
     91 f'results.\nMNE = {info.ch_names}.\n'
     92 f'GLM = {list(statsmodel_df["ch_name"].values)}')
     94 ea = EvokedArray(np.tile(statsmodel_df[value].values.T, (1, 1)).T,
     95 info.copy())
---> 97 return _plot_3d_evoked_array(inst, ea, picks=picks,
     98 value=value,
     99 background=background, figure=figure,
    100 clim=clim,
    101 mode=mode, colormap=colormap,
    102 surface=surface, hemi=hemi, size=size,
    103 view=view, colorbar=colorbar,
    104 distance=distance,
    105 subjects_dir=subjects_dir, src=src,
    106 verbose=verbose)

File ~/anaconda3/envs/svwm/lib/python3.10/site-packages/mne_nirs/visualisation/_plot_GLM_surface_projection.py:142, in _plot_3d_evoked_array(inst, ea, picks, value, background, figure, clim, mode, colormap, surface, hemi, size, view, colorbar, distance, subjects_dir, src, verbose)
    139 stc = stc_near_sensors(picks=picks, **kwargs, verbose=verbose)
    141 # Produce brain plot
--> 142 brain = stc.plot(src=src, subjects_dir=subjects_dir, hemi=hemi,
    143 surface=surface, initial_time=0, clim=clim, size=size,
    144 colormap=colormap, figure=figure, background=background,
    145 colorbar=colorbar, verbose=verbose)
    146 if view is not None:
    147 brain.show_view(view)

File ~/anaconda3/envs/svwm/lib/python3.10/site-packages/mne/source_estimate.py:740, in _BaseSourceEstimate.plot(self, subject, surface, hemi, colormap, time_label, smoothing_steps, transparent, alpha, time_viewer, subjects_dir, figure, views, colorbar, clim, cortex, size, background, foreground, initial_time, time_unit, backend, spacing, title, show_traces, src, volume_options, view_layout, add_data_kwargs, brain_kwargs, verbose)
    706 @copy_function_doc_to_method_doc(plot_source_estimates)
    707 def plot(
    708 self,
   (...)
    738 verbose=None,
    739 ):
--> 740 brain = plot_source_estimates(
    741 self,
    742 subject,
    743 surface=surface,
    744 hemi=hemi,
    745 colormap=colormap,
    746 time_label=time_label,
    747 smoothing_steps=smoothing_steps,
    748 transparent=transparent,
    749 alpha=alpha,
    750 time_viewer=time_viewer,
    751 subjects_dir=subjects_dir,
    752 figure=figure,
    753 views=views,
    754 colorbar=colorbar,
    755 clim=clim,
    756 cortex=cortex,
    757 size=size,
    758 background=background,
    759 foreground=foreground,
    760 initial_time=initial_time,
    761 time_unit=time_unit,
    762 backend=backend,
    763 spacing=spacing,
    764 title=title,
    765 show_traces=show_traces,
    766 src=src,
    767 volume_options=volume_options,
    768 view_layout=view_layout,
    769 add_data_kwargs=add_data_kwargs,
    770 brain_kwargs=brain_kwargs,
    771 verbose=verbose,
    772 )
    773 return brain

File <decorator-gen-130>:10, in plot_source_estimates(stc, subject, surface, hemi, colormap, time_label, smoothing_steps, transparent, alpha, time_viewer, subjects_dir, figure, views, colorbar, clim, cortex, size, background, foreground, initial_time, time_unit, backend, spacing, title, show_traces, src, volume_options, view_layout, add_data_kwargs, brain_kwargs, verbose)

File ~/anaconda3/envs/svwm/lib/python3.10/site-packages/mne/viz/_3d.py:2467, in plot_source_estimates(stc, subject, surface, hemi, colormap, time_label, smoothing_steps, transparent, alpha, time_viewer, subjects_dir, figure, views, colorbar, clim, cortex, size, background, foreground, initial_time, time_unit, backend, spacing, title, show_traces, src, volume_options, view_layout, add_data_kwargs, brain_kwargs, verbose)
   2465 else:
   2466 with use_3d_backend(backend):
-> 2467 return _plot_stc(
   2468 stc,
   2469 overlay_alpha=alpha,
   2470 brain_alpha=alpha,
   2471 vector_alpha=alpha,
   2472 cortex=cortex,
   2473 foreground=foreground,
   2474 size=size,
   2475 scale_factor=None,
   2476 show_traces=show_traces,
   2477 src=src,
   2478 volume_options=volume_options,
   2479 view_layout=view_layout,
   2480 add_data_kwargs=add_data_kwargs,
   2481 brain_kwargs=brain_kwargs,
   2482 **kwargs,
   2483 )

File ~/anaconda3/envs/svwm/lib/python3.10/site-packages/mne/viz/_3d.py:2637, in _plot_stc(stc, subject, surface, hemi, colormap, time_label, smoothing_steps, subjects_dir, views, clim, figure, initial_time, time_unit, background, time_viewer, colorbar, transparent, brain_alpha, overlay_alpha, vector_alpha, cortex, foreground, size, scale_factor, show_traces, src, volume_options, view_layout, add_data_kwargs, brain_kwargs)
   2634 del kwargs
   2636 if time_viewer:
-> 2637 brain.setup_time_viewer(time_viewer=time_viewer, show_traces=show_traces)
   2638 else:
   2639 brain.show()

File ~/anaconda3/envs/svwm/lib/python3.10/site-packages/mne/viz/_brain/_brain.py:600, in Brain.setup_time_viewer( ***failed resolving arguments*** )
    598 self._configure_menu()
    599 self._configure_status_bar()
--> 600 self._configure_playback()
    601 self._configure_help()
    602 # show everything at the end

File ~/anaconda3/envs/svwm/lib/python3.10/site-packages/mne/viz/_brain/_brain.py:1101, in Brain._configure_playback(self)
   1100 def _configure_playback(self):
-> 1101 self._renderer._playback_initialize(
   1102 func=self._play,
   1103 timeout=self.refresh_rate_ms,
   1104 value=self._data["time_idx"],
   1105 rng=[0, len(self._data["time"]) - 1],
   1106 time_widget=self.widgets["time"],
   1107 play_widget=self.widgets["play"],
   1108 )

File ~/anaconda3/envs/svwm/lib/python3.10/site-packages/mne/viz/backends/_notebook.py:1342, in _IpyPlayback._playback_initialize(self, func, timeout, value, rng, time_widget, play_widget)
   1340 play.max = rng[1]
   1341 play.value = value
-> 1342 slider = time_widget._widget
   1343 jsdlink((play, "value"), (slider, "value"))
   1344 jsdlink((slider, "value"), (play, "value"))

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

```

---

<div class="post-metadata">

**Author:** ![Sam54000](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/sam54000/32/2152_2.png) [@Sam54000](https://mne.discourse.group/u/Sam54000)\
**Post date:** [December 7, 2023, 1:36pm UTC](https://mne.discourse.group/t/nonetype-object-has-no-attribute-widget/7751/5 "2023-12-07T13:36:50Z")

</div>

Hi!  
I tried to reproduce the error but I got another error related to [freesurfer BEM dataset](https://mne.tools/stable/generated/mne.datasets.fetch_fsaverage.html#mne.datasets.fetch_fsaverage). The solution was to get this dataset. Can you try to add this line

```python
mne.datasets.fetch_fsaverage(subjects_dir=None,verbose=None)

```

below `# Get dataset details` in your example?  
Tell me what you get

---

<div class="post-metadata">

**Author:** ![drammock](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/drammock/32/4_2.png) [@drammock](https://mne.discourse.group/u/drammock)\
**Post date:** [December 7, 2023, 11:18pm UTC](https://mne.discourse.group/t/nonetype-object-has-no-attribute-widget/7751/6 "2023-12-07T23:18:27Z")

</div>

I also tried to reproduce (with current dev versions of MNE and MNE-NIRS) but I get a different error (about color limits not being monotonically increasing). But if I run this line instead:

```python
brain = plot_glm_surface_projection(
    raw_haemo.copy().pick("hbo"),
    model_df,
    colorbar=True,
    clim=dict(kind="percent", pos_lims=(90, 95, 99)), # <--- new line
)

```

then I get a plot:

 ![nirs](https://global.discourse-cdn.com/free1/uploads/mne/original/2X/e/e8a05d4d7010cf2fb004262243ab3505e962f09c.jpeg)

so… maybe the bug you’re seeing is already fixed in MNE-NIRS 0.6, or in MNE-Python \> 1.5.1?
