【问题标题】:multiprocessing show matplotlib plot多处理显示 matplotlib 图
【发布时间】:2017-04-23 13:41:38
【问题描述】:

我正在尝试打开多个地块,但遇到了一些问题。当我尝试使用线程创建绘图时,python 会首先打开一些窗口,然后关闭除第一个之外的所有窗口。

在另一个问题中,建议我使用我尝试过的多处理。代码运行没有错误,只是没有显示任何情节。
在继续我的主要项目之前,我正在尝试做一些非常简单的工作。

# Import the necessary packages and modules
import matplotlib.pyplot as plt
import numpy as np


#from threading import Thread
import multiprocessing

def plot(datax, datay, name):
    # Prepare the data
    x = datax
    y = datay**2
    # Plot the data
    plt.scatter(x, y, label=name)

    # Add a legend
    plt.legend()

    # Show the plot
    plt.show()



#plot(3,3,)
'''
for i in range(10):
    t = Thread(target=plot, args=(i,i+1,i,))
    t.start()
    '''
for i in range(2):
    p = multiprocessing.Process(target=plot, args=(i, i, i))
    p.start()

更新: 由于某种原因,多处理再次停止工作。我尝试创建一个函数 multiP() 只是为了打开进程,但是当我添加输入('value:')时它不起作用。 scine 我不知道如何将数据发送到特定线程 我将像这样保存数据: dat = [[x,y0,y1,...yn],[x,y0,y1,.. .yn],...] 和每个绘图过程都检查是否将某些内容添加到 dat。

import matplotlib.pyplot as plt
import numpy as np

import multiprocessing
#multiprocessing.freeze_support() # <- may be required on windows

def plot(datax, datay, name):
    x = datax
    y = datay**2
    plt.scatter(x, y, label=name)
    plt.legend()
    plt.show()

def multiP():
    if __name__ == "__main__":   
        for i in range(2):
            p = multiprocessing.Process(target=plot, args=(i, i, i))
            p.start()
if True:
    #input('Vlaue: ') # while commented plots are shown
    multiP()

【问题讨论】:

  • 使用多处理或线程的目的究竟是什么?
  • 好吧,我基本上只需要能够绘制我通过 pyusb 获得的数据并将其实时绘制到多个图表中(或尽可能接近)
  • 我怀疑这里使用的多处理对实时绘图有帮助,因为一旦启动,您就需要与进程进行通信。
  • 您知道其他实时绘制多张图表或类似的方法吗?
  • 我的意思是你仍然可以尝试,我可能在这里错了。我当然会首先按顺序更新它们,并且只有当这真的不够快时才考虑其他选项。

标签: python-3.x matplotlib multiprocessing


【解决方案1】:

以下代码根据需要生成两个数字。

import matplotlib.pyplot as plt
import numpy as np

import multiprocessing
#multiprocessing.freeze_support() # <- may be required on windows

def plot(datax, datay, name):
    x = datax
    y = datay**2
    plt.scatter(x, y, label=name)
    plt.legend()
    plt.show()

def multiP():
    for i in range(2):
        p = multiprocessing.Process(target=plot, args=(i, i, i))
        p.start()

if __name__ == "__main__": 
    input('Value: ') 
    multiP()

【讨论】:

  • 感谢代码工作,但我又遇到了问题。在 for 循环之前我添加了 x = input('Value: '),现在图表不会再显示了。我在循环中添加了 print('hi') 以查看它是否正在进入(它是)
  • 这应该也应该在只作为脚本执行的部分;我在答案中发表了评论。
  • 同样,输入需要是仅在用作脚本时才更新的代码的一部分。
【解决方案2】:

接受ImportanceOfBeingErnest 的回答,我在下面留下一个只显示一个窗口并等待窗口关闭的实现,这非常方便。每次调用它时,它都会显示一个带有相应图像的新窗口(将为每个图像启动一个新进程)。在调试期间在某个断点处停止时,我使用了很多来查看图像。

# Library packages needed
import numpy as np
import datetime
import sys
import queue
import multiprocessing

# Plot related packages
import matplotlib.pyplot as plt


def showImage(img: np.ndarray, title: str = str(datetime.datetime.today())):
    """Show an image in a new process without blocking. Usefull for debugging.

    Args:
        img (np.ndarray): Image to be shown
        title (str, optional): Title to be shown. Defaults to
    str(datetime.datetime.today()).
    """

    def plot(q, title):
        fig = plt.figure()
        fig.suptitle(title)
        try:
            q.get(True, 2.0)  # Wait a couple of seconds
        except queue.Empty:
            print('Not image received to plot...quitting')
            sys.exit()

        plt.imshow(img)
        plt.show()
        sys.exit()

    # Create a queue to share data between process
    q = multiprocessing.Queue()

    # Create and start the process
    proc = multiprocessing.Process(None, plot, args=(q, title))
    proc.start()
    q.put(img)

要运行它,只需将其保存到 show_image.py 文件并调用

from show_image.py import showImage
show_image(img, title)

【讨论】:

  • 遇到错误:AttributeError: Can't pickle local object 'showImage.&lt;locals&gt;.plot'
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-11
相关资源
最近更新 更多