bsplot 0.0.2__py3-none-any.whl

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 (89) hide show
  1. bsplot/__init__.py +23 -0
  2. bsplot/anat.py +55 -0
  3. bsplot/animate.py +194 -0
  4. bsplot/bioicons.py +777 -0
  5. bsplot/brain.py +188 -0
  6. bsplot/colors.py +1935 -0
  7. bsplot/data/HCP_avg-SC.txt +379 -0
  8. bsplot/data/MNI152.rh.pial +0 -0
  9. bsplot/data/STN_lh.nii.gz +0 -0
  10. bsplot/data/STN_rh.nii.gz +0 -0
  11. bsplot/data/__init__.py +22 -0
  12. bsplot/data/left_electrode.ply +257270 -0
  13. bsplot/data/parcellations/HCP-MMP1.L.label.gii +442 -0
  14. bsplot/data/parcellations/HCP-MMP1.R.label.gii +442 -0
  15. bsplot/data/parcellations/code/split_hcpmmp1.sh +4 -0
  16. bsplot/data/right_electrode.ply +257270 -0
  17. bsplot/data/surface.py +112 -0
  18. bsplot/data/tpl-MNI152NLin2009b_atlas-hcpmmp1_desc-ordered_dseg.nii.gz +0 -0
  19. bsplot/figure.py +177 -0
  20. bsplot/graph/__init__.py +31 -0
  21. bsplot/graph/edges.py +312 -0
  22. bsplot/graph/flowchart.py +762 -0
  23. bsplot/graph/layout.py +201 -0
  24. bsplot/graph/network.py +974 -0
  25. bsplot/graph/nodes.py +452 -0
  26. bsplot/panels.py +110 -0
  27. bsplot/scientific_color_maps/__init__.py +0 -0
  28. bsplot/scientific_color_maps/_sync_from_zenodo_download.sh +1 -0
  29. bsplot/scientific_color_maps/batlowK.txt +256 -0
  30. bsplot/scientific_color_maps/batlowW.txt +256 -0
  31. bsplot/scientific_color_maps/cyclic/bamO.txt +256 -0
  32. bsplot/scientific_color_maps/cyclic/brocO.txt +256 -0
  33. bsplot/scientific_color_maps/cyclic/corkO.txt +256 -0
  34. bsplot/scientific_color_maps/cyclic/romaO.txt +256 -0
  35. bsplot/scientific_color_maps/cyclic/vikO.txt +256 -0
  36. bsplot/scientific_color_maps/diverging/bam.txt +256 -0
  37. bsplot/scientific_color_maps/diverging/berlin.txt +256 -0
  38. bsplot/scientific_color_maps/diverging/broc.txt +256 -0
  39. bsplot/scientific_color_maps/diverging/cork.txt +256 -0
  40. bsplot/scientific_color_maps/diverging/lisbon.txt +256 -0
  41. bsplot/scientific_color_maps/diverging/managua.txt +256 -0
  42. bsplot/scientific_color_maps/diverging/roma.txt +256 -0
  43. bsplot/scientific_color_maps/diverging/tofino.txt +256 -0
  44. bsplot/scientific_color_maps/diverging/vanimo.txt +256 -0
  45. bsplot/scientific_color_maps/diverging/vik.txt +256 -0
  46. bsplot/scientific_color_maps/multisequential/bukavu.txt +256 -0
  47. bsplot/scientific_color_maps/multisequential/fes.txt +256 -0
  48. bsplot/scientific_color_maps/multisequential/oleron.txt +256 -0
  49. bsplot/scientific_color_maps/naviaW.txt +256 -0
  50. bsplot/scientific_color_maps/sequential/acton.txt +256 -0
  51. bsplot/scientific_color_maps/sequential/bamako.txt +256 -0
  52. bsplot/scientific_color_maps/sequential/batlow.txt +256 -0
  53. bsplot/scientific_color_maps/sequential/bilbao.txt +256 -0
  54. bsplot/scientific_color_maps/sequential/buda.txt +256 -0
  55. bsplot/scientific_color_maps/sequential/davos.txt +256 -0
  56. bsplot/scientific_color_maps/sequential/devon.txt +256 -0
  57. bsplot/scientific_color_maps/sequential/glasgow.txt +256 -0
  58. bsplot/scientific_color_maps/sequential/grayC.txt +256 -0
  59. bsplot/scientific_color_maps/sequential/hawaii.txt +256 -0
  60. bsplot/scientific_color_maps/sequential/imola.txt +256 -0
  61. bsplot/scientific_color_maps/sequential/lajolla.txt +256 -0
  62. bsplot/scientific_color_maps/sequential/lapaz.txt +256 -0
  63. bsplot/scientific_color_maps/sequential/lipari.txt +256 -0
  64. bsplot/scientific_color_maps/sequential/navia.txt +256 -0
  65. bsplot/scientific_color_maps/sequential/nuuk.txt +256 -0
  66. bsplot/scientific_color_maps/sequential/oslo.txt +256 -0
  67. bsplot/scientific_color_maps/sequential/tokyo.txt +256 -0
  68. bsplot/scientific_color_maps/sequential/turku.txt +256 -0
  69. bsplot/streamlines.py +314 -0
  70. bsplot/style.py +791 -0
  71. bsplot/styles/black.mplstyle +78 -0
  72. bsplot/styles/bss.mplstyle +50 -0
  73. bsplot/styles/bwcomp.mplstyle +30 -0
  74. bsplot/styles/nature.mplstyle +57 -0
  75. bsplot/styles/transparent.mplstyle +16 -0
  76. bsplot/styles/tvbo.mplstyle +57 -0
  77. bsplot/surface.py +2370 -0
  78. bsplot/templates.py +270 -0
  79. bsplot/text.py +199 -0
  80. bsplot/text2obj.py +59 -0
  81. bsplot/timeseries.py +10 -0
  82. bsplot/utils.py +13 -0
  83. bsplot/volume.py +958 -0
  84. bsplot-0.0.2.dist-info/METADATA +60 -0
  85. bsplot-0.0.2.dist-info/RECORD +89 -0
  86. bsplot-0.0.2.dist-info/WHEEL +5 -0
  87. bsplot-0.0.2.dist-info/entry_points.txt +2 -0
  88. bsplot-0.0.2.dist-info/licenses/LICENSE +193 -0
  89. bsplot-0.0.2.dist-info/top_level.txt +1 -0
