Repository: nilearn/nilearn
Pull request #5234: [ENH] Refactor nilearn.plotting - create plotting.surface package 
Author: login: hndgzkn
Created: 2025-03-17T08:09:46Z | Merged: 2025-03-18T20:57:55Z

<!---
This is a suggested pull request template for nilearn.
It's designed to capture information we've found to be useful in reviewing pull requests.

If there is other information that would be helpful to include, please don't hesitate to add it!

Please make sure your pull request also follows the
[contribution guidelines](https://nilearn.github.io/stable/development.html#contribution-guidelines) that
will be enforced during the review process.
-->

<!-- Please indicate after the # which issue you're closing with this PR.
This is helpful for the maintainers AND will magically close the issue when this
pull request is merged!
If the PR closes multiple issues, includes "closes" before each one is listed.
https://help.github.com/articles/closing-issues-using-keywords -->
- Closes None

<!-- Please give a brief overview of what has changed in the PR.
If you're not sure what to write, consider it a note to the maintainers to indicate
what they should be looking for when they review the pull request. -->
Changes proposed in this pull request:

- move `plotting.surf_plotting` to `plotting.surface.surf_plotting`
- move `nilearn.plotting.html_surface` under `nilearn.plotting.surface`
- move corresponding tests under `nilearn.plotting.surface.tests`


> This PR only moves code between modules, the actual code is not changed.


Diff:
diff --git a/doc/changes/latest.rst b/doc/changes/latest.rst
index ba71320112e..fa39119fc68 100644
--- a/doc/changes/latest.rst
+++ b/doc/changes/latest.rst
@@ -83,4 +83,6 @@ Changes
 
 - :bdg-primary:`Doc` Add license information for Yeo 2011 atlas (:gh:`5195` by `Patrick Sadil`_).
 
+- :bdg-dark:`Code` Move ``nilearn.plotting.surf_plotting`` and ``nilearn.plotting.html_surface`` under ``nilearn.plotting.surface`` (:gh:`5234` by `Hande Gözükan`_).
+
 - :bdg-dark:`Code` Move ``nilearn.plotting.matrix_plotting`` under ``nilearn.plotting.matrix`` (:gh:`5240` by `Hande Gözükan`_).
diff --git a/nilearn/plotting/__init__.py b/nilearn/plotting/__init__.py
index 988fce725fa..0aa8fe7f433 100644
--- a/nilearn/plotting/__init__.py
+++ b/nilearn/plotting/__init__.py
@@ -14,7 +14,6 @@
 )
 from nilearn.plotting.html_connectome import view_connectome, view_markers
 from nilearn.plotting.html_stat_map import view_img
-from nilearn.plotting.html_surface import view_img_on_surf, view_surf
 from nilearn.plotting.img_comparison import (
     plot_bland_altman,
     plot_img_comparison,
@@ -39,12 +38,14 @@
     plot_event,
     plot_matrix,
 )
