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()