{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "view-in-github"
},
"source": [
""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ozr3W25l4RMG"
},
"source": [
"# Movement Control: Motor Cortex\n",
"\n",
"This notebook contains a series of interactive plots to explore the tuning and population coding principles presented by [Georgopoulos et al (1982)](https://www.jneurosci.org/content/2/11/1527). "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Setup"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"cellView": "form",
"id": "lsLegXKnaptb",
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"#@title {display-mode: \"form\"}\n",
"\n",
"#@markdown Run this cell to set up notebook coding environment.\n",
"import numpy as np\n",
"import math\n",
"import plotly.express as px\n",
"import plotly.graph_objects as go\n",
"from ipywidgets import widgets,interactive \n",
"from numpy import NaN\n",
"import matplotlib.pyplot as plt\n",
"\n",
"my_layout = widgets.Layout()\n",
"# def tuningcurve(theta, b0, b1, b2):\n",
"# return [b0 + b1*math.sin(math.radians(t)) - b2*math.cos(math.radians(t)) for t in theta]\n",
"plt.style.use(\"https://raw.githubusercontent.com/NeuromatchAcademy/course-content/master/nma.mplstyle\")\n",
"\n",
"\n",
"theta=[0,45,90,135,180,225,270,315,360]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Directional Tuning"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "7DWhQraJOr_y"
},
"source": [
"There are two different equations that can be used to describe the directional tuning of neurons in M1. \n",
"\n",
"1. y = b0 + b1*sin(theta) + b2*cos(theta)\n",
"\n",
"2. y = b0 + c1*cos(theta - theta0)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"cellView": "form",
"id": "5detrJopp38Q",
"tags": [
"hide-input"
]
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "18473dc78900493e81ad7a5a2c8f19f8",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(FloatSlider(value=0.0, description='b0', layout=Layout(width='600px'), step=2.0), FloatS…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#@title {display-mode: \"form\"}\n",
"\n",
"#@markdown Run this cell to enable an interactive plot\n",
"#@markdown exploring the parameters b0, b1, and b2 in equation 1.\n",
"\n",
"my_layout.width = '600px'\n",
"style = {'description_width': 'initial'}\n",
"@widgets.interact(\n",
" b0=widgets.FloatSlider(0., min=0., max=100., step=2,\n",
" layout=my_layout),\n",
" b1=widgets.FloatSlider(0., min=0., max=100., step=2,\n",
" layout=my_layout),\n",
" b2=widgets.FloatSlider(0., min=0., max=100., step=2,\n",
" layout=my_layout)\n",
")\n",
"\n",
"def tuning(b0, b1, b2):\n",
" response = [b0 + b1*math.sin(math.radians(t)) + b2*math.cos(math.radians(t)) for t in [0,45,90,135,180,225,270,315,360]]\n",
" fig = go.Figure()\n",
" fig.add_trace(go.Scatter(x=[0,45,90,135,180,225,270,315,360],y=response,line_color='black',name='tuning curve'))\n",
" fig.update_layout(xaxis_title=\"degree\", yaxis_title='spike rate',width=600, height=400)\n",
" fig.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "JdQVtSOBmY_k"
},
"source": [
"- Why is b0 super important for spiking tuning curve functions? \n",
"- What does the ratio betweeen b1 and b2 change?\n",
"- What does the absolute value of b1 and b2 change?"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"cellView": "form",
"id": "GMeQRb7ZeZNN",
"tags": [
"hide-input"
]
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "69f36bfa9cbb4697a1494d3f9b054cc6",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(FloatSlider(value=0.0, description='theta', layout=Layout(width='600px'), max=360.0, ste…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#@title {display-mode: \"form\"}\n",
"\n",
"#@markdown Run this cell to enable an interactive plot\n",
"#@markdown exploring the parameters theta, b0, and c1 in equation 2.\n",
"\n",
"my_layout.width = '600px'\n",
"style = {'description_width': 'initial'}\n",
"@widgets.interact(\n",
" theta=widgets.FloatSlider(0., min=0., max=360., step=2,\n",
" layout=my_layout),\n",
" b0=widgets.FloatSlider(0., min=0., max=100., step=2,\n",
" layout=my_layout),\n",
" c1=widgets.FloatSlider(0., min=0., max=100., step=2,\n",
" layout=my_layout)\n",
")\n",
"\n",
"def preferred_direction(theta, b0, c1):\n",
" response = [b0 + c1*math.cos(math.radians(t-theta)) for t in [0,45,90,135,180,225,270,315,360]]\n",
" fig = go.Figure()\n",
" fig.add_trace(go.Scatter(x=[0,45,90,135,180,225,270,315,360],y=response,line_color='black',name='tuning curve'))\n",
" fig.update_layout(xaxis_title=\"degree\", yaxis_title='spike rate',width=600, height=400)\n",
" fig.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "SYQYSfeIyho3"
},
"source": [
"Challenge: Re-create Figure 4 from the paper using each of the two formulations of the tuning curve. (Hint: the regression coefficient values for the example cell are reported in the paper) \n",
"\n",
"So far, we have been plotting the neuron's response only at the experimentally tested directions. However, with the regression coefficients, we can plot a smooth tuning function with the estimated response at all locations. In the following interactive demos, you can see the result of using the regression (\"fit\") coefficients to estimate the response at all locations. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Directional Tuning index"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"cellView": "form",
"id": "qcpErbvu0A24",
"tags": [
"hide-input"
]
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "95ebc11296ac49dbaf5196fa14e7fcf5",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(FloatSlider(value=0.0, description='theta', max=360.0, step=2.0, style=SliderStyle(descr…"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "d53d0d9ad3cd448c9ba36505c07de6c7",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Label(value='directional tuning index = 0.9890109890109888', layout=Layout(width='800px'))"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#@title {display-mode: \"form\"}\n",
"\n",
"#@markdown Run this cell to create an interactive \n",
"#@markdown plot to investigate the directional tuning index.\n",
"\n",
"slider_theta = widgets.FloatSlider(\n",
" min = 0,\n",
" max=360,\n",
" value=0,\n",
" step=2,\n",
" description='theta',\n",
" style = {'description_width': '100px'},\n",
" disabled=False\n",
")\n",
"\n",
"slider_b0 = widgets.FloatSlider(\n",
" min = 0,\n",
" max=100,\n",
" value=1,\n",
" step=1,\n",
" description='b0',\n",
" style = {'description_width': '100px'},\n",
" disabled=False\n",
")\n",
"\n",
"slider_c1 = widgets.FloatSlider(\n",
" min = 0,\n",
" max=100,\n",
" value=1,\n",
" step=1,\n",
" description='c1',\n",
" style = {'description_width': '100px'},\n",
" disabled=False\n",
")\n",
"\n",
"DTI_readout = widgets.Label(\n",
" value=f'directional tuning index = {NaN}'\n",
")\n",
"DTI_readout.layout.width = '800px'\n",
"\n",
"\n",
"def update_plot(theta_,b0_,c1_):\n",
" fig, ax = plt.subplots(figsize=(8,4),num=1); #specify figure number so that it does not keep creating new ones\n",
" ax.set_xlabel('degree')\n",
" ax.set_ylabel('spike rate')\n",
" \n",
" x = np.arange(0,361,2)\n",
" response = [b0_ + c1_*math.cos(math.radians(t-theta_)) for t in x]\n",
" DI=0\n",
" if ((np.mean(response)>0) | (np.mean(response)<0)) & (b0_!=0):\n",
" DI = (np.max(response) - np.mean(response)) / np.mean(response)\n",
" ax.plot(x,response,color='black')\n",
"\n",
" DTI_readout.value=f'directional tuning index = {DI}'\n",
"\n",
"\n",
"w_dti_ = interactive(update_plot, theta_=slider_theta, b0_= slider_b0, c1_=slider_c1);\n",
"display(w_dti_,DTI_readout)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Polar Plot\n",
"\n",
"Polar plots are a common an be a great way to more intuitively visualize directional tuning curves."
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {
"cellView": "form",
"id": "yox10Zm-wF9k",
"tags": [
"hide-input"
]
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "abce3903ffd747f087f4b69bd6d192f8",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(FloatSlider(value=0.0, description='theta', layout=Layout(width='300px'), max=360.0, ste…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#@title {display-mode: \"form\"}\n",
"\n",
"#@markdown Run this cell to enable the interactive demo.\n",
"\n",
"my_layout.width = '300px'\n",
"style = {'description_width': 'initial'}\n",
"@widgets.interact(\n",
" theta=widgets.FloatSlider(0., min=0., max=360., step=2,\n",
" layout=my_layout),\n",
" b0=widgets.FloatSlider(1., min=0., max=100., step=1,\n",
" layout=my_layout),\n",
" c1=widgets.FloatSlider(1., min=0., max=100., step=1,\n",
" layout=my_layout)\n",
")\n",
"\n",
"def polar_tuning(theta, b0, c1):\n",
" x = np.arange(0,360,2)\n",
" response = [b0 + c1*math.cos(math.radians(t-theta)) for t in x]\n",
"\n",
" fig = go.Figure(data=\n",
" go.Scatterpolar(\n",
" r = response,\n",
" theta = x,\n",
" mode='lines'\n",
" ))\n",
"\n",
" fig.update_layout(showlegend=False,height = 400, width=400)\n",
" fig.show()\n",
"\n",
"\n",
"# #peak should be halfway between the two, and minimum spike rate above zero\n",
"\n",
"# response = tuningcurve(theta,b0,b1,b2) \n",
"\n",
"# fig = go.Figure(data=\n",
"# go.Scatterpolar(\n",
"# r = response,\n",
"# theta = theta,\n",
"# ))\n",
"\n",
"# fig.update_layout(showlegend=False,height = 400, width=400)\n",
"# fig.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Population coding\n",
"\n",
"In this section, you can examine population tuning using these types of neurons.\n",
" > For this demo, c1 = 1 and b0 = 1"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {
"cellView": "form",
"id": "TLsIOudOxLgB",
"tags": [
"hide-input"
]
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "6dfc4a64fc0248c49a795d522247df38",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(FloatSlider(value=0.0, description='theta_1', layout=Layout(width='400px'), max=360.0, s…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#@title {display-mode: \"form\"}\n",
"\n",
"#@markdown Run this cell to enable the interactive demo.\n",
"\n",
"my_layout.width = '400px'\n",
"style = {'description_width': 'initial'}\n",
"@widgets.interact(\n",
" theta_1=widgets.FloatSlider(0., min=0., max=360., step=2,\n",
" layout=my_layout),\n",
" theta_2=widgets.FloatSlider(0., min=0., max=360., step=2,\n",
" layout=my_layout),\n",
" theta_3=widgets.FloatSlider(0., min=0., max=360., step=2,\n",
" layout=my_layout)\n",
")\n",
"\n",
"def multineuron_tuning(theta_1, theta_2, theta_3):\n",
" b0 = 1\n",
" c1 = 1\n",
" x = np.arange(0,360,1)\n",
" N_1 = [b0 + c1*math.cos(math.radians(t-theta_1)) for t in x]\n",
" N_2 = [b0 + c1*math.cos(math.radians(t-theta_2)) for t in x]\n",
" N_3 = [b0 + c1*math.cos(math.radians(t-theta_3)) for t in x]\n",
" fig = go.Figure()\n",
" fig.add_trace(go.Scatter(x=x,y=N_1,name='neuron 1'))\n",
" fig.add_trace(go.Scatter(x=x,y=N_2,name='neuron 2'))\n",
" fig.add_trace(go.Scatter(x=x,y=N_3,name='neuron 3'))\n",
" fig.update_layout(xaxis_title=\"degree\", yaxis_title='spike rate',width=600, height=400)\n",
" fig.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Population manifolds\n",
"\n",
"In 3-dimensions, we can visualize how the firing rate of neurons among the population combine to define a unique location in 2-D space (0-360 degrees). \n",
" > For this demo, c1 = 1 and b0 = 1\n",
" \n",
"Notice that with just one neuron (ie. when all 3 neurons have the same direction selectivity), you cannot encode 2-Dimensional space. \n",
" > Puzzle: what does the difference in tuning preference between two neurons need to be in order to encode 360 degrees with equal magnitude at each location? Does it depend on the relative tuning preference between/among the neurons or on the direction from which you view the space? Or both?\n",
"\n",
"**The *perspective* from which you view the neural activity in 2D space (the 2D manifold) is analagous to different convergent/divergent synaptic connectivity of the population on two post-synaptic (downstream) neurons.** We will uncover this concept further when we talk about the Churchland lab's work on the motor cortex later in the course ."
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {
"cellView": "form",
"id": "D0YbppQSlCn6",
"tags": [
"hide-input"
]
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "517e78b139f841ccb6f80cef9ecf6589",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(FloatSlider(value=0.0, description='theta_1', layout=Layout(width='400px'), max=360.0, s…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#@title {display-mode: \"form\"}\n",
"\n",
"#@markdown Run this cell to enable the interactive demo\n",
"\n",
"my_layout.width = '400px'\n",
"style = {'description_width': 'initial'}\n",
"@widgets.interact(\n",
" theta_1=widgets.FloatSlider(0., min=0., max=360., step=2,\n",
" layout=my_layout),\n",
" theta_2=widgets.FloatSlider(0., min=0., max=360., step=2,\n",
" layout=my_layout),\n",
" theta_3=widgets.FloatSlider(0., min=0., max=360., step=2,\n",
" layout=my_layout),\n",
")\n",
"\n",
"def multineuron_tuning_3D(theta_1, theta_2, theta_3): #, b0, c1):\n",
" b0 = 1\n",
" c1 = 1\n",
" x = np.arange(0,360,1)\n",
" N_1 = [b0 + c1*math.cos(math.radians(t-theta_1)) for t in x]\n",
" N_2 = [b0 + c1*math.cos(math.radians(t-theta_2)) for t in x]\n",
" N_3 = [b0 + c1*math.cos(math.radians(t-theta_3)) for t in x]\n",
" fig = go.Figure()\n",
" fig.add_trace(go.Scatter3d(x=N_1,y=N_2,z = N_3, line_color='black'))\n",
" fig.update_layout(width=500, height=500)\n",
" fig.show()"
]
}
],
"metadata": {
"colab": {
"authorship_tag": "ABX9TyPyHkRvfLoln7YTJkWFswQg",
"collapsed_sections": [],
"include_colab_link": true,
"name": "NotebookColab_Georgopoulus1982.ipynb",
"provenance": []
},
"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.13"
},
"widgets": {
"application/vnd.jupyter.widget-state+json": {
"state": {
"00310dc7f45d450a8f6a8063bc57a557": {
"model_module": "@jupyter-widgets/output",
"model_module_version": "1.0.0",
"model_name": "OutputModel",
"state": {
"layout": "IPY_MODEL_3ceea37bb4c04c9aa3896ba612e18e0b",
"outputs": [
{
"data": {
"application/vnd.plotly.v1+json": {
"config": {
"plotlyServerURL": "https://plot.ly"
},
"data": [
{
"line": {
"color": "black"
},
"type": "scatter3d",
"x": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"y": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"z": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
],
"layout": {
"height": 600,
"scene": {
"aspectmode": "auto",
"aspectratio": {
"x": 1,
"y": 1,
"z": 1
},
"camera": {
"center": {
"x": 0,
"y": 0,
"z": 0
},
"eye": {
"x": 0.7590807023729994,
"y": 0.7590807023729993,
"z": 0.7590807023729993
},
"projection": {
"type": "perspective"
},
"up": {
"x": 0,
"y": 0,
"z": 1
}
}
},
"template": {
"data": {
"bar": [
{
"error_x": {
"color": "#2a3f5f"
},
"error_y": {
"color": "#2a3f5f"
},
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
},
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "bar"
}
],
"barpolar": [
{
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
},
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "barpolar"
}
],
"carpet": [
{
"aaxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "white",
"linecolor": "white",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f"
},
"baxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "white",
"linecolor": "white",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f"
},
"type": "carpet"
}
],
"choropleth": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "choropleth"
}
],
"contour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "contour"
}
],
"contourcarpet": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "contourcarpet"
}
],
"heatmap": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "heatmap"
}
],
"heatmapgl": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "heatmapgl"
}
],
"histogram": [
{
"marker": {
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "histogram"
}
],
"histogram2d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2d"
}
],
"histogram2dcontour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2dcontour"
}
],
"mesh3d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "mesh3d"
}
],
"parcoords": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "parcoords"
}
],
"pie": [
{
"automargin": true,
"type": "pie"
}
],
"scatter": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatter"
}
],
"scatter3d": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatter3d"
}
],
"scattercarpet": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattercarpet"
}
],
"scattergeo": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergeo"
}
],
"scattergl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergl"
}
],
"scattermapbox": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattermapbox"
}
],
"scatterpolar": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolar"
}
],
"scatterpolargl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolargl"
}
],
"scatterternary": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterternary"
}
],
"surface": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "surface"
}
],
"table": [
{
"cells": {
"fill": {
"color": "#EBF0F8"
},
"line": {
"color": "white"
}
},
"header": {
"fill": {
"color": "#C8D4E3"
},
"line": {
"color": "white"
}
},
"type": "table"
}
]
},
"layout": {
"annotationdefaults": {
"arrowcolor": "#2a3f5f",
"arrowhead": 0,
"arrowwidth": 1
},
"autotypenumbers": "strict",
"coloraxis": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"colorscale": {
"diverging": [
[
0,
"#8e0152"
],
[
0.1,
"#c51b7d"
],
[
0.2,
"#de77ae"
],
[
0.3,
"#f1b6da"
],
[
0.4,
"#fde0ef"
],
[
0.5,
"#f7f7f7"
],
[
0.6,
"#e6f5d0"
],
[
0.7,
"#b8e186"
],
[
0.8,
"#7fbc41"
],
[
0.9,
"#4d9221"
],
[
1,
"#276419"
]
],
"sequential": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"sequentialminus": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
]
},
"colorway": [
"#636efa",
"#EF553B",
"#00cc96",
"#ab63fa",
"#FFA15A",
"#19d3f3",
"#FF6692",
"#B6E880",
"#FF97FF",
"#FECB52"
],
"font": {
"color": "#2a3f5f"
},
"geo": {
"bgcolor": "white",
"lakecolor": "white",
"landcolor": "#E5ECF6",
"showlakes": true,
"showland": true,
"subunitcolor": "white"
},
"hoverlabel": {
"align": "left"
},
"hovermode": "closest",
"mapbox": {
"style": "light"
},
"paper_bgcolor": "white",
"plot_bgcolor": "#E5ECF6",
"polar": {
"angularaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"bgcolor": "#E5ECF6",
"radialaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
}
},
"scene": {
"xaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
},
"yaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
},
"zaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
}
},
"shapedefaults": {
"line": {
"color": "#2a3f5f"
}
},
"ternary": {
"aaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"baxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"bgcolor": "#E5ECF6",
"caxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
}
},
"title": {
"x": 0.05
},
"xaxis": {
"automargin": true,
"gridcolor": "white",
"linecolor": "white",
"ticks": "",
"title": {
"standoff": 15
},
"zerolinecolor": "white",
"zerolinewidth": 2
},
"yaxis": {
"automargin": true,
"gridcolor": "white",
"linecolor": "white",
"ticks": "",
"title": {
"standoff": 15
},
"zerolinecolor": "white",
"zerolinewidth": 2
}
}
},
"width": 600
}
},
"text/html": "