Created
February 20, 2020 15:13
-
-
Save noklam/ac4142501b0582a4c5facfbc246f8ac6 to your computer and use it in GitHub Desktop.
/00_core.ipynb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#default_exp core", | |
"execution_count": 1, | |
"outputs": [] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "# fastdot.core\n\n> Drawing graphs with graphviz." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\nfrom fastcore.all import *\nimport pydot\nfrom matplotlib.colors import rgb2hex, hex2color", | |
"execution_count": 14, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\n_all_ = ['pydot']", | |
"execution_count": 15, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#hide\nfrom nbdev.showdoc import *", | |
"execution_count": 16, | |
"outputs": [] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "## Nodes" | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\ndef Dot(defaults=None, rankdir='LR', directed=True, compound=True, **kwargs):\n \"Create a `pydot.Dot` graph with fastai/fastdot style defaults\"\n return pydot.Dot(rankdir=rankdir, directed=directed, compound=compound, **kwargs)", | |
"execution_count": 17, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\ndef uniq_name(o): return 'n'+(uuid4().hex)\n\ndef quote(x, q='\"'):\n 'Surround `x` with `\"`'\n return f'\"{x}\"'\n\n@patch\ndef _repr_svg_(self:pydot.Dot):\n return self.create_svg().decode('utf-8')", | |
"execution_count": 18, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\ngraph_objects = {}\nobject_names = {}", | |
"execution_count": 19, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\ndef add_mapping(graph_item, obj):\n graph_objects[graph_item.get_name()] = graph_item\n object_names[id(obj)] = graph_item.get_name()\n return graph_item", | |
"execution_count": 20, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\ndef _pydot_create(f, obj, **kwargs):\n for k,v in kwargs.items():\n if callable(v): v = kwargs[k] = v(obj)\n if k not in ('name','graph_name'): kwargs[k] = quote(v)\n return add_mapping(f(**kwargs), obj)", | |
"execution_count": 21, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\nnode_defaults = dict(label=str, tooltip=str, name=uniq_name, shape='box', style='rounded, filled', fillcolor='white')", | |
"execution_count": 22, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\ndef Node(obj, **kwargs):\n \"Create a `pydot.Node` with a unique name\"\n if not isinstance(obj,str) and isinstance(obj, Collection) and len(obj)==2:\n obj,kwargs['tooltip'] = obj\n kwargs = merge(node_defaults, kwargs)\n return _pydot_create(pydot.Node, obj, **kwargs)", | |
"execution_count": 23, | |
"outputs": [] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "`pydot` uses the same name-based approach to identifying graph items as `graphviz`. However we would rather use python objects. Therefore, we patch `pydot` to use unique names." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "g = Dot()\na = Node('a')\ng.add_node(a)\ng ", | |
"execution_count": 31, | |
"outputs": [ | |
{ | |
"data": { | |
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n<!-- Generated by graphviz version 2.38.0 (20140413.2041)\r\n -->\r\n<!-- Title: G Pages: 1 -->\r\n<svg width=\"62pt\" height=\"44pt\"\r\n viewBox=\"0.00 0.00 62.00 44.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 40)\">\r\n<title>G</title>\r\n<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-40 58,-40 58,4 -4,4\"/>\r\n<!-- n0110bb65118749d09015a10b13d08221 -->\r\n<g id=\"node1\" class=\"node\"><title>n0110bb65118749d09015a10b13d08221</title>\r\n<g id=\"a_node1\"><a xlink:title=\"a\">\r\n<path fill=\"white\" stroke=\"black\" d=\"M42,-36C42,-36 12,-36 12,-36 6,-36 0,-30 0,-24 0,-24 0,-12 0,-12 0,-6 6,-0 12,-0 12,-0 42,-0 42,-0 48,-0 54,-6 54,-12 54,-12 54,-24 54,-24 54,-30 48,-36 42,-36\"/>\r\n<text text-anchor=\"middle\" x=\"27\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">a</text>\r\n</a>\r\n</g>\r\n</g>\r\n</g>\r\n</svg>\r\n", | |
"text/plain": "<pydot.Dot at 0x1e500a54608>" | |
}, | |
"execution_count": 31, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "type(g)", | |
"execution_count": 32, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": "pydot.Dot" | |
}, | |
"execution_count": 32, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "If a 2-tuple is passed to `add_node`, then the 2nd element becomes the tooltip. You can also pass any `kwargs` that are accepted by `graphviz`." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "g = Dot()\ng.add_node(Node(['a', \"My tooltip\"], fillcolor='pink'))\ng", | |
"execution_count": 33, | |
"outputs": [ | |
{ | |
"data": { | |
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n<!-- Generated by graphviz version 2.38.0 (20140413.2041)\r\n -->\r\n<!-- Title: G Pages: 1 -->\r\n<svg width=\"62pt\" height=\"44pt\"\r\n viewBox=\"0.00 0.00 62.00 44.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 40)\">\r\n<title>G</title>\r\n<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-40 58,-40 58,4 -4,4\"/>\r\n<!-- n92ae0971082c409fb3641ce0767e990b -->\r\n<g id=\"node1\" class=\"node\"><title>n92ae0971082c409fb3641ce0767e990b</title>\r\n<g id=\"a_node1\"><a xlink:title=\"My tooltip\">\r\n<path fill=\"pink\" stroke=\"black\" d=\"M42,-36C42,-36 12,-36 12,-36 6,-36 0,-30 0,-24 0,-24 0,-12 0,-12 0,-6 6,-0 12,-0 12,-0 42,-0 42,-0 48,-0 54,-6 54,-12 54,-12 54,-24 54,-24 54,-30 48,-36 42,-36\"/>\r\n<text text-anchor=\"middle\" x=\"27\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">a</text>\r\n</a>\r\n</g>\r\n</g>\r\n</g>\r\n</svg>\r\n", | |
"text/plain": "<pydot.Dot at 0x1e500a41fc8>" | |
}, | |
"execution_count": 33, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "Keyword args can also be arbitrary functions, which will called with the node's label." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "g = Dot()\no = 'a'\ng.add_node(Node(o, fillcolor=lambda o:'pink'))\ng", | |
"execution_count": 34, | |
"outputs": [ | |
{ | |
"data": { | |
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n<!-- Generated by graphviz version 2.38.0 (20140413.2041)\r\n -->\r\n<!-- Title: G Pages: 1 -->\r\n<svg width=\"62pt\" height=\"44pt\"\r\n viewBox=\"0.00 0.00 62.00 44.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 40)\">\r\n<title>G</title>\r\n<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-40 58,-40 58,4 -4,4\"/>\r\n<!-- n9430834ba8d5483e81d5d7407b247ffc -->\r\n<g id=\"node1\" class=\"node\"><title>n9430834ba8d5483e81d5d7407b247ffc</title>\r\n<g id=\"a_node1\"><a xlink:title=\"a\">\r\n<path fill=\"pink\" stroke=\"black\" d=\"M42,-36C42,-36 12,-36 12,-36 6,-36 0,-30 0,-24 0,-24 0,-12 0,-12 0,-6 6,-0 12,-0 12,-0 42,-0 42,-0 48,-0 54,-6 54,-12 54,-12 54,-24 54,-24 54,-30 48,-36 42,-36\"/>\r\n<text text-anchor=\"middle\" x=\"27\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">a</text>\r\n</a>\r\n</g>\r\n</g>\r\n</g>\r\n</svg>\r\n", | |
"text/plain": "<pydot.Dot at 0x1e500a5d408>" | |
}, | |
"execution_count": 34, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\ndef object2graph(o):\n \"Get graph item representing `o`\"\n return graph_objects[object_names[id(o)]]", | |
"execution_count": 35, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "object2graph(o).get_fillcolor()", | |
"execution_count": 36, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": "'\"pink\"'" | |
}, | |
"execution_count": 36, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "## Colors" | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "The callable kwargs functionality can be used to map labels to colors in a consistent way.." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\ndef obj2node_color(cm, minalpha, rangealpha, o):\n \"Create a consistent mapping from objects to colors, using colormap `cm`\"\n h = hash(o)\n i = float(h % 256) / 256\n alpha = (h^hash('something')) % rangealpha + minalpha\n return rgb2hex(cm(i)) + f'{alpha:02X}'", | |
"execution_count": 37, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#exports\ngraph_colors1 = partial(obj2node_color, plt.get_cmap('rainbow'), 30, 160)\ngraph_colors2 = partial(obj2node_color, plt.get_cmap('tab20'), 30, 160)", | |
"execution_count": 38, | |
"outputs": [] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "These predefined color mapping functions provide a good range of colors and readable text." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "g = Dot()\ng.add_node(Node('a', fillcolor=graph_colors1))\ng.add_node(Node('b', fillcolor=graph_colors1))\ng", | |
"execution_count": 39, | |
"outputs": [ | |
{ | |
"data": { | |
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n<!-- Generated by graphviz version 2.38.0 (20140413.2041)\r\n -->\r\n<!-- Title: G Pages: 1 -->\r\n<svg width=\"62pt\" height=\"98pt\"\r\n viewBox=\"0.00 0.00 62.00 98.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 94)\">\r\n<title>G</title>\r\n<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-94 58,-94 58,4 -4,4\"/>\r\n<!-- nf59f75a0ad614fad920015930c7e2f9a -->\r\n<g id=\"node1\" class=\"node\"><title>nf59f75a0ad614fad920015930c7e2f9a</title>\r\n<g id=\"a_node1\"><a xlink:title=\"a\">\r\n<path fill=\"#9bfba5\" fill-opacity=\"0.423529\" stroke=\"black\" d=\"M42,-36C42,-36 12,-36 12,-36 6,-36 0,-30 0,-24 0,-24 0,-12 0,-12 0,-6 6,-0 12,-0 12,-0 42,-0 42,-0 48,-0 54,-6 54,-12 54,-12 54,-24 54,-24 54,-30 48,-36 42,-36\"/>\r\n<text text-anchor=\"middle\" x=\"27\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">a</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n5ef1142c5dd04829b8cdc96f989741f7 -->\r\n<g id=\"node2\" class=\"node\"><title>n5ef1142c5dd04829b8cdc96f989741f7</title>\r\n<g id=\"a_node2\"><a xlink:title=\"b\">\r\n<path fill=\"#583efd\" fill-opacity=\"0.458824\" stroke=\"black\" d=\"M42,-90C42,-90 12,-90 12,-90 6,-90 0,-84 0,-78 0,-78 0,-66 0,-66 0,-60 6,-54 12,-54 12,-54 42,-54 42,-54 48,-54 54,-60 54,-66 54,-66 54,-78 54,-78 54,-84 48,-90 42,-90\"/>\r\n<text text-anchor=\"middle\" x=\"27\" y=\"-68.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">b</text>\r\n</a>\r\n</g>\r\n</g>\r\n</g>\r\n</svg>\r\n", | |
"text/plain": "<pydot.Dot at 0x1e500b5c688>" | |
}, | |
"execution_count": 39, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "g = Dot()\ng.add_node(Node('a', fillcolor=graph_colors2))\ng.add_node(Node('b', fillcolor=graph_colors2))\ng", | |
"execution_count": 40, | |
"outputs": [ | |
{ | |
"data": { | |
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n<!-- Generated by graphviz version 2.38.0 (20140413.2041)\r\n -->\r\n<!-- Title: G Pages: 1 -->\r\n<svg width=\"62pt\" height=\"98pt\"\r\n viewBox=\"0.00 0.00 62.00 98.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 94)\">\r\n<title>G</title>\r\n<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-94 58,-94 58,4 -4,4\"/>\r\n<!-- n8a0a892a46294134bd6c233931178a89 -->\r\n<g id=\"node1\" class=\"node\"><title>n8a0a892a46294134bd6c233931178a89</title>\r\n<g id=\"a_node1\"><a xlink:title=\"a\">\r\n<path fill=\"#c49c94\" fill-opacity=\"0.423529\" stroke=\"black\" d=\"M42,-36C42,-36 12,-36 12,-36 6,-36 0,-30 0,-24 0,-24 0,-12 0,-12 0,-6 6,-0 12,-0 12,-0 42,-0 42,-0 48,-0 54,-6 54,-12 54,-12 54,-24 54,-24 54,-30 48,-36 42,-36\"/>\r\n<text text-anchor=\"middle\" x=\"27\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">a</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n879fe15631b740f7b5ccc9c7c01bff10 -->\r\n<g id=\"node2\" class=\"node\"><title>n879fe15631b740f7b5ccc9c7c01bff10</title>\r\n<g id=\"a_node2\"><a xlink:title=\"b\">\r\n<path fill=\"#aec7e8\" fill-opacity=\"0.458824\" stroke=\"black\" d=\"M42,-90C42,-90 12,-90 12,-90 6,-90 0,-84 0,-78 0,-78 0,-66 0,-66 0,-60 6,-54 12,-54 12,-54 42,-54 42,-54 48,-54 54,-60 54,-66 54,-66 54,-78 54,-78 54,-84 48,-90 42,-90\"/>\r\n<text text-anchor=\"middle\" x=\"27\" y=\"-68.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">b</text>\r\n</a>\r\n</g>\r\n</g>\r\n</g>\r\n</svg>\r\n", | |
"text/plain": "<pydot.Dot at 0x1e500b5c0c8>" | |
}, | |
"execution_count": 40, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "We'll use the former color function as our default. You can change it by simply modifying `node_defaults`." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\nnode_defaults['fillcolor'] = graph_colors1", | |
"execution_count": 41, | |
"outputs": [] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "## Clusters and Items" | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\ncluster_defaults = dict(label=str, tooltip=str, graph_name=uniq_name, style='rounded, filled', fillcolor='#55555522')", | |
"execution_count": 42, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\ndef Cluster(obj='', **kwargs):\n \"Create a `pydot.Cluster` with a unique name\"\n kwargs = merge(cluster_defaults, kwargs)\n return _pydot_create(pydot.Cluster, obj, **kwargs)", | |
"execution_count": 43, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "g = Dot()\nsg = Cluster('clus', tooltip='Cluster tooltip')\nsg.add_node(Node(['a', \"My tooltip\"]))\nsg.add_node(Node('b'))\ng.add_subgraph(sg)\ng", | |
"execution_count": 44, | |
"outputs": [ | |
{ | |
"data": { | |
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n<!-- Generated by graphviz version 2.38.0 (20140413.2041)\r\n -->\r\n<!-- Title: G Pages: 1 -->\r\n<svg width=\"94pt\" height=\"153pt\"\r\n viewBox=\"0.00 0.00 94.00 153.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 149)\">\r\n<title>G</title>\r\n<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-149 90,-149 90,4 -4,4\"/>\r\n<g id=\"clust1\" class=\"cluster\"><title>cluster_n89051654684c4bc3aac2c6eb820a16b1</title>\r\n<g id=\"a_clust1\"><a xlink:title=\"Cluster tooltip\">\r\n<path fill=\"#555555\" fill-opacity=\"0.133333\" stroke=\"black\" d=\"M20,-8C20,-8 66,-8 66,-8 72,-8 78,-14 78,-20 78,-20 78,-125 78,-125 78,-131 72,-137 66,-137 66,-137 20,-137 20,-137 14,-137 8,-131 8,-125 8,-125 8,-20 8,-20 8,-14 14,-8 20,-8\"/>\r\n<text text-anchor=\"middle\" x=\"43\" y=\"-121.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">clus</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n120facb5f8c547d2bf34998afcaf39c7 -->\r\n<g id=\"node1\" class=\"node\"><title>n120facb5f8c547d2bf34998afcaf39c7</title>\r\n<g id=\"a_node1\"><a xlink:title=\"My tooltip\">\r\n<path fill=\"#9bfba5\" fill-opacity=\"0.423529\" stroke=\"black\" d=\"M58,-106C58,-106 28,-106 28,-106 22,-106 16,-100 16,-94 16,-94 16,-82 16,-82 16,-76 22,-70 28,-70 28,-70 58,-70 58,-70 64,-70 70,-76 70,-82 70,-82 70,-94 70,-94 70,-100 64,-106 58,-106\"/>\r\n<text text-anchor=\"middle\" x=\"43\" y=\"-84.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">a</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n0d69ff0a74dd48d9b4a148c459e09ef2 -->\r\n<g id=\"node2\" class=\"node\"><title>n0d69ff0a74dd48d9b4a148c459e09ef2</title>\r\n<g id=\"a_node2\"><a xlink:title=\"b\">\r\n<path fill=\"#583efd\" fill-opacity=\"0.458824\" stroke=\"black\" d=\"M58,-52C58,-52 28,-52 28,-52 22,-52 16,-46 16,-40 16,-40 16,-28 16,-28 16,-22 22,-16 28,-16 28,-16 58,-16 58,-16 64,-16 70,-22 70,-28 70,-28 70,-40 70,-40 70,-46 64,-52 58,-52\"/>\r\n<text text-anchor=\"middle\" x=\"43\" y=\"-30.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">b</text>\r\n</a>\r\n</g>\r\n</g>\r\n</g>\r\n</svg>\r\n", | |
"text/plain": "<pydot.Dot at 0x1e500b9b348>" | |
}, | |
"execution_count": 44, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\n@patch\ndef nodes(self:pydot.Graph):\n \"`i`th node in `Graph`\"\n return L(o for o in self.get_nodes() if o.get_label() is not None)", | |
"execution_count": 45, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\n@patch\ndef __getitem__(self:pydot.Graph, i):\n \"`i`th node in `Graph`\"\n return self.nodes()[i]", | |
"execution_count": 46, | |
"outputs": [] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "You can subscript into a `Graph`'s `Node`s by index:" | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "print(sg[0].get_label())", | |
"execution_count": 47, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": "\"a\"\n" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\n@patch\ndef add_item(self:pydot.Graph, item, **kwargs):\n \"Add a `Cluster`, `Node`, or `Edge` to the `Graph`\"\n if not isinstance(item, (pydot.Edge,pydot.Node,pydot.Graph)): item = Node(item, **kwargs)\n f = self.add_node if isinstance(item, pydot.Node ) else \\\n self.add_subgraph if isinstance(item, pydot.Graph) else \\\n self.add_edge if isinstance(item, pydot.Edge ) else None\n f(item)\n return item", | |
"execution_count": 48, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\n@patch\ndef __add__(self:pydot.Graph, item, **kwargs):\n \"Add a `Cluster`, `Node`, or `Edge` to the `Graph`\"\n if not isinstance(item, (pydot.Edge,pydot.Node,pydot.Graph)): item = Node(item, **kwargs)\n f = self.add_node if isinstance(item, pydot.Node ) else \\\n self.add_subgraph if isinstance(item, pydot.Graph) else \\\n self.add_edge if isinstance(item, pydot.Edge ) else None\n f(item)\n return item", | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "There's no good reason to have different methods for adding clusters vs nodes (as `pydot` requires), so we provide a single method." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "a=g+sg", | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "g= Dot()", | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "sg = Cluster('clus')", | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "g", | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "g = Dot()\nsg = Cluster('clus')\ng + sg\nsg + 'a'\ng", | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "g = Dot()\nsg = Cluster('clus')\n# g.add_item(sg)\n# sg.add_item('a')\ng", | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\n@patch\ndef add_items(self:pydot.Graph, *items, **kwargs):\n \"Add `items` the `Graph`\"\n return L(self.add_item(it, **kwargs) for it in items)", | |
"execution_count": 50, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\ndef graph_items(*items, **kwargs):\n \"Add `items` to a new `pydot.Dot`\"\n g = Dot()\n g.add_items(*items, **kwargs)\n return g", | |
"execution_count": 51, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "sg1 = Cluster('clus')\nsg1.add_items('n1', 'n2')\nsg2 = Cluster()\nsg2.add_item('n')\ngraph_items(sg1,sg2)", | |
"execution_count": 52, | |
"outputs": [ | |
{ | |
"data": { | |
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n<!-- Generated by graphviz version 2.38.0 (20140413.2041)\r\n -->\r\n<!-- Title: G Pages: 1 -->\r\n<svg width=\"94pt\" height=\"213pt\"\r\n viewBox=\"0.00 0.00 94.00 213.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 209)\">\r\n<title>G</title>\r\n<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-209 90,-209 90,4 -4,4\"/>\r\n<g id=\"clust1\" class=\"cluster\"><title>cluster_n712bfd598f194928bf41de3b0163b620</title>\r\n<g id=\"a_clust1\"><a xlink:title=\"clus\">\r\n<path fill=\"#555555\" fill-opacity=\"0.133333\" stroke=\"black\" d=\"M20,-8C20,-8 66,-8 66,-8 72,-8 78,-14 78,-20 78,-20 78,-125 78,-125 78,-131 72,-137 66,-137 66,-137 20,-137 20,-137 14,-137 8,-131 8,-125 8,-125 8,-20 8,-20 8,-14 14,-8 20,-8\"/>\r\n<text text-anchor=\"middle\" x=\"43\" y=\"-121.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">clus</text>\r\n</a>\r\n</g>\r\n</g>\r\n<g id=\"clust2\" class=\"cluster\"><title>cluster_n5a5ce4a7af0c4fac89704872c6e6c561</title>\r\n<path fill=\"#555555\" fill-opacity=\"0.133333\" stroke=\"black\" d=\"M20,-145C20,-145 66,-145 66,-145 72,-145 78,-151 78,-157 78,-157 78,-185 78,-185 78,-191 72,-197 66,-197 66,-197 20,-197 20,-197 14,-197 8,-191 8,-185 8,-185 8,-157 8,-157 8,-151 14,-145 20,-145\"/>\r\n</g>\r\n<!-- nc572d9cf687d4863ac58d6f7875bb559 -->\r\n<g id=\"node1\" class=\"node\"><title>nc572d9cf687d4863ac58d6f7875bb559</title>\r\n<g id=\"a_node1\"><a xlink:title=\"n1\">\r\n<path fill=\"#bced8f\" fill-opacity=\"0.231373\" stroke=\"black\" d=\"M58,-106C58,-106 28,-106 28,-106 22,-106 16,-100 16,-94 16,-94 16,-82 16,-82 16,-76 22,-70 28,-70 28,-70 58,-70 58,-70 64,-70 70,-76 70,-82 70,-82 70,-94 70,-94 70,-100 64,-106 58,-106\"/>\r\n<text text-anchor=\"middle\" x=\"43\" y=\"-84.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">n1</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n0e87fd8c3c0b4799baa79ad78794acc0 -->\r\n<g id=\"node2\" class=\"node\"><title>n0e87fd8c3c0b4799baa79ad78794acc0</title>\r\n<g id=\"a_node2\"><a xlink:title=\"n2\">\r\n<path fill=\"#54f6cb\" fill-opacity=\"0.403922\" stroke=\"black\" d=\"M58,-52C58,-52 28,-52 28,-52 22,-52 16,-46 16,-40 16,-40 16,-28 16,-28 16,-22 22,-16 28,-16 28,-16 58,-16 58,-16 64,-16 70,-22 70,-28 70,-28 70,-40 70,-40 70,-46 64,-52 58,-52\"/>\r\n<text text-anchor=\"middle\" x=\"43\" y=\"-30.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">n2</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n28311f03a248488aa7cec3256fd9b1ab -->\r\n<g id=\"node3\" class=\"node\"><title>n28311f03a248488aa7cec3256fd9b1ab</title>\r\n<g id=\"a_node3\"><a xlink:title=\"n\">\r\n<path fill=\"#ff8143\" fill-opacity=\"0.458824\" stroke=\"black\" d=\"M58,-189C58,-189 28,-189 28,-189 22,-189 16,-183 16,-177 16,-177 16,-165 16,-165 16,-159 22,-153 28,-153 28,-153 58,-153 58,-153 64,-153 70,-159 70,-165 70,-165 70,-177 70,-177 70,-183 64,-189 58,-189\"/>\r\n<text text-anchor=\"middle\" x=\"43\" y=\"-167.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">n</text>\r\n</a>\r\n</g>\r\n</g>\r\n</g>\r\n</svg>\r\n", | |
"text/plain": "<pydot.Dot at 0x1e500c313c8>" | |
}, | |
"execution_count": 52, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "## Edges" | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\n@patch\ndef first(self:pydot.Graph):\n \"First node in `Graph`, searching subgraphs recursively as needed\"\n nodes = self.nodes()\n if nodes: return nodes[0]\n for subg in self.get_subgraphs():\n res = subg.first()\n if res: return res", | |
"execution_count": 53, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\n@patch\ndef last(self:pydot.Graph):\n \"Lastt node in `Graph`, searching subgraphs recursively as needed\"\n nodes = self.nodes()\n if nodes: return nodes[-1]\n for subg in reversed(self.get_subgraphs()):\n res = subg.last()\n if res: return res", | |
"execution_count": 54, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\n@patch\ndef with_compass(self:(pydot.Node,pydot.Graph), compass=None):\n r = self.get_name()\n return f'{r}:{compass}' if compass else r", | |
"execution_count": 55, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "# export\n@patch\ndef connect(self:(pydot.Node,pydot.Graph), item, compass1=None, compass2=None, **kwargs):\n \"Connect two nodes or clusters\"\n a,b,ltail,lhead = self,item,'',''\n if isinstance(self,pydot.Graph):\n a = self.last()\n ltail=self.get_name()\n if isinstance(item,pydot.Graph):\n b = item.first()\n lhead=item.get_name()\n a,b = a.with_compass(compass1),b.with_compass(compass2)\n return pydot.Edge(a, b, lhead=lhead, ltail=ltail, **kwargs)", | |
"execution_count": 56, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "sg2 = Cluster('clus2')\nn1 = sg2.add_item('n1', fillcolor='pink')\nn2 = sg2.add_item('n2', fillcolor='lightblue')\nsg2.add_item(n1.connect(n2))\n\nsg1 = Cluster('clus1')\nsg1.add_item(sg2)\n\na,b = Node('a'),Node('b')\nedges = a.connect(b),a.connect(a),sg1.connect(b),sg2[0].connect(a)\ng = Dot()\ng.add_items(sg1, a, b, *edges)\ng", | |
"execution_count": 57, | |
"outputs": [ | |
{ | |
"data": { | |
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n<!-- Generated by graphviz version 2.38.0 (20140413.2041)\r\n -->\r\n<!-- Title: G Pages: 1 -->\r\n<svg width=\"266pt\" height=\"192pt\"\r\n viewBox=\"0.00 0.00 266.00 192.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 188)\">\r\n<title>G</title>\r\n<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-188 262,-188 262,4 -4,4\"/>\r\n<g id=\"clust1\" class=\"cluster\"><title>cluster_n26d0ab988e774275beb960519b20b318</title>\r\n<g id=\"a_clust1\"><a xlink:title=\"clus1\">\r\n<path fill=\"#555555\" fill-opacity=\"0.133333\" stroke=\"black\" d=\"M20,-62C20,-62 172,-62 172,-62 178,-62 184,-68 184,-74 184,-74 184,-164 184,-164 184,-170 178,-176 172,-176 172,-176 20,-176 20,-176 14,-176 8,-170 8,-164 8,-164 8,-74 8,-74 8,-68 14,-62 20,-62\"/>\r\n<text text-anchor=\"middle\" x=\"96\" y=\"-160.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">clus1</text>\r\n</a>\r\n</g>\r\n</g>\r\n<g id=\"clust2\" class=\"cluster\"><title>cluster_nd29353746aad4a099c09e0179bf6bcf6</title>\r\n<g id=\"a_clust2\"><a xlink:title=\"clus2\">\r\n<path fill=\"#555555\" fill-opacity=\"0.133333\" stroke=\"black\" d=\"M28,-70C28,-70 164,-70 164,-70 170,-70 176,-76 176,-82 176,-82 176,-133 176,-133 176,-139 170,-145 164,-145 164,-145 28,-145 28,-145 22,-145 16,-139 16,-133 16,-133 16,-82 16,-82 16,-76 22,-70 28,-70\"/>\r\n<text text-anchor=\"middle\" x=\"96\" y=\"-129.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">clus2</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n35feb868a45f4770a49f7fd2a9d07f7e -->\r\n<g id=\"node1\" class=\"node\"><title>n35feb868a45f4770a49f7fd2a9d07f7e</title>\r\n<g id=\"a_node1\"><a xlink:title=\"n1\">\r\n<path fill=\"pink\" stroke=\"black\" d=\"M66,-114C66,-114 36,-114 36,-114 30,-114 24,-108 24,-102 24,-102 24,-90 24,-90 24,-84 30,-78 36,-78 36,-78 66,-78 66,-78 72,-78 78,-84 78,-90 78,-90 78,-102 78,-102 78,-108 72,-114 66,-114\"/>\r\n<text text-anchor=\"middle\" x=\"51\" y=\"-92.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">n1</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n82f11263d3ea43a383e5fad417d19f79 -->\r\n<g id=\"node2\" class=\"node\"><title>n82f11263d3ea43a383e5fad417d19f79</title>\r\n<g id=\"a_node2\"><a xlink:title=\"n2\">\r\n<path fill=\"lightblue\" stroke=\"black\" d=\"M156,-114C156,-114 126,-114 126,-114 120,-114 114,-108 114,-102 114,-102 114,-90 114,-90 114,-84 120,-78 126,-78 126,-78 156,-78 156,-78 162,-78 168,-84 168,-90 168,-90 168,-102 168,-102 168,-108 162,-114 156,-114\"/>\r\n<text text-anchor=\"middle\" x=\"141\" y=\"-92.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">n2</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n35feb868a45f4770a49f7fd2a9d07f7e->n82f11263d3ea43a383e5fad417d19f79 -->\r\n<g id=\"edge1\" class=\"edge\"><title>n35feb868a45f4770a49f7fd2a9d07f7e->n82f11263d3ea43a383e5fad417d19f79</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M78.4029,-96C86.3932,-96 95.3106,-96 103.824,-96\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"103.919,-99.5001 113.919,-96 103.919,-92.5001 103.919,-99.5001\"/>\r\n</g>\r\n<!-- n19507a3b6bdb4827b0fd1e47252ef48c -->\r\n<g id=\"node3\" class=\"node\"><title>n19507a3b6bdb4827b0fd1e47252ef48c</title>\r\n<g id=\"a_node3\"><a xlink:title=\"a\">\r\n<path fill=\"#9bfba5\" fill-opacity=\"0.423529\" stroke=\"black\" d=\"M156,-36C156,-36 126,-36 126,-36 120,-36 114,-30 114,-24 114,-24 114,-12 114,-12 114,-6 120,-0 126,-0 126,-0 156,-0 156,-0 162,-0 168,-6 168,-12 168,-12 168,-24 168,-24 168,-30 162,-36 156,-36\"/>\r\n<text text-anchor=\"middle\" x=\"141\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">a</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n35feb868a45f4770a49f7fd2a9d07f7e->n19507a3b6bdb4827b0fd1e47252ef48c -->\r\n<g id=\"edge5\" class=\"edge\"><title>n35feb868a45f4770a49f7fd2a9d07f7e->n19507a3b6bdb4827b0fd1e47252ef48c</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M72.4102,-77.9092C84.0992,-67.5484 98.9418,-54.3925 111.739,-43.0498\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"114.234,-45.5152 119.396,-36.2629 109.591,-40.2768 114.234,-45.5152\"/>\r\n</g>\r\n<!-- nef33d08909e64a73b068bb38af4c10a2 -->\r\n<g id=\"node4\" class=\"node\"><title>nef33d08909e64a73b068bb38af4c10a2</title>\r\n<g id=\"a_node4\"><a xlink:title=\"b\">\r\n<path fill=\"#583efd\" fill-opacity=\"0.458824\" stroke=\"black\" d=\"M246,-75C246,-75 216,-75 216,-75 210,-75 204,-69 204,-63 204,-63 204,-51 204,-51 204,-45 210,-39 216,-39 216,-39 246,-39 246,-39 252,-39 258,-45 258,-51 258,-51 258,-63 258,-63 258,-69 252,-75 246,-75\"/>\r\n<text text-anchor=\"middle\" x=\"231\" y=\"-53.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">b</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n82f11263d3ea43a383e5fad417d19f79->nef33d08909e64a73b068bb38af4c10a2 -->\r\n<g id=\"edge4\" class=\"edge\"><title>n82f11263d3ea43a383e5fad417d19f79->nef33d08909e64a73b068bb38af4c10a2</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M183.844,-77.4555C187.464,-75.8511 191.104,-74.2381 194.665,-72.66\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"196.195,-75.8103 203.919,-68.5586 193.358,-69.4106 196.195,-75.8103\"/>\r\n</g>\r\n<!-- n19507a3b6bdb4827b0fd1e47252ef48c->n19507a3b6bdb4827b0fd1e47252ef48c -->\r\n<g id=\"edge3\" class=\"edge\"><title>n19507a3b6bdb4827b0fd1e47252ef48c->n19507a3b6bdb4827b0fd1e47252ef48c</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M124.718,-36.1527C122.213,-45.5391 127.641,-54 141,-54 149.141,-54 154.336,-50.8581 156.586,-46.2796\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"160.088,-46.3691 157.282,-36.1527 153.105,-45.8893 160.088,-46.3691\"/>\r\n</g>\r\n<!-- n19507a3b6bdb4827b0fd1e47252ef48c->nef33d08909e64a73b068bb38af4c10a2 -->\r\n<g id=\"edge2\" class=\"edge\"><title>n19507a3b6bdb4827b0fd1e47252ef48c->nef33d08909e64a73b068bb38af4c10a2</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M168.403,-29.7013C176.657,-33.3592 185.9,-37.4555 194.665,-41.34\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"193.358,-44.5894 203.919,-45.4414 196.195,-38.1897 193.358,-44.5894\"/>\r\n</g>\r\n</g>\r\n</svg>\r\n", | |
"text/plain": "<pydot.Dot at 0x1e500c80b48>" | |
}, | |
"execution_count": 57, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\ndef object_connections(conns):\n \"Create connections between all pairs in `conns`\"\n return [object2graph(a).connect(object2graph(b)) for a,b in conns]", | |
"execution_count": 58, | |
"outputs": [] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "This is a shortcut for creating connections between objects that are already in a graph." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "a,b = 'a','b'\ng = graph_items(a, b)\ng.add_items(*object_connections([(a,b)]))\ng", | |
"execution_count": 59, | |
"outputs": [ | |
{ | |
"data": { | |
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n<!-- Generated by graphviz version 2.38.0 (20140413.2041)\r\n -->\r\n<!-- Title: G Pages: 1 -->\r\n<svg width=\"152pt\" height=\"44pt\"\r\n viewBox=\"0.00 0.00 152.00 44.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 40)\">\r\n<title>G</title>\r\n<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-40 148,-40 148,4 -4,4\"/>\r\n<!-- nccfd3310b4714831bafcba388a239870 -->\r\n<g id=\"node1\" class=\"node\"><title>nccfd3310b4714831bafcba388a239870</title>\r\n<g id=\"a_node1\"><a xlink:title=\"a\">\r\n<path fill=\"#9bfba5\" fill-opacity=\"0.423529\" stroke=\"black\" d=\"M42,-36C42,-36 12,-36 12,-36 6,-36 0,-30 0,-24 0,-24 0,-12 0,-12 0,-6 6,-0 12,-0 12,-0 42,-0 42,-0 48,-0 54,-6 54,-12 54,-12 54,-24 54,-24 54,-30 48,-36 42,-36\"/>\r\n<text text-anchor=\"middle\" x=\"27\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">a</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n934b4caaca0b49f3b14a5f9639651169 -->\r\n<g id=\"node2\" class=\"node\"><title>n934b4caaca0b49f3b14a5f9639651169</title>\r\n<g id=\"a_node2\"><a xlink:title=\"b\">\r\n<path fill=\"#583efd\" fill-opacity=\"0.458824\" stroke=\"black\" d=\"M132,-36C132,-36 102,-36 102,-36 96,-36 90,-30 90,-24 90,-24 90,-12 90,-12 90,-6 96,-0 102,-0 102,-0 132,-0 132,-0 138,-0 144,-6 144,-12 144,-12 144,-24 144,-24 144,-30 138,-36 132,-36\"/>\r\n<text text-anchor=\"middle\" x=\"117\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">b</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- nccfd3310b4714831bafcba388a239870->n934b4caaca0b49f3b14a5f9639651169 -->\r\n<g id=\"edge1\" class=\"edge\"><title>nccfd3310b4714831bafcba388a239870->n934b4caaca0b49f3b14a5f9639651169</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M54.4029,-18C62.3932,-18 71.3106,-18 79.8241,-18\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"79.919,-21.5001 89.919,-18 79.919,-14.5001 79.919,-21.5001\"/>\r\n</g>\r\n</g>\r\n</svg>\r\n", | |
"text/plain": "<pydot.Dot at 0x1e500c53748>" | |
}, | |
"execution_count": 59, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "## Sequential" | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "Since it's common to want to connect a series sequentially, we provide some simple shortcuts for this functionality." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\ndef graph_edges_seq(items):\n \"Add edges between each pair of nodes in `items`\"\n return L(items[i].connect(items[i+1]) for i in range(len(items)-1))", | |
"execution_count": 60, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\n@patch\ndef add_edges_seq(self:pydot.Graph, items):\n \"Add edges between each pair of nodes in `items`\"\n return self.add_items(*graph_edges_seq(items))", | |
"execution_count": 61, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "g = Dot()\nits = g.add_items('a','b','c')\ng.add_edges_seq(its)\ng", | |
"execution_count": 62, | |
"outputs": [ | |
{ | |
"data": { | |
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n<!-- Generated by graphviz version 2.38.0 (20140413.2041)\r\n -->\r\n<!-- Title: G Pages: 1 -->\r\n<svg width=\"242pt\" height=\"44pt\"\r\n viewBox=\"0.00 0.00 242.00 44.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 40)\">\r\n<title>G</title>\r\n<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-40 238,-40 238,4 -4,4\"/>\r\n<!-- n1c597863bdeb4e95839997381c978a2a -->\r\n<g id=\"node1\" class=\"node\"><title>n1c597863bdeb4e95839997381c978a2a</title>\r\n<g id=\"a_node1\"><a xlink:title=\"a\">\r\n<path fill=\"#9bfba5\" fill-opacity=\"0.423529\" stroke=\"black\" d=\"M42,-36C42,-36 12,-36 12,-36 6,-36 0,-30 0,-24 0,-24 0,-12 0,-12 0,-6 6,-0 12,-0 12,-0 42,-0 42,-0 48,-0 54,-6 54,-12 54,-12 54,-24 54,-24 54,-30 48,-36 42,-36\"/>\r\n<text text-anchor=\"middle\" x=\"27\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">a</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n1798a3a935f9495cb4de66a087e7e804 -->\r\n<g id=\"node2\" class=\"node\"><title>n1798a3a935f9495cb4de66a087e7e804</title>\r\n<g id=\"a_node2\"><a xlink:title=\"b\">\r\n<path fill=\"#583efd\" fill-opacity=\"0.458824\" stroke=\"black\" d=\"M132,-36C132,-36 102,-36 102,-36 96,-36 90,-30 90,-24 90,-24 90,-12 90,-12 90,-6 96,-0 102,-0 102,-0 132,-0 132,-0 138,-0 144,-6 144,-12 144,-12 144,-24 144,-24 144,-30 138,-36 132,-36\"/>\r\n<text text-anchor=\"middle\" x=\"117\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">b</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n1c597863bdeb4e95839997381c978a2a->n1798a3a935f9495cb4de66a087e7e804 -->\r\n<g id=\"edge1\" class=\"edge\"><title>n1c597863bdeb4e95839997381c978a2a->n1798a3a935f9495cb4de66a087e7e804</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M54.4029,-18C62.3932,-18 71.3106,-18 79.8241,-18\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"79.919,-21.5001 89.919,-18 79.919,-14.5001 79.919,-21.5001\"/>\r\n</g>\r\n<!-- n679b040cb1c24fc8a6e8faac4cfd6815 -->\r\n<g id=\"node3\" class=\"node\"><title>n679b040cb1c24fc8a6e8faac4cfd6815</title>\r\n<g id=\"a_node3\"><a xlink:title=\"c\">\r\n<path fill=\"#ff6232\" fill-opacity=\"0.227451\" stroke=\"black\" d=\"M222,-36C222,-36 192,-36 192,-36 186,-36 180,-30 180,-24 180,-24 180,-12 180,-12 180,-6 186,-0 192,-0 192,-0 222,-0 222,-0 228,-0 234,-6 234,-12 234,-12 234,-24 234,-24 234,-30 228,-36 222,-36\"/>\r\n<text text-anchor=\"middle\" x=\"207\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">c</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n1798a3a935f9495cb4de66a087e7e804->n679b040cb1c24fc8a6e8faac4cfd6815 -->\r\n<g id=\"edge2\" class=\"edge\"><title>n1798a3a935f9495cb4de66a087e7e804->n679b040cb1c24fc8a6e8faac4cfd6815</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M144.403,-18C152.393,-18 161.311,-18 169.824,-18\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"169.919,-21.5001 179.919,-18 169.919,-14.5001 169.919,-21.5001\"/>\r\n</g>\r\n</g>\r\n</svg>\r\n", | |
"text/plain": "<pydot.Dot at 0x1e500c5ab88>" | |
}, | |
"execution_count": 62, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#export\ndef seq_cluster(items, cluster_label='', **kwargs):\n sg = Cluster(cluster_label)\n its = sg.add_items(*items, **kwargs)\n sg.add_edges_seq(its)\n return sg", | |
"execution_count": 63, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "g = Dot()\ng.add_item(seq_cluster(['a','b','c'], 'clust'))\ng.add_item(seq_cluster(['1','2','c'], 'clust2'))\ng", | |
"execution_count": 64, | |
"outputs": [ | |
{ | |
"data": { | |
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n<!-- Generated by graphviz version 2.38.0 (20140413.2041)\r\n -->\r\n<!-- Title: G Pages: 1 -->\r\n<svg width=\"274pt\" height=\"182pt\"\r\n viewBox=\"0.00 0.00 274.00 182.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 178)\">\r\n<title>G</title>\r\n<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-178 270,-178 270,4 -4,4\"/>\r\n<g id=\"clust1\" class=\"cluster\"><title>cluster_n6350c6ea2b7649d18fff3c6d5e5cdc2a</title>\r\n<g id=\"a_clust1\"><a xlink:title=\"clust\">\r\n<path fill=\"#555555\" fill-opacity=\"0.133333\" stroke=\"black\" d=\"M20,-8C20,-8 246,-8 246,-8 252,-8 258,-14 258,-20 258,-20 258,-71 258,-71 258,-77 252,-83 246,-83 246,-83 20,-83 20,-83 14,-83 8,-77 8,-71 8,-71 8,-20 8,-20 8,-14 14,-8 20,-8\"/>\r\n<text text-anchor=\"middle\" x=\"133\" y=\"-67.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">clust</text>\r\n</a>\r\n</g>\r\n</g>\r\n<g id=\"clust2\" class=\"cluster\"><title>cluster_n9b144468eddf4dcca0559b2f915b674e</title>\r\n<g id=\"a_clust2\"><a xlink:title=\"clust2\">\r\n<path fill=\"#555555\" fill-opacity=\"0.133333\" stroke=\"black\" d=\"M20,-91C20,-91 246,-91 246,-91 252,-91 258,-97 258,-103 258,-103 258,-154 258,-154 258,-160 252,-166 246,-166 246,-166 20,-166 20,-166 14,-166 8,-160 8,-154 8,-154 8,-103 8,-103 8,-97 14,-91 20,-91\"/>\r\n<text text-anchor=\"middle\" x=\"133\" y=\"-150.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">clust2</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n1600399bd4c74e4ba320348f157069cd -->\r\n<g id=\"node1\" class=\"node\"><title>n1600399bd4c74e4ba320348f157069cd</title>\r\n<g id=\"a_node1\"><a xlink:title=\"a\">\r\n<path fill=\"#9bfba5\" fill-opacity=\"0.423529\" stroke=\"black\" d=\"M58,-52C58,-52 28,-52 28,-52 22,-52 16,-46 16,-40 16,-40 16,-28 16,-28 16,-22 22,-16 28,-16 28,-16 58,-16 58,-16 64,-16 70,-22 70,-28 70,-28 70,-40 70,-40 70,-46 64,-52 58,-52\"/>\r\n<text text-anchor=\"middle\" x=\"43\" y=\"-30.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">a</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n003714d39c334b8cb4a4d131c25828d5 -->\r\n<g id=\"node2\" class=\"node\"><title>n003714d39c334b8cb4a4d131c25828d5</title>\r\n<g id=\"a_node2\"><a xlink:title=\"b\">\r\n<path fill=\"#583efd\" fill-opacity=\"0.458824\" stroke=\"black\" d=\"M148,-52C148,-52 118,-52 118,-52 112,-52 106,-46 106,-40 106,-40 106,-28 106,-28 106,-22 112,-16 118,-16 118,-16 148,-16 148,-16 154,-16 160,-22 160,-28 160,-28 160,-40 160,-40 160,-46 154,-52 148,-52\"/>\r\n<text text-anchor=\"middle\" x=\"133\" y=\"-30.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">b</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n1600399bd4c74e4ba320348f157069cd->n003714d39c334b8cb4a4d131c25828d5 -->\r\n<g id=\"edge1\" class=\"edge\"><title>n1600399bd4c74e4ba320348f157069cd->n003714d39c334b8cb4a4d131c25828d5</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M70.4029,-34C78.3932,-34 87.3106,-34 95.8241,-34\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"95.919,-37.5001 105.919,-34 95.919,-30.5001 95.919,-37.5001\"/>\r\n</g>\r\n<!-- nf8d52281e6a64945903495847606463d -->\r\n<g id=\"node3\" class=\"node\"><title>nf8d52281e6a64945903495847606463d</title>\r\n<g id=\"a_node3\"><a xlink:title=\"c\">\r\n<path fill=\"#ff6232\" fill-opacity=\"0.227451\" stroke=\"black\" d=\"M238,-52C238,-52 208,-52 208,-52 202,-52 196,-46 196,-40 196,-40 196,-28 196,-28 196,-22 202,-16 208,-16 208,-16 238,-16 238,-16 244,-16 250,-22 250,-28 250,-28 250,-40 250,-40 250,-46 244,-52 238,-52\"/>\r\n<text text-anchor=\"middle\" x=\"223\" y=\"-30.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">c</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n003714d39c334b8cb4a4d131c25828d5->nf8d52281e6a64945903495847606463d -->\r\n<g id=\"edge2\" class=\"edge\"><title>n003714d39c334b8cb4a4d131c25828d5->nf8d52281e6a64945903495847606463d</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M160.403,-34C168.393,-34 177.311,-34 185.824,-34\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"185.919,-37.5001 195.919,-34 185.919,-30.5001 185.919,-37.5001\"/>\r\n</g>\r\n<!-- n02db93d3bf86444e9b4408278f0a51cf -->\r\n<g id=\"node4\" class=\"node\"><title>n02db93d3bf86444e9b4408278f0a51cf</title>\r\n<g id=\"a_node4\"><a xlink:title=\"1\">\r\n<path fill=\"#ff562c\" fill-opacity=\"0.619608\" stroke=\"black\" d=\"M58,-135C58,-135 28,-135 28,-135 22,-135 16,-129 16,-123 16,-123 16,-111 16,-111 16,-105 22,-99 28,-99 28,-99 58,-99 58,-99 64,-99 70,-105 70,-111 70,-111 70,-123 70,-123 70,-129 64,-135 58,-135\"/>\r\n<text text-anchor=\"middle\" x=\"43\" y=\"-113.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">1</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n1ce890132e1d4f5499a72f7c10797f9b -->\r\n<g id=\"node5\" class=\"node\"><title>n1ce890132e1d4f5499a72f7c10797f9b</title>\r\n<g id=\"a_node5\"><a xlink:title=\"2\">\r\n<path fill=\"#3176f8\" fill-opacity=\"0.509804\" stroke=\"black\" d=\"M148,-135C148,-135 118,-135 118,-135 112,-135 106,-129 106,-123 106,-123 106,-111 106,-111 106,-105 112,-99 118,-99 118,-99 148,-99 148,-99 154,-99 160,-105 160,-111 160,-111 160,-123 160,-123 160,-129 154,-135 148,-135\"/>\r\n<text text-anchor=\"middle\" x=\"133\" y=\"-113.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">2</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n02db93d3bf86444e9b4408278f0a51cf->n1ce890132e1d4f5499a72f7c10797f9b -->\r\n<g id=\"edge3\" class=\"edge\"><title>n02db93d3bf86444e9b4408278f0a51cf->n1ce890132e1d4f5499a72f7c10797f9b</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M70.4029,-117C78.3932,-117 87.3106,-117 95.8241,-117\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"95.919,-120.5 105.919,-117 95.919,-113.5 95.919,-120.5\"/>\r\n</g>\r\n<!-- n19d51cac713d4fbda14b1871aa3d1636 -->\r\n<g id=\"node6\" class=\"node\"><title>n19d51cac713d4fbda14b1871aa3d1636</title>\r\n<g id=\"a_node6\"><a xlink:title=\"c\">\r\n<path fill=\"#ff6232\" fill-opacity=\"0.227451\" stroke=\"black\" d=\"M238,-135C238,-135 208,-135 208,-135 202,-135 196,-129 196,-123 196,-123 196,-111 196,-111 196,-105 202,-99 208,-99 208,-99 238,-99 238,-99 244,-99 250,-105 250,-111 250,-111 250,-123 250,-123 250,-129 244,-135 238,-135\"/>\r\n<text text-anchor=\"middle\" x=\"223\" y=\"-113.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">c</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n1ce890132e1d4f5499a72f7c10797f9b->n19d51cac713d4fbda14b1871aa3d1636 -->\r\n<g id=\"edge4\" class=\"edge\"><title>n1ce890132e1d4f5499a72f7c10797f9b->n19d51cac713d4fbda14b1871aa3d1636</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M160.403,-117C168.393,-117 177.311,-117 185.824,-117\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"185.919,-120.5 195.919,-117 185.919,-113.5 185.919,-120.5\"/>\r\n</g>\r\n</g>\r\n</svg>\r\n", | |
"text/plain": "<pydot.Dot at 0x1e500cfd188>" | |
}, | |
"execution_count": 64, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "g = Dot()\ng.add_item(seq_cluster(['a','b','c'], 'clust'))\ng", | |
"execution_count": 65, | |
"outputs": [ | |
{ | |
"data": { | |
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n<!-- Generated by graphviz version 2.38.0 (20140413.2041)\r\n -->\r\n<!-- Title: G Pages: 1 -->\r\n<svg width=\"274pt\" height=\"99pt\"\r\n viewBox=\"0.00 0.00 274.00 99.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 95)\">\r\n<title>G</title>\r\n<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-95 270,-95 270,4 -4,4\"/>\r\n<g id=\"clust1\" class=\"cluster\"><title>cluster_n4ab5953f98f043cd92750e94f02dcc41</title>\r\n<g id=\"a_clust1\"><a xlink:title=\"clust\">\r\n<path fill=\"#555555\" fill-opacity=\"0.133333\" stroke=\"black\" d=\"M20,-8C20,-8 246,-8 246,-8 252,-8 258,-14 258,-20 258,-20 258,-71 258,-71 258,-77 252,-83 246,-83 246,-83 20,-83 20,-83 14,-83 8,-77 8,-71 8,-71 8,-20 8,-20 8,-14 14,-8 20,-8\"/>\r\n<text text-anchor=\"middle\" x=\"133\" y=\"-67.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">clust</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n757e2b243c834ad082efdaef8736ec99 -->\r\n<g id=\"node1\" class=\"node\"><title>n757e2b243c834ad082efdaef8736ec99</title>\r\n<g id=\"a_node1\"><a xlink:title=\"a\">\r\n<path fill=\"#9bfba5\" fill-opacity=\"0.423529\" stroke=\"black\" d=\"M58,-52C58,-52 28,-52 28,-52 22,-52 16,-46 16,-40 16,-40 16,-28 16,-28 16,-22 22,-16 28,-16 28,-16 58,-16 58,-16 64,-16 70,-22 70,-28 70,-28 70,-40 70,-40 70,-46 64,-52 58,-52\"/>\r\n<text text-anchor=\"middle\" x=\"43\" y=\"-30.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">a</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n18fe5b44dddc4410807d19d95c59d3b7 -->\r\n<g id=\"node2\" class=\"node\"><title>n18fe5b44dddc4410807d19d95c59d3b7</title>\r\n<g id=\"a_node2\"><a xlink:title=\"b\">\r\n<path fill=\"#583efd\" fill-opacity=\"0.458824\" stroke=\"black\" d=\"M148,-52C148,-52 118,-52 118,-52 112,-52 106,-46 106,-40 106,-40 106,-28 106,-28 106,-22 112,-16 118,-16 118,-16 148,-16 148,-16 154,-16 160,-22 160,-28 160,-28 160,-40 160,-40 160,-46 154,-52 148,-52\"/>\r\n<text text-anchor=\"middle\" x=\"133\" y=\"-30.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">b</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n757e2b243c834ad082efdaef8736ec99->n18fe5b44dddc4410807d19d95c59d3b7 -->\r\n<g id=\"edge1\" class=\"edge\"><title>n757e2b243c834ad082efdaef8736ec99->n18fe5b44dddc4410807d19d95c59d3b7</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M70.4029,-34C78.3932,-34 87.3106,-34 95.8241,-34\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"95.919,-37.5001 105.919,-34 95.919,-30.5001 95.919,-37.5001\"/>\r\n</g>\r\n<!-- n16e7fe2d761d4e8ea2bc51a62d46fe39 -->\r\n<g id=\"node3\" class=\"node\"><title>n16e7fe2d761d4e8ea2bc51a62d46fe39</title>\r\n<g id=\"a_node3\"><a xlink:title=\"c\">\r\n<path fill=\"#ff6232\" fill-opacity=\"0.227451\" stroke=\"black\" d=\"M238,-52C238,-52 208,-52 208,-52 202,-52 196,-46 196,-40 196,-40 196,-28 196,-28 196,-22 202,-16 208,-16 208,-16 238,-16 238,-16 244,-16 250,-22 250,-28 250,-28 250,-40 250,-40 250,-46 244,-52 238,-52\"/>\r\n<text text-anchor=\"middle\" x=\"223\" y=\"-30.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">c</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n18fe5b44dddc4410807d19d95c59d3b7->n16e7fe2d761d4e8ea2bc51a62d46fe39 -->\r\n<g id=\"edge2\" class=\"edge\"><title>n18fe5b44dddc4410807d19d95c59d3b7->n16e7fe2d761d4e8ea2bc51a62d46fe39</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M160.403,-34C168.393,-34 177.311,-34 185.824,-34\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"185.919,-37.5001 195.919,-34 185.919,-30.5001 185.919,-37.5001\"/>\r\n</g>\r\n</g>\r\n</svg>\r\n", | |
"text/plain": "<pydot.Dot at 0x1e500c98608>" | |
}, | |
"execution_count": 65, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "sg1 = seq_cluster(['a','b','c'], 'clust1')\nsg2 = seq_cluster(['a1','a2',sg1], 'clust2')\ng = Dot()\ng.add_item(sg2)\ng", | |
"execution_count": 66, | |
"outputs": [ | |
{ | |
"data": { | |
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n<!-- Generated by graphviz version 2.38.0 (20140413.2041)\r\n -->\r\n<!-- Title: G Pages: 1 -->\r\n<svg width=\"462pt\" height=\"138pt\"\r\n viewBox=\"0.00 0.00 462.00 138.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 134)\">\r\n<title>G</title>\r\n<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-134 458,-134 458,4 -4,4\"/>\r\n<g id=\"clust1\" class=\"cluster\"><title>cluster_n86db42b225474bfba1a333a9859edba3</title>\r\n<g id=\"a_clust1\"><a xlink:title=\"clust2\">\r\n<path fill=\"#555555\" fill-opacity=\"0.133333\" stroke=\"black\" d=\"M20,-8C20,-8 434,-8 434,-8 440,-8 446,-14 446,-20 446,-20 446,-110 446,-110 446,-116 440,-122 434,-122 434,-122 20,-122 20,-122 14,-122 8,-116 8,-110 8,-110 8,-20 8,-20 8,-14 14,-8 20,-8\"/>\r\n<text text-anchor=\"middle\" x=\"227\" y=\"-106.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">clust2</text>\r\n</a>\r\n</g>\r\n</g>\r\n<g id=\"clust2\" class=\"cluster\"><title>cluster_n88a2531a72694320987f5312fb1bc4a1</title>\r\n<g id=\"a_clust2\"><a xlink:title=\"clust1\">\r\n<path fill=\"#555555\" fill-opacity=\"0.133333\" stroke=\"black\" d=\"M200,-16C200,-16 426,-16 426,-16 432,-16 438,-22 438,-28 438,-28 438,-79 438,-79 438,-85 432,-91 426,-91 426,-91 200,-91 200,-91 194,-91 188,-85 188,-79 188,-79 188,-28 188,-28 188,-22 194,-16 200,-16\"/>\r\n<text text-anchor=\"middle\" x=\"313\" y=\"-75.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">clust1</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n933863f287a94cfe95990a1697ae6d87 -->\r\n<g id=\"node1\" class=\"node\"><title>n933863f287a94cfe95990a1697ae6d87</title>\r\n<g id=\"a_node1\"><a xlink:title=\"a1\">\r\n<path fill=\"#cee184\" fill-opacity=\"0.384314\" stroke=\"black\" d=\"M58,-60C58,-60 28,-60 28,-60 22,-60 16,-54 16,-48 16,-48 16,-36 16,-36 16,-30 22,-24 28,-24 28,-24 58,-24 58,-24 64,-24 70,-30 70,-36 70,-36 70,-48 70,-48 70,-54 64,-60 58,-60\"/>\r\n<text text-anchor=\"middle\" x=\"43\" y=\"-38.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">a1</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n7c23dc98b71846a2a2dab760ab83129f -->\r\n<g id=\"node2\" class=\"node\"><title>n7c23dc98b71846a2a2dab760ab83129f</title>\r\n<g id=\"a_node2\"><a xlink:title=\"a2\">\r\n<path fill=\"#0ca7ef\" fill-opacity=\"0.592157\" stroke=\"black\" d=\"M148,-60C148,-60 118,-60 118,-60 112,-60 106,-54 106,-48 106,-48 106,-36 106,-36 106,-30 112,-24 118,-24 118,-24 148,-24 148,-24 154,-24 160,-30 160,-36 160,-36 160,-48 160,-48 160,-54 154,-60 148,-60\"/>\r\n<text text-anchor=\"middle\" x=\"133\" y=\"-38.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">a2</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n933863f287a94cfe95990a1697ae6d87->n7c23dc98b71846a2a2dab760ab83129f -->\r\n<g id=\"edge3\" class=\"edge\"><title>n933863f287a94cfe95990a1697ae6d87->n7c23dc98b71846a2a2dab760ab83129f</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M70.4029,-42C78.3932,-42 87.3106,-42 95.8241,-42\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"95.919,-45.5001 105.919,-42 95.919,-38.5001 95.919,-45.5001\"/>\r\n</g>\r\n<!-- n2649fee7b2044373a38b2c197b841c95 -->\r\n<g id=\"node3\" class=\"node\"><title>n2649fee7b2044373a38b2c197b841c95</title>\r\n<g id=\"a_node3\"><a xlink:title=\"a\">\r\n<path fill=\"#9bfba5\" fill-opacity=\"0.423529\" stroke=\"black\" d=\"M238,-60C238,-60 208,-60 208,-60 202,-60 196,-54 196,-48 196,-48 196,-36 196,-36 196,-30 202,-24 208,-24 208,-24 238,-24 238,-24 244,-24 250,-30 250,-36 250,-36 250,-48 250,-48 250,-54 244,-60 238,-60\"/>\r\n<text text-anchor=\"middle\" x=\"223\" y=\"-38.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">a</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n7c23dc98b71846a2a2dab760ab83129f->n2649fee7b2044373a38b2c197b841c95 -->\r\n<g id=\"edge4\" class=\"edge\"><title>n7c23dc98b71846a2a2dab760ab83129f->n2649fee7b2044373a38b2c197b841c95</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M160.403,-42C168.393,-42 177.311,-42 185.824,-42\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"178,-45.5005 188,-42 178,-38.5005 178,-45.5005\"/>\r\n</g>\r\n<!-- n1093035be3f540b1b4632f6c72124bcb -->\r\n<g id=\"node4\" class=\"node\"><title>n1093035be3f540b1b4632f6c72124bcb</title>\r\n<g id=\"a_node4\"><a xlink:title=\"b\">\r\n<path fill=\"#583efd\" fill-opacity=\"0.458824\" stroke=\"black\" d=\"M328,-60C328,-60 298,-60 298,-60 292,-60 286,-54 286,-48 286,-48 286,-36 286,-36 286,-30 292,-24 298,-24 298,-24 328,-24 328,-24 334,-24 340,-30 340,-36 340,-36 340,-48 340,-48 340,-54 334,-60 328,-60\"/>\r\n<text text-anchor=\"middle\" x=\"313\" y=\"-38.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">b</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n2649fee7b2044373a38b2c197b841c95->n1093035be3f540b1b4632f6c72124bcb -->\r\n<g id=\"edge1\" class=\"edge\"><title>n2649fee7b2044373a38b2c197b841c95->n1093035be3f540b1b4632f6c72124bcb</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M250.403,-42C258.393,-42 267.311,-42 275.824,-42\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"275.919,-45.5001 285.919,-42 275.919,-38.5001 275.919,-45.5001\"/>\r\n</g>\r\n<!-- nb25917515bad475ea3f1c4f3999f2b4c -->\r\n<g id=\"node5\" class=\"node\"><title>nb25917515bad475ea3f1c4f3999f2b4c</title>\r\n<g id=\"a_node5\"><a xlink:title=\"c\">\r\n<path fill=\"#ff6232\" fill-opacity=\"0.227451\" stroke=\"black\" d=\"M418,-60C418,-60 388,-60 388,-60 382,-60 376,-54 376,-48 376,-48 376,-36 376,-36 376,-30 382,-24 388,-24 388,-24 418,-24 418,-24 424,-24 430,-30 430,-36 430,-36 430,-48 430,-48 430,-54 424,-60 418,-60\"/>\r\n<text text-anchor=\"middle\" x=\"403\" y=\"-38.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">c</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n1093035be3f540b1b4632f6c72124bcb->nb25917515bad475ea3f1c4f3999f2b4c -->\r\n<g id=\"edge2\" class=\"edge\"><title>n1093035be3f540b1b4632f6c72124bcb->nb25917515bad475ea3f1c4f3999f2b4c</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M340.403,-42C348.393,-42 357.311,-42 365.824,-42\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"365.919,-45.5001 375.919,-42 365.919,-38.5001 365.919,-45.5001\"/>\r\n</g>\r\n</g>\r\n</svg>\r\n", | |
"text/plain": "<pydot.Dot at 0x1e500d3f808>" | |
}, | |
"execution_count": 66, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "sg1 = seq_cluster(['inp'], 'clust1')\nsg2 = seq_cluster(['a','b','c'], 'clust2')\nsg2.add_items(sg1.connect(sg2[-1]), sg1.connect(sg2))\ng = Dot()\ng.add_items(sg1,sg2)\ng", | |
"execution_count": 67, | |
"outputs": [ | |
{ | |
"data": { | |
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n<!-- Generated by graphviz version 2.38.0 (20140413.2041)\r\n -->\r\n<!-- Title: G Pages: 1 -->\r\n<svg width=\"364pt\" height=\"111pt\"\r\n viewBox=\"0.00 0.00 364.00 111.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 107)\">\r\n<title>G</title>\r\n<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-107 360,-107 360,4 -4,4\"/>\r\n<g id=\"clust1\" class=\"cluster\"><title>cluster_n2a43295f85784ad587280112ec3c0e92</title>\r\n<g id=\"a_clust1\"><a xlink:title=\"clust1\">\r\n<path fill=\"#555555\" fill-opacity=\"0.133333\" stroke=\"black\" d=\"M20,-8C20,-8 66,-8 66,-8 72,-8 78,-14 78,-20 78,-20 78,-71 78,-71 78,-77 72,-83 66,-83 66,-83 20,-83 20,-83 14,-83 8,-77 8,-71 8,-71 8,-20 8,-20 8,-14 14,-8 20,-8\"/>\r\n<text text-anchor=\"middle\" x=\"43\" y=\"-67.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">clust1</text>\r\n</a>\r\n</g>\r\n</g>\r\n<g id=\"clust2\" class=\"cluster\"><title>cluster_n173d2165a5554c8ab6c688af8381fc73</title>\r\n<g id=\"a_clust2\"><a xlink:title=\"clust2\">\r\n<path fill=\"#555555\" fill-opacity=\"0.133333\" stroke=\"black\" d=\"M110,-20C110,-20 336,-20 336,-20 342,-20 348,-26 348,-32 348,-32 348,-83 348,-83 348,-89 342,-95 336,-95 336,-95 110,-95 110,-95 104,-95 98,-89 98,-83 98,-83 98,-32 98,-32 98,-26 104,-20 110,-20\"/>\r\n<text text-anchor=\"middle\" x=\"223\" y=\"-79.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">clust2</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n252d45a7f1484aaf800ae8574aa07ce2 -->\r\n<g id=\"node1\" class=\"node\"><title>n252d45a7f1484aaf800ae8574aa07ce2</title>\r\n<g id=\"a_node1\"><a xlink:title=\"inp\">\r\n<path fill=\"#ff8e4a\" fill-opacity=\"0.666667\" stroke=\"black\" d=\"M58,-52C58,-52 28,-52 28,-52 22,-52 16,-46 16,-40 16,-40 16,-28 16,-28 16,-22 22,-16 28,-16 28,-16 58,-16 58,-16 64,-16 70,-22 70,-28 70,-28 70,-40 70,-40 70,-46 64,-52 58,-52\"/>\r\n<text text-anchor=\"middle\" x=\"43\" y=\"-30.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">inp</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- nb0c56ea0294843a3a6bb9969b3fb445e -->\r\n<g id=\"node2\" class=\"node\"><title>nb0c56ea0294843a3a6bb9969b3fb445e</title>\r\n<g id=\"a_node2\"><a xlink:title=\"a\">\r\n<path fill=\"#9bfba5\" fill-opacity=\"0.423529\" stroke=\"black\" d=\"M148,-64C148,-64 118,-64 118,-64 112,-64 106,-58 106,-52 106,-52 106,-40 106,-40 106,-34 112,-28 118,-28 118,-28 148,-28 148,-28 154,-28 160,-34 160,-40 160,-40 160,-52 160,-52 160,-58 154,-64 148,-64\"/>\r\n<text text-anchor=\"middle\" x=\"133\" y=\"-42.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">a</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n252d45a7f1484aaf800ae8574aa07ce2->nb0c56ea0294843a3a6bb9969b3fb445e -->\r\n<g id=\"edge4\" class=\"edge\"><title>n252d45a7f1484aaf800ae8574aa07ce2->nb0c56ea0294843a3a6bb9969b3fb445e</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M77.7296,-38.5995C83.6523,-39.4071 89.838,-40.2506 95.8241,-41.0669\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"87.5495,-43.1865 98,-41.4435 88.7435,-36.2891 87.5495,-43.1865\"/>\r\n</g>\r\n<!-- na35cd38fb8424e4887b45d7e28275fdc -->\r\n<g id=\"node4\" class=\"node\"><title>na35cd38fb8424e4887b45d7e28275fdc</title>\r\n<g id=\"a_node4\"><a xlink:title=\"c\">\r\n<path fill=\"#ff6232\" fill-opacity=\"0.227451\" stroke=\"black\" d=\"M328,-64C328,-64 298,-64 298,-64 292,-64 286,-58 286,-52 286,-52 286,-40 286,-40 286,-34 292,-28 298,-28 298,-28 328,-28 328,-28 334,-28 340,-34 340,-40 340,-40 340,-52 340,-52 340,-58 334,-64 328,-64\"/>\r\n<text text-anchor=\"middle\" x=\"313\" y=\"-42.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">c</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n252d45a7f1484aaf800ae8574aa07ce2->na35cd38fb8424e4887b45d7e28275fdc -->\r\n<g id=\"edge3\" class=\"edge\"><title>n252d45a7f1484aaf800ae8574aa07ce2->na35cd38fb8424e4887b45d7e28275fdc</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M77.6974,-23.1332C84.3587,-21.4144 91.3478,-19.9067 98,-19 164.937,-9.87599 183.864,-5.2242 250,-19 258.935,-20.8612 268.161,-24.082 276.678,-27.6649\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"275.381,-30.9189 285.938,-31.8109 278.241,-24.53 275.381,-30.9189\"/>\r\n</g>\r\n<!-- nb9676250af204f3080e1295bbf2f800d -->\r\n<g id=\"node3\" class=\"node\"><title>nb9676250af204f3080e1295bbf2f800d</title>\r\n<g id=\"a_node3\"><a xlink:title=\"b\">\r\n<path fill=\"#583efd\" fill-opacity=\"0.458824\" stroke=\"black\" d=\"M238,-64C238,-64 208,-64 208,-64 202,-64 196,-58 196,-52 196,-52 196,-40 196,-40 196,-34 202,-28 208,-28 208,-28 238,-28 238,-28 244,-28 250,-34 250,-40 250,-40 250,-52 250,-52 250,-58 244,-64 238,-64\"/>\r\n<text text-anchor=\"middle\" x=\"223\" y=\"-42.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">b</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- nb0c56ea0294843a3a6bb9969b3fb445e->nb9676250af204f3080e1295bbf2f800d -->\r\n<g id=\"edge1\" class=\"edge\"><title>nb0c56ea0294843a3a6bb9969b3fb445e->nb9676250af204f3080e1295bbf2f800d</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M160.403,-46C168.393,-46 177.311,-46 185.824,-46\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"185.919,-49.5001 195.919,-46 185.919,-42.5001 185.919,-49.5001\"/>\r\n</g>\r\n<!-- nb9676250af204f3080e1295bbf2f800d->na35cd38fb8424e4887b45d7e28275fdc -->\r\n<g id=\"edge2\" class=\"edge\"><title>nb9676250af204f3080e1295bbf2f800d->na35cd38fb8424e4887b45d7e28275fdc</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M250.403,-46C258.393,-46 267.311,-46 275.824,-46\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"275.919,-49.5001 285.919,-46 275.919,-42.5001 275.919,-49.5001\"/>\r\n</g>\r\n</g>\r\n</svg>\r\n", | |
"text/plain": "<pydot.Dot at 0x1e500dc7a08>" | |
}, | |
"execution_count": 67, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "# export\ndef Point(label='pnt', **kwargs):\n \"Create a `Node` with a 'point' shape\"\n return (Node('pnt', shape='point'))", | |
"execution_count": 68, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "sg = Cluster('clus')\na,b,c = sg.add_items('a','b','c')\np = sg.add_item(Point())\nsg.add_item(p.connect(c))\nsg.add_items(p.connect(a), a.connect(b), b.connect(c))\n\ng = Dot()\ng.add_items(sg)\ng", | |
"execution_count": 69, | |
"outputs": [ | |
{ | |
"data": { | |
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\r\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n<!-- Generated by graphviz version 2.38.0 (20140413.2041)\r\n -->\r\n<!-- Title: G Pages: 1 -->\r\n<svg width=\"314pt\" height=\"119pt\"\r\n viewBox=\"0.00 0.00 313.60 119.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 115)\">\r\n<title>G</title>\r\n<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-115 309.6,-115 309.6,4 -4,4\"/>\r\n<g id=\"clust1\" class=\"cluster\"><title>cluster_n2547236312244e518b99e437e53dc513</title>\r\n<g id=\"a_clust1\"><a xlink:title=\"clus\">\r\n<path fill=\"#555555\" fill-opacity=\"0.133333\" stroke=\"black\" d=\"M20,-8C20,-8 285.6,-8 285.6,-8 291.6,-8 297.6,-14 297.6,-20 297.6,-20 297.6,-91 297.6,-91 297.6,-97 291.6,-103 285.6,-103 285.6,-103 20,-103 20,-103 14,-103 8,-97 8,-91 8,-91 8,-20 8,-20 8,-14 14,-8 20,-8\"/>\r\n<text text-anchor=\"middle\" x=\"152.8\" y=\"-87.8\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">clus</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n7ed0fc186e5e453d85b47b0d266ef6c7 -->\r\n<g id=\"node1\" class=\"node\"><title>n7ed0fc186e5e453d85b47b0d266ef6c7</title>\r\n<g id=\"a_node1\"><a xlink:title=\"a\">\r\n<path fill=\"#9bfba5\" fill-opacity=\"0.423529\" stroke=\"black\" d=\"M97.6,-52C97.6,-52 67.6,-52 67.6,-52 61.6,-52 55.6,-46 55.6,-40 55.6,-40 55.6,-28 55.6,-28 55.6,-22 61.6,-16 67.6,-16 67.6,-16 97.6,-16 97.6,-16 103.6,-16 109.6,-22 109.6,-28 109.6,-28 109.6,-40 109.6,-40 109.6,-46 103.6,-52 97.6,-52\"/>\r\n<text text-anchor=\"middle\" x=\"82.6\" y=\"-30.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">a</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n04789dc84b7c448a92fa8041a1ead17f -->\r\n<g id=\"node2\" class=\"node\"><title>n04789dc84b7c448a92fa8041a1ead17f</title>\r\n<g id=\"a_node2\"><a xlink:title=\"b\">\r\n<path fill=\"#583efd\" fill-opacity=\"0.458824\" stroke=\"black\" d=\"M187.6,-52C187.6,-52 157.6,-52 157.6,-52 151.6,-52 145.6,-46 145.6,-40 145.6,-40 145.6,-28 145.6,-28 145.6,-22 151.6,-16 157.6,-16 157.6,-16 187.6,-16 187.6,-16 193.6,-16 199.6,-22 199.6,-28 199.6,-28 199.6,-40 199.6,-40 199.6,-46 193.6,-52 187.6,-52\"/>\r\n<text text-anchor=\"middle\" x=\"172.6\" y=\"-30.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">b</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n7ed0fc186e5e453d85b47b0d266ef6c7->n04789dc84b7c448a92fa8041a1ead17f -->\r\n<g id=\"edge3\" class=\"edge\"><title>n7ed0fc186e5e453d85b47b0d266ef6c7->n04789dc84b7c448a92fa8041a1ead17f</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M110.003,-34C117.993,-34 126.911,-34 135.424,-34\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"135.519,-37.5001 145.519,-34 135.519,-30.5001 135.519,-37.5001\"/>\r\n</g>\r\n<!-- n84a2e724d190437cbab65f20224da84a -->\r\n<g id=\"node3\" class=\"node\"><title>n84a2e724d190437cbab65f20224da84a</title>\r\n<g id=\"a_node3\"><a xlink:title=\"c\">\r\n<path fill=\"#ff6232\" fill-opacity=\"0.227451\" stroke=\"black\" d=\"M277.6,-62C277.6,-62 247.6,-62 247.6,-62 241.6,-62 235.6,-56 235.6,-50 235.6,-50 235.6,-38 235.6,-38 235.6,-32 241.6,-26 247.6,-26 247.6,-26 277.6,-26 277.6,-26 283.6,-26 289.6,-32 289.6,-38 289.6,-38 289.6,-50 289.6,-50 289.6,-56 283.6,-62 277.6,-62\"/>\r\n<text text-anchor=\"middle\" x=\"262.6\" y=\"-40.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">c</text>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- n04789dc84b7c448a92fa8041a1ead17f->n84a2e724d190437cbab65f20224da84a -->\r\n<g id=\"edge4\" class=\"edge\"><title>n04789dc84b7c448a92fa8041a1ead17f->n84a2e724d190437cbab65f20224da84a</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M200.003,-37.0003C207.993,-37.9083 216.911,-38.9217 225.424,-39.8891\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"225.188,-43.3847 235.519,-41.0362 225.978,-36.4294 225.188,-43.3847\"/>\r\n</g>\r\n<!-- nba378858c2654667ba7833c20ac11bee -->\r\n<g id=\"node4\" class=\"node\"><title>nba378858c2654667ba7833c20ac11bee</title>\r\n<g id=\"a_node4\"><a xlink:title=\"pnt\">\r\n<ellipse fill=\"#ff2613\" fill-opacity=\"0.682353\" stroke=\"black\" cx=\"17.8\" cy=\"-52\" rx=\"1.8\" ry=\"1.8\"/>\r\n</a>\r\n</g>\r\n</g>\r\n<!-- nba378858c2654667ba7833c20ac11bee->n7ed0fc186e5e453d85b47b0d266ef6c7 -->\r\n<g id=\"edge2\" class=\"edge\"><title>nba378858c2654667ba7833c20ac11bee->n7ed0fc186e5e453d85b47b0d266ef6c7</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M19.89,-51.6876C23.2748,-50.7174 34.0781,-47.6209 45.7202,-44.284\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"46.9039,-47.5858 55.5525,-41.4659 44.9751,-40.8567 46.9039,-47.5858\"/>\r\n</g>\r\n<!-- nba378858c2654667ba7833c20ac11bee->n84a2e724d190437cbab65f20224da84a -->\r\n<g id=\"edge1\" class=\"edge\"><title>nba378858c2654667ba7833c20ac11bee->n84a2e724d190437cbab65f20224da84a</title>\r\n<path fill=\"none\" stroke=\"black\" d=\"M19.6956,-52.3041C23.7682,-53.6687 40.9729,-59.2373 55.6,-61 119.14,-68.657 136.172,-69.5382 199.6,-61 208.093,-59.8567 217.069,-57.87 225.474,-55.6486\"/>\r\n<polygon fill=\"black\" stroke=\"black\" points=\"226.694,-58.9413 235.372,-52.8635 224.798,-52.203 226.694,-58.9413\"/>\r\n</g>\r\n</g>\r\n</svg>\r\n", | |
"text/plain": "<pydot.Dot at 0x1e500e4e9c8>" | |
}, | |
"execution_count": 69, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "# Export -" | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "#hide\nfrom nbdev.export import notebook2script\nnotebook2script()", | |
"execution_count": 70, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": "Converted 00_core.ipynb.\nConverted index.ipynb.\n" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "", | |
"execution_count": null, | |
"outputs": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"name": "python3", | |
"display_name": "Python 3", | |
"language": "python" | |
}, | |
"jupytext": { | |
"formats": "ipynb,py:light" | |
}, | |
"language_info": { | |
"name": "python", | |
"version": "3.7.4", | |
"mimetype": "text/x-python", | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"pygments_lexer": "ipython3", | |
"nbconvert_exporter": "python", | |
"file_extension": ".py" | |
}, | |
"toc": { | |
"nav_menu": {}, | |
"number_sections": true, | |
"sideBar": true, | |
"skip_h1_title": false, | |
"base_numbering": 1, | |
"title_cell": "Table of Contents", | |
"title_sidebar": "Contents", | |
"toc_cell": false, | |
"toc_position": {}, | |
"toc_section_display": true, | |
"toc_window_display": true | |
}, | |
"gist": { | |
"id": "", | |
"data": { | |
"description": "/00_core.ipynb", | |
"public": true | |
} | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment