使用wxPython中的draw()(复制轴)正确绘制未向上倾斜
我对Python和wxPython还不熟悉,我正在尝试模拟盒子中的粒子,在随机方向上具有随机速度。 我在wxFormBuilder中创建了一个简单的GUI,在这里我有一个面板来显示分区图。粒子被设置到某个位置并绘制到面板上,然后我开始模拟并更新粒子的x和y位置。当重新绘制位置时,轴看起来像以前一样“更厚”,看起来好像有几个轴在彼此的顶部 我找不到关于这个问题的任何信息,我希望有人能帮我解决这个问题 这是创建绘图的代码:使用wxPython中的draw()(复制轴)正确绘制未向上倾斜,python,plot,wxwidgets,axes,Python,Plot,Wxwidgets,Axes,我对Python和wxPython还不熟悉,我正在尝试模拟盒子中的粒子,在随机方向上具有随机速度。 我在wxFormBuilder中创建了一个简单的GUI,在这里我有一个面板来显示分区图。粒子被设置到某个位置并绘制到面板上,然后我开始模拟并更新粒子的x和y位置。当重新绘制位置时,轴看起来像以前一样“更厚”,看起来好像有几个轴在彼此的顶部 我找不到关于这个问题的任何信息,我希望有人能帮我解决这个问题 这是创建绘图的代码: import wx import particles import ra
import wx
import particles
import random
import matplotlib
matplotlib.use('WXAgg')
from matplotlib.figure import Figure
from matplotlib.backends.backend_wxagg import \
FigureCanvasWxAgg as FigCanvas, \
NavigationToolbar2WxAgg as NavigationToolbar
matplotlib.rcParams.update({'font.size': 8})
class MyFrameSub( particles.GUI_MainFrame ):
def __init__( self, parent ):
particles.GUI_MainFrame.__init__( self, parent )
def InitData(self):
self.npart = int(self.m_npart.GetValue())
self.nsteps = int(self.m_steps.GetValue())
self.ndt = float(self.m_dt.GetValue())
self.x= [random.random() for I in range(self.npart)]
self.y= [2*random.random()-1 for I in range(self.npart)]
self.vx= [self.ndt*(2*random.random()-1) for I in range(self.npart)]
self.vy= [self.ndt*(2*random.random()-1) for I in range(self.npart)]
return
def CreatePlot(self):
panelsize = self.m_PlotPanel.GetClientSize()
self.figure = Figure(figsize=(panelsize[0]/100.0,panelsize[1]/100.0), dpi=100, frameon=False)
self.canvas = FigCanvas(self.m_PlotPanel, wx.ID_ANY, self.figure)
self.axes = self.figure.add_subplot(111)
self.axes.axis((-1,1,-1,1))
self.partplot, = self.axes.plot(self.x, self.y, 'ro')
self.canvas.draw()
return
def UpdateData(self):
for i in range(self.nsteps):
for j in range(self.npart):
self.x[j]=self.x[j]+self.vx[j]
self.y[j]=self.y[j]+self.vy[j]
if abs(self.x[j])>1:
self.vx[j]=-self.vx[j]
if abs(self.y[j])>1:
self.vy[j]=-self.vy[j]
self.partplot.set_xdata(self.x)
self.partplot.set_ydata(self.y)
self.canvas.draw()
return
后面是按钮定义,如下所示:
在运行模拟之前:
运行模拟后:
正如你所看到的,斧子变丑了,我不知道为什么
我想的另一个问题是:
当我运行一个UI没有响应的循环时,如果需要,是否可以让UI处于活动状态以取消循环?对于没有响应的UI,我在更新Matplotlib时使用了greenlets
from gevent.greenlet import Greenlet
from gevent import sleep
import matplotlib.plot as plt
# Plot stuff
def event_handler():
# Can update plot
sleep(1) # Simulate handling or number crunching (numpy WILL block)
g = Greenlet(event_handler)
g.start()
plt.plot(0,0) # Works immediately and updates
值得注意的是,对于严肃的应用程序,您需要添加一些保护,以防止在绘图时出现种族冲突。根据我的经验,Numpy和外部科学库通常会导致整个应用程序变得无响应,因为它们阻止了greenlet上下文切换器范围之外的系统调用。对于一些简单的东西,尽管上面的模式效果很好。感谢您指向greenlets,这看起来非常有趣。我将详细阅读这篇文章,因为我还不完全理解它。greenlet是在python实例中排序和切换的类似线程的tasklet。由于Python的全局解释器锁线程效率低下,因此Greenlets介入并控制上下文切换,并为使用并发性提供非常干净的API,在本例中,一个用于绘图,一个用于事件循环,用于侦听用户操作。下面几页介绍了上述问题的解决方案:特别是第二个链接提供了详细信息。我不知道如何结束这个问题,因为我不能接受我自己写的答案。