代码之家  ›  专栏  ›  技术社区  ›  Mathieu

带滑块的Matplotlib动态绘图

  •  0
  • Mathieu  · 技术社区  · 6 年前

    我不太习惯 matplotlib 动态的情节,因此我有一些困难,创造一个理想的情节。我试图绘制N个相同大尺寸(800k点)的时间线(不太多,更不用说少于5个)。我想用一个滑块来表示这个。

    import numpy as np
    from matplotlib import pyplot as plt
    from matplotlib.widgets import Slider
    
    plt.ioff()
    
    timelines = [np.random.randint(-2, 5, size = 800000),
                 np.random.randint(-2, 5, size = 800000), 
                 np.random.randint(-2, 5, size = 800000)]
    timelines_labels = ["label1", "label2", "label3"]
    
    def slide_plot(timelines, timelines_labels):
    
        f, ax = plt.subplots(len(timelines), 1, sharex = True, figsize = (20, 10))
    
        def update(pos, ax = ax, timelines = timelines):
            for k, a in enumerate(ax):
                a.axis([pos,pos+80,-max(timelines[k])-1, max(timelines[k])+1])
            f.canvas.draw_idle()
    
        f.subplots_adjust(bottom=0.25)
        plt.setp([a.get_xticklabels() for a in f.axes[:-1]], visible=False)
        t = np.arange(0.0, len(timelines[0]), 1)
    
        for k, a in enumerate(ax):
            a.plot(t, timelines[k], lw = 0.55, label=timelines_labels[k])
            a.legend(loc="upper right")
            a.axis([0, 160000, -max(timelines[k])-1, max(timelines[k])+1])
    
        ax[-1].set_xticks(np.arange(0.0, len(timelines[0])+80000, 80000))
    
        axpos = plt.axes([0.2, 0.1, 0.65, 0.03])
        spos = Slider(axpos, 'Time (ms)', valmin =0, valmax=800000, valinit=0)
        spos.on_changed(update)
        plt.show()
    
    slide_plot(timelines, timelines_labels)
    

    正如你所看到的,因为我的图是共享X轴,我拿出XTICK标签(以后也会用XTICK做同样的事)。

    然后我创建变量t,这就是时间,我觉得它是无用的,而且 ax[k].plot(timelines[k]) 就够了。

    我做了更多的格式化设置每80000点一个勾号。

    最后,我拿到了滑杆。显然,update函数不起作用。我不知道正确的语法,也不知道实现这一点的正确方法。

    谢谢:)

    编辑:通过放置参数 ax = ax timelines = timelines 似乎开始工作了,但是我不喜欢这个功能的外观。我肯定有更好的方法存在。

    编辑:最新脚本。。。以及输出:

    output

    1 回复  |  直到 6 年前
        1
  •  1
  •   ImportanceOfBeingErnest    6 年前

    问题应该只出现在IPython中(或者Spyder使用IPython)。问题是 plt.show() 不会阻塞和函数 slide_plot 会回来的。一旦返回,对滑块的所有引用以及因此而产生的回调都将消失。 (中的代码 this linked answer 不使用函数,因此不会出现此问题。)

    解决方法是让函数返回对滑块的引用并将其存储。

    import numpy as np
    from matplotlib import pyplot as plt
    from matplotlib.widgets import Slider
    
    timelines = [np.random.randint(-2, 5, size = 800000),
                 np.random.randint(-2, 5, size = 800000), 
                 np.random.randint(-2, 5, size = 800000)]
    timelines_labels = ["label1", "label2", "label3"]
    
    def slide_plot(timelines, timelines_labels):
    
        f, ax = plt.subplots(len(timelines), 1, sharex = True)
    
        def update(pos):
            for k, a in enumerate(ax):
                a.axis([pos,pos+25,-max(timelines[k])-1, max(timelines[k])+1])
            f.canvas.draw_idle()
    
        f.subplots_adjust(bottom=0.25)
        plt.setp([a.get_xticklabels() for a in f.axes[:-1]], visible=False)
        t = np.arange(0.0, len(timelines[0]), 1)
    
        for k, a in enumerate(ax):
            a.plot(t, timelines[k], lw = 0.55, label=timelines_labels[k])
            a.legend(loc="upper right")
            a.axis([0, 25, -max(timelines[k])-1, max(timelines[k])+1])
    
        ax[-1].set_xticks(np.arange(0.0, len(timelines[0]) / 8000, 10))
    
        axpos = plt.axes([0.2, 0.1, 0.65, 0.03])
        spos = Slider(axpos, 'Time (ms)', 0.1, 90.0)
        spos.on_changed(update)
        plt.show()
        return spos
    
    slider = slide_plot(timelines, timelines_labels)
    

    或者,您可以将Spyder配置为不使用Preferences/IPython/graphics下的“matplotlib图形支持”,禁用“激活支持”并启动新的IPython控制台以使其生效。