Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python matplotlib-为什么闪电冻结图形_Python_Python 2.7_Matplotlib_Matplotlib Animation - Fatal编程技术网

Python matplotlib-为什么闪电冻结图形

Python matplotlib-为什么闪电冻结图形,python,python-2.7,matplotlib,matplotlib-animation,Python,Python 2.7,Matplotlib,Matplotlib Animation,我一直在搜索stackoverflow,以找到一种解决方案,解决在将数据流传输到stackoverflow时出现的交互式mpl图形问题。我已经接近下面的例子了,但是当我绘制这个图时,无论我对代码做了什么修改,我都无法与figure窗口交互。我缺少什么概念可以让我将数据流传输到此窗口并拖动窗口?正如你所看到的,它会打开并打印,但如果我抓住帧将其移动到另一个位置,它会崩溃,并且大部分时间都被固定在原地 我正在使用Python2.7、Paycharm和Windows10 下面是一个我正在使用的有用的例

我一直在搜索stackoverflow,以找到一种解决方案,解决在将数据流传输到stackoverflow时出现的交互式mpl图形问题。我已经接近下面的例子了,但是当我绘制这个图时,无论我对代码做了什么修改,我都无法与figure窗口交互。我缺少什么概念可以让我将数据流传输到此窗口并拖动窗口?正如你所看到的,它会打开并打印,但如果我抓住帧将其移动到另一个位置,它会崩溃,并且大部分时间都被固定在原地

我正在使用Python2.7、Paycharm和Windows10

下面是一个我正在使用的有用的例子。

问题是因为我使用的是plt.show()?我的测试代码由3个文件组成,一个datagen、数据使用者(绘图仪)和一个顶层文件(测试台),用于实例化和启动数据生成器和打印模块。我只是将62字节的正弦波数据添加到数组的末尾,并绘制它,使它看起来像是在滚动

试验台: NB_DataGen->NB_绘图仪(接收62字节的数据和绘图)

模块1:数据绘图模块

# This is the no blitting data plot module built out as a threaded module.
#
#
# Notes:
# 1. Bug in frame rate code
# 2. Going to try to remove queue from plotter and just have a direct access call for
# direct writes to plot.  Queue seems to be bogging down window and I can't drag it
# around.
#
try:
    import Queue as queue
except:
    import queue
import numpy as np
from matplotlib import pyplot as plt
import time
import threading
import matplotlib
print(matplotlib.__version__)





class BlitManager:
    def __init__(self, canvas, animated_artists=()):
        """
        Parameters
        ----------
        canvas : FigureCanvasAgg
            The canvas to work with, this only works for sub-classes of the Agg
            canvas which have the `~FigureCanvasAgg.copy_from_bbox` and
            `~FigureCanvasAgg.restore_region` methods.

        animated_artists : Iterable[Artist]
            List of the artists to manage
        """
        self.canvas = canvas
        self._bg = None
        self._artists = []

        for a in animated_artists:
            self.add_artist(a)
        # grab the background on every draw
        self.cid = canvas.mpl_connect("draw_event", self.on_draw)

    def on_draw(self, event):
        """Callback to register with 'draw_event'."""
        cv = self.canvas
        if event is not None:
            if event.canvas != cv:
                raise RuntimeError
        self._bg = cv.copy_from_bbox(cv.figure.bbox)
        self._draw_animated()

    def add_artist(self, art):
        """
        Add an artist to be managed.

        Parameters
        ----------
        art : Artist

            The artist to be added.  Will be set to 'animated' (just
            to be safe).  *art* must be in the figure associated with
            the canvas this class is managing.

        """
        if art.figure != self.canvas.figure:
            raise RuntimeError
        art.set_animated(True)
        self._artists.append(art)

    def _draw_animated(self):
        """Draw all of the animated artists."""
        fig = self.canvas.figure
        for a in self._artists:
            fig.draw_artist(a)

    def update(self):
        """Update the screen with animated artists."""
        cv = self.canvas
        fig = cv.figure
        # paranoia in case we missed the draw event,
        if self._bg is None:
            self.on_draw(None)
        else:
            # restore the background
            cv.restore_region(self._bg)
            # draw all of the animated artists
            self._draw_animated()
            # update the GUI state
            cv.blit(fig.bbox)
        # let the GUI event loop process anything it has to do
        cv.flush_events()



