2012-11-28 9 views
5

Tôi đang cố gắng hình dung một ma trận kết nối của một vấn đề đặt bi-partite. Làm thế nào để tôi làm điều này theo cách thể hiện tốt nhất?Làm thế nào để tôi hình dung một Ma trận kết nối với Matplotlib?

Tôi đã bắt đầu với điều này bằng cách sử dụng Yed chương trình đồ họa:

example

Các vòng tròn mô tả một loại mối liên hệ giữa màu đỏ và màu xanh và các ô vuông khác. Cả hai ô vuông màu đỏ và xanh dương sẽ có một số loại văn bản trên chúng.

Tuy nhiên, nó sẽ đẹp hơn khi tạo grafic này với matplotlib, vì tôi muốn tạo điều này khi đang di chuyển với dữ liệu được đính kèm. Làm thế nào tôi sẽ tiến hành để làm điều đó? Dữ liệu của tôi trông kinda như thế này:

dữ liệu:

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

và vân vân. Tôi muốn viết các thẻ tên vào các ô vuông màu xanh/đỏ để người dùng biết cái nào.

Câu hỏi tiếp theo: Làm cách nào để tạo biểu đồ từ nút này với các nút được đánh dấu một phần màu xanh/đỏ? Loại như thế này:

graphexample

Nhưng với các nút phản ánh tính chất song phương của họ. Tôi vẫn còn một chút trong bóng tối về điều này, chủ yếu là bởi vì tôi không biết làm thế nào để giải quyết điều này với matplotlib. Tôi hy vọng cho một vài gợi ý tốt về cách hình dung điều này và có thể một ví dụ thực hiện cho tôi thấy con đường.

+1

Bạn nên chia theo bạn lên câu hỏi thành một câu hỏi riêng biệt. – tacaswell

+0

whazt tôi đã thử dán hình ảnh trong một mạng lưới của n^2 subplots. Tuy nhiên đây không phải là thực sự pythonic hoặc cách matplotlib làm điều này. Một giải pháp tốt hơn cho tôi và những người cần loại hình trực quan này sẽ được đánh giá cao. – tarrasch

Trả lời

0

gì về việc một đại diện song phương với cạnh màu như thế này?

Bipartite graph with different kinds of connections

Sau đây là mã tạo hình ảnh.

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

Để có được một cái gì đó giống như những gì bạn đang vẽ trong 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

sẽ chấp nhận, nếu ma trận kết nối cũng có trong đó ... :) – tarrasch

+0

@tarrasch oh, tôi hiểu. Tôi không chắc chắn một đại diện đồ thị sạch sẽ là có thể, ngoại trừ nếu bạn biết các bộ là nhỏ bởi vì bạn sẽ phải vẽ nhiều cliques kết nối với nhau. Tôi đã vẽ với matplotlib chính xác những gì bạn đã làm với yEd, mà tôi nghĩ rằng hiển thị thông tin này tốt nhất và sửa đổi câu trả lời với mã – bcurcio

+0

ok, bạn kiếm được điều này :) tôi sẽ bổ sung thêm bạn nếu bạn có thể nhận ra định dạng tệp của tôi và chuyển đổi nó: "Pair: (MAN DESC WOMAN DESC) type: 1" Trong đó MAN DESC là tên của nút. Tôi có toàn bộ tập tin theo cách này. – tarrasch

6

Thử sử dụng networkx. Bạn có thể sử dụng nó để hiển thị biểu đồ với các màu cụ thể trên các nút và liên kết để khớp với dữ liệu của bạn.

Dưới đây là một ví dụ:

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

chắc chắn sẽ kiểm tra điều đó. – tarrasch

5

Dưới đây là một ý tưởng 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