如何修复matplotlib中不在多线程环境中工作的FuncAnimation?

2024-09-25 06:24:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个python 2.7代码,不同的线程并行运行。带有matplotlib动画的线程正在显示一个黑屏。我需要有关修复代码中动画位置的帮助

我尝试在线程外使用FuncAnimation的绘图函数,它在随机数据中工作得非常好。 此外,如果没有FuncAnimation,使用简单的plot命令,一切都正常,但速度太慢,这就是为什么我想在代码中使用FuncAnimation的原因。 runGraph(threadName,sleepTime)运行一次并调用updateG(frame)一次

import os
from time import sleep, strftime
from math import tan, pi
from threading import Thread
import matplotlib.pyplot as plt #1.55 SECONDS
from matplotlib.animation import FuncAnimation
import GPS_USB_Controller

graphX=[] 
graphY=[]
last_received = ''
cnt=0
frame=0
initial_y=0
initial_x=0
exitapp = False
GPS_USB_Controller.start_gps()
plt.ion()
Xper_last=0 
Yper_last=0
ix=0
iy=0

fig=0
ax=0
ln=0

cnt=0

fig,ax=plt.subplots(1,1)
ln, = plt.plot([], [], 'ro')
plt.show()


def GPS_fix():

    try:
        while (GPS_USB_Controller.gpsc.gpsd.fix.mode != 3):
            print "Waiting for GPS Fix.  GPS mode:",GPS_USB_Controller.gpsc.gpsd.fix.mode, "Satellites:", GPS_USB_Controller.gpsc.satellites
        #1 - no fix, 2 - 2D fix, 3 - 3D fix

    except KeyboardInterrupt:
        #print "GPS fix acquired."
        sleep(1)
        pass  

def zeroLevel():
    i=0
    global initial_x
    global initial_y
    global Xper_last
    global Yper_last
    buffer_string = ''    
    last_received = ''    

    while (i < 100):
        buffer_string = buffer_string + ser.read(ser.inWaiting())
        if '\n' in buffer_string:
            lines = buffer_string.split('\n') # Guaranteed to have at least 2 entries
            last_received = lines[-2]
            buffer_string = lines[-1]
            ##print last_received         
        response = last_received
        if (response.count(";")) == 3: #Y; X; Heading; from IMU
            current_values=response.split(';')
            current_values.pop()           

            initial_x=tan(float(current_values[2])*(pi/180))*100 #convert degrees to radians to percent
            initial_y=tan(float(current_values[1])*(pi/180))*100

            Xper_last=initial_x
            Yper_last=initial_y  

            #print ("Initial X:" + str(initial_x) +", Initial Y: "+ str(initial_y))
            i=i+1 
            ##print i            
        else:
            print "Not all initialization data recieved - retrying"
    print "Level initialization complete"

GPS_fix ()

#Calibrate level
##print "Total Time", total
print "Enter the current percent cross slope (X)"
userX = input()
print "Enter the current percent running slope (Y)"
userY = input()
zeroLevel ()

def initG():
    global ax,fig,ln
    ax.set_xlim(-15,15)
    ax.set_ylim(-15, 15)
    return ln,
def runLevel(threadName, sleepTime):
    ser.flushInput() 
    global Xper
    global Yper
    global last_received
    global Xper_last
    global Yper_last
    Xper=initial_x
    Yper=initial_y
    buffer_string = ''  
    global ix
    global iy


    while not exitapp:
        sleep(sleepTime)
        buffer_string = buffer_string + ser.read(ser.inWaiting())
        if '\n' in buffer_string:
            lines = buffer_string.split('\n') # Guaranteed to have at least 2 entries
            last_received = lines[-2]
            buffer_string = lines[-1]
            ##print last_received         

        response = last_received

        if (response.count(";")) == 3: #check if recieved time; Y; X; and Heading; from IMU-time removed
            current_values=response.split(';')
            current_values.pop()

            current_x=tan(float(current_values[2])*(pi/180))*100 #convert degrees to radians to percent
            current_y=tan(float(current_values[1])*(pi/180))*100

            Xper_actual=round((userX-initial_x)+current_x,2)
            Yper_actual=round((userY-initial_y)+current_y,2)
            Zper=round(float(current_values[0]),2)

            Xchange=abs(Xper_last-Xper_actual)
            Ychange=abs(Yper_last-Yper_actual)

            if (ix>4):
                Xper=Xper_actual
                ix=0
            elif (Xchange > 3):
                Xper=Xper_last
                ix=ix+1
            else:
                Xper=Xper_actual
                ix=0

            if (iy>4):
                Yper=Yper_actual
                iy=0                  
            elif (Ychange > 3):
                Yper=Yper_last
                iy=iy+1              
            else:
                Yper=Yper_actual    
                iy=0

            Xper_last=Xper
            Yper_last=Yper            

            matrixwritecommand([0x58]) #clear screen
            matrixwritecommand([0x47,1,1])
            ser_lcd.write("Cross:   "+str(Xper)+"%")#cross slope
            matrixwritecommand([0x47,1,2])
            ser_lcd.write("Running: "+str(Yper)+"%")#running slope
            database_stuff.log_data (GPS_USB_Controller.gpsc.fix.latitude, GPS_USB_Controller.gpsc.fix.longitude, Xper, Yper, Zper, "n/a", "n/a")            
        else:
            print "Data error"

def isnan(value):
    try:

        import math
        return math.isnan(float(value))
    except:

        return False

def updateG(frame):
    global Xper,Yper,graphX,graphY,cnt,isnan

    if(not isnan(Xper)):
        graphX.append(Xper) 
        graphY.append(Yper)  
    print("----------------")
    print(graphX)
    print(graphY)
    print("----------------")
    ln.set_data(graphX, graphY)
    if(cnt>=50):
        graphX.pop(0)                       
        graphY.pop(0)
        cnt=0
    return ln,

def runGraph(threadName, sleepTime):
    global fig,ax,ln,cnt,updateG,initG,Xper
    print("graph running")

    ani = FuncAnimation(fig, updateG, frames=int(Xper), init_func=initG, blit=True, interval=0)
    print(ani)
    plt.show()

def runGPS(threadName, sleepTime):
    while not exitapp:
        sleep(sleepTime)
        GPS_USB_Controller.print_gps()

if __name__ == '__main__':
    try:
        fig,ax=plt.subplots(1,1)
        ln, = plt.plot([], [], 'ro')
        plt.show()
        t1=Thread(target=runLevel, args=("Level", 0))
        t2=Thread(target=runGPS, args=("GPS", .5))
        t4=Thread(target=runGraph, args=("Graph", .5))
        t1.daemon=True
        t2.daemon=True
        t4.daemon=True
        t1.start()
        t2.start()
        t4.start()
        while True:
            sleep(.5)

    except KeyboardInterrupt:  #Ctrl C or Ctrl D
        exitapp=True
        lcdflash()
        matrixwritecommand([0x47,1,1])
        ser_lcd.write("Cancelled       ")

    except:
        lcdflash()
        matrixwritecommand([0x47,1,1])
        ser_lcd.write("ERROR           ")
        exitapp=True
        raise

    finally:
        GPS_USB_Controller.gpsc.stopController()
        GPS_USB_Controller.gpsc.join()
        t1.join()
        t2.join()
        t4.join()
        database_stuff.create_csv()
        matrixwritecommand([0x47,1,2])
        ser_lcd.write("CSV File Created")
        matrixwritecommand([0x46])

我没有得到任何错误或警告,只是一个黑色的matplotlib窗口,不应该是这样。matplotlib屏幕应显示实时图形


Tags: stringifbuffercurrentfixglobalsergps