{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Plotting routines in `touchsim`\n", "The `touchsim` package uses `holoviews` for plotting." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import touchsim as ts\n", "from touchsim.plotting import plot, figsave\n", "import numpy as np\n", "import holoviews as hv\n", "hv.notebook_extension()\n", "%output holomap='scrubber' # animate holomaps\n", "\n", "import warnings\n", "warnings.simplefilter(\"ignore\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Hand model" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plot() # short for plot(ts.hand_surface)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Regions labels and the coordinate system can be overlaid on the plot." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%output size=250\n", "plot(tags=True,coord=10) # coord sets the lengths of the coordinate axes in mm" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Visualising `AfferentPopulation` objects" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = ts.affpop_hand(region='D2d')\n", "plot(a,size=10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Plots can be overlaid using the `*` operator.\n", "\n", "Plots are `holoviews` objects and can be indexed to only show, say, a specific afferent population. The `*` operator overlays different plots (e.g. the hand outline and the afferent locations, as shown below)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plot(region='D2d') * plot(a,size=10)['PC']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "New subpanels can be added using the `+` operator." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "(plot(region='D2d') * plot(a,size=10)['SA1']) + (plot(region='D2d') * plot(a,size=10)['RA']) + (plot(region='D2d') * plot(a,size=10)['PC'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The first index of an `AfferentPopulation` plot object is the afferent type, while the next two indices are pixel coordinates." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# zoom into fingertip\n", "plot(a,size=10)[:,120:140,450:475]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Visualising `Stimulus` objects\n", "Plotting a `Stimulus` object shows the trace of all pins by default." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s = ts.stim_ramp(len=0.25,amp=.1,ramp_len=0.05)\n", "plot(s)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s += ts.stim_sine(freq=25.,len=.25,loc=[1.,1.])\n", "plot(s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pin traces can also be shown in a grid view." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plot(s,grid=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pin positions can also be shown spatially." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s = ts.stim_indent_shape(ts.shape_circle(hdiff=0.5,pins_per_mm=2,radius=3),ts.stim_ramp(len=0.1))\n", "plot(s,spatial=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The spatial view can be animated with pin depths indicated by color." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plot(region='D2d') * plot(s,spatial=True,bin=10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Visualising `Response` objects\n", "Plotting a `Response` object shows the spike trains of all included neurons" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = ts.affpop_hand(region='D2')\n", "s = ts.stim_sine(freq=50.,amp=0.1,len=0.5)\n", "r = a.response(s)\n", "plot(r)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The second index is the time index." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plot(r)[:,0:0.2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Responses can also be plotted spatially, in which case the size of each dot scaled with the neuron's firing rate." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%output size=150 # increase size of plot by 150%\n", "plot(region='D2') * plot(r,spatial=True,scaling_factor=.1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Alternatively, firing rate can be indicated by color instead:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plot(region='D2') * plot(r,spatial=True,scale=False)[:,'RA'] + plot(region='D2') * plot(r,spatial=True,scale=False)[:,'PC']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Responses in spatial view can also be shown animated if a bin size (in ms) is given." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plot(region='D2') * plot(r,spatial=True,bin=10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Advanced example (might be slow to compute)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "contact_locs = np.zeros((2,2))\n", "contact_locs[0] = np.array([0.,0.])\n", "contact_locs[1] = np.array([150.,0])\n", " \n", "a = ts.affpop_hand(noisy=False)\n", "s = ts.stim_indent_shape(contact_locs,ts.stim_ramp(amp=0.75,len=.2,ramp_len=0.05,ramp_type='lin',pin_radius=5.,pad_len=0.025))\n", "r = a.response(s)\n", "plot(r)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plot() * plot(r,spatial=True,bin=10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Saving figures and animations\n", "Figures can be saved using the `figsave` function; figure size and resolution can be controlled using the `size` and `dpi` parameters, respectively." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "figsave(plot(),'test_fig',size=150,dpi=50)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When the `gif` format is selected, animations will be saved as animated gifs; their framerate can be controlled with the `fps` parameter" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "bin = 50\n", "fig = plot(s,bin=bin) + plot()*plot(r,spatial=True,bin=bin)\n", "figsave(fig,'test_gif',size=150,fps=5,fmt='gif')" ] } ], "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.6.10" } }, "nbformat": 4, "nbformat_minor": 4 }