编程语言
首页 > 编程语言> > python – 如何在动画粒子的同时与mayavi窗口进行交互? (在粒子群优化期间)

python – 如何在动画粒子的同时与mayavi窗口进行交互? (在粒子群优化期间)

作者:互联网

我正在尝试使用Python和Mayavi2制作粒子群优化的动画.

动画工作正常,我的问题是,当动画为动画制作动画时,无法与绘图进行交互.具体来说我想转动图形和缩放.也许有人有动画制作经验?

我这样做的方法是首先计算粒子的位置,然后存储它们.计算完成后,我用point3d()绘制粒子在第一个时间点的位置,然后迭代使用set()方法更新数据的时间.

有没有办法可以转动图表?我听说过线程的东西,解除了渲染,但我无法弄清楚如何在我的代码中做到这一点.除了很多其他的东西,我读过:

http://code.enthought.com/projects/mayavi//docs/development/html/mayavi/mlab_animating.html

http://code.enthought.com/projects/mayavi//docs/development/html/mayavi/tips.html#acceleration-mayavi-scripts

但它无法看到如何使用它.

有什么建议?

这是我的代码:

#!/usr/bin/env python
'''
    @author rt
'''
import pylab as plt
from numpy import *
from mayavi import mlab
from threading import Thread # making plotting faster?
import ackley as ac

class Swarm(Thread, object):
    '''
        constructor for the swarm
        initializes all instance variables
    '''
    def __init__(self,objective_function):
        Thread.__init__(self)
        # optimization options
        self.omega = 0.9 # inertial constant
        self.c1 = 0.06 # cognitive/private constant
        self.c2 = 0.06 # social constant
        self.objective = objective_function # function object

        self.max_iteration = 100 # maximal number of iterations
        # Swarm stuff
        self.number = 0
        self.best = [] # gbest; the global best position
        self.particles = [] # empty list for particles
        # temporary
        self.min = self.objective.min
        self.max = self.objective.max
        self.best_evolution = []
        # self.dimensions = 2 # dimensions NB! 


    '''
        add particles to the swarm
        find the best position of particle in swarm to set global best
    '''
    def add_particles(self, n):
        for i in range(n):
            particle = Particle(self)
            if i == 0: # initialize self.best
                self.best = particle.position
            if particle.eval() < self._eval(): # check if there is a better and if, set it
                self.best = copy(particle.position) 
            self.particles.append(particle) # append the particle to the swarm    

    def _eval(self):
        return self.objective.evaluate(self.best)

    def plot(self):
        for i in range(self.max_iteration):
            pos_x = []
            pos_y = []
            pos_z = []
            #print pos_x
            for particle in self.particles:
                [x,y,z] = particle.trail[i]
                pos_x.append(x)
                pos_y.append(y)
                pos_z.append(z)
            #print pos_x
            if i ==0:
                g = mlab.points3d(pos_x, pos_y,pos_z, scale_factor=0.5)
                ms =g.mlab_source
                ms.anti_aliasing_frames = 0
            ms.set(x=pos_x, y = pos_y, z = pos_z,scale_factor=0.5)     #updating y value
            #print pos_y
            #ms.set(x=pos_x) # update x values
            #ms.set(y=pos_y)     #updating y value
            #ms.set(z=pos_z)     #updating y value

        #for p in self.particles:
            #p.plot()
    def plot_objective(self):
        delta = 0.1
        v = mgrid[self.min:self.max:delta,self.min:self.max:delta]
        z = self.objective.evaluate(v)
        #mlab.mesh(v[0],v[1],z)
        mlab.surf(v[0],v[1],z) # surf creates a more efficient data structure than mesh
        mlab.xlabel('x-axis', object=None)
        mlab.ylabel('y-axis', object=None)
        mlab.zlabel('z-axis', object=None)


    def _info(self):
        self.plot()
        print '----------------------------'
        print 'The best result is:'
        print 'Coordinates:', self.best
        print 'Value: ', self._eval()
        #print 'with ', nreval, 'evaluations'
        print 'nr of particles: ', len(self.particles)
        print '----------------------------'  

    def run(self):
        self.plot_objective()
        self.best = self.particles[0].get_position()  
        iteration = 0
        while iteration < self.max_iteration:
            #if iteration!= 0: obj.scene.disable_render = True
            #disable_render = True
            for particle in self.particles:
                rnd_c1 = array([random.uniform(0,1),random.uniform(0,1)])
                rnd_c2 = array([random.uniform(0,1),random.uniform(0,1)])
                particle.velocity = self.omega * array(particle.velocity) + \
                                    self.c1 * rnd_c1 * (array(particle.best) - array(particle.position)) + \
                                    self.c2 * rnd_c2 * (array(self.best) - array(particle.position)) # TODO: change so independent rnd for components
                particle.position = array(particle.position) + particle.velocity
                if particle.eval() < particle.best_eval():
                    particle.best = copy(particle.position)
                    if particle.eval() < self._eval():
                        self.best = copy(particle.position)
                particle.update() # add the point to the trail
            iteration +=1
            self.best_evolution.append(self._eval())
            #obj.scene.disable_render = False
        print 'finished: ', iteration
        self._info()

'''
    Class modeling particle
'''
class Particle():
    def __init__(self, swarm):
        self.swarm = swarm
        x_rand = random.uniform(self.swarm.min,self.swarm.max)
        y_rand = random.uniform(self.swarm.min,self.swarm.max)
        self.position = array([x_rand,y_rand])
        v_x_rand = random.uniform(self.swarm.min,self.swarm.max)
        v_y_rand = random.uniform(self.swarm.min,self.swarm.max)
        self.velocity = array([v_x_rand, v_y_rand])
        self.size = 0.5
        self.best = self.position
        # visualization
        self.trail = []

    def plot(self):
        [x,y] = self.position
        z = self.eval()
        mlab.points3d(x,y,z,scale_factor=self.size)
    def eval(self):
        return self.swarm.objective.evaluate(self.position)
    def best_eval(self):
        return self.swarm.objective.evaluate(self.best)
    def get_position(self):
        return self.position
    def update(self):
        [x,y] = self.position
        z = self.eval()
        #print [x,y,z]
        self.trail.append([x,y,z])
    def plot_trail(self,index):
        [x,y,z] = self.trail[index]
        mlab.points3d(x,y,z,scale_factor=self.size)

# Make the animation
mlab.figure(1, bgcolor=(0, 0, 0), size=(1300, 700)) # create a new figure with black background and size 1300x700

objective = ac.Ackley() # make an objective function

swarm = pso.Swarm(objective) # create a swarm
nr_of_particles = 25 # nr of particles in swarm

swarm.add_particles(nr_of_particles)      
swarm.run()
#swarm.start()
mlab.show()

print '------------------------------------------------------'
print 'Particle Swarm Optimization'
#objective.info()
print 'Objective function to minimize has dimension = ', objective.get_dimension()
print '# of iterations = ', 1000
print '# of particles in swarm = ', nr_of_particles
print '------------------------------------------------------'

解决方法:

在我的情况下,即使我有点能够做Brandon Rhodes建议的模拟程序(https://stackoverflow.com/questions/16617814/interacting-with-mlab-scene-while-it-is-being-drawn),我也无法转换我已经存在的大型程序.

然后我找到了这个链接:http://wiki.wxpython.org/LongRunningTasks

所以,我只是在我的循环中撒了很多wx.Yield().这样我就不需要改变我的程序结构了,而且我能够与窗口进行交互.我想在链接中解释了更好的方法.

标签:python,mayavi
来源: https://codeday.me/bug/20190709/1415321.html