Issue
In the while loop,the command plt.plot(x,y,'*')
paints the trail of an object.SO there are many points painted in the axes. But I just want a moving point to describe the trail.
Details are in the "while loop" of following code:
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)
Are there any resolution given? This program is just for dynamic painting... aka paint a moving point to show the track of an object. The point's coordinate get updated with its regular speed. In my code, all points of the track are painted, but I only need one moving point. Just like an running car in the road, every time you see one moving car in a different place of the track. You can delete the "while" loop, if you could use other ways to achieve my expectation.
Solution
I'm still not sure I understood your question, but:
It looks like you've fallen into the same trap as 90% of people asking about animations and matplotlib, in that you are repeatedly calling plot()
at each step of your iterations, thus creating new points (really, new Line2D
objects) at each steps, instead of updating the properties of the existing one.
The general procedure for animations is to:
- create your figure and all the fixed elements that do not need to be updated
- create the artists that need to be updated, and keep a reference to them
- in your loop, update (instead of replacing or creating new artists) the properties of the artists created in the previous step.
Since you did not get my hint about creating a minimal working example, let me show that 99% of your code was useless and that your problem can be simplified and solved just like so:
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)
Finally, I will echo @ImportanceOfBeingErnest's comment and suggest you look into the FuncAnimation module to produce your animations, although the overall strategy remains exactly the same.
Answered By - Diziet Asahi
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.