Я пытаюсь создать небольшой графический интерфейс с графиком, который обновляется каждый раз, когда читается новый образец данных. Я бы предпочел не запускать его с таймером, так как данные будут поступать с разными интервалами. Вместо этого я пытаюсь сделать реализацию с использованием сигналов, где функция сбора данных будет генерировать сигнал при чтении данных, а затем функция рисования будет генерировать сигнал, когда рисование завершено.
Проблема, как кажется сейчас, заключается в том, что холст не обновляется, как только я вызываю canvas.draw(). Когда эта программа запускается, data_collect() и paint() попеременно отправляют сигналы, но рисунок не обновляется до тех пор, пока я не остановлю процесс. Как я могу заставить matplotlib обновлять фигуру всякий раз, когда вызывается paint()?
Далее следует относительно простой пример кода, который не является оптимальным, но, надеюсь, передаст суть того, что я пытаюсь сделать...
N_length = 150;
count = [0];
def sinval(delay):
k = 0;
x = [];
# set up data vector with sinusoidal data in it.
while k < N_length:
x.append(math.sin(2*math.pi*k/N_length));
k += 1;
def next():
time.sleep(delay);
outstring = "%0.3e" % (x[count[0]]);
if (count[0] == (N_length-1)):
count[0] = 0;
else:
count[0] += 1;
return outstring;
return next;
class DesignerMainWindow(QtGui.QMainWindow, Ui_mplMainWindow):
def __init__(self, parent = None):
super(DesignerMainWindow, self).__init__(parent)
self.setupUi(self)
QtCore.QObject.connect(self.mplStartButton, QtCore.SIGNAL("clicked()"), self.start_graph);
QtCore.QObject.connect(self.mplStopButton, QtCore.SIGNAL("clicked()"), self.stop_graph);
QtCore.QObject.connect(self.mplQuitButton, QtCore.SIGNAL("clicked()"), QtGui.qApp, QtCore.SLOT("quit()"));
QtCore.QObject.connect(self, QtCore.SIGNAL("data_collect()"), self.data_collect);
QtCore.QObject.connect(self, QtCore.SIGNAL("paint()"), self.paint);
def start_graph(self):
# generates first "empty" plots
self.user = [];
self.l_user, = self.mpl.canvas.ax.plot([], self.user, label='sine wave');
# set up the axes.
self.mpl.canvas.ax.set_xlim(0, 300);
self.mpl.canvas.ax.set_ylim(-1.1, 1.1);
self.mpl.canvas.draw();
# start the data collection process.
self.delay = 0.05;
self.next = sinval(self.delay);
self.emit(QtCore.SIGNAL('data_collect()'));
def data_collect(self):
outstring = self.next();
self.user.append(float(outstring.split()[0]));
self.l_user.set_data(range(len(self.user)), self.user);
self.emit(QtCore.SIGNAL('paint()'));
def paint(self):
self.mpl.canvas.draw();
self.emit(QtCore.SIGNAL('data_collect()'));
data_collect
, ниpaint
, кажется, не имеют каких-либо сюжетных команд (например,self.mpl.canvas.ax.plot
), которые могли бы изменить сюжет. Так не будет ли вызовself.mpl.canvas.draw()
просто перерисовывать тот же старый график? - person unutbu   schedule 18.08.2010self.l_user.set_data(...)
, а не перерисовывает все. (Это намного эффективнее, чем вызов plot, если вы просто хотите изменить данные графика, а не перерисовывать метки оси и т. д.) - person Joe Kington   schedule 18.08.2010