在线程中使用matplotlib进行绘图 [英] Plotting with matplotlib in threads

查看:1311
本文介绍了在线程中使用matplotlib进行绘图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道关于matplotlib和线程存在很多问题,而且pyplot不是threadave.但是,我在此特定问题上找不到任何东西.我想要做的是:绘制一个图形并每秒对其进行更新.为此,我想创建一个线程,但是到目前为止,我什至无法从该线程获得真实的图.另外,我还停留在qt4上,所以可能其他后端的行为有所不同.

I know there are quite some questions on matplotlib and threading, also that pyplot is not threadsave. I couldn't find anything on this particular problem however. What I want to do is: plot a figure and update it every second. For this I wanted to create a thread, but so far I couldn't even get a real plot from the thread. Also, I'm stuck with qt4, so it may be other backends behave different.

这是一个非常简单的示例:在plot_a_graph()中创建了一个图.从主程序调用时,此方法工作正常,但会延迟主代码的进一步执行.但是,从线程调用时,不会显示任何图形.

Here is a very simple example: A plot is created in plot_a_graph(). This works fine when called from the main program but delays the further execution of the main code. When called from a thread however, no graph is displayed.

import matplotlib
matplotlib.use("qt4agg")
import matplotlib.pyplot as plt
import threading
import time

def plot_a_graph():
    f,a = plt.subplots(1)
    line = plt.plot(range(10))
    plt.show()
    print "plotted graph"    
    time.sleep(4)


testthread = threading.Thread(target=plot_a_graph)

plot_a_graph()      # this works fine, displays the graph and waits
print "that took some time"

testthread.start() # Thread starts, window is opened but no graph appears
print "already there"

为您提供帮助

推荐答案

我的建议是使用python multiprocessing 模块而不是线程模块.我只能对您的示例代码进行少量修改,就可以成功地将matplotlib绘图卸载到子进程中,同时继续进行主进程中的控制流(请参见下面的代码).

My suggestion here is to use the python multiprocessing module instead of the threading module. I've been able to perform only slight modifications to your sample code and successfully offload the matplotlib plotting to a child process while the control flow in the main process continues (see code below).

如果您希望子流程进行回访,我建议阅读多处理文档或有关该主题的大量博客文章.在较大的代码控制流的上下文中与父级(在问题中没有完全描述)进行交互.请注意,多处理具有规避python 全局解释器锁允许您利用多核计算机体系结构.

I do suggest reading the multiprocessing documentation, or any of the plethora of blog posts on the subject, if you want the child process(es) to communicate back & forth with the parent in the context of your larger code control flow (which isn't fully described in your question). Note that multiprocessing has the added advantage of circumventing the python global interpreter lock & allowing you to exploit multi-core computer architectures.

#a slight modification of your code using multiprocessing
import matplotlib
matplotlib.use("qt4agg")
import matplotlib.pyplot as plt 
#import threading
#let's try using multiprocessing instead of threading module:
import multiprocessing
import time

#we'll keep the same plotting function, except for one change--I'm going to use the multiprocessing module to report the plotting of the graph from the child process (on another core):
def plot_a_graph():
    f,a = plt.subplots(1)
    line = plt.plot(range(10))
    print multiprocessing.current_process().name,"starting plot show process" #print statement preceded by true process name
    plt.show() #I think the code in the child will stop here until the graph is closed
    print multiprocessing.current_process().name,"plotted graph" #print statement preceded by true process name
    time.sleep(4)

#use the multiprocessing module to perform the plotting activity in another process (i.e., on another core):
job_for_another_core = multiprocessing.Process(target=plot_a_graph,args=())
job_for_another_core.start()

#the follow print statement will also be modified to demonstrate that it comes from the parent process, and should happen without substantial delay as another process performs the plotting operation:
print multiprocessing.current_process().name, "The main process is continuing while another process deals with plotting."

这篇关于在线程中使用matplotlib进行绘图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