相关文章推荐

在一个线程内绘图并更新它(python)

0 人关注

我正面临一个在Python中使用多线程的问题。让我介绍一下背景,我正试图从示波器中读取数值,并实时绘制直方图。但问题是实时绘图使我的测量变得非常慢。

所以我想在一个线程中读取示波器的值,然后在另一个线程中绘制柱状图--这应该可以解决速度慢的问题。因为我是Python的初学者,我遇到了很多错误。

This is my code I wrote:

    import time
    import matplotlib.pyplot as plt
    import numpy as np
    from matplotlib.ticker import PercentFormatter
    from numpy.core.shape_base import block
    import pyvisa
    import os
    from matplotlib.pyplot import  figure, step
    from scipy.signal import find_peaks
    import queue
    import threading
    def acquisition(queue, name):
        rm = pyvisa.ResourceManager()
        rta = rm.open_resource('TCPIP::192.168.100.101::INSTR')
        path='Desktop/Laboratorio/Programacion- 
        Automatizacion/Pyvisa/Output/'
        rta.write("MEASurement1:TIMeout:AUTO")
        valuep = []
        aux = 0
        #Comprobamos que no existen ya esos ficheros
        if os.path.isfile(path + name + '.txt'):
            os.remove(path + name + '.txt') 
        if os.path.isfile(path + name + '.png'):
            os.remove(path + name + '.png') 
        start_time = time.time()
        entries=1000
        gain=0  
        completed = 0
        while len(valuep) < entries:
            if rta.query("*OPC?"):
                p1=float(rta.query("CURSor1:Y1Position?"))
            if rta.query("*OPC?"):
                p2=float(rta.query("CURSor1:Y2Position?"))
            r=(p1-p2)
            valuep.append(r)
            a = np.array(valuep)
            completed = len(valuep)/entries*100
            print(str(completed) + ' %\n')
            hist, bin_edges = np.histogram(a, 300)
            bin_edges = bin_edges[1:]
            peaks, _ = find_peaks(hist, distance=10, prominence=10)
            sumDelta = 0
            if len(peaks) >= 2:
                sumDelta = 0
                for i in range(len(peaks)-1):
                    deltaV=bin_edges[peaks[i+1]]-bin_edges[peaks[i]]
                    sumDelta += deltaV
                    gain=(sumDelta/(len(peaks)-1))/(50*1.602e-19)
            if completed == 10 or completed == 20 or completed == 30 or 
            completed == 40 or completed == 50 or completed == 60 or 
            completed == 70 or completed == 80 or completed == 90 or 
            completed == 100:
                auxLen = np.arange(0 , len(valuep) , 1)
                with open(path + name + '.txt', 'w') as f:
                    f.write(str(gain) + ' | ' + str(round((time.time() - 
                    start_time)/60, 3)) + '\n')
                    for i in auxLen:
                        f.write(str(valuep[i]))
                        f.write('\n')
            message = a
            queue.put(message)
        rta.close()
    def histogram(queue, name):
        while True:
            message = queue.get()
            plt.cla()
            # plt.xlabel("Vs | %=" + str(round(len(valuep)/entries*100, 3)) + " | Time: " + str(round((time.time() - start_time)/60, 3)) + " min")
            plt.ylabel("Bins")
            plt.yscale('log')
            hist, bin_edges = np.histogram(message, 300)
            bin_edges = bin_edges[1:]
            plt.plot(bin_edges, hist)
            # plt.plot(bin_edges[peaks], hist[peaks], "x")
            plt.show()
            plt.tight_layout()
    if __name__ == "__main__":
        print('Input code name: ')
        name = input()
        q = queue.Queue()
        acquire = threading.Thread(target=acquisition, args=(q, name,))
        hist = threading.Thread(target=histogram, args=(q, name,))
        acquire.start()
        hist.start()
        acquire.join()
        hist.join()
        q.join()
        plt.plot()

该函数acquire从示波器中读取数值,并以numpy数组的形式返回到队列中。

The error is:

UserWarning: Starting a Matplotlib GUI outside of the main thread will likely fail.

我真的很感谢你的帮助和任何意见,我应该如何进行。请提前感谢。

