2015-07-16 2 views
3

Я хотел бы знать, есть ли способ рисовать вложенные сетевые графики в python.Рисование вложенных диаграмм networkx

Я могу успешно сделать эти графики с помощью nx.draw _ (...) вызова метода, как описано в NetworkX документации, но дело, я использую его для требует, чтобы один из самих узлов представляет собой график (Представьте себе сеть комнат, на верхнем уровне с сетью зон/зон в этих комнатах на следующем уровне вниз). Я хотел бы показать это с помощью matplotlib или аналогичного.

Любые идеи будут оценены.

+0

Вы хотите, чтобы 2D-график был правильным? – Kikohs

+0

Да, просто обычный 2D сюжет, ничего необычного. – xyzen

ответ

5

Редактировать Возможно, вы можете сделать лучше, чем мой первоначальный ответ, определив рекурсивную функцию. Вот пример того, как будет выглядеть рекурсивная функция. Мой ответ ниже дает менее элегантный подход, который можно легко настроить для конкретного случая, но если вы когда-либо делаете это часто, вам, вероятно, понадобится эта рекурсивная версия.

def recursive_draw(G,currentscalefactor=0.1,center_loc=(0,0),nodesize=300, shrink=0.1): 
    pos = nx.spring_layout(G) 
    scale(pos,currentscalefactor) #rescale distances to be smaller 
    shift(pos,center_loc) #you'll have to write your own code to shift all positions to be centered at center_loc 
    nx.draw(G,pos=pos, nodesize=nodesize) 
    for node in G.nodes_iter(): 
     if type(node)==Graph: # or diGraph etc... 
      recursive_draw(node,currentscalefactor=shrink*currentscalefactor,center_loc=pos[node], nodesize = nodesize*shrink, shrink=shrink) 

Если кто-то создает рекурсивную функцию, добавьте ее как отдельный ответ и дайте мне комментарий. Я укажу на это из этого ответа.


Оригинальный ответ Вот первый проход (я надеюсь, изменить для полного ответа к концу дня, но я думаю, что это поможет вам большую часть пути туда):

import networkx as nx 
import pylab as py 

G = nx.Graph() 

H = nx.Graph() 
H.add_edges_from([(1,2), (2,3), (1,3)]) 

I = nx.Graph() 
I.add_edges_from([(1,3), (3,2)]) 


G.add_edge(H,I) 

Gpos = nx.spring_layout(G) 
Hpos = nx.spring_layout(H) 
Ipos = nx.spring_layout(I) 

scalefactor = 0.1 
for node in H.nodes(): 
    Hpos[node] = Hpos[node]*scalefactor + Gpos[H] 

for node in I.nodes(): 
    Ipos[node] = Ipos[node]*scalefactor + Gpos[I] 


nx.draw_networkx_edges(G, pos = Gpos) 
nx.draw_networkx_nodes(G, pos = Gpos, node_color = 'b', node_size = 15000, alpha = 0.5) 
nx.draw(H, pos = Hpos, with_labels = True) 
nx.draw(I, pos = Ipos, with_labels = True) 
py.savefig('tmp.png') 

enter image description here

Главное, что я должен сделать, это сосредоточить каждую подзону. Это потребует определения xmin, xmax, ymin и ymax для каждого подзаголовка и корректировки. Вы также можете играть с scalefactor.

+0

Спасибо, Джоэл, не подумал бы об этом. Thats больше, что достаточно, чтобы заставить меня идти :) Я, скорее всего, отмечу это как ответ, если альтернативное/более чистое решение не появится на следующий день или около того! – xyzen