bsplot 0.0.9__tar.gz → 0.0.11__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. {bsplot-0.0.9 → bsplot-0.0.11}/MANIFEST.in +6 -0
  2. bsplot-0.0.11/PKG-INFO +131 -0
  3. bsplot-0.0.11/README.md +99 -0
  4. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/__init__.py +10 -1
  5. bsplot-0.0.11/bsplot/_glass_brain.py +151 -0
  6. bsplot-0.0.11/bsplot/ascii.py +1122 -0
  7. bsplot-0.0.11/bsplot/ascii_movie.py +805 -0
  8. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/brain.py +12 -9
  9. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/colors.py +135 -11
  10. bsplot-0.0.11/bsplot/data/glass_brain/NILEARN_LICENSE +26 -0
  11. bsplot-0.0.11/bsplot/data/glass_brain/README.md +34 -0
  12. bsplot-0.0.11/bsplot/data/glass_brain/brain_schematics_back.json +5626 -0
  13. bsplot-0.0.11/bsplot/data/glass_brain/brain_schematics_side.json +3565 -0
  14. bsplot-0.0.11/bsplot/data/glass_brain/brain_schematics_top.json +7339 -0
  15. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/data/surface.py +57 -1
  16. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/style.py +14 -0
  17. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/surface.py +84 -61
  18. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/volume.py +40 -6
  19. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot.egg-info/SOURCES.txt +12 -1
  20. {bsplot-0.0.9 → bsplot-0.0.11}/pyproject.toml +15 -1
  21. bsplot-0.0.11/tests/test_ascii.py +167 -0
  22. bsplot-0.0.11/tests/test_ascii_movie.py +319 -0
  23. bsplot-0.0.11/tests/test_nilearn_free.py +273 -0
  24. bsplot-0.0.9/PKG-INFO +0 -61
  25. bsplot-0.0.9/README.md +0 -35
  26. {bsplot-0.0.9 → bsplot-0.0.11}/LICENSE +0 -0
  27. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/anat.py +0 -0
  28. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/animate.py +0 -0
  29. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/bioicons.py +0 -0
  30. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/data/HCP_avg-SC.txt +0 -0
  31. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/data/MNI152.rh.pial +0 -0
  32. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/data/STN_lh.nii.gz +0 -0
  33. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/data/STN_rh.nii.gz +0 -0
  34. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/data/__init__.py +0 -0
  35. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/data/parcellations/HCP-MMP1.L.label.gii +0 -0
  36. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/data/parcellations/HCP-MMP1.R.label.gii +0 -0
  37. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/figure.py +0 -0
  38. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/graph/__init__.py +0 -0
  39. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/graph/edges.py +0 -0
  40. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/graph/flowchart.py +0 -0
  41. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/graph/layout.py +0 -0
  42. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/graph/network.py +0 -0
  43. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/graph/nodes.py +0 -0
  44. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/panels.py +0 -0
  45. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/__init__.py +0 -0
  46. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/_sync_from_zenodo_download.sh +0 -0
  47. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/batlowK.txt +0 -0
  48. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/batlowW.txt +0 -0
  49. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/cyclic/bamO.txt +0 -0
  50. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/cyclic/brocO.txt +0 -0
  51. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/cyclic/corkO.txt +0 -0
  52. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/cyclic/romaO.txt +0 -0
  53. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/cyclic/vikO.txt +0 -0
  54. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/diverging/bam.txt +0 -0
  55. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/diverging/berlin.txt +0 -0
  56. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/diverging/broc.txt +0 -0
  57. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/diverging/cork.txt +0 -0
  58. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/diverging/lisbon.txt +0 -0
  59. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/diverging/managua.txt +0 -0
  60. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/diverging/roma.txt +0 -0
  61. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/diverging/tofino.txt +0 -0
  62. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/diverging/vanimo.txt +0 -0
  63. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/diverging/vik.txt +0 -0
  64. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/multisequential/bukavu.txt +0 -0
  65. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/multisequential/fes.txt +0 -0
  66. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/multisequential/oleron.txt +0 -0
  67. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/naviaW.txt +0 -0
  68. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/sequential/acton.txt +0 -0
  69. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/sequential/bamako.txt +0 -0
  70. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/sequential/batlow.txt +0 -0
  71. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/sequential/bilbao.txt +0 -0
  72. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/sequential/buda.txt +0 -0
  73. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/sequential/davos.txt +0 -0
  74. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/sequential/devon.txt +0 -0
  75. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/sequential/glasgow.txt +0 -0
  76. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/sequential/grayC.txt +0 -0
  77. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/sequential/hawaii.txt +0 -0
  78. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/sequential/imola.txt +0 -0
  79. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/sequential/lajolla.txt +0 -0
  80. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/sequential/lapaz.txt +0 -0
  81. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/sequential/lipari.txt +0 -0
  82. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/sequential/navia.txt +0 -0
  83. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/sequential/nuuk.txt +0 -0
  84. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/sequential/oslo.txt +0 -0
  85. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/sequential/tokyo.txt +0 -0
  86. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/scientific_color_maps/sequential/turku.txt +0 -0
  87. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/streamlines.py +0 -0
  88. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/styles/black.mplstyle +0 -0
  89. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/styles/bss.mplstyle +0 -0
  90. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/styles/bwcomp.mplstyle +0 -0
  91. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/styles/nature.mplstyle +0 -0
  92. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/styles/template.mplstyle +0 -0
  93. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/styles/transparent.mplstyle +0 -0
  94. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/styles/tvbo.mplstyle +0 -0
  95. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/styles/white.mplstyle +0 -0
  96. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/templates.py +0 -0
  97. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/text.py +0 -0
  98. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/text2obj.py +0 -0
  99. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/timeseries.py +0 -0
  100. {bsplot-0.0.9 → bsplot-0.0.11}/bsplot/utils.py +0 -0
  101. {bsplot-0.0.9 → bsplot-0.0.11}/setup.cfg +0 -0
