From 1cafdc6d0bd24657b77e00cc93455a4425e8d63e Mon Sep 17 00:00:00 2001 From: Robert Haase Date: Sun, 18 Aug 2024 16:35:54 +0200 Subject: [PATCH 1/3] Bug fix: clusterplot didn't work with 3d images --- stackview/_clusterplot.py | 5 ++++- stackview/_scatterplot.py | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/stackview/_clusterplot.py b/stackview/_clusterplot.py index d823524..885b06c 100644 --- a/stackview/_clusterplot.py +++ b/stackview/_clusterplot.py @@ -42,6 +42,8 @@ def clusterplot(df, labels, column_x:str="x", column_y:str="y", column_selection from ._scatterplot import scatterplot import functools + labels = np.asarray(labels) + if column_selection in df.columns: selection = df["selection"].tolist() @@ -72,6 +74,7 @@ def update(selection, label_image, selected_image, widget): return grid([[ image_display, - scatterplot + scatterplot, + ]]) diff --git a/stackview/_scatterplot.py b/stackview/_scatterplot.py index 8b9c6d5..8f30b62 100644 --- a/stackview/_scatterplot.py +++ b/stackview/_scatterplot.py @@ -120,7 +120,9 @@ def __init__(self, df, column_x, column_y, column_selection, figsize, selection_ manager = Gcf.get_active() Gcf.figs.pop(manager.num, None) - self.selector = Selector(self.fig, self.ax, self.plotted_points, callback=self.set_selection) + self.selector = None + #self.selector = Selector(self.fig, self.ax, self.plotted_points, callback=self.set_selection) + self.update() # show selection if defined if column_selection in df.columns: From 963de7ebb8b005dd9a99414b00aeb29524bdb032 Mon Sep 17 00:00:00 2001 From: Robert Haase Date: Sun, 18 Aug 2024 16:37:52 +0200 Subject: [PATCH 2/3] added example --- docs/clusterplot.ipynb | 306 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 306 insertions(+) create mode 100644 docs/clusterplot.ipynb diff --git a/docs/clusterplot.ipynb b/docs/clusterplot.ipynb new file mode 100644 index 0000000..5067002 --- /dev/null +++ b/docs/clusterplot.ipynb @@ -0,0 +1,306 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "35d1c118-c57f-4ba4-9926-de78d5db451c", + "metadata": {}, + "outputs": [], + "source": [ + "import bia_bob\n", + "import pyclesperanto_prototype as cle\n", + "import stackview" + ] + }, + { + "cell_type": "raw", + "id": "39df4e10-bdf9-4e6f-8289-71554fa11ee8", + "metadata": {}, + "source": [ + "%bob load the cells3d dataset and extract the nuclei channel" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "e9bbbd3b-ac3c-4171-a42f-ea07cadc7d63", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(60, 256, 256)" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import numpy as np # Already imported modules should not be imported again\n", + "from skimage.data import cells3d\n", + "\n", + "# Extract the nuclei channel (assuming channel 1 is the nuclei channel)\n", + "nuclei_channel = cells3d()[:, 1, :, :]\n", + "\n", + "nuclei_channel.shape # to verify the extraction" + ] + }, + { + "cell_type": "raw", + "id": "09769fd0-4606-437f-9fc5-f7f260f871a5", + "metadata": {}, + "source": [ + "%bob segment the nuclei_channel image using otsu thresholding and connected component labeling" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "72a47ee0-be9b-456c-91d3-f91a58c95dff", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
shape(60, 256, 256)
dtypeuint32
size15.0 MB
min0
max740
\n", + "\n", + "
" + ], + "text/plain": [ + "StackViewNDArray([[[0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " ...,\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0]],\n", + "\n", + " [[0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " ...,\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0]],\n", + "\n", + " [[0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " ...,\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0]],\n", + "\n", + " ...,\n", + "\n", + " [[0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " ...,\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0]],\n", + "\n", + " [[0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " ...,\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0]],\n", + "\n", + " [[0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " ...,\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0]]], dtype=uint32)" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Apply Otsu's threshold to create a binary image\n", + "binary_nuclei = cle.threshold_otsu(nuclei_channel)\n", + "\n", + "# Perform connected component labeling\n", + "labeled_nuclei = cle.connected_components_labeling_box(binary_nuclei)\n", + "\n", + "# Display the segmented label map\n", + "stackview.insight(labeled_nuclei)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "f94055dd-0aef-4de6-9d18-dc938bb0149e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
labelareamean_intensity
0127119.012862.000295
125.011143.800000
23168.011268.273810
3460.011758.683333
451.010527.000000
\n", + "
" + ], + "text/plain": [ + " label area mean_intensity\n", + "0 1 27119.0 12862.000295\n", + "1 2 5.0 11143.800000\n", + "2 3 168.0 11268.273810\n", + "3 4 60.0 11758.683333\n", + "4 5 1.0 10527.000000" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "from skimage.measure import regionprops_table\n", + "\n", + "# Define properties to extract\n", + "properties = ['label', 'area', 'mean_intensity']\n", + "\n", + "# Extract features\n", + "measurements = regionprops_table(np.asarray(labeled_nuclei), intensity_image=nuclei_channel, properties=properties)\n", + "\n", + "# Store results in a DataFrame\n", + "df = pd.DataFrame(measurements)\n", + "df.head() # To display the first few rows of the extracted features" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "1fba06ed-5ae5-4049-a656-d1d4ea18894d", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "9e50d99d1f4b431787c2b422e15f6b49", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "VBox(children=(HBox(children=(VBox(children=(HBox(children=(VBox(children=(ImageWidget(height=256, width=256),…" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import stackview\n", + "stackview.clusterplot(df, labeled_nuclei, column_x=\"area\", column_y=\"mean_intensity\", image=nuclei_channel)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5c07c9fc-873b-490b-a2b3-b280a9557f13", + "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.11.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From f457f9ab1bdacbb91a9eb47b63e0c1ba417144c6 Mon Sep 17 00:00:00 2001 From: Robert Haase Date: Sun, 18 Aug 2024 16:38:46 +0200 Subject: [PATCH 3/3] bump version --- setup.py | 2 +- stackview/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index d18135e..4d2beb3 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="stackview", - version="0.8.1", + version="0.8.2", author="Robert Haase", author_email="robert.haase@uni-leipzig.de", description="Interactive image stack viewing in jupyter notebooks", diff --git a/stackview/__init__.py b/stackview/__init__.py index 8bed0a0..671d389 100644 --- a/stackview/__init__.py +++ b/stackview/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.8.1" +__version__ = "0.8.2" from ._static_view import jupyter_displayable_output, insight from ._utilities import merge_rgb