web-dev-qa-db-fra.com

Tracé d'arbre en Python

Je veux tracer des arbres en utilisant Python. Arbres de décision, organigrammes, etc. Une bibliothèque qui m'aide avec ça?

33
Injeniero Barsa

Il y a graphviz - http://www.graphviz.org/ . Il utilise le langage "DOT" pour tracer des graphiques. Vous pouvez soit générer le code DOT vous-même, soit utiliser pydot - https://code.google.com/p/pydot/ . Vous pouvez également utiliser networkx - http://networkx.lanl.gov/tutorial/tutorial.html#drawing-graphs , ce qui facilite le dessin sur graphviz ou matplotlib.

networkx + matplotlib + graphviz vous offre le plus de flexibilité et de puissance, mais vous devez en installer beaucoup.

Si vous voulez une solution rapide, essayez:

Installez 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

Ensuite, vous installez pydot, car pydot le fait déjà pour vous. Ensuite, vous pouvez utiliser networkx pour "piloter" pydot.

19
wisty

Je développe [~ # ~] ete [~ # ~] , qui est un package python destiné, entre autres) trucs, pour le rendu et la visualisation d'arborescence programmatique. Vous pouvez créer vos propres fonctions de disposition et produire des images d'arbre personnalisées : enter image description here

Il se concentre sur la phylogénétique, mais il peut en fait traiter tout type d'arbre hiérarchique (clustering, arbres de décision, etc.)

39
jhc

Plotly peut tracer des diagrammes d'arbre en utilisant igraph. Vous pouvez également l'utiliser hors ligne ces jours-ci. L'exemple ci-dessous est destiné à être exécuté dans un ordinateur portable Jupyter

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

Sortie

4
KevinH

C'est expérimental, mais Google a un GraphViz api . C'est pratique si vous souhaitez simplement visualiser rapidement un graphique, mais ne souhaitez installer aucun logiciel.

2
Austin Marshall