2016-02-18 2 views
4

Как отображать двудольный граф в пакете python networkX с узлами из одного класса в столбце слева и справа от другого класса?Как отображать двухсторонние графики с пакетом python networkX?

Я могу создать график и отображать его как этот

B = nx.Graph() 
B.add_nodes_from([1,2,3,4], bipartite=0) # Add the node attribute "bipartite" 
B.add_nodes_from(['a','b','c'], bipartite=1) 
B.add_edges_from([(1,'a'), (1,'b'), (2,'b'), (2,'c'), (3,'c'), (4,'a')]) 
nx.draw(B) 
plt.show() 

Но я хочу узлы 1,2,3,4 на левом в колонке, и узлы «а», «B»,» c 'в столбце справа, причем между ними пересекаются ребра.

ответ

2

Вам нужно установить позиции для каждого узла самостоятельно:

B = nx.Graph() 
B.add_nodes_from([1,2,3,4], bipartite=0) # Add the node attribute "bipartite" 
B.add_nodes_from(['a','b','c'], bipartite=1) 
B.add_edges_from([(1,'a'), (1,'b'), (2,'b'), (2,'c'), (3,'c'), (4,'a')]) 

# Separate by group 
l, r = nx.bipartite.sets(B) 
pos = {} 

# Update position for node from each group 
pos.update((node, (1, index)) for index, node in enumerate(l)) 
pos.update((node, (2, index)) for index, node in enumerate(r)) 

nx.draw(B, pos=pos) 
plt.show() 

enter image description here

+1

Это замечательно. Любая идея, как распространить его на многочастные графы, где есть, скажем, три столбца? Похоже, двухсторонний объект ограничивает вас двумя. –

0

Чтобы ответить на мой собственный вопрос, основанный на @Rikka выше - Вот код для определения позиции для узлов в произвольном многочастном графе, заданные имена для частей.

def position_MultiPartiteGraph(Graph, Parts): 
    # Graph is a networkX Graph object, where the nodes have attribute 'agentType' with part name as a value 
    # Parts is a list of names for the parts (to be shown as columns) 
    # returns list of dictionaries with keys being networkX Nodes, values being x,y coordinates for plottingxPos = {} 
    xPos = {} 
    yPos = {} 
    for index1, agentType in enumerate(Parts): 
    xPos[agentType] = index1 
    yPos[agentType] = 0 

    pos = {} 
    for node, attrDict in Graph.nodes(data=True): 
    agentType = attrDict['agentType'] 
    # print ('node: %s\tagentType: %s' % (node, agentType)) 
    # print ('\t(x,y): (%d,%d)' % (xPos[agentType], yPos[agentType])) 
    pos[node] = (xPos[agentType], yPos[agentType]) 
    yPos[agentType] += 1 

    return pos 

Теперь предположим, что я определяю трехсторонний граф, как это (вес не имеют значения для данного примера):

TG = nx.Graph() 
TG.add_nodes_from([1,2,3,4], agentType='world') # Add the node attribute "bipartite" 
TG.add_nodes_from(['a','b','c'], agentType='sender') 
TG.add_nodes_from(['A','B','C'], agentType='receiver') 

# This is just an easier way to add (and to automatically generate) weighted edges 
myEdges = [(1,'a',0.75), 
     (1,'b',0.25), 
     (2,'b',0.5), 
     (2,'c',0.5), 
     (3,'c',1.0), 
     (4,'a',1.0), 
     ('a','C',0.10), 
     ('a','A',0.80), 
     ('c','A',1.0), 
     ('b','C',1.0)] 

[TG.add_edge(x,y,weight=z) for x,y, z in myEdges] 

Тогда вот как его использовать:

nx.draw(TG,pos=position_MultiPartiteGraph(TG, ['world', 'sender', 'receiver'])) 
plt.show() 

Я m не уверен, как показать результат, но он работает для меня! Ура! Благодаря @Rikka!

Смежные вопросы