Подтвердить что ты не робот

Pylab.ion() в python 2, matplotlib 1.1.1 и обновление графика во время выполнения программы

то, что я пытаюсь сделать, это script вычислить что-то, подготовить график и показать уже полученные результаты как pylab.figure - в python 2 (в частности, python 2.7) со стабильным matplotlib (который равен 1.1. 1).

В python 3 (python 3.2.3 с matplotlib git build... version 1.2.x) это работает отлично. В качестве простого примера (моделирования длительных вычислений по time.sleep()) рассмотрим

import pylab
import time
import random

dat=[0,1]
pylab.plot(dat)
pylab.ion()
pylab.draw()    
for i in range (18):
    dat.append(random.uniform(0,1))
    pylab.plot(dat)
    pylab.draw()
    time.sleep(1)

В python 2 (версия 2.7.3 vith matplotlib 1.1.1) код работает без ошибок, но не показывает этот рисунок. Небольшая пробная версия и ошибка с интерпретатором python2, казалось, предлагали заменить pylab.draw() на pylab.show(); сделать это один раз, по-видимому, достаточно (не так, как при рисовании, называя его после каждого изменения/добавления к сюжету). Следовательно:

import pylab
import time
import random

dat=[0,1]
pylab.plot(dat)
pylab.ion()
pylab.show()    
for i in range (18):
    dat.append(random.uniform(0,1))
    pylab.plot(dat)
    #pylab.draw()
    time.sleep(1)

Однако это тоже не работает. Опять же, он работает чисто, но не показывает цифру. Кажется, это делается только при ожидании ввода пользователем. Мне непонятно, почему это так, но график наконец показан, когда raw_input() добавляется в цикл

import pylab
import time
import random

dat=[0,1]
pylab.plot(dat)
pylab.ion()
pylab.show()    
for i in range (18):
    dat.append(random.uniform(0,1))
    pylab.plot(dat)
    #pylab.draw()
    time.sleep(1)
    raw_input()

При этом script, конечно, будет ждать ввода пользователя, показывая график, и не будет продолжать вычислять данные до того, как пользователь попадет в enter. Это было, конечно, не намерение.

Это может быть вызвано различными версиями matplotlib (1.1.1 и 1.2.x) или разными версиями python (2.7.3 и 3.2.3).

Есть ли способ выполнить с python 2 со стабильным (1.1.1) matplotlib то, что имеет вышеуказанный script (первый) в python 3, matplotlib 1.2.x: - вычисление данных (что в приведенном выше примере занимает симуляция time.sleep()) в цикле или итерированной функции и - (пока все еще вычисляет), показывая то, что уже было вычислено в предыдущих итерациях - и не беспокоить пользователя, чтобы он постоянно нажимал enter для вычисления, чтобы продолжить

Спасибо; Буду признателен за любую помощь...

4b9b3361

Ответ 1

Вы хотите, чтобы функция pause дала фреймворку gui возможность повторного рисования экрана:

import pylab
import time
import random
import matplotlib.pyplot as plt

dat=[0,1]
fig = plt.figure()
ax = fig.add_subplot(111)
Ln, = ax.plot(dat)
ax.set_xlim([0,20])
plt.ion()
plt.show()    
for i in range (18):
    dat.append(random.uniform(0,1))
    Ln.set_ydata(dat)
    Ln.set_xdata(range(len(dat)))
    plt.pause(1)

    print 'done with loop'

Вам не нужно создавать новый объект Line2D каждый проход, вы можете просто обновить данные в существующем.

Документация:

pause(interval)
    Pause for *interval* seconds.

    If there is an active figure it will be updated and displayed,
    and the gui event loop will run during the pause.

    If there is no active figure, or if a non-interactive backend
    is in use, this executes time.sleep(interval).

    This can be used for crude animation. For more complex
    animation, see :mod:`matplotlib.animation`.

    This function is experimental; its behavior may be changed
    or extended in a future release.

На самом деле метод over-kill заключается в использовании модуля matplotlib.animate. С другой стороны, это дает вам хороший способ сохранить данные, если вы хотите (разорвал мой ответ на Python - 1 секунда сюжета, непрерывная презентация).

example, api, tutorial

Ответ 2

Некоторые серверы (по моему опыту "Qt4Agg" ) требуют функции pause, как предположил @tcaswell.

Другие бэкенды (по моему опыту "TkAgg" ), похоже, просто обновлены на draw(), не требуя pause. Таким образом, еще одним решением является переключить ваш сервер, например, с помощью matplotlib.use('TkAgg').