1

私はPythonとwxPythonが初めてで、ランダムな方向にランダムな速度でボックス内の粒子をシミュレートしようとしています。粒子のプロットを表示するパネルがある wxFormBuilder で簡単な GUI を作成しました。パーティクルの位置を設定してパネルにプロットしたら、シミュレーションを開始してパーティクルの 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

ここに画像の説明を入力

シミュレーション実行後: www.merlinvs.de/after.jpg

ここに画像の説明を入力

ご覧のとおり、軸が醜くなりましたが、その理由はわかりません。

私が考えていたもう 1 つの質問は次のとおりです。UI が応答しなくなるまでに時間がかかるループを実行する場合、必要に応じて UI をアクティブにしてループをキャンセルすることは可能ですか?

4

1 に答える 1

0

応答しない 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 コンテキスト スイッチャーの範囲外でシステム コールがブロックされているためです。上記のパターンはうまく機能しますが、単純なものの場合。

于 2012-04-25T19:58:05.350 に答える