#
# Main Class
#
class NB_Plotter4(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

        self.i = 0

        # thread loop flag
        self.thread_event = threading.Event()
        self.thread_event.set()     # set thread by default

        # create plot objects
        self.fig = plt.figure()
        self.ax1 = self.fig.add_subplot(1,1,1)
        self.ax1.grid()
        self.line, = self.ax1.plot([], lw=3)
        self.text = self.ax1.text(0.8, 0.5, "")

        self.x_new = np.linspace(0.0, 200.0, num=1000)
        self.y_total = np.empty(1000, dtype=float)

        #set limits
        self.ax1.set_xlim(self.x_new.min(), self.x_new.max())
        self.ax1.set_ylim([-1.1, 1.1])

        # start timer for frame counter
        self.t_start = time.time()


        #self.bm = BlitManager(self.fig.canvas, [self.line, self.text])
        self.bm = BlitManager(self.fig.canvas, [self.line])

        plt.show(block=False)
        plt.pause(0.1)






    #
    # main thread loop
    #
    def Write(self, data):

        # need to grab y-data here from queue
        self.y_ndata = data
        self.y_total = np.concatenate([self.y_total[62:], self.y_ndata])

        self.i = self.i + 1



    #
    # Over-ride thread run method
    #
    def run(self):
        while self.thread_event.is_set():

            self.line.set_data(self.x_new, self.y_total)

            tx = 'Mean Frame Rate:\n {fps:.5f}FPS'.format(fps=((self.i + 1) / (time.time() - self.t_start)))
            self.text.set_text(tx)

            self.bm.update()
模块2:数据生成模块

# This is the no blitting data gen module.  This module is intended to produce data
# in 62 byte blocks resulting in sine wave data blocks.  This is initally meant to
# spoof my DR500 USB payload size so I can' drive some real time plotting.
#
#
# Notes:
#
#
#



try:
    import Queue as queue
except:
    import queue
import numpy as np
import threading
import time

#
# Main Class
#
# For the 62 byte class the rounding in the x vector produces some small errors.  This shouldn't
# be a big problem since the resolution is so high.
#
class NB_DataGen2(threading.Thread):
    def __init__(self, Plotter):
        threading.Thread.__init__(self)

        self.y_data = np.empty(62, dtype=float)
        self.x_data = np.linspace(0.0, np.pi/62.0, num=62)
        self.offset_val = self.x_data[1]

        self.Plotter_Handle = Plotter

        self.inc_cnt = 0.0
        self.first_it_flag = 0      # first iteration flag

        # thread loop flag
        self.thread_event = threading.Event()
        self.thread_event.set()     # set thread by default




    #
    # Produce 62 byte packet of sine wave data
    # - produce next 62 byte chunk of sine wave data
    def Get62ByteSine(self, debug=False):
        # hit for iterations > 0
        if(self.first_it_flag > 0):
            # gen
            self.x_data = self.x_data + (np.pi / 62.0) + self.offset_val
            self.y_data = np.sin(self.x_data)
            if(debug == True):
                print(self.y_data)

            return self.y_data
        # hit for iterations < 1 -> (first iteration)
        else:
            # first iteration
            self.x_data = self.x_data
            self.y_data = np.sin(self.x_data)
            if (debug == True):
                print(self.y_data)
            self.inc_cnt = self.inc_cnt + 1.0
            # flip first run flag
            self.first_it_flag = 1
            return self.y_data


    #
    # Ignore / Not in use
    #
    # Used to check the error from the last value in one block (62 byte block)
    # and the first value of the next block.  the difference in the two should
    # match the offset value roughly. Enable print funcitons in the above
    # Get62ByteSine function for this to work.
    #
    def CheckError(self):
        self.Get62ByteSine(True)
        self.Get62ByteSine(True)
        self.Get62ByteSine(True)
        # print offset
        print(self.offset_val)


    #
    # Kill thread
    #
    def KillThread(self):
        self.thread_event.clear()



    #
    # main thread loop
    #
    def run(self):
        while self.thread_event.is_set():

            self.Plotter_Handle.Write(self.Get62ByteSine())
            time.sleep(1)

长话短说——我试图运行这段代码来绘制传入的数据,并能够拖动窗口或通过鼠标与之交互。有人知道我哪里出错了吗?

您使用的是什么版本的Python?我使用的是Python 2.7.17我想主要问题是我将matplotlib代码放在一个线程中。
# This is the no blitting test bench top module
#
#
# Notes:
#
#
#
from NB_DataGen2 import NB_DataGen2
from NB_Plotter4 import NB_Plotter4



#
# Testbench Class
#
class NB_TestBench(object):
    def __init__(self):

        # create data/plot objects (DUTs) - obj's under test
        self.Plotter = NB_Plotter4()
        self.DataGen = NB_DataGen2(self.Plotter)



    def Start(self):
        self.DataGen.start()
        self.DataGen.isDaemon()
        self.Plotter.start()
        self.Plotter.isDaemon()




# Run test bench
NB = NB_TestBench()
NB.Start()