Skip to content

Instantly share code, notes, and snippets.

@Btibert3
Last active September 30, 2020 00:29
Show Gist options
  • Save Btibert3/ed7bdc7f8000e0a0dcdd850b79d07d70 to your computer and use it in GitHub Desktop.
Save Btibert3/ed7bdc7f8000e0a0dcdd850b79d07d70 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "Building Diagrams in Python (and in Notebooks!)",
"provenance": [],
"collapsed_sections": []
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "i-1LuCQNZyV3"
},
"source": [
"# Build diagrams in python\n",
"\n",
"\n",
"This notebook highlights what is possible when we are willing to think about our work as coding problems. Below, if you ever need to draw diagrams to model a process, a dataflow, whatever(!), we don't have to leave python!\n",
"\n",
"<br>\n",
"\n",
"---\n",
"\n",
"<br>\n",
"\n",
"\n",
"### Resources\n",
"\n",
"https://diagrams.mingrammer.com/docs/getting-started/installation\n",
"\n",
"Wraps graphviz\n",
"\n",
"https://graphviz.readthedocs.io/en/stable/"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "uBYBBNJQULzt"
},
"source": [
"# Install"
]
},
{
"cell_type": "code",
"metadata": {
"id": "gxUGlQqzZHMw"
},
"source": [
"! pip install diagrams"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "VcmEimZ_Mu2_"
},
"source": [
"# The web service diagram from the docs"
]
},
{
"cell_type": "code",
"metadata": {
"id": "xxaGcV5UZJEO"
},
"source": [
"from diagrams import Diagram\n",
"from diagrams.aws.compute import EC2\n",
"from diagrams.aws.database import RDS\n",
"from diagrams.aws.network import ELB\n",
"\n",
"with Diagram(\"Web Service\", show=False):\n",
" ELB(\"lb\") >> EC2(\"web\") >> RDS(\"userdb\")"
],
"execution_count": 10,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "ZJ7vWqjXZmbp"
},
"source": [
"> The code above creates a png file in our local directory, which can be opened in Colab."
]
},
{
"cell_type": "code",
"metadata": {
"id": "1PYuqUInMD61",
"outputId": "38d4d3c0-23d0-4e99-a9f7-566624d9d3ae",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 617
}
},
"source": [
"from IPython.display import Image\n",
"Image('web_service.png')"
],
"execution_count": 11,
"outputs": [
{
"output_type": "execute_result",
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA6QAAAJYCAIAAAD6+rxcAAAABmJLR0QA/wD/AP+gvaeTAAAgAElEQVR4nOzdd3wc9Z3/8c93tjd1yZYsd1vuDdtgIHQI1RhIgEAKJZUULrlfkgu55JIcJJfckcJdcqQeCQQIoYOB0EzH2MYFGxe5d/VdaXub+f7+2DZtpZVmJVnj9/PxAEs7fXZ39uXx7C7jnBMAAAAAgBkJo70CAAAAAADDBbELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAAADAtxC4AAAAAmBZiFwAAAABMC7ELAAAAAKaF2AUAAAAA00LsAgAAAIBpIXYBAAAAwLQQuwAAAABgWohdAAAA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xC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWsQuAAAApEXsAgAAQFrELgAAAKRF7AIAAEBaxC4AAACkRewCAABAWv8f4JGhdRO23SMAAAAASUVORK5CYII=\n",
"text/plain": [
"<IPython.core.display.Image object>"
]
},
"metadata": {
"tags": []
},
"execution_count": 11
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ZCAHVi8pTBaX"
},
"source": [
"> Why is above important? We can draw all sorts of data flow diagrams, which could be really helpful when you are trying to document how the data flow through your organization's cloud resources, and more importantly, how it comes to you as a data analyst. Simply, if you are building a data analysis pipeline, you can document your flow, in code! \n",
"\n",
"> TLDR: __No need to point+click in a slide deck!__"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "sJUnvQT1MK4C"
},
"source": [
"# graphviz\n",
"\n",
"The above install is, in part, built on top of `graphviz`, which we cna use for modeling processes and much, MUCH, more!\n",
"\n",
"https://www.graphviz.org/\n",
"\n",
"> Let's suggest a basic data analysis workflow, shall we?"
]
},
{
"cell_type": "code",
"metadata": {
"id": "XRJFE912MzeU"
},
"source": [
"from graphviz import Digraph"
],
"execution_count": 12,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "uT8EATcwM8I1"
},
"source": [
"# setup the graph\n",
"g = Digraph('G', filename='basic-data-flow.gv')\n",
"\n",
"# build the diagram\n",
"# help from here: https://nbviewer.jupyter.org/github/xflr6/graphviz/blob/master/examples/notebook.ipynb\n",
"\n",
"g.attr('node', shape=\"circle\")\n",
"g.edge('Imports', 'Settings')\n",
"g.edge('Settings', 'Load Data')\n",
"g.edge('Load Data', 'Data Cleaning')\n",
"g.edge('Data Cleaning', 'EDA')\n",
"g.edge('EDA', 'Model')\n",
"g.edge('Model', 'Evaluate')\n",
"g.edge('Evaluate', 'Data Cleaning')\n",
"\n",
"# create the next node as a diamond\n",
"g.attr('node', shape=\"diamond\")\n",
"g.node('Reporting')\n",
"\n",
"# the nodes now exist, create an edge\n",
"g.edge('Evaluate', 'Reporting')"
],
"execution_count": 13,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "_Q4H3nfrNwQc",
"outputId": "a0d9a2a2-f663-45a1-b9be-712e0a1b0529",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 1000
}
},
"source": [
"# print to a file\n",
"# g.view()\n",
"\n",
"g"
],
"execution_count": 14,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"<graphviz.dot.Digraph at 0x7f2257fec668>"
],
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<!-- Generated by graphviz version 2.40.1 (20161225.0304)\n -->\n<!-- Title: G Pages: 1 -->\n<svg width=\"144pt\" height=\"900pt\"\n viewBox=\"0.00 0.00 144.04 900.45\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 896.4464)\">\n<title>G</title>\n<polygon fill=\"#ffffff\" stroke=\"transparent\" points=\"-4,4 -4,-896.4464 140.0353,-896.4464 140.0353,4 -4,4\"/>\n<!-- Imports -->\n<g id=\"node1\" class=\"node\">\n<title>Imports</title>\n<ellipse fill=\"none\" stroke=\"#000000\" cx=\"68.0176\" cy=\"-852.7999\" rx=\"39.7935\" ry=\"39.7935\"/>\n<text text-anchor=\"middle\" x=\"68.0176\" y=\"-849.0999\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Imports</text>\n</g>\n<!-- Settings -->\n<g id=\"node2\" class=\"node\">\n<title>Settings</title>\n<ellipse fill=\"none\" stroke=\"#000000\" cx=\"68.0176\" cy=\"-736.857\" rx=\"40.0939\" ry=\"40.0939\"/>\n<text text-anchor=\"middle\" x=\"68.0176\" y=\"-733.157\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Settings</text>\n</g>\n<!-- Imports&#45;&gt;Settings -->\n<g id=\"edge1\" class=\"edge\">\n<title>Imports&#45;&gt;Settings</title>\n<path fill=\"none\" stroke=\"#000000\" d=\"M68.0176,-812.8989C68.0176,-804.7027 68.0176,-795.971 68.0176,-787.4551\"/>\n<polygon fill=\"#000000\" stroke=\"#000000\" points=\"71.5177,-787.225 68.0176,-777.2251 64.5177,-787.2251 71.5177,-787.225\"/>\n</g>\n<!-- Load Data -->\n<g id=\"node3\" class=\"node\">\n<title>Load Data</title>\n<ellipse fill=\"none\" stroke=\"#000000\" cx=\"68.0176\" cy=\"-610.515\" rx=\"50.0912\" ry=\"50.0912\"/>\n<text text-anchor=\"middle\" x=\"68.0176\" y=\"-606.815\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Load Data</text>\n</g>\n<!-- Settings&#45;&gt;Load Data -->\n<g id=\"edge2\" class=\"edge\">\n<title>Settings&#45;&gt;Load Data</title>\n<path fill=\"none\" stroke=\"#000000\" d=\"M68.0176,-696.5342C68.0176,-688.3331 68.0176,-679.5383 68.0176,-670.8165\"/>\n<polygon fill=\"#000000\" stroke=\"#000000\" points=\"71.5177,-670.6514 68.0176,-660.6514 64.5177,-670.6515 71.5177,-670.6514\"/>\n</g>\n<!-- Data Cleaning -->\n<g id=\"node4\" class=\"node\">\n<title>Data Cleaning</title>\n<ellipse fill=\"none\" stroke=\"#000000\" cx=\"68.0176\" cy=\"-460.7751\" rx=\"63.8893\" ry=\"63.8893\"/>\n<text text-anchor=\"middle\" x=\"68.0176\" y=\"-457.0751\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Data Cleaning</text>\n</g>\n<!-- Load Data&#45;&gt;Data Cleaning -->\n<g id=\"edge3\" class=\"edge\">\n<title>Load Data&#45;&gt;Data Cleaning</title>\n<path fill=\"none\" stroke=\"#000000\" d=\"M68.0176,-560.2372C68.0176,-551.9932 68.0176,-543.3016 68.0176,-534.6282\"/>\n<polygon fill=\"#000000\" stroke=\"#000000\" points=\"71.5177,-534.4827 68.0176,-524.4827 64.5177,-534.4827 71.5177,-534.4827\"/>\n</g>\n<!-- EDA -->\n<g id=\"node5\" class=\"node\">\n<title>EDA</title>\n<ellipse fill=\"none\" stroke=\"#000000\" cx=\"39.0176\" cy=\"-330.5334\" rx=\"30.5947\" ry=\"30.5947\"/>\n<text text-anchor=\"middle\" x=\"39.0176\" y=\"-326.8334\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">EDA</text>\n</g>\n<!-- Data Cleaning&#45;&gt;EDA -->\n<g id=\"edge4\" class=\"edge\">\n<title>Data Cleaning&#45;&gt;EDA</title>\n<path fill=\"none\" stroke=\"#000000\" d=\"M54.1122,-398.3246C52.0017,-388.8461 49.8744,-379.292 47.9095,-370.4674\"/>\n<polygon fill=\"#000000\" stroke=\"#000000\" points=\"51.278,-369.4917 45.6882,-360.4914 44.4453,-371.0131 51.278,-369.4917\"/>\n</g>\n<!-- Model -->\n<g id=\"node6\" class=\"node\">\n<title>Model</title>\n<ellipse fill=\"none\" stroke=\"#000000\" cx=\"37.0176\" cy=\"-228.8893\" rx=\"35.194\" ry=\"35.194\"/>\n<text text-anchor=\"middle\" x=\"37.0176\" y=\"-225.1893\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Model</text>\n</g>\n<!-- EDA&#45;&gt;Model -->\n<g id=\"edge5\" class=\"edge\">\n<title>EDA&#45;&gt;Model</title>\n<path fill=\"none\" stroke=\"#000000\" d=\"M38.4121,-299.761C38.2552,-291.7852 38.0828,-283.0248 37.9144,-274.4651\"/>\n<polygon fill=\"#000000\" stroke=\"#000000\" points=\"41.4084,-274.119 37.7122,-264.1898 34.4097,-274.2568 41.4084,-274.119\"/>\n</g>\n<!-- Evaluate -->\n<g id=\"node7\" class=\"node\">\n<title>Evaluate</title>\n<ellipse fill=\"none\" stroke=\"#000000\" cx=\"68.0176\" cy=\"-114.8962\" rx=\"42.7926\" ry=\"42.7926\"/>\n<text text-anchor=\"middle\" x=\"68.0176\" y=\"-111.1962\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Evaluate</text>\n</g>\n<!-- Model&#45;&gt;Evaluate -->\n<g id=\"edge6\" class=\"edge\">\n<title>Model&#45;&gt;Evaluate</title>\n<path fill=\"none\" stroke=\"#000000\" d=\"M46.2347,-194.9962C48.672,-186.0338 51.3588,-176.1539 53.9886,-166.4835\"/>\n<polygon fill=\"#000000\" stroke=\"#000000\" points=\"57.4488,-167.0972 56.6957,-156.5291 50.6941,-165.2602 57.4488,-167.0972\"/>\n</g>\n<!-- Evaluate&#45;&gt;Data Cleaning -->\n<g id=\"edge7\" class=\"edge\">\n<title>Evaluate&#45;&gt;Data Cleaning</title>\n<path fill=\"none\" stroke=\"#000000\" d=\"M76.3139,-157.3221C78.2573,-169.0857 80.0439,-181.8937 81.0176,-193.7924 86.3603,-259.0776 81.859,-333.5367 76.7451,-387.2052\"/>\n<polygon fill=\"#000000\" stroke=\"#000000\" points=\"73.2465,-387.0202 75.7511,-397.3148 80.2129,-387.7052 73.2465,-387.0202\"/>\n</g>\n<!-- Reporting -->\n<g id=\"node8\" class=\"node\">\n<title>Reporting</title>\n<polygon fill=\"none\" stroke=\"#000000\" points=\"68.0176,-36 -.0176,-18 68.0176,0 136.0529,-18 68.0176,-36\"/>\n<text text-anchor=\"middle\" x=\"68.0176\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Reporting</text>\n</g>\n<!-- Evaluate&#45;&gt;Reporting -->\n<g id=\"edge8\" class=\"edge\">\n<title>Evaluate&#45;&gt;Reporting</title>\n<path fill=\"none\" stroke=\"#000000\" d=\"M68.0176,-71.8318C68.0176,-63.2141 68.0176,-54.3662 68.0176,-46.3972\"/>\n<polygon fill=\"#000000\" stroke=\"#000000\" points=\"71.5177,-46.1792 68.0176,-36.1792 64.5177,-46.1793 71.5177,-46.1792\"/>\n</g>\n</g>\n</svg>\n"
},
"metadata": {
"tags": []
},
"execution_count": 14
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "5XaOObIuOra1"
},
"source": [
"# how about this left to right orientation?\n",
"g.attr(rankdir=\"LR\")"
],
"execution_count": 15,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "B109YiF6OrYn",
"outputId": "4d4a04fe-b0b9-4dab-b9c2-e7e19f27b596",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 229
}
},
"source": [
"g"
],
"execution_count": 16,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"<graphviz.dot.Digraph at 0x7f2257fec668>"
],
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<!-- Generated by graphviz version 2.40.1 (20161225.0304)\n -->\n<!-- Title: G Pages: 1 -->\n<svg width=\"1000pt\" height=\"141pt\"\n viewBox=\"0.00 0.00 1000.48 140.79\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 136.7912)\">\n<title>G</title>\n<polygon fill=\"#ffffff\" stroke=\"transparent\" points=\"-4,4 -4,-136.7912 996.4816,-136.7912 996.4816,4 -4,4\"/>\n<!-- Imports -->\n<g id=\"node1\" class=\"node\">\n<title>Imports</title>\n<ellipse fill=\"none\" stroke=\"#000000\" cx=\"39.6465\" cy=\"-63.6943\" rx=\"39.7935\" ry=\"39.7935\"/>\n<text text-anchor=\"middle\" x=\"39.6465\" y=\"-59.9943\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Imports</text>\n</g>\n<!-- Settings -->\n<g id=\"node2\" class=\"node\">\n<title>Settings</title>\n<ellipse fill=\"none\" stroke=\"#000000\" cx=\"155.5894\" cy=\"-63.6943\" rx=\"40.0939\" ry=\"40.0939\"/>\n<text text-anchor=\"middle\" x=\"155.5894\" y=\"-59.9943\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Settings</text>\n</g>\n<!-- Imports&#45;&gt;Settings -->\n<g id=\"edge1\" class=\"edge\">\n<title>Imports&#45;&gt;Settings</title>\n<path fill=\"none\" stroke=\"#000000\" d=\"M79.5475,-63.6943C87.7437,-63.6943 96.4753,-63.6943 104.9913,-63.6943\"/>\n<polygon fill=\"#000000\" stroke=\"#000000\" points=\"105.2213,-67.1944 115.2213,-63.6943 105.2213,-60.1944 105.2213,-67.1944\"/>\n</g>\n<!-- Load Data -->\n<g id=\"node3\" class=\"node\">\n<title>Load Data</title>\n<ellipse fill=\"none\" stroke=\"#000000\" cx=\"281.9314\" cy=\"-63.6943\" rx=\"50.0912\" ry=\"50.0912\"/>\n<text text-anchor=\"middle\" x=\"281.9314\" y=\"-59.9943\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Load Data</text>\n</g>\n<!-- Settings&#45;&gt;Load Data -->\n<g id=\"edge2\" class=\"edge\">\n<title>Settings&#45;&gt;Load Data</title>\n<path fill=\"none\" stroke=\"#000000\" d=\"M195.9122,-63.6943C204.1132,-63.6943 212.9081,-63.6943 221.6299,-63.6943\"/>\n<polygon fill=\"#000000\" stroke=\"#000000\" points=\"221.795,-67.1944 231.7949,-63.6943 221.7949,-60.1944 221.795,-67.1944\"/>\n</g>\n<!-- Data Cleaning -->\n<g id=\"node4\" class=\"node\">\n<title>Data Cleaning</title>\n<ellipse fill=\"none\" stroke=\"#000000\" cx=\"431.6713\" cy=\"-63.6943\" rx=\"63.8893\" ry=\"63.8893\"/>\n<text text-anchor=\"middle\" x=\"431.6713\" y=\"-59.9943\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Data Cleaning</text>\n</g>\n<!-- Load Data&#45;&gt;Data Cleaning -->\n<g id=\"edge3\" class=\"edge\">\n<title>Load Data&#45;&gt;Data Cleaning</title>\n<path fill=\"none\" stroke=\"#000000\" d=\"M332.2092,-63.6943C340.4532,-63.6943 349.1448,-63.6943 357.8182,-63.6943\"/>\n<polygon fill=\"#000000\" stroke=\"#000000\" points=\"357.9637,-67.1944 367.9637,-63.6943 357.9636,-60.1944 357.9637,-67.1944\"/>\n</g>\n<!-- EDA -->\n<g id=\"node5\" class=\"node\">\n<title>EDA</title>\n<ellipse fill=\"none\" stroke=\"#000000\" cx=\"561.9129\" cy=\"-95.6943\" rx=\"30.5947\" ry=\"30.5947\"/>\n<text text-anchor=\"middle\" x=\"561.9129\" y=\"-91.9943\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">EDA</text>\n</g>\n<!-- Data Cleaning&#45;&gt;EDA -->\n<g id=\"edge4\" class=\"edge\">\n<title>Data Cleaning&#45;&gt;EDA</title>\n<path fill=\"none\" stroke=\"#000000\" d=\"M493.7406,-78.9446C503.4515,-81.3306 513.2532,-83.7388 522.2792,-85.9565\"/>\n<polygon fill=\"#000000\" stroke=\"#000000\" points=\"521.5478,-89.3808 532.0941,-88.368 523.2181,-82.583 521.5478,-89.3808\"/>\n</g>\n<!-- Model -->\n<g id=\"node6\" class=\"node\">\n<title>Model</title>\n<ellipse fill=\"none\" stroke=\"#000000\" cx=\"663.5571\" cy=\"-97.6943\" rx=\"35.194\" ry=\"35.194\"/>\n<text text-anchor=\"middle\" x=\"663.5571\" y=\"-93.9943\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Model</text>\n</g>\n<!-- EDA&#45;&gt;Model -->\n<g id=\"edge5\" class=\"edge\">\n<title>EDA&#45;&gt;Model</title>\n<path fill=\"none\" stroke=\"#000000\" d=\"M592.6854,-96.2998C600.6611,-96.4568 609.4215,-96.6292 617.9813,-96.7976\"/>\n<polygon fill=\"#000000\" stroke=\"#000000\" points=\"618.1896,-100.3023 628.2565,-96.9998 618.3273,-93.3036 618.1896,-100.3023\"/>\n</g>\n<!-- Evaluate -->\n<g id=\"node7\" class=\"node\">\n<title>Evaluate</title>\n<ellipse fill=\"none\" stroke=\"#000000\" cx=\"777.5502\" cy=\"-65.6943\" rx=\"42.7926\" ry=\"42.7926\"/>\n<text text-anchor=\"middle\" x=\"777.5502\" y=\"-61.9943\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Evaluate</text>\n</g>\n<!-- Model&#45;&gt;Evaluate -->\n<g id=\"edge6\" class=\"edge\">\n<title>Model&#45;&gt;Evaluate</title>\n<path fill=\"none\" stroke=\"#000000\" d=\"M697.4501,-88.1799C706.5069,-85.6375 716.5006,-82.8321 726.2681,-80.0902\"/>\n<polygon fill=\"#000000\" stroke=\"#000000\" points=\"727.2354,-83.454 735.9172,-77.3815 725.3434,-76.7145 727.2354,-83.454\"/>\n</g>\n<!-- Evaluate&#45;&gt;Data Cleaning -->\n<g id=\"edge7\" class=\"edge\">\n<title>Evaluate&#45;&gt;Data Cleaning</title>\n<path fill=\"none\" stroke=\"#000000\" d=\"M735.1011,-58.0357C723.3374,-56.2418 710.5352,-54.5927 698.654,-53.6943 633.3685,-48.7578 558.9095,-52.3053 505.241,-56.4817\"/>\n<polygon fill=\"#000000\" stroke=\"#000000\" points=\"504.8186,-53.0043 495.1315,-57.295 505.38,-59.9818 504.8186,-53.0043\"/>\n</g>\n<!-- Reporting -->\n<g id=\"node8\" class=\"node\">\n<title>Reporting</title>\n<polygon fill=\"none\" stroke=\"#000000\" points=\"924.464,-83.6943 856.4287,-65.6943 924.464,-47.6943 992.4993,-65.6943 924.464,-83.6943\"/>\n<text text-anchor=\"middle\" x=\"924.464\" y=\"-61.9943\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Reporting</text>\n</g>\n<!-- Evaluate&#45;&gt;Reporting -->\n<g id=\"edge8\" class=\"edge\">\n<title>Evaluate&#45;&gt;Reporting</title>\n<path fill=\"none\" stroke=\"#000000\" d=\"M820.8346,-65.6943C828.8648,-65.6943 837.4774,-65.6943 846.1807,-65.6943\"/>\n<polygon fill=\"#000000\" stroke=\"#000000\" points=\"846.4098,-69.1944 856.4098,-65.6943 846.4098,-62.1944 846.4098,-69.1944\"/>\n</g>\n</g>\n</svg>\n"
},
"metadata": {
"tags": []
},
"execution_count": 16
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dfKk3WMgSzCx"
},
"source": [
"----"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "1sF4Vnm-N-ss"
},
"source": [
"# Summary\n",
"\n",
"As noted, there is so much more that we can do, but hopefully you see how this opens up a process for your to, write code, AND, document your workflows!\n",
"\n",
"<br>\n",
"\n",
"---\n",
"\n",
"<br>\n",
"\n",
"# More resources:\n",
"\n",
"<br>\n",
"\n",
"For more on what is possible, see this notebook:\n",
"\n",
"\n",
"https://nbviewer.jupyter.org/github/xflr6/graphviz/blob/master/examples/notebook.ipynb\n",
"\n",
"For ideas, you can refer to the examples: https://graphviz.readthedocs.io/en/stable/examples.html#"
]
},
{
"cell_type": "code",
"metadata": {
"id": "onbMaHCwVDQH"
},
"source": [
""
],
"execution_count": 16,
"outputs": []
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment