matplotlib画图嵌入tkinter界面并动态更新

该博客展示了如何使用Python的Tkinter库创建一个主界面,并结合matplotlib进行实时数据更新。程序中包含两个定时器,一个用于生成模拟数据,另一个用于更新效率与真空度的图表。同时,提供了配置界面,允许用户输入特定设置。博客重点讨论了Tkinter与matplotlib的集成以及交互式数据展示的方法。
摘要由CSDN通过智能技术生成

效果图:

 

先上完整代码

import tkinter
import random
import tkinter as tk
import tkinter.font as tkFont
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
 
 
def generate_data():
    global vacuum, efficiency, vacuumHisList, effiHisList
    vacuum = random.uniform(-1, 0)
    efficiency = random.uniform(30, 100)
    vacuumHisList.append(vacuum)
    effiHisList.append(efficiency)
    if len(vacuumHisList) > 15:
        vacuumHisList.pop(0)
        effiHisList.pop(0)
 
    root.after(1000, generate_data)
 
def plot_efffi_vacuum():
    global vacuum, efficiency, vacuumHisList, effiHisList, fig1
 
    fig1.clf()  # 清除上一帧内容
 
    g11 = fig1.add_subplot(2, 1, 1)
    g11.plot(vacuumHisList, effiHisList, c='lawngreen')
    g11.scatter(vacuum, efficiency, c="yellow", s=30)
    g11.set_xlim([-1, 1])
    g11.set_ylim([20, 100])
    g11.set_xlabel("vacuum bar")
    g11.set_ylabel("effi %")
    g11.patch.set_facecolor('whitesmoke')
 
    g12 = fig1.add_subplot(2, 1, 2)
    g12.set_xlim([0, 120])
    g12.set_ylim([-20, 20])
    g12.set_xlabel('time s')
    g12.set_ylabel('angle deg')
    g12.patch.set_facecolor('whitesmoke')
 
    canvas.draw()
 
    root.after(1000, plot_efffi_vacuum)
 
 
def plot_fpcurve():
    pass
 
 
def plot_vacuum():
    pass
 
 
def plot_visor_angle():
    pass
 
 
def write_spc_set(x, y):
    print(x, y)
 
 
def spc_set_window():
    spc_window = tk.Toplevel()
    spc_window.title("spc set")
    spc_window.geometry("250x200")
 
    label = tk.Label(spc_window, text="Kd: ", anchor='e')
    label.place(x=0, y=0, width=80, height=30)
    text = tk.Text(spc_window, font=tkFont.Font(size=16))
    text.tag_configure("tag_name", justify='center')
    text.place(x=80, y=0, width=100, height=30)
 
    label1 = tk.Label(spc_window, text="折算系数: ", anchor='e')
    label1.place(x=0, y=50, width=80, height=30)
    text1 = tk.Text(spc_window, font=tkFont.Font(size=16))
    text1.tag_configure("tag_name", justify='center')
    text1.place(x=80, y=50, width=100, height=30)
 
    spc_confirm_btn = tk.Button(spc_window, text="Confirm", font=tkFont.Font(size=16),
                                command=lambda: write_spc_set(text.get('0.0', 'end')[:-1],
                                                              text1.get('0.0', 'end')[:-1])) #用lambda函数获取传入的参数,get 方法获取text中内容,-1去掉换行符
    spc_confirm_btn.place(x=80, y=100, width=100, height=30)
 
 
def avc_set_window():
    avc_window = tk.Toplevel()
    avc_window.title("avc set")
    avc_window.geometry("250x200")
 
    label = tk.Label(avc_window, text="真空高值: ", anchor='e')
    label.place(x=0, y=0, width=80, height=30)
    text = tk.Text(avc_window, font=tkFont.Font(size=16))
    text.tag_configure("tag_name", justify='center')
    text.place(x=80, y=0, width=100, height=30)
 
    label1 = tk.Label(avc_window, text="真空低值: ", anchor='e')
    label1.place(x=0, y=50, width=80, height=30)
    text1 = tk.Text(avc_window, font=tkFont.Font(size=16))
    text1.tag_configure("tag_name", justify='center')
    text1.place(x=80, y=50, width=100, height=30)
 
    spc_confirm_btn = tk.Button(avc_window, text="Confirm", font=tkFont.Font(size=16),
                                command=lambda: write_spc_set(text.get('0.0', 'end')[:-1],
                                                              text1.get('0.0', 'end')[:-1])) #用lambda函数获取传入的参数,get 方法获取text中内容,-1去掉换行符
    spc_confirm_btn.place(x=80, y=100, width=100, height=30)
 
 
# 定义全局变量
vacuum = 0
efficiency = 0
vacuumHisList = []
effiHisList = []
 
# 创建tkinter主界面
root = tk.Tk()
root.title("smart controller")
root.geometry("800x450+0+0")
root.configure(bg="gainsboro")
# 创建button
button_spc = tk.Button(root, text="spc设置", command=spc_set_window)
button_spc.place(x=0, y=0, width=100, height=30)
button_avc = tk.Button(root, text="avc设置", command=avc_set_window)
button_avc.place(x=100, y=0, width=100, height=30)
 
