Ich möchte schöne Baumstrukturdaten mit Jupyter Notebook oder einer Webanwendung zeichnen! Das ist meine Motivation. Ich verwende Python, um die Originaldaten bequem analysieren zu können, und wollte die Analyse und Visualisierung interaktiv wiederholen.
Python Es scheint viele Möglichkeiten zu geben, eine Baumstruktur in Python zu zeichnen, und die erste, die mir in den Sinn kommt, ist networkx und [graphviz]. Ich verwende eine Diagrammbibliothek wie (https://graphviz.readthedocs.io/en/stable/), aber da der Zweck darin besteht, die Diagrammstruktur zu analysieren, halte ich ausgefeilte Ausdrücke für schwierig.
Auf der anderen Seite gibt es ETE Toolkit als spezielles Analyse- und Visualisierungswerkzeug für Baumstrukturen. Das Modell wird im Newick-Format dargestellt, das eine bekannte Darstellung der Baumstruktur zu sein scheint. Das sieht ziemlich gut aus, aber angesichts der Kompatibilität im Web wollte ich etwas Vielseitigeres wie JSON verwenden, um das Modell zu beschreiben.
Javascript Eine gute Zusammenfassung der Zeichnungsgraphenstrukturen in Javascript finden Sie hier [https://qiita.com/d0nchaaan/items/c47dc74cfefd92516e28]. Es gibt verschiedene Dinge, aber in Bezug auf Vielseitigkeit und Informationsmenge denke ich, dass es D3.js ist. Es gibt auch eine Bibliothek zum Zeichnen von Bäumen.
Also werde ich versuchen, mit Jup3.ter Notebook eine Baumstruktur mit D3.js zu zeichnen. Jupyter Notebook hat von Anfang an eine gute Affinität, da es Javascript ausführen und HTML zeichnen kann, während der Python-Kernel mithilfe von Zellmagie (%% Javascript) verwendet wird.
Als Methode können Sie Javascript Cell Magic oder py_d3 verwenden. Ersteres ist mit RequireJS nur schwer intuitiv zu verstehen (siehe hier). Letzteres scheint die Zellmagie von Javascript gut zu verpacken. Hier erkläre ich das Zeichnen mit py_d3.
Wie auch immer, installieren Sie py_d3. Verwenden Sie pip. pip install py_d3
Laden Sie das Modul zunächst wie folgt:
import py_d3
py_d3.load_ipython_extension(get_ipython())
Unten finden Sie ein Beispielzitat von der Homepage. Das erste %% d3 5.12.0
gibt die Version von d3.js an. Sie können herausfinden, welche Version verfügbar ist, indem Sie "% d3 version" eingeben.
%%d3 5.12.0
<g></g>
<style>
element {
height: 25px;
}
div.bar {
display: inline-block;
width: 20px;
height: 75px;
margin-right: 2px;
background-color: teal;
}
</style>
<script>
var dataset = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,
11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];
d3.select("g").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class", "bar")
.style("height", function(d) {
var barHeight = d * 5;
return barHeight + "px";
});
</script>
Sie können die Ausgabe des Diagramms wie unten gezeigt überprüfen.
Durch die vollständige Nutzung von RequireJS ist es möglich, in Python berechnete Objekte und Variablen in die definierte Javascript-Funktion einzugeben. Es unterscheidet sich jedoch nicht wesentlich von der Ausgabe in JSON und dem Lesen in d3.js. Wenn die Daten also nicht sehr groß sind, ist es einfach, die Zwischendatei durchzugehen. Bereiten Sie beispielsweise eine JSON-Datei mit Baumstruktur vor, wie unten gezeigt.
import json
data = {
"name": "A",
"children": [
{ "name": "B" },
{
"name": "C",
"children": [{ "name": "D" }, { "name": "E" }, { "name": "F" }]
},
{ "name": "G" },
{
"name": "H",
"children": [{ "name": "I" }, { "name": "J" }]
},
{ "name": "K" }
]
};
json_file = open('test.json', 'w')
json.dump(data, json_file)
Verwenden Sie das Baumlayout von d3-Hierarchie, um die Baumstruktur zu zeichnen. Nachdem Sie die JSON-Datenstruktur geladen und einen Baum basierend auf diesen Daten erstellt haben, müssen Sie lediglich die SVG-Zeichnung anpassen. Informationen zur Feineinstellung der Zeichnung finden Sie in den Dokumenten d3.js und SVG.
%%d3 5.12.0
<style>
.link {
fill: none;
stroke: #555;
stroke-opacity: 0.4;
stroke-width: 1.5px;
}
</style>
<svg width="800" height="600"></svg>
<script>
var width = 800;
var height = 600;
var g = d3.select("svg").append("g")
.attr("transform", "translate(80,0)");
console.log("data");
d3.json("test.json")
.then((data) => {
console.log(data);
var root = d3.hierarchy(data);
var tree = d3.tree(root).size([height, width - 160]);
tree(root);
var link = g.selectAll(".link")
.data(root.descendants().slice(1))
.enter()
.append("path")
.attr("class", "link")
.attr("d", (d) => {
return "M" + d.y + "," + d.x +
"C" + (d.parent.y + 100) + "," + d.x +
" " + (d.parent.y + 100) + "," + d.parent.x +
" " + d.parent.y + "," + d.parent.x;
});
var node = g.selectAll(".node")
.data(root.descendants())
.enter()
.append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
node.append("circle")
.attr("r", 8)
.attr("fill", "#999");
node.append("text")
.attr("dy", 3)
.attr("x", function(d) { return d.children ? -12 : 12; })
.style("text-anchor", function(d) { return d.children ? "end" : "start"; })
.attr("font-size", "200%")
.text(function(d) { return d.data.name; });
})
.catch((error)=>{
}
)
</script>
Recommended Posts