我希望能够在点移动时用鼠标移动3D轴。查看下面的代码(this的修改版本) - 很明显,如果您尝试缩放/旋转3D轴,绘制的线将随您的鼠标一起旋转,但轴将继续捕捉到它的初始方向。如果blit=True
更改为blit=False
,则可以删除此奇怪的行为,但由于我正在使用大型数据集,因此我绝对需要blit=True
。我希望能够在绘图时移动轴。
"""
A simple example of an animated plot... In 3D!
"""
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as p3
import matplotlib.animation as animation
def Gen_RandLine(length, dims=2) :
lineData = np.empty((dims, length))
lineData[:, 0] = np.random.rand(dims)
for index in range(1, length) :
# scaling the random numbers by 0.1 so
# movement is small compared to position.
# subtraction by 0.5 is to change the range to [-0.5, 0.5]
# to allow a line to move backwards.
step = ((np.random.rand(dims) - 0.5) * 0.1)
lineData[:, index] = lineData[:, index-1] + step
return lineData
def update_lines(num, dataLines, lines) :
for line, data in zip(lines, dataLines) :
# NOTE: there is no .set_data() for 3 dim data...
line.set_data(data[0:2, num-1:num])
line.set_3d_properties(data[2,num-1:num])
return lines
# Attaching 3D axis to the figure
fig = plt.figure()
ax = p3.Axes3D(fig)
# Fifty lines of random 3-D lines
data = [Gen_RandLine(2500, 3) for index in range(1)]
# Creating fifty line objects.
# NOTE: Can't pass empty arrays into 3d version of plot()
lines = [ax.plot(dat[0, 0:1], dat[1, 0:1], dat[2, 0:1], marker='o')[0] for dat in data]
# Setting the axes properties
ax.set_xlim3d([0.0, 1.0])
ax.set_xlabel('X')
ax.set_ylim3d([0.0, 1.0])
ax.set_ylabel('Y')
ax.set_zlim3d([0.0, 1.0])
ax.set_zlabel('Z')
ax.set_title('3D Test')
# Creating the Animation object
line_ani = animation.FuncAnimation(fig, update_lines, fargs=(data, lines),
interval=50, blit=True, repeat=False)
plt.show()
前面的答案说明了如何为3D轴外的对象设置动画,使用自定义的_blit_draw
函数,如here所述。好的,我希望扩展bbox动画然后允许轴也动画。这就是我想出的:
"""
A simple example of an animated plot... In 3D!
"""
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as p3
import matplotlib.animation as animation
def Gen_RandLine(length, dims=2) :
lineData = np.empty((dims, length))
lineData[:, 0] = np.random.rand(dims)
for index in range(1, length) :
# scaling the random numbers by 0.1 so
# movement is small compared to position.
# subtraction by 0.5 is to change the range to [-0.5, 0.5]
# to allow a line to move backwards.
step = ((np.random.rand(dims) - 0.5) * 0.1)
lineData[:, index] = lineData[:, index-1] + step
return lineData
def update_lines(num, dataLines, lines) :
for line, data in zip(lines, dataLines) :
# NOTE: there is no .set_data() for 3 dim data...
line.set_data(data[0:2, num-1:num])
line.set_3d_properties(data[2,num-1:num])
return lines
def _blit_draw(self, artists, bg_cache):
# Handles blitted drawing, which renders only the artists given instead
# of the entire figure.
updated_ax = []
for a in artists:
# If we haven't cached the background for this axes object, do
# so now. This might not always be reliable, but it's an attempt
# to automate the process.
if a.axes not in bg_cache:
# bg_cache[a.axes] = a.figure.canvas.copy_from_bbox(a.axes.bbox)
# change here
bg_cache[a.axes] = a.figure.canvas.copy_from_bbox(a.get_window_extent(a.figure.canvas.renderer))
a.axes.draw_artist(a)
updated_ax.append(a.axes)
# After rendering all the needed artists, blit each axes individually.
for ax in set(updated_ax):
# and here
# ax.figure.canvas.blit(ax.bbox)
ax.figure.canvas.blit(ax.figure.bbox)
# Attaching 3D axis to the figure
fig = plt.figure()
ax = p3.Axes3D(fig)
# Fifty lines of random 3-D lines
data = [Gen_RandLine(2500, 3) for index in range(1)]
# Creating fifty line objects.
# NOTE: Can't pass empty arrays into 3d version of plot()
lines = [ax.plot(dat[0, 0:1], dat[1, 0:1], dat[2, 0:1], marker='o')[0] for dat in data]
# Setting the axes properties
ax.set_xlim3d([0.0, 1.0])
ax.set_xlabel('X')
ax.set_ylim3d([0.0, 1.0])
ax.set_ylabel('Y')
ax.set_zlim3d([0.0, 1.0])
ax.set_zlabel('Z')
ax.set_title('3D Test')
# Creating the Animation object
line_ani = animation.FuncAnimation(fig, update_lines, fargs=(data, lines),
interval=50, blit=True, repeat=False)
matplotlib.animation.Animation._blit_draw = _blit_draw
plt.show()
现在,可以在绘图过程中拖动和旋转轴,所有这些都使用blit=True
。然而,点现在留下了之前没有的痕迹,这就是问题所在。有趣的是,每次调整窗口大小或移动轴时,点迹线都会消失。我试图同时实现动画奇点和交互式3D轴都没有成功。
我非常感谢帮助找出我需要解决的问题。我已经坚持了好几天了!干杯