# 创建一个容器用于显示matplotlib的fig
frame1 = tk.Frame(root, bg="gainsboro")
frame1.place(x=0, y=30, width=800, height=600)
# 解决matplot中文显示乱码
plt.rcParams['font.sans-serif'] = ['SimHei']  # 防止中文标签乱码,还有通过导入字体文件的方法
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['lines.linewidth'] = 1  # 设置曲线线条宽度
# 创建画图figure
fig1 = plt.figure(figsize=(4, 4))
fig1.subplots_adjust(left=0.15, right=0.9, top=0.95, bottom=0.15, wspace=0.5, hspace=0.5)
fig1.patch.set_facecolor('gainsboro')
g11 = fig1.add_subplot(2, 1, 1)
g11.set_xlim([-1, 1])
g11.set_ylim([20, 100])
g11.set_xlabel("vacuum bar")
g11.set_ylabel("effi %")
g11.patch.set_facecolor('whitesmoke')
g12 = fig1.add_subplot(2, 1, 2)
g12.set_xlim([0, 6])
g12.set_ylim([0, 4])
g12.set_xlabel('流量 m$^3$/s')
g12.set_ylabel('产量 m$^3$/s')
g12.patch.set_facecolor('whitesmoke')
# 将fig放入画布
canvas = FigureCanvasTkAgg(fig1, master=frame1)
canvas.draw()
# 将画布放进窗口
canvas.get_tk_widget().place(x=0, y=0)
# 创建第二个图
fig2 = plt.figure(figsize=(4, 4))
fig2.subplots_adjust(left=0.2, right=0.9, top=0.95, bottom=0.15, wspace=0.5, hspace=0.5)
fig2.patch.set_facecolor('gainsboro')
g21 = fig2.add_subplot(2, 1, 1)
g21.set_xlim([0, 120])
g21.set_ylim([-1, 0])
g21.set_xlabel("time s")
g21.set_ylabel("vacuum bar")
g21.patch.set_facecolor('whitesmoke')
g22 = fig2.add_subplot(2, 1, 2)
g22.set_xlim([0, 120])
g22.set_ylim([-20, 20])
g22.set_xlabel('time s')
g22.set_ylabel('angle deg')
g22.patch.set_facecolor('whitesmoke')
# 打开matplot交互模式
plt.ion()
# fig2 放入画布
canvas2 = FigureCanvasTkAgg(fig2, master=frame1)
canvas2.draw()
canvas2.get_tk_widget().place(x=420, y=0)
# 使用一个定时器计算后台数据
generate_data()
# fig更新
plot_efffi_vacuum()
plot_fpcurve()
plot_vacuum()
plot_visor_angle()
 
root.mainloop()
程序中,一个定时器用于生成数据,另一个定时器用于将数据动态显示在tkinter主界面上

首先定义需要的全局变量

vacuum = 0
efficiency = 0
vacuumHisList = []
effiHisList = []
在数据生成定时器中和更新图像定时器中,使用这些全局变量,并对数据更新

def generate_data():
    global vacuum, efficiency, vacuumHisList, effiHisList
 更新图像定时器中,还需要将fig定义为全局变量,对图像刷新

def plot_efffi_vacuum():
    global vacuum, efficiency, vacuumHisList, effiHisList, fig1
tkinter中使用after方法实现定时器效果,两个参数的含义为:1000ms后,执行generate_data子程序

root.after(1000, generate_data)
matplotlib嵌入tkinter中的步骤为:首先定义容器frame

# 创建一个容器用于显示matplotlib的fig
frame1 = tk.Frame(root, bg="gainsboro")
frame1.place(x=0, y=30, width=800, height=600)
定义fig

# 创建画图figure
fig1 = plt.figure(figsize=(4, 4))
fig1.subplots_adjust(left=0.15, right=0.9, top=0.95, bottom=0.15, wspace=0.5, hspace=0.5)
fig1.patch.set_facecolor('gainsboro')
g11 = fig1.add_subplot(2, 1, 1)
g11.set_xlim([-1, 1])
g11.set_ylim([20, 100])
g11.set_xlabel("vacuum bar")
g11.set_ylabel("effi %")
g11.patch.set_facecolor('whitesmoke')
g12 = fig1.add_subplot(2, 1, 2)
g12.set_xlim([0, 6])
g12.set_ylim([0, 4])
g12.set_xlabel('流量 m$^3$/s')
g12.set_ylabel('产量 m$^3$/s')
g12.patch.set_facecolor('whitesmoke')
定义canvas,并放入主窗口

# 将fig放入画布
canvas = FigureCanvasTkAgg(fig1, master=frame1)
canvas.draw()
# 将画布放进窗口
canvas.get_tk_widget().place(x=0, y=0)
在最后打开matplotlib交互模式

plt.ion()
def plot_efffi_vacuum():
函数实现fig刷新

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值