Написал тестовый примерчик для того, чтобы немного разобраться с matplotlib:
# -*- coding:utf8 -*-
import sys
import numpy as np
from PyQt4 import QtGui
from PyQt4 import QtCore
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg \
import FigureCanvasQTAgg as FigureCanvas
class Monitor(FigureCanvas, QtCore.QObject):
def __init__(self):
self.fig = Figure(facecolor='#E8D6BB', edgecolor='#000000')
self.ax = self.fig.add_subplot(111, axisbg='#E8D6BB')
# initialize the figure canvas
FigureCanvas.__init__(self, self.fig)
# set up the display limits for the figure
self.ax.set_xlim(0,30)
self.ax.set_ylim(0,1)
# turn off autoscaling
self.ax.set_autoscale_on(False)
line, = self.ax.plot(np.random.rand(100), 'o', picker=5)
self.fig.canvas.draw()
self.stopButtonAction = False
@QtCore.pyqtSignature("")
def zoomIn(self):
"""
Увеличиваем в 2 раза
"""
self.stopButtonAction = True
while self.stopButtonAction:
start, end = self.ax.get_xaxis().get_view_interval()
print start, end, end-start
if (end - start > 0.0001):
self.ax.get_xaxis().set_view_interval( start + ((end - start)/4)
, end - ((end - start)/4), True)
print "Before draw"
self.fig.canvas.draw()
print "Before Qt"
QtGui.qApp.processEvents();
@QtCore.pyqtSignature("")
def zoomOut(self):
"""
Увеньшает в 2 раза
"""
self.stopButtonAction = True
while self.stopButtonAction:
start, end = self.ax.get_xaxis().get_view_interval()
self.ax.get_xaxis().set_view_interval( start - ((end - start)/2)
, end + ((end - start)/2), True)
self.fig.canvas.draw()
QtGui.qApp.processEvents();
@QtCore.pyqtSignature("")
def panLeft(self):
"""
Сдвигаем на 1/10
"""
self.stopButtonAction = True
while self.stopButtonAction:
start, end = self.ax.get_xaxis().get_view_interval()
interval = (end - start)/10
self.ax.get_xaxis().set_view_interval( start - interval
, end - interval, True)
self.fig.canvas.draw()
QtGui.qApp.processEvents();
@QtCore.pyqtSignature("")
def panRight(self):
self.stopButtonAction = True
while self.stopButtonAction:
start, end = self.ax.get_xaxis().get_view_interval()
interval = (end - start)/10
self.ax.get_xaxis().set_view_interval( start + interval
, end + interval, True)
self.fig.canvas.draw()
QtGui.qApp.processEvents();
@QtCore.pyqtSignature("")
def stopAction(self):
self.stopButtonAction = False
if __name__ == "__main__":
# set up the qt application
app = QtGui.QApplication(sys.argv)
# initialize the widget
window = QtGui.QWidget()
buttonZoomIn = QtGui.QPushButton("ZoomIn");
buttonZoomOut = QtGui.QPushButton("ZoomOut");
buttonPanLeft = QtGui.QPushButton("PanLeft");
buttonPanRight = QtGui.QPushButton("PanRight");
scrollbar = QtGui.QScrollBar()
w = Monitor()
w.setWindowTitle('Updating in real time')
layout = QtGui.QVBoxLayout()
layout.addWidget(buttonZoomIn)
layout.addWidget(buttonZoomOut)
layout.addWidget(buttonPanLeft)
layout.addWidget(buttonPanRight)
layout.addWidget(w)
#w.show()
window.setLayout(layout)
window.show()
QtCore.QObject.connect(buttonZoomIn, QtCore.SIGNAL("pressed()"), w.zoomIn )
QtCore.QObject.connect(buttonZoomOut, QtCore.SIGNAL("pressed()"), w.zoomOut )
QtCore.QObject.connect(buttonPanLeft, QtCore.SIGNAL("pressed()"), w.panLeft )
QtCore.QObject.connect(buttonPanRight, QtCore.SIGNAL("pressed()"), w.panRight )
QtCore.QObject.connect(buttonZoomIn, QtCore.SIGNAL("released()"), w.stopAction )
QtCore.QObject.connect(buttonZoomOut, QtCore.SIGNAL("released()"), w.stopAction )
QtCore.QObject.connect(buttonPanRight, QtCore.SIGNAL("released()"), w.stopAction )
QtCore.QObject.connect(buttonPanLeft, QtCore.SIGNAL("released()"), w.stopAction )
# start the main application loop
sys.exit(app.exec_())
Всё работает здорово до тех пор пока не начал делать сильное увеличение. Например если увеличиваю в окрестности 0, то дойдя до значений 0.000010 0.000015 ловлю seg fault. Немного удивился, ну да ладно. Сделал небольшое ограничение и повторил. Всё работает.. но вотк акая не задача.. при отдалении от точки ноль к числу скажем 20 000 и попытка проделать приводт к тому, что seg fault возникает гораздо раньше, когда разница между крайними значениями порядка 0.01. Причём возникает он перед отрисовкой где-то в self.fig.canvas.draw()
Самое весёлое, что в тестовом примере
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
line, = ax.plot(np.random.rand(100), 'o', picker=5) # 5 points tolerance
def onpick(event):
thisline = event.artist
xdata = thisline.get_xdata()
ydata = thisline.get_ydata()
ind = event.ind
print 'onpick points:', zip(xdata[ind], ydata[ind])
fig.canvas.mpl_connect('pick_event', onpick)
ax.set_xlim(0, 10)
ax.set_ylim(-1, 1)
ax.set_ybound(-1,1)
plt.show()
з.ы. Ещё поймал странный глюк при попытке использовать zoom(5) при разметке x: 0 - 30 y: 0 - 1. Ось x сжимается куда-то…