2

I'm trying to find the neatest way to make an animation similar to this one, with the difference that I need to update the graph topology and the vertices' properties synchronously (it's a graph analog of the game of life). I have been doing so far by simply constructing a graph sequence by copying the graph on the (i-1)-th iteration, computing alterations based on the original graph, and returning the updated copy.

As it seems to me, the problem with this approach is that when using GraphWindow, like in the linked example, I need to modify the graph in-place, instead of making copies. So the best I could do was to iterate twice over the graph, at each call of the update_state function. The first iteration is to compute the new states, the second to assign them. A batch assignment would work for properties with scalar values, but I couldn't manage to do it for properties with string values.

Summing it up, I want to, at each call of update_state, update synchronously two properties, a scalar one, corresponding to the state of a vertex, vp.state, and a string-valued one, corresponding to its color, vp.color;

This is an excerpt of the full code (the update_state function -- which I named run_simulation)

def run_simulation():

    global count, g
    
    to_remove = []
    alterations = []
    r = 0
    

    for v in g.get_vertices():
        if len(g.get_all_edges(v)) == 0:
            print(r)
            r+=1
            to_remove.append(v)
        else:
            Nv = g.get_all_neighbors(v)
            sum_nbstates = sum([g.vp.state[u] for u in Nv])
            nb_size = len(Nv)
            acoef = sum_nbstates / nb_size
    
            if g.vp.state[v] == 1:
                if 2 / nb_size <= acoef <= 3 / nb_size:
                    state = 1
                    color = "white"
                else:
                    state = 0
                    color = "black"

            elif g.vp.state[v] == 0:
                # if (acoef == 3/nb_size):
                if 2 / nb_size <= acoef <= 4 / nb_size:
                    state = 1
                    color = "white"
                else:
                    state = 0
                    color = "black"
            
            alterations.append([v, state, color])
            states.append(state)
            colors.append(color)

    ###some checks
    #print(vertices)
    diff = len(to_remove)
    if diff >= 1:
        print(f"diff {diff}, count {count}") #this eventually results in something ≠ 0, I still haven't find out why 
    ###
        
    for (v, new_state, new_color) in alterations:
        g.vp.state[v] = new_state
        g.vp.color[v] = new_color


    gt.sfdp_layout(
        g, pos=g.vp.pos, eweight=g.ep.weight, max_iter=1, init_step=0.01, K=0.5
         )

    g.remove_vertex(to_remove) 

    count += 1

    win.graph.regenerate_surface()
    win.graph.queue_draw()
    
    if OFFSCREEN:
        pixbuf = win.get_pixbuf()
        pixbuf.savev(r'./frames/graphol%06d.png' % count, 'png', [], [])

    if count >= max_count:
        sys.exit(0)

    return True
Sam Joshua
  • 310
  • 6
  • 17
izzorts
  • 106
  • 6

0 Answers0