【问题标题】:Plot freezing because of fast input stream to a GNU Radio block由于 GNU Radio 块的快速输入流而导致绘图冻结
【发布时间】:2015-09-13 02:57:29
【问题描述】:

我已经实现了一个sync block,它使用input_items 值在其work 函数内绘图。现在的问题是绘图机制对于输入流来说不够快(input_items 的值不断变化)。

我已尝试尽可能简化代码并添加了 cmets。这里是:

....
import matplotlib
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure
temp = ''
class xyz(gr.sync_block):
    def __init__(self,parent,title,order):
        a = []
        self.count = 1
        gr.sync_block.__init__(self,
                name="xyz",
                in_sig=[numpy.float32,numpy.float32],
                out_sig=None)
        self.win = xyzPlot(parent) #I have a Top Block(wxFrame). I am just making it the parent of xyzPlot(wxPanel) here.

    def work(self, input_items, output_items):
        global temp
        if (self.count == 1):
            temp = input_items+list()
        bool = not(np.allclose(temp,input_items))#bool will be true if the value of `input_items` changes. 
        .......
        #the code that evaluates z1,z2 depending on the value of input_items    
        .......
        if ( bool or self.count == 1 ):
        #If bool is true or it is the first time then I am calling plot() which plots the graph. 
            self.win.plot(tf(self.z1,self.z3),None,True,True,True,True)
        self.count = 0
        temp = input_items+list()
        return len(input_items[0])

class xyzPlot(wx.Panel):
    def __init__(self, parent, dB=None, Hz=None, deg=None):
        wx.Panel.__init__(self , parent , -1 ,size=(600,475))
        self.fig = Figure()
        self.axes = self.fig.add_subplot(111)

    def plot(self, syslist, omega=None, dB=None, Hz=None, deg=None, Plot=True, *args , **kwargs):
        self.axes.clear() #I clear the graph here so that new values can be plotted.
        .....
        self.axes.semilogx(omega,mag,*args,**kwargs)
        self.canvas = FigCanvas(self, -1, self.fig)
        self.canvas.draw()

如您所见,我正在使用 wxPython,但是每当我将 input_items 的值更改得太快时,面板就会冻结(如果我慢慢更改它就可以正常工作)。有什么建议吗?我是新手。

【问题讨论】:

  • 不要清除轴并重建艺术家。创建一次,并保留对它的引用。然后您可以使用set_data 仅更改数据点。同样适用于画布。只创建一次,然后调用draw 应该足以更新图形。
  • @hitzg:是的,但问题似乎是他在非 GUI 线程的线程中异步且高速地绘制事物。我认为您可能更习惯于 matplotlib/wx 集成,所以我很乐意在我的 answer 下看到您的评论。
  • @MarcusMüllerꕺꕺ 不是真的。我的评论只是关于如何加快剧情更新的建议。
  • @hitzg:我理解画布的变化。在他使用semilogx的情况下如何使用set_data
  • semilogxplot 完全相同。它返回一个艺术家列表。

标签: python matplotlib wxpython gnuradio


【解决方案1】:

引用another answer我给了:

这很快也会出现多线程问题。明确一点:什么 你正在尝试做(从块线程调用绘图函数)是 有问题,通常不起作用。

问题是您在复杂的多线程环境中工作:

  • 每个 GNU Radio 块都在自己的线程中工作
  • WX Gui 主循环不断运行以更新屏幕。

您在这里所做的是,从 GNU Radio 块线程更改窗口中显示的内容。这是一件坏事,因为它改变了 WX Gui 线程上下文中的内容。如果这些更改不冲突,并且 WX Gui 线程在您更改它时没有访问此类数据(在某些时候,它必须访问它 - - 否则,没有人会更新您的窗口)。

这是所有更新后的 GUI 都存在的问题,不仅仅是 GNU Radio!

这种情况是否发生只是概率问题:显示更新缓慢,您的冲突概率很低,但当您经常更新时,它接近 1。

现有的可视化是用 C++ 编写的,并且非常小心地以正确的方式做事——也就是说,让你的 Gui 工具包(在你的情况下是 WX,尽管我明确推荐并且已经建议远离那个) 知道需要更新的东西,然后提供 WX 一个函数来更新它自己的线程中的显示。

【讨论】:

  • 感谢您的回答。是否有任何关于如何为现有可视化工具提供样本的教程?您能否指导我找到它们或实现类似内容的文件,以便我可以浏览代码?
  • @PuRaK:指导教程是你的朋友。您只需输入样本。源代码是公开的,github.com/gnuradio/gnuradio。查看 gr-qtgui/lib(或者如果你真的想这样做,不要那样做,WX 已经死了,gr-wxgui)文件夹。
猜你喜欢
  • 2015-03-21
  • 1970-01-01
  • 2016-06-15
  • 1970-01-01
  • 2015-10-29
  • 2019-12-16
  • 2020-07-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多