带滑块的Matplotlib动态图

时间:2018-08-10 10:58:43

标签: python matplotlib slider

我不太习惯matplotlib动态图,因此创建所需的图有些困难。我正在尝试绘制相同大小(800k点)的N个时间轴(不要太多,少说少于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轴,所以我要从底部的所有轴中取出xticks标签(以后将与xticks相同)。

然后我创建了只是时间的变量t,我觉得它没有用,ax[k].plot(timelines[k])就足够了。

我通过每80000点设置一个刻度来进行更多格式化。

最后,我得到了滑块。显然,更新功能不起作用。我不知道正确的语法,也不知道实现此目的的正确方法。

谢谢:)

编辑:通过放置参数ax = axtimelines = timelines似乎开始起作用,但是我不喜欢该函数的外观。我很确定存在更好的方法。

编辑:最新脚本...输出:

output

1 个答案:

答案 0 :(得分:1)

该问题仅应在IPython(或使用IPython的Spyder)中发生。问题在于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图形支持”,禁用“ Activate support”并启动新的IPython控制台以使其生效。