{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Minmum Distortion Embedding with Anchored Constraints\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import numpy as np\nimport time\nfrom fury.window import record\n\nfrom helios import NetworkDraw\nfrom helios.layouts.mde import MDE\n\n# from https://github.com/cvxgrp/pymde/blob/main/examples/anchor_constraints.ipynb\n\ndepth = 9\nn_items = 2**(depth + 1) - 1\n\nedges = []\nstack = [0]\nwhile stack:\n    root = stack.pop()\n    first_child = root*2 + 1\n    second_child = root*2 + 2\n    if first_child < n_items:\n        edges.append([root, first_child])\n        stack.append(first_child)\n    if second_child < n_items:\n        edges.append([root, second_child])\n        stack.append(second_child)\n\n# these are the indices of the nodes that we will pin in place\nanchors = np.arange(2**depth) + 2**depth - 1\n\n\nradius = 20\n\n# pin the root to be at (0, 0), and the leaves to be spaced uniformly on a circle\nangles = np.linspace(0, 2*np.pi, anchors.shape[0] + 1)[1:]\nanchors_pos = radius * np.stack([np.sin(angles), np.cos(angles)], axis=1)\ncenters = np.random.normal(size=(n_items, 2))*5\ncenters[anchors] = anchors_pos.copy()\n\n\nnetwork_draw = NetworkDraw(\n        positions=centers, \n        scales=.4,\n        node_edge_width=0,\n        #colors=(1, 0,0),\n        edge_line_opacity=.5,\n        edge_line_color=(0, 0, 0),\n        marker='3d',\n        window_size=(500, 500),\n        edges=np.array(edges)\n)\n\nmde = MDE(\n    np.array(edges), network_draw,\n    constraint_name='anchored',\n    anchors=anchors.astype('float32'),\n    anchors_pos=anchors_pos.astype('float32'),\n    use_shortest_path=True\n)\n\n\ninteractive = False\nif not interactive:\n    mde.start(\n        100, 1, 300, \n        record_positions=False, without_iren_start=True)\n    time.sleep(30)\n    mde.stop()\nelse:\n    mde.start(\n        3, 300, 1, \n        record_positions=True, without_iren_start=False)\n\nif interactive:\n    network_draw.showm.initialize()\n    network_draw.showm.start()\n\nrecord(\n    network_draw.showm.scene, out_path='viz_mde.png', size=(600, 600))"
      ]
    }
  ],
  "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.5"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}