0.2秒ごとにグリッド全体を作成します。また、0.2秒ごとに新しいプロットを作成します。これにより、アプリケーションの処理速度が低下します。 新しいタイマーを作成するたびに、emitGraph
が呼び出されるたびに問題が発生する可能性があります。
プログラムを改善するには、グリッドを一度作成して内部のデータを更新するだけです。 また、プロットを1回作成し、新しいデータで更新します。 原則として、numpyは配列操作で非常に高速で、データを画面にプロットすることは問題ではありません。あなたのコードを見てみると、あなたが実際にnumpy配列の代わりにリストを使って多くの作業をしているという問題があります。リストの作成とfor-loopsを避けるようにしてください。実際には、mesh
の機能を完全になくし、それによって多くの時間を節約することができると思います。
プロットに関しては、毎回imshow()
を呼び出しないでください!たとえばself.image
のためにあなたのimshowは、プロットしたものである場合は、ちょうどあなたが使用している配列の形状に関するより多くの情報を提供し、どのようなself.slit
である私たちに伝えることができれば、私はおそらくあなたを助けることができるself.image.set_data(zz)
を呼び出すことによって、このプロットを更新もっと。
この時点で、ビームプロファイラを模倣して非常に高速に実行される次のコードを見てみたいかもしれません。
from PyQt4 import QtGui, QtCore
import numpy as np
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
import sys, time, random
class WorkerObject(QtCore.QObject):
signalStatus = QtCore.pyqtSignal(object)
def __init__(self, parent=None):
super(self.__class__, self).__init__(parent)
self.data = np.zeros((600,800))
self.x = np.arange(0,800)
self.y = np.arange(0,600)
self.Y, self.X = np.meshgrid(self.x, self.y)
self.f = lambda x, y, x0, y0, sigmax, sigmay : 0.96*np.exp(-((x-x0)/float(sigmax))**2)*np.exp(-((y-y0)/float(sigmay))**2)
@QtCore.pyqtSlot()
def startWork(self):
print "StartWork"
x0 = random.randint(250,550)
y0 = random.randint(250,350)
sigmax = random.randint(100,200)
sigmay = random.randint(100,200)
while 1 > 0:
x0, y0, sigmax, sigmay = self.doWork(x0, y0, sigmax, sigmay)
def doWork(self, x0, y0, sigmax, sigmay):
dx, dy, dsx, dsy = random.randint(0,1)*2-1, random.randint(0,1)*2-1, random.randint(0,1)*2-1, random.randint(0,1)*2-1
self.data[:,:] = (self.f(self.X, self.Y, x0+dx, y0+dy, sigmax+dsx, sigmay+dsy)+np.random.random((600,800))*0.04)*(1.+np.random.rand()*0.04-0.02)
self.signalStatus.emit(self.data)
time.sleep(0.04)
return x0+dx, y0+dy, sigmax+dsx, sigmay+dsy
class App(QtGui.QMainWindow):
signalStatus = QtCore.pyqtSignal(object)
abortSignal = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(App, self).__init__(parent)
self.button_start = QtGui.QPushButton('Start',self)
self.button_cancel = QtGui.QPushButton('Cancel', self)
self.label_status = QtGui.QLabel('', self)
self.mainbox = QtGui.QWidget(self)
self.layout = QtGui.QVBoxLayout()
self.mainbox.setLayout(self.layout)
self.setCentralWidget(self.mainbox)
self.layout.addWidget(self.button_start)
self.layout.addWidget(self.button_cancel)
self.layout.addWidget(self.label_status)
self.fig = Figure((6.0, 3.0), dpi=72)
self.canvas = FigureCanvas(self.fig)
self.canvas.setParent(self)
self.canvastoolbar = NavigationToolbar(self.canvas, self)
self.fig.patch.set_alpha(0.0)
self.ax = self.fig.add_subplot(111)
self.x = np.arange(0,800); self.y = np.arange(0,600)
self.im = self.ax.imshow(np.zeros((600, 800)), origin='upper', vmin=0, vmax=1)
self.pv, = self.ax.plot(np.zeros(600) ,self.y , color="white" , alpha=0.6, lw=2)
self.ph, = self.ax.plot(self.x ,np.zeros(800) , color="white" , alpha=0.6, lw=2)
self.ax.set_xlim([0,800]); self.ax.set_ylim([0,600])
self.layout.addWidget(self.canvas)
self.layout.addWidget(self.canvastoolbar)
self.initWorker()
def initWorker(self):
self.worker = WorkerObject()
self.worker_thread = QtCore.QThread()
self._connectSignals()
self.worker.moveToThread(self.worker_thread)
self.worker_thread.start()
def _connectSignals(self):
self.button_start.clicked.connect(self.worker.startWork)
self.button_cancel.clicked.connect(self.forceWorkerQuit)
self.worker.signalStatus.connect(self.updateStatus)
def forceWorkerQuit(self):
print "calculation aborted"
if self.worker_thread.isRunning():
self.worker_thread.terminate()
self.worker_thread.start()
@QtCore.pyqtSlot(object)
def updateStatus(self, obj):
self.im.set_data(obj)
argm = np.unravel_index(np.argmax(obj), (600,800))
self.pv.set_data(obj[:,argm[0]]*250, self.y)
self.ph.set_data(self.x, obj[argm[1], :]*250)
self.fig.canvas.draw()
if __name__=='__main__':
app = QtGui.QApplication(sys.argv)
thisapp = App()
thisapp.show()
sys.exit(app.exec_())
編集(zz
を計算する方法を求めて、下記のコメント答):
私が正しく理解していれば、あなたのslit_data_int[0]
はX方向に蓄積された強度であり、slit_data_int[1]
は、Y方向の一方です。zz[j,i] = slit_data_int[1][j]*slit_data_int[0][i]
場合、これはnumpyのでは行列の乗算(np.outer
)を使用して、より良い計算されます。
zz[:,:] = np.outer(slit_data_int[1], slit_data_int[0])
ありがとうございました!それは私の問題のほとんどを解決しましたが、私はまだzzデータを計算する方法にいくつかの問題があります。ビームプロファイラーは4つのスリットからデータを返します。したがって、このnp.array([[slit1データ]、[slit2data]、[slit3data]、[slit4data]])のようなベクトルです。スリット0(X軸)と1(Y軸)は25umスリットで、2と3は5umスリットです。だから私は自分が選んでいるスリットを選ぶためにself.slitを使うだけです。 強度行列だけをプロットしているので、位置ベクトルが使用されていないため、私のデータをプロットする方法を理解できません – Eduardo
スリット2と3は何ですか?彼らはまったく使用されていますか?とにかく、スリットは動いているのですか?あるいは、ちょうど2つの1Dアレイから完全な2次元情報を得るにはどうしますか? – ImportanceOfBeingErnest
私のGuiにスリットを変更するラジオボタンがあります。したがって、0と1または2と3のいずれかです。 実際には1Dアレイは4つです。これは、X軸とY軸の2つのペアであるとしましょう。最初のペアでは、1つの位置配列と、位置配列の各点の強度を示す1つの強度配列があります。 したがって、完全な2Dデータを再構成するには、XとYの位置に基づいてグリッドを作成し、強度の行列を作成する必要があります。その要素は直交軸上の投影の強度積です。このように:ZMatrix [i、j] = intx(i)* inty(j) – Eduardo