@@ -8,6 +8,12 @@ include bsplot/data/HCP_avg-SC.txt
8
8
  include bsplot/data/MNI152.rh.pial
9
9
  include bsplot/data/parcellations/HCP-MMP1.L.label.gii
10
10
  include bsplot/data/parcellations/HCP-MMP1.R.label.gii
11
+ # Glass-brain schematics vendored from nilearn (BSD-3-Clause). The JSON data
12
+ # AND the NILEARN_LICENSE must ship with the source distribution to satisfy the
13
+ # BSD licence's source-redistribution clause.
14
+ recursive-include bsplot/data/glass_brain *.json
15
+ include bsplot/data/glass_brain/NILEARN_LICENSE
16
+ include bsplot/data/glass_brain/README.md
11
17
  recursive-include bsplot/scientific_color_maps *
12
18
 
13
19
  prune docs
bsplot-0.0.11/PKG-INFO ADDED
@@ -0,0 +1,131 @@
1
+ Metadata-Version: 2.4
2
+ Name: bsplot
3
+ Version: 0.0.11
4
+ Summary: Plotting utilities for neuroscience: styles, palettes, surfaces, glass-brain, and panel helpers.
5
+ License-Expression: EUPL-1.2
6
+ Project-URL: Repository, https://github.com/leon-k-martin/bsplot
7
+ Requires-Python: >=3.9
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: matplotlib
11
+ Requires-Dist: pybtex
12
+ Requires-Dist: pyaml
13
+ Requires-Dist: scikit-image
14
+ Requires-Dist: scipy
15
+ Requires-Dist: nibabel
16
+ Requires-Dist: templateflow
17
+ Requires-Dist: graphviz
18
+ Requires-Dist: cmap
19
+ Provides-Extra: docs
20
+ Requires-Dist: quarto; extra == "docs"
21
+ Requires-Dist: quartodoc; extra == "docs"
22
+ Requires-Dist: griffe<1.0; extra == "docs"
23
+ Requires-Dist: jupyter-cache; extra == "docs"
24
+ Requires-Dist: cairosvg; extra == "docs"
25
+ Provides-Extra: projection
26
+ Requires-Dist: nilearn; extra == "projection"
27
+ Provides-Extra: tvbo
28
+ Requires-Dist: xarray; extra == "tvbo"
29
+ Requires-Dist: h5netcdf; extra == "tvbo"
30
+ Requires-Dist: h5py; extra == "tvbo"
31
+ Dynamic: license-file
32
+
33
+ <h1>
34
+ bsplot
35
+ <img src="docs/Usage/_output/anim1.gif" alt="Sagittal volume animation" height="55" align="right">
36
+ <img src="docs/Usage/_output/anim4.gif" alt="Surface rotation animation" height="55" align="right">
37
+ </h1>
38
+
39
+ Neuroscience plotting utilities built on **matplotlib**.
40
+
41
+ ## Overview
42
+
43
+ ![](docs/overview_figure.png)
44
+
45
+ - Brain surfaces and glass-brain visualizations
46
+ - Volume slicing with anatomical overlays
47
+ - Tractography rendering
48
+ - Publication-ready styles and scientific colormaps
49
+ - Panel helpers for multi-figure layouts
50
+ - Terminal (ASCII) surface backend — render a lit brain as text, with data overlays
51
+
52
+ ## Terminal (ASCII) rendering
53
+
54
+ Render a cortical surface straight to text — no matplotlib figure — as a lit
55
+ "surface of letters", with optional scalar overlays and parcellations in colour.
56
+ The default is the folded **pial** cortex, and the output adapts to wherever it
57
+ is drawn: **terminal** (ANSI colour), **notebook/website** (`color_mode="html"`,
58
+ auto-selected in a notebook), or **README/plain-text** (`color_mode="none"`).
59
+
60
+ ```python
61
+ import bsplot
62
+
63
+ bsplot.plot_surf_ascii() # pial template brain, lateral
64
+ bsplot.plot_surf_ascii(data=my_stat_map) # scalar overlay, colour-mapped
65
+ bsplot.plot_surf_ascii(parcellation=labels) # coloured regions
66
+ bsplot.plot_surf_ascii(width=140) # width = resolution knob
67
+ bsplot.plot_surf_ascii(background="light") # for a white background
68
+ ```
69
+
70
+ ```bash
71
+ bsplot-ascii # pial fsaverage, lateral (or: python -m bsplot.ascii)
72
+ bsplot-ascii --view top --hemi both # both hemispheres, dorsal
73
+ bsplot-ascii --html > brain.html # emit an HTML block
74
+ bsplot-ascii --sphere # offline demo (no download)
75
+ ```
76
+
77
+ See the [Terminal surface guide](docs/Usage/AsciiSurface.qmd) for ramps, colormaps, views, and resolution.
78
+
79
+ ### Timeseries — recordings and simulations
80
+
81
+ Surface colouring over time, cheap enough to stream live. The geometry is
82
+ prepared once, so each frame only re-colours the visible faces: **~0.7 ms/frame
83
+ (>1000 fps)** against ~184 ms for a full render.
84
+
85
+ ```python
86
+ mov = bsplot.AsciiSurfaceMovie(data, hemi="lh", view="lateral", width=80)
87
+ mov.play(fps=20) # live in the terminal
88
+ mov.to_gif("sim.gif"); mov.to_html("sim.html"); mov.to_cast("sim.cast")
89
+
90
+ # region-level data (TVB-style) mapped onto the surface by an atlas
91
+ bsplot.AsciiSurfaceMovie(data, atlas="DesikanKilliany", region_labels=labels)
92
+
93
+ # straight from a tvbo simulation result
94
+ bsplot.AsciiSurfaceMovie.from_tvbo("exp-3_result.h5", atlas="dk").play()
95
+ ```
96
+
97
+ ```bash
98
+ bsplot-ascii-movie data.npy --atlas Destrieux --fps 20 # play
99
+ bsplot-ascii-movie result.h5 --tvbo -o sim.gif # or export
100
+ ```
101
+
102
+ See the [Timeseries guide](docs/Usage/AsciiTimeseries/AsciiTimeseries.qmd).
103
+ Reading tvbo result files needs `pip install "bsplot[tvbo]"`.
104
+
105
+ ![alt text](docs/figures/brain_network_with_insets.png)
106
+
107
+
108
+ ## Installation
109
+
110
+ ```bash
111
+ pip install bsplot
112
+ ```
113
+
114
+ Two optional features — volume-to-surface projection (`project_vol_to_surf`)
115
+ and fsaverage cortical flatmaps (`get_flat_surface_geometry`) — additionally
116
+ need `nilearn`:
117
+
118
+ ```bash
119
+ pip install "bsplot[projection]"
120
+ ```
121
+
122
+ ## Dependencies
123
+
124
+ - `matplotlib`
125
+ - `nibabel`
126
+ - `scipy`
127
+ - `templateflow`
128
+ - `scikit-image`
129
+ - `nilearn` — optional, only for `project_vol_to_surf` and cortical flatmaps
130
+ (`pip install "bsplot[projection]"`)
131
+
@@ -0,0 +1,99 @@
1
+ <h1>
2
+ bsplot
3
+ <img src="docs/Usage/_output/anim1.gif" alt="Sagittal volume animation" height="55" align="right">
4
+ <img src="docs/Usage/_output/anim4.gif" alt="Surface rotation animation" height="55" align="right">
5
+ </h1>
6
+
7
+ Neuroscience plotting utilities built on **matplotlib**.
8
+
9
+ ## Overview
10
+
11
+ ![](docs/overview_figure.png)
12
+
13
+ - Brain surfaces and glass-brain visualizations
14
+ - Volume slicing with anatomical overlays
15
+ - Tractography rendering
16
+ - Publication-ready styles and scientific colormaps
17
+ - Panel helpers for multi-figure layouts
18
+ - Terminal (ASCII) surface backend — render a lit brain as text, with data overlays
19
+
20
+ ## Terminal (ASCII) rendering
21
+
22
+ Render a cortical surface straight to text — no matplotlib figure — as a lit
23
+ "surface of letters", with optional scalar overlays and parcellations in colour.
24
+ The default is the folded **pial** cortex, and the output adapts to wherever it
25
+ is drawn: **terminal** (ANSI colour), **notebook/website** (`color_mode="html"`,
26
+ auto-selected in a notebook), or **README/plain-text** (`color_mode="none"`).
27
+
28
+ ```python
29
+ import bsplot
30
+
31
+ bsplot.plot_surf_ascii() # pial template brain, lateral
32
+ bsplot.plot_surf_ascii(data=my_stat_map) # scalar overlay, colour-mapped
33
+ bsplot.plot_surf_ascii(parcellation=labels) # coloured regions
34
+ bsplot.plot_surf_ascii(width=140) # width = resolution knob
35
+ bsplot.plot_surf_ascii(background="light") # for a white background
36
+ ```
37
+
38
+ ```bash
39
+ bsplot-ascii # pial fsaverage, lateral (or: python -m bsplot.ascii)
40
+ bsplot-ascii --view top --hemi both # both hemispheres, dorsal
41
+ bsplot-ascii --html > brain.html # emit an HTML block
42
+ bsplot-ascii --sphere # offline demo (no download)
43
+ ```
44
+
45
+ See the [Terminal surface guide](docs/Usage/AsciiSurface.qmd) for ramps, colormaps, views, and resolution.
46
+
47
+ ### Timeseries — recordings and simulations
48
+
49
+ Surface colouring over time, cheap enough to stream live. The geometry is
50
+ prepared once, so each frame only re-colours the visible faces: **~0.7 ms/frame
51
+ (>1000 fps)** against ~184 ms for a full render.
52
+
53
+ ```python
54
+ mov = bsplot.AsciiSurfaceMovie(data, hemi="lh", view="lateral", width=80)
55
+ mov.play(fps=20) # live in the terminal
56
+ mov.to_gif("sim.gif"); mov.to_html("sim.html"); mov.to_cast("sim.cast")
57
+
58
+ # region-level data (TVB-style) mapped onto the surface by an atlas
59
+ bsplot.AsciiSurfaceMovie(data, atlas="DesikanKilliany", region_labels=labels)
60
+
61
+ # straight from a tvbo simulation result
62
+ bsplot.AsciiSurfaceMovie.from_tvbo("exp-3_result.h5", atlas="dk").play()
63
+ ```
64
+
65
+ ```bash
66
+ bsplot-ascii-movie data.npy --atlas Destrieux --fps 20 # play
67
+ bsplot-ascii-movie result.h5 --tvbo -o sim.gif # or export
68
+ ```
69
+
70
+ See the [Timeseries guide](docs/Usage/AsciiTimeseries/AsciiTimeseries.qmd).
71
+ Reading tvbo result files needs `pip install "bsplot[tvbo]"`.
72
+
73
+ ![alt text](docs/figures/brain_network_with_insets.png)
74
+
75
+
76
+ ## Installation
77
+
78
+ ```bash
79
+ pip install bsplot
80
+ ```
81
+
82
+ Two optional features — volume-to-surface projection (`project_vol_to_surf`)
83
+ and fsaverage cortical flatmaps (`get_flat_surface_geometry`) — additionally
84
+ need `nilearn`:
85
+
86
+ ```bash
87
+ pip install "bsplot[projection]"
88
+ ```
89
+
90
+ ## Dependencies
91
+
92
+ - `matplotlib`
93
+ - `nibabel`
94
+ - `scipy`
95
+ - `templateflow`
96
+ - `scikit-image`
97
+ - `nilearn` — optional, only for `project_vol_to_surf` and cortical flatmaps
98
+ (`pip install "bsplot[projection]"`)
99
+
@@ -1,13 +1,22 @@
1
1
  # Copyright © Charité Universitätsmedizin Berlin. This software is licensed under the terms of the European Union Public Licence (EUPL) version 1.2 or later.
