2012-11-28 12 views
5

Sto provando a visualizzare una matrice di connessione di un problema con set bidirezionale. Come faccio a farlo in un modo che dimostri il meglio?Come visualizzo una connessione Matrix con Matplotlib?

ho iniziato con questo utilizzando un programma di grafica Yed:

example

I cerchi descrivono un certo tipo di collegamento tra il rosso e blu e le piazze altro. Entrambi i quadrati rossi e blu avranno una sorta di testo su di essi.

Tuttavia sarebbe più bello generare questo grafico con matplotlib, poiché mi piacerebbe generare questo al volo con i dati allegati. Come avrei proceduto a farlo? miei dati sembra un po 'come questo:

dati:

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

e così via. Mi piacerebbe scrivere le targhette dei nomi sui quadrati blu/rossi, in modo che l'utente sappia quale è quale.

Domanda successiva: Come posso generare un grafico da questo con i nodi parzialmente contrassegnati in blu/rosso? Tipo di come questo:

graphexample

Ma con i nodi riflettono la loro natura bilaterale. Sono ancora un po 'al buio su questo, principalmente perché non so come affrontarlo con Matplotlib. Sto sperando in alcuni buoni suggerimenti su come visualizzare questo e forse un esempio di implementazione che mi mostra la strada.

+1

Si dovrebbe dividere il follow-up domanda in una domanda separata. – tacaswell

+0

whazt ho provato sta incollando le immagini in una griglia di n^2 sottotrame. Tuttavia questo non è in realtà pietonico o il modo in cui è possibile farlo. Una soluzione migliore per me e altre persone che hanno bisogno di questo tipo di visualizzazione sarebbe apprezzata. – tarrasch

risposta

0

Che dire di fare una rappresentazione bipartita con bordi di colore come questo?

Bipartite graph with different kinds of connections

seguito è il codice che ha generato l'immagine.

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() 

Per ottenere qualcosa di simile a ciò che stai disegno 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

accetterebbe, se la matrice di connessione fosse anche lì ... :) – tarrasch

+0

@tarrasch oh, ho capito. Non sono sicuro che sia possibile una rappresentazione grafica pulita, a meno che tu sappia che i set sono piccoli perché dovrai disegnare più cliques interconnesse. Ho disegnato con matplotlib esattamente quello che hai fatto con yEd, che penso mostri meglio questa informazione e ho modificato la risposta con il codice – bcurcio

+0

ok, l'hai guadagnato :) ti invierò anche se riesci a riconoscere il mio formato di file e convertirlo: "Coppia: (MAN DESC WOMAN DESC) digitare: 1" Dove MAN DESC è il nome del nodo. Ho un intero file di questo modo. – tarrasch

6

Provare a utilizzare networkx. Puoi usarlo per visualizzare il grafico con colori specifici sui nodi e link per abbinare i tuoi dati.

Ecco un esempio:

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

lo verificherà sicuramente. – tarrasch

5

Ecco un'altra idea NetworkX/Matplotlib

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

enter image description here

enter image description here