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, qWarning, Signal
00046 from python_qt_binding.QtGui import QWidget, QVBoxLayout, QSizePolicy, QColor
00047
00048 import operator
00049 import matplotlib
00050 if matplotlib.__version__ < '1.1.0':
00051 raise ImportError('A newer matplotlib is required (at least 1.1.0)')
00052
00053 try:
00054 matplotlib.use('Qt4Agg')
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 super(MatDataPlot.Canvas, self).__init__(Figure())
00073 self.axes = self.figure.add_subplot(111)
00074 self.axes.grid(True, color='gray')
00075 self.figure.tight_layout()
00076 self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
00077 self.updateGeometry()
00078
00079 def resizeEvent(self, event):
00080 super(MatDataPlot.Canvas, self).resizeEvent(event)
00081 self.figure.tight_layout()
00082
00083 limits_changed = Signal()
00084
00085 def __init__(self, parent=None):
00086 super(MatDataPlot, self).__init__(parent)
00087 self._canvas = MatDataPlot.Canvas()
00088 self._toolbar = NavigationToolbar(self._canvas, self._canvas)
00089 vbox = QVBoxLayout()
00090 vbox.addWidget(self._toolbar)
00091 vbox.addWidget(self._canvas)
00092 self.setLayout(vbox)
00093
00094 self._curves = {}
00095 self._current_vline = None
00096 self._canvas.mpl_connect('button_release_event', self._limits_changed)
00097
00098 def _limits_changed(self, event):
00099 self.limits_changed.emit()
00100
00101 def add_curve(self, curve_id, curve_name, curve_color=QColor(Qt.blue), markers_on=False):
00102
00103
00104 x_limits = self.get_xlim()
00105 y_limits = self.get_ylim()
00106 if markers_on:
00107 marker_size = 3
00108 else:
00109 marker_size = 0
00110 line = self._canvas.axes.plot([], [], 'o-', markersize=marker_size, label=curve_name, linewidth=1, picker=5, color=curve_color.name())[0]
00111 self._curves[curve_id] = line
00112 self._update_legend()
00113 self.set_xlim(x_limits)
00114 self.set_ylim(y_limits)
00115
00116 def remove_curve(self, curve_id):
00117 curve_id = str(curve_id)
00118 if curve_id in self._curves:
00119 self._curves[curve_id].remove()
00120 del self._curves[curve_id]
00121 self._update_legend()
00122
00123 def _update_legend(self):
00124 handles, labels = self._canvas.axes.get_legend_handles_labels()
00125 if handles:
00126 hl = sorted(zip(handles, labels), key=operator.itemgetter(1))
00127 handles, labels = zip(*hl)
00128 self._canvas.axes.legend(handles, labels, loc='upper left')
00129
00130 def set_values(self, curve, data_x, data_y):
00131 line = self._curves[curve]
00132 line.set_data(data_x, data_y)
00133
00134 def redraw(self):
00135 self._canvas.axes.grid(True, color='gray')
00136 self._canvas.draw()
00137
00138 def vline(self, x, color):
00139
00140 matcolor=(color[0]/255.0, color[1]/255.0, color[2]/255.0)
00141 if self._current_vline:
00142 self._current_vline.remove()
00143 self._current_vline = self._canvas.axes.axvline(x=x, color=matcolor)
00144
00145 def set_xlim(self, limits):
00146 self._canvas.axes.set_xbound(lower=limits[0], upper=limits[1])
00147
00148 def set_ylim(self, limits):
00149 self._canvas.axes.set_ybound(lower=limits[0], upper=limits[1])
00150
00151 def get_xlim(self):
00152 return list(self._canvas.axes.get_xbound())
00153
00154 def get_ylim(self):
00155 return list(self._canvas.axes.get_ybound())