在wxPython中使用draw()(复制轴)绘制不正确

2024-04-27 04:22:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我是Python和wxPython的新手,我尝试在一个盒子里模拟粒子,在随机的方向上以随机的速度。 我在wxFormBuilder中创建了一个简单的GUI,其中我有一个面板来显示paricles的图。粒子被设置到一个位置并绘制到面板上,然后我开始模拟并更新粒子的x和y位置。当重新绘制位置时,轴看起来像以前一样“粗”,看起来好像有几个轴在上面。在

我找不到关于这个问题的任何信息,我希望有人能帮我解决这个问题?在

这是创建绘图的代码:

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

接下来是按钮定义,如下所示: 在运行模拟之前:www.merlinvs.de/before.jpg

enter image description here

运行模拟后:www.merlinvs.de/after.jpg

enter image description here

你看斧子变丑了,我不知道为什么。在

我想的另一个问题是: 当我运行一个需要一段时间UI没有响应的循环时,是否可以让UI处于活动状态以取消循环(如果需要)?在


Tags: inimportselfformatplotlibdef粒子range
1条回答
网友
1楼 · 发布于 2024-04-27 04:22:11

至于无响应的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上下文切换器无法访问的系统调用。虽然上面的模式很简单。在

相关问题 更多 >