Skip to content

Commit

Permalink
added docs and testing
Browse files Browse the repository at this point in the history
  • Loading branch information
akhanf committed Dec 1, 2024
1 parent 53df85c commit 0e4429d
Show file tree
Hide file tree
Showing 4 changed files with 291 additions and 55 deletions.
29 changes: 29 additions & 0 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: CI

on: [push, pull_request]

jobs:
test:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.x' # Specify the Python version you want to use

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install .
- name: Run tests
run: |
python -m unittest discover -s . -p "test_*.py"
- name: Run doctests
run: |
python -m doctest utils.py
97 changes: 73 additions & 24 deletions hippunfold_plot/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,88 @@
from nilearn.plotting import plot_surf
from hippunfold_plot.utils import get_surf_limits, get_data_limits, get_resource_path, check_surf_map_is_label_gii, get_legend_elements_from_label_gii



def plot_hipp_surf(surf_map, density='0p5mm', hemi='left',space=None,figsize=(12,8), dpi=300, vmin=None, vmax=None,colorbar=False, colorbar_shrink=0.25,cmap=None,view='dorsal',avg_method='median',bg_on_data=True,alpha=0.1,darkness=2,**kwargs):

""" Plots surf_map, which can be a label-hippdentate shape.gii or func.gii, or
a Vx1 array (where V is number of vertices in hipp + dentate. Any arguments
that can be supplied to nilearn's plot_surf() can also be applied here. These
would override the defaults set below.
By default this function will plot one hemisphere (left by default), in both canonical and unfold space.
(This is since nilearn's plot_surf also only plots one hemisphere at a time)
def plot_hipp_surf(surf_map, density='0p5mm', hemi='left', space=None, figsize=(12, 8), dpi=300, vmin=None, vmax=None, colorbar=False, colorbar_shrink=0.25, cmap=None, view='dorsal', avg_method='median', bg_on_data=True, alpha=0.1, darkness=2, **kwargs):
"""Plot hippocampal surface map.
This function plots a surface map of the hippocampus, which can be a label-hippdentate shape.gii, func.gii, or a Vx1 array
(where V is the number of vertices in the hippocampus and dentate). Any arguments that can be supplied to nilearn's plot_surf()
can also be applied here, overriding the defaults set below.
Parameters
----------
surf_map : str or array-like
The surface map to plot. This can be a file path to a .gii file or a Vx1 array.
density : str, optional
The density of the surface map. Can be 'unfoldiso', '0p5mm', '1mm', or '2mm'. Default is '0p5mm'.
hemi : str, optional
The hemisphere to plot. Can be 'left', 'right', or None (in which case both are plotted). Default is 'left'.
space : str, optional
The space of the surface map. Can be 'canonical', 'unfold', or None (in which case both are plotted). Default is None.
figsize : tuple, optional
The size of the figure. Default is (12, 8).
dpi : int, optional
The resolution of the figure in dots per inch. Default is 300.
vmin : float, optional
The minimum value for the color scale. Default is None.
vmax : float, optional
The maximum value for the color scale. Default is None.
colorbar : bool, optional
Whether to display a colorbar. Default is False.
colorbar_shrink : float, optional
The shrink factor for the colorbar. Default is 0.25.
cmap : str or colormap, optional
The colormap to use. Default is None.
view : str, optional
The view of the surface plot. Default is 'dorsal'.
avg_method : str, optional
The method to average the data. Default is 'median'.
bg_on_data : bool, optional
Whether to display the background on the data. Default is True.
alpha : float, optional
The alpha transparency level. Default is 0.1.
darkness : float, optional
The darkness level of the background. Default is 2.
**kwargs : dict
Additional arguments to pass to nilearn's plot_surf().
Returns
-------
fig : matplotlib.figure.Figure
The figure object.
mappable : matplotlib.cm.ScalarMappable, optional
The mappable object, if return_mappable is True.
Notes
-----
By default, this function will plot one hemisphere (left by default) in both canonical and unfolded space.
Both surfaces can be plotted with hemi=None, but the same surf_map will be plotted on both.
Use return_mappable=True if you want to make a colorbar afterwards, e.g.:
fig,mappable = plot_hipp_surf(... return_mappable=True)
plt.colorbar(mappable, shrink=0.5) #shrink makes it smaller which is recommended
fig, mappable = plot_hipp_surf(..., return_mappable=True)
plt.colorbar(mappable, shrink=0.5) # shrink makes it smaller which is recommended
"""
# Validate inputs
valid_densities = ['unfoldiso', '0p5mm', '1mm', '2mm']
valid_spaces = ['canonical', 'unfold', None]
if density not in valid_densities:
raise ValueError(f"Invalid value for 'density'. Expected one of {valid_densities}.")
if hemi not in ['left', 'right', None]:
raise ValueError("Invalid value for 'hemi'. Expected 'left', 'right', or None.")
if space not in valid_spaces:
raise ValueError(f"Invalid value for 'space'. Expected one of {valid_spaces}.")


surf_gii = get_resource_path('tpl-avg_hemi-{hemi}_space-{space}_label-hippdentate_density-{density}_midthickness.surf.gii')
curv_gii = get_resource_path('tpl-avg_label-hippdentate_density-{density}_curvature.shape.gii')


plot_kwargs = {'surf_map': surf_map,
'bg_map':curv_gii.format(density=density),
'alpha': alpha,
'bg_on_data': bg_on_data,
'darkness': darkness,
'avg_method':avg_method,
'cmap': cmap,
'view':view}
'bg_map': curv_gii.format(density=density),
'alpha': alpha,
'bg_on_data': bg_on_data,
'darkness': darkness,
'avg_method': avg_method,
'cmap': cmap,
'view': view}

#add any user arguments
plot_kwargs.update(kwargs)
Expand Down Expand Up @@ -84,8 +135,6 @@ def plot_hipp_surf(surf_map, density='0p5mm', hemi='left',space=None,figsize=(12
norm = mpl.colors.Normalize(vmin=vmin if vmin else datamin, vmax=vmax if vmax else datamax) # Match your data range
sm = mpl.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([]) # Dummy array for ScalarMappable


plt.colorbar(sm,ax=fig.axes,shrink=colorbar_shrink)

return fig
Expand Down
39 changes: 39 additions & 0 deletions hippunfold_plot/tests/test_plotting.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import unittest
import matplotlib.pyplot as plt
from plotting import plot_hipp_surf

class TestPlotHippSurf(unittest.TestCase):

def test_invalid_density(self):
with self.assertRaises(ValueError):
plot_hipp_surf(surf_map='dummy_path', density='invalid_density')

def test_invalid_hemi(self):
with self.assertRaises(ValueError):
plot_hipp_surf(surf_map='dummy_path', hemi='invalid_hemi')

def test_invalid_space(self):
with self.assertRaises(ValueError):
plot_hipp_surf(surf_map='dummy_path', space='invalid_space')

def test_plot_creation(self):
fig = plot_hipp_surf(surf_map='dummy_path')
self.assertIsInstance(fig, plt.Figure)

def test_colorbar(self):
fig = plot_hipp_surf(surf_map='dummy_path', colorbar=True)
self.assertIsInstance(fig, plt.Figure)
self.assertEqual(len(fig.axes), 6) # 5 plots + 1 colorbar

def test_default_parameters(self):
fig = plot_hipp_surf(surf_map='dummy_path')
self.assertIsInstance(fig, plt.Figure)
self.assertEqual(len(fig.axes), 5) # 5 plots

def test_custom_parameters(self):
fig = plot_hipp_surf(surf_map='dummy_path', density='1mm', hemi='right', space='canonical', figsize=(10, 6), dpi=200, vmin=0, vmax=1, colorbar=True, colorbar_shrink=0.5, cmap='viridis', view='ventral', avg_method='mean', bg_on_data=False, alpha=0.5, darkness=1)
self.assertIsInstance(fig, plt.Figure)
self.assertEqual(len(fig.axes), 6) # 5 plots + 1 colorbar

if __name__ == '__main__':
unittest.main()
Loading

0 comments on commit 0e4429d

Please sign in to comment.