{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# scikit-learn Toy data sets"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "toc": true
   },
   "source": [
    "<h1>Contents<span class=\"tocSkip\"></span></h1>\n",
    "<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#Pre-requirements\" data-toc-modified-id=\"Pre-requirements-1\"><span class=\"toc-item-num\">1&nbsp;&nbsp;</span>Pre-requirements</a></span><ul class=\"toc-item\"><li><span><a href=\"#Import-dependencies\" data-toc-modified-id=\"Import-dependencies-1.1\"><span class=\"toc-item-num\">1.1&nbsp;&nbsp;</span>Import dependencies</a></span></li><li><span><a href=\"#Notebook-configuration\" data-toc-modified-id=\"Notebook-configuration-1.2\"><span class=\"toc-item-num\">1.2&nbsp;&nbsp;</span>Notebook configuration</a></span></li><li><span><a href=\"#Package-configuration\" data-toc-modified-id=\"Package-configuration-1.3\"><span class=\"toc-item-num\">1.3&nbsp;&nbsp;</span>Package configuration</a></span></li></ul></li><li><span><a href=\"#Data-set-generation\" data-toc-modified-id=\"Data-set-generation-2\"><span class=\"toc-item-num\">2&nbsp;&nbsp;</span>Data set generation</a></span></li><li><span><a href=\"#CNN-clustering-with-data-points-as-input\" data-toc-modified-id=\"CNN-clustering-with-data-points-as-input-3\"><span class=\"toc-item-num\">3&nbsp;&nbsp;</span>CNN clustering with data points as input</a></span></li><li><span><a href=\"#CNN-clustering-with-pre-computed-distances\" data-toc-modified-id=\"CNN-clustering-with-pre-computed-distances-4\"><span class=\"toc-item-num\">4&nbsp;&nbsp;</span>CNN clustering with pre-computed distances</a></span></li><li><span><a href=\"#CNN-clustering-with-pre-computed-neighbourhoods\" data-toc-modified-id=\"CNN-clustering-with-pre-computed-neighbourhoods-5\"><span class=\"toc-item-num\">5&nbsp;&nbsp;</span>CNN clustering with pre-computed neighbourhoods</a></span></li></ul></div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Pre-requirements"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Import dependencies"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-09T15:22:58.067082Z",
     "start_time": "2020-06-09T15:22:57.863688Z"
    }
   },
   "outputs": [],
   "source": [
    "import sys\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib as mpl\n",
    "from sklearn import cluster   # Forked at https://github.com/janjoswig/scikit-learn\n",
    "from sklearn import datasets  # For sklearn test data set creation\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "import cnnclustering.cnn as cnn  # CNN clustering"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This notebook was created using Python 3.8."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-08T09:14:22.691008Z",
     "start_time": "2020-06-08T09:14:22.685971Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3.8.3 (default, May 15 2020, 15:24:35) \n",
      "[GCC 8.3.0]\n"
     ]
    }
   ],
   "source": [
    "# Version information\n",
    "print(sys.version)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Notebook configuration"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-09T15:20:52.376618Z",
     "start_time": "2020-06-09T15:20:52.352120Z"
    }
   },
   "outputs": [],
   "source": [
    "# Matplotlib configuration\n",
    "mpl.rc_file(\n",
    "    \"matplotlibrc\",\n",
    "    use_default_template=False\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-09T15:20:45.262300Z",
     "start_time": "2020-06-09T15:20:45.252405Z"
    }
   },
   "outputs": [],
   "source": [
    "# Axis property defaults for the plots\n",
    "ax_props = {\n",
    "    \"xlabel\": None,\n",
    "    \"ylabel\": None,\n",
    "    \"xlim\": (-2.5, 2.5),\n",
    "    \"ylim\": (-2.5, 2.5),\n",
    "    \"xticks\": (),\n",
    "    \"yticks\": (),\n",
    "    \"aspect\": \"equal\"\n",
    "}\n",
    "\n",
    "# Line plot property defaults\n",
    "line_props = {\n",
    "    \"linewidth\": 0,\n",
    "    \"marker\": '.',\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Optionally, clustering results can be nicely collected in a `pandas` data frame."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Package configuration"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-08T09:14:44.838616Z",
     "start_time": "2020-06-08T09:14:44.836274Z"
    }
   },
   "outputs": [],
   "source": [
    "# Configuration file found?\n",
    "cnn.settings.cfgfile  # If None, no file is provided"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-09T15:52:56.864945Z",
     "start_time": "2020-06-09T15:52:56.847658Z"
    },
    "run_control": {
     "marked": true
    },
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'default_cnn_cutoff': '1',\n",
       " 'default_cnn_offset': '0',\n",
       " 'default_radius_cutoff': '1',\n",
       " 'default_member_cutoff': '2',\n",
       " 'default_fit_policy': 'conservative',\n",
       " 'float_precision': 'sp',\n",
       " 'int_precision': 'sp'}"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Display default settings\n",
    "cnn.settings.defaults"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-11T13:48:26.641740Z",
     "start_time": "2019-09-11T13:48:26.638371Z"
    }
   },
   "source": [
    "## Data set generation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-11T13:48:56.480391Z",
     "start_time": "2019-09-11T13:48:56.477467Z"
    }
   },
   "source": [
    "To see the CNN clustering in action, let's have a look at a handful of basic 2D data sets from scikit-learn (like from https://scikit-learn.org/stable/auto_examples/cluster/plot_cluster_comparison.html)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-09T15:20:37.174346Z",
     "start_time": "2020-06-09T15:20:37.166543Z"
    }
   },
   "outputs": [],
   "source": [
    "# Data set generation parameters\n",
    "np.random.seed(0)\n",
    "n_samples = 2000"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-09T15:20:37.692680Z",
     "start_time": "2020-06-09T15:20:37.673720Z"
    }
   },
   "outputs": [],
   "source": [
    "# Data set generation\n",
    "# circles\n",
    "noisy_circles, _ = datasets.make_circles(\n",
    "    n_samples=n_samples,\n",
    "    factor=.5,\n",
    "    noise=.05\n",
    "    )\n",
    "\n",
    "# moons\n",
    "noisy_moons, _ = datasets.make_moons(\n",
    "    n_samples=n_samples,\n",
    "    noise=.05\n",
    "    )\n",
    "\n",
    "# blobs\n",
    "blobs, _ = datasets.make_blobs(\n",
    "    n_samples=n_samples,\n",
    "    random_state=8\n",
    "    )\n",
    "\n",
    "# None\n",
    "no_structure = np.random.rand(\n",
    "    n_samples, 2\n",
    "    )\n",
    "\n",
    "# aniso\n",
    "random_state = 170\n",
    "X, y = datasets.make_blobs(\n",
    "    n_samples=n_samples,\n",
    "    random_state=random_state\n",
    "    )\n",
    "\n",
    "transformation = [[0.6, -0.6], [-0.4, 0.8]]\n",
    "aniso = np.dot(X, transformation)\n",
    "\n",
    "# varied\n",
    "varied, _ = datasets.make_blobs(\n",
    "    n_samples=n_samples,\n",
    "    cluster_std=[1.0, 2.5, 0.5],\n",
    "    random_state=random_state\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-09T15:20:38.688601Z",
     "start_time": "2020-06-09T15:20:38.678685Z"
    }
   },
   "outputs": [],
   "source": [
    "# Define cluster parameters\n",
    "dsets = [ # \"name\", set, **parameters\n",
    "    ('circles', noisy_circles, {\n",
    "        'radius_cutoff': 0.5,\n",
    "        'cnn_cutoff': 20,\n",
    "        'member_cutoff': 100,\n",
    "        'max_clusters': None\n",
    "        }),\n",
    "    ('moons', noisy_moons, {\n",
    "        'radius_cutoff': 0.5,\n",
    "        'cnn_cutoff': 20,\n",
    "        'member_cutoff': 2,\n",
    "        'max_clusters': None\n",
    "        }),\n",
    "    ('varied', varied, {\n",
    "        'radius_cutoff': 0.28,\n",
    "        'cnn_cutoff': 20,\n",
    "        'member_cutoff': 20,\n",
    "        'max_clusters': None\n",
    "        }),\n",
    "    ('aniso', aniso, {\n",
    "        'radius_cutoff': 0.29,\n",
    "        'cnn_cutoff': 30,\n",
    "        'member_cutoff': 5,\n",
    "        'max_clusters': None\n",
    "         }),\n",
    "    ('blobs', blobs, {\n",
    "        'radius_cutoff': 0.4,\n",
    "        'cnn_cutoff': 20,\n",
    "        'member_cutoff': 2,\n",
    "        'max_clusters': None\n",
    "        }),\n",
    "    ('None', no_structure, {\n",
    "        'radius_cutoff': 0.5,\n",
    "        'cnn_cutoff': 20,\n",
    "        'member_cutoff': 1,\n",
    "        'max_clusters': None\n",
    "        }),\n",
    "    ]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-09T15:20:55.450564Z",
     "start_time": "2020-06-09T15:20:55.122748Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 53584 characters]\n",
      "text/plain": [
       "<Figure size 750x450 with 6 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Plot the original data sets\n",
    "fig, ax = plt.subplots(2, 3)\n",
    "Ax = ax.flatten()\n",
    "\n",
    "for count, (name, data, *_) in enumerate(dsets):\n",
    "    # Fit all datasets to the same value range\n",
    "    data = StandardScaler().fit_transform(data)\n",
    "    # Plot\n",
    "    Ax[count].plot(data[:, 0], data[:, 1], **line_props)\n",
    "    Ax[count].set(**ax_props)\n",
    "    Ax[count].set_title(f'{name}', fontsize=10, pad=4)\n",
    "    \n",
    "fig.subplots_adjust(\n",
    "    left=0, right=1, bottom=0, top=1, wspace=0.1, hspace=0.3 \n",
    "    )\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## CNN clustering with data points as input"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-09T15:37:45.458018Z",
     "start_time": "2020-06-09T15:37:42.499867Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Execution time for call of fit: 0 hours, 0 minutes, 0.2897 seconds\n",
      "--------------------------------------------------------------------------------\n",
      "#points   R         C         min       max       #clusters %largest  %noise    \n",
      "2000      0.500     20        100       None      2         0.500     0.000     \n",
      "--------------------------------------------------------------------------------\n",
      "\n",
      "Execution time for call of fit: 0 hours, 0 minutes, 0.3340 seconds\n",
      "--------------------------------------------------------------------------------\n",
      "#points   R         C         min       max       #clusters %largest  %noise    \n",
      "2000      0.500     20        2         None      2         0.500     0.000     \n",
      "--------------------------------------------------------------------------------\n",
      "\n",
      "Execution time for call of fit: 0 hours, 0 minutes, 0.6569 seconds\n",
      "--------------------------------------------------------------------------------\n",
      "#points   R         C         min       max       #clusters %largest  %noise    \n",
      "2000      0.280     20        20        None      3         0.338     0.114     \n",
      "--------------------------------------------------------------------------------\n",
      "\n",
      "Execution time for call of fit: 0 hours, 0 minutes, 0.3483 seconds\n",
      "--------------------------------------------------------------------------------\n",
      "#points   R         C         min       max       #clusters %largest  %noise    \n",
      "2000      0.290     30        5         None      3         0.319     0.050     \n",
      "--------------------------------------------------------------------------------\n",
      "\n",
      "Execution time for call of fit: 0 hours, 0 minutes, 0.6493 seconds\n",
      "--------------------------------------------------------------------------------\n",
      "#points   R         C         min       max       #clusters %largest  %noise    \n",
      "2000      0.400     20        2         None      3         0.334     0.001     \n",
      "--------------------------------------------------------------------------------\n",
      "\n",
      "Execution time for call of fit: 0 hours, 0 minutes, 0.2841 seconds\n",
      "--------------------------------------------------------------------------------\n",
      "#points   R         C         min       max       #clusters %largest  %noise    \n",
      "2000      0.500     20        1         None      1         1.000     0.000     \n",
      "--------------------------------------------------------------------------------\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 97032 characters]\n",
      "text/plain": [
       "<Figure size 750x450 with 6 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Cluster the sets and plot the result\n",
    "fig, ax = plt.subplots(2, 3)\n",
    "Ax = ax.flatten()\n",
    "\n",
    "for count, (name, data, params) in enumerate(dsets):\n",
    "    # Fit all datasets to the same value range\n",
    "    data = StandardScaler().fit_transform(data)\n",
    "\n",
    "    clustering = cnn.CNN(points=data)\n",
    "    # Calculate neighbours on-the-fly\n",
    "    clustering.fit(**params, policy=\"conservative\")\n",
    "    print()\n",
    "\n",
    "    # Plot\n",
    "    clustering.evaluate(ax=Ax[count], annotate_pos=\"random\")\n",
    "    Ax[count].set(**ax_props)\n",
    "    Ax[count].set_title(f'{name}', fontsize=10, pad=4)\n",
    "    \n",
    "fig.subplots_adjust(\n",
    "    left=0, right=1, bottom=0, top=1, wspace=0.1, hspace=0.3 \n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## CNN clustering with pre-computed distances"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-09T15:52:29.578919Z",
     "start_time": "2020-06-09T15:52:27.697935Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Execution time for call of fit: 0 hours, 0 minutes, 0.1107 seconds\n",
      "--------------------------------------------------------------------------------\n",
      "#points   R         C         min       max       #clusters %largest  %noise    \n",
      "2000      0.500     20        100       None      2         0.500     0.000     \n",
      "--------------------------------------------------------------------------------\n",
      "\n",
      "Execution time for call of fit: 0 hours, 0 minutes, 0.1571 seconds\n",
      "--------------------------------------------------------------------------------\n",
      "#points   R         C         min       max       #clusters %largest  %noise    \n",
      "2000      0.500     20        2         None      2         0.500     0.000     \n",
      "--------------------------------------------------------------------------------\n",
      "\n",
      "Execution time for call of fit: 0 hours, 0 minutes, 0.2057 seconds\n",
      "--------------------------------------------------------------------------------\n",
      "#points   R         C         min       max       #clusters %largest  %noise    \n",
      "2000      0.280     20        20        None      3         0.338     0.114     \n",
      "--------------------------------------------------------------------------------\n",
      "\n",
      "Execution time for call of fit: 0 hours, 0 minutes, 0.1340 seconds\n",
      "--------------------------------------------------------------------------------\n",
      "#points   R         C         min       max       #clusters %largest  %noise    \n",
      "2000      0.290     30        5         None      3         0.319     0.050     \n",
      "--------------------------------------------------------------------------------\n",
      "\n",
      "Execution time for call of fit: 0 hours, 0 minutes, 0.5806 seconds\n",
      "--------------------------------------------------------------------------------\n",
      "#points   R         C         min       max       #clusters %largest  %noise    \n",
      "2000      0.400     20        2         None      3         0.334     0.001     \n",
      "--------------------------------------------------------------------------------\n",
      "\n",
      "Execution time for call of fit: 0 hours, 0 minutes, 0.1047 seconds\n",
      "--------------------------------------------------------------------------------\n",
      "#points   R         C         min       max       #clusters %largest  %noise    \n",
      "2000      0.500     20        1         None      1         1.000     0.000     \n",
      "--------------------------------------------------------------------------------\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 96784 characters]\n",
      "text/plain": [
       "<Figure size 750x450 with 6 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Cluster the sets and plot the result\n",
    "fig, ax = plt.subplots(2, 3)\n",
    "Ax = ax.flatten()\n",
    "\n",
    "for count, (name, data, params) in enumerate(dsets):\n",
    "    # Fit all datasets to the same value range\n",
    "    data = StandardScaler().fit_transform(data)\n",
    "\n",
    "    clustering = cnn.CNN(points=data)\n",
    "    clustering.calc_dist()  # Pre-calculate distances from points\n",
    "    # Calculate neighbours on-the-fly\n",
    "    clustering.fit(**params, policy=\"conservative\")\n",
    "    print()\n",
    "\n",
    "    # Plot\n",
    "    clustering.evaluate(ax=Ax[count], annotate_pos=\"random\")\n",
    "    Ax[count].set(**ax_props)\n",
    "    Ax[count].set_title(f'{name}', fontsize=10, pad=4)\n",
    "    \n",
    "fig.subplots_adjust(\n",
    "    left=0, right=1, bottom=0, top=1, wspace=0.1, hspace=0.3 \n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## CNN clustering with pre-computed neighbourhoods"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-09T16:01:09.992260Z",
     "start_time": "2020-06-09T16:01:09.031178Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Execution time for call of fit: 0 hours, 0 minutes, 0.0118 seconds\n",
      "--------------------------------------------------------------------------------\n",
      "#points   R         C         min       max       #clusters %largest  %noise    \n",
      "2000      0.500     20        100       None      2         0.500     0.000     \n",
      "--------------------------------------------------------------------------------\n",
      "\n",
      "Execution time for call of fit: 0 hours, 0 minutes, 0.0116 seconds\n",
      "--------------------------------------------------------------------------------\n",
      "#points   R         C         min       max       #clusters %largest  %noise    \n",
      "2000      0.500     20        2         None      2         0.500     0.000     \n",
      "--------------------------------------------------------------------------------\n",
      "\n",
      "Execution time for call of fit: 0 hours, 0 minutes, 0.0123 seconds\n",
      "--------------------------------------------------------------------------------\n",
      "#points   R         C         min       max       #clusters %largest  %noise    \n",
      "2000      0.280     20        20        None      3         0.338     0.105     \n",
      "--------------------------------------------------------------------------------\n",
      "\n",
      "Execution time for call of fit: 0 hours, 0 minutes, 0.0151 seconds\n",
      "--------------------------------------------------------------------------------\n",
      "#points   R         C         min       max       #clusters %largest  %noise    \n",
      "2000      0.290     30        5         None      3         0.320     0.046     \n",
      "--------------------------------------------------------------------------------\n",
      "\n",
      "Execution time for call of fit: 0 hours, 0 minutes, 0.0104 seconds\n",
      "--------------------------------------------------------------------------------\n",
      "#points   R         C         min       max       #clusters %largest  %noise    \n",
      "2000      0.400     20        2         None      3         0.334     0.001     \n",
      "--------------------------------------------------------------------------------\n",
      "\n",
      "Execution time for call of fit: 0 hours, 0 minutes, 0.0136 seconds\n",
      "--------------------------------------------------------------------------------\n",
      "#points   R         C         min       max       #clusters %largest  %noise    \n",
      "2000      0.500     20        1         None      1         1.000     0.000     \n",
      "--------------------------------------------------------------------------------\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 96540 characters]\n",
      "text/plain": [
       "<Figure size 750x450 with 6 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Cluster the sets and plot the result\n",
    "fig, ax = plt.subplots(2, 3)\n",
    "Ax = ax.flatten()\n",
    "\n",
    "for count, (name, data, params) in enumerate(dsets):\n",
    "    # Fit all datasets to the same value range\n",
    "    data = StandardScaler().fit_transform(data)\n",
    "\n",
    "    clustering = cnn.CNN(points=data)\n",
    "    clustering.data.points.cKDTree()  # Build search tree on points\n",
    "    clustering.calc_neighbours_from_cKDTree(params[\"radius_cutoff\"])\n",
    "    clustering.fit(**params)  # Fit from precomputed neighbourhoods\n",
    "    print()\n",
    "\n",
    "    # Plot\n",
    "    clustering.evaluate(ax=Ax[count], annotate_pos=\"random\")\n",
    "    Ax[count].set(**ax_props)\n",
    "    Ax[count].set_title(f'{name}', fontsize=10, pad=4)\n",
    "    \n",
    "fig.subplots_adjust(\n",
    "    left=0, right=1, bottom=0, top=1, wspace=0.1, hspace=0.3 \n",
    "    )"
   ]
  }
 ],
 "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.8.3"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": true,
   "title_cell": "Contents",
   "title_sidebar": "Contents",
   "toc_cell": true,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "164.988px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