-from nilearn.plotting.surf_plotting import (
+from nilearn.plotting.surface import (
     plot_img_on_surf,
     plot_surf,
     plot_surf_contours,
     plot_surf_roi,
     plot_surf_stat_map,
+    view_img_on_surf,
+    view_surf,
 )
 
 __all__ = [
diff --git a/nilearn/plotting/surface/__init__.py b/nilearn/plotting/surface/__init__.py
new file mode 100644
index 00000000000..e16bcbe9f0c
--- /dev/null
+++ b/nilearn/plotting/surface/__init__.py
@@ -0,0 +1,18 @@
+from nilearn.plotting.surface.html_surface import view_img_on_surf, view_surf
+from nilearn.plotting.surface.surf_plotting import (
+    plot_img_on_surf,
+    plot_surf,
+    plot_surf_contours,
+    plot_surf_roi,
+    plot_surf_stat_map,
+)
+
+__all__ = [
+    "plot_img_on_surf",
+    "plot_surf",
+    "plot_surf_contours",
+    "plot_surf_roi",
+    "plot_surf_stat_map",
+    "view_img_on_surf",
+    "view_surf",
+]
diff --git a/nilearn/plotting/html_surface.py b/nilearn/plotting/surface/html_surface.py
similarity index 100%
rename from nilearn/plotting/html_surface.py
rename to nilearn/plotting/surface/html_surface.py
diff --git a/nilearn/plotting/surf_plotting.py b/nilearn/plotting/surface/surf_plotting.py
similarity index 99%
rename from nilearn/plotting/surf_plotting.py
rename to nilearn/plotting/surface/surf_plotting.py
index 14c79e76c2f..fb1aa08105e 100644
--- a/nilearn/plotting/surf_plotting.py
+++ b/nilearn/plotting/surface/surf_plotting.py
@@ -30,8 +30,8 @@
 )
 from nilearn.plotting.cm import mix_colormaps
 from nilearn.plotting.displays import PlotlySurfaceFigure
-from nilearn.plotting.html_surface import get_vertexcolor
 from nilearn.plotting.js_plotting_utils import colorscale
+from nilearn.plotting.surface.html_surface import get_vertexcolor
 from nilearn.surface import (
     load_surf_data,
     load_surf_mesh,
diff --git a/nilearn/plotting/surface/tests/__init__.py b/nilearn/plotting/surface/tests/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/nilearn/plotting/tests/test_html_surface.py b/nilearn/plotting/surface/tests/test_html_surface.py
similarity index 91%
rename from nilearn/plotting/tests/test_html_surface.py
rename to nilearn/plotting/surface/tests/test_html_surface.py
index 0d217b1901d..d9f433bfd32 100644
--- a/nilearn/plotting/tests/test_html_surface.py
+++ b/nilearn/plotting/surface/tests/test_html_surface.py
@@ -7,13 +7,18 @@
 from nilearn._utils.exceptions import DimensionError
 from nilearn.datasets import fetch_surf_fsaverage
 from nilearn.image import get_data
-from nilearn.plotting import html_surface
-from nilearn.plotting.html_surface import (
+from nilearn.plotting.js_plotting_utils import decode
+from nilearn.plotting.surface.html_surface import (
+    _fill_html_template,
+    _full_brain_info,
+    _one_mesh_info,
     colorscale,
+    full_brain_info,
     get_vertexcolor,
+    one_mesh_info,
     view_img_on_surf,
+    view_surf,
 )
-from nilearn.plotting.js_plotting_utils import decode
 from nilearn.plotting.tests.test_js_plotting_utils import (
     check_colors,
     check_html,
@@ -154,7 +159,7 @@ def test_one_mesh_info():
     mesh = fsaverage["pial_left"]
     surf_map = load_surf_data(fsaverage["sulc_left"])
     mesh = load_surf_mesh(mesh)
-    info = html_surface._one_mesh_info(
+    info = _one_mesh_info(
         surf_map, mesh, "90%", black_bg=True, bg_map=surf_map
     )
     assert {"_x", "_y", "_z", "_i", "_j", "_k"}.issubset(
@@ -176,13 +181,13 @@ def test_one_mesh_info():
         "to _one_mesh_info. Using the deprecated name will "
         "raise an error in release 0.13",
     ):
-        html_surface.one_mesh_info(surf_map, mesh)
+        one_mesh_info(surf_map, mesh)
 
 
 def test_full_brain_info(mni152_template_res_2):
     surfaces = datasets.fetch_surf_fsaverage()
 
-    info = html_surface._full_brain_info(mni152_template_res_2, surfaces)
+    info = _full_brain_info(mni152_template_res_2, surfaces)
     check_colors(info["colorscale"])
     assert {
         "pial_left",
@@ -213,14 +218,14 @@ def test_full_brain_info(mni152_template_res_2):
         "_full_brain_info. Using the deprecated name will raise an error "
         "in release 0.13",
     ):
-        html_surface.full_brain_info(mni152_template_res_2)
+        full_brain_info(mni152_template_res_2)
 
 
 def test_fill_html_template(tmp_path, mni152_template_res_2):
     fsaverage = fetch_surf_fsaverage()
     mesh = load_surf_mesh(fsaverage["pial_right"])
     surf_map = mesh.coordinates[:, 0]
-    info = html_surface._one_mesh_info(
+    info = _one_mesh_info(
         surf_map,
         fsaverage["pial_right"],
         "90%",
@@ -228,12 +233,12 @@ def test_fill_html_template(tmp_path, mni152_template_res_2):
         bg_map=fsaverage["sulc_right"],
     )
     info["title"] = None
-    html = html_surface._fill_html_template(info, embed_js=False)
+    html = _fill_html_template(info, embed_js=False)
     check_html(tmp_path, html)
     assert "jquery.min.js" in html.html
-    info = html_surface._full_brain_info(mni152_template_res_2)
+    info = _full_brain_info(mni152_template_res_2)
     info["title"] = None
-    html = html_surface._fill_html_template(info)
+    html = _fill_html_template(info)
     check_html(tmp_path, html)
     assert "* plotly.js (gl3d - minified) v1." in html.html
 
@@ -242,11 +247,11 @@ def test_view_surf(tmp_path, rng):
     fsaverage = fetch_surf_fsaverage()
     mesh = load_surf_mesh(fsaverage["pial_right"])
     surf_map = mesh.coordinates[:, 0]
-    html = html_surface.view_surf(
+    html = view_surf(
         fsaverage["pial_right"], surf_map, fsaverage["sulc_right"], "90%"
     )
     check_html(tmp_path, html, title="Surface plot")
-    html = html_surface.view_surf(
+    html = view_surf(
         fsaverage["pial_right"],
         surf_map,
         fsaverage["sulc_right"],
@@ -255,14 +260,12 @@ def test_view_surf(tmp_path, rng):
     )
     check_html(tmp_path, html, title="SOME_TITLE")
     assert "SOME_TITLE" in html.html
-    html = html_surface.view_surf(fsaverage["pial_right"])
+    html = view_surf(fsaverage["pial_right"])
     check_html(tmp_path, html)
     atlas = rng.integers(0, 10, size=len(mesh.coordinates))
-    html = html_surface.view_surf(
-        fsaverage["pial_left"], atlas, symmetric_cmap=False
-    )
+    html = view_surf(fsaverage["pial_left"], atlas, symmetric_cmap=False)
     check_html(tmp_path, html)
-    html = html_surface.view_surf(
+    html = view_surf(
         fsaverage["pial_right"],
         fsaverage["sulc_right"],
         threshold=None,
@@ -270,9 +273,9 @@ def test_view_surf(tmp_path, rng):
     )
     check_html(tmp_path, html)
     with pytest.raises(ValueError):
-        html_surface.view_surf(mesh, mesh.coordinates[::2, 0])
+        view_surf(mesh, mesh.coordinates[::2, 0])
     with pytest.raises(ValueError):
-        html_surface.view_surf(
+        view_surf(
             mesh, mesh.coordinates[:, 0], bg_map=mesh.coordinates[::2, 0]
         )
 
diff --git a/nilearn/plotting/tests/test_surf_plotting.py b/nilearn/plotting/surface/tests/test_surf_plotting.py
similarity index 99%
rename from nilearn/plotting/tests/test_surf_plotting.py
rename to nilearn/plotting/surface/tests/test_surf_plotting.py
index be01648ca39..1b991ba8a22 100644
--- a/nilearn/plotting/tests/test_surf_plotting.py
+++ b/nilearn/plotting/surface/tests/test_surf_plotting.py
@@ -25,7 +25,7 @@
 )
 from nilearn.plotting._utils import check_surface_plotting_inputs
 from nilearn.plotting.displays import PlotlySurfaceFigure, SurfaceFigure
-from nilearn.plotting.surf_plotting import (
+from nilearn.plotting.surface.surf_plotting import (
     MATPLOTLIB_VIEWS,
     _compute_facecolors_matplotlib,
     _get_ticks_matplotlib,
@@ -408,7 +408,7 @@ def test_plot_surf_contours_warning_hemi(in_memory_mesh):
 
 @pytest.mark.parametrize("full_view", EXPECTED_CAMERAS_PLOTLY)
 def test_get_view_plot_surf_plotly(full_view):
-    from nilearn.plotting.surf_plotting import (
+    from nilearn.plotting.surface.surf_plotting import (
         _get_camera_view_from_elevation_and_azimut,
         _get_camera_view_from_string_view,
     )
@@ -735,7 +735,7 @@ def test_add_contours_line_properties(plotly, key, value, surface_image_roi):
     ],
 )
 def test_check_view_is_valid(view, is_valid):
-    from nilearn.plotting.surf_plotting import _check_view_is_valid
+    from nilearn.plotting.surface.surf_plotting import _check_view_is_valid
 
     assert _check_view_is_valid(view) is is_valid
 
@@ -750,7 +750,9 @@ def test_check_view_is_valid(view, is_valid):
     ],
 )
 def test_check_hemisphere_is_valid(hemi, is_valid):
-    from nilearn.plotting.surf_plotting import _check_hemisphere_is_valid
+    from nilearn.plotting.surface.surf_plotting import (
+        _check_hemisphere_is_valid,
+    )
 
     assert _check_hemisphere_is_valid(hemi) is is_valid
 
@@ -780,7 +782,7 @@ def test_get_view_plot_surf_view_errors(hemi, view, f):
 
 
 def test_configure_title_plotly():
-    from nilearn.plotting.surf_plotting import _configure_title_plotly
+    from nilearn.plotting.surface.surf_plotting import _configure_title_plotly
 
     assert _configure_title_plotly(None, None) == {}
     assert _configure_title_plotly(None, 22) == {}
@@ -802,7 +804,7 @@ def test_configure_title_plotly():
     ],
 )
 def test_get_bounds(data, expected):
-    from nilearn.plotting.surf_plotting import _get_bounds
+    from nilearn.plotting.surface.surf_plotting import _get_bounds
 
     assert _get_bounds(data) == expected
     assert _get_bounds(data, vmin=0.2) == (0.2, expected[1])
diff --git a/nilearn/surface/surface.py b/nilearn/surface/surface.py
index b8f80655207..38eb4b0bed6 100644
--- a/nilearn/surface/surface.py
+++ b/nilearn/surface/surface.py
@@ -1127,9 +1127,6 @@ def check_mesh_is_fsaverage(mesh):
     """Check that :term:`mesh` data is either a :obj:`str`, or a :obj:`dict`
     with sufficient entries. Basically ensures that the mesh data is
     Freesurfer-like fsaverage data.
-
-    Used by plotting.surf_plotting.plot_img_on_surf and
-    plotting.html_surface._full_brain_info.
     """
     if isinstance(mesh, str):
         # avoid circular imports


Reviews:
user: login: Remi-Gau
body: so far so good

one thing that you may want to do, running a full build of the doc to make sure we don't get any import error on the exmaples

https://nilearn.github.io/dev/ci.html#continuous-integration
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-17T10:20:24Z
user: login: hndgzkn
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T11:26:23Z
user: login: Remi-Gau
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T11:33:33Z
user: login: hndgzkn
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T12:05:16Z
user: login: Remi-Gau
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T12:13:52Z
user: login: bthirion
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-17T22:11:17Z

Review comments:
diff_hunk: @@ -1119,8 +1119,8 @@ def check_mesh_is_fsaverage(mesh):
     with sufficient entries. Basically ensures that the mesh data is
     Freesurfer-like fsaverage data.
 
-    Used by plotting.surf_plotting.plot_img_on_surf and
-    plotting.html_surface._full_brain_info.
+    Used by plotting.surface.plot_img_on_surf and
+    plotting.surface.html_surface._full_brain_info.
path: nilearn/surface/surface.py
user: login: hndgzkn
body: `nilearn.surface.surface.check_mesh_is_fsaverage` is only used by `plotting.surface.plot_img_on_surf` and `plotting.surface.html_surface._full_brain_info`, shall I move it to `plotting.surface` package?
created_at: 2025-03-17T11:26:23Z
author_association: COLLABORATOR
diff_hunk: @@ -1119,8 +1119,8 @@ def check_mesh_is_fsaverage(mesh):
     with sufficient entries. Basically ensures that the mesh data is
     Freesurfer-like fsaverage data.
 
-    Used by plotting.surf_plotting.plot_img_on_surf and
-    plotting.html_surface._full_brain_info.
+    Used by plotting.surface.plot_img_on_surf and
+    plotting.surface.html_surface._full_brain_info.
path: nilearn/surface/surface.py
user: login: Remi-Gau
body: maybe not: we may still want to run this check even if we have not intention of plotting
created_at: 2025-03-17T11:33:33Z
author_association: COLLABORATOR
diff_hunk: @@ -1119,8 +1119,8 @@ def check_mesh_is_fsaverage(mesh):
     with sufficient entries. Basically ensures that the mesh data is
     Freesurfer-like fsaverage data.
 
-    Used by plotting.surf_plotting.plot_img_on_surf and
-    plotting.html_surface._full_brain_info.
+    Used by plotting.surface.plot_img_on_surf and
+    plotting.surface.html_surface._full_brain_info.
path: nilearn/surface/surface.py
user: login: hndgzkn
body: Shall I completely remove these two lines then? I'm not sure if it is a good idea to put such information in docstring.
created_at: 2025-03-17T12:05:16Z
author_association: COLLABORATOR
diff_hunk: @@ -1119,8 +1119,8 @@ def check_mesh_is_fsaverage(mesh):
     with sufficient entries. Basically ensures that the mesh data is
     Freesurfer-like fsaverage data.
 
-    Used by plotting.surf_plotting.plot_img_on_surf and
-    plotting.html_surface._full_brain_info.
+    Used by plotting.surface.plot_img_on_surf and
+    plotting.surface.html_surface._full_brain_info.
path: nilearn/surface/surface.py
user: login: Remi-Gau
body: yes definitely misleading
better to remove them
created_at: 2025-03-17T12:13:52Z
author_association: COLLABORATOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-03-17T08:18:43Z
body: 👋 @hndgzkn Thanks for creating a PR!

Until this PR is ready for review, you can include the [WIP] tag in its title, or leave it as a github draft.

Please make sure it is compliant with our [contributing guidelines](https://nilearn.github.io/stable/development.html#contribution-guidelines). In particular, be sure it checks the boxes listed below.
- [ ] PR has an interpretable title.
- [ ] PR links to Github issue with mention `Closes #XXXX` (see our documentation on [PR structure](https://nilearn.github.io/stable/development.html#pr-structure))
- [ ] Code is PEP8-compliant (see our documentation on [coding style](https://nilearn.github.io/stable/development.html#coding-style))
- [ ] Changelog or what's new entry in `doc/changes/latest.rst` (see our documentation on [PR structure](https://nilearn.github.io/stable/development.html#pr-structure))

For new features:
- [ ] There is at least one unit test per new function / class (see our documentation on [testing](https://nilearn.github.io/stable/development.html#tests))
- [ ] The new feature is demoed in at least one relevant example.

For bug fixes:
- [ ] There is at least one test that would fail under the original bug conditions.

We will review it as quick as possible, feel free to ping us with questions if needed.
author_association: CONTRIBUTOR
user: login: codecov[bot]
created_at: 2025-03-17T08:36:48Z
body: ## [Codecov](https://app.codecov.io/gh/nilearn/nilearn/pull/5234?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 96.69%. Comparing base [(`0cc98a9`)](https://app.codecov.io/gh/nilearn/nilearn/commit/0cc98a99a127600b92f104785cf233ce70dbf62f?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) to head [(`a30894a`)](https://app.codecov.io/gh/nilearn/nilearn/commit/a30894ad06a30adb206a742d6ec4d62a326dc40c?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn).
> Report is 2 commits behind head on main.

<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff           @@
##             main    #5234   +/-   ##
=======================================
  Coverage   96.69%   96.69%           
=======================================
  Files         262      263    +1     
  Lines       36397    36398    +1     
  Branches     3696     3696           
=======================================
+ Hits        35194    35195    +1     
  Misses        659      659           
  Partials      544      544           
```

| [Flag](https://app.codecov.io/gh/nilearn/nilearn/pull/5234/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) | Coverage Δ | |
|---|---|---|
| [macos-latest_3.10_plotting](https://app.codecov.io/gh/nilearn/nilearn/pull/5234/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) | `95.40% <100.00%> (+0.11%)` | :arrow_up: |
| [macos-latest_3.11_plotting](https://app.codecov.io/gh/nilearn/nilearn/pull/5234/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) | `95.40% <100.00%> (+0.11%)` | :arrow_up: |
| [macos-latest_3.12_plotting](https://app.codecov.io/gh/nilearn/nilearn/pull/5234/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) | `95.40% <100.00%> (+0.11%)` | :arrow_up: |
| [macos-latest_3.13_plotting](https://app.codecov.io/gh/nilearn/nilearn/pull/5234/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) | `95.40% <100.00%> (+0.11%)` | :arrow_up: |
| [macos-latest_3.9_min](https://app.codecov.io/gh/nilearn/nilearn/pull/5234/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) | `75.73% <0.00%> (+0.77%)` | :arrow_up: |
| [macos-latest_3.9_plot_min](https://app.codecov.io/gh/nilearn/nilearn/pull/5234/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) | `95.17% <100.00%> (+0.12%)` | :arrow_up: |
| [macos-latest_3.9_plotting](https://app.codecov.io/gh/nilearn/nilearn/pull/5234/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) | `95.40% <100.00%> (+0.11%)` | :arrow_up: |
| [ubuntu-latest_3.10_plotting](https://app.codecov.io/gh/nilearn/nilearn/pull/5234/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) | `95.42% <100.00%> (+0.11%)` | :arrow_up: |
| [ubuntu-latest_3.11_plotting](https://app.codecov.io/gh/nilearn/nilearn/pull/5234/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) | `95.42% <100.00%> (+0.11%)` | :arrow_up: |
| [ubuntu-latest_3.12_plotting](https://app.codecov.io/gh/nilearn/nilearn/pull/5234/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) | `95.42% <100.00%> (+0.11%)` | :arrow_up: |
| [ubuntu-latest_3.13_plotting](https://app.codecov.io/gh/nilearn/nilearn/pull/5234/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) | `95.42% <100.00%> (+0.11%)` | :arrow_up: |
| [ubuntu-latest_3.13_pre](https://app.codecov.io/gh/nilearn/nilearn/pull/5234/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) | `95.42% <100.00%> (+0.11%)` | :arrow_up: |
| [ubuntu-latest_3.9_plotting](https://app.codecov.io/gh/nilearn/nilearn/pull/5234/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) | `95.42% <100.00%> (+0.11%)` | :arrow_up: |
| [windows-latest_3.10_plotting](https://app.codecov.io/gh/nilearn/nilearn/pull/5234/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) | `95.40% <100.00%> (+0.11%)` | :arrow_up: |
| [windows-latest_3.11_plotting](https://app.codecov.io/gh/nilearn/nilearn/pull/5234/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) | `95.40% <100.00%> (+0.11%)` | :arrow_up: |
| [windows-latest_3.12_plotting](https://app.codecov.io/gh/nilearn/nilearn/pull/5234/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) | `95.40% <100.00%> (+0.11%)` | :arrow_up: |
| [windows-latest_3.13_plotting](https://app.codecov.io/gh/nilearn/nilearn/pull/5234/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) | `95.40% <100.00%> (+0.11%)` | :arrow_up: |
| [windows-latest_3.9_plotting](https://app.codecov.io/gh/nilearn/nilearn/pull/5234/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn) | `95.40% <100.00%> (+0.11%)` | :arrow_up: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn#carryforward-flags-in-the-pull-request-comment) to find out more.

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/nilearn/nilearn/pull/5234?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=nilearn).

<details><summary>🚀 New features to boost your workflow: </summary>

- ❄ [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- 📦 [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
author_association: NONE
user: login: Remi-Gau
created_at: 2025-03-17T10:21:09Z
body: it will take a long time to run (>1h30 hour) so run it once all your changes are in
author_association: COLLABORATOR
user: login: hndgzkn
created_at: 2025-03-17T10:36:45Z
body: > so far so good
> 
> one thing that you may want to do, running a full build of the doc to make sure we don't get any import error on the exmaples
> 
> https://nilearn.github.io/dev/ci.html#continuous-integration

I've added `[full doc]` at the end of the last commit message. Is that OK?
author_association: COLLABORATOR
user: login: Remi-Gau
created_at: 2025-03-17T11:10:28Z
body: > Is that OK?
when in doubt check the doc building workflow run:

in your case it is indeed currently building the whole doc:

![image](https://github.com/user-attachments/assets/0a70edf7-883a-4c40-9a2f-3a37ab011194)


https://github.com/nilearn/nilearn/actions/runs/13897281192/job/38880706790?pr=5234#step:4:25
author_association: COLLABORATOR
user: login: hndgzkn
created_at: 2025-03-17T11:13:30Z
body: > in your case it is indeed currently building the whole doc:
>
Ok, thanks!
author_association: COLLABORATOR
user: login: hndgzkn
created_at: 2025-03-17T11:29:00Z
body: I also think that I can rename `nilearn.plotting.surface.surf_plotting` to `nilearn.plotting.surface._surf_plotting` and `nilearn.plotting.surface.html_surface` to `nilearn.plotting.surface._html_surface` as public functions are exposed in `nilearn.surface.__init__`. Would that be ok @Remi-Gau ?
author_association: COLLABORATOR
user: login: Remi-Gau
created_at: 2025-03-17T11:35:52Z
body: > I also think that I can rename `nilearn.plotting.surface.surf_plotting` to `nilearn.plotting.surface._surf_plotting` and `nilearn.plotting.surface.html_surface` to `nilearn.plotting.surface._html_surface` as public functions are exposed in `nilearn.surface.__init__`. Would that be ok @Remi-Gau ?

I think this is pattern I have seen in sklearn and a few other places: make most module private and only expose things via the __init__

but it is not a common one in nilearn, so I am not sure we should do this without having a clear repo wide policy
author_association: COLLABORATOR
user: login: hndgzkn
created_at: 2025-03-17T11:44:15Z
body: > I think this is pattern I have seen in sklearn and a few other places: make most module private and only expose things via the **init**
> 
> but it is not a common one in nilearn, so I am not sure we should do this without having a clear repo wide policy

I thought it would comply with https://nilearn.github.io/stable/development.html#guidelines-for-private-functions . And from the users' point of view, it would be more clear what is expected to be used by the users and what not (and thus subject to change). 
author_association: COLLABORATOR
user: login: bthirion
created_at: 2025-03-17T22:10:45Z
body: The PR looks technically OK.
However, this adds a level of nesting which means a bit of complexity. Maybe this is needed now ?
author_association: MEMBER
user: login: hndgzkn
created_at: 2025-03-18T08:47:26Z
body: > The PR looks technically OK. However, this adds a level of nesting which means a bit of complexity. Maybe this is needed now ?

From users' point of view, it does not change anything actually. All imports are still from `nilearn.plotting`. 

From contributors' point of view, it increases depth (not that much actually, there is already nilearn.plotting.displays package at the same level) however it creates more coherent subpackages. It becomes simpler to identify which part of the code is related to which concept. 

I also think that, these subpackages should keep implementation details inside the package and not expose to outside so that if we change implementation, users will not be affected from that, and we do not need to have deprecation cycle each time.
author_association: COLLABORATOR
user: login: hndgzkn
created_at: 2025-03-18T09:08:12Z
body: > The PR looks technically OK. However, this adds a level of nesting which means a bit of complexity. Maybe this is needed now ?

Or if you prefer, we can discuss that in team meeting today. 
author_association: COLLABORATOR
user: login: Remi-Gau
created_at: 2025-03-18T09:11:33Z
body: > From contributors' point of view, it increases depth (not that much actually, there is already nilearn.plotting.displays package at the same level) however it creates more coherent subpackages. It becomes simpler to identify which part of the code is related to which concept.

I kind of agree that this helps quickly (literally at first sight) knowing which modules 'go together' rather than a flat listing of all the modules.
author_association: COLLABORATOR