From 3a21fd5636f3e702e60d9ab50c86878e201f6c86 Mon Sep 17 00:00:00 2001 From: Tyler Biggs Date: Fri, 3 Jan 2020 13:10:18 -0800 Subject: [PATCH 1/2] notebooks updated --- examples/user_guide/GeneSet_Analysis.ipynb | 932 ++++++++++++++++-- .../workflow_guide/Using_Workflows.ipynb | 475 +++++++-- 2 files changed, 1256 insertions(+), 151 deletions(-) diff --git a/examples/user_guide/GeneSet_Analysis.ipynb b/examples/user_guide/GeneSet_Analysis.ipynb index ef6f71d..f9e7cb4 100644 --- a/examples/user_guide/GeneSet_Analysis.ipynb +++ b/examples/user_guide/GeneSet_Analysis.ipynb @@ -573,20 +573,7 @@ "text/html": [ "\n", "\n", - "\n", "\n", "\n", @@ -1609,8 +1609,11 @@ "source": [ "import os\n", "import numpy as np\n", + "\n", + "import matplotlib.pyplot as plt\n", "import holoviews as hv\n", "hv.extension(\"bokeh\")\n", + "%matplotlib inline\n", "\n", "import GSForge as gsf" ] @@ -1700,12 +1703,7 @@ "text/plain": [ "\n", "Boruta Results\n", - " \n", - " Name: Rice\n", - " Selected GEM Variable: 'counts'\n", - " Gene 55986\n", - " Sample 475\n", - "GeneSet Keys and # of Selected Genes\n", + "GeneSets (3 total): Support Count\n", " Boruta_Treatment: 681\n", " Boruta_Genotype: 661\n", " Boruta_Subspecies: 231" @@ -1748,7 +1746,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -1774,8 +1772,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 29.6 s, sys: 38.5 s, total: 1min 8s\n", - "Wall time: 51 s\n" + "CPU times: user 30.1 s, sys: 38.9 s, total: 1min 8s\n", + "Wall time: 50.8 s\n" ] } ], @@ -1793,7 +1791,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -1804,13 +1802,13 @@ "Coordinates:\n", " * Gene (Gene) object 'LOC_Os03g11550' ... 'LOC_Os10g36690'\n", " * feature_importance_iter (feature_importance_iter) int64 0 1 2\n", - " feature_importance_mean (Gene) float64 0.001065 0.0006369 ... 0.0009736\n", - " feature_importance_std (Gene) float64 5.643e-05 9.922e-05 ... 0.0002128\n", + " feature_importance_mean (Gene) float64 0.001169 0.0007716 ... 0.0007009\n", + " feature_importance_std (Gene) float64 0.0001653 9.932e-05 ... 0.0002353\n", "Data variables:\n", - " feature_importances (feature_importance_iter, Gene) float64 0.001003 ... 0.001145" + " feature_importances (feature_importance_iter, Gene) float64 0.001377 ... 0.0007873" ] }, - "execution_count": 10, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -1828,7 +1826,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -1854,7 +1852,7 @@ " __GSForge.GeneSet.params: {\"gene_index_name\": \"Gene\", \"name\": \"Boru..." ] }, - "execution_count": 12, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -1873,15 +1871,15 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 38.8 s, sys: 1min 25s, total: 2min 4s\n", - "Wall time: 1min 43s\n" + "CPU times: user 39.6 s, sys: 1min 25s, total: 2min 5s\n", + "Wall time: 1min 42s\n" ] } ], @@ -1899,7 +1897,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -1910,13 +1908,13 @@ "Coordinates:\n", " * Gene (Gene) object 'LOC_Os03g11550' ... 'LOC_Os10g36690'\n", " * fwe_iter (fwe_iter) int64 0 1 2\n", - " fwe_mean (Gene) float64 0.0 0.0 0.0 0.0004895 ... 0.0 0.0 0.0\n", - " fwe_std (Gene) float64 0.0 0.0 0.0 0.0006922 ... 0.0 0.0 0.0\n", + " fwe_mean (Gene) float64 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0\n", + " fwe_std (Gene) float64 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0\n", "Data variables:\n", " Family-wise error rate (fwe_iter, Gene) float64 0.0 0.0 0.0 ... 0.0 0.0 0.0" ] }, - "execution_count": 14, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -1927,7 +1925,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -1944,15 +1942,15 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 31.1 s, sys: 49.3 s, total: 1min 20s\n", - "Wall time: 1min 3s\n" + "CPU times: user 32.1 s, sys: 50.4 s, total: 1min 22s\n", + "Wall time: 1min 4s\n" ] } ], @@ -1970,7 +1968,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -1987,7 +1985,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -2021,7 +2019,7 @@ " __GSForge.GeneSet.params: {\"gene_index_name\": \"Gene\", \"name\": \"Boru..." ] }, - "execution_count": 18, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -2033,7 +2031,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -2042,7 +2040,7 @@ "681" ] }, - "execution_count": 23, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -2061,7 +2059,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -2072,21 +2070,21 @@ "Coordinates:\n", " * Gene (Gene) object 'LOC_Os03g11550' ... 'LOC_Os10g36690'\n", " * feature_importance_iter (feature_importance_iter) int64 0 1 2\n", - " feature_importance_mean (Gene) float64 0.001065 0.0006369 ... 0.0009736\n", - " feature_importance_std (Gene) float64 5.643e-05 9.922e-05 ... 0.0002128\n", + " feature_importance_mean (Gene) float64 0.001169 0.0007716 ... 0.0007009\n", + " feature_importance_std (Gene) float64 0.0001653 9.932e-05 ... 0.0002353\n", " * fwe_iter (fwe_iter) int64 0 1 2\n", - " fwe_mean (Gene) float64 0.0 0.0 0.0 ... 0.0 0.0 0.0\n", - " fwe_std (Gene) float64 0.0 0.0 0.0 ... 0.0 0.0 0.0\n", + " fwe_mean (Gene) float64 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0\n", + " fwe_std (Gene) float64 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0\n", " * nrd_iter (nrd_iter) int64 0 1 2\n", - " nrd_mean (Gene) float64 0.0004895 0.02252 ... 0.0 0.01126\n", - " nrd_std (Gene) float64 0.0006922 0.02769 ... 0.0 0.01293\n", + " nrd_mean (Gene) float64 0.0 0.003916 0.0 ... 0.0 0.001958\n", + " nrd_std (Gene) float64 0.0 0.002769 0.0 ... 0.0 0.002769\n", "Data variables:\n", " support (Gene) bool True True True True ... True True True\n", " support_weak (Gene) bool False False False ... False False False\n", " ranking (Gene) int64 1 1 1 1 1 1 1 1 1 ... 1 1 1 1 1 1 1 1\n", - " feature_importances (feature_importance_iter, Gene) float64 0.001003 ... 0.001145\n", + " feature_importances (feature_importance_iter, Gene) float64 0.001377 ... 0.0007873\n", " Family-wise error rate (fwe_iter, Gene) float64 0.0 0.0 0.0 ... 0.0 0.0\n", - " null rank distribution (nrd_iter, Gene) float64 0.001468 ... 0.004405\n", + " null rank distribution (nrd_iter, Gene) float64 0.0 0.005874 ... 0.0 0.0\n", "Attributes:\n", " boruta_model: {\"two_step\": true, \"max_iter\": 50, \"estim...\n", " ranking_model: {\"bootstrap\": true, \"class_weight\": \"bala...\n", @@ -2095,7 +2093,7 @@ " __GSForge.GeneSet.params: {\"gene_index_name\": \"Gene\", \"name\": \"Boru..." ] }, - "execution_count": 20, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -2107,7 +2105,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -2117,7 +2115,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 20, "metadata": {}, "outputs": [ { @@ -2130,13 +2128,13 @@ "\n", "\n", "\n", - "
\n", + "
\n", "\n", "" ], "text/plain": [ - ":Scatter [feature_importance_mean] (nrd_mean,nrd_std,fwe_std,fwe_mean,feature_importance_std)" + ":Scatter [feature_importance_mean] (nrd_mean,feature_importance_std,fwe_std,nrd_std,fwe_mean)" ] }, - "execution_count": 22, + "execution_count": 20, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1003" @@ -2176,19 +2174,393 @@ "hv.Scatter(df).opts(padding=0.1, width=500, height=500)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Receiver Operating Characteristic (ROC)\n", + "\n", + "Another way to evaluate a classification model is the [ROC](https://scikit-learn.org/stable/auto_examples/model_selection/plot_roc.html#sphx-glr-auto-examples-model-selection-plot-roc-py).\n", + "\n", + "Viewing ROC curves for multi-label models is a bit indirect, so we provide this walkthrough.\n", + "Also examine the [sklearn demo](https://scikit-learn.org/stable/auto_examples/model_selection/plot_roc.html)." + ] + }, { "cell_type": "code", - "execution_count": null, + "execution_count": 86, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "from sklearn.multiclass import OneVsRestClassifier\n", + "from sklearn.metrics import roc_curve, auc, roc_auc_score, plot_roc_curve\n", + "from sklearn import preprocessing, model_selection" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get the count and annotation data from GSForge." + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array(['CONTROL', 'HEAT', 'RECOV_HEAT', 'DROUGHT', 'RECOV_DROUGHT'],\n", + " dtype=object)" + ] + }, + "execution_count": 96, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "counts, treatment = gsf.get_data(agem, annotation_variables=\"Treatment\")\n", + "classes = treatment.to_series().unique()\n", + "classes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Encode the annotation labels with a [one hot encoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html#sklearn.preprocessing.OneHotEncoder)." + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[1., 0., 0., 0., 0.],\n", + " [1., 0., 0., 0., 0.],\n", + " [1., 0., 0., 0., 0.],\n", + " ...,\n", + " [0., 0., 0., 1., 0.],\n", + " [0., 0., 0., 1., 0.],\n", + " [0., 0., 0., 1., 0.]])" + ] + }, + "execution_count": 83, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "enc = preprocessing.OneHotEncoder().fit(treatment.values.reshape(-1, 1))\n", + "treatment_onehot = enc.transform(treatment.values.reshape(-1, 1)).toarray()\n", + "treatment_onehot" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Split the data and encoded annotations into a train and test set." + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "metadata": {}, + "outputs": [], + "source": [ + "x_train, x_test, y_train, y_test = model_selection.train_test_split(counts, treatment_onehot)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Fit the model with the training data." + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 5.42 s, sys: 476 ms, total: 5.89 s\n", + "Wall time: 14 s\n" + ] + } + ], + "source": [ + "%%time\n", + "roc_rf_model = OneVsRestClassifier(RandomForestClassifier(class_weight='balanced', \n", + " n_estimators=1000, n_jobs=-1))\n", + "roc_rf_model = roc_rf_model.fit(x_train, y_train)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now predict class probabilities for the test count data." + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[0.643, 0.01 , 0.024, 0.063, 0.212],\n", + " [0.616, 0.318, 0.066, 0.02 , 0.011],\n", + " [0.013, 0.007, 0.868, 0.024, 0.065],\n", + " [0.31 , 0.066, 0.231, 0.085, 0.183],\n", + " [0.185, 0.004, 0.646, 0.008, 0.142]])" + ] + }, + "execution_count": 93, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y_score = roc_rf_model.predict_proba(x_test)\n", + "y_score[:5]" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": {}, + "outputs": [], + "source": [ + "fpr = dict()\n", + "tpr = dict()\n", + "roc_auc = dict()\n", + "for i, class_ in enumerate(classes):\n", + " fpr[class_], tpr[class_], _ = roc_curve(y_test[:, i], y_score[:, i])\n", + " roc_auc[class_] = auc(fpr[class_], tpr[class_])" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": {}, + "outputs": [], + "source": [ + "roc_curves = {class_: hv.Curve((fpr[class_], tpr[class_]))\n", + " for class_ in classes}" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.holoviews_exec.v0+json": "", + "text/html": [ + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "
\n", + "" + ], + "text/plain": [ + ":NdOverlay [Element]\n", + " :Curve [x] (y)" + ] + }, + "execution_count": 102, + "metadata": { + "application/vnd.holoviews_exec.v0+json": { + "id": "1963" + } + }, + "output_type": "execute_result" + } + ], + "source": [ + "hv.NdOverlay(roc_curves).opts(padding=0.05, legend_position=\"right\", width=600)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### View a Decision Tree" + ] + }, + { + "cell_type": "code", + "execution_count": 155, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn import tree" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Extract a single tree from a list of estimators." + ] + }, + { + "cell_type": "code", + "execution_count": 149, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([0, 1, 2, 3, 4])" + ] + }, + "execution_count": 149, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "roc_rf_model.classes_" + ] + }, + { + "cell_type": "code", + "execution_count": 150, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight='balanced',\n", + " criterion='gini', max_depth=None, max_features='auto',\n", + " max_leaf_nodes=None, max_samples=None,\n", + " min_impurity_decrease=0.0, min_impurity_split=None,\n", + " min_samples_leaf=1, min_samples_split=2,\n", + " min_weight_fraction_leaf=0.0, n_estimators=1000,\n", + " n_jobs=-1, oob_score=False, random_state=None, verbose=0,\n", + " warm_start=False)" + ] + }, + "execution_count": 150, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "control_rfc = roc_rf_model.estimators_[0]\n", + "control_rfc" + ] + }, + { + "cell_type": "code", + "execution_count": 153, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1000" + ] + }, + "execution_count": 153, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(control_rfc.estimators_)" + ] + }, + { + "cell_type": "code", + "execution_count": 152, + "metadata": {}, + "outputs": [], + "source": [ + "selected_tree = control_rfc.estimators_[0]" + ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "selected_tree." + ] + }, + { + "cell_type": "code", + "execution_count": 156, + "metadata": {}, + "outputs": [ + { + "ename": "ValueError", + "evalue": "Length of feature_names, 681 does not match number of features, 55986", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0mfilled\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0mrounded\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m special_characters=True))\n\u001b[0m", + "\u001b[0;32m~/anaconda3/lib/python3.7/site-packages/sklearn/tree/_export.py\u001b[0m in \u001b[0;36mexport_graphviz\u001b[0;34m(decision_tree, out_file, max_depth, feature_names, class_names, label, filled, leaves_parallel, impurity, node_ids, proportion, rotate, rounded, special_characters, precision)\u001b[0m\n\u001b[1;32m 762\u001b[0m \u001b[0mrounded\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mrounded\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mspecial_characters\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mspecial_characters\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 763\u001b[0m precision=precision)\n\u001b[0;32m--> 764\u001b[0;31m \u001b[0mexporter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexport\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdecision_tree\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 765\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 766\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mreturn_string\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.7/site-packages/sklearn/tree/_export.py\u001b[0m in \u001b[0;36mexport\u001b[0;34m(self, decision_tree)\u001b[0m\n\u001b[1;32m 397\u001b[0m \u001b[0;34m\"does not match number of features, %d\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 398\u001b[0m % (len(self.feature_names),\n\u001b[0;32m--> 399\u001b[0;31m decision_tree.n_features_))\n\u001b[0m\u001b[1;32m 400\u001b[0m \u001b[0;31m# each part writes to out_file\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 401\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhead\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mValueError\u001b[0m: Length of feature_names, 681 does not match number of features, 55986" + ] + } + ], + "source": [ + "graphviz.Source(tree.export_graphviz(\n", + " selected_tree, \n", + " out_file=None, \n", + " feature_names=counts.Gene.values, \n", + " class_names=classes,\n", + " filled=True, \n", + " rounded=True, \n", + " special_characters=True))" + ] }, { "cell_type": "code", @@ -2197,6 +2569,434 @@ "outputs": [], "source": [] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get the count and annotation data from GSForge." + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\n", + "array([[ 130, 1264, 48, ..., 249, 225, 342],\n", + " [ 46, 284, 46, ..., 145, 112, 152],\n", + " [ 80, 1342, 142, ..., 219, 167, 336],\n", + " ...,\n", + " [ 33, 1956, 242, ..., 226, 284, 424],\n", + " [ 64, 1737, 34, ..., 350, 206, 274],\n", + " [ 102, 1129, 540, ..., 863, 309, 335]])\n", + "Coordinates:\n", + " * Gene (Gene) object 'LOC_Os03g11550' ... 'LOC_Os10g36690'\n", + " * Sample (Sample) object 'SRX1423934' 'SRX1423935' ... 'SRX1424408'\n", + " quantile float64 0.75" + ] + }, + "execution_count": 105, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "counts, treatment = gsf.get_data(gsc, annotation_variables=\"Treatment\", selected_gene_sets=[\"Boruta_Treatment\"])\n", + "classes = treatment.to_series().unique()\n", + "counts" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Encode the annotation labels with a [one hot encoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html#sklearn.preprocessing.OneHotEncoder)." + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[1., 0., 0., 0., 0.],\n", + " [1., 0., 0., 0., 0.],\n", + " [1., 0., 0., 0., 0.],\n", + " ...,\n", + " [0., 0., 0., 1., 0.],\n", + " [0., 0., 0., 1., 0.],\n", + " [0., 0., 0., 1., 0.]])" + ] + }, + "execution_count": 107, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "enc = preprocessing.OneHotEncoder().fit(treatment.values.reshape(-1, 1))\n", + "treatment_onehot = enc.transform(treatment.values.reshape(-1, 1)).toarray()\n", + "treatment_onehot" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Split the data and encoded annotations into a train and test set." + ] + }, + { + "cell_type": "code", + "execution_count": 139, + "metadata": {}, + "outputs": [], + "source": [ + "x_train, x_test, y_train, y_test = model_selection.train_test_split(counts, treatment)" + ] + }, + { + "cell_type": "code", + "execution_count": 140, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn import tree" + ] + }, + { + "cell_type": "code", + "execution_count": 141, + "metadata": {}, + "outputs": [], + "source": [ + "dtree = tree.DecisionTreeClassifier(max_depth=3)\n", + "dtree = dtree.fit(x_train, y_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 145, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.8487394957983193" + ] + }, + "execution_count": 145, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dtree.score(x_test, y_test)" + ] + }, + { + "cell_type": "code", + "execution_count": 142, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['CONTROL', 'HEAT', 'RECOV_HEAT', 'DROUGHT', 'RECOV_DROUGHT']" + ] + }, + "execution_count": 142, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(classes)" + ] + }, + { + "cell_type": "code", + "execution_count": 143, + "metadata": {}, + "outputs": [], + "source": [ + "import graphviz " + ] + }, + { + "cell_type": "code", + "execution_count": 144, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tree\n", + "\n", + "\n", + "\n", + "0\n", + "\n", + "LOC_Os01g04370 ≤ 652.5\n", + "gini = 0.773\n", + "samples = 356\n", + "value = [108, 51, 98, 54, 45]\n", + "class = CONTROL\n", + "\n", + "\n", + "\n", + "1\n", + "\n", + "LOC_Os05g38290 ≤ 15.5\n", + "gini = 0.621\n", + "samples = 213\n", + "value = [108, 51, 0, 54, 0]\n", + "class = CONTROL\n", + "\n", + "\n", + "\n", + "0->1\n", + "\n", + "\n", + "True\n", + "\n", + "\n", + "\n", + "8\n", + "\n", + "LOC_Os06g09560 ≤ 41.0\n", + "gini = 0.431\n", + "samples = 143\n", + "value = [0, 0, 98, 0, 45]\n", + "class = RECOV_HEAT\n", + "\n", + "\n", + "\n", + "0->8\n", + "\n", + "\n", + "False\n", + "\n", + "\n", + "\n", + "2\n", + "\n", + "LOC_Os09g27030 ≤ 677.0\n", + "gini = 0.339\n", + "samples = 130\n", + "value = [104, 16, 0, 10, 0]\n", + "class = CONTROL\n", + "\n", + "\n", + "\n", + "1->2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "5\n", + "\n", + "LOC_Os02g46030 ≤ 50.5\n", + "gini = 0.539\n", + "samples = 83\n", + "value = [4, 35, 0, 44, 0]\n", + "class = DROUGHT\n", + "\n", + "\n", + "\n", + "1->5\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "3\n", + "\n", + "gini = 0.513\n", + "samples = 39\n", + "value = [22, 16, 0, 1, 0]\n", + "class = CONTROL\n", + "\n", + "\n", + "\n", + "2->3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "4\n", + "\n", + "gini = 0.178\n", + "samples = 91\n", + "value = [82, 0, 0, 9, 0]\n", + "class = CONTROL\n", + "\n", + "\n", + "\n", + "2->4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "6\n", + "\n", + "gini = 0.229\n", + "samples = 39\n", + "value = [4, 1, 0, 34, 0]\n", + "class = DROUGHT\n", + "\n", + "\n", + "\n", + "5->6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "7\n", + "\n", + "gini = 0.351\n", + "samples = 44\n", + "value = [0, 34, 0, 10, 0]\n", + "class = HEAT\n", + "\n", + "\n", + "\n", + "5->7\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "9\n", + "\n", + "LOC_Os06g28124 ≤ 21.5\n", + "gini = 0.127\n", + "samples = 44\n", + "value = [0, 0, 3, 0, 41]\n", + "class = RECOV_DROUGHT\n", + "\n", + "\n", + "\n", + "8->9\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "12\n", + "\n", + "LOC_Os01g44050 ≤ 1055.5\n", + "gini = 0.078\n", + "samples = 99\n", + "value = [0, 0, 95, 0, 4]\n", + "class = RECOV_HEAT\n", + "\n", + "\n", + "\n", + "8->12\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "10\n", + "\n", + "gini = 0.0\n", + "samples = 3\n", + "value = [0, 0, 3, 0, 0]\n", + "class = RECOV_HEAT\n", + "\n", + "\n", + "\n", + "9->10\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "11\n", + "\n", + "gini = 0.0\n", + "samples = 41\n", + "value = [0, 0, 0, 0, 41]\n", + "class = RECOV_DROUGHT\n", + "\n", + "\n", + "\n", + "9->11\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "13\n", + "\n", + "gini = 0.0\n", + "samples = 95\n", + "value = [0, 0, 95, 0, 0]\n", + "class = RECOV_HEAT\n", + "\n", + "\n", + "\n", + "12->13\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "14\n", + "\n", + "gini = 0.0\n", + "samples = 4\n", + "value = [0, 0, 0, 0, 4]\n", + "class = RECOV_DROUGHT\n", + "\n", + "\n", + "\n", + "12->14\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 144, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dot_data = tree.export_graphviz(dtree, out_file=None, \n", + " feature_names=counts.Gene.values, \n", + " class_names=classes,\n", + " filled=True, rounded=True, \n", + " special_characters=True) \n", + "graph = graphviz.Source(dot_data) \n", + "graph" + ] + }, { "cell_type": "markdown", "metadata": {}, diff --git a/examples/user_guide/workflow_guide/Using_Workflows.ipynb b/examples/user_guide/workflow_guide/Using_Workflows.ipynb index 2170526..a987900 100644 --- a/examples/user_guide/workflow_guide/Using_Workflows.ipynb +++ b/examples/user_guide/workflow_guide/Using_Workflows.ipynb @@ -37,9 +37,9 @@ "\n", "```groovy\n", "// Singular data input and selection.\n", - "params.gem_netcdf = \"~/GSForge_demo_data/osfstorage/rice.nc\"\n", + "params.gem_netcdf = \"~/GSForge_demo_data/rice.nc\"\n", "params.x_label = \"counts\"\n", - "params.y_label = [\"treatment\", \"genotype\", \"rep\"]\n", + "params.y_label = [\"Treatment\", \"Genotype\", \"Subspecies\"]\n", "\n", "// Ranking model options.\n", "params.ranking_model = \"RandomForestClassifier\"\n", @@ -47,20 +47,14 @@ "params.ranking_model_opts.n_jobs = [-1]\n", "\n", "// BorutaPy options.\n", - "params.boruta_opts.perc = [75, 100]\n", - "params.boruta_opts.max_iter = [1000]\n", + "params.boruta_opts.perc = [95, 100]\n", + "params.boruta_opts.max_iter = [200]\n", "\n", "// How often to repeat each set of arguments.\n", "params.repeats = 2\n", "\n", "// Output directory.\n", - "params.out_dir = \"~/GSForge_demo_data/osfstorage/workflow_demo\"\n", - "\n", - "profiles {\n", - " standard { executor.queueSize = 1 }\n", - " docker { docker.enabled = true\n", - " process.container = 'systemsgenetics/gsforge_workflow:latest' }\n", - "}\n", + "params.out_dir = \"~/GSForge_demo_data/boruta_workflow_gene_sets\"\n", "```\n", "\n", "### Running the Workflow\n", @@ -80,7 +74,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 1, "metadata": { "pycharm": { "is_executing": true @@ -1371,7 +1365,20 @@ "text/html": [ "\n", "\n", - "\n", "\n", "\n", @@ -2412,6 +2406,16 @@ "hv.extension(\"bokeh\")" ] }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [], + "source": [ + "import re\n", + "import collections" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -2445,10 +2449,12 @@ "metadata": {}, "outputs": [], "source": [ - "# OSF_PATH = Path(environ.get(\"GSFORGE_DEMO_DATA\", default=\"~/GSForge_demo_data\")).expanduser()\n", - "# AGEM_PATH = OSF_PATH.joinpath(\"osfstorage\", \"rice.nc\")\n", - "# BOR_COLL_PATH = OSF_PATH.joinpath(\"osfstorage\", \"boruta_gene_sets\")\n", - "# assert AGEM_PATH.exists()" + "OSF_PATH = Path(environ.get(\"GSFORGE_DEMO_DATA\", default=\"~/GSForge_demo_data\")).expanduser()\n", + "AGEM_PATH = OSF_PATH.joinpath(\"osfstorage\", \"rice.nc\")\n", + "NFWF_PATH = OSF_PATH.joinpath(\"osfstorage\", \"boruta_workflow_gene_sets\")\n", + "\n", + "assert AGEM_PATH.exists()\n", + "assert NFWF_PATH.exists()" ] }, { @@ -2479,8 +2485,8 @@ } ], "source": [ - "# agem = gsf.AnnotatedGEM(AGEM_PATH)\n", - "# agem" + "agem = gsf.AnnotatedGEM(AGEM_PATH)\n", + "agem" ] }, { @@ -2492,125 +2498,424 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[PosixPath('/home/tyler/GSForge_demo_data/boruta_results/Boruta_stress.nc'),\n", - " PosixPath('/home/tyler/GSForge_demo_data/boruta_results/Boruta_species.nc')]" + "[PosixPath('/home/tyler/GSForge_demo_data/osfstorage/boruta_workflow_gene_sets/019524_b48286.nc'),\n", + " PosixPath('/home/tyler/GSForge_demo_data/osfstorage/boruta_workflow_gene_sets/b8df5c_fcadb6.nc'),\n", + " PosixPath('/home/tyler/GSForge_demo_data/osfstorage/boruta_workflow_gene_sets/921936_8c7f65.nc'),\n", + " PosixPath('/home/tyler/GSForge_demo_data/osfstorage/boruta_workflow_gene_sets/921936_7717b7.nc'),\n", + " PosixPath('/home/tyler/GSForge_demo_data/osfstorage/boruta_workflow_gene_sets/4f9452_26da90.nc')]" ] }, - "execution_count": 7, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# list(Path(GDS2910_boruta_result_path).expanduser().resolve().glob(\"*.nc\"))" + "result_paths = list(NFWF_PATH.expanduser().resolve().glob(\"*.nc\"))\n", + "result_paths[:5]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Let's combine the replicates into a single lineament." + "This workflow names the files:\n", + "\n", + "```\n", + "_.nc\n", + "```" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 13, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'019524_b48286.nc'" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "# treatment_lcoll = gp.GeneSetCollection.from_folder(agem, LINEAMENT_DIR, \n", - "# name=\"Treatment\", \n", - "# glob_filter=\"*Treatment*.nc\")\n", - "# genotype_lcoll = gp.GeneSetCollection.from_folder(agem, LINEAMENT_DIR, \n", - "# name=\"Genotype\", \n", - "# glob_filter=\"*Genotype*.nc\")\n", - "# subspecies_lcoll = gp.GeneSetCollection.from_folder(agem, LINEAMENT_DIR, \n", - "# name=\"Subspecies\", \n", - "# glob_filter=\"*Subspecies*.nc\")\n", - "\n", - "# treatment_lcoll" + "result_paths[0].name" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "***Combine the collections into their own lineaments:***" + "### Load and Examine a Single Result" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\n", + "Name: GeneSet01321\n", + " Supported Genes: 239, 0.43% of 55986" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "demo_result = gsf.GeneSet(result_paths[0])\n", + "demo_result" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\n", + "Dimensions: (Gene: 55986)\n", + "Coordinates:\n", + " * Gene (Gene) object 'LOC_Os06g05820' ... 'LOC_Os07g03418'\n", + "Data variables:\n", + " support (Gene) bool False False False False ... False False False\n", + " support_weak (Gene) bool ...\n", + " ranking (Gene) int64 ...\n", + "Attributes:\n", + " boruta_model: {\"two_step\": true, \"random_state\": null, ...\n", + " ranking_model: {\"bootstrap\": true, \"ccp_alpha\": 0.0, \"cl...\n", + " selected_count_variable: counts\n", + " selected_annotation_variables: Subspecies\n", + " arg_hash: 019524" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "demo_result.data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "*First get a copy of the attributes, since they are all replicates it doesn't matter which one.*" + "### Combine by Argument Hash" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 32, "metadata": {}, "outputs": [], "source": [ - "# subspecies_attrs = next(iter(subspecies_lcoll.lineaments.values())).data.attrs\n", - "# treatment_attrs = next(iter(treatment_lcoll.lineaments.values())).data.attrs\n", - "# genotype_attrs = next(iter(genotype_lcoll.lineaments.values())).data.attrs" + "replicates = set()\n", + "\n", + "for path in result_paths:\n", + " argument, uuid = path.name.split(\"_\")\n", + " replicates = set([argument]).union(replicates)\n", + " \n", + "# replicates" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "\n", - " \n", - " Name: Oryza sativa\n", - " Selected GEM Variable: 'counts'\n", - " Gene 55986\n", - " Sample 475\n", - "GeneSet Keys and # of Selected Genes\n", - " Treatment: 1171\n", - " Genotype: 754\n", - " Subspecies: 312" + "\n", + "GeneSetCollection01562\n", + "GeneSets (60 total): Support Count\n", + " 36b179_451cf8: 2414\n", + " 3a6380_737034: 2393\n", + " 3a6380_38175b: 2383\n", + " 36b179_f8be07: 2366\n", + " 644cfd_3c8807: 2321\n", + " 644cfd_4554ce: 2310\n", + " 21a38c_bbb811: 2146\n", + " 21a38c_c68f41: 2138\n", + " f962d6_3da9fb: 1532\n", + " f962d6_d77341: 1532" ] }, - "execution_count": 12, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# lineaments = {\n", - "# \"Subspecies\": gp.GeneSet.from_lineaments(subspecies_lcoll.lineaments.values(),\n", - "# agem.gene_index,\n", - "# name=\"Subspecies\", attrs=subspecies_attrs),\n", - "# \"Treatment\": gp.GeneSet.from_lineaments(treatment_lcoll.lineaments.values(), agem.gene_index, \n", - "# name=\"Treatment\", attrs=treatment_attrs),\n", - "# \"Genotype\": gp.GeneSet.from_lineaments(genotype_lcoll.lineaments.values(), agem.gene_index,\n", - "# name=\"Genotype\", attrs=genotype_attrs),\n", - "# }\n", + "workflow_collection = gsf.GeneSetCollection.from_folder(agem, NFWF_PATH)\n", + "workflow_collection" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [], + "source": [ + "combined = collections.defaultdict(list)\n", "\n", - "# lcoll = gp.GeneSetCollection(gem=agem, lineaments=lineaments)\n", - "# lcoll" + "for replicate in replicates:\n", + " pattern = re.compile(replicate)\n", + " for result in workflow_collection.gene_sets.keys():\n", + " \n", + " if pattern.match(result):\n", + " combined[replicate].append(result)" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 54, + "metadata": {}, + "outputs": [], + "source": [ + "label_colls = dict()\n", + "\n", + "for label in [\"Treatment\", \"Genotype\", \"Subspecies\"]:\n", + " combined = collections.defaultdict(list)\n", + "\n", + " for replicate in replicates:\n", + " pattern = re.compile(replicate)\n", + " for result, geneset in workflow_collection.gene_sets.items():\n", + " if geneset.data.attrs[\"selected_annotation_variables\"] == label:\n", + " if pattern.match(result):\n", + " combined[replicate].append(result)\n", + " label_colls[label] = combined" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Treatment': defaultdict(list,\n", + " {'e90ecb': ['e90ecb'],\n", + " '3a6380': ['3a6380'],\n", + " '36b179': ['36b179'],\n", + " 'a45d98': ['a45d98'],\n", + " '26b197': ['26b197'],\n", + " '644cfd': ['644cfd'],\n", + " '21a38c': ['21a38c'],\n", + " 'eb6a41': ['eb6a41'],\n", + " 'f79407': ['f79407'],\n", + " 'f962d6': ['f962d6']}),\n", + " 'Genotype': defaultdict(list,\n", + " {'8fa5fc': ['8fa5fc'],\n", + " 'b8df5c': ['b8df5c'],\n", + " '9fda5b': ['9fda5b'],\n", + " '488d45': ['488d45'],\n", + " 'd38fb9': ['d38fb9'],\n", + " '75bfe3': ['75bfe3'],\n", + " '4d726f': ['4d726f'],\n", + " 'a6130e': ['a6130e'],\n", + " '891c83': ['891c83'],\n", + " 'dc6a48': ['dc6a48']}),\n", + " 'Subspecies': defaultdict(list,\n", + " {'921936': ['921936'],\n", + " '1ec403': ['1ec403'],\n", + " 'c3e5ee': ['c3e5ee'],\n", + " '749d0e': ['749d0e'],\n", + " 'd75652': ['d75652'],\n", + " '4f9452': ['4f9452'],\n", + " '019524': ['019524'],\n", + " '2e4ade': ['2e4ade'],\n", + " 'cfa346': ['cfa346'],\n", + " '0a0991': ['0a0991']})}" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "label_colls" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [], + "source": [ + "collections = []\n", + "\n", + "for label in [\"Treatment\", \"Genotype\", \"Subspecies\"]:\n", + " coll = label_colls[label]\n", + " \n", + " combined_genesets = {}\n", + "\n", + " for argument_hash, keys in coll.items():\n", + " gene_sets = [workflow_collection.gene_sets[key] for key in keys]\n", + " combined_genesets[argument_hash] = gsf.GeneSet.from_GeneSets(gene_sets, agem.gene_index, name=argument_hash, attrs=gene_sets[0].data.attrs)\n", + "\n", + " collections.append(gsf.GeneSetCollection(gem=agem, gene_sets=combined_genesets, name=label))\n", + " \n", + "treatment_coll, genotype_coll, subspecies_coll = collections" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\n", + "Treatment\n", + "GeneSets (10 total): Support Count\n", + " 3a6380: 2577\n", + " 36b179: 2576\n", + " 644cfd: 2504\n", + " 21a38c: 2289\n", + " f962d6: 1636\n", + " f79407: 1064\n", + " e90ecb: 1039\n", + " 26b197: 965\n", + " eb6a41: 876\n", + " a45d98: 766" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "treatment_coll" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "OrderedDict([('boruta_model',\n", + " '{\"estimator\": \"\", \"two_step\": true, \"verbose\": 0, \"max_iter\": 200, \"perc\": 95, \"alpha\": 0.05, \"n_estimators\": 1000, \"random_state\": null}'),\n", + " ('ranking_model',\n", + " '{\"bootstrap\": true, \"ccp_alpha\": 0.0, \"class_weight\": null, \"criterion\": \"gini\", \"max_depth\": 6, \"max_features\": \"auto\", \"max_leaf_nodes\": null, \"max_samples\": null, \"min_impurity_decrease\": 0.0, \"min_impurity_split\": null, \"min_samples_leaf\": 1, \"min_samples_split\": 2, \"min_weight_fraction_leaf\": 0.0, \"n_estimators\": 1000, \"n_jobs\": -1, \"oob_score\": false, \"random_state\": \"\", \"verbose\": 0, \"warm_start\": false}'),\n", + " ('selected_count_variable', 'counts'),\n", + " ('selected_annotation_variables', 'Treatment'),\n", + " ('arg_hash', '3a6380')])" + ] + }, + "execution_count": 61, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "treatment_coll.gene_sets[\"3a6380\"].data.attrs" + ] + }, + { + "cell_type": "code", + "execution_count": null, "metadata": {}, "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\n", + "Genotype\n", + "GeneSets (10 total): Support Count\n", + " 75bfe3: 1139\n", + " 488d45: 1125\n", + " a6130e: 1121\n", + " 891c83: 1077\n", + " dc6a48: 910\n", + " 9fda5b: 759\n", + " 4d726f: 747\n", + " d38fb9: 742\n", + " 8fa5fc: 729\n", + " b8df5c: 687" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "genotype_coll" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\n", + "Subspecies\n", + "GeneSets (10 total): Support Count\n", + " 921936: 387\n", + " d75652: 384\n", + " 2e4ade: 382\n", + " 1ec403: 374\n", + " 749d0e: 363\n", + " 4f9452: 279\n", + " 0a0991: 276\n", + " c3e5ee: 273\n", + " 019524: 273\n", + " cfa346: 273" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "# lcoll.save(LINEAMENT_DIR)" + "subspecies_coll" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "markdown", "metadata": {}, @@ -2643,13 +2948,13 @@ "pycharm": { "stem_cell": { "cell_type": "raw", - "source": [], "metadata": { "collapsed": false - } + }, + "source": [] } } }, "nbformat": 4, "nbformat_minor": 4 -} \ No newline at end of file +} From 4ac2f6b73f551b94904f3fc791ed6175ecd40635 Mon Sep 17 00:00:00 2001 From: Tyler Biggs Date: Tue, 7 Jan 2020 15:17:59 -0800 Subject: [PATCH 2/2] updated notebooks: --- examples/Welcome.ipynb | 24 +- examples/assets/user_guide.svg | 1 + examples/user_guide/GeneSet_Analysis.ipynb | 1014 +++++++---------- .../Genewise_Scatter_and_Distributions.ipynb | 122 +- .../UMAP_Panels_and_views.ipynb | 273 +++-- examples/user_guide/user_guide.ipynb | 79 ++ 6 files changed, 667 insertions(+), 846 deletions(-) create mode 100644 examples/assets/user_guide.svg create mode 100644 examples/user_guide/user_guide.ipynb diff --git a/examples/Welcome.ipynb b/examples/Welcome.ipynb index 45fafff..ad1d670 100644 --- a/examples/Welcome.ipynb +++ b/examples/Welcome.ipynb @@ -10,8 +10,6 @@ "\n", "\"GSForge\n", "\n", - "\"GSForge\n", - "\n", "### Tutorial Links\n", "\n", "+ [User Guide](user_guide/index)\n", @@ -24,22 +22,32 @@ ], "metadata": { "kernelspec": { - "display_name": "", - "name": "" + "display_name": "Python (base)", + "language": "python", + "name": "python3" }, "language_info": { - "name": "" + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" }, "pycharm": { "stem_cell": { "cell_type": "raw", - "source": [], "metadata": { "collapsed": false - } + }, + "source": [] } } }, "nbformat": 4, "nbformat_minor": 4 -} \ No newline at end of file +} diff --git a/examples/assets/user_guide.svg b/examples/assets/user_guide.svg new file mode 100644 index 0000000..e2690b2 --- /dev/null +++ b/examples/assets/user_guide.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/user_guide/GeneSet_Analysis.ipynb b/examples/user_guide/GeneSet_Analysis.ipynb index 9a2a2eb..a0f9760 100644 --- a/examples/user_guide/GeneSet_Analysis.ipynb +++ b/examples/user_guide/GeneSet_Analysis.ipynb @@ -4,6 +4,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ + "# GeneSet Analysis\n", + "\n", "This notebook gives some simple examples for:\n", "+ Comparing GeneSets to eachother via some machine-learning model score.\n", "+ Ranking genes within a geneset based on some machine-learning model." @@ -571,7 +573,20 @@ "text/html": [ "\n", "\n", - "\n", "\n", "\n", @@ -1744,7 +1746,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -1770,8 +1772,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 30.1 s, sys: 38.9 s, total: 1min 8s\n", - "Wall time: 50.8 s\n" + "CPU times: user 32 s, sys: 48.4 s, total: 1min 20s\n", + "Wall time: 1min 1s\n" ] } ], @@ -1800,10 +1802,10 @@ "Coordinates:\n", " * Gene (Gene) object 'LOC_Os03g11550' ... 'LOC_Os10g36690'\n", " * feature_importance_iter (feature_importance_iter) int64 0 1 2\n", - " feature_importance_mean (Gene) float64 0.001169 0.0007716 ... 0.0007009\n", - " feature_importance_std (Gene) float64 0.0001653 9.932e-05 ... 0.0002353\n", + " feature_importance_mean (Gene) float64 0.001046 0.0007688 ... 0.0008783\n", + " feature_importance_std (Gene) float64 0.000333 0.0001248 ... 7.171e-05\n", "Data variables:\n", - " feature_importances (feature_importance_iter, Gene) float64 0.001377 ... 0.0007873" + " feature_importances (feature_importance_iter, Gene) float64 0.0007384 ... 0.0008816" ] }, "execution_count": 9, @@ -1864,7 +1866,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "***Family-wise error rates***" + "### Estimate False Discovery Rates" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**nFDR**" ] }, { @@ -1876,15 +1885,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 39.6 s, sys: 1min 25s, total: 2min 5s\n", - "Wall time: 1min 42s\n" + "CPU times: user 59.8 s, sys: 29.8 s, total: 1min 29s\n", + "Wall time: 49.9 s\n" ] } ], "source": [ "%%time\n", - "\n", - "treatment_fwe = gsf.operations.analytics.calculate_family_wise_error_rates(\n", + "treatment_nFDR = gsf.operations.analytics.nFDR(\n", " gsc,\n", " selected_gene_sets=[\"Boruta_Treatment\"],\n", " annotation_variables=\"Treatment\",\n", @@ -1902,14 +1910,14 @@ "data": { "text/plain": [ "\n", - "Dimensions: (Gene: 681, fwe_iter: 3)\n", + "Dimensions: (Gene: 681, nFDR_iter: 3)\n", "Coordinates:\n", - " * Gene (Gene) object 'LOC_Os03g11550' ... 'LOC_Os10g36690'\n", - " * fwe_iter (fwe_iter) int64 0 1 2\n", - " fwe_mean (Gene) float64 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0\n", - " fwe_std (Gene) float64 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0\n", + " * Gene (Gene) object 'LOC_Os03g11550' ... 'LOC_Os10g36690'\n", + " * nFDR_iter (nFDR_iter) int64 0 1 2\n", + " nFDR_mean (Gene) float64 0.9481 0.979 0.006363 ... 0.8209 0.514 0.8243\n", + " nFDR_std (Gene) float64 0.02289 0.01165 0.007983 ... 0.04809 0.3655 0.2329\n", "Data variables:\n", - " Family-wise error rate (fwe_iter, Gene) float64 0.0 0.0 0.0 ... 0.0 0.0 0.0" + " nFDR (nFDR_iter, Gene) float64 0.9163 0.9633 ... 0.4758 0.4949" ] }, "execution_count": 12, @@ -1918,7 +1926,7 @@ } ], "source": [ - "treatment_fwe" + "treatment_nFDR" ] }, { @@ -1927,15 +1935,14 @@ "metadata": {}, "outputs": [], "source": [ - "gsc.gene_sets[\"Boruta_Treatment\"].data = gsc.gene_sets[\"Boruta_Treatment\"].data.update(treatment_fwe)\n", - "# gsc.gene_sets[\"Boruta_stress\"].data " + "gsc.gene_sets[\"Boruta_Treatment\"].data = gsc.gene_sets[\"Boruta_Treatment\"].data.update(treatment_nFDR)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "***Null-rank distribution***" + "**mProbes**" ] }, { @@ -1947,15 +1954,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 32.1 s, sys: 50.4 s, total: 1min 22s\n", - "Wall time: 1min 4s\n" + "CPU times: user 33.6 s, sys: 27.9 s, total: 1min 1s\n", + "Wall time: 38.9 s\n" ] } ], "source": [ "%%time\n", - "\n", - "treatment_nrd = gsf.operations.analytics.calculate_null_rank_distribution(\n", + "treatment_mProbes = gsf.operations.analytics.mProbes(\n", " gsc,\n", " selected_gene_sets=[\"Boruta_Treatment\"],\n", " annotation_variables=\"Treatment\",\n", @@ -1968,69 +1974,60 @@ "cell_type": "code", "execution_count": 15, "metadata": {}, - "outputs": [], - "source": [ - "gsc.gene_sets[\"Boruta_Treatment\"].data = gsc.gene_sets[\"Boruta_Treatment\"].data.update(treatment_nrd)\n", - "# gsc.gene_sets[\"Boruta_stress\"].data " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "***Getting at the rankings***" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\n", - "Dimensions: (Gene: 55986, feature_importance_iter: 3, fwe_iter: 3, nrd_iter: 3)\n", + "Dimensions: (Gene: 681, mProbes_iter: 3)\n", "Coordinates:\n", - " * Gene (Gene) object 'LOC_Os06g05820' ... 'LOC_Os07g03418'\n", - " * feature_importance_iter (feature_importance_iter) int64 0 1 2\n", - " feature_importance_mean (Gene) float64 nan nan nan nan ... nan nan nan\n", - " feature_importance_std (Gene) float64 nan nan nan nan ... nan nan nan\n", - " * fwe_iter (fwe_iter) int64 0 1 2\n", - " fwe_mean (Gene) float64 nan nan nan nan ... 0.0 nan nan nan\n", - " fwe_std (Gene) float64 nan nan nan nan ... 0.0 nan nan nan\n", - " * nrd_iter (nrd_iter) int64 0 1 2\n", - " nrd_mean (Gene) float64 nan nan nan nan ... nan nan nan\n", - " nrd_std (Gene) float64 nan nan nan nan ... nan nan nan\n", + " * Gene (Gene) object 'LOC_Os03g11550' ... 'LOC_Os10g36690'\n", + " * mProbes_iter (mProbes_iter) int64 0 1 2\n", + " mProbes_mean (Gene) float64 0.0004895 0.0004895 0.0 ... 0.0 0.0 0.0\n", + " mProbes_std (Gene) float64 0.0006922 0.0006922 0.0 ... 0.0 0.0 0.0\n", "Data variables:\n", - " support (Gene) bool False False False ... False False False\n", - " support_weak (Gene) bool False False False ... False False False\n", - " ranking (Gene) int64 10029 34446 34446 ... 34446 3373 34446\n", - " feature_importances (feature_importance_iter, Gene) float64 nan ... nan\n", - " Family-wise error rate (fwe_iter, Gene) float64 nan nan nan ... nan nan\n", - " null rank distribution (nrd_iter, Gene) float64 nan nan nan ... nan nan\n", - "Attributes:\n", - " boruta_model: {\"two_step\": true, \"max_iter\": 50, \"estim...\n", - " ranking_model: {\"bootstrap\": true, \"class_weight\": \"bala...\n", - " selected_count_variable: counts\n", - " selected_annotation_variables: Treatment\n", - " __GSForge.GeneSet.params: {\"gene_index_name\": \"Gene\", \"name\": \"Boru..." + " mProbes NRD (mProbes_iter, Gene) float64 0.001468 0.001468 0.0 ... 0.0 0.0" ] }, - "execution_count": 16, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# View the xarray dataset of a GeneSet:\n", - "gsc.gene_sets[\"Boruta_Treatment\"].data" + "treatment_mProbes" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "gsc.gene_sets[\"Boruta_Treatment\"].data = gsc.gene_sets[\"Boruta_Treatment\"].data.update(treatment_mProbes)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Examine Rankings" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, + "outputs": [], + "source": [ + "# View the xarray dataset of a GeneSet:\n", + "# gsc.gene_sets[\"Boruta_Treatment\"].data" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, "outputs": [ { "data": { @@ -2038,7 +2035,7 @@ "681" ] }, - "execution_count": 17, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -2057,32 +2054,32 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\n", - "Dimensions: (Gene: 681, feature_importance_iter: 3, fwe_iter: 3, nrd_iter: 3)\n", + "Dimensions: (Gene: 681, feature_importance_iter: 3, mProbes_iter: 3, nFDR_iter: 3)\n", "Coordinates:\n", " * Gene (Gene) object 'LOC_Os03g11550' ... 'LOC_Os10g36690'\n", " * feature_importance_iter (feature_importance_iter) int64 0 1 2\n", - " feature_importance_mean (Gene) float64 0.001169 0.0007716 ... 0.0007009\n", - " feature_importance_std (Gene) float64 0.0001653 9.932e-05 ... 0.0002353\n", - " * fwe_iter (fwe_iter) int64 0 1 2\n", - " fwe_mean (Gene) float64 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0\n", - " fwe_std (Gene) float64 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0\n", - " * nrd_iter (nrd_iter) int64 0 1 2\n", - " nrd_mean (Gene) float64 0.0 0.003916 0.0 ... 0.0 0.001958\n", - " nrd_std (Gene) float64 0.0 0.002769 0.0 ... 0.0 0.002769\n", + " feature_importance_mean (Gene) float64 0.001046 0.0007688 ... 0.0008783\n", + " feature_importance_std (Gene) float64 0.000333 0.0001248 ... 7.171e-05\n", + " * nFDR_iter (nFDR_iter) int64 0 1 2\n", + " nFDR_mean (Gene) float64 0.9481 0.979 ... 0.514 0.8243\n", + " nFDR_std (Gene) float64 0.02289 0.01165 ... 0.3655 0.2329\n", + " * mProbes_iter (mProbes_iter) int64 0 1 2\n", + " mProbes_mean (Gene) float64 0.0004895 0.0004895 0.0 ... 0.0 0.0\n", + " mProbes_std (Gene) float64 0.0006922 0.0006922 0.0 ... 0.0 0.0\n", "Data variables:\n", " support (Gene) bool True True True True ... True True True\n", " support_weak (Gene) bool False False False ... False False False\n", " ranking (Gene) int64 1 1 1 1 1 1 1 1 1 ... 1 1 1 1 1 1 1 1\n", - " feature_importances (feature_importance_iter, Gene) float64 0.001377 ... 0.0007873\n", - " Family-wise error rate (fwe_iter, Gene) float64 0.0 0.0 0.0 ... 0.0 0.0\n", - " null rank distribution (nrd_iter, Gene) float64 0.0 0.005874 ... 0.0 0.0\n", + " feature_importances (feature_importance_iter, Gene) float64 0.0007384 ... 0.0008816\n", + " nFDR (nFDR_iter, Gene) float64 0.9163 0.9633 ... 0.4949\n", + " mProbes NRD (mProbes_iter, Gene) float64 0.001468 ... 0.0\n", "Attributes:\n", " boruta_model: {\"two_step\": true, \"max_iter\": 50, \"estim...\n", " ranking_model: {\"bootstrap\": true, \"class_weight\": \"bala...\n", @@ -2091,7 +2088,7 @@ " __GSForge.GeneSet.params: {\"gene_index_name\": \"Gene\", \"name\": \"Boru..." ] }, - "execution_count": 18, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -2103,7 +2100,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -2113,26 +2110,99 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 134, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.holoviews_exec.v0+json": "", + "text/html": [ + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "
\n", + "" + ], + "text/plain": [ + ":Scatter [feature_importance_mean,nFDR_mean] (mProbes_mean,feature_importance_std,nFDR_std,mProbes_std)" + ] + }, + "execution_count": 134, + "metadata": { + "application/vnd.holoviews_exec.v0+json": { + "id": "5215" + } + }, + "output_type": "execute_result" + } + ], + "source": [ + "df = ds[[\"feature_importance_mean\", \"nFDR_mean\"]].to_dataframe()\n", + "plot = hv.Scatter(df, [(\"feature_importance_mean\", \"Mean Feature Importance Rank\"),\n", + " (\"nFDR_mean\", \"False Discovery Rate\")]\n", + " ).opts(padding=0.1, width=400, height=400)\n", + "plot" + ] + }, + { + "cell_type": "code", + "execution_count": 135, + "metadata": {}, + "outputs": [], + "source": [ + "# hv.save(plot, \"fdr_vs_importance.png\")" + ] + }, + { + "cell_type": "code", + "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "application/vnd.holoviews_exec.v0+json": "", "text/html": [ - "
\n", + "
\n", "\n", "\n", "\n", "\n", "\n", - "
\n", + "
\n", "
\n", "" ], "text/plain": [ - ":Scatter [feature_importance_mean] (nrd_mean,feature_importance_std,fwe_std,nrd_std,fwe_mean)" + ":Scatter [feature_importance_mean] (mProbes_mean,nFDR_mean,feature_importance_std,nFDR_std,mProbes_std)" ] }, - "execution_count": 20, + "execution_count": 22, "metadata": { "application/vnd.holoviews_exec.v0+json": { - "id": "1003" + "id": "1111" } }, "output_type": "execute_result" } ], "source": [ - "df = ds[[\"feature_importance_mean\", \"nrd_mean\"]].to_dataframe()\n", - "hv.Scatter(df).opts(padding=0.1, width=500, height=500)" + "df = ds[[\"feature_importance_mean\", \"mProbes_mean\"]].to_dataframe()\n", + "hv.Scatter(df).opts(padding=0.1, width=400, height=400)" ] }, { @@ -2180,13 +2250,13 @@ "\n", "Another way to evaluate a classification model is the [ROC](https://scikit-learn.org/stable/auto_examples/model_selection/plot_roc.html#sphx-glr-auto-examples-model-selection-plot-roc-py).\n", "\n", - "Viewing ROC curves for multi-label models is a bit indirect, so we provide this walkthrough.\n", + "Viewing ROC curves for multi-label models is a bit indirect as we have to use a binary classifier for each unique target label, so we provide this walkthrough.\n", "Also examine the [sklearn demo](https://scikit-learn.org/stable/auto_examples/model_selection/plot_roc.html)." ] }, { "cell_type": "code", - "execution_count": 86, + "execution_count": 23, "metadata": {}, "outputs": [], "source": [ @@ -2204,7 +2274,7 @@ }, { "cell_type": "code", - "execution_count": 96, + "execution_count": 97, "metadata": {}, "outputs": [ { @@ -2214,13 +2284,13 @@ " dtype=object)" ] }, - "execution_count": 96, + "execution_count": 97, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "counts, treatment = gsf.get_data(agem, annotation_variables=\"Treatment\")\n", + "counts, treatment = gsf.get_data(gsc, annotation_variables=\"Treatment\",selected_gene_sets=[\"Boruta_Treatment\"])\n", "classes = treatment.to_series().unique()\n", "classes" ] @@ -2234,7 +2304,7 @@ }, { "cell_type": "code", - "execution_count": 83, + "execution_count": 98, "metadata": {}, "outputs": [ { @@ -2249,7 +2319,7 @@ " [0., 0., 0., 1., 0.]])" ] }, - "execution_count": 83, + "execution_count": 98, "metadata": {}, "output_type": "execute_result" } @@ -2269,7 +2339,7 @@ }, { "cell_type": "code", - "execution_count": 84, + "execution_count": 99, "metadata": {}, "outputs": [], "source": [ @@ -2285,21 +2355,21 @@ }, { "cell_type": "code", - "execution_count": 88, + "execution_count": 100, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 5.42 s, sys: 476 ms, total: 5.89 s\n", - "Wall time: 14 s\n" + "CPU times: user 5 s, sys: 322 ms, total: 5.32 s\n", + "Wall time: 7.05 s\n" ] } ], "source": [ "%%time\n", - "roc_rf_model = OneVsRestClassifier(RandomForestClassifier(class_weight='balanced', \n", + "roc_rf_model = OneVsRestClassifier(RandomForestClassifier(class_weight='balanced', max_depth=3,\n", " n_estimators=1000, n_jobs=-1))\n", "roc_rf_model = roc_rf_model.fit(x_train, y_train)" ] @@ -2313,20 +2383,20 @@ }, { "cell_type": "code", - "execution_count": 93, + "execution_count": 101, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "array([[0.643, 0.01 , 0.024, 0.063, 0.212],\n", - " [0.616, 0.318, 0.066, 0.02 , 0.011],\n", - " [0.013, 0.007, 0.868, 0.024, 0.065],\n", - " [0.31 , 0.066, 0.231, 0.085, 0.183],\n", - " [0.185, 0.004, 0.646, 0.008, 0.142]])" + "array([[0.73333022, 0.66598266, 0.00726503, 0.15976397, 0.01979039],\n", + " [0.05407875, 0.00253519, 0.87441341, 0.01685384, 0.1158844 ],\n", + " [0.12352609, 0.02328239, 0.52621856, 0.02173646, 0.57647534],\n", + " [0.26545577, 0.00429616, 0.0633575 , 0.03606417, 0.83556347],\n", + " [0.59150757, 0.1084059 , 0.0406514 , 0.4259592 , 0.03584087]])" ] }, - "execution_count": 93, + "execution_count": 101, "metadata": {}, "output_type": "execute_result" } @@ -2338,7 +2408,7 @@ }, { "cell_type": "code", - "execution_count": 97, + "execution_count": 102, "metadata": {}, "outputs": [], "source": [ @@ -2352,7 +2422,7 @@ }, { "cell_type": "code", - "execution_count": 99, + "execution_count": 103, "metadata": {}, "outputs": [], "source": [ @@ -2362,26 +2432,26 @@ }, { "cell_type": "code", - "execution_count": 102, + "execution_count": 104, "metadata": {}, "outputs": [ { "data": { "application/vnd.holoviews_exec.v0+json": "", "text/html": [ - "
\n", + "
\n", "\n", "\n", "\n", "\n", "\n", - "
\n", + "
\n", "
\n", "" + ], + "text/plain": [ + ":Raster [x,y] (z)" + ] + }, + "execution_count": 130, + "metadata": { + "application/vnd.holoviews_exec.v0+json": { + "id": "4891" + } + }, + "output_type": "execute_result" + } + ], + "source": [ + "tree_subset = counts.isel(Gene=np.argwhere(selected_tree.feature_importances_).flatten())\n", + "hv.Raster(tree_subset.values).opts(logz=True)" ] }, { @@ -3024,13 +2862,13 @@ "pycharm": { "stem_cell": { "cell_type": "raw", - "source": [], "metadata": { "collapsed": false - } + }, + "source": [] } } }, "nbformat": 4, "nbformat_minor": 4 -} \ No newline at end of file +} diff --git a/examples/user_guide/plotting_guide/Genewise_Scatter_and_Distributions.ipynb b/examples/user_guide/plotting_guide/Genewise_Scatter_and_Distributions.ipynb index c6393b0..3f5b0f5 100644 --- a/examples/user_guide/plotting_guide/Genewise_Scatter_and_Distributions.ipynb +++ b/examples/user_guide/plotting_guide/Genewise_Scatter_and_Distributions.ipynb @@ -745,59 +745,6 @@ " \n", "\n", "\n", - " \n", - " \n", "\n", "\n", "
\n" @@ -1377,47 +1324,6 @@ " }\n", "}\n", "\n", - "// Define MPL specific subclasses\n", - "function MPLSelectionWidget() {\n", - " SelectionWidget.apply(this, arguments);\n", - "}\n", - "\n", - "function MPLScrubberWidget() {\n", - " ScrubberWidget.apply(this, arguments);\n", - "}\n", - "\n", - "// Let them inherit from the baseclasses\n", - "MPLSelectionWidget.prototype = Object.create(SelectionWidget.prototype);\n", - "MPLScrubberWidget.prototype = Object.create(ScrubberWidget.prototype);\n", - "\n", - "// Define methods to override on widgets\n", - "var MPLMethods = {\n", - " init_slider : function(init_val){\n", - " if(this.load_json) {\n", - " this.from_json()\n", - " } else {\n", - " this.update_cache();\n", - " }\n", - " if (this.dynamic | !this.cached | (this.current_vals === undefined)) {\n", - " this.update(0)\n", - " } else {\n", - " this.set_frame(this.current_vals[0], 0)\n", - " }\n", - " },\n", - " process_msg : function(msg) {\n", - " var data = msg.content.data;\n", - " this.frames[this.current] = data;\n", - " this.update_cache(true);\n", - " this.update(this.current);\n", - " }\n", - "}\n", - "// Extend MPL widgets with backend specific methods\n", - "extend(MPLSelectionWidget.prototype, MPLMethods);\n", - "extend(MPLScrubberWidget.prototype, MPLMethods);\n", - "\n", - "window.HoloViews.MPLSelectionWidget = MPLSelectionWidget\n", - "window.HoloViews.MPLScrubberWidget = MPLScrubberWidget\n", - "\n", "// Define Bokeh specific subclasses\n", "function BokehSelectionWidget() {\n", " SelectionWidget.apply(this, arguments);\n", @@ -1679,7 +1585,7 @@ " }\n", "}\n" ], - "application/vnd.holoviews_load.v0+json": "function HoloViewsWidget() {\n}\n\nHoloViewsWidget.prototype.init_slider = function(init_val){\n if(this.load_json) {\n this.from_json()\n } else {\n this.update_cache();\n }\n}\n\nHoloViewsWidget.prototype.populate_cache = function(idx){\n this.cache[idx].innerHTML = this.frames[idx];\n if (this.embed) {\n delete this.frames[idx];\n }\n}\n\nHoloViewsWidget.prototype.process_error = function(msg){\n}\n\nHoloViewsWidget.prototype.from_json = function() {\n var data_url = this.json_path + this.id + '.json';\n $.getJSON(data_url, $.proxy(function(json_data) {\n this.frames = json_data;\n this.update_cache();\n this.update(0);\n }, this));\n}\n\nHoloViewsWidget.prototype.dynamic_update = function(current){\n if (current === undefined) {\n return\n }\n this.current = current;\n if (this.comm) {\n var msg = {comm_id: this.id+'_client', content: current}\n this.comm.send(msg);\n }\n}\n\nHoloViewsWidget.prototype.update_cache = function(force){\n var frame_len = Object.keys(this.frames).length;\n for (var i=0; i 0) {\n that.time = Date.now();\n that.dynamic_update(that.queue[that.queue.length-1]);\n that.queue = [];\n } else {\n that.wait = false;\n }\n if ((msg.msg_type == \"Ready\") && msg.content) {\n console.log(\"Python callback returned following output:\", msg.content);\n } else if (msg.msg_type == \"Error\") {\n console.log(\"Python failed with the following traceback:\", msg.traceback)\n }\n }\n var comm = HoloViews.comm_manager.get_client_comm(this.plot_id, this.id+'_client', ack_callback);\n return comm\n }\n}\n\nHoloViewsWidget.prototype.msg_handler = function(msg) {\n var metadata = msg.metadata;\n if ((metadata.msg_type == \"Ready\")) {\n if (metadata.content) {\n console.log(\"Python callback returned following output:\", metadata.content);\n }\n\treturn;\n } else if (metadata.msg_type == \"Error\") {\n console.log(\"Python failed with the following traceback:\", metadata.traceback)\n return\n }\n this.process_msg(msg)\n}\n\nHoloViewsWidget.prototype.process_msg = function(msg) {\n}\n\nfunction SelectionWidget(frames, id, slider_ids, keyMap, dim_vals, notFound, load_json, mode, cached, json_path, dynamic, plot_id){\n this.frames = frames;\n this.id = id;\n this.plot_id = plot_id;\n this.slider_ids = slider_ids;\n this.keyMap = keyMap\n this.current_frame = 0;\n this.current_vals = dim_vals;\n this.load_json = load_json;\n this.mode = mode;\n this.notFound = notFound;\n this.cached = cached;\n this.dynamic = dynamic;\n this.cache = {};\n this.json_path = json_path;\n this.init_slider(this.current_vals[0]);\n this.queue = [];\n this.wait = false;\n if (!this.cached || this.dynamic) {\n this.comm = this.init_comms();\n }\n}\n\nSelectionWidget.prototype = new HoloViewsWidget;\n\n\nSelectionWidget.prototype.get_key = function(current_vals) {\n var key = \"(\";\n for (var i=0; i Date.now()))) {\n this.queue.push(key);\n return\n }\n this.queue = [];\n this.time = Date.now();\n this.current_frame = key;\n this.wait = true;\n this.dynamic_update(key)\n } else if (key !== undefined) {\n this.update(key)\n }\n}\n\n\n/* Define the ScrubberWidget class */\nfunction ScrubberWidget(frames, num_frames, id, interval, load_json, mode, cached, json_path, dynamic, plot_id){\n this.slider_id = \"_anim_slider\" + id;\n this.loop_select_id = \"_anim_loop_select\" + id;\n this.id = id;\n this.plot_id = plot_id;\n this.interval = interval;\n this.current_frame = 0;\n this.direction = 0;\n this.dynamic = dynamic;\n this.timer = null;\n this.load_json = load_json;\n this.mode = mode;\n this.cached = cached;\n this.frames = frames;\n this.cache = {};\n this.length = num_frames;\n this.json_path = json_path;\n document.getElementById(this.slider_id).max = this.length - 1;\n this.init_slider(0);\n this.wait = false;\n this.queue = [];\n if (!this.cached || this.dynamic) {\n this.comm = this.init_comms()\n }\n}\n\nScrubberWidget.prototype = new HoloViewsWidget;\n\nScrubberWidget.prototype.set_frame = function(frame){\n this.current_frame = frame;\n var widget = document.getElementById(this.slider_id);\n if (widget === null) {\n this.pause_animation();\n return\n }\n widget.value = this.current_frame;\n if (this.dynamic || !this.cached) {\n if ((this.time !== undefined) && ((this.wait) && ((this.time + 10000) > Date.now()))) {\n this.queue.push(frame);\n return\n }\n this.queue = [];\n this.time = Date.now();\n this.wait = true;\n this.dynamic_update(frame)\n } else {\n this.update(frame)\n }\n}\n\nScrubberWidget.prototype.get_loop_state = function(){\n var button_group = document[this.loop_select_id].state;\n for (var i = 0; i < button_group.length; i++) {\n var button = button_group[i];\n if (button.checked) {\n return button.value;\n }\n }\n return undefined;\n}\n\n\nScrubberWidget.prototype.next_frame = function() {\n this.set_frame(Math.min(this.length - 1, this.current_frame + 1));\n}\n\nScrubberWidget.prototype.previous_frame = function() {\n this.set_frame(Math.max(0, this.current_frame - 1));\n}\n\nScrubberWidget.prototype.first_frame = function() {\n this.set_frame(0);\n}\n\nScrubberWidget.prototype.last_frame = function() {\n this.set_frame(this.length - 1);\n}\n\nScrubberWidget.prototype.slower = function() {\n this.interval /= 0.7;\n if(this.direction > 0){this.play_animation();}\n else if(this.direction < 0){this.reverse_animation();}\n}\n\nScrubberWidget.prototype.faster = function() {\n this.interval *= 0.7;\n if(this.direction > 0){this.play_animation();}\n else if(this.direction < 0){this.reverse_animation();}\n}\n\nScrubberWidget.prototype.anim_step_forward = function() {\n if(this.current_frame < this.length - 1){\n this.next_frame();\n }else{\n var loop_state = this.get_loop_state();\n if(loop_state == \"loop\"){\n this.first_frame();\n }else if(loop_state == \"reflect\"){\n this.last_frame();\n this.reverse_animation();\n }else{\n this.pause_animation();\n this.last_frame();\n }\n }\n}\n\nScrubberWidget.prototype.anim_step_reverse = function() {\n if(this.current_frame > 0){\n this.previous_frame();\n } else {\n var loop_state = this.get_loop_state();\n if(loop_state == \"loop\"){\n this.last_frame();\n }else if(loop_state == \"reflect\"){\n this.first_frame();\n this.play_animation();\n }else{\n this.pause_animation();\n this.first_frame();\n }\n }\n}\n\nScrubberWidget.prototype.pause_animation = function() {\n this.direction = 0;\n if (this.timer){\n clearInterval(this.timer);\n this.timer = null;\n }\n}\n\nScrubberWidget.prototype.play_animation = function() {\n this.pause_animation();\n this.direction = 1;\n var t = this;\n if (!this.timer) this.timer = setInterval(function(){t.anim_step_forward();}, this.interval);\n}\n\nScrubberWidget.prototype.reverse_animation = function() {\n this.pause_animation();\n this.direction = -1;\n var t = this;\n if (!this.timer) this.timer = setInterval(function(){t.anim_step_reverse();}, this.interval);\n}\n\nfunction extend(destination, source) {\n for (var k in source) {\n if (source.hasOwnProperty(k)) {\n destination[k] = source[k];\n }\n }\n return destination;\n}\n\nfunction update_widget(widget, values) {\n if (widget.hasClass(\"ui-slider\")) {\n widget.slider('option', {\n min: 0,\n max: values.length-1,\n dim_vals: values,\n value: 0,\n dim_labels: values\n })\n widget.slider('option', 'slide').call(widget, event, {value: 0})\n } else {\n widget.empty();\n for (var i=0; i\", {\n value: i,\n text: values[i]\n }))\n };\n widget.data('values', values);\n widget.data('value', 0);\n widget.trigger(\"change\");\n };\n}\n\nfunction init_slider(id, plot_id, dim, values, next_vals, labels, dynamic, step, value, next_dim,\n dim_idx, delay, jQueryUI_CDN, UNDERSCORE_CDN) {\n // Slider JS Block START\n function loadcssfile(filename){\n var fileref=document.createElement(\"link\")\n fileref.setAttribute(\"rel\", \"stylesheet\")\n fileref.setAttribute(\"type\", \"text/css\")\n fileref.setAttribute(\"href\", filename)\n document.getElementsByTagName(\"head\")[0].appendChild(fileref)\n }\n loadcssfile(\"https://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css\");\n /* Check if jQuery and jQueryUI have been loaded\n otherwise load with require.js */\n var jQuery = window.jQuery,\n // check for old versions of jQuery\n oldjQuery = jQuery && !!jQuery.fn.jquery.match(/^1\\.[0-4](\\.|$)/),\n jquery_path = '',\n paths = {},\n noConflict;\n var jQueryUI = jQuery.ui;\n // check for jQuery\n if (!jQuery || oldjQuery) {\n // load if it's not available or doesn't meet min standards\n paths.jQuery = jQuery;\n noConflict = !!oldjQuery;\n } else {\n // register the current jQuery\n define('jquery', [], function() { return jQuery; });\n }\n if (!jQueryUI) {\n paths.jQueryUI = jQueryUI_CDN.slice(null, -3);\n } else {\n define('jQueryUI', [], function() { return jQuery.ui; });\n }\n paths.underscore = UNDERSCORE_CDN.slice(null, -3);\n var jquery_require = {\n paths: paths,\n shim: {\n \"jQueryUI\": {\n exports:\"$\",\n deps: ['jquery']\n },\n \"underscore\": {\n exports: '_'\n }\n }\n }\n require.config(jquery_require);\n require([\"jQueryUI\", \"underscore\"], function(jUI, _){\n if (noConflict) $.noConflict(true);\n var vals = values;\n if (dynamic && vals.constructor === Array) {\n var default_value = parseFloat(value);\n var min = parseFloat(vals[0]);\n var max = parseFloat(vals[vals.length-1]);\n var wstep = step;\n var wlabels = [default_value];\n var init_label = default_value;\n } else {\n var min = 0;\n if (dynamic) {\n var max = Object.keys(vals).length - 1;\n var init_label = labels[value];\n var default_value = values[value];\n } else {\n var max = vals.length - 1;\n var init_label = labels[value];\n var default_value = value;\n }\n var wstep = 1;\n var wlabels = labels;\n }\n function adjustFontSize(text) {\n var width_ratio = (text.parent().width()/8)/text.val().length;\n var size = Math.min(0.9, Math.max(0.6, width_ratio))+'em';\n text.css('font-size', size);\n }\n var slider = $('#_anim_widget'+id+'_'+dim);\n slider.slider({\n animate: \"fast\",\n min: min,\n max: max,\n step: wstep,\n value: default_value,\n dim_vals: vals,\n dim_labels: wlabels,\n next_vals: next_vals,\n slide: function(event, ui) {\n var vals = slider.slider(\"option\", \"dim_vals\");\n var next_vals = slider.slider(\"option\", \"next_vals\");\n var dlabels = slider.slider(\"option\", \"dim_labels\");\n if (dynamic) {\n var dim_val = ui.value;\n if (vals.constructor === Array) {\n var label = ui.value;\n } else {\n var label = dlabels[ui.value];\n }\n } else {\n var dim_val = vals[ui.value];\n var label = dlabels[ui.value];\n }\n var text = $('#textInput'+id+'_'+dim);\n text.val(label);\n adjustFontSize(text);\n HoloViews.index[plot_id].set_frame(dim_val, dim_idx);\n if (Object.keys(next_vals).length > 0) {\n var new_vals = next_vals[dim_val];\n var next_widget = $('#_anim_widget'+id+'_'+next_dim);\n update_widget(next_widget, new_vals);\n }\n }\n });\n slider.keypress(function(event) {\n if (event.which == 80 || event.which == 112) {\n var start = slider.slider(\"option\", \"value\");\n var stop = slider.slider(\"option\", \"max\");\n for (var i=start; i<=stop; i++) {\n var delay = i*delay;\n $.proxy(function doSetTimeout(i) { setTimeout($.proxy(function() {\n var val = {value:i};\n slider.slider('value',i);\n slider.slider(\"option\", \"slide\")(null, val);\n }, slider), delay);}, slider)(i);\n }\n }\n if (event.which == 82 || event.which == 114) {\n var start = slider.slider(\"option\", \"value\");\n var stop = slider.slider(\"option\", \"min\");\n var count = 0;\n for (var i=start; i>=stop; i--) {\n var delay = count*delay;\n count = count + 1;\n $.proxy(function doSetTimeout(i) { setTimeout($.proxy(function() {\n var val = {value:i};\n slider.slider('value',i);\n slider.slider(\"option\", \"slide\")(null, val);\n }, slider), delay);}, slider)(i);\n }\n }\n });\n var textInput = $('#textInput'+id+'_'+dim)\n textInput.val(init_label);\n adjustFontSize(textInput);\n });\n}\n\nfunction init_dropdown(id, plot_id, dim, vals, value, next_vals, labels, next_dim, dim_idx, dynamic) {\n var widget = $(\"#_anim_widget\"+id+'_'+dim);\n widget.data('values', vals)\n for (var i=0; i\", {\n value: val,\n text: labels[i]\n }));\n };\n widget.data(\"next_vals\", next_vals);\n widget.val(value);\n widget.on('change', function(event, ui) {\n if (dynamic) {\n var dim_val = parseInt(this.value);\n } else {\n var dim_val = $.data(this, 'values')[this.value];\n }\n var next_vals = $.data(this, \"next_vals\");\n if (Object.keys(next_vals).length > 0) {\n var new_vals = next_vals[dim_val];\n var next_widget = $('#_anim_widget'+id+'_'+next_dim);\n update_widget(next_widget, new_vals);\n }\n var widgets = HoloViews.index[plot_id]\n if (widgets) {\n widgets.set_frame(dim_val, dim_idx);\n }\n });\n}\n\n\nif (window.HoloViews === undefined) {\n window.HoloViews = {}\n window.PyViz = window.HoloViews\n} else if (window.PyViz === undefined) {\n window.PyViz = window.HoloViews\n}\n\n\nvar _namespace = {\n init_slider: init_slider,\n init_dropdown: init_dropdown,\n comms: {},\n comm_status: {},\n index: {},\n plot_index: {},\n kernels: {},\n receivers: {}\n}\n\nfor (var k in _namespace) {\n if (!(k in window.HoloViews)) {\n window.HoloViews[k] = _namespace[k];\n }\n}\n\n// Define MPL specific subclasses\nfunction MPLSelectionWidget() {\n SelectionWidget.apply(this, arguments);\n}\n\nfunction MPLScrubberWidget() {\n ScrubberWidget.apply(this, arguments);\n}\n\n// Let them inherit from the baseclasses\nMPLSelectionWidget.prototype = Object.create(SelectionWidget.prototype);\nMPLScrubberWidget.prototype = Object.create(ScrubberWidget.prototype);\n\n// Define methods to override on widgets\nvar MPLMethods = {\n init_slider : function(init_val){\n if(this.load_json) {\n this.from_json()\n } else {\n this.update_cache();\n }\n if (this.dynamic | !this.cached | (this.current_vals === undefined)) {\n this.update(0)\n } else {\n this.set_frame(this.current_vals[0], 0)\n }\n },\n process_msg : function(msg) {\n var data = msg.content.data;\n this.frames[this.current] = data;\n this.update_cache(true);\n this.update(this.current);\n }\n}\n// Extend MPL widgets with backend specific methods\nextend(MPLSelectionWidget.prototype, MPLMethods);\nextend(MPLScrubberWidget.prototype, MPLMethods);\n\nwindow.HoloViews.MPLSelectionWidget = MPLSelectionWidget\nwindow.HoloViews.MPLScrubberWidget = MPLScrubberWidget\n\n// Define Bokeh specific subclasses\nfunction BokehSelectionWidget() {\n SelectionWidget.apply(this, arguments);\n}\n\nfunction BokehScrubberWidget() {\n ScrubberWidget.apply(this, arguments);\n}\n\n// Let them inherit from the baseclasses\nBokehSelectionWidget.prototype = Object.create(SelectionWidget.prototype);\nBokehScrubberWidget.prototype = Object.create(ScrubberWidget.prototype);\n\n// Define methods to override on widgets\nvar BokehMethods = {\n update_cache : function(){\n for (var index in this.frames) {\n this.frames[index] = JSON.parse(this.frames[index]);\n }\n },\n update : function(current){\n if (current === undefined) {\n return;\n }\n var data = this.frames[current];\n if (data !== undefined) {\n if (data.root in HoloViews.plot_index) {\n var doc = HoloViews.plot_index[data.root].model.document;\n } else {\n var doc = Bokeh.index[data.root].model.document;\n }\n doc.apply_json_patch(data.content);\n }\n },\n init_comms: function() {\n if (Bokeh.protocol !== undefined) {\n this.receiver = new Bokeh.protocol.Receiver()\n } else {\n this.receiver = null;\n }\n return HoloViewsWidget.prototype.init_comms.call(this);\n },\n process_msg : function(msg) {\n if (this.plot_id in HoloViews.plot_index) {\n var doc = HoloViews.plot_index[this.plot_id].model.document;\n } else {\n var doc = Bokeh.index[this.plot_id].model.document;\n }\n if (this.receiver === null) { return }\n var receiver = this.receiver;\n if (msg.buffers.length > 0) {\n receiver.consume(msg.buffers[0].buffer)\n } else {\n receiver.consume(msg.content.data)\n }\n const comm_msg = receiver.message;\n if ((comm_msg != null) && (doc != null)) {\n doc.apply_json_patch(comm_msg.content, comm_msg.buffers)\n }\n }\n}\n\n// Extend Bokeh widgets with backend specific methods\nextend(BokehSelectionWidget.prototype, BokehMethods);\nextend(BokehScrubberWidget.prototype, BokehMethods);\n\nwindow.HoloViews.BokehSelectionWidget = BokehSelectionWidget\nwindow.HoloViews.BokehScrubberWidget = BokehScrubberWidget\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n }\n\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n" + "application/vnd.holoviews_load.v0+json": "function HoloViewsWidget() {\n}\n\nHoloViewsWidget.prototype.init_slider = function(init_val){\n if(this.load_json) {\n this.from_json()\n } else {\n this.update_cache();\n }\n}\n\nHoloViewsWidget.prototype.populate_cache = function(idx){\n this.cache[idx].innerHTML = this.frames[idx];\n if (this.embed) {\n delete this.frames[idx];\n }\n}\n\nHoloViewsWidget.prototype.process_error = function(msg){\n}\n\nHoloViewsWidget.prototype.from_json = function() {\n var data_url = this.json_path + this.id + '.json';\n $.getJSON(data_url, $.proxy(function(json_data) {\n this.frames = json_data;\n this.update_cache();\n this.update(0);\n }, this));\n}\n\nHoloViewsWidget.prototype.dynamic_update = function(current){\n if (current === undefined) {\n return\n }\n this.current = current;\n if (this.comm) {\n var msg = {comm_id: this.id+'_client', content: current}\n this.comm.send(msg);\n }\n}\n\nHoloViewsWidget.prototype.update_cache = function(force){\n var frame_len = Object.keys(this.frames).length;\n for (var i=0; i 0) {\n that.time = Date.now();\n that.dynamic_update(that.queue[that.queue.length-1]);\n that.queue = [];\n } else {\n that.wait = false;\n }\n if ((msg.msg_type == \"Ready\") && msg.content) {\n console.log(\"Python callback returned following output:\", msg.content);\n } else if (msg.msg_type == \"Error\") {\n console.log(\"Python failed with the following traceback:\", msg.traceback)\n }\n }\n var comm = HoloViews.comm_manager.get_client_comm(this.plot_id, this.id+'_client', ack_callback);\n return comm\n }\n}\n\nHoloViewsWidget.prototype.msg_handler = function(msg) {\n var metadata = msg.metadata;\n if ((metadata.msg_type == \"Ready\")) {\n if (metadata.content) {\n console.log(\"Python callback returned following output:\", metadata.content);\n }\n\treturn;\n } else if (metadata.msg_type == \"Error\") {\n console.log(\"Python failed with the following traceback:\", metadata.traceback)\n return\n }\n this.process_msg(msg)\n}\n\nHoloViewsWidget.prototype.process_msg = function(msg) {\n}\n\nfunction SelectionWidget(frames, id, slider_ids, keyMap, dim_vals, notFound, load_json, mode, cached, json_path, dynamic, plot_id){\n this.frames = frames;\n this.id = id;\n this.plot_id = plot_id;\n this.slider_ids = slider_ids;\n this.keyMap = keyMap\n this.current_frame = 0;\n this.current_vals = dim_vals;\n this.load_json = load_json;\n this.mode = mode;\n this.notFound = notFound;\n this.cached = cached;\n this.dynamic = dynamic;\n this.cache = {};\n this.json_path = json_path;\n this.init_slider(this.current_vals[0]);\n this.queue = [];\n this.wait = false;\n if (!this.cached || this.dynamic) {\n this.comm = this.init_comms();\n }\n}\n\nSelectionWidget.prototype = new HoloViewsWidget;\n\n\nSelectionWidget.prototype.get_key = function(current_vals) {\n var key = \"(\";\n for (var i=0; i Date.now()))) {\n this.queue.push(key);\n return\n }\n this.queue = [];\n this.time = Date.now();\n this.current_frame = key;\n this.wait = true;\n this.dynamic_update(key)\n } else if (key !== undefined) {\n this.update(key)\n }\n}\n\n\n/* Define the ScrubberWidget class */\nfunction ScrubberWidget(frames, num_frames, id, interval, load_json, mode, cached, json_path, dynamic, plot_id){\n this.slider_id = \"_anim_slider\" + id;\n this.loop_select_id = \"_anim_loop_select\" + id;\n this.id = id;\n this.plot_id = plot_id;\n this.interval = interval;\n this.current_frame = 0;\n this.direction = 0;\n this.dynamic = dynamic;\n this.timer = null;\n this.load_json = load_json;\n this.mode = mode;\n this.cached = cached;\n this.frames = frames;\n this.cache = {};\n this.length = num_frames;\n this.json_path = json_path;\n document.getElementById(this.slider_id).max = this.length - 1;\n this.init_slider(0);\n this.wait = false;\n this.queue = [];\n if (!this.cached || this.dynamic) {\n this.comm = this.init_comms()\n }\n}\n\nScrubberWidget.prototype = new HoloViewsWidget;\n\nScrubberWidget.prototype.set_frame = function(frame){\n this.current_frame = frame;\n var widget = document.getElementById(this.slider_id);\n if (widget === null) {\n this.pause_animation();\n return\n }\n widget.value = this.current_frame;\n if (this.dynamic || !this.cached) {\n if ((this.time !== undefined) && ((this.wait) && ((this.time + 10000) > Date.now()))) {\n this.queue.push(frame);\n return\n }\n this.queue = [];\n this.time = Date.now();\n this.wait = true;\n this.dynamic_update(frame)\n } else {\n this.update(frame)\n }\n}\n\nScrubberWidget.prototype.get_loop_state = function(){\n var button_group = document[this.loop_select_id].state;\n for (var i = 0; i < button_group.length; i++) {\n var button = button_group[i];\n if (button.checked) {\n return button.value;\n }\n }\n return undefined;\n}\n\n\nScrubberWidget.prototype.next_frame = function() {\n this.set_frame(Math.min(this.length - 1, this.current_frame + 1));\n}\n\nScrubberWidget.prototype.previous_frame = function() {\n this.set_frame(Math.max(0, this.current_frame - 1));\n}\n\nScrubberWidget.prototype.first_frame = function() {\n this.set_frame(0);\n}\n\nScrubberWidget.prototype.last_frame = function() {\n this.set_frame(this.length - 1);\n}\n\nScrubberWidget.prototype.slower = function() {\n this.interval /= 0.7;\n if(this.direction > 0){this.play_animation();}\n else if(this.direction < 0){this.reverse_animation();}\n}\n\nScrubberWidget.prototype.faster = function() {\n this.interval *= 0.7;\n if(this.direction > 0){this.play_animation();}\n else if(this.direction < 0){this.reverse_animation();}\n}\n\nScrubberWidget.prototype.anim_step_forward = function() {\n if(this.current_frame < this.length - 1){\n this.next_frame();\n }else{\n var loop_state = this.get_loop_state();\n if(loop_state == \"loop\"){\n this.first_frame();\n }else if(loop_state == \"reflect\"){\n this.last_frame();\n this.reverse_animation();\n }else{\n this.pause_animation();\n this.last_frame();\n }\n }\n}\n\nScrubberWidget.prototype.anim_step_reverse = function() {\n if(this.current_frame > 0){\n this.previous_frame();\n } else {\n var loop_state = this.get_loop_state();\n if(loop_state == \"loop\"){\n this.last_frame();\n }else if(loop_state == \"reflect\"){\n this.first_frame();\n this.play_animation();\n }else{\n this.pause_animation();\n this.first_frame();\n }\n }\n}\n\nScrubberWidget.prototype.pause_animation = function() {\n this.direction = 0;\n if (this.timer){\n clearInterval(this.timer);\n this.timer = null;\n }\n}\n\nScrubberWidget.prototype.play_animation = function() {\n this.pause_animation();\n this.direction = 1;\n var t = this;\n if (!this.timer) this.timer = setInterval(function(){t.anim_step_forward();}, this.interval);\n}\n\nScrubberWidget.prototype.reverse_animation = function() {\n this.pause_animation();\n this.direction = -1;\n var t = this;\n if (!this.timer) this.timer = setInterval(function(){t.anim_step_reverse();}, this.interval);\n}\n\nfunction extend(destination, source) {\n for (var k in source) {\n if (source.hasOwnProperty(k)) {\n destination[k] = source[k];\n }\n }\n return destination;\n}\n\nfunction update_widget(widget, values) {\n if (widget.hasClass(\"ui-slider\")) {\n widget.slider('option', {\n min: 0,\n max: values.length-1,\n dim_vals: values,\n value: 0,\n dim_labels: values\n })\n widget.slider('option', 'slide').call(widget, event, {value: 0})\n } else {\n widget.empty();\n for (var i=0; i\", {\n value: i,\n text: values[i]\n }))\n };\n widget.data('values', values);\n widget.data('value', 0);\n widget.trigger(\"change\");\n };\n}\n\nfunction init_slider(id, plot_id, dim, values, next_vals, labels, dynamic, step, value, next_dim,\n dim_idx, delay, jQueryUI_CDN, UNDERSCORE_CDN) {\n // Slider JS Block START\n function loadcssfile(filename){\n var fileref=document.createElement(\"link\")\n fileref.setAttribute(\"rel\", \"stylesheet\")\n fileref.setAttribute(\"type\", \"text/css\")\n fileref.setAttribute(\"href\", filename)\n document.getElementsByTagName(\"head\")[0].appendChild(fileref)\n }\n loadcssfile(\"https://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css\");\n /* Check if jQuery and jQueryUI have been loaded\n otherwise load with require.js */\n var jQuery = window.jQuery,\n // check for old versions of jQuery\n oldjQuery = jQuery && !!jQuery.fn.jquery.match(/^1\\.[0-4](\\.|$)/),\n jquery_path = '',\n paths = {},\n noConflict;\n var jQueryUI = jQuery.ui;\n // check for jQuery\n if (!jQuery || oldjQuery) {\n // load if it's not available or doesn't meet min standards\n paths.jQuery = jQuery;\n noConflict = !!oldjQuery;\n } else {\n // register the current jQuery\n define('jquery', [], function() { return jQuery; });\n }\n if (!jQueryUI) {\n paths.jQueryUI = jQueryUI_CDN.slice(null, -3);\n } else {\n define('jQueryUI', [], function() { return jQuery.ui; });\n }\n paths.underscore = UNDERSCORE_CDN.slice(null, -3);\n var jquery_require = {\n paths: paths,\n shim: {\n \"jQueryUI\": {\n exports:\"$\",\n deps: ['jquery']\n },\n \"underscore\": {\n exports: '_'\n }\n }\n }\n require.config(jquery_require);\n require([\"jQueryUI\", \"underscore\"], function(jUI, _){\n if (noConflict) $.noConflict(true);\n var vals = values;\n if (dynamic && vals.constructor === Array) {\n var default_value = parseFloat(value);\n var min = parseFloat(vals[0]);\n var max = parseFloat(vals[vals.length-1]);\n var wstep = step;\n var wlabels = [default_value];\n var init_label = default_value;\n } else {\n var min = 0;\n if (dynamic) {\n var max = Object.keys(vals).length - 1;\n var init_label = labels[value];\n var default_value = values[value];\n } else {\n var max = vals.length - 1;\n var init_label = labels[value];\n var default_value = value;\n }\n var wstep = 1;\n var wlabels = labels;\n }\n function adjustFontSize(text) {\n var width_ratio = (text.parent().width()/8)/text.val().length;\n var size = Math.min(0.9, Math.max(0.6, width_ratio))+'em';\n text.css('font-size', size);\n }\n var slider = $('#_anim_widget'+id+'_'+dim);\n slider.slider({\n animate: \"fast\",\n min: min,\n max: max,\n step: wstep,\n value: default_value,\n dim_vals: vals,\n dim_labels: wlabels,\n next_vals: next_vals,\n slide: function(event, ui) {\n var vals = slider.slider(\"option\", \"dim_vals\");\n var next_vals = slider.slider(\"option\", \"next_vals\");\n var dlabels = slider.slider(\"option\", \"dim_labels\");\n if (dynamic) {\n var dim_val = ui.value;\n if (vals.constructor === Array) {\n var label = ui.value;\n } else {\n var label = dlabels[ui.value];\n }\n } else {\n var dim_val = vals[ui.value];\n var label = dlabels[ui.value];\n }\n var text = $('#textInput'+id+'_'+dim);\n text.val(label);\n adjustFontSize(text);\n HoloViews.index[plot_id].set_frame(dim_val, dim_idx);\n if (Object.keys(next_vals).length > 0) {\n var new_vals = next_vals[dim_val];\n var next_widget = $('#_anim_widget'+id+'_'+next_dim);\n update_widget(next_widget, new_vals);\n }\n }\n });\n slider.keypress(function(event) {\n if (event.which == 80 || event.which == 112) {\n var start = slider.slider(\"option\", \"value\");\n var stop = slider.slider(\"option\", \"max\");\n for (var i=start; i<=stop; i++) {\n var delay = i*delay;\n $.proxy(function doSetTimeout(i) { setTimeout($.proxy(function() {\n var val = {value:i};\n slider.slider('value',i);\n slider.slider(\"option\", \"slide\")(null, val);\n }, slider), delay);}, slider)(i);\n }\n }\n if (event.which == 82 || event.which == 114) {\n var start = slider.slider(\"option\", \"value\");\n var stop = slider.slider(\"option\", \"min\");\n var count = 0;\n for (var i=start; i>=stop; i--) {\n var delay = count*delay;\n count = count + 1;\n $.proxy(function doSetTimeout(i) { setTimeout($.proxy(function() {\n var val = {value:i};\n slider.slider('value',i);\n slider.slider(\"option\", \"slide\")(null, val);\n }, slider), delay);}, slider)(i);\n }\n }\n });\n var textInput = $('#textInput'+id+'_'+dim)\n textInput.val(init_label);\n adjustFontSize(textInput);\n });\n}\n\nfunction init_dropdown(id, plot_id, dim, vals, value, next_vals, labels, next_dim, dim_idx, dynamic) {\n var widget = $(\"#_anim_widget\"+id+'_'+dim);\n widget.data('values', vals)\n for (var i=0; i\", {\n value: val,\n text: labels[i]\n }));\n };\n widget.data(\"next_vals\", next_vals);\n widget.val(value);\n widget.on('change', function(event, ui) {\n if (dynamic) {\n var dim_val = parseInt(this.value);\n } else {\n var dim_val = $.data(this, 'values')[this.value];\n }\n var next_vals = $.data(this, \"next_vals\");\n if (Object.keys(next_vals).length > 0) {\n var new_vals = next_vals[dim_val];\n var next_widget = $('#_anim_widget'+id+'_'+next_dim);\n update_widget(next_widget, new_vals);\n }\n var widgets = HoloViews.index[plot_id]\n if (widgets) {\n widgets.set_frame(dim_val, dim_idx);\n }\n });\n}\n\n\nif (window.HoloViews === undefined) {\n window.HoloViews = {}\n window.PyViz = window.HoloViews\n} else if (window.PyViz === undefined) {\n window.PyViz = window.HoloViews\n}\n\n\nvar _namespace = {\n init_slider: init_slider,\n init_dropdown: init_dropdown,\n comms: {},\n comm_status: {},\n index: {},\n plot_index: {},\n kernels: {},\n receivers: {}\n}\n\nfor (var k in _namespace) {\n if (!(k in window.HoloViews)) {\n window.HoloViews[k] = _namespace[k];\n }\n}\n\n// Define Bokeh specific subclasses\nfunction BokehSelectionWidget() {\n SelectionWidget.apply(this, arguments);\n}\n\nfunction BokehScrubberWidget() {\n ScrubberWidget.apply(this, arguments);\n}\n\n// Let them inherit from the baseclasses\nBokehSelectionWidget.prototype = Object.create(SelectionWidget.prototype);\nBokehScrubberWidget.prototype = Object.create(ScrubberWidget.prototype);\n\n// Define methods to override on widgets\nvar BokehMethods = {\n update_cache : function(){\n for (var index in this.frames) {\n this.frames[index] = JSON.parse(this.frames[index]);\n }\n },\n update : function(current){\n if (current === undefined) {\n return;\n }\n var data = this.frames[current];\n if (data !== undefined) {\n if (data.root in HoloViews.plot_index) {\n var doc = HoloViews.plot_index[data.root].model.document;\n } else {\n var doc = Bokeh.index[data.root].model.document;\n }\n doc.apply_json_patch(data.content);\n }\n },\n init_comms: function() {\n if (Bokeh.protocol !== undefined) {\n this.receiver = new Bokeh.protocol.Receiver()\n } else {\n this.receiver = null;\n }\n return HoloViewsWidget.prototype.init_comms.call(this);\n },\n process_msg : function(msg) {\n if (this.plot_id in HoloViews.plot_index) {\n var doc = HoloViews.plot_index[this.plot_id].model.document;\n } else {\n var doc = Bokeh.index[this.plot_id].model.document;\n }\n if (this.receiver === null) { return }\n var receiver = this.receiver;\n if (msg.buffers.length > 0) {\n receiver.consume(msg.buffers[0].buffer)\n } else {\n receiver.consume(msg.content.data)\n }\n const comm_msg = receiver.message;\n if ((comm_msg != null) && (doc != null)) {\n doc.apply_json_patch(comm_msg.content, comm_msg.buffers)\n }\n }\n}\n\n// Extend Bokeh widgets with backend specific methods\nextend(BokehSelectionWidget.prototype, BokehMethods);\nextend(BokehScrubberWidget.prototype, BokehMethods);\n\nwindow.HoloViews.BokehSelectionWidget = BokehSelectionWidget\nwindow.HoloViews.BokehScrubberWidget = BokehScrubberWidget\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n }\n\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n" }, "metadata": {}, "output_type": "display_data" @@ -1690,10 +1596,7 @@ "import numpy as np\n", "\n", "import holoviews as hv\n", - "hv.extension(\n", - " 'bokeh',\n", - " 'matplotlib'\n", - ")\n", + "hv.extension('bokeh')\n", "\n", "import GSForge as gsf" ] @@ -1783,12 +1686,7 @@ "text/plain": [ "\n", "Boruta Results\n", - " \n", - " Name: Rice\n", - " Selected GEM Variable: 'counts'\n", - " Gene 55986\n", - " Sample 475\n", - "GeneSet Keys and # of Selected Genes\n", + "GeneSets (3 total): Support Count\n", " Boruta_Treatment: 681\n", " Boruta_Genotype: 661\n", " Boruta_Subspecies: 231" @@ -1860,15 +1758,15 @@ "\n", "\n", "\n", - "
\n", + "
\n", "\n", "
\n", " \n", "" ], @@ -1962,12 +1860,12 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ - "# hv.save(my_plot.options(toolbar=None), # This sometimes does not remove the toolbar.\n", - "# \"osativa_mean_vs_var.png\")" + "hv.save(my_plot.options(toolbar=None), # This sometimes does not remove the toolbar.\n", + " \"datashaded_osativa_mean_vs_var.png\")" ] }, { diff --git a/examples/user_guide/plotting_guide/UMAP_Panels_and_views.ipynb b/examples/user_guide/plotting_guide/UMAP_Panels_and_views.ipynb index 42759e1..a1f78b6 100644 --- a/examples/user_guide/plotting_guide/UMAP_Panels_and_views.ipynb +++ b/examples/user_guide/plotting_guide/UMAP_Panels_and_views.ipynb @@ -558,7 +558,20 @@ "text/html": [ "\n", "\n", - "\n", "\n", "\n", @@ -745,59 +745,6 @@ " \n", "\n", "\n", - " \n", - " \n", "\n", "\n", "\n" @@ -1446,47 +1393,6 @@ "window.HoloViews.BokehSelectionWidget = BokehSelectionWidget\n", "window.HoloViews.BokehScrubberWidget = BokehScrubberWidget\n", "\n", - "// Define MPL specific subclasses\n", - "function MPLSelectionWidget() {\n", - " SelectionWidget.apply(this, arguments);\n", - "}\n", - "\n", - "function MPLScrubberWidget() {\n", - " ScrubberWidget.apply(this, arguments);\n", - "}\n", - "\n", - "// Let them inherit from the baseclasses\n", - "MPLSelectionWidget.prototype = Object.create(SelectionWidget.prototype);\n", - "MPLScrubberWidget.prototype = Object.create(ScrubberWidget.prototype);\n", - "\n", - "// Define methods to override on widgets\n", - "var MPLMethods = {\n", - " init_slider : function(init_val){\n", - " if(this.load_json) {\n", - " this.from_json()\n", - " } else {\n", - " this.update_cache();\n", - " }\n", - " if (this.dynamic | !this.cached | (this.current_vals === undefined)) {\n", - " this.update(0)\n", - " } else {\n", - " this.set_frame(this.current_vals[0], 0)\n", - " }\n", - " },\n", - " process_msg : function(msg) {\n", - " var data = msg.content.data;\n", - " this.frames[this.current] = data;\n", - " this.update_cache(true);\n", - " this.update(this.current);\n", - " }\n", - "}\n", - "// Extend MPL widgets with backend specific methods\n", - "extend(MPLSelectionWidget.prototype, MPLMethods);\n", - "extend(MPLScrubberWidget.prototype, MPLMethods);\n", - "\n", - "window.HoloViews.MPLSelectionWidget = MPLSelectionWidget\n", - "window.HoloViews.MPLScrubberWidget = MPLScrubberWidget\n", - "\n", " function JupyterCommManager() {\n", " }\n", "\n", @@ -1679,7 +1585,7 @@ " }\n", "}\n" ], - "application/vnd.holoviews_load.v0+json": "function HoloViewsWidget() {\n}\n\nHoloViewsWidget.prototype.init_slider = function(init_val){\n if(this.load_json) {\n this.from_json()\n } else {\n this.update_cache();\n }\n}\n\nHoloViewsWidget.prototype.populate_cache = function(idx){\n this.cache[idx].innerHTML = this.frames[idx];\n if (this.embed) {\n delete this.frames[idx];\n }\n}\n\nHoloViewsWidget.prototype.process_error = function(msg){\n}\n\nHoloViewsWidget.prototype.from_json = function() {\n var data_url = this.json_path + this.id + '.json';\n $.getJSON(data_url, $.proxy(function(json_data) {\n this.frames = json_data;\n this.update_cache();\n this.update(0);\n }, this));\n}\n\nHoloViewsWidget.prototype.dynamic_update = function(current){\n if (current === undefined) {\n return\n }\n this.current = current;\n if (this.comm) {\n var msg = {comm_id: this.id+'_client', content: current}\n this.comm.send(msg);\n }\n}\n\nHoloViewsWidget.prototype.update_cache = function(force){\n var frame_len = Object.keys(this.frames).length;\n for (var i=0; i 0) {\n that.time = Date.now();\n that.dynamic_update(that.queue[that.queue.length-1]);\n that.queue = [];\n } else {\n that.wait = false;\n }\n if ((msg.msg_type == \"Ready\") && msg.content) {\n console.log(\"Python callback returned following output:\", msg.content);\n } else if (msg.msg_type == \"Error\") {\n console.log(\"Python failed with the following traceback:\", msg.traceback)\n }\n }\n var comm = HoloViews.comm_manager.get_client_comm(this.plot_id, this.id+'_client', ack_callback);\n return comm\n }\n}\n\nHoloViewsWidget.prototype.msg_handler = function(msg) {\n var metadata = msg.metadata;\n if ((metadata.msg_type == \"Ready\")) {\n if (metadata.content) {\n console.log(\"Python callback returned following output:\", metadata.content);\n }\n\treturn;\n } else if (metadata.msg_type == \"Error\") {\n console.log(\"Python failed with the following traceback:\", metadata.traceback)\n return\n }\n this.process_msg(msg)\n}\n\nHoloViewsWidget.prototype.process_msg = function(msg) {\n}\n\nfunction SelectionWidget(frames, id, slider_ids, keyMap, dim_vals, notFound, load_json, mode, cached, json_path, dynamic, plot_id){\n this.frames = frames;\n this.id = id;\n this.plot_id = plot_id;\n this.slider_ids = slider_ids;\n this.keyMap = keyMap\n this.current_frame = 0;\n this.current_vals = dim_vals;\n this.load_json = load_json;\n this.mode = mode;\n this.notFound = notFound;\n this.cached = cached;\n this.dynamic = dynamic;\n this.cache = {};\n this.json_path = json_path;\n this.init_slider(this.current_vals[0]);\n this.queue = [];\n this.wait = false;\n if (!this.cached || this.dynamic) {\n this.comm = this.init_comms();\n }\n}\n\nSelectionWidget.prototype = new HoloViewsWidget;\n\n\nSelectionWidget.prototype.get_key = function(current_vals) {\n var key = \"(\";\n for (var i=0; i Date.now()))) {\n this.queue.push(key);\n return\n }\n this.queue = [];\n this.time = Date.now();\n this.current_frame = key;\n this.wait = true;\n this.dynamic_update(key)\n } else if (key !== undefined) {\n this.update(key)\n }\n}\n\n\n/* Define the ScrubberWidget class */\nfunction ScrubberWidget(frames, num_frames, id, interval, load_json, mode, cached, json_path, dynamic, plot_id){\n this.slider_id = \"_anim_slider\" + id;\n this.loop_select_id = \"_anim_loop_select\" + id;\n this.id = id;\n this.plot_id = plot_id;\n this.interval = interval;\n this.current_frame = 0;\n this.direction = 0;\n this.dynamic = dynamic;\n this.timer = null;\n this.load_json = load_json;\n this.mode = mode;\n this.cached = cached;\n this.frames = frames;\n this.cache = {};\n this.length = num_frames;\n this.json_path = json_path;\n document.getElementById(this.slider_id).max = this.length - 1;\n this.init_slider(0);\n this.wait = false;\n this.queue = [];\n if (!this.cached || this.dynamic) {\n this.comm = this.init_comms()\n }\n}\n\nScrubberWidget.prototype = new HoloViewsWidget;\n\nScrubberWidget.prototype.set_frame = function(frame){\n this.current_frame = frame;\n var widget = document.getElementById(this.slider_id);\n if (widget === null) {\n this.pause_animation();\n return\n }\n widget.value = this.current_frame;\n if (this.dynamic || !this.cached) {\n if ((this.time !== undefined) && ((this.wait) && ((this.time + 10000) > Date.now()))) {\n this.queue.push(frame);\n return\n }\n this.queue = [];\n this.time = Date.now();\n this.wait = true;\n this.dynamic_update(frame)\n } else {\n this.update(frame)\n }\n}\n\nScrubberWidget.prototype.get_loop_state = function(){\n var button_group = document[this.loop_select_id].state;\n for (var i = 0; i < button_group.length; i++) {\n var button = button_group[i];\n if (button.checked) {\n return button.value;\n }\n }\n return undefined;\n}\n\n\nScrubberWidget.prototype.next_frame = function() {\n this.set_frame(Math.min(this.length - 1, this.current_frame + 1));\n}\n\nScrubberWidget.prototype.previous_frame = function() {\n this.set_frame(Math.max(0, this.current_frame - 1));\n}\n\nScrubberWidget.prototype.first_frame = function() {\n this.set_frame(0);\n}\n\nScrubberWidget.prototype.last_frame = function() {\n this.set_frame(this.length - 1);\n}\n\nScrubberWidget.prototype.slower = function() {\n this.interval /= 0.7;\n if(this.direction > 0){this.play_animation();}\n else if(this.direction < 0){this.reverse_animation();}\n}\n\nScrubberWidget.prototype.faster = function() {\n this.interval *= 0.7;\n if(this.direction > 0){this.play_animation();}\n else if(this.direction < 0){this.reverse_animation();}\n}\n\nScrubberWidget.prototype.anim_step_forward = function() {\n if(this.current_frame < this.length - 1){\n this.next_frame();\n }else{\n var loop_state = this.get_loop_state();\n if(loop_state == \"loop\"){\n this.first_frame();\n }else if(loop_state == \"reflect\"){\n this.last_frame();\n this.reverse_animation();\n }else{\n this.pause_animation();\n this.last_frame();\n }\n }\n}\n\nScrubberWidget.prototype.anim_step_reverse = function() {\n if(this.current_frame > 0){\n this.previous_frame();\n } else {\n var loop_state = this.get_loop_state();\n if(loop_state == \"loop\"){\n this.last_frame();\n }else if(loop_state == \"reflect\"){\n this.first_frame();\n this.play_animation();\n }else{\n this.pause_animation();\n this.first_frame();\n }\n }\n}\n\nScrubberWidget.prototype.pause_animation = function() {\n this.direction = 0;\n if (this.timer){\n clearInterval(this.timer);\n this.timer = null;\n }\n}\n\nScrubberWidget.prototype.play_animation = function() {\n this.pause_animation();\n this.direction = 1;\n var t = this;\n if (!this.timer) this.timer = setInterval(function(){t.anim_step_forward();}, this.interval);\n}\n\nScrubberWidget.prototype.reverse_animation = function() {\n this.pause_animation();\n this.direction = -1;\n var t = this;\n if (!this.timer) this.timer = setInterval(function(){t.anim_step_reverse();}, this.interval);\n}\n\nfunction extend(destination, source) {\n for (var k in source) {\n if (source.hasOwnProperty(k)) {\n destination[k] = source[k];\n }\n }\n return destination;\n}\n\nfunction update_widget(widget, values) {\n if (widget.hasClass(\"ui-slider\")) {\n widget.slider('option', {\n min: 0,\n max: values.length-1,\n dim_vals: values,\n value: 0,\n dim_labels: values\n })\n widget.slider('option', 'slide').call(widget, event, {value: 0})\n } else {\n widget.empty();\n for (var i=0; i\", {\n value: i,\n text: values[i]\n }))\n };\n widget.data('values', values);\n widget.data('value', 0);\n widget.trigger(\"change\");\n };\n}\n\nfunction init_slider(id, plot_id, dim, values, next_vals, labels, dynamic, step, value, next_dim,\n dim_idx, delay, jQueryUI_CDN, UNDERSCORE_CDN) {\n // Slider JS Block START\n function loadcssfile(filename){\n var fileref=document.createElement(\"link\")\n fileref.setAttribute(\"rel\", \"stylesheet\")\n fileref.setAttribute(\"type\", \"text/css\")\n fileref.setAttribute(\"href\", filename)\n document.getElementsByTagName(\"head\")[0].appendChild(fileref)\n }\n loadcssfile(\"https://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css\");\n /* Check if jQuery and jQueryUI have been loaded\n otherwise load with require.js */\n var jQuery = window.jQuery,\n // check for old versions of jQuery\n oldjQuery = jQuery && !!jQuery.fn.jquery.match(/^1\\.[0-4](\\.|$)/),\n jquery_path = '',\n paths = {},\n noConflict;\n var jQueryUI = jQuery.ui;\n // check for jQuery\n if (!jQuery || oldjQuery) {\n // load if it's not available or doesn't meet min standards\n paths.jQuery = jQuery;\n noConflict = !!oldjQuery;\n } else {\n // register the current jQuery\n define('jquery', [], function() { return jQuery; });\n }\n if (!jQueryUI) {\n paths.jQueryUI = jQueryUI_CDN.slice(null, -3);\n } else {\n define('jQueryUI', [], function() { return jQuery.ui; });\n }\n paths.underscore = UNDERSCORE_CDN.slice(null, -3);\n var jquery_require = {\n paths: paths,\n shim: {\n \"jQueryUI\": {\n exports:\"$\",\n deps: ['jquery']\n },\n \"underscore\": {\n exports: '_'\n }\n }\n }\n require.config(jquery_require);\n require([\"jQueryUI\", \"underscore\"], function(jUI, _){\n if (noConflict) $.noConflict(true);\n var vals = values;\n if (dynamic && vals.constructor === Array) {\n var default_value = parseFloat(value);\n var min = parseFloat(vals[0]);\n var max = parseFloat(vals[vals.length-1]);\n var wstep = step;\n var wlabels = [default_value];\n var init_label = default_value;\n } else {\n var min = 0;\n if (dynamic) {\n var max = Object.keys(vals).length - 1;\n var init_label = labels[value];\n var default_value = values[value];\n } else {\n var max = vals.length - 1;\n var init_label = labels[value];\n var default_value = value;\n }\n var wstep = 1;\n var wlabels = labels;\n }\n function adjustFontSize(text) {\n var width_ratio = (text.parent().width()/8)/text.val().length;\n var size = Math.min(0.9, Math.max(0.6, width_ratio))+'em';\n text.css('font-size', size);\n }\n var slider = $('#_anim_widget'+id+'_'+dim);\n slider.slider({\n animate: \"fast\",\n min: min,\n max: max,\n step: wstep,\n value: default_value,\n dim_vals: vals,\n dim_labels: wlabels,\n next_vals: next_vals,\n slide: function(event, ui) {\n var vals = slider.slider(\"option\", \"dim_vals\");\n var next_vals = slider.slider(\"option\", \"next_vals\");\n var dlabels = slider.slider(\"option\", \"dim_labels\");\n if (dynamic) {\n var dim_val = ui.value;\n if (vals.constructor === Array) {\n var label = ui.value;\n } else {\n var label = dlabels[ui.value];\n }\n } else {\n var dim_val = vals[ui.value];\n var label = dlabels[ui.value];\n }\n var text = $('#textInput'+id+'_'+dim);\n text.val(label);\n adjustFontSize(text);\n HoloViews.index[plot_id].set_frame(dim_val, dim_idx);\n if (Object.keys(next_vals).length > 0) {\n var new_vals = next_vals[dim_val];\n var next_widget = $('#_anim_widget'+id+'_'+next_dim);\n update_widget(next_widget, new_vals);\n }\n }\n });\n slider.keypress(function(event) {\n if (event.which == 80 || event.which == 112) {\n var start = slider.slider(\"option\", \"value\");\n var stop = slider.slider(\"option\", \"max\");\n for (var i=start; i<=stop; i++) {\n var delay = i*delay;\n $.proxy(function doSetTimeout(i) { setTimeout($.proxy(function() {\n var val = {value:i};\n slider.slider('value',i);\n slider.slider(\"option\", \"slide\")(null, val);\n }, slider), delay);}, slider)(i);\n }\n }\n if (event.which == 82 || event.which == 114) {\n var start = slider.slider(\"option\", \"value\");\n var stop = slider.slider(\"option\", \"min\");\n var count = 0;\n for (var i=start; i>=stop; i--) {\n var delay = count*delay;\n count = count + 1;\n $.proxy(function doSetTimeout(i) { setTimeout($.proxy(function() {\n var val = {value:i};\n slider.slider('value',i);\n slider.slider(\"option\", \"slide\")(null, val);\n }, slider), delay);}, slider)(i);\n }\n }\n });\n var textInput = $('#textInput'+id+'_'+dim)\n textInput.val(init_label);\n adjustFontSize(textInput);\n });\n}\n\nfunction init_dropdown(id, plot_id, dim, vals, value, next_vals, labels, next_dim, dim_idx, dynamic) {\n var widget = $(\"#_anim_widget\"+id+'_'+dim);\n widget.data('values', vals)\n for (var i=0; i\", {\n value: val,\n text: labels[i]\n }));\n };\n widget.data(\"next_vals\", next_vals);\n widget.val(value);\n widget.on('change', function(event, ui) {\n if (dynamic) {\n var dim_val = parseInt(this.value);\n } else {\n var dim_val = $.data(this, 'values')[this.value];\n }\n var next_vals = $.data(this, \"next_vals\");\n if (Object.keys(next_vals).length > 0) {\n var new_vals = next_vals[dim_val];\n var next_widget = $('#_anim_widget'+id+'_'+next_dim);\n update_widget(next_widget, new_vals);\n }\n var widgets = HoloViews.index[plot_id]\n if (widgets) {\n widgets.set_frame(dim_val, dim_idx);\n }\n });\n}\n\n\nif (window.HoloViews === undefined) {\n window.HoloViews = {}\n window.PyViz = window.HoloViews\n} else if (window.PyViz === undefined) {\n window.PyViz = window.HoloViews\n}\n\n\nvar _namespace = {\n init_slider: init_slider,\n init_dropdown: init_dropdown,\n comms: {},\n comm_status: {},\n index: {},\n plot_index: {},\n kernels: {},\n receivers: {}\n}\n\nfor (var k in _namespace) {\n if (!(k in window.HoloViews)) {\n window.HoloViews[k] = _namespace[k];\n }\n}\n\n// Define Bokeh specific subclasses\nfunction BokehSelectionWidget() {\n SelectionWidget.apply(this, arguments);\n}\n\nfunction BokehScrubberWidget() {\n ScrubberWidget.apply(this, arguments);\n}\n\n// Let them inherit from the baseclasses\nBokehSelectionWidget.prototype = Object.create(SelectionWidget.prototype);\nBokehScrubberWidget.prototype = Object.create(ScrubberWidget.prototype);\n\n// Define methods to override on widgets\nvar BokehMethods = {\n update_cache : function(){\n for (var index in this.frames) {\n this.frames[index] = JSON.parse(this.frames[index]);\n }\n },\n update : function(current){\n if (current === undefined) {\n return;\n }\n var data = this.frames[current];\n if (data !== undefined) {\n if (data.root in HoloViews.plot_index) {\n var doc = HoloViews.plot_index[data.root].model.document;\n } else {\n var doc = Bokeh.index[data.root].model.document;\n }\n doc.apply_json_patch(data.content);\n }\n },\n init_comms: function() {\n if (Bokeh.protocol !== undefined) {\n this.receiver = new Bokeh.protocol.Receiver()\n } else {\n this.receiver = null;\n }\n return HoloViewsWidget.prototype.init_comms.call(this);\n },\n process_msg : function(msg) {\n if (this.plot_id in HoloViews.plot_index) {\n var doc = HoloViews.plot_index[this.plot_id].model.document;\n } else {\n var doc = Bokeh.index[this.plot_id].model.document;\n }\n if (this.receiver === null) { return }\n var receiver = this.receiver;\n if (msg.buffers.length > 0) {\n receiver.consume(msg.buffers[0].buffer)\n } else {\n receiver.consume(msg.content.data)\n }\n const comm_msg = receiver.message;\n if ((comm_msg != null) && (doc != null)) {\n doc.apply_json_patch(comm_msg.content, comm_msg.buffers)\n }\n }\n}\n\n// Extend Bokeh widgets with backend specific methods\nextend(BokehSelectionWidget.prototype, BokehMethods);\nextend(BokehScrubberWidget.prototype, BokehMethods);\n\nwindow.HoloViews.BokehSelectionWidget = BokehSelectionWidget\nwindow.HoloViews.BokehScrubberWidget = BokehScrubberWidget\n\n// Define MPL specific subclasses\nfunction MPLSelectionWidget() {\n SelectionWidget.apply(this, arguments);\n}\n\nfunction MPLScrubberWidget() {\n ScrubberWidget.apply(this, arguments);\n}\n\n// Let them inherit from the baseclasses\nMPLSelectionWidget.prototype = Object.create(SelectionWidget.prototype);\nMPLScrubberWidget.prototype = Object.create(ScrubberWidget.prototype);\n\n// Define methods to override on widgets\nvar MPLMethods = {\n init_slider : function(init_val){\n if(this.load_json) {\n this.from_json()\n } else {\n this.update_cache();\n }\n if (this.dynamic | !this.cached | (this.current_vals === undefined)) {\n this.update(0)\n } else {\n this.set_frame(this.current_vals[0], 0)\n }\n },\n process_msg : function(msg) {\n var data = msg.content.data;\n this.frames[this.current] = data;\n this.update_cache(true);\n this.update(this.current);\n }\n}\n// Extend MPL widgets with backend specific methods\nextend(MPLSelectionWidget.prototype, MPLMethods);\nextend(MPLScrubberWidget.prototype, MPLMethods);\n\nwindow.HoloViews.MPLSelectionWidget = MPLSelectionWidget\nwindow.HoloViews.MPLScrubberWidget = MPLScrubberWidget\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n }\n\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n" + "application/vnd.holoviews_load.v0+json": "function HoloViewsWidget() {\n}\n\nHoloViewsWidget.prototype.init_slider = function(init_val){\n if(this.load_json) {\n this.from_json()\n } else {\n this.update_cache();\n }\n}\n\nHoloViewsWidget.prototype.populate_cache = function(idx){\n this.cache[idx].innerHTML = this.frames[idx];\n if (this.embed) {\n delete this.frames[idx];\n }\n}\n\nHoloViewsWidget.prototype.process_error = function(msg){\n}\n\nHoloViewsWidget.prototype.from_json = function() {\n var data_url = this.json_path + this.id + '.json';\n $.getJSON(data_url, $.proxy(function(json_data) {\n this.frames = json_data;\n this.update_cache();\n this.update(0);\n }, this));\n}\n\nHoloViewsWidget.prototype.dynamic_update = function(current){\n if (current === undefined) {\n return\n }\n this.current = current;\n if (this.comm) {\n var msg = {comm_id: this.id+'_client', content: current}\n this.comm.send(msg);\n }\n}\n\nHoloViewsWidget.prototype.update_cache = function(force){\n var frame_len = Object.keys(this.frames).length;\n for (var i=0; i 0) {\n that.time = Date.now();\n that.dynamic_update(that.queue[that.queue.length-1]);\n that.queue = [];\n } else {\n that.wait = false;\n }\n if ((msg.msg_type == \"Ready\") && msg.content) {\n console.log(\"Python callback returned following output:\", msg.content);\n } else if (msg.msg_type == \"Error\") {\n console.log(\"Python failed with the following traceback:\", msg.traceback)\n }\n }\n var comm = HoloViews.comm_manager.get_client_comm(this.plot_id, this.id+'_client', ack_callback);\n return comm\n }\n}\n\nHoloViewsWidget.prototype.msg_handler = function(msg) {\n var metadata = msg.metadata;\n if ((metadata.msg_type == \"Ready\")) {\n if (metadata.content) {\n console.log(\"Python callback returned following output:\", metadata.content);\n }\n\treturn;\n } else if (metadata.msg_type == \"Error\") {\n console.log(\"Python failed with the following traceback:\", metadata.traceback)\n return\n }\n this.process_msg(msg)\n}\n\nHoloViewsWidget.prototype.process_msg = function(msg) {\n}\n\nfunction SelectionWidget(frames, id, slider_ids, keyMap, dim_vals, notFound, load_json, mode, cached, json_path, dynamic, plot_id){\n this.frames = frames;\n this.id = id;\n this.plot_id = plot_id;\n this.slider_ids = slider_ids;\n this.keyMap = keyMap\n this.current_frame = 0;\n this.current_vals = dim_vals;\n this.load_json = load_json;\n this.mode = mode;\n this.notFound = notFound;\n this.cached = cached;\n this.dynamic = dynamic;\n this.cache = {};\n this.json_path = json_path;\n this.init_slider(this.current_vals[0]);\n this.queue = [];\n this.wait = false;\n if (!this.cached || this.dynamic) {\n this.comm = this.init_comms();\n }\n}\n\nSelectionWidget.prototype = new HoloViewsWidget;\n\n\nSelectionWidget.prototype.get_key = function(current_vals) {\n var key = \"(\";\n for (var i=0; i Date.now()))) {\n this.queue.push(key);\n return\n }\n this.queue = [];\n this.time = Date.now();\n this.current_frame = key;\n this.wait = true;\n this.dynamic_update(key)\n } else if (key !== undefined) {\n this.update(key)\n }\n}\n\n\n/* Define the ScrubberWidget class */\nfunction ScrubberWidget(frames, num_frames, id, interval, load_json, mode, cached, json_path, dynamic, plot_id){\n this.slider_id = \"_anim_slider\" + id;\n this.loop_select_id = \"_anim_loop_select\" + id;\n this.id = id;\n this.plot_id = plot_id;\n this.interval = interval;\n this.current_frame = 0;\n this.direction = 0;\n this.dynamic = dynamic;\n this.timer = null;\n this.load_json = load_json;\n this.mode = mode;\n this.cached = cached;\n this.frames = frames;\n this.cache = {};\n this.length = num_frames;\n this.json_path = json_path;\n document.getElementById(this.slider_id).max = this.length - 1;\n this.init_slider(0);\n this.wait = false;\n this.queue = [];\n if (!this.cached || this.dynamic) {\n this.comm = this.init_comms()\n }\n}\n\nScrubberWidget.prototype = new HoloViewsWidget;\n\nScrubberWidget.prototype.set_frame = function(frame){\n this.current_frame = frame;\n var widget = document.getElementById(this.slider_id);\n if (widget === null) {\n this.pause_animation();\n return\n }\n widget.value = this.current_frame;\n if (this.dynamic || !this.cached) {\n if ((this.time !== undefined) && ((this.wait) && ((this.time + 10000) > Date.now()))) {\n this.queue.push(frame);\n return\n }\n this.queue = [];\n this.time = Date.now();\n this.wait = true;\n this.dynamic_update(frame)\n } else {\n this.update(frame)\n }\n}\n\nScrubberWidget.prototype.get_loop_state = function(){\n var button_group = document[this.loop_select_id].state;\n for (var i = 0; i < button_group.length; i++) {\n var button = button_group[i];\n if (button.checked) {\n return button.value;\n }\n }\n return undefined;\n}\n\n\nScrubberWidget.prototype.next_frame = function() {\n this.set_frame(Math.min(this.length - 1, this.current_frame + 1));\n}\n\nScrubberWidget.prototype.previous_frame = function() {\n this.set_frame(Math.max(0, this.current_frame - 1));\n}\n\nScrubberWidget.prototype.first_frame = function() {\n this.set_frame(0);\n}\n\nScrubberWidget.prototype.last_frame = function() {\n this.set_frame(this.length - 1);\n}\n\nScrubberWidget.prototype.slower = function() {\n this.interval /= 0.7;\n if(this.direction > 0){this.play_animation();}\n else if(this.direction < 0){this.reverse_animation();}\n}\n\nScrubberWidget.prototype.faster = function() {\n this.interval *= 0.7;\n if(this.direction > 0){this.play_animation();}\n else if(this.direction < 0){this.reverse_animation();}\n}\n\nScrubberWidget.prototype.anim_step_forward = function() {\n if(this.current_frame < this.length - 1){\n this.next_frame();\n }else{\n var loop_state = this.get_loop_state();\n if(loop_state == \"loop\"){\n this.first_frame();\n }else if(loop_state == \"reflect\"){\n this.last_frame();\n this.reverse_animation();\n }else{\n this.pause_animation();\n this.last_frame();\n }\n }\n}\n\nScrubberWidget.prototype.anim_step_reverse = function() {\n if(this.current_frame > 0){\n this.previous_frame();\n } else {\n var loop_state = this.get_loop_state();\n if(loop_state == \"loop\"){\n this.last_frame();\n }else if(loop_state == \"reflect\"){\n this.first_frame();\n this.play_animation();\n }else{\n this.pause_animation();\n this.first_frame();\n }\n }\n}\n\nScrubberWidget.prototype.pause_animation = function() {\n this.direction = 0;\n if (this.timer){\n clearInterval(this.timer);\n this.timer = null;\n }\n}\n\nScrubberWidget.prototype.play_animation = function() {\n this.pause_animation();\n this.direction = 1;\n var t = this;\n if (!this.timer) this.timer = setInterval(function(){t.anim_step_forward();}, this.interval);\n}\n\nScrubberWidget.prototype.reverse_animation = function() {\n this.pause_animation();\n this.direction = -1;\n var t = this;\n if (!this.timer) this.timer = setInterval(function(){t.anim_step_reverse();}, this.interval);\n}\n\nfunction extend(destination, source) {\n for (var k in source) {\n if (source.hasOwnProperty(k)) {\n destination[k] = source[k];\n }\n }\n return destination;\n}\n\nfunction update_widget(widget, values) {\n if (widget.hasClass(\"ui-slider\")) {\n widget.slider('option', {\n min: 0,\n max: values.length-1,\n dim_vals: values,\n value: 0,\n dim_labels: values\n })\n widget.slider('option', 'slide').call(widget, event, {value: 0})\n } else {\n widget.empty();\n for (var i=0; i\", {\n value: i,\n text: values[i]\n }))\n };\n widget.data('values', values);\n widget.data('value', 0);\n widget.trigger(\"change\");\n };\n}\n\nfunction init_slider(id, plot_id, dim, values, next_vals, labels, dynamic, step, value, next_dim,\n dim_idx, delay, jQueryUI_CDN, UNDERSCORE_CDN) {\n // Slider JS Block START\n function loadcssfile(filename){\n var fileref=document.createElement(\"link\")\n fileref.setAttribute(\"rel\", \"stylesheet\")\n fileref.setAttribute(\"type\", \"text/css\")\n fileref.setAttribute(\"href\", filename)\n document.getElementsByTagName(\"head\")[0].appendChild(fileref)\n }\n loadcssfile(\"https://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css\");\n /* Check if jQuery and jQueryUI have been loaded\n otherwise load with require.js */\n var jQuery = window.jQuery,\n // check for old versions of jQuery\n oldjQuery = jQuery && !!jQuery.fn.jquery.match(/^1\\.[0-4](\\.|$)/),\n jquery_path = '',\n paths = {},\n noConflict;\n var jQueryUI = jQuery.ui;\n // check for jQuery\n if (!jQuery || oldjQuery) {\n // load if it's not available or doesn't meet min standards\n paths.jQuery = jQuery;\n noConflict = !!oldjQuery;\n } else {\n // register the current jQuery\n define('jquery', [], function() { return jQuery; });\n }\n if (!jQueryUI) {\n paths.jQueryUI = jQueryUI_CDN.slice(null, -3);\n } else {\n define('jQueryUI', [], function() { return jQuery.ui; });\n }\n paths.underscore = UNDERSCORE_CDN.slice(null, -3);\n var jquery_require = {\n paths: paths,\n shim: {\n \"jQueryUI\": {\n exports:\"$\",\n deps: ['jquery']\n },\n \"underscore\": {\n exports: '_'\n }\n }\n }\n require.config(jquery_require);\n require([\"jQueryUI\", \"underscore\"], function(jUI, _){\n if (noConflict) $.noConflict(true);\n var vals = values;\n if (dynamic && vals.constructor === Array) {\n var default_value = parseFloat(value);\n var min = parseFloat(vals[0]);\n var max = parseFloat(vals[vals.length-1]);\n var wstep = step;\n var wlabels = [default_value];\n var init_label = default_value;\n } else {\n var min = 0;\n if (dynamic) {\n var max = Object.keys(vals).length - 1;\n var init_label = labels[value];\n var default_value = values[value];\n } else {\n var max = vals.length - 1;\n var init_label = labels[value];\n var default_value = value;\n }\n var wstep = 1;\n var wlabels = labels;\n }\n function adjustFontSize(text) {\n var width_ratio = (text.parent().width()/8)/text.val().length;\n var size = Math.min(0.9, Math.max(0.6, width_ratio))+'em';\n text.css('font-size', size);\n }\n var slider = $('#_anim_widget'+id+'_'+dim);\n slider.slider({\n animate: \"fast\",\n min: min,\n max: max,\n step: wstep,\n value: default_value,\n dim_vals: vals,\n dim_labels: wlabels,\n next_vals: next_vals,\n slide: function(event, ui) {\n var vals = slider.slider(\"option\", \"dim_vals\");\n var next_vals = slider.slider(\"option\", \"next_vals\");\n var dlabels = slider.slider(\"option\", \"dim_labels\");\n if (dynamic) {\n var dim_val = ui.value;\n if (vals.constructor === Array) {\n var label = ui.value;\n } else {\n var label = dlabels[ui.value];\n }\n } else {\n var dim_val = vals[ui.value];\n var label = dlabels[ui.value];\n }\n var text = $('#textInput'+id+'_'+dim);\n text.val(label);\n adjustFontSize(text);\n HoloViews.index[plot_id].set_frame(dim_val, dim_idx);\n if (Object.keys(next_vals).length > 0) {\n var new_vals = next_vals[dim_val];\n var next_widget = $('#_anim_widget'+id+'_'+next_dim);\n update_widget(next_widget, new_vals);\n }\n }\n });\n slider.keypress(function(event) {\n if (event.which == 80 || event.which == 112) {\n var start = slider.slider(\"option\", \"value\");\n var stop = slider.slider(\"option\", \"max\");\n for (var i=start; i<=stop; i++) {\n var delay = i*delay;\n $.proxy(function doSetTimeout(i) { setTimeout($.proxy(function() {\n var val = {value:i};\n slider.slider('value',i);\n slider.slider(\"option\", \"slide\")(null, val);\n }, slider), delay);}, slider)(i);\n }\n }\n if (event.which == 82 || event.which == 114) {\n var start = slider.slider(\"option\", \"value\");\n var stop = slider.slider(\"option\", \"min\");\n var count = 0;\n for (var i=start; i>=stop; i--) {\n var delay = count*delay;\n count = count + 1;\n $.proxy(function doSetTimeout(i) { setTimeout($.proxy(function() {\n var val = {value:i};\n slider.slider('value',i);\n slider.slider(\"option\", \"slide\")(null, val);\n }, slider), delay);}, slider)(i);\n }\n }\n });\n var textInput = $('#textInput'+id+'_'+dim)\n textInput.val(init_label);\n adjustFontSize(textInput);\n });\n}\n\nfunction init_dropdown(id, plot_id, dim, vals, value, next_vals, labels, next_dim, dim_idx, dynamic) {\n var widget = $(\"#_anim_widget\"+id+'_'+dim);\n widget.data('values', vals)\n for (var i=0; i\", {\n value: val,\n text: labels[i]\n }));\n };\n widget.data(\"next_vals\", next_vals);\n widget.val(value);\n widget.on('change', function(event, ui) {\n if (dynamic) {\n var dim_val = parseInt(this.value);\n } else {\n var dim_val = $.data(this, 'values')[this.value];\n }\n var next_vals = $.data(this, \"next_vals\");\n if (Object.keys(next_vals).length > 0) {\n var new_vals = next_vals[dim_val];\n var next_widget = $('#_anim_widget'+id+'_'+next_dim);\n update_widget(next_widget, new_vals);\n }\n var widgets = HoloViews.index[plot_id]\n if (widgets) {\n widgets.set_frame(dim_val, dim_idx);\n }\n });\n}\n\n\nif (window.HoloViews === undefined) {\n window.HoloViews = {}\n window.PyViz = window.HoloViews\n} else if (window.PyViz === undefined) {\n window.PyViz = window.HoloViews\n}\n\n\nvar _namespace = {\n init_slider: init_slider,\n init_dropdown: init_dropdown,\n comms: {},\n comm_status: {},\n index: {},\n plot_index: {},\n kernels: {},\n receivers: {}\n}\n\nfor (var k in _namespace) {\n if (!(k in window.HoloViews)) {\n window.HoloViews[k] = _namespace[k];\n }\n}\n\n// Define Bokeh specific subclasses\nfunction BokehSelectionWidget() {\n SelectionWidget.apply(this, arguments);\n}\n\nfunction BokehScrubberWidget() {\n ScrubberWidget.apply(this, arguments);\n}\n\n// Let them inherit from the baseclasses\nBokehSelectionWidget.prototype = Object.create(SelectionWidget.prototype);\nBokehScrubberWidget.prototype = Object.create(ScrubberWidget.prototype);\n\n// Define methods to override on widgets\nvar BokehMethods = {\n update_cache : function(){\n for (var index in this.frames) {\n this.frames[index] = JSON.parse(this.frames[index]);\n }\n },\n update : function(current){\n if (current === undefined) {\n return;\n }\n var data = this.frames[current];\n if (data !== undefined) {\n if (data.root in HoloViews.plot_index) {\n var doc = HoloViews.plot_index[data.root].model.document;\n } else {\n var doc = Bokeh.index[data.root].model.document;\n }\n doc.apply_json_patch(data.content);\n }\n },\n init_comms: function() {\n if (Bokeh.protocol !== undefined) {\n this.receiver = new Bokeh.protocol.Receiver()\n } else {\n this.receiver = null;\n }\n return HoloViewsWidget.prototype.init_comms.call(this);\n },\n process_msg : function(msg) {\n if (this.plot_id in HoloViews.plot_index) {\n var doc = HoloViews.plot_index[this.plot_id].model.document;\n } else {\n var doc = Bokeh.index[this.plot_id].model.document;\n }\n if (this.receiver === null) { return }\n var receiver = this.receiver;\n if (msg.buffers.length > 0) {\n receiver.consume(msg.buffers[0].buffer)\n } else {\n receiver.consume(msg.content.data)\n }\n const comm_msg = receiver.message;\n if ((comm_msg != null) && (doc != null)) {\n doc.apply_json_patch(comm_msg.content, comm_msg.buffers)\n }\n }\n}\n\n// Extend Bokeh widgets with backend specific methods\nextend(BokehSelectionWidget.prototype, BokehMethods);\nextend(BokehScrubberWidget.prototype, BokehMethods);\n\nwindow.HoloViews.BokehSelectionWidget = BokehSelectionWidget\nwindow.HoloViews.BokehScrubberWidget = BokehScrubberWidget\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n }\n\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n" }, "metadata": {}, "output_type": "display_data" @@ -1690,10 +1596,7 @@ "import numpy as np\n", "\n", "import holoviews as hv\n", - "hv.extension(\n", - " 'bokeh',\n", - " 'matplotlib'\n", - ")\n", + "hv.extension('bokeh')\n", "\n", "import GSForge as gsf" ] @@ -1783,12 +1686,7 @@ "text/plain": [ "\n", "Boruta Results\n", - " \n", - " Name: Rice\n", - " Selected GEM Variable: 'counts'\n", - " Gene 55986\n", - " Sample 475\n", - "GeneSet Keys and # of Selected Genes\n", + "GeneSets (3 total): Support Count\n", " Boruta_Treatment: 681\n", " Boruta_Genotype: 661\n", " Boruta_Subspecies: 231" @@ -1805,22 +1703,31 @@ "gsc" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## View a Panel\n", + "\n", + "Display an interacgive panel." + ] + }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "application/vnd.holoviews_exec.v0+json": "", "text/html": [ - "
\n", + "
\n", "\n", "\n", "\n", "\n", "\n", - "
\n", + "
\n", "
\n", "" + ], + "text/plain": [ + ":Layout\n", + " .Points.I :Points [x,y] (Sample,SampleSRR,Treatment,Time,Tissue,Genotype,Subspecies,quantile)\n", + " .Points.II :Points [x,y] (Sample,SampleSRR,Treatment,Time,Tissue,Genotype,Subspecies,quantile)" ] }, - "execution_count": 7, + "execution_count": 9, "metadata": { "application/vnd.holoviews_exec.v0+json": { - "id": "1175" + "id": "2139" } }, "output_type": "execute_result" } ], "source": [ - "gsf.panels.UMAP_Panel(interface=gsf.Interface(gsc)).panel()" + "umap_panel = gsf.panels.UMAP_Panel(gsc, hue=\"Treatment\", random_state=42)\n", + "plot_1 = umap_panel.hvplot_view()\n", + "\n", + "umap_panel = gsf.panels.UMAP_Panel(gsc, hue=\"Treatment\", random_state=42, interface_opts={\"selected_gene_sets\": [\"Boruta_Treatment\"]})\n", + "plot_2 = umap_panel.hvplot_view()\n", + "\n", + "layout = (plot_1 + plot_2)\n", + "layout" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "hv.save(layout.opts(toolbar=None), \"umap_subsets.png\")" ] }, { @@ -1948,13 +1945,13 @@ "pycharm": { "stem_cell": { "cell_type": "raw", - "source": [], "metadata": { "collapsed": false - } + }, + "source": [] } } }, "nbformat": 4, "nbformat_minor": 4 -} \ No newline at end of file +} diff --git a/examples/user_guide/user_guide.ipynb b/examples/user_guide/user_guide.ipynb new file mode 100644 index 0000000..ff33883 --- /dev/null +++ b/examples/user_guide/user_guide.ipynb @@ -0,0 +1,79 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Welcome to the **GSForge** user guide!\n", + "\n", + "GSForge is a Python software package that assists researchers in the selection of gene sets with potential association\n", + "to an experimental condition or phenotypic trait, which offers new potential hypotheses for gene-trait causality.\n", + "\n", + "### Getting Started\n", + "\n", + "*Links within images do not seem to work within notebook markdown. Click the links below instead.*\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "+ [**AnnotatedGEM from pandas**](AnnotatedGEM_from_pandas.ipynb) \n", + " How to load your count and label .csv or .txt files into an `xarray.Dataset` using `GSForge`, and save them as a single netcdf (.nc) file for future use.\n", + "\n", + "+ [**GEM Normalization**](GEM_Normalization.ipynb) \n", + " How to run and save different normalizations to the same `AnnotatedGEM` object.\n", + "\n", + "\n", + "* [**Selecting Genes with Boruta**](Selecting_Genes_with_Boruta.ipynb) \n", + " How to select genes based on a sample label using random forests via the Boruta algorithm.\n", + "\n", + "\n", + "* [**GeneSet Analysis**](GeneSet_Analysis.ipynb) \n", + " How to run a basic gene (feature) selection using random forests and the Boruta all-relevant feature selection algorithm.\n", + "\n", + "\n", + "* [**Plotting Guide**](plotting_guide/index.rst) \n", + " Plotting examples by plot type.\n", + "\n", + "* [**Workflow Guide**](workflow_guide/index.rst) \n", + " Using nextflow to run many different boruta analyses.\n", + "\n", + "* [**R-Integration Guide**](R_integration_guide/index.rst) \n", + " Integrating results from R packages into GeneSet objects." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python (base)", + "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.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}