2012-11-28 8 views
5

Ich versuche, eine Verbindungsmatrix eines Problems mit zwei Teilmengen zu visualisieren. Wie mache ich das am besten?Wie visualisiere ich eine Verbindungsmatrix mit Matplotlib?

Ich habe dies mit einem Grafikprogramm yed gestartet:

example

Die Kreise eine bestimmte Art von Verbindung zwischen Rot beschreiben und Blau und den weiteren Plätzen. Sowohl rote als auch blaue Quadrate haben eine Art Text auf ihnen.

Aber es wäre schöner, diese Grafik mit Matplotlib zu generieren, da ich dies mit Daten an der Fliege erzeugen möchte. Wie würde ich damit fortfahren? Meine Daten sieht irgendwie wie folgt aus:

Daten:

name_blue name_red Connection Type 
bluepart1 redpart1 1 
bluepart1 redpart2 1 
bluepart1 redpart3 1 
bluepart3 redpart2 2 
bluepart4 redpart2 2 
... 

und so weiter. Ich möchte die Nametags auf die blauen/roten Quadrate schreiben, damit der Benutzer weiß, welches was ist.

Folgefrage: Wie kann ich daraus einen Graph mit den teilweise blau/rot markierten Knoten erzeugen? Art wie folgt aus:

graphexample

Aber mit den Knoten ihre zweiteiligen Natur widerspiegelt. Ich bin immer noch etwas im Dunkeln, hauptsächlich weil ich nicht weiß, wie ich das mit Matplotlib angehen soll. Ich hoffe auf ein paar gute Vorschläge, wie das zu visualisieren ist und vielleicht eine Beispielimplementierung, die mir den Weg weist.

+1

Sie sollten Frage in eine separate Frage teilen Sie Ihre Follow-up. – tacaswell

+0

what ich versuchte, klebt Bilder in einem Raster von n^2 Teilplots. Dies ist jedoch nicht wirklich Python oder der Matplotlib-Weg, dies zu tun. Eine bessere Lösung für mich und andere Leute, die diese Art der Visualisierung benötigen, wäre willkommen. – tarrasch

Antwort

0

Was ist eine zweigeteilte Darstellung mit Farbkanten wie dies zu tun?

Bipartite graph with different kinds of connections

Es folgt der Code, der das Bild erzeugt.

import matplotlib.pyplot as plt 

def addconnection(i,j,c): 
    return [((-1,1),(i-1,j-1),c)] 

def drawnodes(s,i): 
    global ax 
    if(i==1): 
    color='r' 
    posx=1 
    else: 
    color='b' 
    posx=-1 

    posy=0 
    for n in s: 
    plt.gca().add_patch(plt.Circle((posx,posy),radius=0.05,fc=color)) 
    if posx==1: 
     ax.annotate(n,xy=(posx,posy+0.1)) 
    else: 
     ax.annotate(n,xy=(posx-len(n)*0.1,posy+0.1)) 
    posy+=1 

ax=plt.figure().add_subplot(111) 
set1=['Man1','Man2','Man3','Man4'] 
set2=['Woman1','Woman2','Woman3','Woman4','Woman5'] 
plt.axis([-2,2,-1,max(len(set1),len(set2))+1]) 
frame=plt.gca() 
frame.axes.get_xaxis().set_ticks([]) 
frame.axes.get_yaxis().set_ticks([]) 

drawnodes(set1,1) 
drawnodes(set2,2) 

connections=[] 
connections+=addconnection(1,2,'g') 
connections+=addconnection(1,3,'y') 
connections+=addconnection(1,4,'g') 
connections+=addconnection(2,1,'g') 
connections+=addconnection(4,1,'y') 
connections+=addconnection(4,3,'g') 
connections+=addconnection(5,4,'y') 

for c in connections: 
    plt.plot(c[0],c[1],c[2]) 

plt.show() 

Um so etwas wie, was Ihr in yEd

Connection matrix

import matplotlib.pyplot as plt 

COLOR1='r' 
COLOR2='b' 

def addconnection(i,j,c): 
    if(c==1): 
    plt.gca().add_patch(plt.Rectangle((j-0.1,-i-0.1),0.2,0.2,fc='y')) 
    if(c==2): 
    plt.gca().add_patch(plt.Circle((j,-i),radius=0.1,fc='y')) 

def drawnodes(s,i): 
    global ax 
    if(i==1): 
    color=COLOR1 
    vx=1 
    vy=0 
    else: 
    color=COLOR2 
    vx=0 
    vy=1 

    step=1 
    for n in s: 
    posx=step*vx 
    posy=step*vy 

    plt.gca().add_patch(plt.Circle((posx,-posy),radius=0.1,fc=color)) 
    ax.annotate(n,xy=(posx-len(n)*0.1,-posy+0.15)) 
    step+=1 

