【问题标题】:Matplotlib dynamic plot with a sliderMatplotlib 带滑块的动态绘图
【发布时间】:2018-08-10 10:58:42
【问题描述】:

我不太习惯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 = ax 和timelines = timelines 它似乎开始工作,但我不喜欢函数的外观。我很确定存在更好的方法。

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

【问题讨论】:

  • 您的缩进似乎搞砸了,请验证并修复它。此外,你永远不会打电话给slide_plot
  • @ReblochonMasque 不,缩进是正确的。事实上,我没有与电话联系......我只是用随机数构建了那个虚拟示例。
  • 随着 EDIT 的细微变化,更新不会崩溃。但是,滚动条不起作用,窗口等于完整的点集:/
  • 您可以直接使用def update(pos):,如果需要,可以删除pos = spos.val这一行。然而,目前的代码已经可以工作了。因此,问题是你在哪里以及如何运行它?
  • @ImportanceOfBeingErnest 很有趣。我已经开始尝试这篇文章:stackoverflow.com/questions/31001713/…,一旦axcolors 行被取出,它就会起作用。我正在使用 spyder,我首先在 Ipytohn 控制台中设置 %matplotlib 以打开带有绘图的新窗口。帖子中的示例有效,但是,在我的场景中,滚动条不起作用。

标签: python matplotlib slider


【解决方案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)

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

【讨论】:

  • 非常感谢,我绝对猜不到 x')
猜你喜欢
  • 1970-01-01
  • 2017-12-12
  • 2020-11-19
  • 2011-10-05
  • 2021-10-12
  • 1970-01-01
  • 1970-01-01
  • 2011-01-04
  • 2012-06-12
相关资源
最近更新 更多