【问题标题】:matplotlib - How do you keep the axes constant while adding new data?matplotlib - 添加新数据时如何保持轴不变?
【发布时间】:2013-06-06 13:37:54
【问题描述】:

我正在使用 matplotlib 来显示不断更新的数据(大约每秒更改 10 次)。我正在使用 3D 散点图,并且我希望将轴固定在特定范围内,因为数据相对于绘图边缘的位置很重要。

目前,每当我添加新数据时,轴都会重置为按数据缩放,而不是我想要的大小(当我有 hold=False 时)。如果我设置了hold=True,坐标轴将保持正确的大小,但新数据将覆盖在旧数据上,这不是我想要的。

如果每次获得新数据时都重新调整坐标轴,我可以让它工作,但这似乎是一种低效的方法,特别是因为我还需要再次进行所有其他格式化(添加标题、图例等) )

有没有什么方法可以让我只指定一次绘图的属性,并且在我添加新数据时这将保持不变?

这是我的代码的粗略大纲,以帮助解释我的意思:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

X_MAX = 50
Y_MAX = 50
Z_MAX = 50

fig = plt.figure(1)
ax = fig.add_subplot(111, projection='3d')
ax.set_title("My Title")
ax.set_xlim3d([0, X_MAX])
ax.set_ylim3d([0, Y_MAX])
ax.set_zlim3d([0, Z_MAX])
ax.set_autoscale_on(False)
# This is so the new data replaces the old data
# seems to be replacing the axis ranges as well, maybe a different method should be used?
ax.hold(False)

plt.ion()
plt.show()

a = 0
while a < 50:
  a += 1
  ax.scatter( a, a/2+1, 3, s=1 )
  # If I don't set the title and axes ranges again here, they will be reset each time
  # I want to know if there is a way to only set them once and have it persistent
  ax.set_title("My Title")
  ax.set_xlim3d([0, X_MAX])
  ax.set_ylim3d([0, Y_MAX])
  ax.set_zlim3d([0, Z_MAX])
  plt.pause(0.001)

编辑: 1.我也试过ax.set_autoscale_on(False),但没有成功 2. 我用常规的二维散点图试过了,同样的问题仍然存在 3. 找到了related question 也没有答案

【问题讨论】:

  • 你看过autoscale吗?
  • 根据@BrenBarn 的评论,我会在while 循环之前(或者在plt.show() 之前)测试ax.set_autoscale_on(False)
  • 我试过在几个地方使用 ax.set_autoscale_on(False) 以及 ax.autoscale(False),但还是没有成功
  • Matplotlib 还有一个module for animations,看看this example,也许有帮助。
  • 感谢您的建议。看起来动画模块希望您在启动动画时拥有所有可用数据,但对于我的用例,数据是实时流式传输的,并且可能不是恒定速率。不过,它对于重放数据仍然很有用。

标签: python python-2.7 matplotlib


【解决方案1】:

我会做这样的事情(注意删除 hold(False) ):

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

X_MAX = 50
Y_MAX = 50
Z_MAX = 50
fig = plt.figure(1)
ax = fig.add_subplot(111, projection='3d')
ax.set_title("My Title")
ax.set_xlim3d([0, X_MAX])
ax.set_ylim3d([0, Y_MAX])
ax.set_zlim3d([0, Z_MAX])
ax.set_autoscale_on(False)
plt.ion()
plt.show()

a = 0
sct = None
while a < 50:
  a += 1
  if sct is not None:
      sct.remove()
  sct = ax.scatter( a, a/2+1, 3, s=1 )
  fig.canvas.draw()
  plt.pause(0.001)

您在每次循环中删除只是添加的散点图。

【讨论】:

  • 这似乎可以解决问题,谢谢!还需要注意的是,除非您删除 ax.hold(False),否则这将不起作用,因为旧图已被删除,因此不再需要它。在某个时候,我会测试这两种方法之间的时间差是多少
  • 这对我不起作用。我收到错误消息TypeError: remove() takes exactly one argument (0 given)。 (matplotlib 1.4.3)
  • @StephenBosch 这太神秘了,请用最小(非)工作示例打开一个新问题。我刚刚对此进行了测试(并更新了缺少行的答案),它对我有用(在接近 master 的版本上)。
猜你喜欢
  • 1970-01-01
  • 2022-01-13
  • 2021-11-25
  • 2016-12-11
  • 2019-03-18
  • 1970-01-01
  • 1970-01-01
  • 2022-08-17
  • 1970-01-01
相关资源
最近更新 更多