Hello,
I’ve looked at the animation examples and was able to write something like this:
from graph_tool.all import *
from graph_tool.generation import graph_union
from gi.repository import Gtk, Gdk, GdkPixbuf, GObject, GLib
from numpy.random import *
import sys, os, os.path
import time
iternum = 100
i = 0
g = load_graph(f"ACH-000681_OLAPARIB_i1.xml")
graphs = [*range(iternum)]
for i in range(iternum):
graphs[i] = load_graph(f"ACH-000681_OLAPARIB_i{i+1}.xml")
pos = sfdp_layout(g)
#pos = fruchterman_reingold_layout(g)
#pos = random_layout(g)
# We will filter out vertices which are in the "Recovered" state, by masking
# them using a property map.
removed = g.new_vertex_property("bool")
ON = [1,1,1,1] #white
OFF = [0,0,0,1] #black
INC = [0,20,0,1] #green
DEC = [20,0,0,1] #red
state = g.new_vertex_property("vector<double>")
for v in g.vertices():
state[v] = ON
# Newly infected nodes will be highlighted in red
# If True, the frames will be dumped to disk as images.
offscreen = sys.argv[1] == "offscreen" if len(sys.argv) > 1 else False
max_count = 500
if offscreen and not os.path.exists("./frames"):
os.mkdir("./frames")
if not offscreen:
win = GraphWindow(g, pos, geometry=(500, 400),
edge_color=[0.6, 0.6, 0.6, 1],
vertex_fill_color=state,
vertex_halo_color=[0.8, 0, 0, 0.6])
else:
count = 0
win = Gtk.OffscreenWindow()
win.set_default_size(500, 400)
win.graph = GraphWidget(g, pos,
edge_color=[0.6, 0.6, 0.6, 1],
vertex_fill_color=state,
vertex_halo_color=[0.8, 0, 0, 0.6])
win.add(win.graph)
def update_state():
global i
removed.a = False
for v in g.vertices():
if i != 0:
if v in graphs[i].vertices():
if graphs[i].vertex_properties["change"][v] > 0:
state[v] = graphs[i].vertex_properties["change"][v]*INC
elif graphs[i].vertex_properties["change"][v] < 0:
state[v] = graphs[i].vertex_properties["change"][v]*DEC
else:
state[v] = ON
else:
state[v] = OFF
if state[v] == OFF:
removed[v] = True
time.sleep(1)
# Filter out the recovered vertices
g.set_vertex_filter(removed.t(lambda x: 1-x))
# The following will force the re-drawing of the graph, and issue a
# re-drawing of the GTK window.
win.graph.regenerate_surface()
win.graph.queue_draw()
if offscreen:
global count
pixbuf = win.get_pixbuf()
pixbuf.savev(r'./frames/sirs%06d.png' % count, 'png', [], [])
if count > max_count:
sys.exit(0)
count += 1
i = i+1
if i == 100:
return False
return True
# Bind the function above as an 'idle' callback.
cid = GLib.idle_add(update_state)
# We will give the user the ability to stop the program by closing the window.win.connect("delete_event", Gtk.main_quit)
win.connect("delete_event", Gtk.main_quit)
# Actually show the window, and start the main loop.
win.show_all()
Gtk.main()
using the idle callback and updating the global variables i wanted to simulate a for loop, since the values i have are already stored in the graphs array with the sequence of graphs in that.
the problem is that it isn’t animating, it only shows a single frame of probably the last iteration:
how do i fix this?