Animation with a set number of iterations

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?