Better visualizations

release/4.3a0
p-zach 2025-04-16 16:28:58 -04:00
parent bcfd0ec3a9
commit 60d00621ff
1 changed files with 208 additions and 142 deletions

View File

@ -57,7 +57,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 9,
"metadata": {
"id": "bayestree_import_code"
},
@ -88,7 +88,7 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 10,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
@ -101,74 +101,165 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Original Factor Graph:\n",
"\n",
"size: 7\n",
"factor 0: \n",
" A[x0] = [\n",
"\t-1\n",
"]\n",
" b = [ 0 ]\n",
" Noise model: unit (1) \n",
"factor 1: \n",
" A[x0] = [\n",
"\t-1\n",
"]\n",
" A[x1] = [\n",
"\t1\n",
"]\n",
" b = [ 0 ]\n",
" Noise model: unit (1) \n",
"factor 2: \n",
" A[x1] = [\n",
"\t-1\n",
"]\n",
" A[x2] = [\n",
"\t1\n",
"]\n",
" b = [ 0 ]\n",
" Noise model: unit (1) \n",
"factor 3: \n",
" A[l1] = [\n",
"\t-1\n",
"]\n",
" A[x0] = [\n",
"\t1\n",
"]\n",
" b = [ 0 ]\n",
" Noise model: unit (1) \n",
"factor 4: \n",
" A[l1] = [\n",
"\t-1\n",
"]\n",
" A[x1] = [\n",
"\t1\n",
"]\n",
" b = [ 0 ]\n",
" Noise model: unit (1) \n",
"factor 5: \n",
" A[l2] = [\n",
"\t-1\n",
"]\n",
" A[x1] = [\n",
"\t1\n",
"]\n",
" b = [ 0 ]\n",
" Noise model: unit (1) \n",
"factor 6: \n",
" A[l2] = [\n",
"\t-1\n",
"]\n",
" A[x2] = [\n",
"\t1\n",
"]\n",
" b = [ 0 ]\n",
" Noise model: unit (1) \n"
"Original Factor Graph:\n"
]
},
{
"data": {
"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.50.0 (0)\n",
" -->\n",
"<!-- Pages: 1 -->\n",
"<svg width=\"350pt\" height=\"84pt\"\n",
" viewBox=\"0.00 0.00 350.00 83.60\" 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 79.6)\">\n",
"<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-79.6 346,-79.6 346,4 -4,4\"/>\n",
"<!-- var7782220156096217089 -->\n",
"<g id=\"node1\" class=\"node\">\n",
"<title>var7782220156096217089</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"99\" cy=\"-57.6\" rx=\"27\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"99\" y=\"-53.9\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">l1</text>\n",
"</g>\n",
"<!-- factor3 -->\n",
"<g id=\"node9\" class=\"node\">\n",
"<title>factor3</title>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"75\" cy=\"-1.8\" rx=\"1.8\" ry=\"1.8\"/>\n",
"</g>\n",
"<!-- var7782220156096217089&#45;&#45;factor3 -->\n",
"<g id=\"edge6\" class=\"edge\">\n",
"<title>var7782220156096217089&#45;&#45;factor3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M91.67,-40.17C85.49,-26.32 77.36,-8.1 75.43,-3.76\"/>\n",
"</g>\n",
"<!-- factor4 -->\n",
"<g id=\"node10\" class=\"node\">\n",
"<title>factor4</title>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"123\" cy=\"-1.8\" rx=\"1.8\" ry=\"1.8\"/>\n",
"</g>\n",
"<!-- var7782220156096217089&#45;&#45;factor4 -->\n",
"<g id=\"edge8\" class=\"edge\">\n",
"<title>var7782220156096217089&#45;&#45;factor4</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M106.33,-40.17C112.51,-26.32 120.64,-8.1 122.57,-3.76\"/>\n",
"</g>\n",
"<!-- var7782220156096217090 -->\n",
"<g id=\"node2\" class=\"node\">\n",
"<title>var7782220156096217090</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"315\" cy=\"-57.6\" rx=\"27\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"315\" y=\"-53.9\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">l2</text>\n",
"</g>\n",
"<!-- factor5 -->\n",
"<g id=\"node11\" class=\"node\">\n",
"<title>factor5</title>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"243\" cy=\"-1.8\" rx=\"1.8\" ry=\"1.8\"/>\n",
"</g>\n",
"<!-- var7782220156096217090&#45;&#45;factor5 -->\n",
"<g id=\"edge10\" class=\"edge\">\n",
"<title>var7782220156096217090&#45;&#45;factor5</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M297.57,-43.58C278.26,-29.15 249.13,-7.38 243.84,-3.43\"/>\n",
"</g>\n",
"<!-- factor6 -->\n",
"<g id=\"node12\" class=\"node\">\n",
"<title>factor6</title>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"279\" cy=\"-1.8\" rx=\"1.8\" ry=\"1.8\"/>\n",
"</g>\n",
"<!-- var7782220156096217090&#45;&#45;factor6 -->\n",
"<g id=\"edge12\" class=\"edge\">\n",
"<title>var7782220156096217090&#45;&#45;factor6</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M304.39,-40.75C295.1,-26.86 282.63,-8.22 279.66,-3.78\"/>\n",
"</g>\n",
"<!-- var8646911284551352320 -->\n",
"<g id=\"node3\" class=\"node\">\n",
"<title>var8646911284551352320</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-57.6\" rx=\"27\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"27\" y=\"-53.9\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">x0</text>\n",
"</g>\n",
"<!-- factor0 -->\n",
"<g id=\"node6\" class=\"node\">\n",
"<title>factor0</title>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"27\" cy=\"-1.8\" rx=\"1.8\" ry=\"1.8\"/>\n",
"</g>\n",
"<!-- var8646911284551352320&#45;&#45;factor0 -->\n",
"<g id=\"edge1\" class=\"edge\">\n",
"<title>var8646911284551352320&#45;&#45;factor0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M27,-39.58C27,-25.79 27,-7.97 27,-3.73\"/>\n",
"</g>\n",
"<!-- factor1 -->\n",
"<g id=\"node7\" class=\"node\">\n",
"<title>factor1</title>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"100\" cy=\"-1.8\" rx=\"1.8\" ry=\"1.8\"/>\n",
"</g>\n",
"<!-- var8646911284551352320&#45;&#45;factor1 -->\n",
"<g id=\"edge2\" class=\"edge\">\n",
"<title>var8646911284551352320&#45;&#45;factor1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M44.67,-43.58C64.25,-29.15 93.78,-7.38 99.15,-3.43\"/>\n",
"</g>\n",
"<!-- var8646911284551352320&#45;&#45;factor3 -->\n",
"<g id=\"edge7\" class=\"edge\">\n",
"<title>var8646911284551352320&#45;&#45;factor3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M40.37,-41.61C52.8,-27.68 69.99,-8.41 74.09,-3.81\"/>\n",
"</g>\n",
"<!-- var8646911284551352321 -->\n",
"<g id=\"node4\" class=\"node\">\n",
"<title>var8646911284551352321</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"171\" cy=\"-57.6\" rx=\"27\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"171\" y=\"-53.9\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">x1</text>\n",
"</g>\n",
"<!-- var8646911284551352321&#45;&#45;factor1 -->\n",
"<g id=\"edge3\" class=\"edge\">\n",
"<title>var8646911284551352321&#45;&#45;factor1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M153.81,-43.58C134.77,-29.15 106.05,-7.38 100.83,-3.43\"/>\n",
"</g>\n",
"<!-- factor2 -->\n",
"<g id=\"node8\" class=\"node\">\n",
"<title>factor2</title>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"178\" cy=\"-1.8\" rx=\"1.8\" ry=\"1.8\"/>\n",
"</g>\n",
"<!-- var8646911284551352321&#45;&#45;factor2 -->\n",
"<g id=\"edge4\" class=\"edge\">\n",
"<title>var8646911284551352321&#45;&#45;factor2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M173.21,-39.58C175.01,-25.79 177.33,-7.97 177.88,-3.73\"/>\n",
"</g>\n",
"<!-- var8646911284551352321&#45;&#45;factor4 -->\n",
"<g id=\"edge9\" class=\"edge\">\n",
"<title>var8646911284551352321&#45;&#45;factor4</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M157.63,-41.61C145.2,-27.68 128.01,-8.41 123.91,-3.81\"/>\n",
"</g>\n",
"<!-- var8646911284551352321&#45;&#45;factor5 -->\n",
"<g id=\"edge11\" class=\"edge\">\n",
"<title>var8646911284551352321&#45;&#45;factor5</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M188.43,-43.58C207.74,-29.15 236.87,-7.38 242.16,-3.43\"/>\n",
"</g>\n",
"<!-- var8646911284551352322 -->\n",
"<g id=\"node5\" class=\"node\">\n",
"<title>var8646911284551352322</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"243\" cy=\"-57.6\" rx=\"27\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"243\" y=\"-53.9\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">x2</text>\n",
"</g>\n",
"<!-- var8646911284551352322&#45;&#45;factor2 -->\n",
"<g id=\"edge5\" class=\"edge\">\n",
"<title>var8646911284551352322&#45;&#45;factor2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M226.6,-43.02C209.75,-29.08 185.18,-8.74 179.3,-3.87\"/>\n",
"</g>\n",
"<!-- var8646911284551352322&#45;&#45;factor6 -->\n",
"<g id=\"edge13\" class=\"edge\">\n",
"<title>var8646911284551352322&#45;&#45;factor6</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M253.61,-40.75C262.9,-26.86 275.37,-8.22 278.34,-3.78\"/>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<graphviz.sources.Source at 0x1d6fb24ec10>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Create a simple Gaussian Factor Graph (more complex this time)\n",
"# Create a simple Gaussian Factor Graph\n",
"graph = GaussianFactorGraph()\n",
"model = gtsam.noiseModel.Isotropic.Sigma(1, 1.0)\n",
"graph.add(X(0), -np.eye(1), np.zeros(1), model) # Prior on x0\n",
@ -180,19 +271,18 @@
"graph.add(L(2), -np.eye(1), X(2), np.eye(1), np.zeros(1), model) # l2 -> x2 (measurement)\n",
"\n",
"print(\"Original Factor Graph:\")\n",
"graph.print()"
"display(graphviz.Source(graph.dot()))"
]
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Resulting BayesTree:\n",
": cliques: 2, variables: 5\n",
"- p(x1 l2 x2 )\n",
@ -213,8 +303,52 @@
" [ -0.948683 ]\n",
" d = [ 0 0 ]\n",
" logNormalizationConstant: -1.03316\n",
" No noise model\n"
" No noise model\n",
"\n",
"Visualization:\n"
]
},
{
"data": {
"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.50.0 (0)\n",
" -->\n",
"<!-- Title: G Pages: 1 -->\n",
"<svg width=\"103pt\" height=\"116pt\"\n",
" viewBox=\"0.00 0.00 102.89 116.00\" 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 112)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-112 98.89,-112 98.89,4 -4,4\"/>\n",
"<!-- 2 -->\n",
"<g id=\"node1\" class=\"node\">\n",
"<title>2</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"47.45\" cy=\"-90\" rx=\"44.69\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"47.45\" y=\"-86.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">x1, l2, x2</text>\n",
"</g>\n",
"<!-- 3 -->\n",
"<g id=\"node2\" class=\"node\">\n",
"<title>3</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"47.45\" cy=\"-18\" rx=\"47.39\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"47.45\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">l1, x0 : x1</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;3 -->\n",
"<g id=\"edge1\" class=\"edge\">\n",
"<title>2&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M47.45,-71.7C47.45,-63.98 47.45,-54.71 47.45,-46.11\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"50.95,-46.1 47.45,-36.1 43.95,-46.1 50.95,-46.1\"/>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<graphviz.sources.Source at 0x1d6fb28be10>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
@ -223,8 +357,10 @@
"# Note: Multifrontal typically yields multiple roots if graph is disconnected\n",
"bayes_tree = graph.eliminateMultifrontal(ordering)\n",
"\n",
"print(\"\\nResulting BayesTree:\")\n",
"bayes_tree.print()"
"print(\"Resulting BayesTree:\")\n",
"bayes_tree.print()\n",
"print(\"\\nVisualization:\")\n",
"display(graphviz.Source(bayes_tree.dot()))"
]
},
{
@ -328,76 +464,6 @@
"print(\"\\nJoint Marginal Factor Graph on (x0, x2):\")\n",
"joint_x0_x2.print()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "bayestree_viz_md"
},
"source": [
"## Visualization\n",
"\n",
"Bayes trees can be visualized using Graphviz."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "bayestree_dot_code",
"outputId": "789abcde-f012-3456-789a-bcdef0123456"
},
"outputs": [
{
"data": {
"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.50.0 (0)\n",
" -->\n",
"<!-- Title: G Pages: 1 -->\n",
"<svg width=\"103pt\" height=\"116pt\"\n",
" viewBox=\"0.00 0.00 102.89 116.00\" 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 112)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-112 98.89,-112 98.89,4 -4,4\"/>\n",
"<!-- 0 -->\n",
"<g id=\"node1\" class=\"node\">\n",
"<title>0</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"47.45\" cy=\"-90\" rx=\"44.69\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"47.45\" y=\"-86.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">x1, l2, x2</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node2\" class=\"node\">\n",
"<title>1</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"47.45\" cy=\"-18\" rx=\"47.39\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"47.45\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">l1, x0 : x1</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;1 -->\n",
"<g id=\"edge1\" class=\"edge\">\n",
"<title>0&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M47.45,-71.7C47.45,-63.98 47.45,-54.71 47.45,-46.11\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"50.95,-46.1 47.45,-36.1 43.95,-46.1 50.95,-46.1\"/>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<graphviz.sources.Source at 0x1d6fb25a900>"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"graphviz.Source(bayes_tree.dot())"
]
}
],
"metadata": {