IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> (Python)在子线程中使用Matplotlib进行绘图(100%解决问题) -> 正文阅读

[Python知识库](Python)在子线程中使用Matplotlib进行绘图(100%解决问题)

首先

??今天在那边做一个UI界面的时候,想往里面做一个功能:“主线程上进行当前数据的监控、并将数据存入MongoDB中。当按下UI界面上的一个按钮后,创建一个子线程,让他去查MongoDB中的过往数据,并通过Matplotlib将其做成折线图进行数据可视化”。
??我想这么做的理由是:我不想在我画图、展示图片的时候,我的监控停下来,所以我想把画图、展示图片的那一部分放到另一个线程里面去,这样我主线程的数据监控就不会停下来了。
??一开始以为,这是个非常简单的事情,结果写了代码出来后发现,他爆了一个错误:

“Starting a Matplotlib GUI outside of the main thread will likely fail.”

??当时瞬间就感觉,事情不太对的样子。果然,他告诉我matplotlib只能运行在主线程里面:

“set_wakeup_fd only works in main thread”

??于是我,停止了思考(bushi
??

尝试方法1:使用multiprocessing(最后未使用)

??我开始百度,最先看到了这个方法,然后我去试了试但好像,对于我这个问题,解决不太了,效果不太好,所以就没用这个方法。当时参考的文章是这篇,感兴趣的可以自行去尝试下:https://www.it1352.com/1606767.html
??

尝试方法2:主线程中画图,然后子线程进行展示(最后未使用)

??这个思路我参考的是下面这个帖子:https://ask.csdn.net/questions/7465991
??这个的话,我当时测过后,是没啥技术问题的,我当时根据这个方法,在点击UI界面上的按钮后,先在主线程里面使用pymongo和matplotlib库把图画好后,没有使用plt.show函数,而是变成:

plt.savefig("final.png")

??之后的话,在子线程里面,通过PIL库来进行展示即可。当时我的部分代码如下:

-----------------------------------mongo.py中(这个文件是我自己写的)-----------------------------------
from PIL import Image
import threading

# 因为画图和存照片的部分在主线程里,所以这一块就只管显示图片
def draw_final():
	img=Image.open('final.png')
	img.show()

# 多线程类,主要执行的命令就是展示图片
class myDraw_final(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
	# 线程启动后,执行的操作
    def run(self):
        draw_final()

# UI界面上进行绑定的函数
def start_draw_final():
	# find_final函数就是使用matplotlib、pymongo进行数据读取、画图、存储的函数
	find_final()  # 它会把最终结果以“final.png”的形式存储到本地
	# 但上面那个函数执行的地方,并不是子线程中,而是在主线程中
	# 下面的my.start中执行的,才是在子线程里执行的命令
    my = myDraw_final()
    my.start()

-----------------------------------我的UI界面py文件中-----------------------------------
# 该按钮点击后,执行mongo.py下的start_draw_final函数
............
............
bu1 = Button(self.window, textvariable=self.st1, font=('Arial', 10), command= \
            lambda: mongo.start_draw_final())
............
 ............

??这样的话,是差不多可以实现我想要的效果的,现在是:子线程中显示结果,显示结果的时候,也不堵塞我主线程中的数据监测了,但是这样写还有一点缺陷,就是它绘图还是在我当前程序的主线程中进行的,当他数据读取、绘图、保存的时候,我主线程还是被堵塞了,数据监听中断了。只有显示的时候不堵塞。这样我觉得还是不太够的。

尝试方法3:欺诈(最终采用)

??正如开始的时候所说,我们的matplotlib只能在主线程中使用,那么我们的解决方法就是:就让他在主线程里面跑。
??这个时候你可能会说:我们方法2里面,不就是在主线程里面跑的matplotlib嘛?那我们这里的方法3和方法2有什么区别呢?
??这就不对了。方法2里面,是在我们的当前UI程序的主线程里面跑的,方法3里面,我想让matplotlib觉得自己跑在主线程里,但是其实它跑在我的UI程序的子线程里。(这感觉咋和云计算里面的虚拟化一样)
??为了实现上述的效果,我把画图、显示的那一部分,写在另一个py文件,叫做draw_final.py里面,作为那个py文件的主函数。
??然后我的UI程序里面,创造一个子线程,而这个子线程的作用,是启动draw_final.py,这样就能让matplotlib跑在它想要的主线程里面,且不影响我UI程序上数据的监测了。双赢。

??draw_final.py中的主要代码如下所示:

import matplotlib.pyplot as plt
import pymongo


# 对ori数据进行查询
def find_final():
	--- 去mongodb里面查数据 ---
	--- 用matplotlib画图 ---
	plt.show()


if __name__ == "__main__":
	find_final()

??然后是mongo.py文件,里面主要包含多线程的内容,下面为部分代码:

import threading
import os


# 调用上面画图的那个draw_final.py程序
def draw_final():
    os.system("python E:\\desktop\\net9\\draw_final.py")


# 多线程,多出来的一条线程用于调用另一个程序
class myDraw_final(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
	# 子线程用来调用那个py文件,此时,那个被调用的py文件中的程序运行在那个py文件的主线程里
	# 但是那个程序,是在我这个程序的子线程里被调用的
    def run(self):
        draw_final()


# UI窗口上的按钮与这个函数进行绑定,那个按钮按下后,创建子线程并开始执行上面那个类的run函数
def start_draw_final():
    my = myDraw_final()
    my.start()

??UI界面上的程序中,将按钮与其绑定:

# 按下按钮后,跑去执行mongo.py中的start_draw_final函数
bu1 = Button(self.window, textvariable=self.st1, font=('Arial', 10), command= \
            lambda: mongo.start_draw_final())

??通过上述的一轮阴险操作,成功欺骗了matplotlib,顺利实现了我们想要的结果。

总结

??希望上述的内容,能帮助遇到相同问题情况的人,谢谢大家。

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 20:45:38  更:2022-03-21 20:46:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 19:26:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码