несоответствие между построенным графиком networkx и записями данных - PullRequest
0 голосов
/ 26 июня 2018

Я пытаюсь построить ориентированный граф из кадра данных, содержащего данные моего узла и ребра. График нарисован, но когда я попытался назначить альфа-значения или конкретную ширину для моих ребер, я понял, что существует несоответствие между данными в кадре данных и тем, что рисуется сетью x (ребра получают неправильную ширину).

Вот мой код:

df = df.drop_duplicates()
df = df.reset_index(drop=True)

edge_list = df.loc[:, ['f', 't', 'v']]
edge_list.to_csv('edges.csv', index=False, header=False)

G = read_edgelist('edges.csv', delimiter=',', create_using=MultiDiGraph(), data=[('weight', float)],
                    edgetype=float)

pos = nx_pydot.pydot_layout(G, prog='dot')

plot.figure(figsize=(10, 10), dpi=150)

draw_networkx_nodes(G, pos, node_color='skyblue', node_size=5000, nodelist=nodes)
draw_networkx_nodes(G, pos, node_size=2000, node_color='r', nodelist=[address], node_shape='s', edgecolors='black')
draw_networkx_nodes(G, pos, node_size=2000, node_color='r', nodelist=taintsources, node_shape='s', edgecolors='black')
edges = draw_networkx_edges(G, pos, arrows=True, arrowsize=30, arrowstyle='->', edge_color='black')
draw_networkx_labels(G, pos, font_size=9)

# set alphas
i = 0
for a in df['v']:
    edges[i].set_alpha(a)
    i += 1

plot.show()

Теперь данные в кадре данных (df после переиндексации и удаления) выглядят следующим образом:

                f                                           t          v                                                  l
0   0xdbd838...  0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be   4.999775  0xaeaac2670575ca1602b598401c43e85513edf7e99974...
1   0xe6c334...  0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be   1.507629  0xcad1b3c29d03dc55234334d906e61dde140b91985a13...
2   0xec7bcd...  0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be   1.428406  0x419685acc8b968b48536d190d2c50dffc7fda8fb8579...
3   0x1fe81d...  0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be   2.973072  0xac8d0f5c672b5e27dad3687606bc2aedffc3611fa2f8...
4   0xe6c334...  0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be   0.714586  0xaa27468c07ba13b185f83e71934ab0e0aa684570faf6...
5   0xdbd838...  0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be   0.714511  0x56a0783f46e8176df3b5833480e6565e3110e8ba952d...
6   0xa92189...                                 0xdbd838...   5.000000  0xda791bbba0fd49e733970ad9b48d6c1fff02d5e93b1b...
7   0x523564...                                 0xa92189...   5.000255  0x0c5e6548f5285520fc03a7ebf5f636e9475c1f678db8...
8   0x5abf99...                                 0x523564...  10.714286  0x24699357078cc1cfe6b3d57a67ffab18ef132dc86996...
9   0xc50be6...                                 0xe6c334...   1.507929  0xe6bf05d6c99db12d1735a62f2c3a9df37941025de2d6...
10  0x523564...                                 0xc50be6...   1.508184  0x62c7a7793294ac46094ceb0c580fcc8593575a8c6fbc...
11  0x329fda...                                 0x1fe81d...   2.977357  0x66bd13433f5ab207aced390ba2c915f913556105f010...
12  0x9dc588...                                 0x329fda...   2.977582  0x09714e7e2dedec960801b74d4838aac99ded96bbb29e...
13  0x523564...                                 0x9dc588...   2.977837  0xe83750f61b3bde48c39ce384d3b480e393e39c78d2fb...
14  0x68a419...                                 0xec7bcd...   1.428571  0xecba439590735ca8cdd69ba5669c8fdcbda68eefeee1...
15  0xfb08f9...                                 0x68a419...   1.428826  0x6c5d9dc5af2074b1ff81ef7f700df837693d6fba21b5...
16  0x523564...                                 0xfb08f9...   1.494462  0x5d404be34d7108a3b029340f39fe2e62e6983dba858f...

Сейчас есть две проблемы: df содержит 17 записей, в то время как граф содержит только 15 (?) ребер, и поэтому веса не назначены правильным ребрам Результирующий график (plot.show ()) имеет некоторые явно неправильные назначения, когда речь идет о ширине стрелок (самая широкая стрелка на неправильном крае). Я предполагаю, что некоторые ребра объединяются в графе, и это приводит к несоответствию. Как я могу предотвратить это? Как мне сделать это правильно? Я очень благодарен за ваш вклад! :)

Edit1: Вот мои данные, использованные в этом коде (в виде строки JSON):

address = "0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be"
taintsources = ["0x5abf99..."]
nodes = ["0x9dc588...", "0xec7bcd...", "0xdbd838...", "0xc50be6...", "0xa92189...", "0x523564...", "0x1fe81d...", "0xe6c334...", "0x68a419...", "0xfb08f9...", "0x329fda..."]

df (после сброса и сброса индекса):

https://pastebin.com/vc8L665V (альфа-масштабирование)

https://pastebin.com/JyDLwdNJ (масштабирование по ширине)

Edit2: Корректировки кода для большего контекста. Также скорректированы значения df, так как v-столбец теперь масштабируется между 0,1 и 1,0 (для соответствия альфа-каналам) вместо масштабируемого от 1 до 10 (когда ранее пытались установить другую ширину стрелки для ребра).

Edit3: добавлено изображение: enter image description here Как видно, граница между 0x5abf99 ... и 0x523564 ... не имеет сплошного соединения, но в соответствии с кадром данных она должна.

1 Ответ

0 голосов
/ 27 июня 2018

Итак, основным виновником являются следующие два ряда

4   0xe6c334...     0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be  0.714586    0xaa27468c07ba13b185f83e71934ab0e0aa684570faf6...
5   0xdbd838...     0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be  0.714511    0x56a0783f46e8176df3b5833480e6565e3110e8ba952d...

Это дублирующие ребра, единственное отличие состоит в значении в столбце v Поэтому вам нужно создать multiDigraph () для учета нескольких ребер с разными атрибутами.

Кроме того, я не был уверен, поддерживает ли from_pandas_edgelist атрибуты чтения ребра, поэтому я внес следующие изменения в ваш код, используя read_edgelist , и это учитывает несколько ребер

df = df.drop_duplicates()
df = df.reset_index(drop=True)

#Convert the data to node1, node2, attribute_data format
edge_list = df.loc[:,['f','t','v']]
edge_list.to_csv('edges.csv', index=False,header=False)

G = nx.read_edgelist('edges.csv',delimiter=',',create_using=nx.MultiDiGraph(),data=[('weight',float)],edgetype=float)

print len(G.edges())
#output : 17
...