Matplotlib в Python - Рисование фигур и их анимация - PullRequest
5 голосов
/ 21 января 2010

Итак, я представляю сеть Token Ring (выполняю симуляцию в SimPy), я совершенно новичок в matplotlib, но мне сказали, что это было бы очень хорошо для визуального представления моей симуляции.

Так что я погуглил и выяснил, как рисовать фигуры и линии - используя add_patch и add_line соответственно по осям (я полагаю). Так что теперь у меня есть этот вывод, который совершенно нормально:

(пока нельзя публиковать изображения !!) http://img137.imageshack.us/img137/7822/screenshot20100121at120.png

Но я получаю это с помощью функции pylab.show (), и я думаю, что хочу добиться этого с помощью функции pylab.plot (), чтобы я мог обновлять ее по мере того, как моё моделирование выполняется с использованием pylab. draw () потом.

Мой код выглядит следующим образом:

plab.ion()

plab.axes()

for circ in self.circleList:
    plab.gca().add_patch(circ)

for line in self.lineList:
    plab.gca().add_line(line)

plab.axis('scaled')
plab.show()

Где circleList и lineList - списки, содержащие круги и линии на диаграмме

Возможно, я здесь неправильно понимаю что-то простое, но на самом деле я не могу найти ни одного примера, не основанного на графике, который использует функцию plot ().


Уточнение:

Как получить такой же вывод, используя pylab.plot () вместо pylab.show ()?

Ответы [ 3 ]

4 голосов
/ 21 января 2010

Репликация вашего изображения с использованием метода сюжета:

from pylab import *

points = []
points.append((-0.25, -1.0))
points.append((0.7, -0.7))
points.append((1,0))
points.append((0.7,1))
points.append((-0.25,1.2))
points.append((-1,0.5))
points.append((-1,-0.5))
points.append((-0.25, -1.0))

a_line = plot(*zip(*points))[0]
a_line.set_color('g')
a_line.set_marker('o')
a_line.set_markerfacecolor('b')
a_line.set_markersize(30)
axis([-1.5,1.5,-1.5,1.5])

show()

РЕДАКТИРОВАТЬ НА ОСНОВЕ КОММЕНТАРИЙ

При этом используется многопроцессорная библиотека python для запуска анимации matplotlib в отдельном процессе. Основной процесс использует очередь для передачи в нее данных, которая затем обновляет изображение графика.

# general imports
import random, time
from multiprocessing import Process, Queue

# for matplotlib
import random
import numpy as np
import matplotlib
matplotlib.use('GTKAgg') # do this before importing pylab

import matplotlib.pyplot as plt
from matplotlib.patches import Circle


def matplotLibAnimate(q,points):

    # set up initial plot
    fig = plt.figure()
    ax = fig.add_subplot(111)


    circles = []
    for point in points:
        ax.add_patch(Circle(point,0.1))

    a_line, = ax.plot(*zip(*points))
    a_line.set_color('g')
    a_line.set_lw(2)

    currentNode = None  
    def animate(currentNode = currentNode):
        while 1:
            newNode = q.get()
            if currentNode: currentNode.remove()
            circle = Circle(newNode,0.1)
            currentNode = ax.add_patch(circle)
            circle.set_fc('r')
            fig.canvas.draw()

    # start the animation
    import gobject
    gobject.idle_add(animate)
    plt.show()

#initial points
points = ((-0.25, -1.0),(0.7, -0.7),(1,0),(0.7,1),(-0.25,1.2),(-1,0.5),(-1,-0.5),(-0.25, -1.0))
q = Queue()
p = Process(target = matplotLibAnimate, args=(q,points,))
p.start()

# feed animation data
while 1:
    time.sleep(random.randrange(4))
    q.put(random.sample(points,1)[0])

Конечно, после этого я думаю, что вам лучше подойдет решение для работы с изображениями Whatnick. Я бы создал свой собственный графический интерфейс и не использовал бы встроенные в виджет matplotlibs. Затем я бы "оживил" свой графический интерфейс, генерируя PNG и меняя их местами.

1 голос
/ 02 декабря 2010

Звучит так, как будто у Марка есть ответ, который вы искали, но если вы решите использовать подход Whatnick и создать анимацию из отдельных png, вот код для реализации предложения Амит использовать mencoder (из http://en.wikibooks.org/wiki/Mplayer):

mencoder mf://*.png -mf w=400:h=400 -ovc lavc -lavcopts vcodec=xvid -of avi -o output.avi
1 голос
/ 21 января 2010

Основной метод заключается в обновлении данных визуализируемых элементов с использованием set_data. Затем вызовите draw (). Посмотрите, есть ли у ваших элементов окружности и линии функции set_data. В противном случае вы можете использовать pyvtk . Другой вариант - рендерить и сохранять графики в png-файлах, а затем создавать из них анимацию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...