Найти - Пользователи
Полная версия: [GTK] Обновление графика Matplotlib
Начало » GUI » [GTK] Обновление графика Matplotlib
1
jag
Имеется прога, которая принимает данные извне и неким образом ведет статистику. Для этого я создал отдельный поток, в котором все что нужно вычисляется и обновляется на экране. Кроме цифр нужно ещё вывести график, который обновляется грубо говоря раз в секунду. Делал вот по этому примеру: http://matplotlib.sourceforge.net/examples/animation/simple_anim_gtk.html только вызов animate у меня происходит в потоке, а не через gobject (при вызове gobject.idle_add(animate) интерфейс вообще не прорисовывается).
Сам график инициализируется в потоке так:
import matplotlib
matplotlib.use('GTKAgg')
import matplotlib.pyplot as plt
from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas
#...
self.fig = plt.figure()
self.ax = self.fig.add_subplot(111)
self.ax.grid()
self.x = [i for i in range(50)]
self.y = [300 for i in range(50)]
self.line, = self.ax.plot(self.x, self.y, lw=2)
self.canvas = FigureCanvas(self.fig)
self.processcls.vbox5.pack_start(self.canvas)
self.canvas.show()
#...
Исходник функции обновления, тут через random просто эмулируются поступающие данные:
def animate(self):
self.y.pop(0)
self.y.append(round(random.uniform(290, 310), 1))
self.line.set_ydata(self.y)
self.canvas = FigureCanvas(self.fig)
self.canvas.draw()
Проблема в следующем: график обновляется только при изменении размера окна! Как перерисовать его без этого?
Ещё методом научного тыка в функцию animate я добавил строчку self.canvas = FigureCanvas(self.fig) - без неё через 5-10 секунд программа просто подвисает, никаких сообщений на консоль не выдается. Что с этим можно сделать? Нужно чтобы график обновлялся нормально. Я пробовал другие способы обновления/анимации, через blit и draw_artist, через ion тоже пробовал, но они вообще не заработали в моей программе.
Может есть какие-нибудь альтернативные способы построения и обновления простейших графиков? Куда копать?
DonVulture
Проблема в том, что вы совместно используете метод show и draw

class TGraphic(object):
“”“набор графиков”“”
def __init__(self,x,y):
self.fig=plt.figure()
self.x=x
self.y=y


def Plot(self):
# сначала почистим канву
# self.fig.clear() # вам можно канву не чистить
self.fig.canvas.draw()
ax = self.fig.add_subplot(1,1,1)
ax.plot(x,y)

# отобразить
self.fig.canvas.draw()
jag
DonVulture
Проблема в том, что вы совместно используете метод show и draw
Но без show график просто не отображается в интерейсе, этот метод же к gtk относится, а не к matplotlib, почему их нельзя совместно использовать?
jag
Немного одуплился с этими графиками. Оказывается, при вызове функции animate из потока на консоль выдается ошибка (почему-то не была видна из консоли моей IDE - это было последней каплей и теперь только vim):

The program ‘panel.py’ received an X Window System error.
This probably reflects a bug in the program.
The error was ‘BadDrawable (invalid Pixmap or Window parameter)’.
(Details: serial 6974 error_code 9 request_code 62 minor_code 0)
(Note to programmers: normally, X errors are reported asynchronously;
that is, you will receive the error a while after causing it.
To debug your program, run it with the –sync command line
option to change this behavior. You can then get a meaningful
backtrace from your debugger if you break on the gdk_x_error() function.)

Почему так случается я так и не понял, но пока обхожусь костылем - обновляю график по нажатию кнопки. Какое бы событие придумать, чтобы оно тупо раз в секунду срабатывало и вызывало мою функцию?
DonVulture
Передо мной стоит задача сделать график с аналогичной функциональностью. Делаю его не в GTK, а в Wx.
Пока перерисовываю по нажатию кнопки. Планирую повесить на onIdle или обновление данных в БД.
Можно взять таймер.
jag
Благодарю, строчка gobject.timeout_add(1000, self.animate) решила все вопросы.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB