tkinter+matplotlib实现示波器效果,动态显示汽车数据

       最近研究汽车的can数据,想实时显示油门刹车转向灯量的图形,搞了好久,总是不能做到实时,都放弃了,一天看到了一片文章:能实时显示音波数据,而且代码就几十行,于是拿来运行,效果不错。代码放在下面。

# -*- coding: utf-8 -*-
"""
Created on Tue Mar 24 10:48:07 2015
@author: Administrator
"""


import pyaudio
import Tkinter as tk
import wave
import threading
import Queue as queue
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib.lines as line
import numpy as np
from scipy import fftpack
from scipy import signal


CHUNK = 102400
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"
data =[]
Recording=False
FFT_LEN = 128
frames=[]
counter=1


#GUI
class Application(tk.Frame):
    def __init__(self,master=None):
        tk.Frame.__init__(self,master)
        self.grid()
        self.creatWidgets()


    def creatWidgets(self):
        self.quitButton=tk.Button(self,text='quit',command=root.destroy)
        self.quitButton.grid(column=1,row=3)




#Matplotlib
fig = plt.figure()
rt_ax = plt.subplot(212,xlim=(0,CHUNK), ylim=(-10000,10000))
fft_ax = plt.subplot(211)
fft_ax.set_yscale('log')
fft_ax.set_xlim(0,CHUNK/2 + 1)
fft_ax.set_ylim(1,100000000)
rt_ax.set_title("Real Time")
fft_ax.set_title("FFT Time")
rt_line = line.Line2D([],[])
fft_line = line.Line2D([],[])


rt_data=np.arange(0,CHUNK,1)
fft_data=np.arange(0,CHUNK/2 + 1,1)
rt_x_data=np.arange(0,CHUNK,1)
fft_x_data=np.arange(0,CHUNK/2 + 1,1)


def plot_init():
    rt_ax.add_line(rt_line)
    fft_ax.add_line(fft_line)
    return fft_line,rt_line,
    
def plot_update(i):
    global rt_data
    global fft_data
    
    rt_line.set_xdata(rt_x_data)
    rt_line.set_ydata(rt_data)
    
    fft_line.set_xdata(fft_x_data)
    fft_line.set_ydata(fft_data)
    return fft_line,rt_line,




ani = animation.FuncAnimation(fig, plot_update,
                              init_func=plot_init, 
                              frames=1,
                              interval=30,
                              blit=True)




# pyaudio
p = pyaudio.PyAudio()
q = queue.Queue()


def audio_callback(in_data, frame_count, time_info, status):
    global ad_rdy_ev


    q.put(in_data)
    ad_rdy_ev.set()
    if counter <= 0:
        return (None,pyaudio.paComplete)
    else:
        return (None,pyaudio.paContinue)




stream = p.open(format=FORMAT,
        channels=CHANNELS,
        rate=RATE,
        input=True,
        output=False,
        frames_per_buffer=CHUNK,
        stream_callback=audio_callback)




if Recording:
    wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
    wf.setnchannels(CHANNELS)
    wf.setsampwidth(p.get_sample_size(FORMAT))
    wf.setframerate(RATE)


print("Start Recording")
stream.start_stream()


#processing block


window = signal.hamming(CHUNK)


def read_audio_thead(q,stream,frames,ad_rdy_ev):
    global rt_data
    global fft_data


    while stream.is_active():
        ad_rdy_ev.wait(timeout=1000)
        if not q.empty():
            #process audio data here
            data=q.get()
            while not q.empty():
                q.get()
            rt_data = np.frombuffer(data,np.dtype('<i2'))
            #rt_data = rt_data * window
            fft_temp_data=fftpack.fft(rt_data,rt_data.size,overwrite_x=True)
            fft_data=np.abs(fft_temp_data)[0:int(fft_temp_data.size/2+1)]
            if Recording :
                frames.append(data)
        ad_rdy_ev.clear()


ad_rdy_ev=threading.Event()


t=threading.Thread(target=read_audio_thead,args=(q,stream,frames,ad_rdy_ev))


t.daemon=True
t.start()


plt.show()
root=tk.Tk()
app=Application(master=root)
app.master.title("Test")
app.mainloop()


stream.stop_stream()
stream.close()
p.terminate()


print("* done recording")
if Recording:
    wf.writeframes(b''.join(frames))
    wf.close()


    我怎么使用它呢?他这个代码是没有与tkinter结合的,我放到我们的tkinter代码里,发现animation不能用,于是又网搜,找到了方案,ax必须放在tkinter控件创建完毕后才能创建,从而animation才能起作用。后来又遇到多线程导致程序崩溃的问题。发现不能在多个线程做gui更新,于是把gui操作放在动画的每一帧里做,问题解决,用了全局量,虽然不喜欢但是工作正常,也就不深究了。现在实时效果很好。

要在tkinter实现matplotlib,需要使用matplotlib的FigureCanvasTkAgg类。首先,导入必要的库,包括tkinter以及FigureCanvasTkAgg和matplotlib.pyplot。然后,创建一个tkinter窗口,并在其中添加一个画布。接下来,将matplotlib的图形对象绘制在画布上,然后使用pack()或grid()等方法将画布显示在窗口上。最后,使用mainloop()方法启动窗口的事件循环,以保持窗口的显示。以下是一个示例代码: ```python import tkinter as tk from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg import matplotlib.pyplot as plt # 创建tkinter窗口 window = tk.Tk() # 创建一个画布 canvas = tk.Canvas(window, width=400, height=400) canvas.pack() # 创建一个matplotlib图形对象 fig, ax = plt.subplots() ax.plot([1, 2, 3, 4, 5], [1, 4, 9, 16, 25]) # 创建一个FigureCanvasTkAgg对象,并将图形对象绘制在画布上 canvas_widget = FigureCanvasTkAgg(fig, canvas) canvas_widget.draw() # 将画布显示在窗口上 canvas_widget.get_tk_widget().pack() # 启动窗口的事件循环 window.mainloop() ``` 这样就可以在tkinter窗口中显示matplotlib绘制的图形了。注意,需要安装相应的库才能运行上述代码。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [tkinter 显示matplotlib绘图](https://blog.csdn.net/qq_33267306/article/details/125587834)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Python+mysql+tkinter+matplotlib的可视化学生成绩管理系统课程设计](https://blog.csdn.net/m0_56604317/article/details/128473414)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [利用Tkintermatplotlib两种方式画饼状图的实例](https://download.csdn.net/download/weixin_38717450/13770205)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值