2014-02-24 137 views
19

我在使用python-networkx創建的圖形可視化時遇到了一些問題,我希望能夠減少混亂並調節節點之間的距離(我也試過spring_layout,它只是佈局節點以橢圓形式)。請指教。 enter image description here改進Python NetworkX圖形佈局

零件代碼:

nx.draw_networkx_edges(G, pos, edgelist=predges, edge_color='red', arrows=True) 
nx.draw_networkx_edges(G, pos, edgelist=black_edges, arrows=False, style='dashed') 
# label fonts 
nx.draw_networkx_labels(G,pos,font_size=7,font_family='sans-serif') 
nx.draw_networkx_edge_labels(G,pos,q_list,label_pos=0.3) 

回答

36

在networkx中,有必要通過nx.graphviz_layout來檢查由graphviz提供的圖形繪製算法。

我有很好的成功與neato但其他可能的輸入是

  • dot - 「分層」或有向圖的分層圖。如果邊具有方向性,這是使用的默認工具。

  • neato - 「spring model」佈局如果圖形不是太大(大約100個節點),並且您不知道其他任何信息,那麼這是默認的工具。能量函數相當於統計多維尺度

  • fdp - 「彈簧模型」的佈局類似於neato,但是這是通過減少力量而不是通過能量來實現的。

  • sfdp - 用於大圖佈局的fdp多尺度版本。

  • twopi - 徑向佈局,在Graham Wills 97之後。節點根據距離給定根節點的距離放置在同心圓上。

  • circo - 圓形佈局,在Six和Tollis 99,Kauffman和Wiese 02之後。這適用於多個循環結構的某些圖,例如某些電信網絡。

一般來說,graph drawing是一個難題。如果這些算法不夠用,則必須編寫自己的或單獨使用networkx繪圖部件。

+1

對'graphviz_layout'的問題請參考http://stackoverflow.com/questions/35279733/what-c​​ould-cause-networkx-pygraphviz-to-work-fine-alone-but-not-together – Mrlenny

+2

用法:'nx。繪製(G,pos = graphviz_layout(G))' – Mrlenny

4

你有大量的數據在你的圖形,所以它將會是難以去除雜波。

我建議你使用任何標準佈局。你說你用過spring_layout。我建議你再試一次,但這次使用weight屬性添加邊緣。

例如:

import networkx as nx 

G = nx.Graph(); 
G.add_node('A') 
G.add_node('B') 
G.add_node('C') 
G.add_node('D') 
G.add_edge('A','B',weight=1) 
G.add_edge('C','B',weight=1) 
G.add_edge('B','D',weight=30) 

pos = nx.spring_layout(G,scale=2) 

nx.draw(G,pos,font_size=8) 
plt.show() 

另外,你可以使用參數scale增加節點之間的全局距離。

+1

權重如何影響算法?更重的==節點靠近或者相反? –

3

要回答你的問題如何規範節點之間的距離,我就Hooked's answer擴大:

如果你畫通過Graphviz的後端圖形,當你再使用fdp算法,可以調整節點之間的距離由edge attribute len

這裏的代碼示例,如何繪製的曲線圖G並保存在Graphviz的文件gvfile與節點之間的較寬的距離(fdp默認距離是0.3):

A = nx.to_agraph(G) 
A.edge_attr.update(len=3) 
A.write(gv_file_name) 

兩個評論:

  1. 通常建議用圖中節點數調整len
  2. len屬性僅由fdpneato算法識別,但不是例如。通過sfdp算法。
1

我發現這對於快速查看來自PostgreSQL的源文件爲CSV文件的交互數據很有用。 [下面輸出重新格式化爲可讀性。]

## PSQL ['DUMMY' DATA]: 

[interactions_practice]# \copy (SELECT gene_1, gene_2 FROM interactions 
    WHERE gene_1 in (SELECT gene_2 FROM interactions)) 
    TO '/tmp/a.csv' WITH CSV  -- << note: no terminating ";" for this query 

## BASH: 

[[email protected] ~]$ cat /tmp/a.csv                          

    APC,TP73 
    BARD1,BRCA1 
    BARD1,ESR1 
    BARD1,KRAS2 
    BARD1,SLC22A18 
    BARD1,TP53 
    BRCA1,BRCA2 
    BRCA1,CHEK2 
    BRCA1,MLH1 
    BRCA1,PHB 
    BRCA2,CHEK2 
    BRCA2,TP53 
    CASP8,ESR1 
    CASP8,KRAS2 
    CASP8,PIK3CA 
    CASP8,SLC22A18 
    CDK2,CDKN1A 
    CHEK2,CDK2 
    ESR1,BRCA1 
    ESR1,KRAS2 
    ESR1,PPM1D 
    ESR1,SLC22A18 
    KRAS2,BRCA1 
    MLH1,CHEK2 
    MLH1,PMS2 
    PIK3CA,BRCA1 
    PIK3CA,ESR1 
    PIK3CA,RB1CC1 
    PIK3CA,SLC22A18 
    PMS2,TP53 
    PTEN,BRCA1 
    PTEN,MLH3 
    RAD51,BRCA1 
    RB1CC1,SLC22A18 
    SLC22A18,BRCA1 
    TP53,PTEN 


