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

效果图:

 

先上完整代码

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
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Matplotlib可以嵌入Tkinter,实现在Tkinter窗口中显示Matplotlib图形。具体步骤如下: 1. 导入TkinterMatplotlib库 2. 创建Tkinter窗口 3. 创建Matplotlib图形 4. 将Matplotlib图形嵌入Tkinter窗口中 5. 运行Tkinter主循环 示例代码如下: ```python import tkinter as tk from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.figure import Figure # 创建Tkinter窗口 root = tk.Tk() root.title("Matplotlib in Tkinter") # 创建Matplotlib图形 fig = Figure(figsize=(5, 4), dpi=100) ax = fig.add_subplot(111) ax.plot([1, 2, 3, 4, 5], [2, 3, 5, 4, 6]) # 将Matplotlib图形嵌入Tkinter窗口中 canvas = FigureCanvasTkAgg(fig, master=root) canvas.draw() canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) # 运行Tkinter主循环 tk.mainloop() ``` 运行以上代码,即可在Tkinter窗口中显示Matplotlib图形。 ### 回答2: Matplotlib是一个非常强大的Python绘图库,它可以用来绘制各种图形,包括折线图、散点图、饼图、直方图等等。而Tkinter是Python自带的一个GUI库,可以用来创建GUI应用程序,包括窗口、按钮、标签和文本框等等。 在Python中,我们可以将Matplotlib集成到Tkinter应用程序中,实现可视化图形的交互。这个过程中需要使用到Matplotlib的子模块TkAgg(TkAgg:Tcl/Tk Agg backend,是指将Matplotlib绘制的图形放置在Tkinter应用程序的Canvas组件中)及matplotlib.backends.backend_tkagg。 具体实现步骤如下: 1. 导入相关库,包括MatplotlibTkinter和numpy。 2. 建立main窗口。 3. 创建一个matplotlib图形,将其放置在Tkinter窗口中。 4. 启动Tkinter的事件循环,以响应控件的事件和用户的交互。 代码示例: ``` import tkinter as tk from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.figure import Figure import numpy as np #建立主窗口 root = tk.Tk() root.title("Matplotlib Embedding in Tkinter") #建立一个1x1图形,并在其中添加subplot fig = Figure(figsize = (5, 5), dpi = 100) ax = fig.add_subplot(111) #生成100个随机数的Numpy数组 x = np.arange(0, 100) y = np.random.normal(0, 1, 100) #绘制图形 ax.plot(x, y) #创建一个Canvas并将其放置在Tkinter窗口中 canvas = FigureCanvasTkAgg(fig, master = root) canvas.draw() #将Canvas放置在Tkinter窗口中 canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) #启动Tkinter事件循环 tk.mainloop() ``` 以上代码创建了一个主窗口,并在其中添加一个1x1的图形,用Numpy随机数绘制折线图。最后,将图形的Canvas放置在Tkinter窗口中,并启动Tkinter的事件循环,以响应用户的交互。 总体来说,Matplotlib嵌入Tkinter是一种非常有用的技术,它使得我们可以在Tkinter应用程序中轻松地添加可视化图形,并快速地与用户进行交互。 ### 回答3: Matplotlib是一款强大的用于绘制图形的Python库,而Tkinter则是Python的标准GUI库。将这两者结合起来,可以在Tkinter应用程序中嵌入Matplotlib图形并将其显示出来。这对于需要实现数据可视化的应用程序非常有用。 使用Matplotlib嵌入Tkinter,需要使用FigureCanvasTkAgg类。该类可将Matplotlib图形绘制到Tkinter画布上。首先需要导入必要的模块: ```python import matplotlib import tkinter as tk from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.figure import Figure ``` 然后,可以创建一个Tkinter窗口和一个Matplotlib图形,并将图形绘制到Tkinter画布上: ```python root = tk.Tk() root.title("Matplotlib with Tkinter") # 创建一个Matplotlib图形 fig = Figure(figsize=(5, 4), dpi=100) ax = fig.add_subplot(111) ax.plot([0,1,2,3,4],[10,1,20,3,40]) # 创建一个Tkinter画布,并将Matplotlib图形绘制到该画布上 canvas = FigureCanvasTkAgg(fig, master=root) canvas.draw() canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) # 启动Tkinter事件循环 tk.mainloop() ``` 这段代码首先创建了一个Tkinter窗口,然后创建了一个Matplotlib图形并将其绘制到画布上。最后,启动了Tkinter事件循环,显示窗口和图形。 除了绘制图形,还可以通过将Matplotlib图形封装在Tkinter框架中来实现用户与图形的交互。例如,可以轻松地添加按钮和滑块来更改图形参数,并实时更新Matplotlib图形。这为定制化的绘图提供了极大的灵活性。 总之,Matplotlib嵌入Tkinter是Python中实现数据可视化的一种强大的方法,通过将两种库结合起来,我们可以创建强大的应用程序来探索、分析和可视化数据

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值