matplotlib包如何用一个点来描述一个物体的轨迹
How to use a point to discribe the trail of an object with package matplotlib
在while循环中,命令"plt.plot(x,y,'*')"画了一个object.SO的轨迹axes.But画了很多点axes.But我只是想要一个移动点来描述trail.Details 在以下代码的 "while loop" 中。
import matplotlib.pyplot as plt
import numpy as np
#just a dynamic painting
tolerance = 1e-1
radius = np.pi
# missile 1
x_m1, y_m1 = -np.pi, 0
v_m1 = 5
# missile 2
x_m2, y_m2 = 0, np.pi
v_m2 = v_m1
# missile 3
x_m3, y_m3 = np.pi, 0
v_m3 = v_m1
# missile 4
x_m4, y_m4 = 0, -np.pi
v_m4 = v_m1
plt.figure(figsize=(10, 10), dpi=80)
plt.title(" missile flight simulator ", fontsize=40)
plt.xlim(-4, 4)
plt.ylim(-4, 4)
#plt.xticks([])
#plt.yticks([])
# set spines
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data', 0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data', 0))
plt.annotate('missile start point', xy=(x_m1, y_m1), xycoords='data',
xytext=(+15, +15), textcoords='offset points', fontsize=12,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
# alpha labels
for label in ax.get_xticklabels() + ax.get_yticklabels():
label.set_fontsize(16)
label.set_bbox(dict(facecolor='white', edgecolor='None', alpha=0.65))
class ob(object):
"""docstring for ob"""
def __init__(self, x, y):
self.x = x
self.y = y
class missile(ob):
"""docstring for missile"""
def __init__(self, x, y):
super(missile, self).__init__(x, y)
def forward(self, v, target):
"""docstring for forward"""
if self.x < target.x:
alpha = np.arctan((target.y - self.y) / (target.x - self.x))
elif self.x > target.x:
alpha = np.pi + np.arctan((target.y - self.y) / (target.x - self.x))
elif self.x == target.x and self.y < target.y:
alpha = np.pi / 2
else:
alpha = -np.pi / 2
self.x = self.x + v * 0.01 * np.cos(alpha)
self.y = self.y + v * 0.01 * np.sin(alpha)
return self.x, self.y
def distance(self, target):
"""docstring for distance"""
return np.sqrt((self.x - target.x) ** 2 + (self.y - target.y) ** 2)
class target(ob):
"""docstring for target"""
def __init__(self, x, y):
super(target, self).__init__(x, y)
def newposition(self, x, y):
"""docstring for newposition"""
self.x = x
self.y = y
m1 = missile(x_m1, y_m1)
m2 = missile(x_m2, y_m2)
m3 = missile(x_m3, y_m3)
m4 = missile(x_m4, y_m4)
while True: #details
#just a dynamic painting
if m1.distance(m2) < tolerance or m1.distance(m3) < tolerance or m1.distance(m4) < tolerance: #In the loop,many points are painted to discribe the trail
print "collision"
plt.plot(x_m1, y_m1, 'o')
plt.annotate('crash point', xy=(x_m1, y_m1), xycoords='data',
xytext=(+15, +15), textcoords='offset points', fontsize=12,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
plt.pause(0.1)
plt.show()
break
elif m3.distance(m2) < tolerance or m3.distance(m4) < tolerance:
print "collision"
plt.plot(x_m3, y_m3, 'o')
plt.annotate('crash point', xy=(x_m3, y_m3), xycoords='data',
xytext=(+15, +15), textcoords='offset points', fontsize=12,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
plt.pause(0.1)
plt.show
break
x_m1, y_m1 = m1.forward(v_m1, m2)
x_m2, y_m2 = m2.forward(v_m2, m3)
x_m3, y_m3 = m3.forward(v_m3, m4)
x_m4, y_m4 = m4.forward(v_m4, m1)
#print alpha, beta
plt.plot(x_m1, y_m1, 'bx', alpha=.5)
plt.plot(x_m2, y_m2, 'k*', alpha=.5)
plt.plot(x_m3, y_m3, 'r.', alpha=.5)
plt.plot(x_m4, y_m4, 'gp', alpha=.5)
plt.legend(("missile1", "missile2", "missile3", "missile4"), loc="upper left", prop={'size': 12})
plt.pause(0.1)
有解决办法吗?这个程序只是为了一个动态的painting.Paint一个移动点来显示一个object.The点坐标的轨迹以它的正常速度更新。在我的代码中,轨道的所有点都被绘制了,但我只需要一辆移动的 point.Just 就像一辆 运行 汽车在路上,每次你在 [=24= 的不同位置看到一辆移动的汽车]可以删除"while"循环,如果你能用其他方式达到我的期望。
我仍然不确定我是否理解您的问题,但是:
看来您已陷入与 90% 询问动画和 matplotlib 的人相同的陷阱,因为您在迭代的每一步都重复调用 plot()
,从而创建新点 (实际上,新的 Line2D
个对象),而不是更新现有对象的属性。
动画的一般程序是:
- 创建你的图形和所有不需要更新的固定元素
- 创建需要更新的艺术家,并保留对他们的引用
- 在您的循环中,更新(而不是替换或创建新艺术家)在上一步中创建的艺术家的属性。
既然你没有得到我关于创建一个最小工作示例的提示,让我来证明你的代码 99% 是无用的,你的问题可以简化并解决像这样:
import matplotlib.pyplot as plt
import numpy as np
plt.figure()
# create a placeholder artist object, and keep a reference to it
my_line, = plt.plot([], [], 'bx', alpha=.5)
plt.legend(["my line"], loc="upper left", prop={'size': 12})
plt.xlim([0, 10])
plt.ylim([0, 10])
i = 0
while True:
# do whatever to get next coordinates
i = (i + 1) % 10
new_x, new_y = i, i
# update artist
my_line.set_data(new_x, new_y)
plt.draw()
plt.pause(0.1)
最后,我会回应@ImportanceOfBeingErnest 的评论并建议您研究the FuncAnimation module 来制作您的动画,尽管总体策略保持完全相同。
在while循环中,命令"plt.plot(x,y,'*')"画了一个object.SO的轨迹axes.But画了很多点axes.But我只是想要一个移动点来描述trail.Details 在以下代码的 "while loop" 中。
import matplotlib.pyplot as plt
import numpy as np
#just a dynamic painting
tolerance = 1e-1
radius = np.pi
# missile 1
x_m1, y_m1 = -np.pi, 0
v_m1 = 5
# missile 2
x_m2, y_m2 = 0, np.pi
v_m2 = v_m1
# missile 3
x_m3, y_m3 = np.pi, 0
v_m3 = v_m1
# missile 4
x_m4, y_m4 = 0, -np.pi
v_m4 = v_m1
plt.figure(figsize=(10, 10), dpi=80)
plt.title(" missile flight simulator ", fontsize=40)
plt.xlim(-4, 4)
plt.ylim(-4, 4)
#plt.xticks([])
#plt.yticks([])
# set spines
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data', 0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data', 0))
plt.annotate('missile start point', xy=(x_m1, y_m1), xycoords='data',
xytext=(+15, +15), textcoords='offset points', fontsize=12,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
# alpha labels
for label in ax.get_xticklabels() + ax.get_yticklabels():
label.set_fontsize(16)
label.set_bbox(dict(facecolor='white', edgecolor='None', alpha=0.65))
class ob(object):
"""docstring for ob"""
def __init__(self, x, y):
self.x = x
self.y = y
class missile(ob):
"""docstring for missile"""
def __init__(self, x, y):
super(missile, self).__init__(x, y)
def forward(self, v, target):
"""docstring for forward"""
if self.x < target.x:
alpha = np.arctan((target.y - self.y) / (target.x - self.x))
elif self.x > target.x:
alpha = np.pi + np.arctan((target.y - self.y) / (target.x - self.x))
elif self.x == target.x and self.y < target.y:
alpha = np.pi / 2
else:
alpha = -np.pi / 2
self.x = self.x + v * 0.01 * np.cos(alpha)
self.y = self.y + v * 0.01 * np.sin(alpha)
return self.x, self.y
def distance(self, target):
"""docstring for distance"""
return np.sqrt((self.x - target.x) ** 2 + (self.y - target.y) ** 2)
class target(ob):
"""docstring for target"""
def __init__(self, x, y):
super(target, self).__init__(x, y)
def newposition(self, x, y):
"""docstring for newposition"""
self.x = x
self.y = y
m1 = missile(x_m1, y_m1)
m2 = missile(x_m2, y_m2)
m3 = missile(x_m3, y_m3)
m4 = missile(x_m4, y_m4)
while True: #details
#just a dynamic painting
if m1.distance(m2) < tolerance or m1.distance(m3) < tolerance or m1.distance(m4) < tolerance: #In the loop,many points are painted to discribe the trail
print "collision"
plt.plot(x_m1, y_m1, 'o')
plt.annotate('crash point', xy=(x_m1, y_m1), xycoords='data',
xytext=(+15, +15), textcoords='offset points', fontsize=12,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
plt.pause(0.1)
plt.show()
break
elif m3.distance(m2) < tolerance or m3.distance(m4) < tolerance:
print "collision"
plt.plot(x_m3, y_m3, 'o')
plt.annotate('crash point', xy=(x_m3, y_m3), xycoords='data',
xytext=(+15, +15), textcoords='offset points', fontsize=12,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
plt.pause(0.1)
plt.show
break
x_m1, y_m1 = m1.forward(v_m1, m2)
x_m2, y_m2 = m2.forward(v_m2, m3)
x_m3, y_m3 = m3.forward(v_m3, m4)
x_m4, y_m4 = m4.forward(v_m4, m1)
#print alpha, beta
plt.plot(x_m1, y_m1, 'bx', alpha=.5)
plt.plot(x_m2, y_m2, 'k*', alpha=.5)
plt.plot(x_m3, y_m3, 'r.', alpha=.5)
plt.plot(x_m4, y_m4, 'gp', alpha=.5)
plt.legend(("missile1", "missile2", "missile3", "missile4"), loc="upper left", prop={'size': 12})
plt.pause(0.1)
有解决办法吗?这个程序只是为了一个动态的painting.Paint一个移动点来显示一个object.The点坐标的轨迹以它的正常速度更新。在我的代码中,轨道的所有点都被绘制了,但我只需要一辆移动的 point.Just 就像一辆 运行 汽车在路上,每次你在 [=24= 的不同位置看到一辆移动的汽车]可以删除"while"循环,如果你能用其他方式达到我的期望。
我仍然不确定我是否理解您的问题,但是:
看来您已陷入与 90% 询问动画和 matplotlib 的人相同的陷阱,因为您在迭代的每一步都重复调用 plot()
,从而创建新点 (实际上,新的 Line2D
个对象),而不是更新现有对象的属性。
动画的一般程序是:
- 创建你的图形和所有不需要更新的固定元素
- 创建需要更新的艺术家,并保留对他们的引用
- 在您的循环中,更新(而不是替换或创建新艺术家)在上一步中创建的艺术家的属性。
既然你没有得到我关于创建一个最小工作示例的提示,让我来证明你的代码 99% 是无用的,你的问题可以简化并解决像这样:
import matplotlib.pyplot as plt
import numpy as np
plt.figure()
# create a placeholder artist object, and keep a reference to it
my_line, = plt.plot([], [], 'bx', alpha=.5)
plt.legend(["my line"], loc="upper left", prop={'size': 12})
plt.xlim([0, 10])
plt.ylim([0, 10])
i = 0
while True:
# do whatever to get next coordinates
i = (i + 1) % 10
new_x, new_y = i, i
# update artist
my_line.set_data(new_x, new_y)
plt.draw()
plt.pause(0.1)
最后,我会回应@ImportanceOfBeingErnest 的评论并建议您研究the FuncAnimation module 来制作您的动画,尽管总体策略保持完全相同。