python - Matplotlib 带滑块的动态绘图
问题描述
我不太习惯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
它似乎开始工作,但是我不喜欢函数的外观。我很确定存在更好的方法。
编辑:最新脚本...和输出:
解决方案
该问题应该只出现在 IPython(或使用 IPython 的 Spyder)中。问题是plt.show()
不会阻塞,函数slide_plot
会返回。一旦它返回,所有对滑块的引用和回调都消失了。(此链接答案中的代码不使用函数,因此此处不会出现此问题。)
一种解决方案是让函数返回对滑块的引用并存储它。
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 graphics support”,禁用“Activate support”并启动一个新的 IPython 控制台以使其生效。
推荐阅读
- spring - ConfigServletWebServerApplicationContext:如何从 Spring Maven 项目中卸载 Flyway
- rust - 封装一个对象和一个使用其生命周期的引用
- python - 如何使用 Python (pandas) 将文本文件格式化/解析为 CSV
- grafana - 读取 k8s configmap 数据并使用 grafana 进行可视化
- java - 未调用客户授权标头过滤器
- html - Electron App 上的 href 转换之间出现白色闪烁
- excel - 使用 ActiveCell..Offset(-1,0)= 的 If/And/Then/Else 语句的 VBA 问题
- mysql - 将 Shiny 应用程序连接到主机上运行的 MySQL 数据库会给出“容器未及时响应”
- python-3.x - Fbchat 登录失败。检查电子邮件/密码
- amazon-web-services - 什么是 Cloudformation 的 !Sub 在 Terraform 中的等效项