Python 移动物体后如何更新箭图?
我正在写一个小的可视化项目,这个项目假设显示几个带电体周围的向量场 我的问题是: 我不知道如何在从主位置移动圆(带电粒子)后更新箭袋场 链接到图片,因为我的声誉太低。我对stackoverflow几乎是新手Python 移动物体后如何更新箭图?,python,python-3.x,matplotlib,Python,Python 3.x,Matplotlib,我正在写一个小的可视化项目,这个项目假设显示几个带电体周围的向量场 我的问题是: 我不知道如何在从主位置移动圆(带电粒子)后更新箭袋场 链接到图片,因为我的声誉太低。我对stackoverflow几乎是新手 from pylab import * from scipy import * import matplotlib.pyplot as plt import matplotlib.patches as patches import scipy.constants as const skr =
from pylab import *
from scipy import *
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import scipy.constants as const
skr = const.pi*const.epsilon_0*4
class DraggablePoint:
def __init__(self, p, q0):
self.q = q0
self.point = p
self.c_kruznice = p.center
self.press = None
def connect(self):
self.cidpress = self.point.figure.canvas.mpl_connect('button_press_event', self.button_press_event)
self.cidrelease = self.point.figure.canvas.mpl_connect('button_release_event',self.button_release_event)
self.cidmotion = self.point.figure.canvas.mpl_connect('motion_notify_event', self.motion_notify_event)
def disconnect(self):
self.point.figure.canvas.mpl_disconnect(self.cidpress)
self.point.figure.canvas.mpl_disconnect(self.cidrelease)
self.point.figure.canvas.mpl_disconnect(self.cidmotion)
def button_press_event(self,event):
if event.inaxes != self.point.axes:
return
contains = self.point.contains(event)[0]
if not contains: return
self.press = self.point.center, event.xdata, event.ydata
def button_release_event(self,event):
self.press = None
self.point.figure.canvas.draw()
def motion_notify_event(self, event):
if self.press is None: return
if event.inaxes != self.point.axes: return
self.point.center, xpress, ypress = self.press
dx = event.xdata - xpress
dy = event.ydata - ypress
self.point.center = (self.point.center[0]+dx, self.point.center[1]+dy)
print(self.point.center)
self.point.figure.canvas.draw()
if __name__ == '__main__':
f_s=0.3
def R(x,y):
r=np.sqrt(x**2+y**2)+f_s
return r
def polje(tela, X, Y):
Ex = 0
Ey = 0
for i in range(len(tela)):
r=R(tela[i].c_kruznice[0] - X, tela[i].c_kruznice[1] - Y )
ex = X - tela[i].c_kruznice[0]
ey = Y - tela[i].c_kruznice[1]
Ex += (tela[i].q/skr)*(1/(r+f_s)**3)*ex
Ey += (tela[i].q/skr)*(1/(r+f_s)**3)*ey
return Ex, Ey
fig = plt.figure(figsize=(8,8))
ax = fig.add_axes([0.05,0.05,0.92,0.92])
ax.set_xlim(-6,6)
ax.set_ylim(-6,6)
scale = 0.2
X,Y=np.mgrid[-5:5:scale, -5:5:scale]
circles = []
q=3*const.e
s=abs(q)
sx=sqrt(s/np.pi)*1e8*5
circle2 = patches.Circle((3,0.3), 0.3, fc='r', alpha=0.5, picker=True)
circle1 = patches.Circle((0.7,0.3), 0.3, fc='r', alpha=0.5, picker=True)
circle = patches.Circle((-4,0.3), 0.3, fc='b', alpha=0.5, picker=True)
circles.append(ax.add_patch(circle1))
circles.append(ax.add_patch(circle))
circles.append(ax.add_patch(circle2))
drs = []
for c in circles:
print(c.center[0])
dr = DraggablePoint(c,-1)
dr.connect()
drs.append(dr)
racun=polje(drs, X, Y)
ax.quiver(X,Y,racun[0],racun[1], color='r', alpha=0.5)
ax.quiver(X,Y,racun[0],racun[1], edgecolor='k', facecolor='None', linewidth =.5)
plt.show ()
我也是新来的,所以我会尽我所能帮助你 对我来说合乎逻辑的解决方案是为你们的圈子建立索引。每当你移动一个圆圈,你的类就会调用函数
按钮\u释放\u事件
尽可能多的圆圈。所以,当涉及到最后一个圆(你给它指定了具体的索引)时,你只需要删除你的绘图,然后重新做一遍(你需要画圆和字段)
有趣的是,当它检查圆时,它总是在第一个圆上完成,索引为0。我不知道为什么会发生这种情况,但这很好,因为它与图形上有多少圈无关
此外,还需要使用lineself.c_kruznice=self.point.center[0],self.point.center[1]
,因为它将更新您拖动的点的中心,以便计算字段。关键的一点是:对绘图字段使用plt.draw()
,因为只有这样,拖动圆后才会更新字段。因为plt.show()
等待您完成绘制它的所有操作(这就是为什么在您开始下一次拖动时它会绘制),但是plt.draw()
在发布时进行绘制
编辑:在重新打印(我编辑了代码)之前,您需要清除列表圆圈
下面是这个想法的代码
from pylab import *
from scipy import *
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import scipy.constants as const
skr = const.pi*const.epsilon_0*4
class DraggablePoint:
global Polje
def __init__(self, p, q0, ind):
self.q = q0
self.point = p
self.c_kruznice = p.center
self.press = None
self.indeks = ind
def connect(self):
self.cidpress = self.point.figure.canvas.mpl_connect('button_press_event', self.button_press_event)
self.cidrelease = self.point.figure.canvas.mpl_connect('button_release_event',self.button_release_event)
self.cidmotion = self.point.figure.canvas.mpl_connect('motion_notify_event', self.motion_notify_event)
def disconnect(self):
self.point.figure.canvas.mpl_disconnect(self.cidpress)
self.point.figure.canvas.mpl_disconnect(self.cidrelease)
self.point.figure.canvas.mpl_disconnect(self.cidmotion)
def button_press_event(self,event):
if event.inaxes != self.point.axes:
return
contains = self.point.contains(event)[0]
if not contains: return
self.press = self.point.center, event.xdata, event.ydata
def button_release_event(self,event):
self.press = None
self.point.figure.canvas.draw()
# This is the part which will erase field
# and draw for us new one
self.c_kruznice = self.point.center[0], self.point.center[1]
if self.indeks == 0:
racun = polje(drs, X, Y)
ax.cla()
circles = []
circles.append(ax.add_patch(circle1))
circles.append(ax.add_patch(circle))
circles.append(ax.add_patch(circle2))
circles.append(ax.add_patch(circle3))
ax.quiver(X,Y,racun[0],racun[1], color='r', alpha=0.5)
ax.quiver(X,Y,racun[0],racun[1], edgecolor='k', facecolor='None', linewidth =.5)
plt.draw()
def motion_notify_event(self, event):
if self.press is None: return
if event.inaxes != self.point.axes: returnO
self.point.center, xpress, ypress = self.press
dx = event.xdata - xpress
dy = event.ydata - ypress
self.point.center = (self.point.center[0]+dx, self.point.center[1]+dy)
self.point.figure.canvas.draw()
if __name__ == '__main__':
f_s=0.3
def R(x,y):
r=np.sqrt(x**2+y**2)+f_s
return r
def polje(tela, X, Y):
Ex = 0
Ey = 0
for i in range(len(tela)):
r = R(tela[i].c_kruznice[0] - X, tela[i].c_kruznice[1] - Y )
ex = X - tela[i].c_kruznice[0]
ey = Y - tela[i].c_kruznice[1]
Ex += (tela[i].q/skr)*(1/(r+f_s)**3)*ex
Ey += (tela[i].q/skr)*(1/(r+f_s)**3)*ey
return Ex, Ey
fig = plt.figure(figsize=(8,8))
ax = fig.add_axes([0.05,0.05,0.92,0.92])
ax.set_xlim(-6,6)
ax.set_ylim(-6,6)
scale = 0.2
X,Y=np.mgrid[-5:5:scale, -5:5:scale]
circles = []
q=3*const.e
s=abs(q)
sx=sqrt(s/np.pi)*1e8*5
circle2 = patches.Circle((2,3), 0.3, fc='r', alpha=0.5, picker=True)
circle1 = patches.Circle((2,-3), 0.3, fc='r', alpha=0.5, picker=True)
circle = patches.Circle((-2,3), 0.3, fc='b', alpha=0.5, picker=True)
circle3 = patches.Circle((-2,-3), 0.3, fc = 'b', alpha = 0.5, picker = True )
circles.append(ax.add_patch(circle1))
circles.append(ax.add_patch(circle))
circles.append(ax.add_patch(circle2))
circles.append(ax.add_patch(circle3))
drs = []
i = 0
q = [-1, 1, -1, 1]
for c in circles:
dr = DraggablePoint(c, q[i], i)
dr.connect()
drs.append(dr)
i += 1
racun = polje(drs, X, Y)
ax.quiver(X,Y,racun[0],racun[1], color='r', alpha=0.5)
ax.quiver(X,Y,racun[0],racun[1], edgecolor='k', facecolor='None', linewidth =.5)
plt.show()
如果要为图像设置动画,请查看matplotlib.animation库。看看这个。这是个好主意,但不确定它是否简单。单击每个点时,它会触发自己的重绘。箭袋图取决于所有点的位置,因此可能不应在点移动事件中重新绘制。你可以破解一些东西,但是为了正确地完成它,你可能需要一个field类,包含所有与鼠标事件绑定的点。field类可以在更新字段时调用您已经拥有的点更新…我,某种程度上,修复了我的问题。”这段代码是有效的,但每次我移动一些圆圈时,我都需要再次单击以刷新箭袋字段。此外,只有一个补丁是完全可移动的,其他补丁在我尝试移动它们时只是取消了粘贴,然后在我“单击刷新”字段时再次重新绘制。我可以说它是有用的,买的很轻便。谢谢!!!这就是我想要的。在这之后,我在几秒钟内更新到N body visualization。