bsplot/brain.py ADDED
@@ -0,0 +1,188 @@
1
+ from os.path import join
2
+ import inspect
3
+
4
+ import matplotlib.pyplot as plt
5
+ import numpy as np
6
+ from nilearn import surface
7
+
8
+ from bsplot import anat, data
9
+
10
+ # imshow kwargs that are not in plot_slice's signature but should still be
11
+ # routed to plot_slice / imshow rather than to Patch schematics
12
+ _IMSHOW_PARAMS = frozenset({
13
+ "norm", "vmin", "vmax", "interpolation", "interpolation_stage",
14
+ "filternorm", "filterrad", "resample", "url", "origin", "extent",
15
+ })
16
+
17
+
18
+ def _split_glass_brain_kwargs(kwargs):
19
+ """Split **kwargs into (slice_kwargs, patch_kwargs).
20
+
21
+ Kwargs whose names match a ``plot_slice`` parameter or a known
22
+ ``imshow`` parameter are routed to *slice_kwargs* (for the image).
23
+ Everything else is routed to *patch_kwargs* (for the brain outline
24
+ Patch objects drawn by ``plot_brain_schematics``).
25
+ """
26
+ from bsplot.volume import plot_slice
27
+
28
+ sig = inspect.signature(plot_slice)
29
+ slice_param_names = {
30
+ name
31
+ for name, p in sig.parameters.items()
32
+ if p.kind != inspect.Parameter.VAR_KEYWORD
33
+ }
34
+ slice_param_names |= _IMSHOW_PARAMS
35
+
36
+ slice_kw = {}
37
+ patch_kw = {}
38
+ for key, value in kwargs.items():
39
+ if key in slice_param_names:
40
+ slice_kw[key] = value
41
+ else:
42
+ patch_kw[key] = value
43
+ return slice_kw, patch_kw
44
+
45
+
46
+ def glass_brain(
47
+ img,
48
+ ax=None,
49
+ view="sagittal",
50
+ cmap="viridis",
51
+ colorbar=False,
52
+ intensity_projection="absmax",
53
+ linewidth=None,
54
+ abs_linewidth=None,
55
+ **kwargs,
56
+ ):
57
+ # Split kwargs: plot_slice / imshow kwargs vs Patch / schematics kwargs
58
+ slice_kwargs, patch_kwargs = _split_glass_brain_kwargs(kwargs)
59
+
60
+ if linewidth is not None:
61
+ patch_kwargs["linewidth"] = linewidth
62
+ if abs_linewidth is not None:
63
+ patch_kwargs["abs_linewidth"] = abs_linewidth
64
+
65
+ if view in ["lateral", "sagittal"]:
66
+ view = "sagittal"
67
+
68
+ if ax is None and view.lower() == "all":
69
+ fig, axs = plt.subplots(ncols=3, layout="compressed", figsize=(9, 4))
70
+ views = ["coronal", "sagittal", "horizontal"]
71
+ for i, view in enumerate(views):
72
+ ax = axs[i]
73
+ mappable = anat.plot_img(
74
+ img,
75
+ intensity_projection=intensity_projection,
76
+ view=view,
77
+ cmap=cmap,
78
+ ax=ax,
79
+ **slice_kwargs,
80
+ )
81
+ anat.plot_brain_schematics(ax, view=view, **patch_kwargs)
82
+ ax.axis("off")
83
+ return_fig = True
84
+ else:
85
+ if ax is None:
86
+ fig, ax = plt.subplots()
87
+ return_fig = True
88
+ else:
89
+ return_fig = False
90
+
91
+ mappable = anat.plot_img(
92
+ img, intensity_projection=intensity_projection, view=view, cmap=cmap, ax=ax, **slice_kwargs
93
+ )
94
+ # Get image extent before schematics overwrite it
95
+ img_xlim = ax.get_xlim()
96
+ img_ylim = ax.get_ylim()
97
+
98
+ schematic_bounds = anat.plot_brain_schematics(ax=ax, view=view, **patch_kwargs)
99
+
100
+ # Use union of image and schematic bounds
101
+ xlim = (min(img_xlim[0], schematic_bounds[0]), max(img_xlim[1], schematic_bounds[1]))
102
+ ylim = (min(img_ylim[0], schematic_bounds[2]), max(img_ylim[1], schematic_bounds[3]))
103
+ ax.set_xlim(xlim)
104
+ ax.set_ylim(ylim)
105
+
106
+ ax.set_aspect("equal")
107
+ if return_fig:
108
+ if colorbar:
109
+ fig.colorbar(mappable, ax=ax, shrink=0.8)
110
+ plt.close()
111
+ return fig
112
+ else:
113
+ return mappable
114
+
115
+
116
+ def glass_brain_3d(img, ax=None, surf="fsaverage", cmap="viridis", brain_color="k"):
117
+ if ax is None:
118
+ fig, ax = plt.subplots(1, 1)
119
+ return_fig = True
120
+ else:
121
+ return_fig = False
122
+
123
+ img_data = img.get_fdata()
124
+
125
+ if surf == "fsaverage":
126
+ # fsaverage = datasets.fetch_surf_fsaverage()
127
+ # mesh = surface.load_surf_mesh(fsaverage.pial_right)
128
+ mesh = surface.load_surf_mesh(
129
+ data.surface.get_surface_geometry(
130
+ template="fsaverage", hemi="rh", suffix="pial", density="10k"
131
+ )
132
+ )
133
+ linewidth = 0.1
134
+ elif surf == "mni09c":
135
+ mesh = surface.load_surf_mesh(join(data.surface.root, "MNI152.rh.pial"))
136
+ linewidth = 0.05
137
+
138
+ coords, faces = mesh[0], mesh[1]
139
+ x, y, z = coords.T
140
+
141
+ if surf != "nilearn":
142
+ ax.triplot(
143
+ y, z, faces, color=brain_color, alpha=0.8, linewidth=linewidth, zorder=100
144
+ )
145
+
146
+ xlim = ax.get_xlim()
147
+ ylim = ax.get_ylim()
148
+
149
+ affine = img.affine
150
+
151
+ voxel_sizes = np.linalg.norm(affine[:3, :3], axis=0) # Get voxel sizes
152
+ origin = affine[:3, 3] # Get translation offset
153
+ x_coords = np.arange(img_data.shape[1]) * voxel_sizes[1] + origin[1]
154
+ y_coords = np.arange(img_data.shape[2]) * voxel_sizes[2] + origin[2]
155
+
156
+ mip_sagittal = np.max(img_data, axis=0) # Maximum Intensity Projection
157
+ mip_sagittal[mip_sagittal == 0] = np.nan
158
+ mip_sagittal = mip_sagittal.T
159
+ valid_x = np.any(~np.isnan(mip_sagittal), axis=0) # Check columns
160
+ valid_y = np.any(~np.isnan(mip_sagittal), axis=1) # Check rows
161
+
162
+ first_valid_x_index, last_valid_x_index = np.flatnonzero(valid_x)[[0, -1]]
163
+ first_valid_y_index, last_valid_y_index = np.flatnonzero(valid_y)[[0, -1]]
164
+
165
+ ax.imshow(
166
+ mip_sagittal,
167
+ cmap=cmap,
168
+ origin="lower",
169
+ interpolation="none",
170
+ alpha=1,
171
+ extent=[
172
+ x_coords[0],
173
+ x_coords[-1],
174
+ y_coords[0],
175
+ y_coords[-1],
176
+ ],
177
+ zorder=0,
178
+ )
179
+ ax.set_xlim(x_coords[first_valid_x_index], x_coords[last_valid_x_index])
180
+ ax.set_ylim(y_coords[first_valid_y_index], y_coords[last_valid_y_index])
181
+ ax.set_ylim(ylim)
182
+ ax.set_xlim(xlim)
183
+ ax.set_aspect("equal")
184
+
185
+ if return_fig:
186
+ ax.axis("off")
187
+ plt.close()
188
+ return fig