Skip to content

Instantly share code, notes, and snippets.

@alexlib
Last active November 28, 2022 09:32
Show Gist options
  • Save alexlib/b9f7833694021aafc35126a1cb1fe884 to your computer and use it in GitHub Desktop.
Save alexlib/b9f7833694021aafc35126a1cb1fe884 to your computer and use it in GitHub Desktop.
Create colored vector field on image background using napari, based on https://napari.org/stable/gallery/add_vectors_color_by_angle.html
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "7ff2cc68",
"metadata": {},
"outputs": [],
"source": [
"# napari attempt"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "380d28db",
"metadata": {},
"outputs": [],
"source": [
"import napari\n",
"import numpy as np\n",
"from skimage import data\n",
"\n",
"# create vector data\n",
"n = 250\n",
"vectors = np.zeros((n, 2, 2), dtype=np.float32)\n",
"phi_space = np.linspace(0, 4 * np.pi, n)\n",
"radius_space = np.linspace(0, 100, n)\n",
"# assign x-y projection\n",
"vectors[:, 1, 0] = radius_space * np.cos(phi_space)\n",
"vectors[:, 1, 1] = radius_space * np.sin(phi_space)\n",
"# assign x-y position\n",
"vectors[:, 0] = vectors[:, 1] + 256\n",
"\n",
"# add the image\n",
"viewer = napari.view_image(data.camera(), name='photographer')\n",
"# add the vectors\n",
"vectors_layer = viewer.add_vectors(vectors, edge_width=3, edge_colormap = 'RdBu')"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "c2031266",
"metadata": {},
"outputs": [],
"source": [
"import napari\n",
"from skimage import data\n",
"import numpy as np\n",
"\n",
"\n",
"# create the viewer and window\n",
"viewer = napari.Viewer()\n",
"\n",
"layer = viewer.add_image(data.camera(), name='photographer')\n",
"\n",
"# sample vector coord-like data\n",
"n = 300\n",
"pos = np.zeros((n, 2, 2), dtype=np.float32)\n",
"phi_space = np.linspace(0, 4 * np.pi, n)\n",
"radius_space = np.linspace(0, 100, n)\n",
"\n",
"# assign x-y position\n",
"pos[:, 0, 0] = radius_space * np.cos(phi_space) + 300\n",
"pos[:, 0, 1] = radius_space * np.sin(phi_space) + 256\n",
"\n",
"# assign x-y projection\n",
"pos[:, 1, 0] = 2 * radius_space * np.cos(phi_space)\n",
"pos[:, 1, 1] = 2 * radius_space * np.sin(phi_space)\n",
"\n",
"# make the angle feature, range 0-2pi\n",
"angle = np.mod(phi_space, 2 * np.pi)\n",
"\n",
"# create a feature that is true for all angles > pi\n",
"pos_angle = angle > np.pi\n",
"\n",
"\n",
"\n",
"# create the features dictionary.\n",
"features = {\n",
" 'angle': angle,\n",
" 'pos_angle': pos_angle,\n",
" 'magnitude': radius_space,\n",
"}\n",
"\n",
"# add the vectors\n",
"layer = viewer.add_vectors(\n",
" pos,\n",
" edge_width=3,\n",
" features=features,\n",
" edge_color='magnitude',\n",
" edge_colormap='husl',\n",
" name='vectors'\n",
")\n",
"\n",
"# set the edge color mode to colormap\n",
"layer.edge_color_mode = 'colormap'"
]
},
{
"cell_type": "code",
"execution_count": 41,
"id": "15679e5b",
"metadata": {},
"outputs": [],
"source": [
"viewer = napari.Viewer()\n",
"layer = viewer.add_image(a, name='a')\n",
"\n",
"# viewer.add_image(b, name ='b')\n",
"\n",
"s = 10\n",
"\n",
"vectors = np.zeros((len(u.flatten()), 2, 2), dtype=np.float32)\n",
"vectors[:,0,1] = x.flatten()\n",
"vectors[:,0,0] = y.flatten()\n",
"\n",
"\n",
"u[np.isnan(u)] = 0\n",
"v[np.isnan(v)] = 0\n",
"\n",
"vectors[:,1,1] = s*u.flatten()\n",
"vectors[:,1,0] = s*v.flatten()\n",
"\n",
"magnitude = np.sqrt(u.flatten()**2 + v.flatten()**2)\n",
"angle = np.arctan2(u.flatten(),v.flatten())\n",
"\n",
"# create the features dictionary.\n",
"features = {\n",
" 'angle': angle,\n",
" # 'pos_angle': pos_angle,\n",
" 'magnitude': magnitude,\n",
"}\n",
"\n",
"\n",
"# add the vectors\n",
"layer = viewer.add_vectors(\n",
" vectors,\n",
" edge_width=3,\n",
" features=features,\n",
" edge_color='magnitude',\n",
" edge_colormap='husl',\n",
" name='vectors'\n",
")\n",
"\n",
"# set the edge color mode to colormap\n",
"layer.edge_color_mode = 'colormap'\n",
"\n",
"\n",
"\n",
"import matplotlib.pyplot as plt\n",
"from matplotlib.backends.backend_qt5agg import FigureCanvas\n",
"from matplotlib.figure import Figure\n",
"\n",
"NUM_ITER = 500\n",
"\n",
"# build the plot, but don't display it yet\n",
"# — we'll add it to the napari viewer later\n",
"with plt.style.context('dark_background'):\n",
" loss_canvas = FigureCanvas(Figure(figsize=(5, 3)))\n",
" loss_axes = loss_canvas.figure.subplots()\n",
" lines = loss_axes.plot([], []) # make empty plot\n",
" loss_axes.set_xlim(0, NUM_ITER)\n",
" loss_axes.set_xlabel('batch number')\n",
" loss_axes.set_ylabel('loss')\n",
" loss_canvas.figure.tight_layout()\n",
" loss_line = lines[0]\n",
"\n",
"# Napari's threading utilities, created by Talley Lambert, allow *yielding*\n",
"# of values during a thread's execution, and connecting those yielded\n",
"\n",
"\n",
"# ewer.add_vectors(vectors, edge_width=0.4, name='vectors', edge_colormap='bwr')"
]
},
{
"cell_type": "code",
"execution_count": 42,
"id": "6da294b0",
"metadata": {},
"outputs": [
{
"ename": "ModuleNotFoundError",
"evalue": "No module named 'nilearn'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)",
"Input \u001b[0;32mIn [42]\u001b[0m, in \u001b[0;36m<cell line: 7>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mmatplotlib\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mfigure\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m Figure\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mmatplotlib\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mpyplot\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mplt\u001b[39;00m\n\u001b[0;32m----> 7\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mnilearn\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m datasets\n\u001b[1;32m 8\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mnilearn\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m surface\n\u001b[1;32m 10\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mnumpy\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mnp\u001b[39;00m\n",
"\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'nilearn'"
]
}
],
"source": [
"import napari\n",
"import matplotlib as mpl\n",
"from matplotlib.backends.backend_qt5agg import FigureCanvas\n",
"from matplotlib.figure import Figure\n",
"import matplotlib.pyplot as plt\n",
"\n",
"from nilearn import datasets\n",
"from nilearn import surface\n",
"\n",
"import numpy as np\n",
"\n",
"nki_dataset = datasets.fetch_surf_nki_enhanced(n_subjects=1)\n",
"fsaverage = datasets.fetch_surf_fsaverage()\n",
"\n",
"brain_vertices, brain_faces = surface.load_surf_data(fsaverage['pial_left'])\n",
"timeseries = surface.load_surf_data(nki_dataset['func_left'][0])\n",
"timeseries = timeseries.transpose((1, 0))\n",
"\n",
"def axis_changed(event):\n",
"\n",
" idx_max = viewer.dims.range[0][1]\n",
" idx = viewer.dims.current_step[0]\n",
"\n",
" if idx < idx_max and layer.visible:\n",
" random_number = np.random.random()\n",
" mappable1.set_clim(random_number, random_number+1)\n",
" mappable2.set_clim(random_number, random_number+1)\n",
" mappable3.set_clim(random_number, random_number+1)\n",
" # comment next line to check performance\n",
" colorbars_widget.draw_idle()\n",
"\n",
"\n",
"viewer = napari.Viewer(ndisplay=3)\n",
"\n",
"with plt.style.context('dark_background'):\n",
"\n",
" colorbars_widget = FigureCanvas(Figure(constrained_layout=True))\n",
" fig = colorbars_widget.figure\n",
"\n",
" gs = fig.add_gridspec(3, 1)\n",
" ax1 = fig.add_subplot(gs[0, 0])\n",
" ax2 = fig.add_subplot(gs[1, 0])\n",
" ax3 = fig.add_subplot(gs[2, 0])\n",
"\n",
" cmap1 = mpl.cm.jet\n",
" mappable1 = mpl.cm.ScalarMappable(cmap=cmap1)\n",
" colorbar1 = fig.colorbar(mappable1, cax=ax1, orientation='horizontal')\n",
" colorbar1.set_label('jet')\n",
"\n",
" cmap2 = mpl.cm.gist_rainbow\n",
" mappable2 = mpl.cm.ScalarMappable(cmap=cmap2)\n",
" colorbar2 = fig.colorbar(mappable2, cax=ax2, orientation='horizontal')\n",
" colorbar2.set_label('gist_rainbow')\n",
"\n",
" cmap3 = mpl.cm.viridis\n",
" mappable3 = mpl.cm.ScalarMappable(cmap=cmap3)\n",
" colorbar3 = fig.colorbar(mappable3, cax=ax3, orientation='horizontal')\n",
" colorbar3.set_label('viridis')\n",
"\n",
"\n",
"layer = viewer.add_surface((brain_vertices, brain_faces, timeseries))\n",
"layer.colormap = cmap1.name\n",
"\n",
"viewer.dims.events.axis.connect(axis_changed)\n",
"\n",
"colorbars_widget.setFixedWidth(300)\n",
"colorbars_widget.setFixedHeight(200)\n",
"\n",
"colorbars_dock = viewer.window.add_dock_widget(colorbars_widget, name='Colorbars', area = 'left')\n"
]
},
{
"cell_type": "code",
"execution_count": 43,
"id": "f8dca141",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Collecting nilearn\n",
" Downloading nilearn-0.9.2-py3-none-any.whl (9.6 MB)\n",
" |████████████████████████████████| 9.6 MB 1.2 MB/s \n",
"\u001b[?25hCollecting nibabel>=3.0.0\n",
" Downloading nibabel-4.0.2-py3-none-any.whl (3.3 MB)\n",
" |████████████████████████████████| 3.3 MB 8.7 MB/s \n",
"\u001b[?25hRequirement already satisfied: requests>=2 in /home/user/.edm/envs/napari/lib/python3.8/site-packages (from nilearn) (2.28.1)\n",
"Collecting scikit-learn>=0.22\n",
" Downloading scikit_learn-1.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (31.2 MB)\n",
" |████████████████████████████████| 31.2 MB 8.6 MB/s \n",
"\u001b[?25hRequirement already satisfied: scipy>=1.5 in /home/user/.edm/envs/napari/lib/python3.8/site-packages (from nilearn) (1.8.1)\n",
"Requirement already satisfied: numpy>=1.18 in /home/user/.edm/envs/napari/lib/python3.8/site-packages (from nilearn) (1.23.1)\n",
"Collecting lxml\n",
" Using cached lxml-4.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (6.9 MB)\n",
"Requirement already satisfied: pandas>=1.0 in /home/user/.edm/envs/napari/lib/python3.8/site-packages (from nilearn) (1.4.3)\n",
"Collecting joblib>=0.15\n",
" Downloading joblib-1.2.0-py3-none-any.whl (297 kB)\n",
" |████████████████████████████████| 297 kB 37.6 MB/s \n",
"\u001b[?25hRequirement already satisfied: packaging>=17.0 in /home/user/.edm/envs/napari/lib/python3.8/site-packages (from nibabel>=3.0.0->nilearn) (21.3)\n",
"Requirement already satisfied: setuptools in /home/user/.edm/envs/napari/lib/python3.8/site-packages (from nibabel>=3.0.0->nilearn) (57.0.0)\n",
"Requirement already satisfied: pytz>=2020.1 in /home/user/.edm/envs/napari/lib/python3.8/site-packages (from pandas>=1.0->nilearn) (2022.1)\n",
"Requirement already satisfied: python-dateutil>=2.8.1 in /home/user/.edm/envs/napari/lib/python3.8/site-packages (from pandas>=1.0->nilearn) (2.8.2)\n",
"Requirement already satisfied: charset-normalizer<3,>=2 in /home/user/.edm/envs/napari/lib/python3.8/site-packages (from requests>=2->nilearn) (2.1.0)\n",
"Requirement already satisfied: urllib3<1.27,>=1.21.1 in /home/user/.edm/envs/napari/lib/python3.8/site-packages (from requests>=2->nilearn) (1.26.10)\n",
"Requirement already satisfied: idna<4,>=2.5 in /home/user/.edm/envs/napari/lib/python3.8/site-packages (from requests>=2->nilearn) (3.3)\n",
"Requirement already satisfied: certifi>=2017.4.17 in /home/user/.edm/envs/napari/lib/python3.8/site-packages (from requests>=2->nilearn) (2022.6.15)\n",
"Collecting threadpoolctl>=2.0.0\n",
" Using cached threadpoolctl-3.1.0-py3-none-any.whl (14 kB)\n",
"Requirement already satisfied: pyparsing!=3.0.5,>=2.0.2 in /home/user/.edm/envs/napari/lib/python3.8/site-packages (from packaging>=17.0->nibabel>=3.0.0->nilearn) (3.0.9)\n",
"Requirement already satisfied: six>=1.5 in /home/user/.edm/envs/napari/lib/python3.8/site-packages (from python-dateutil>=2.8.1->pandas>=1.0->nilearn) (1.16.0)\n",
"Installing collected packages: threadpoolctl, joblib, scikit-learn, nibabel, lxml, nilearn\n",
"Successfully installed joblib-1.2.0 lxml-4.9.1 nibabel-4.0.2 nilearn-0.9.2 scikit-learn-1.1.3 threadpoolctl-3.1.0\n"
]
}
],
"source": [
"!pip install nilearn"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b6340090",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment