Анимируйте диффузию графа с помощью NetworkX

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

Предположим, у нас есть следующий график:

import networkx as nx

g = nx.Graph()
g.add_edges_from([(1, 2), (2, 3), (1, 3), (1, 4), (3, 4), (4, 5), (5, 9), (4, 9)])

Также у нас есть начальный набор узлов, которые мы называем активными:

active = {1, 3}

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

active = {1, 3, 2, 4}

На следующей итерации набор активных узлов будет:

active = {1, 3, 2, 4, 5}.

На последней итерации все узлы графа станут активными:

active = {1, 3, 2, 4, 5, 9}

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

def tipping(graph, seed_set, thr=2):
    active = seed_set
    has_changed = False
    for n in filter(lambda n: n not in active, graph.nodes()):
        if len(filter(lambda nei: nei in active, graph.neighbors(n))) >= thr:
            active.add(n)
            has_changed = True
    if has_changed:
        return tipping(graph, active, thr) | active
    return active

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

Одним из возможных решений может быть построение графика на каждом этапе процесса с разными цветами узлов, сохранение каждого из них и создание анимации gif со всеми сохраненными изображениями.

Как я могу анимировать распространение с помощью Networkx? Предпочтительно, чтобы анимация выполнялась в блокноте IPython.


person Ashkan    schedule 04.08.2015    source источник
comment
Одним из возможных решений может быть построение графика на каждом этапе процесса с разными цветами узлов, сохранение каждого из них и создание анимации gif со всеми сохраненными изображениями. Вот что я бы порекомендовал.   -  person Joel    schedule 05.08.2015


Ответы (2)


Вот упрощенный, урезанный пример анимации, который будет полезен всем, кто ищет анимацию networkx. И это действительно работает, если вы запустите его.

import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
from matplotlib import animation


def simple_update(num, n, layout, G, ax):
    ax.clear()

    # Draw the graph with random node colors
    random_colors = np.random.randint(2, size=n)
    nx.draw(G, pos=layout, node_color=random_colors, ax=ax)

    # Set the title
    ax.set_title("Frame {}".format(num))


def simple_animation():

    # Build plot
    fig, ax = plt.subplots(figsize=(6,4))

    # Create a graph and layout
    n = 30 # Number of nodes
    m = 70 # Number of edges
    G = nx.gnm_random_graph(n, m)
    layout = nx.spring_layout(G)

    ani = animation.FuncAnimation(fig, simple_update, frames=10, fargs=(n, layout, G, ax))
    ani.save('animation_1.gif', writer='imagemagick')

    plt.show()

simple_animation()

Вам нужна одна функция simple_animation для настройки и запуска анимации и одна функция simple_update для обновления анимации. fargs позволяет передавать аргументы функции simple_update.

Эта анимация просто устанавливает случайные цвета, вы сможете адаптировать ее для любых других целей.

person chasmani    schedule 08.07.2019
comment
Можете ли вы сделать так, чтобы анимация отображалась в консоли jupyter, а не сохраняла файл .gif? Я попытался запустить ваш скрипт, и я могу только показать анимацию в консоли jupyter, если я удалю def simple_animation() и выполню анимацию в основном скрипте, а не внутри функции. - person Adam Gosztolai; 23.09.2019
comment
Извините, я не использую jupyter - person chasmani; 25.09.2019

Я реализовал анимированную диффузию тепла Networkx, используя фреймворк matplotlib animation. Если вы установите плагин JSAnimation для ноутбуков IPython, вы даже сможете визуализировать анимацию в своем блокноте!

Алгоритм должен быть примерно таким:

import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation

# Optionnal if you want to animate in your notebook
from JSAnimation import IPython_display

def update_func(step, data, nodes):
    # the step parameter is mandatory for matplotlib
    # Set new value for figure data
    # update node color here
    new_data = data + 1
    nodes.set_array(new_data)
    return nodes

def diffuse_anim(inputs, G, data, nb_frames=50):
    fig = plt.figure()
    nodes = nx.draw_networkx_nodes(G, pos, node_size=30, node_color='b')
    return animation.FuncAnimation(fig, update_func, frames=xrange(nb_frames), fargs=(data, nodes))

В моем приложении вы могли видеть распространение тепла из разных источников в красивой анимации в блокноте IPython.

введите здесь описание изображения

person Kirell    schedule 05.08.2015