{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Tutorial about rendering LocData" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from pathlib import Path\n", "\n", "%matplotlib inline\n", "# %matplotlib widget\n", "\n", "import numpy as np\n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "from mpl_toolkits.mplot3d import Axes3D\n", "\n", "import locan as lc" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "lc.show_versions(system=False, dependencies=False, verbose=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Synthetic data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Localizations are simulated that are distributed according to a Neyman-Scott distribution (blobs)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "rng = np.random.default_rng(seed=1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "locdata = lc.simulate_Thomas(parent_intensity=1e-5, region=((0, 1000), (0, 1000)), cluster_mu=100, cluster_std=10, seed=rng)\n", "\n", "locdata.print_summary()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since localization data is kept as a pandas dataframe standard plotting routines from pandas or matplotlip can be used." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(nrows=1, ncols=1)\n", "locdata.data.plot.scatter(x='position_x', y='position_y', ax=ax, color='Blue', label='locdata')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Render by simple 2D binning" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A method for simply binning localization data in 2D pixels is provided." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "img, bins, label = lc.histogram(locdata, bin_size=10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The intensity values of the binned locdata are distributed as:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plt.hist(img.ravel(), bins=256, range=(1, 50), fc='k', ec='k');" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The intensity values can be rescaled in many ways. There are normalization classes and a convenience function in the locan.render.transformation module with predefined transformations as listed in locan.Trafo:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "list(lc.Trafo)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "img_new = lc.adjust_contrast(img, rescale=lc.Trafo.STANDARDIZE)\n", "epsilon = np.finfo(float).resolution\n", "plt.hist(img_new.ravel(), bins=256, range=(epsilon, 1), fc='k', ec='k');" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "norm = lc.HistogramEqualization(power=1, mask=img>0)\n", "img_new = norm(img)\n", "plt.hist(img_new.ravel(), bins=256, range=(epsilon, 1), fc='k', ec='k');" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `render_2d` method can directly provide a new figure as output." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "lc.render_2d(locdata, bin_size=10);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Or it can be used within the matplotlib environment." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(nrows=1, ncols=1)\n", "lc.render_2d(locdata, ax = ax, bin_size=10, cmap='viridis')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Intensity is per default scaled to the min and max intensity values but can be rescaled by applying any norm function as described for matplotlib.imshow:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "norm = plt.Normalize(vmax=10)\n", "lc.render_2d(locdata, bin_size=10, norm=norm);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Intensity can also be rescaled by normalization functions as defined in locan.Trafo. Histogram equlization yields this image:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "lc.render_2d(locdata, bin_size=10, rescale=lc.Trafo.EQUALIZE);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Histogram equlization with a power-intensification of p=0.3 yields this image:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "lc.render_2d(locdata, bin_size=10, rescale=lc.Trafo.EQUALIZE_0P3);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Any callable normalization object can be passed into the rescale kwarg:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "norm = lc.HistogramEqualization(power=0.3)\n", "lc.render_2d(locdata, bin_size=10, rescale=norm);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The image size is set automatically to the min and max coordinates but can be set to (0, max) or an arbitrary range." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "lc.render_2d(locdata, bin_size=10, bin_range='zero');" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "lc.render_2d(locdata, bin_size=10, bin_range=((0, 300),(200, 500)));" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Use different libraries for rendering" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Rendering can also be carried out with a different render engine. Choose one of the following (MPL is the standard matplotlib):" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "list(lc.RenderEngine)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### napari" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As external viewer you can use **napari**." ] }, { "cell_type": "raw", "metadata": {}, "source": [ "import napari" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "lc.render_2d_napari(locdata, bin_size=5, rescale=lc.Trafo.EQUALIZE)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or alternatively:" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "lc.render_2d(locdata, bin_size=50, render_engine=lc.RenderEngine.NAPARI)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Choose colormaps" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Colormaps can be chosen in matplotlib, napari and other visualization tools.\n", "\n", "Colormaps are identified through specific class instances or by a name.\n", "\n", "locan.Colormap serves as adapter class for the various visualization tools.\n", "\n", "A Colormap instance can be created with the `get_colormap` function:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "colormap = lc.get_colormap(\"viridis\")\n", "colormap.name" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "colormap.matplotlib" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A mapping of names on Colormap instances is provided and can be extended by users. If a colormap name is provided to any rendering function, first the colormap_registry is searched, then the maplotlib registry and finally napari colormap names." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "lc.colormap_registry" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Default colormaps are defined for use with locan and can be accessed through a mapping or an enum:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "lc.COLORMAP_DEFAULTS" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "list(lc.Colormaps)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "lc.render_2d(locdata, bin_size=10, cmap=lc.Colormaps.CONTINUOUS_GRAY_REVERSE);" ] } ], "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.12.6" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": {}, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 4 }