it-swarm.com.de

Baumzeichnung in Python

Ich möchte Bäume mit Python plotten. Entscheidungsbäume, Organigramme usw. Gibt es eine Bibliothek, die mir dabei hilft?

33
Injeniero Barsa

Es gibt graphviz - http://www.graphviz.org/ . Es verwendet die Sprache "DOT", um Diagramme zu zeichnen. Sie können den DOT-Code entweder selbst generieren oder pydot - https://code.google.com/p/pydot/ verwenden. Sie können auch networkx - http://networkx.lanl.gov/tutorial/tutorial.html#drawing-graphs verwenden, um das Zeichnen in graphviz oder matplotlib zu vereinfachen.

networkx + matplotlib + graphviz bietet Ihnen die größte Flexibilität und Leistung, aber Sie müssen viel installieren.

Wenn Sie eine schnelle Lösung wünschen, versuchen Sie Folgendes:

Installieren Sie Graphviz.

open('hello.dot','w').write("digraph G {Hello->World}")
import subprocess
subprocess.call(["path/to/dot.exe","-Tpng","hello.dot","-o","graph1.png"]) 
# I think this is right - try it form the command line to debug

Dann installieren Sie pydot, da pydot dies bereits für Sie erledigt. Dann können Sie networkx verwenden, um pydot zu "fahren".

19
wisty

Ich entwickle ETE , das ist ein python) - Paket, das unter anderem für das programmatische Rendern und Visualisieren von Bäumen gedacht ist erstelle deine eigenen Layoutfunktionen und erstelle eigene Baumbilder : enter image description here

Es konzentriert sich auf die Phylogenetik, kann aber tatsächlich mit jeder Art von hierarchischem Baum (Clustering, Entscheidungsbäume usw.) umgehen.

39
jhc

Plotly kann Baumdiagramme mit igraph zeichnen. Sie können es heutzutage auch offline verwenden. Das folgende Beispiel soll in einem Jupyter-Notizbuch ausgeführt werden

import plotly.plotly as py
import plotly.graph_objs as go

import igraph
from igraph import *
# I do not endorse importing * like this

#Set Up Tree with igraph

nr_vertices = 25
v_label = map(str, range(nr_vertices))
G = Graph.Tree(nr_vertices, 2) # 2 stands for children number
lay = G.layout('rt')

position = {k: lay[k] for k in range(nr_vertices)}
Y = [lay[k][1] for k in range(nr_vertices)]
M = max(Y)

es = EdgeSeq(G) # sequence of edges
E = [e.Tuple for e in G.es] # list of edges

L = len(position)
Xn = [position[k][0] for k in range(L)]
Yn = [2*M-position[k][1] for k in range(L)]
Xe = []
Ye = []
for Edge in E:
    Xe+=[position[Edge[0]][0],position[Edge[1]][0], None]
    Ye+=[2*M-position[Edge[0]][1],2*M-position[Edge[1]][1], None] 

labels = v_label

#Create Plotly Traces

lines = go.Scatter(x=Xe,
                   y=Ye,
                   mode='lines',
                   line=dict(color='rgb(210,210,210)', width=1),
                   hoverinfo='none'
                   )
dots = go.Scatter(x=Xn,
                  y=Yn,
                  mode='markers',
                  name='',
                  marker=dict(symbol='dot',
                                size=18, 
                                color='#6175c1',    #'#DB4551', 
                                line=dict(color='rgb(50,50,50)', width=1)
                                ),
                  text=labels,
                  hoverinfo='text',
                  opacity=0.8
                  )

# Create Text Inside the Circle via Annotations

def make_annotations(pos, text, font_size=10, 
                     font_color='rgb(250,250,250)'):
    L=len(pos)
    if len(text)!=L:
        raise ValueError('The lists pos and text must have the same len')
    annotations = go.Annotations()
    for k in range(L):
        annotations.append(
            go.Annotation(
                text=labels[k], # or replace labels with a different list 
                                # for the text within the circle  
                x=pos[k][0], y=2*M-position[k][1],
                xref='x1', yref='y1',
                font=dict(color=font_color, size=font_size),
                showarrow=False)
        )
    return annotations  

# Add Axis Specifications and Create the Layout

axis = dict(showline=False, # hide axis line, grid, ticklabels and  title
            zeroline=False,
            showgrid=False,
            showticklabels=False,
            )

layout = dict(title= 'Tree with Reingold-Tilford Layout',  
              annotations=make_annotations(position, v_label),
              font=dict(size=12),
              showlegend=False,
              xaxis=go.XAxis(axis),
              yaxis=go.YAxis(axis),          
              margin=dict(l=40, r=40, b=85, t=100),
              hovermode='closest',
              plot_bgcolor='rgb(248,248,248)'          
              )

# Plot

data=go.Data([lines, dots])
fig=dict(data=data, layout=layout)
fig['layout'].update(annotations=make_annotations(position, v_label))
py.iplot(fig, filename='Tree-Reingold-Tilf')
# use py.plot instead of py.iplot if you're not using a Jupyter notebook

Ausgabe

4
KevinH

Es ist expirmental, aber Google hat ein GraphViz api . Es ist praktisch, wenn Sie nur ein Diagramm schnell visualisieren möchten, aber keine Software installieren möchten.

2
Austin Marshall