diff --git a/docs/cookbook/floweaver-path/README.md b/docs/cookbook/floweaver-path/README.md new file mode 100644 index 0000000..f0dd4e5 --- /dev/null +++ b/docs/cookbook/floweaver-path/README.md @@ -0,0 +1,51 @@ +# floweaver-path example + +![Demo](https://github.com/fullflu/floweaver-path/blob/master/demo/floweaver_path_demo.gif) + +I implement [floweaver-path](https://github.com/fullflu/floweaver-path), an extension of the [floweaver](https://sankeyview.readthedocs.io/en/latest/) to handle the visualization of paths that pass through a selected node. + +It would be reasonable to maintain floweaver-path apart from the original floweaver at the moment. +Therefore, I describe only the summary of the extension and put the minimum resources (`data/template.csv` and `template_before_separation.ipynb`) here. + +Please check my repository above if you want to know the details of how floweaver-path works. + +If you have any questions, please feel free to ask me ([@fullflu](https://github.com/fullflu)). + +## Summary +We focus on the visualization of longitudinal data. + +The idea of our visualization is based on [pathSankey](https://bl.ocks.org/jeinarsson/e37aa55c3b0e11ae6fa1), that is an extension of [d3-sankey](https://github.com/d3/d3-sankey). + +The color of paths that pass through a selected node is yellow-green (highlighted), and that of other paths is gray. + +You can interactively select a node by using dropdowns in jupyter notebook. + +We have two technical contributions to the field of visualization using Sankey diagrams. + +One is to extend the layer number: +- Ordinary Sankey diagrams can only visualize paths between 2 layers. +- pathSankey can only visualize paths between 3 layers. +- We can visualize the comparison of paths between two layers before and after (up to 5 layers). + +The other is to create a notebook that can interact with users. We integrate several functions of ipywidgets into floweaver. + +## Requirement + +### in this repository (using pip or conda) +- floweaver (==2.0.0a5) +- ipysankeywidget (==0.2.5) + +### in floweaver-path repository (using docker) +- docker (installs two libraries: floweaver, ipysankeywidget) + +### in both repositories +- input file (`*.csv, *.pickle or *.xlsx` should be put in `data` directory) + + +## Structure +``` +├── README.md +├── data +│   └── template.csv +└── template_before_separation.ipynb +``` \ No newline at end of file diff --git a/docs/cookbook/floweaver-path/data/template.csv b/docs/cookbook/floweaver-path/data/template.csv new file mode 100644 index 0000000..2f1e23e --- /dev/null +++ b/docs/cookbook/floweaver-path/data/template.csv @@ -0,0 +1,401 @@ +index,date,x1,x3 +0,2016/04/01,4,4 +0,2016/10/01,4,4 +0,2017/04/01,1,4 +0,2017/10/01,2,1 +1,2016/04/01,1,4 +1,2016/10/01,4,2 +1,2017/04/01,1,3 +1,2017/10/01,3,4 +2,2016/04/01,2,4 +2,2016/10/01,3,3 +2,2017/04/01,3,2 +2,2017/10/01,2,3 +3,2016/04/01,4,4 +3,2016/10/01,3,1 +3,2017/04/01,4,3 +3,2017/10/01,3,3 +4,2016/04/01,1,2 +4,2016/10/01,4,1 +4,2017/04/01,4,2 +4,2017/10/01,1,1 +5,2016/04/01,1,4 +5,2016/10/01,1,3 +5,2017/04/01,4,3 +5,2017/10/01,3,3 +6,2016/04/01,1,3 +6,2016/10/01,1,3 +6,2017/04/01,1,4 +6,2017/10/01,2,4 +7,2016/04/01,1,4 +7,2016/10/01,3,3 +7,2017/04/01,4,4 +7,2017/10/01,3,4 +8,2016/04/01,3,3 +8,2016/10/01,3,3 +8,2017/04/01,2,1 +8,2017/10/01,4,3 +9,2016/04/01,2,2 +9,2016/10/01,1,1 +9,2017/04/01,1,3 +9,2017/10/01,2,3 +10,2016/04/01,3,1 +10,2016/10/01,4,1 +10,2017/04/01,2,4 +10,2017/10/01,3,2 +11,2016/04/01,1,4 +11,2016/10/01,4,4 +11,2017/04/01,4,4 +11,2017/10/01,3,3 +12,2016/04/01,4,4 +12,2016/10/01,2,2 +12,2017/04/01,1,3 +12,2017/10/01,2,1 +13,2016/04/01,3,4 +13,2016/10/01,4,3 +13,2017/04/01,4,1 +13,2017/10/01,1,1 +14,2016/04/01,2,2 +14,2016/10/01,1,1 +14,2017/04/01,1,4 +14,2017/10/01,1,2 +15,2016/04/01,2,3 +15,2016/10/01,3,3 +15,2017/04/01,4,1 +15,2017/10/01,1,3 +16,2016/04/01,1,4 +16,2016/10/01,4,2 +16,2017/04/01,2,2 +16,2017/10/01,3,4 +17,2016/04/01,3,2 +17,2016/10/01,4,1 +17,2017/04/01,4,1 +17,2017/10/01,2,2 +18,2016/04/01,1,2 +18,2016/10/01,2,1 +18,2017/04/01,3,2 +18,2017/10/01,3,4 +19,2016/04/01,1,3 +19,2016/10/01,2,2 +19,2017/04/01,3,2 +19,2017/10/01,2,4 +20,2016/04/01,2,4 +20,2016/10/01,1,2 +20,2017/04/01,1,2 +20,2017/10/01,1,1 +21,2016/04/01,2,2 +21,2016/10/01,3,2 +21,2017/04/01,3,1 +21,2017/10/01,3,3 +22,2016/04/01,3,4 +22,2016/10/01,4,3 +22,2017/04/01,3,2 +22,2017/10/01,3,1 +23,2016/04/01,4,2 +23,2016/10/01,2,3 +23,2017/04/01,3,2 +23,2017/10/01,1,2 +24,2016/04/01,2,2 +24,2016/10/01,4,4 +24,2017/04/01,1,1 +24,2017/10/01,2,2 +25,2016/04/01,1,2 +25,2016/10/01,4,2 +25,2017/04/01,1,1 +25,2017/10/01,3,1 +26,2016/04/01,1,2 +26,2016/10/01,1,2 +26,2017/04/01,4,2 +26,2017/10/01,1,3 +27,2016/04/01,4,3 +27,2016/10/01,3,1 +27,2017/04/01,1,1 +27,2017/10/01,2,2 +28,2016/04/01,3,1 +28,2016/10/01,3,2 +28,2017/04/01,4,1 +28,2017/10/01,4,3 +29,2016/04/01,1,2 +29,2016/10/01,2,2 +29,2017/04/01,2,3 +29,2017/10/01,3,2 +30,2016/04/01,3,3 +30,2016/10/01,3,1 +30,2017/04/01,4,1 +30,2017/10/01,1,2 +31,2016/04/01,2,4 +31,2016/10/01,1,2 +31,2017/04/01,4,3 +31,2017/10/01,4,1 +32,2016/04/01,2,2 +32,2016/10/01,3,1 +32,2017/04/01,2,3 +32,2017/10/01,3,4 +33,2016/04/01,3,3 +33,2016/10/01,1,4 +33,2017/04/01,1,1 +33,2017/10/01,2,3 +34,2016/04/01,1,2 +34,2016/10/01,4,4 +34,2017/04/01,3,3 +34,2017/10/01,1,1 +35,2016/04/01,1,1 +35,2016/10/01,2,2 +35,2017/04/01,2,2 +35,2017/10/01,4,1 +36,2016/04/01,1,2 +36,2016/10/01,1,4 +36,2017/04/01,3,4 +36,2017/10/01,4,1 +37,2016/04/01,2,1 +37,2016/10/01,2,2 +37,2017/04/01,3,4 +37,2017/10/01,3,2 +38,2016/04/01,1,4 +38,2016/10/01,3,1 +38,2017/04/01,1,4 +38,2017/10/01,4,3 +39,2016/04/01,2,2 +39,2016/10/01,1,4 +39,2017/04/01,4,2 +39,2017/10/01,1,3 +40,2016/04/01,1,1 +40,2016/10/01,1,3 +40,2017/04/01,4,2 +40,2017/10/01,1,1 +41,2016/04/01,2,3 +41,2016/10/01,2,2 +41,2017/04/01,1,3 +41,2017/10/01,1,3 +42,2016/04/01,4,3 +42,2016/10/01,4,3 +42,2017/04/01,2,3 +42,2017/10/01,4,1 +43,2016/04/01,3,2 +43,2016/10/01,2,1 +43,2017/04/01,2,1 +43,2017/10/01,2,2 +44,2016/04/01,3,1 +44,2016/10/01,2,2 +44,2017/04/01,3,4 +44,2017/10/01,1,2 +45,2016/04/01,3,2 +45,2016/10/01,4,1 +45,2017/04/01,4,3 +45,2017/10/01,2,1 +46,2016/04/01,4,2 +46,2016/10/01,3,1 +46,2017/04/01,4,2 +46,2017/10/01,1,3 +47,2016/04/01,4,2 +47,2016/10/01,1,3 +47,2017/04/01,1,3 +47,2017/10/01,1,3 +48,2016/04/01,1,3 +48,2016/10/01,4,2 +48,2017/04/01,1,2 +48,2017/10/01,3,1 +49,2016/04/01,1,2 +49,2016/10/01,2,2 +49,2017/04/01,1,2 +49,2017/10/01,2,2 +50,2016/04/01,1,3 +50,2016/10/01,4,3 +50,2017/04/01,4,1 +50,2017/10/01,2,4 +51,2016/04/01,1,4 +51,2016/10/01,3,2 +51,2017/04/01,4,1 +51,2017/10/01,2,2 +52,2016/04/01,2,2 +52,2016/10/01,4,2 +52,2017/04/01,4,3 +52,2017/10/01,1,3 +53,2016/04/01,3,3 +53,2016/10/01,3,3 +53,2017/04/01,4,4 +53,2017/10/01,4,1 +54,2016/04/01,4,2 +54,2016/10/01,3,2 +54,2017/04/01,1,3 +54,2017/10/01,4,3 +55,2016/04/01,3,2 +55,2016/10/01,1,4 +55,2017/04/01,4,1 +55,2017/10/01,4,3 +56,2016/04/01,3,3 +56,2016/10/01,3,3 +56,2017/04/01,4,3 +56,2017/10/01,2,1 +57,2016/04/01,4,3 +57,2016/10/01,3,3 +57,2017/04/01,4,2 +57,2017/10/01,3,1 +58,2016/04/01,2,1 +58,2016/10/01,1,4 +58,2017/04/01,4,2 +58,2017/10/01,2,2 +59,2016/04/01,3,2 +59,2016/10/01,4,1 +59,2017/04/01,4,3 +59,2017/10/01,3,3 +60,2016/04/01,3,2 +60,2016/10/01,1,3 +60,2017/04/01,3,3 +60,2017/10/01,2,3 +61,2016/04/01,1,1 +61,2016/10/01,2,3 +61,2017/04/01,2,3 +61,2017/10/01,3,3 +62,2016/04/01,4,4 +62,2016/10/01,2,1 +62,2017/04/01,2,2 +62,2017/10/01,1,3 +63,2016/04/01,2,3 +63,2016/10/01,1,1 +63,2017/04/01,2,2 +63,2017/10/01,4,4 +64,2016/04/01,4,4 +64,2016/10/01,1,4 +64,2017/04/01,2,3 +64,2017/10/01,4,1 +65,2016/04/01,1,3 +65,2016/10/01,4,3 +65,2017/04/01,3,1 +65,2017/10/01,1,1 +66,2016/04/01,3,1 +66,2016/10/01,3,3 +66,2017/04/01,3,3 +66,2017/10/01,2,3 +67,2016/04/01,2,2 +67,2016/10/01,2,1 +67,2017/04/01,2,2 +67,2017/10/01,4,3 +68,2016/04/01,2,1 +68,2016/10/01,4,1 +68,2017/04/01,4,4 +68,2017/10/01,1,3 +69,2016/04/01,4,3 +69,2016/10/01,4,1 +69,2017/04/01,3,4 +69,2017/10/01,4,3 +70,2016/04/01,2,4 +70,2016/10/01,3,1 +70,2017/04/01,2,1 +70,2017/10/01,3,4 +71,2016/04/01,1,4 +71,2016/10/01,3,4 +71,2017/04/01,2,2 +71,2017/10/01,2,3 +72,2016/04/01,1,3 +72,2016/10/01,4,3 +72,2017/04/01,1,3 +72,2017/10/01,1,4 +73,2016/04/01,2,3 +73,2016/10/01,2,2 +73,2017/04/01,1,1 +73,2017/10/01,2,3 +74,2016/04/01,1,1 +74,2016/10/01,4,2 +74,2017/04/01,3,3 +74,2017/10/01,3,3 +75,2016/04/01,4,2 +75,2016/10/01,2,2 +75,2017/04/01,1,3 +75,2017/10/01,2,4 +76,2016/04/01,3,3 +76,2016/10/01,3,4 +76,2017/04/01,1,2 +76,2017/10/01,4,1 +77,2016/04/01,2,2 +77,2016/10/01,1,3 +77,2017/04/01,3,4 +77,2017/10/01,2,3 +78,2016/04/01,3,3 +78,2016/10/01,2,4 +78,2017/04/01,3,2 +78,2017/10/01,1,3 +79,2016/04/01,3,4 +79,2016/10/01,4,4 +79,2017/04/01,2,1 +79,2017/10/01,3,2 +80,2016/04/01,1,3 +80,2016/10/01,4,3 +80,2017/04/01,2,3 +80,2017/10/01,3,1 +81,2016/04/01,4,4 +81,2016/10/01,2,1 +81,2017/04/01,3,4 +81,2017/10/01,1,1 +82,2016/04/01,4,4 +82,2016/10/01,4,4 +82,2017/04/01,3,3 +82,2017/10/01,3,4 +83,2016/04/01,4,3 +83,2016/10/01,1,3 +83,2017/04/01,2,3 +83,2017/10/01,4,4 +84,2016/04/01,2,4 +84,2016/10/01,1,2 +84,2017/04/01,3,3 +84,2017/10/01,4,3 +85,2016/04/01,3,4 +85,2016/10/01,3,4 +85,2017/04/01,4,1 +85,2017/10/01,2,4 +86,2016/04/01,1,3 +86,2016/10/01,1,3 +86,2017/04/01,4,2 +86,2017/10/01,4,4 +87,2016/04/01,4,2 +87,2016/10/01,1,1 +87,2017/04/01,3,1 +87,2017/10/01,1,4 +88,2016/04/01,2,1 +88,2016/10/01,3,1 +88,2017/04/01,1,1 +88,2017/10/01,2,4 +89,2016/04/01,1,3 +89,2016/10/01,3,4 +89,2017/04/01,3,4 +89,2017/10/01,4,2 +90,2016/04/01,4,4 +90,2016/10/01,4,4 +90,2017/04/01,4,3 +90,2017/10/01,1,1 +91,2016/04/01,3,2 +91,2016/10/01,2,3 +91,2017/04/01,4,2 +91,2017/10/01,4,3 +92,2016/04/01,4,3 +92,2016/10/01,4,3 +92,2017/04/01,2,1 +92,2017/10/01,1,3 +93,2016/04/01,3,1 +93,2016/10/01,1,1 +93,2017/04/01,3,1 +93,2017/10/01,2,2 +94,2016/04/01,2,4 +94,2016/10/01,2,3 +94,2017/04/01,2,4 +94,2017/10/01,1,3 +95,2016/04/01,4,3 +95,2016/10/01,1,4 +95,2017/04/01,1,3 +95,2017/10/01,1,4 +96,2016/04/01,3,3 +96,2016/10/01,1,2 +96,2017/04/01,1,3 +96,2017/10/01,4,2 +97,2016/04/01,3,1 +97,2016/10/01,1,2 +97,2017/04/01,4,2 +97,2017/10/01,2,4 +98,2016/04/01,3,4 +98,2016/10/01,1,1 +98,2017/04/01,3,4 +98,2017/10/01,1,3 +99,2016/04/01,2,3 +99,2016/10/01,4,4 +99,2017/04/01,4,1 +99,2017/10/01,4,1 diff --git a/docs/cookbook/floweaver-path/template_before_separation.ipynb b/docs/cookbook/floweaver-path/template_before_separation.ipynb new file mode 100644 index 0000000..a03e7b1 --- /dev/null +++ b/docs/cookbook/floweaver-path/template_before_separation.ipynb @@ -0,0 +1,485 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# libraries" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "import pandas as pd\n", + "import numpy as np\n", + "import pickle\n", + "from IPython.display import display\n", + "from ipywidgets import interact, Dropdown\n", + "from floweaver import ProcessGroup, Waypoint, Partition, Bundle, SankeyDefinition, weave\n", + "from ipysankeywidget import SankeyWidget\n", + "from IPython.display import clear_output" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# modules" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## variables" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "data_dir = \"data\"\n", + "base_extensions = [\"csv\", \"xlsx\", \"pickle\"]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## functions" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "def extract_files(extensions=base_extensions):\n", + " file_candidate = os.listdir(data_dir)\n", + " file_list = [os.path.join(data_dir, file_path) for file_path in file_candidate\n", + " if sum([extension == file_path.split(\".\")[-1] for extension in extensions])]\n", + " return file_list\n", + "\n", + "\n", + "def load_file(file_path, extensions=base_extensions):\n", + " assert sum([extension == file_path.split(\".\")[-1] for extension in extensions]), \"the extension of your file ({}) is not supported\".format(file_path)\n", + " extension = file_path.split(\".\")[-1]\n", + " if \"csv\" == extension:\n", + " data = pd.read_csv(file_path)\n", + " elif \"xlsx\" == extension:\n", + " data = pd.read_excel(file_path)\n", + " elif \"pickle\" == extension:\n", + " with open(file_path, \"rb\") as f:\n", + " data = pickle.load(f)\n", + " return data\n", + "\n", + "\n", + "def get_palette(y_values, yl):\n", + " nan_color = 'gray'\n", + " base_color = 'yellowgreen'\n", + " palette = {value: nan_color for value in y_values}\n", + " palette[yl] = base_color\n", + " return palette\n", + "\n", + "\n", + "def concat_in_out_df(df, i, col, val):\n", + " n = df[i].unique().shape[0]\n", + " df = df[[i, col, val]].copy()\n", + " add_df = pd.DataFrame()\n", + " add_df[i] = np.arange(n)\n", + " add_df[col] = \"Start\"\n", + " add_df[val] = 'in'\n", + " df = pd.concat([df, add_df])\n", + " add_df = pd.DataFrame()\n", + " add_df[i] = np.arange(n)\n", + " add_df[col] = \"End\"\n", + " add_df[val] = 'out'\n", + " df = pd.concat([df, add_df]).reset_index(drop=True)\n", + " return df\n", + "\n", + "\n", + "def get_node_order_bundle(df, i, x, y):\n", + " df = df.copy()\n", + " df = concat_in_out_df(df, i, x, y)\n", + " df_piv = df.pivot_table(values=y, index=i, columns=x, aggfunc='sum').reset_index()\n", + " x_values = [\"Start\"] + df_piv.columns.drop([i, \"Start\", \"End\"]).sort_values().tolist() + [\"End\"]\n", + " assert len(x_values) > 3, \"the cardinality of x need to be larger than 1\"\n", + " df_piv_count = df_piv.groupby(x_values)[i].count().reset_index().rename(columns={i: \"value\"})\n", + " nodes = {}\n", + " nodes[x_values[0]] = ProcessGroup(np.sort(df_piv_count[x_values[0]].unique()).tolist(), title=x_values[0])\n", + " nodes[x_values[0]].partition = Partition.Simple(\"process\", np.sort(df_piv_count[x_values[0]].unique()).tolist())\n", + " nodes[x_values[-1]] = ProcessGroup(np.sort(df_piv_count[x_values[-1]].unique()).tolist(), title=x_values[-1])\n", + " nodes[x_values[-1]].partition = Partition.Simple(\"process\", np.sort(df_piv_count[x_values[-1]].unique()).tolist())\n", + " for x_value in x_values[1:-1]:\n", + " part = Partition.Simple(x_value, np.sort(df_piv_count[x_value].unique()).tolist())\n", + " nodes[x_value] = Waypoint(part, title=x_value)\n", + "\n", + " ordering = [[x_value] for x_value in x_values]\n", + "\n", + " bundles = [Bundle(x_values[0], x_values[-1], waypoints=x_values[1:-1])]\n", + " tmp_flows = df_piv_count.copy().rename(columns={x_values[0]: \"source\", x_values[-1]: \"target\"})\n", + " return tmp_flows, nodes, bundles, ordering, df_piv" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## class" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "class TsSankey(object):\n", + " def __init__(self, multiple_display_widget, path_widget, index_widget, column_widget, value_widget, column_level_widget, value_level_widget):\n", + " self.df = None\n", + " self.flows = None\n", + " self.column_values = None\n", + " self.multiple_display_widget = multiple_display_widget\n", + " self.path_widget = path_widget\n", + " self.index_widget = index_widget\n", + " self.column_widget = column_widget\n", + " self.value_widget = value_widget\n", + " self.column_level_widget = column_level_widget\n", + " self.value_level_widget = value_level_widget\n", + " self.sdd = None\n", + " # display flag\n", + " self.display_flag = False\n", + "\n", + " def on_path_update(self, change):\n", + " # extract changed value\n", + " file_path = change[\"new\"]\n", + " self.file_path = file_path\n", + "\n", + " # load dataframe\n", + " self.df = load_file(file_path)\n", + " self.index_widget.options = self.df.columns.tolist()\n", + " self.index_widget.value = None\n", + " # reset column level observation\n", + " self.column_widget.unobserve(self.on_column_update, names=\"value\")\n", + " self.column_level_widget.unobserve(self.on_column_to_value_update, names=\"value\")\n", + " # set column list\n", + " self.column_widget.options = self.df.columns.tolist()\n", + " # reset default values\n", + " self.column_widget.value = None\n", + " self.column_level_widget.options = []\n", + " self.column_level_widget.value = None\n", + "\n", + " # reset value level observation\n", + " self.value_widget.unobserve(self.on_value_update, names=\"value\")\n", + " self.value_level_widget.unobserve(self.on_value_level_update, names=\"value\")\n", + " # set column list\n", + " self.value_widget.options = self.df.columns.tolist()\n", + " # reset default values\n", + " self.value_widget.value = None\n", + " self.value_level_widget.options = []\n", + " self.value_level_widget.value = None\n", + "\n", + " # observe level observations\n", + " self.column_widget.observe(self.on_column_update, names=\"value\")\n", + " self.value_widget.observe(self.on_value_update, names=\"value\")\n", + " self.column_level_widget.observe(self.on_column_to_value_update, names=\"value\")\n", + " self.value_level_widget.observe(self.on_value_level_update, names=\"value\")\n", + "\n", + " # reset floweaver resources\n", + " self.sdd = None\n", + " self.flows = None\n", + " self.palette = None\n", + "\n", + " def on_column_update(self, change):\n", + " # extract changed value\n", + " column_name = change[\"new\"]\n", + " # reset column level observation\n", + " self.column_level_widget.unobserve(self.on_column_to_value_update, names=\"value\")\n", + " # reset value level observation\n", + " self.value_level_widget.unobserve(self.on_value_level_update, names=\"value\")\n", + " # set column level options\n", + " self.column_level_widget.options = np.sort(self.df[column_name].unique()).tolist()\n", + " # reset column level value and value level variables\n", + " self.column_level_widget.value = None\n", + " self.value_level_widget.options = []\n", + " self.value_level_widget.value = None\n", + " # reset floweaver resources\n", + " self.sdd = None\n", + " # observe level observations\n", + " self.column_level_widget.observe(self.on_column_to_value_update, names=\"value\")\n", + " self.value_level_widget.observe(self.on_value_level_update, names=\"value\")\n", + "\n", + " def on_value_update(self, change):\n", + " value_name = change[\"new\"]\n", + " if self.column_widget.value is not None and self.column_level_widget.value is not None:\n", + " # reset value level observation\n", + " self.value_level_widget.unobserve(self.on_value_level_update, names=\"value\")\n", + " # update options\n", + " options = np.sort(\n", + " self.df[self.df[self.column_widget.value] == self.column_level_widget.value][value_name].unique()).tolist()\n", + " if self.value_level_widget.value in options:\n", + " self.sdd = self.get_sdd()\n", + " else:\n", + " self.value_level_widget.value = None\n", + " self.sdd = None\n", + " self.value_level_widget.options = options\n", + " self.value_level_widget.observe(self.on_value_level_update, names=\"value\")\n", + "\n", + " def on_column_to_value_update(self, change):\n", + " column_level = change[\"new\"]\n", + " if self.column_widget.value is not None and self.value_widget.value is not None:\n", + " # reset value level observation\n", + " self.value_level_widget.unobserve(self.on_value_level_update, names=\"value\")\n", + " # update options\n", + " options = np.sort(\n", + " self.df[self.df[self.column_widget.value] == column_level][self.value_widget.value].unique()).tolist()\n", + " if self.value_level_widget.value in self.value_level_widget.options:\n", + " self.sdd = self.get_sdd()\n", + " else:\n", + " self.sdd = None\n", + " self.value_level_widget.options = options\n", + " self.value_level_widget.value = None\n", + " self.value_level_widget.observe(self.on_value_level_update, names=\"value\")\n", + "\n", + " def on_value_level_update(self, change):\n", + " value = change[\"new\"]\n", + " if self.df is not None:\n", + " self.sdd = self.get_sdd()\n", + "\n", + " def on_clear_output(self, change):\n", + " flag = change[\"new\"]\n", + " if self.sdd is not None:\n", + " if flag == \"Yes\":\n", + " display(self.multiple_display_widget)\n", + " display(self.path_widget)\n", + " display(self.index_widget)\n", + " display(self.column_widget)\n", + " display(self.value_widget)\n", + " display(self.column_level_widget)\n", + " display(self.value_level_widget)\n", + " print(\"file: {}, index: {}, date: {} is {}, target: {} is {}\".format(\n", + " self.path_widget.value,\n", + " self.index_widget.value,\n", + " self.column_widget.value,\n", + " self.column_level_widget.value,\n", + " self.value_widget.value,\n", + " self.value_level_widget.value\n", + " ))\n", + " display(weave(self.sdd, self.flows, palette=self.palette).to_widget(**self.size))\n", + " else:\n", + " clear_output(wait=False)\n", + " display(self.multiple_display_widget)\n", + " display(self.path_widget)\n", + " display(self.index_widget)\n", + " display(self.column_widget)\n", + " display(self.value_widget)\n", + " display(self.column_level_widget)\n", + " display(self.value_level_widget)\n", + " print(\"file: {}, index: {}, date: {} is {}, target: {} is {}\".format(\n", + " self.path_widget.value,\n", + " self.index_widget.value,\n", + " self.column_widget.value,\n", + " self.column_level_widget.value,\n", + " self.value_widget.value,\n", + " self.value_level_widget.value\n", + " ))\n", + " display(weave(self.sdd, self.flows, palette=self.palette).to_widget(**self.size))\n", + " clear_output(wait=True)\n", + "\n", + " def get_sdd(self):\n", + " tmp_flows, nodes, bundles, orderings, df_piv = get_node_order_bundle(\n", + " self.df,\n", + " self.index_widget.value,\n", + " self.column_widget.value,\n", + " self.value_widget.value\n", + " )\n", + " flow_partition = nodes[self.column_level_widget.value].partition\n", + " y_list = np.sort(df_piv[self.column_level_widget.value].unique()).tolist()\n", + " palette = get_palette(y_list, self.value_level_widget.value)\n", + " sdd = SankeyDefinition(nodes, bundles, orderings,\n", + " flow_partition=flow_partition)\n", + " self.flows = tmp_flows\n", + " self.palette = palette\n", + " self.size = dict(width=1070, height=500)\n", + " if self.multiple_display_widget.value == \"No\" and self.display_flag is True:\n", + " display(self.multiple_display_widget)\n", + " display(self.path_widget)\n", + " display(self.index_widget)\n", + " display(self.column_widget)\n", + " display(self.value_widget)\n", + " display(self.column_level_widget)\n", + " display(self.value_level_widget)\n", + " print(\"file: {}, index: {}, date: {} is {}, target: {} is {}\".format(\n", + " self.path_widget.value,\n", + " self.index_widget.value,\n", + " self.column_widget.value,\n", + " self.column_level_widget.value,\n", + " self.value_widget.value,\n", + " self.value_level_widget.value\n", + " ))\n", + " display(weave(sdd, self.flows, palette=self.palette).to_widget(**self.size))\n", + " if self.multiple_display_widget.value == \"No\":\n", + " clear_output(wait=True)\n", + " self.display_flag = True\n", + " return sdd\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## main function" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "def main():\n", + " # define widgets\n", + " style = {'description_width': 'initial'}\n", + " multiple_display_widget = Dropdown(options=[\"Yes\", \"No\"], value=None, description=\"multiple display?\", style=style)\n", + " path_widget = Dropdown(options=extract_files(), value=None, description=\"file path\", style=style)\n", + " i_widget = Dropdown(options=[], value=None, description=\"index column\", style=style)\n", + " x_widget = Dropdown(options=[], value=None, description=\"date column\", style=style)\n", + " y_widget = Dropdown(options=[], value=None, description=\"target variable\", style=style)\n", + " x_level_widget = Dropdown(options=[], value=None, description=\"target date\", style=style)\n", + " y_level_widget = Dropdown(options=[], value=None, description=\"target value\", style=style)\n", + "\n", + " # define an instance\n", + " ts = TsSankey(multiple_display_widget, path_widget, i_widget, x_widget, y_widget, x_level_widget, y_level_widget)\n", + "\n", + " # update widgets\n", + " multiple_display_widget.observe(ts.on_clear_output, names='value')\n", + " path_widget.observe(ts.on_path_update, names='value')\n", + " x_widget.observe(ts.on_column_update, names='value')\n", + " y_widget.observe(ts.on_value_update, names='value')\n", + " x_level_widget.observe(ts.on_column_to_value_update, names='value')\n", + " y_level_widget.observe(ts.on_value_level_update, names='value')\n", + "\n", + " # temp function to for interaction\n", + " def f(multiple_display_widget, data_path, i_widget, x_widget, y_widget, x_level_widget, y_level_widget):\n", + " pass\n", + "\n", + " interact(f,\n", + " multiple_display_widget=multiple_display_widget,\n", + " data_path=path_widget,\n", + " i_widget=i_widget,\n", + " x_widget=x_widget,\n", + " y_widget=y_widget,\n", + " x_level_widget=x_level_widget,\n", + " y_level_widget=y_level_widget)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# run" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "type `main()` to run the interaction between floweaver-path and data/templace.csv" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# main()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.1" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "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 +}