2
2
  from os.path import abspath, dirname, join
3
3
 
4
- __version__ = "0.0.9"
4
+ __version__ = "0.0.11"
5
5
 
6
6
  ROOT = abspath(dirname(__file__))
7
7
  datadir = join(ROOT, "data")
8
8
 
9
9
  from . import volume, anat, animate, brain, colors, data, figure, streamlines, style, timeseries, surface, templates, utils
10
+ from . import ascii
10
11
  from .surface import vol_to_mesh, LabeledMeshes, project_vol_to_surf, plot_surf
12
+ from .ascii import (
13
+ AsciiGrid,
14
+ AsciiSurfaceRenderer,
15
+ plot_surf_ascii,
16
+ prepare_surf_ascii,
17
+ render_surf_ascii,
18
+ )
19
+ from .ascii_movie import AsciiSurfaceMovie, animate_surf_ascii, load_atlas_labels
11
20
  from .brain import glass_brain
12
21
  from .volume import plot_slice, apply_brain_mask
13
22
  from .colors import explore_colormaps
@@ -0,0 +1,151 @@
1
+ # Copyright © Charité Universitätsmedizin Berlin. This software is licensed under
2
+ # the terms of the European Union Public Licence (EUPL) version 1.2 or later.
3
+ #
4
+ # ---------------------------------------------------------------------------
5
+ # Third-party attribution (BSD-3-Clause)
6
+ #
7
+ # This module and the brain-schematic data files in ``bsplot/data/glass_brain/``
8
+ # are derived from nilearn 0.13.1 (https://github.com/nilearn/nilearn):
9
+ # * code: ``nilearn/plotting/glass_brain.py`` — the helpers ``_codes*``,
10
+ # ``_invert_color``, ``_get_mpl_patches`` and
11
+ # ``_get_json_and_transform`` below are adapted from it;
12
+ # * data: ``nilearn/plotting/glass_brain_files/brain_schematics_{side,back,
13
+ # top}.json`` — redistributed byte-for-byte unmodified.
14
+ #
15
+ # nilearn is distributed under the BSD 3-Clause License:
16
+ #
17
+ # Copyright (c) The nilearn developers.
18
+ # All rights reserved.
19
+ #
20
+ # The BSD 3-Clause conditions and disclaimer are reproduced verbatim in
21
+ # ``bsplot/data/glass_brain/NILEARN_LICENSE`` and retained here as that licence
22
+ # requires. Vendoring lets bsplot draw glass-brain outlines without depending on
23
+ # nilearn (whose private API previously supplied them).
24
+ # ---------------------------------------------------------------------------
25
+ """Vendored glass-brain schematic outlines (adapted from nilearn, BSD-3-Clause).
26
+
27
+ Provides drop-in replacements for the private ``nilearn.plotting.glass_brain``
28
+ functions that ``bsplot.volume.plot_brain_schematics`` relied on:
29
+ ``_get_json_and_transform`` and ``_get_mpl_patches``.
30
+ """
31
+ import pathlib
32
+
33
+ from matplotlib import colors, patches, transforms
34
+ from matplotlib.path import Path
35
+
36
+ # Directory holding the vendored ``brain_schematics_*.json`` files.
37
+ _FILES_DIR = pathlib.Path(__file__).resolve().parent / "data" / "glass_brain"
38
+
39
+ # Only the views used by bsplot are vendored (sagittal/coronal/horizontal ->
40
+ # x/y/z -> side/back/top). ``l``/``r`` map to the side view, mirroring nilearn.
41
+ _DIRECTION_TO_VIEW_NAME = {
42
+ "x": "side",
43
+ "y": "back",
44
+ "z": "top",
45
+ "l": "side",
46
+ "r": "side",
47
+ }
48
+
49
+ # Affine parameters hand-tuned by nilearn to align each schematic with the MNI
50
+ # template, in matplotlib ``Affine2D.from_values`` order (a, b, c, d, e, f).
51
+ _DIRECTION_TO_TRANSFORM_PARAMS = {
52
+ "x": [0.38, 0, 0, 0.38, -108, -70],
53
+ "y": [0.39, 0, 0, 0.39, -73, -73],
54
+ "z": [0.36, 0, 0, 0.37, -71, -107],
55
+ "l": [0.38, 0, 0, 0.38, -108, -70],
56
+ "r": [0.38, 0, 0, 0.38, -108, -70],
57
+ }
58
+
59
+
60
+ def _codes_bezier(pts):
61
+ bezier_num = len(pts)
62
+ # Next two lines are meant to handle both Bezier 3 and 4
63
+ path_attr = f"CURVE{bezier_num}"
64
+ codes = [getattr(Path, path_attr)] * (bezier_num - 1)
65
+ return [Path.MOVETO, *codes]
66
+
67
+
68
+ def _codes_segment(pts):
69
+ # pts is accepted for API consistency with _codes_bezier
70
+ return [Path.MOVETO, Path.LINETO]
71
+
72
+
73
+ def _codes(atype, pts):
74
+ dispatch = {"bezier": _codes_bezier, "segment": _codes_segment}
75
+ return dispatch[atype](pts)
76
+
77
+
78
+ def _invert_color(color):
79
+ """Return inverted color.
80
+
81
+ If ``color`` is (R, G, B) it returns (1 - R, 1 - G, 1 - B). If ``color``
82
+ cannot be converted to a color it is returned unmodified.
83
+ """
84
+ try:
85
+ color_converter = colors.ColorConverter()
86
+ color_rgb = color_converter.to_rgb(color)
87
+ return tuple(1 - level for level in color_rgb)
88
+ except ValueError:
89
+ return color
90
+
91
+
92
+ def _get_mpl_patches(json_content, transform=None, invert_color=False, **kwargs):
93
+ """Walk over the json content and build a list of matplotlib patches."""
94
+ mpl_patches = []
95
+ kwargs_edgecolor = kwargs.pop("edgecolor", None)
96
+ kwargs_linewidth = kwargs.pop("linewidth", None)
97
+ for path in json_content["paths"]:
98
+ if kwargs_edgecolor is not None:
99
+ edgecolor = kwargs_edgecolor
100
+ else:
101
+ edgecolor = path["edgecolor"]
102
+ if invert_color:
103
+ edgecolor = _invert_color(edgecolor)
104
+ linewidth = kwargs_linewidth or path["linewidth"]
105
+ path_id = path["id"]
106
+
107
+ for item in path["items"]:
108
+ type = item["type"]
109
+ pts = item["pts"]
110
+ codes = _codes(type, pts)
111
+ path = Path(pts, codes)
112
+ patch = patches.PathPatch(
113
+ path,
114
+ edgecolor=edgecolor,
115
+ linewidth=linewidth,
116
+ facecolor="none",
117
+ gid=path_id,
118
+ transform=transform,
119
+ **kwargs,
120
+ )
121
+
122
+ mpl_patches.append(patch)
123
+
124
+ return mpl_patches
125
+
126
+
127
+ def _get_json_and_transform(direction):
128
+ """Return the vendored json path and its hand-tuned MNI affine transform.
129
+
130
+ Parameters
131
+ ----------
132
+ direction : {'x', 'y', 'z', 'l', 'r'}
133
+ Viewing direction. ``x``/``l``/``r`` -> side, ``y`` -> back,
134
+ ``z`` -> top.
135
+
136
+ Returns
137
+ -------
138
+ (pathlib.Path, matplotlib.transforms.Affine2D)
139
+ """
140
+ view_name = _DIRECTION_TO_VIEW_NAME.get(direction)
141
+ if view_name is None:
142
+ raise ValueError(
143
+ f"No glass brain view associated with direction '{direction}'. "
144
+ f"Possible directions are {list(_DIRECTION_TO_VIEW_NAME)}."
145
+ )
146
+
147
+ json_filename = _FILES_DIR / f"brain_schematics_{view_name}.json"
148
+ transform = transforms.Affine2D.from_values(
149
+ *_DIRECTION_TO_TRANSFORM_PARAMS[direction]
150
+ )
151
+ return json_filename, transform