{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Import needed libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import mapper\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<b>Step 1: Input data</b><br>\n",
    "    Load the circle data set, circle = $x^2 + y^2 = 1$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "data = mapper.shapes.circle(samples=1000)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Run the following without modification, just preprocessing some variables"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Preprocessing\n",
    "point_labels = None\n",
    "mask = None\n",
    "Gauss_density = mapper.filters.Gauss_density\n",
    "kNN_distance  = mapper.filters.kNN_distance\n",
    "crop = mapper.crop\n",
    "# Custom preprocessing code\n",
    "\n",
    "# End custom preprocessing code\n",
    "data, point_labels = mapper.mask_data(data, mask, point_labels)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "<b>Step 2: Choose metric </b><br>\n",
    "Below we are choosing to use the Euclidean metric"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "intrinsic_metric = False\n",
    "if intrinsic_metric:\n",
    "    is_vector_data = data.ndim != 1\n",
    "    if is_vector_data:\n",
    "        metric = Euclidean            # here we choose Euclidean metric\n",
    "        if metric != 'Euclidean':\n",
    "            raise ValueError('Not implemented')\n",
    "    data = mapper.metric.intrinsic_metric(data, k=1, eps=1.0)\n",
    "is_vector_data = data.ndim != 1\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<b>Step 3: Choose Filter function</b><br>\n",
    "Below we are choosing to use projection to first principal component"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "if is_vector_data:\n",
    "    metricpar = {'metric': 'euclidean'}\n",
    "    f = mapper.filters.dm_eigenvector(data,\n",
    "        metricpar=metricpar,\n",
    "        k=0, mean_center=True)\n",
    "else:\n",
    "    f = mapper.filters.dm_eigenvector(data,\n",
    "        k=0, mean_center=True)\n",
    "mask = None\n",
    "crop = mapper.crop"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<b>Step 4: Select more Mapper parameters</b>\n",
    "Below we choose to use 15 intervals with 50% overlap"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "cover = mapper.cover.cube_cover_primitive(intervals=15, overlap=50.0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below we choose to use single linkage clustering"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "cluster = mapper.single_linkage()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Run the following without modification to run mapper algorithm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "if not is_vector_data:\n",
    "    metricpar = {}\n",
    "mapper_output = mapper.mapper(data, f,\n",
    "    cover=cover,\n",
    "    cluster=cluster,\n",
    "    point_labels=point_labels,\n",
    "    cutoff=None,\n",
    "    metricpar=metricpar)\n",
    "cutoff = mapper.cutoff.first_gap(gap=0.1)\n",
    "mapper_output.cutoff(cutoff, f, cover=cover, simple=False)\n",
    "# mapper_output.draw_scale_graph()\n",
    "# plt.savefig('scale_graph.pdf')\n",
    "# plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<b>Step 5: Choose display parameters</b><br>\n",
    "Choose how to color the vertices (nodes) in mapper output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "nodes = mapper_output.nodes\n",
    "node_color = None\n",
    "point_color = data[:,0]       # coloring nodes in mapper output using average of first coordinate\n",
    "name = 'custom scheme'\n",
    "node_color = mapper_output.postprocess_node_color(node_color, point_color, point_labels)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<b>Step 6:  Output</b><br>\n",
    "Draw TDA mapper graph"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "minsizes = []\n",
    "mapper_output.draw_2D(minsizes=minsizes,\n",
    "    node_color=node_color,\n",
    "    node_color_scheme=name)\n",
    "plt.savefig('mapper_output.pdf')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