## PYTHON 3.5 VENV (ANACONDA): 

>>> import networkx as nx 
>>> import pylab as plt 
>>> G = nx.read_edgelist("/tmp/a.csv", delimiter=",") 

>>> G.edges() 

    [('CDKN1A', 'CDK2'), ('MLH3', 'PTEN'), ('TP73', 'APC'), ('CHEK2', 'MLH1'), 
    ('CHEK2', 'BRCA2'), ('CHEK2', 'CDK2'), ('CHEK2', 'BRCA1'), ('BRCA2', 'TP53'), 
    ('BRCA2', 'BRCA1'), ('KRAS2', 'CASP8'), ('KRAS2', 'ESR1'), ('KRAS2', 'BRCA1'), 
    ('KRAS2', 'BARD1'), ('PPM1D', 'ESR1'), ('BRCA1', 'PHB'), ('BRCA1', 'ESR1'), 
    ('BRCA1', 'PIK3CA'), ('BRCA1', 'PTEN'), ('BRCA1', 'MLH1'), ('BRCA1', 'SLC22A18'), 
    ('BRCA1', 'BARD1'), ('BRCA1', 'RAD51'), ('CASP8', 'ESR1'), ('CASP8', 'SLC22A18'), 
    ('CASP8', 'PIK3CA'), ('TP53', 'PMS2'), ('TP53', 'PTEN'), ('TP53', 'BARD1'), 
    ('PMS2', 'MLH1'), ('PIK3CA', 'SLC22A18'), ('PIK3CA', 'ESR1'), ('PIK3CA', 'RB1CC1'), 
    ('SLC22A18', 'ESR1'), ('SLC22A18', 'RB1CC1'), ('SLC22A18', 'BARD1'), ('BARD1', 'ESR1')] 

>>> G.number_of_edges() 
    36 

>>> G.nodes() 

    ['CDKN1A', 'MLH3', 'TP73', 'CHEK2', 'BRCA2', 'KRAS2', 'CDK2', 'PPM1D', 'BRCA1', 
    'CASP8', 'TP53', 'PMS2', 'RAD51', 'PIK3CA', 'MLH1', 'SLC22A18', 'BARD1', 'PHB', 'APC', 'ESR1', 'RB1CC1', 'PTEN'] 

>>> G.number_of_nodes() 
    22 

>>> from networkx.drawing.nx_agraph import graphviz_layout 

>>> ## nx.draw(G, pos=graphviz_layout(G)) 

## DUE TO AN UNIDENTIFIED BUG, I GET THIS ERROR THE FIRST TIME RUNNING THIS 
## COMMAND; JUST RE-RUN IT: 

>>> nx.draw(G, pos=graphviz_layout(G), node_size=1200, node_color='lightblue', 
    linewidths=0.25, font_size=10, font_weight='bold', with_labels=True) 

    QGtkStyle could not resolve GTK. Make sure you have installed the proper libraries. 

>>> nx.draw(G, pos=graphviz_layout(G), node_size=1200, node_color='lightblue', 
    linewidths=0.25, font_size=10, font_weight='bold', with_labels=True) 

>>> plt.show() ## plot1.png [opens in matplotlib popup window] attached 

這是很難在這些靜態networkx/matplotlib曲線減小擁塞;一個解決辦法是增加的數字大小,每此StackOverflow的Q/A:High Resolution Image of a Graph using NetworkX and Matplotlib

>>> plt.figure(figsize=(20,14)) 
    <matplotlib.figure.Figure object at 0x7f1b65ea5e80> 

>>> nx.draw(G, pos=graphviz_layout(G), node_size=1200, node_color='lightblue', 
    linewidths=0.25, font_size=10, font_weight='bold', with_labels=True, dpi=1000) 

>>> plt.show() ## plot2.png attached 

## RESET OUTPUT FIGURE SIZE TO SYSTEM DEFAULT: 

>>> plt.figure() 
    <matplotlib.figure.Figure object at 0x7f1b454f1588> 

plot1.png plot1.png

plot2.png plot2.png

獎金 - 最短路徑:

>>> nx.dijkstra_path(G, 'CDKN1A', 'MLH3') 
['CDKN1A', 'CDK2', 'CHEK2', 'BRCA1', 'PTEN', 'MLH3']