这是我起初的代码。

#librerias
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import PercentFormatter
import pyvisa
import time
import os
from itertools import count
from matplotlib.animation import FuncAnimation
from matplotlib.pyplot import  figure, step
from scipy.signal import find_peaks
#Abrir sesion VISA
rm = pyvisa.ResourceManager()
rta = rm.open_resource('TCPIP::192.168.100.101::INSTR')
print('Input code name: ')
name=input()
path='Desktop/Laboratorio/Programacion-Automatizacion/Pyvisa/Output/'
rta.write("MEASurement1:TIMeout:AUTO")
rta.write("SYSTem:COMMunicate:INTerface:ETHernet:TRANsfer FD100")
rta.write("FORM BIN") # // Set BIN data format
valuep = []
aux = 0
#Comprobamos que no existen ya esos ficheros
if os.path.isfile(path + name + '.txt'):
    os.remove(path + name + '.txt') 
if os.path.isfile(path + name + '.png'):
    os.remove(path + name + '.png') 
start_time = time.time()
def animate(i):
    global aux
    entries=1000
    gain=0  
    if rta.query("*OPC?"):
        p1=float(rta.query("CURSor1:Y1Position?"))
    if rta.query("*OPC?"):
        p2=float(rta.query("CURSor1:Y2Position?"))
    r=(p1-p2)
    valuep.append(r)
    a = np.array(valuep)
    plt.cla()
    plt.xlabel("Vs | %=" + str(round(len(valuep)/entries*100, 3)) + " | Time: " + str(round((time.time() - start_time)/60, 3)) + " min")
    plt.ylabel("Bins")
    plt.yscale('log')
    hist, bin_edges = np.histogram(a, 300)
    bin_edges = bin_edges[1:]
    plt.plot(bin_edges, hist)
    peaks, _ = find_peaks(hist, distance=10, prominence=10)
    sumDelta = 0
    if len(peaks) >= 2:
        sumDelta = 0
        for i in range(len(peaks)-1):
            deltaV=bin_edges[peaks[i+1]]-bin_edges[peaks[i]]
            sumDelta += deltaV
        gain=(sumDelta/(len(peaks)-1))/(50*1.602e-19)
        #print(gain)
    plt.plot(bin_edges[peaks], hist[peaks], "x")
    plt.show()
    plt.tight_layout() 
    #Escritura fichero CSV
    if len(valuep) == entries:
        auxLen = np.arange(0 , len(valuep) , 1)
        with open(path + name + '.txt', 'w') as f:
            f.write(str(gain) +'\n')
            for i in auxLen:
                f.write(str(valuep[i]))
                f.write('\n')
        plt.savefig(path + name + '.png')
ani = FuncAnimation(plt.gcf(), animate, interval=0.013)
plt.tight_layout()
plt.show()
rta.close()

这段代码和我想的一样,但是非常非常慢,我说用aniFunction绘图,15000次采集需要96分钟,而不用anifunc,30000次采集需要26分钟,这就是为什么我尝试用线程。

5 个评论
明天我将做一个 "def acquisition "的例子,把它发送给一个朋友,以便在没有范围的情况下进行复制,然后我将用这个代码进行编辑。
Kris
UserWarning实际上不是一个错误,它说它可能失败。但你所面临的问题是什么?
@kris, 嗨,Kris,情节正在实现,但没有实时更新,你说这个警告不是一个重要的问题吗?你知道我怎么能在这里使用aniFunction吗?非常感谢你编辑我的英语和评论。
Kris
你能公布完整的代码吗?我不清楚你是否需要最后加入所有线程和情节。我认为,你还应该考虑多进程的可能性,而不是多线程,因为它对性能的提高不大。
@Kris 我可以上传我第一个运行缓慢的代码,以及我现在的代码吗?还是说这是一个很大的问题?
python
python-3.x
1 个回答
已采纳
0 人赞同

好了,我已经把它修好了。我已经使用了。

warnings.filterwarnings("忽略")。

为警告和。

ani = FuncAnimation(plt.gcf(), animate, interval=0.013)

来制作像以前一样的动画。 现在我有一个问题,就是检查队列是否为空,如果我使用。

 
推荐文章