f=open('input.txt') 
t=f.readlines() 
t=map(lambda x: x.replace('(',' ').replace(')',' ').split(':'),t) 

set1=set([]) 
set2=set([]) 

for x in t: 
    s=x[1].split() 
    set1.add(s[0]) 
    set2.add(s[1]) 

set1=list(set1) 
set2=list(set2) 

dic={} 
for e in zip(set1,xrange(1,len(set1)+1)): dic[(e[0],1)]=e[1] 
for e in zip(set2,xrange(1,len(set2)+1)): dic[(e[0],2)]=e[1] 

ax=plt.figure(figsize=(max(len(set1),len(set2))+1,max(len(set1),len(set2))+1)).add_subplot(111) 
plt.axis([-1,max(len(set1),len(set2))+1,-max(len(set1),len(set2))-1,1]) 
frame=plt.gca() 
frame.axes.get_xaxis().set_ticks([]) 
frame.axes.get_yaxis().set_ticks([]) 

drawnodes(set1,1) 
drawnodes(set2,2) 

for x in t: 
    s=x[1].split() 
    addconnection(dic[(s[0],1)],dic[(s[1],2)],int(x[2])) 

plt.show() 
+0

würde akzeptieren, wenn die Verbindungsmatrix auch drin wäre ... :) – tarrasch

+0

@tarrasch oh, ich verstehe. Ich bin mir nicht sicher, ob eine saubere Graphendarstellung möglich ist, außer wenn Sie wissen, dass die Mengen klein sind, weil Sie mehrere miteinander verbundene Cliquen zeichnen müssen. Ich zeichnete mit matplotlib genau, was du mit yEd gemacht hast, was ich denke, zeigt diese Information am besten und modifizierte die Antwort mit dem Code – bcurcio

+0

ok, du hast dir das verdient :) ich werde dich zusätzlich upvoten, wenn du mein Dateiformat erkennen und konvertieren kannst: "Paar: (MAN DESC WOMAN DESC) Typ: 1" wobei MAN DESC der Name des Knotens ist. Ich habe eine ganze Akte dieser Art. – tarrasch

6

Versuchen Sie mit networkx. Sie können es verwenden, um das Diagramm mit bestimmten Farben auf den Knoten und Links anzuzeigen, um Ihre Daten zu vergleichen.

Hier ist ein Beispiel:

import itertools 
import networkx as nx 
import matplotlib.pyplot as plt 
edgelist = [(u,v,(u+v)%2) for u,v in itertools.product(range(3),range(3,6))] 
G = nx.Graph() 
for u,v,t in edgelist: 
    G.add_edge(u,v,attr_dict={'t':t}) 
ecolors = tuple('g' if G[u][v]['t'] == 1 else 'm' for u,v in G.edges()) 
nx.draw_networkx(G,node_color='rrrccc',edge_color=ecolors) 
plt.show() 

Simple Example

+0

wird das definitiv überprüfen. – tarrasch

5

Hier ist eine weitere NetworkX/Matplotlib Idee

import random 
import networkx as nx 
from networkx.algorithms.bipartite import biadjacency_matrix 
import matplotlib.pyplot as plt 
# generate random bipartite graph, part 1: nodes 0-9, part 2: nodes 10-29 
B = nx.bipartite_random_graph(10,20,0.25) 
# add some random weights 
for u,v in B.edges(): 
    B[u][v]['weight']=random.randint(0,4) 

# spring graphy layout 
plt.figure(1) 
pos = nx.spring_layout(B) 
colors = [d['weight'] for (u,v,d) in B.edges(data=True)] 
nx.draw(B,pos,node_color='#A0CBE2',edge_color=colors,width=4,edge_cmap=plt.cm.Blues,with_labels=False) 
plt.savefig('one.png') 

# simple bipartite layout 
plt.figure(2) 
pos = {} 
for n in range(10): 
    pos[n]=(n*2,1) 
for n in range(10,30): 
    pos[n]=(n-10,0) 
nx.draw(B,pos,node_color='#A0CBE2',edge_color=colors,width=4,edge_cmap=plt.cm.Blues,with_labels=False) 
plt.savefig('two.png') 

# biadjacency matrix colormap 
M = biadjacency_matrix(B,row_order=range(10),column_order=range(10,30)) 
plt.matshow(M,cmap=plt.cm.Blues) 
plt.savefig('three.png') 
plt.show() 

enter image description here

zeichnen

enter image description here

enter image description here