1

The next code is to animate with matplotlib.FuncAnimation

def animate(i):
    x_val = changing_list
    y_val = another_changing_list
    plt.cla()
    plt.scatter(x_val, y_val)

ani = animation.FuncAnimation(plt.gcf(), animate, interval =1000)
plt.show()

What I want to know is how to run that animation simultaneously with a loop like this:

for value in values_list:
    changing_list.append(value)

Such that the result is an animation that shows, immediately, the new values in the changing_list list.

I'd appreciate any help!

4

1 Answer 1

0

not sure its what you era asking for, pretty sure is not the best way :

attempt 1:

import time
from threading import Thread, Event, Lock

import matplotlib.pyplot as plt

import matplotlib.animation as animation



from random import randint





changing_list = []

another_changing_list = []

values_list = [randint(0,i) for i in range(1,99)]

a = list(zip(changing_list, another_changing_list))


leng_start = len(changing_list)

lock = Lock()

evt = Event()

def loop_thread(values_list, changing_list, another_changing_list):
    
    global a

    t = 2
    while True:
        
        for value in values_list:
            
            if not evt.is_set():
             
                # print('is not set')
                
                pass
             
             
            if evt.is_set():
             
                print('is set')
                
                break
            
            lock.acquire()
            
            changing_list.append(values_list[randint(0,len(values_list)-1)])
                
            another_changing_list.append(values_list[randint(0,len(values_list)-1)])
                
                
            a = list(zip(changing_list, another_changing_list))
                
            lock.release()    
                
            time.sleep((t))
                
            # print(a)
            # sys.stdout.flush() 
            
            
            
        break
                
    print('exit thread')
    
                
def init_animate():
    pass

cnt = 0        
pippo = None      
def animate(j):
    
    global pippo 
    global cnt
    global leng_start
    global a
    global changing_list
    global another_changing_list
    
    if len(changing_list) != leng_start:
        
        leng_start = len(changing_list)
        
        if pippo:
            pippo.remove()
        
        # print('leng_start : after ', leng_start, ' chan :' ,len(changing_list))
        
        if (cnt % 2) == 0:
            col = 'red'
        else:
            col = 'blue'
        
        cnt += 1
    
        pippo = axe.scatter(changing_list,another_changing_list, color = col)
     
        # print(a[-1][0], a[-1][1],'len a ; ', len(a), ' j : ',j)
    

fig = plt.figure()  
axe = fig.add_subplot(111)


thread_1 = Thread(target=loop_thread, args=(values_list, changing_list, another_changing_list))

thread_1.start()




animat = animation.FuncAnimation(fig, animate, init_func=init_animate,
                              interval=1000, repeat = False)
    
plt.show()

    



evt.set()

print('plt.show() closed')

attempt 2 tries to animate without using animation.FuncAnimation, each scatter in a loop , but goes easily out of synchro, just counts the dots after they get to 4 or 5:

import gc

import time
from threading import Thread, Event, Lock

import matplotlib.pyplot as plt

from random import randint



# changing_list = [1,2,3]
# another_changing_list = [8,7,99]


gc.collect()

changing_list = []

another_changing_list = []



values_list = [randint(0,i) for i in range(1,99)]

a = list(zip(changing_list, another_changing_list))


lock = Lock()

lock2 = Lock()

evt = Event()

evt2 = Event()


pippo = None

def plotting_thread(fig, axe):
    
    global a
    global pippo
    global changing_list
    global another_changing_list
    

    
    leng_start = len(changing_list)
    
    # print('leng_start :', leng_start)
    

    cnt = 0
    while True: 
        
        lock.acquire()
        time.sleep(0.5)
        
        if not evt.is_set():
            
            # print('is not set')

            # print('leng_start before if : ', leng_start)
            
            if len(changing_list) != leng_start:
                
                leng_start = len(changing_list)
                
                # print('leng_start : after ', leng_start, ' chan :' ,len(changing_list))
                
                if (cnt % 2) == 0:
                    col = 'red'
                else:
                    col = 'blue'
                    
                cnt += 1
                
                # print(col)
                

                
                axe.clear()
                
                for i in range(len(changing_list)-1):
                    
                    time.sleep(1)
                    
                    axe.scatter( changing_list[i], another_changing_list[i], color=col)
                
                    fig.canvas.draw_idle() 
                
                    # plt.draw()   ### works too ?

                 
        if evt.is_set():
                 
            print('is set plotting')
                    
            break

        
        
        lock.release()
     
    




def loop_thread(values_list):
    
    global a
    global changing_list
    global another_changing_list

    while True:
        t = 2
        time.sleep((t))
        lock2.acquire()
        
            
        if not evt2.is_set():
             
                # print('is not set')
                
                changing_list.append(values_list[randint(0,len(values_list)-1)])
                    
                another_changing_list.append(values_list[randint(0,len(values_list)-1)])
                
                a = list(zip(changing_list, another_changing_list))
             
             
        if evt2.is_set():
             
                print('is set loop_thread')
                
                break
            
                
            
                
        # print(a)
        # print(changing_list)
        # print(another_changing_list)
        lock2.release()
  
                
    print('exit thread')
    
                


fig = plt.figure()  # the figure will be reused later
axe = fig.add_subplot(111)

thread_1 = Thread(target=loop_thread, args=((values_list,)))

thread_2 = Thread(target=plotting_thread, args=(fig, axe))

thread_1.start()

thread_2.start()





plt.show()

evt.set()

evt2.set()

print('plt.show() closed')


EDITED: code above works fine using:

t = 2
    while True:
        t +=1
        time.sleep((t))
        lock2.acquire()

in loop_thread so that at each iteration animation as more time to complete

Read somewhere that animation.FuncAnimation has to be in main thread. Wasnt able to put it in a while loop to animate each series out of the 'add+1 element to serie' loop using animation.FuncAnimation.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.