2016-12-02 20 views
3

График имеет около 100 узлов, а количество сообществ колеблется от 5 до 20. Есть ли способ рисовать график таким образом, чтобы узлы того же сообщества были близки друг другу?Как нарисовать небольшой график с структурой сообщества в сетиx

Я пытался назначить разные сообщества разных цветов, но это не очень хорошо работает в моем приложении.

Я читал this и this, но не нашел подходящего решения.

Я использую питон 2.7.12 и newtorkx-1,11

ответ

6

Для маленького графа, я считаю spring_layout довольно хорошо для рисования сообществ. Если необходимо выделить узлы (и их общины) Я рекомендую вам:

  • выбирать различные цвета для различных сообществ (чем больше, цвета отличается визуально, тем лучше),

  • увеличить размер узлы и

  • сделать края более светлыми серыми (таким образом, граф выглядит менее захламлен, а узлы более выделены визуально).

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

В следующем примере я использую график по умолчанию (nx.karate_club_graph), в котором я автоматически обнаруживаю сообщества с помощью пакета python-louvain (импортированного как community). Размер узла определяется аргументом node_size в nx.draw_networkx_nodes. Цвета узлов зависят от сообщества, к которому они принадлежат. Я использую цветную карту plt.cm.RdYlBu (см. Больше цветных карт here). Обратите внимание, что вы также можете влиять на размеры узлов (и длины ребер), определяя большее или меньшее изображение с figsize в plt.figure.

import networkx as nx 
import community 
import matplotlib.pyplot as plt 

G = nx.karate_club_graph() # load a default graph 

partition = community.best_partition(G) # compute communities 

pos = nx.spring_layout(G) # compute graph layout 
plt.figure(figsize=(8, 8)) # image is 8 x 8 inches 
plt.axis('off') 
nx.draw_networkx_nodes(G, pos, node_size=600, cmap=plt.cm.RdYlBu, node_color=list(partition.values())) 
nx.draw_networkx_edges(G, pos, alpha=0.3) 
plt.show(G) 

Output (Я побежал код несколько раз и выбрал в «симпатичным» изображение):

enter image description here

Но что, если у вас есть больший граф с менее очевидными сообществами? Вот более сложный граф с 100 узлов и 100 случайных ребер (и, таким образом, случайных общин), но с тем же чертежной подхода:

import networkx as nx 
import community 
import matplotlib.pyplot as plt 
import random 

H = nx.Graph() 

nodes = list(range(100)) # 100 nodes 

# add 100 random edges 
for i in range(100): 
    src = random.choice(nodes) 
    dest = random.choice(nodes) 
    # we don't want src to be the same as dest 
    while src == dest: 
     dest = random.choice(nodes) 

    H.add_edge(src, dest) 

partition = community.best_partition(H) # compute communities 

pos = nx.spring_layout(H) # compute graph layout 
plt.figure(figsize=(10, 10)) 
plt.axis('off') 
nx.draw_networkx_nodes(H, pos, node_size=600, cmap=plt.cm.RdYlBu, node_color=list(partition.values())) 
nx.draw_networkx_edges(H, pos, alpha=0.3) 
plt.show(H) 

Выход:

enter image description here

Мы не видим четких общин в изображение выше.Здесь у вас есть по крайней мере три варианта:

  • определяет расположение графа (узлы координат/позиция) вручную (pos в моем коде),

  • эксперимента с различными раскладками (найден here) и

  • есть изображение для каждого сообщества (или, по крайней мере, наиболее важные сообщества ).

Если вы выберете третий вариант, вы можете иметь узлы одного выделенного сообщества больше, чем другие узлы (и, конечно, разного цвета). Вы также можете изменить цвет и толщину ребер в этом сообществе (не показано в примере ниже).

node_size = [] 

# first community against the others 
for node, community in partition.items(): 
    if community == 1: 
     node_size.append(900) 
    else: 
     partition[node] = 0 # I put all the other communities in one communitiy 
     node_size.append(300) 

plt.figure(figsize=(10, 10)) 
plt.axis('off') 
nodes = nx.draw_networkx_nodes(H, pos, node_size=node_size, cmap=plt.cm.winter, node_color=list(partition.values())) 
nx.draw_networkx_edges(H, pos, alpha=0.3) 
plt.show(H) 

выход (только первая община подсвечена):

enter image description here

Если у вас есть несколько изображений для того же графа, я рекомендую, что узлы имеют одинаковые позиции во всех из них (вы необходимо будет иметь то же самое pos между рисунками). Таким образом, изображения более сопоставимы.

+0

Этот подробный ответ действительно полезен. Использование цветной карты упрощает визуализацию кода и графику. – user3813057