{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Using RangeSliders\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib ipympl\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", "from mpl_interactions import ipyplot as iplt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## How to automatically generate a RangeSlider\n", "\n", "In order to createa a RangeSlider rather than a Slider you prefix the tuples with either `\"r\"` or `\"range\"`, then the rest of the tuple is created according to the rules from converting tuples to sliders. So arrays will remain arrays, or the values will be passed through to np.linspace as approriate.\n", "```\n", "# passed through to np.linspace\n", "(\"range\", min, max, [step]) \n", "(\"r\", min, max, [step])\n", "\n", "# array used directly\n", "(\"range\", np.array)\n", "(\"r\", np.array)\n", "```\n", "\n", "then function can use them the same as any other kwargs, except now they are tuples rather than just numbers." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def f_x(xrange, **kwargs):\n", " return np.linspace(xrange[0], xrange[1], 1000)\n", "\n", "\n", "def f_y(x, tau, **kwargs):\n", " return np.sin(x * tau)\n", "\n", "\n", "fig, ax = plt.subplots()\n", "controls = iplt.plot(f_x, f_y, xrange=(\"r\", -1, 3), tau=(5, 10))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Using a `RangeSlider` for Scalar arguments - Thresholding an Image\n", "\n", "There are some arguments, such as `vmin` and `vmax` that are both scalar and often make sense to have as two ends of a RangeSlider. For these mpl_interactions treats them as a special case and offers a third argument `vmin_vmax` that can be used to control both `vmin` and `vmax` with a range slider.\n", "\n", "Additionally it will also add the `vmin` and `vmax` parameters individually to the controls object. This means that they can be used for other things, such as determinging the positions of the vertical lines on the histogram below. These are accessed by indexing the `controls` object. For more examples of controlling a scalar argument see [Scalar Arguments](scalar-arguments.ipynb)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "N = 128\n", "im = np.random.randn(N * N).reshape(N, N)\n", "\n", "fig, axs = plt.subplots(1, 2, figsize=(12, 5))\n", "\n", "# plot histogram of pixel intensities\n", "axs[1].hist(im.flatten(), bins=\"auto\")\n", "axs[1].set_title(\"Histogram of Pixel Intensities\")\n", "\n", "# create interactive controls\n", "ctrls = iplt.imshow(im, vmin_vmax=(\"r\", im.min(), im.max()), ax=axs[0])\n", "iplt.axvline(ctrls[\"vmin\"], ax=axs[1], c=\"k\")\n", "_ = iplt.axvline(ctrls[\"vmax\"], ax=axs[1], c=\"k\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Using a Matplotlib RangeSlider\n", "\n", "### But maptlotlib doesn't have range sliders???!?!?\n", "\n", "One of the implicit promises of this library is that it will work equally well both in and out of a jupyter notebook. So it leverages ipywidgets when available but otherwise will use matplotlib widgets. However, ipywidgets has RangeSliders while Matplotlib does not, so have we broken this contract? Happily the answer is no. RangeSliders are being added to matplolibt in https://github.com/matplotlib/matplotlib/pull/18829, and in the meantime they are availiable via `mpl_interactions.widgets.RangeSlider`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from mpl_interactions.widgets import RangeSlider\n", "\n", "fig, axs = plt.subplots(1, 2, figsize=(12, 5))\n", "\n", "# plot histogram of pixel intensities\n", "axs[1].hist(im.flatten(), bins=\"auto\")\n", "\n", "# make thresholding slider\n", "plt.subplots_adjust(bottom=0.25)\n", "s_ax = plt.axes([0.575, 0.1, 0.25, 0.05])\n", "slider = RangeSlider(s_ax, \"threshold\", im.min(), im.max(), valinit=(im.min(), im.max()))\n", "\n", "# create interactive controls\n", "ctrls = iplt.imshow(im, vmin_vmax=slider, ax=axs[0])\n", "iplt.axvline(ctrls[\"vmin\"], ax=axs[1], c=\"k\")\n", "iplt.axvline(ctrls[\"vmax\"], ax=axs[1], c=\"k\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.9.0" } }, "nbformat": 4, "nbformat_minor": 4 }