00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 from python_qt_binding import QT_BINDING, QT_BINDING_VERSION
00034 if QT_BINDING == 'pyside':
00035 try:
00036 from pkg_resources import parse_version
00037 except:
00038 import re
00039
00040 def parse_version(s):
00041 return [int(x) for x in re.sub(r'(\.0+)*$', '', s).split('.')]
00042 if parse_version(QT_BINDING_VERSION) <= parse_version('1.1.2'):
00043 raise ImportError('A PySide version newer than 1.1.0 is required.')
00044
00045 from python_qt_binding.QtCore import Slot, Qt
00046 from python_qt_binding.QtGui import QWidget, QVBoxLayout, QSizePolicy, QColor
00047
00048 import collections
00049 import operator
00050 import matplotlib
00051 if matplotlib.__version__ < '1.1.0':
00052 raise ImportError('A newer matplotlib is required (at least 1.1.0)')
00053
00054 try:
00055 from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
00056 except ImportError:
00057
00058 import sys
00059 import thread
00060 sys.modules['_thread'] = thread
00061 from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
00062 from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
00063 from matplotlib.figure import Figure
00064
00065 import numpy
00066
00067
00068 class MatDataPlot(QWidget):
00069 class Canvas(FigureCanvas):
00070 """Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.)."""
00071 def __init__(self, parent=None):
00072 fig = Figure()
00073 self.axes = fig.add_subplot(111)
00074 self.axes.grid(True, color='gray')
00075 super(MatDataPlot.Canvas, self).__init__(fig)
00076 self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
00077 self.updateGeometry()
00078
00079 _colors = [Qt.red, Qt.blue, Qt.magenta, Qt.cyan, Qt.green, Qt.darkYellow, Qt.black, Qt.darkRed, Qt.gray, Qt.darkCyan]
00080
00081 def __init__(self, parent=None):
00082 super(MatDataPlot, self).__init__(parent)
00083 self._canvas = MatDataPlot.Canvas()
00084 self._toolbar = NavigationToolbar(self._canvas, self._canvas)
00085 vbox = QVBoxLayout()
00086 vbox.addWidget(self._toolbar)
00087 vbox.addWidget(self._canvas)
00088 self.setLayout(vbox)
00089
00090 self._color_index = 0
00091 self._curves = {}
00092
00093 def add_curve(self, curve_id, curve_name, data_x, data_y):
00094 data_x = collections.deque(data_x)
00095 data_y = collections.deque(data_y)
00096 color = QColor(self._colors[self._color_index % len(self._colors)])
00097 self._color_index += 1
00098 plot = self._canvas.axes.plot(data_x, data_y, label=curve_name, linewidth=1, picker=5, color=color.name())[0]
00099 self._curves[curve_id] = (data_x, data_y, plot)
00100 self._update_legend()
00101
00102 def remove_curve(self, curve_id):
00103 curve_id = str(curve_id)
00104 if curve_id in self._curves:
00105 self._curves[curve_id][2].remove()
00106 del self._curves[curve_id]
00107 self._update_legend()
00108
00109 def _update_legend(self):
00110 handles, labels = self._canvas.axes.get_legend_handles_labels()
00111 if handles:
00112 hl = sorted(zip(handles, labels), key=operator.itemgetter(1))
00113 handles, labels = zip(*hl)
00114 self._canvas.axes.legend(handles, labels, loc='upper left')
00115
00116 @Slot(str, list, list)
00117 def update_values(self, curve_id, x, y):
00118 data_x, data_y, _ = self._curves[curve_id]
00119 data_x.extend(x)
00120 data_y.extend(y)
00121
00122 def redraw(self):
00123 self._canvas.axes.grid(True, color='gray')
00124
00125 ymin = ymax = None
00126 xmax = 0
00127 for curve in self._curves.values():
00128 data_x, data_y, plot = curve
00129 if len(data_x) == 0:
00130 continue
00131
00132 xmax = max(xmax, data_x[-1])
00133 self._canvas.axes.set_xbound(lower=xmax - 5, upper=xmax)
00134
00135 if ymin is None:
00136 ymin = min(data_y)
00137 ymax = max(data_y)
00138 else:
00139 ymin = min(min(data_y), ymin)
00140 ymax = max(max(data_y), ymax)
00141
00142
00143 delta = max(ymax - ymin, 0.1)
00144 ymin -= .05 * delta
00145 ymax += .05 * delta
00146
00147 self._canvas.axes.set_ybound(lower=ymin, upper=ymax)
00148
00149
00150 for curve in self._curves.values():
00151 data_x, data_y, plot = curve
00152 plot.set_data(numpy.array(data_x), numpy.array(data_y))
00153
00154 self._canvas.draw()