{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "54258582",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "from seeq import spy\n",
    "\n",
    "# Set the compatibility option so that you maximize the chance that SPy will remain compatible with your notebook/script\n",
    "spy.options.compatibility = 193"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "605d2987",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Logged in to <strong>http://localhost:34216</strong> as <strong>agent_api_key</strong>.<br>Seeq Server Version: <strong>R66.0.0-SNAPSHOT</strong><br>Seeq SDK Module Version: <strong>66.0.0</strong> @ C:\\git\\crab\\sdk\\pypi\\seeq\\sdk<br>Seeq SPy Module Version: <strong>193.0</strong> @ C:\\git\\crab\\sdk\\pypi\\seeq\\spy</div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Log into Seeq Server if you're not using Seeq Data Lab:\n",
    "spy.login(url='http://localhost:34216', credentials_file='../credentials.key', force=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6cda1bea",
   "metadata": {},
   "source": [
    "# Data Lab Visualizations\n",
    "\n",
    "Seeq Workbench provides many visualizations out-of-the-box, including the Trend view and XY Plot. You may find that a very specific type of visualization is helpful for a particular use case, and that you can produce this visualization using Python and one of the many open-source libraries at your disposal like [Matplotlib](https://matplotlib.org/), [Plotly](plotly.com), and [Seaborn](https://seaborn.pydata.org/).\n",
    "\n",
    "Wouldn't it be nice to push such visualizations into an Organizer Topic so that you can share them with colleagues, and potentially mix them in with Seeq trends, XY plots, or treemaps? You can do it easily using [Workbook Templates](Workbook%20Templates.ipynb) and this article walks you through it. (You may want to read about Workbook Templates first, but it's not strictly necessary.)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "430ad7ab",
   "metadata": {},
   "source": [
    "## Creating a Template\n",
    "\n",
    "First you must create an Organizer Topic template that will describe the form of the destination for the visualization.\n",
    "\n",
    "For the purposes of illustration, we will first push an Organizer Topic to Seeq so that you can see what the template looks like. Then we'll use it to push a visualization."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "655ce016",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Push successful</div><table class=\"tex2jax_ignore\" style=\"color:black;\"><tr><td style=\"background-color: #EEFFEE;\"></td><td style=\"background-color: #EEFFEE; text-align: left;\">ID</td><td style=\"background-color: #EEFFEE; text-align: left;\">Name</td><td style=\"background-color: #EEFFEE; text-align: left;\">Type</td><td style=\"background-color: #EEFFEE; text-align: left;\">Workbook Type</td><td style=\"background-color: #EEFFEE; text-align: left;\">Count</td><td style=\"background-color: #EEFFEE; text-align: left;\">Time</td><td style=\"background-color: #EEFFEE; text-align: left;\">Errors</td><td style=\"background-color: #EEFFEE; text-align: left;\">Result</td><td style=\"background-color: #EEFFEE; text-align: left;\">Pushed Workbook ID</td><td style=\"background-color: #EEFFEE; text-align: left;\">URL</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">0</td><td style=\"text-align: left; vertical-align: top;\">6BAED6F7-3DF3-4238-AB18-7A9ABE284581</td><td style=\"text-align: left; vertical-align: top;\">Data Lab Visualization Example</td><td style=\"text-align: left; vertical-align: top;\">Workbook</td><td style=\"text-align: left; vertical-align: top;\">Topic</td><td style=\"text-align: right; vertical-align: top;\">2</td><td style=\"vertical-align: top;\">00:00:00.30</td><td style=\"text-align: right; vertical-align: top;\">0</td><td style=\"text-align: left; vertical-align: top;\">Success</td><td style=\"text-align: left; vertical-align: top;\">0EF5BE33-425C-E8D0-AF14-D9651E6DC781</td><td style=\"text-align: left; vertical-align: top;\"><a target=\"_blank\" href=\"http://localhost:34216/workbook/0EF5BE33-425C-E8D0-AF14-D9651E6DC781/worksheet/0EF5BE33-42B6-EE20-BB4A-6675F53BE955\">link</a></td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ID</th>\n",
       "      <th>Name</th>\n",
       "      <th>Type</th>\n",
       "      <th>Workbook Type</th>\n",
       "      <th>Count</th>\n",
       "      <th>Time</th>\n",
       "      <th>Errors</th>\n",
       "      <th>Result</th>\n",
       "      <th>Pushed Workbook ID</th>\n",
       "      <th>URL</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>6BAED6F7-3DF3-4238-AB18-7A9ABE284581</td>\n",
       "      <td>Data Lab Visualization Example</td>\n",
       "      <td>Workbook</td>\n",
       "      <td>Topic</td>\n",
       "      <td>2</td>\n",
       "      <td>0:00:00.297736</td>\n",
       "      <td>0</td>\n",
       "      <td>Success</td>\n",
       "      <td>0EF5BE33-425C-E8D0-AF14-D9651E6DC781</td>\n",
       "      <td>http://localhost:34216/workbook/0EF5BE33-425C-...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                     ID                            Name  \\\n",
       "0  6BAED6F7-3DF3-4238-AB18-7A9ABE284581  Data Lab Visualization Example   \n",
       "\n",
       "       Type Workbook Type Count            Time Errors   Result  \\\n",
       "0  Workbook         Topic     2  0:00:00.297736      0  Success   \n",
       "\n",
       "                     Pushed Workbook ID  \\\n",
       "0  0EF5BE33-425C-E8D0-AF14-D9651E6DC781   \n",
       "\n",
       "                                                 URL  \n",
       "0  http://localhost:34216/workbook/0EF5BE33-425C-...  "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Load the workbook templates from the documentation's Support folder\n",
    "workbooks = spy.workbooks.load('./Support Files/Workbook Templates.zip')\n",
    "\n",
    "# Grab just the Data Lab Visualization example\n",
    "data_lab_visualization_workbook = workbooks['Data Lab Visualization Example']\n",
    "\n",
    "# Push it to Seeq\n",
    "spy.workbooks.push(data_lab_visualization_workbook)"
   ]
  },
  {
   "attachments": {
    "ImageAltText.png": {
     "image/png": "[encoded data, 11216 characters]"
    }
   },
   "cell_type": "markdown",
   "id": "dabcb444",
   "metadata": {},
   "source": [
    "If you click on the _link_ under the URL header of the green box above, you'll see an Organizer Topic with a picture of a grumpy cat.\n",
    "\n",
    "Click on the grumpy cat image, and then select the **Change image text alternative** button:\n",
    " \n",
    "![ImageAltText.png](attachment:ImageAltText.png)"
   ]
  },
  {
   "attachments": {
    "GrumpyCatMustache.jpg": {
     "image/jpeg": "[encoded data, 148600 characters]"
    }
   },
   "cell_type": "markdown",
   "id": "07c19adb",
   "metadata": {},
   "source": [
    "When you do, you'll see that the \"text alternative\" for the image is `{{My Visualization 1}}`:\n",
    "\n",
    "![GrumpyCatMustache.jpg](attachment:GrumpyCatMustache.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "db65302f",
   "metadata": {},
   "source": [
    "This \"double curly-brace\" syntax designates this image as a _mustache variable_. It will appear in the template parameters when you load this Topic as a template, as you will see below.\n",
    "\n",
    "This approach allows you to put any number of placeholder images in your Topic and give them each a different mustache variable name. For example, you may wish to create a table and put several placeholder images in various rows of the table, and you can size them and position them within their cell."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "196c90cb",
   "metadata": {},
   "source": [
    "## Use the Template\n",
    "\n",
    "Now that we've seen what the Topic looks like, let's load it as a template and look at the code for the parameters:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "13bd3fa8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Success</div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "workbooks = spy.workbooks.load('./Support Files/Workbook Templates.zip',\n",
    "                               as_template_with_label=f'{spy.user.username} Data Lab Visualization')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "97699196",
   "metadata": {
    "keep_output_in_docs": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "topic.parameters = {\n",
      "    \"[Image] My Visualization 1\": None,\n",
      "    \"[AltText] My Visualization 1\": None\n",
      "}\n"
     ]
    }
   ],
   "source": [
    "data_lab_visualization_template = workbooks['Data Lab Visualization Example']\n",
    "\n",
    "print(data_lab_visualization_template.code)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "87131b62",
   "metadata": {},
   "source": [
    "As you can see, SPy has found the `My Visualization 1` mustache variable, and it has added two parameters to the template as follows:\n",
    "\n",
    "- `\"[Image] My Visualization 1\"` is where you will specify the filename for the image. It can be any image type that is recognized by a browser. The most common are `.jpg` or `.png`.\n",
    "- `\"[AltText] My Visualization 1\"` is where you can (optionally) define what the alternative text for the image will be."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "af408db1",
   "metadata": {},
   "source": [
    "## Create a Visualization\n",
    "\n",
    "Now let's pull some data and create a simple visualization using Matplotlib.\n",
    "\n",
    "Matplotlib is not installed with core SPy. You may need uncomment the cell below to install the 'templates' extras and use Matplotlib."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "653f7624-ce0e-4cb1-889b-e21934da28ef",
   "metadata": {},
   "outputs": [],
   "source": [
    "# pip install seeq-spy[templates]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "edc27034",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Pull successful from <strong>2024-08-15 23:58:38.629314+00:00</strong> to <strong>2024-08-16 16:58:38.630339+00:00</strong></div><table class=\"tex2jax_ignore\" style=\"color:black;\"><tr><td style=\"background-color: #EEFFEE;\"></td><td style=\"background-color: #EEFFEE; text-align: left;\">ID</td><td style=\"background-color: #EEFFEE; text-align: left;\">Type</td><td style=\"background-color: #EEFFEE; text-align: left;\">Name</td><td style=\"background-color: #EEFFEE; text-align: right;\">Time</td><td style=\"background-color: #EEFFEE; text-align: right;\">Count</td><td style=\"background-color: #EEFFEE; text-align: right;\">Pages</td><td style=\"background-color: #EEFFEE; text-align: left;\">Data Processed</td><td style=\"background-color: #EEFFEE; text-align: left;\">Result</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">0</td><td style=\"text-align: left; vertical-align: top;\">0EF58FC2-8348-EC30-874B-C093508CCDF8</td><td style=\"text-align: left; vertical-align: top;\">StoredSignal</td><td style=\"text-align: left; vertical-align: top;\">Area B_Relative Humidity</td><td style=\"vertical-align: top;\">00:00:00.07</td><td style=\"text-align: right; vertical-align: top;\">68</td><td style=\"text-align: right; vertical-align: top;\">1</td><td style=\"text-align: right; vertical-align: top;\">1 KB</td><td style=\"text-align: left; vertical-align: top;\">Success</td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import os\n",
    "import matplotlib.pyplot as plt\n",
    "from datetime import datetime, timedelta\n",
    "\n",
    "# Pull 10 hours of data to populate a histogram\n",
    "pull_df = spy.pull(spy.search({'Datasource Name': 'Example Data', 'Name': 'Area B_Relative Humidity'}),\n",
    "                   start=datetime.now() - timedelta(hours=10))\n",
    "\n",
    "area_b_rh = pull_df['Area B_Relative Humidity']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "f9bc5e2c",
   "metadata": {
    "keep_output_in_docs": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 10160 characters]\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Create a histogram plot\n",
    "fig, ax = plt.subplots()\n",
    "ax.hist(area_b_rh, linewidth=0.5, edgecolor=\"white\")\n",
    "\n",
    "# Save it to disk so we can use it in the template\n",
    "filename = 'my_data_lab_histogram.png'\n",
    "plt.savefig(filename)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "20ebae89",
   "metadata": {},
   "source": [
    "This simple histogram is the visualization we'll push to the Topic via the template."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b6e342cb",
   "metadata": {},
   "source": [
    "## Push to Organizer\n",
    "\n",
    "Now refer to the place we saved it when filling out the template parameters."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "5c236087",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Push successful</div><table class=\"tex2jax_ignore\" style=\"color:black;\"><tr><td style=\"background-color: #EEFFEE;\"></td><td style=\"background-color: #EEFFEE; text-align: left;\">ID</td><td style=\"background-color: #EEFFEE; text-align: left;\">Name</td><td style=\"background-color: #EEFFEE; text-align: left;\">Type</td><td style=\"background-color: #EEFFEE; text-align: left;\">Workbook Type</td><td style=\"background-color: #EEFFEE; text-align: left;\">Count</td><td style=\"background-color: #EEFFEE; text-align: left;\">Time</td><td style=\"background-color: #EEFFEE; text-align: left;\">Errors</td><td style=\"background-color: #EEFFEE; text-align: left;\">Result</td><td style=\"background-color: #EEFFEE; text-align: left;\">Pushed Workbook ID</td><td style=\"background-color: #EEFFEE; text-align: left;\">URL</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">0</td><td style=\"text-align: left; vertical-align: top;\">6BAED6F7-3DF3-4238-AB18-7A9ABE284581 agent_api_key Data Lab Visualization</td><td style=\"text-align: left; vertical-align: top;\">Data Lab Visualization Example</td><td style=\"text-align: left; vertical-align: top;\">Workbook</td><td style=\"text-align: left; vertical-align: top;\">Topic</td><td style=\"text-align: right; vertical-align: top;\">2</td><td style=\"vertical-align: top;\">00:00:00.21</td><td style=\"text-align: right; vertical-align: top;\">0</td><td style=\"text-align: left; vertical-align: top;\">Success</td><td style=\"text-align: left; vertical-align: top;\">0EF5BE33-5334-7130-9864-18884E2BA8D1</td><td style=\"text-align: left; vertical-align: top;\"><a target=\"_blank\" href=\"http://localhost:34216/workbook/0EF5BE33-5334-7130-9864-18884E2BA8D1/worksheet/0EF5BE33-5393-64A0-AC2D-09665DB66BAF\">link</a></td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ID</th>\n",
       "      <th>Name</th>\n",
       "      <th>Type</th>\n",
       "      <th>Workbook Type</th>\n",
       "      <th>Count</th>\n",
       "      <th>Time</th>\n",
       "      <th>Errors</th>\n",
       "      <th>Result</th>\n",
       "      <th>Pushed Workbook ID</th>\n",
       "      <th>URL</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>6BAED6F7-3DF3-4238-AB18-7A9ABE284581 agent_api...</td>\n",
       "      <td>Data Lab Visualization Example</td>\n",
       "      <td>Workbook</td>\n",
       "      <td>Topic</td>\n",
       "      <td>2</td>\n",
       "      <td>0:00:00.213518</td>\n",
       "      <td>0</td>\n",
       "      <td>Success</td>\n",
       "      <td>0EF5BE33-5334-7130-9864-18884E2BA8D1</td>\n",
       "      <td>http://localhost:34216/workbook/0EF5BE33-5334-...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                  ID  \\\n",
       "0  6BAED6F7-3DF3-4238-AB18-7A9ABE284581 agent_api...   \n",
       "\n",
       "                             Name      Type Workbook Type Count  \\\n",
       "0  Data Lab Visualization Example  Workbook         Topic     2   \n",
       "\n",
       "             Time Errors   Result                    Pushed Workbook ID  \\\n",
       "0  0:00:00.213518      0  Success  0EF5BE33-5334-7130-9864-18884E2BA8D1   \n",
       "\n",
       "                                                 URL  \n",
       "0  http://localhost:34216/workbook/0EF5BE33-5334-...  "
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Specify saved file as the parameter value. Note that you must supply a value for the [Image]\n",
    "# placeholder, but the [AltText] is optional -- you can leave it as None and it will just be\n",
    "# blank after pushing.\n",
    "data_lab_visualization_template.parameters = {\n",
    "    \"[Image] My Visualization 1\": filename,\n",
    "    \"[AltText] My Visualization 1\": \"A histogram of the last 10 hours\"\n",
    "}\n",
    "\n",
    "# Push it!\n",
    "spy.workbooks.push(data_lab_visualization_template)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5b6be424",
   "metadata": {},
   "source": [
    "Click on the _link_ underneath the URL header in the green box and you should see the histogram."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "d99d60d0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Clean up the image file we created\n",
    "os.remove(filename)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "da669da5",
   "metadata": {},
   "source": [
    "## Schedule it\n",
    "\n",
    "Chances are you have created a visualization that you want to be updated periodically. If you're using Seeq Data Lab, that's easy, just schedule it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "a3b16904",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Uncomment the next line to run this notebook on a schedule\n",
    "# spy.jobs.schedule('every 1 day')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "9fcfc5e9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Uncomment the next line to cancel the schedule\n",
    "# spy.jobs.unschedule()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.11",
   "language": "python",
   "name": "python311"
  },
  "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.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
