class GraphCommonNew: def __init__(self, lay=None, wgt=None): self.fig = Figure() self.canvas = FigureCanvas(self.fig) self.gui_graph(wgt, lay) self.leg_selected = False self.data = None self.var_x = None self.unit_x = "num" self.unit_y = None self.flood_mark = False self.obs = False self.update_limites = True def init_ui_common_p(self): self.list_var = [] self.courbes = [] self.annotation = [] self.courbeLaisses = [] self.fig.canvas.mpl_connect('button_release_event', self.graph_off_click) self.fig.canvas.mpl_connect('button_press_event', self.graph_on_click) self.fig.canvas.mpl_connect('motion_notify_event', self.graph_on_press) self.fig.canvas.mpl_connect('pick_event', self.graph_on_pick) def gui_graph(self, wgt, lay_graph, lay_toolbar=None): lay_graph.addWidget(self.canvas) self.toolbar = NavigationToolbar(self.canvas, wgt) if lay_toolbar is not None: lay_toolbar.addWidget(self.toolbar) else: lay_graph.addWidget(self.toolbar) def set_data(self, data, var_x): self.data = data self.var_x = var_x def graph_on_pick(self, evt): art = evt.artist if art == self.leg: self.leg_selected = True elif art in self.lined.keys(): btn = evt.mouseevent.button if btn == 1: courbe = self.lined[art] vis = not courbe.get_visible() courbe.set_visible(vis) if vis: art.set_alpha(1.0) if courbe.get_label() == "Flood marks": for e in self.etiquetteLaisses: e.set_visible(True) else: art.set_alpha(0.2) if courbe.get_label() == "Flood marks": for e in self.etiquetteLaisses: e.set_visible(False) self.maj_limites() def graph_on_click(self, evt): if (not self.leg_selected) and self.data: self.flag = True if evt.button == 1: self.affiche_cadre(evt) self.fig.canvas.draw() def graph_off_click(self, event): if (not self.leg_selected) and self.data: for a in self.annotation: a.set_visible(False) self.v_line.set_visible(False) self.flag = False self.canvas.draw() self.leg_selected = False def graph_on_press(self, event): if (not self.leg_selected) and self.data: if event.button == 1 and self.flag: self.affiche_cadre(event) def affiche_cadre(self, event): no_tool = True for c in self.toolbar.findChildren(QToolButton): if c.isChecked(): no_tool = False break if not no_tool or not event.inaxes: for a in self.annotation: a.set_visible(False) self.v_line.set_visible(False) self.canvas.draw() return if self.unit_x == 'date': temp = round((event.xdata - 719163) * 24) * 3600 decal = datetime.utcfromtimestamp(temp) absc = min(self.data[self.var_x], key=lambda x: abs(x - decal)) else: absc = min(self.data[self.var_x], key=lambda x: abs(x - event.xdata)) idx = self.data[self.var_x].index(absc) ymin, ymax = self.axes.get_ylim() annot = self.annotation[0] annot.set_text("{}".format(absc)) annot.xytext = (10, 20) annot.xy = (absc, ymin) annot.set_visible(True) for var in self.list_var: idx_a = var["id"] annot = self.annotation[idx_a + 1] if self.data[var["name"]] and self.courbes[idx_a].get_visible(): val = self.data[var["name"]][idx] annot.set_text("{} {}".format(val, self.unit_y)) annot.xy = (absc, val) annot.set_visible(True) else: annot.set_visible(False) self.v_line.set_xdata(absc) self.v_line.set_visible(True) self.canvas.draw() def init_legende(self, handles=None): if not handles: handles = self.courbes liste_noms = [] for c in self.courbes: if c.get_visible(): liste_noms.append(c.get_label()) self.leg = self.axes.legend(handles, liste_noms, loc='upper right', fancybox=False, shadow=False, fontsize=7.) self.leg.get_frame().set_alpha(0.4) self.leg.set_zorder(110) DraggableLegendNew(self.leg) self.lined = dict() for legline, courbe in zip(self.leg.get_lines(), self.courbes): legline.set_picker(5) legline.set_linewidth(3) self.lined[legline] = courbe def maj_unit_x(self, unit): self.unit = unit self.axes.set_xlabel("time ({})".format(unit)) if self.unit == 'date': self.unit_x = 'date' self.axes.xaxis.set_major_formatter( mdates.DateFormatter('%d-%m-%Y')) else: self.unit_x = 'num' self.axes.xaxis.set_major_formatter(ticker.ScalarFormatter()) def maj_courbes(self, courbes): for c in courbes.keys(): self.courbes[c].set_data(courbes[c]["x"], courbes[c]["y"]) self.maj_limites() def maj_limites(self): no_data = True fst = True if self.update_limites: for courbe in self.courbes: if courbe.get_visible(): try: lx, lz = courbe.get_data() lx = [x for x in lx if x is not None] lz = [z for z in lz if z is not None] if lx and lz: no_data = False if fst: fst = False mini_x = min(lx) maxi_x = max(lx) mini_z = min(lz) - 1 maxi_z = max(lz) + 1 else: mini_x = min(mini_x, min(lx)) maxi_x = max(maxi_x, max(lx)) mini_z = min(mini_z, min(lz) - 1) maxi_z = max(maxi_z, max(lz) + 1) except AttributeError as e: pass if no_data: self.axes.set_xlim(0., 1.) self.axes.set_ylim(0., 1.) else: self.axes.set_xlim(mini_x, maxi_x) self.axes.set_ylim(mini_z, maxi_z) self.fig.autofmt_xdate() self.canvas.draw()
class QMplWidget (QtGui.QWidget): picked = QtCore.pyqtSignal (str) axisChanged = QtCore.pyqtSignal (tuple, tuple) def __init__(self, parent=None): super(QMplWidget, self).__init__(parent) self.figure = Figure() self.canvas = FigureCanvas(self.figure) try: self.ax = self.figure.add_subplot(111) except: rcdefaults() self.ax = self.figure.add_subplot(111) self.toolbar = NavigationToolbar(self.canvas, self) map (lambda a: a.setVisible(False), filter(lambda a: a.text() in ['Customize'], self.toolbar.findChildren(QtGui.QAction))) layout = QtGui.QVBoxLayout() layout.addWidget(self.canvas) layout.addWidget(self.toolbar) self.setLayout(layout) def on_pick(event): if event.mouseevent.button == 1: label = event.artist.get_label() if len(label): self.picked.emit (label) self.canvas.mpl_connect('pick_event', on_pick) self.legendCols = 1 self.legendPos = 0 self.grid = rcParams['axes.grid'] self.qualifiedColorMaps = ['Accent', 'Dark2', 'Paired', 'Pastel1', 'Pastel2', 'Set1', 'Set2', 'Set3'] self.colorMap = None self.oldLines = {} self.xdate = False self.ydate = False self.clean() def genColorMap (self, numColors=10, colorMapName = ''): if not colorMapName in self.qualifiedColorMaps: colorMapName = self.qualifiedColorMaps[randint(1,len(self.qualifiedColorMaps))-1] cm = get_cmap(colorMapName, numColors) self.colorMap = [cm(1.*i/numColors) for i in range(numColors)] def clean (self, xField='', yField='', resetStyle = False): self.oldLines = {} if not resetStyle: map (lambda l: self.oldLines.__setitem__(l.get_label(),l), self.ax.get_lines()) self.ax.cla() def on_axeslim_changed (ax): self.axisChanged.emit (ax.get_xlim(),ax.get_ylim()) self.ax.callbacks.connect('xlim_changed', on_axeslim_changed) self.ax.callbacks.connect('ylim_changed', on_axeslim_changed) on_axeslim_changed (self.ax) self.xdate = (xField == 'Time') self.ydate = (yField == 'Time') self.ax.set_color_cycle(self.colorMap) def applyTimeFormat (self, timeFormat = ''): timeFormatter = mpdates.DateFormatter(timeFormat) if len(timeFormat) else None if self.xdate and timeFormatter: self.ax.xaxis.set_major_formatter(timeFormatter) if self.ydate and timeFormatter: self.ax.yaxis.set_major_formatter(timeFormatter) self.figure.autofmt_xdate() def plot(self, x=[], y=[], label = None): def _float(value): try: return float(value) except: return -9999 if self.xdate: x = [mpdates.datestr2num(v) for v in x] else: x = [_float(v) for v in x] if self.ydate: y = [mpdates.datestr2num(v) for v in y] else: y = [_float(v) for v in y] line, = self.ax.plot (x, y, label = label, picker=5) if self.xdate: self.ax.xaxis_date() if self.ydate: self.ax.yaxis_date() if self.oldLines.has_key(label): line.update_from(self.oldLines.pop(label)) def updateLegend (self): self.ax.legend(loc = self.legendPos, ncol = self.legendCols) legend = self.ax.get_legend() if legend: legend.draggable (True) @property def xLim (self): return self.ax.get_xlim() @xLim.setter def xLim (self, xRange): self.ax.set_xlim (xRange) @property def yLim (self): return self.ax.get_ylim() @yLim.setter def yLim (self, yRange): self.ax.set_ylim (yRange) @property def title (self): return self.ax.get_title() @title.setter def title (self, value): self.ax.set_title (value, weight='bold') @property def xLabel (self): return self.ax.get_xlabel() @xLabel.setter def xLabel (self, value): self.ax.set_xlabel (value) @property def yLabel (self): return self.ax.get_ylabel() @yLabel.setter def yLabel (self, value): self.ax.set_ylabel (value) @property def legendVisible (self): return self.ax.get_legend().get_visible() if self.ax.get_legend() else False @legendVisible.setter def legendVisible (self, value): if value: self.updateLegend () try: self.ax.get_legend().set_visible (value) except: pass @property def gridVisible (self): return self.grid @gridVisible.setter def gridVisible (self, value): self.grid = value self.ax.grid(self.grid) def draw (self): self.canvas.draw() self.axisChanged.emit (self.ax.get_xlim(),self.ax.get_ylim())
class QMplWidget(QtGui.QWidget): picked = QtCore.pyqtSignal(str) axisChanged = QtCore.pyqtSignal(tuple, tuple) def __init__(self, parent=None): super(QMplWidget, self).__init__(parent) self.figure = Figure() self.canvas = FigureCanvas(self.figure) try: self.ax = self.figure.add_subplot(111) except: rcdefaults() self.ax = self.figure.add_subplot(111) self.toolbar = NavigationToolbar(self.canvas, self) map( lambda a: a.setVisible(False), filter(lambda a: a.text() in ['Customize'], self.toolbar.findChildren(QtGui.QAction))) layout = QtGui.QVBoxLayout() layout.addWidget(self.canvas) layout.addWidget(self.toolbar) self.setLayout(layout) def on_pick(event): if event.mouseevent.button == 1: label = event.artist.get_label() if len(label): self.picked.emit(label) self.canvas.mpl_connect('pick_event', on_pick) self.legendCols = 1 self.legendPos = 0 self.grid = rcParams['axes.grid'] self.qualifiedColorMaps = [ 'Accent', 'Dark2', 'Paired', 'Pastel1', 'Pastel2', 'Set1', 'Set2', 'Set3' ] self.colorMap = None self.oldLines = {} self.xdate = False self.ydate = False self.clean() def genColorMap(self, numColors=10, colorMapName=''): if not colorMapName in self.qualifiedColorMaps: colorMapName = self.qualifiedColorMaps[ randint(1, len(self.qualifiedColorMaps)) - 1] cm = get_cmap(colorMapName, numColors) self.colorMap = [cm(1. * i / numColors) for i in range(numColors)] def clean(self, xField='', yField='', resetStyle=False): self.oldLines = {} if not resetStyle: map(lambda l: self.oldLines.__setitem__(l.get_label(), l), self.ax.get_lines()) self.ax.cla() def on_axeslim_changed(ax): self.axisChanged.emit(ax.get_xlim(), ax.get_ylim()) self.ax.callbacks.connect('xlim_changed', on_axeslim_changed) self.ax.callbacks.connect('ylim_changed', on_axeslim_changed) on_axeslim_changed(self.ax) self.xdate = (xField == 'Time') self.ydate = (yField == 'Time') self.ax.set_color_cycle(self.colorMap) def applyTimeFormat(self, timeFormat=''): timeFormatter = mpdates.DateFormatter(timeFormat) if len( timeFormat) else None if self.xdate and timeFormatter: self.ax.xaxis.set_major_formatter(timeFormatter) if self.ydate and timeFormatter: self.ax.yaxis.set_major_formatter(timeFormatter) self.figure.autofmt_xdate() def plot(self, x=[], y=[], label=None): def _float(value): try: return float(value) except: return -9999 if self.xdate: x = [mpdates.datestr2num(v) for v in x] else: x = [_float(v) for v in x] if self.ydate: y = [mpdates.datestr2num(v) for v in y] else: y = [_float(v) for v in y] line, = self.ax.plot(x, y, label=label, picker=5) if self.xdate: self.ax.xaxis_date() if self.ydate: self.ax.yaxis_date() if self.oldLines.has_key(label): line.update_from(self.oldLines.pop(label)) def updateLegend(self): self.ax.legend(loc=self.legendPos, ncol=self.legendCols) legend = self.ax.get_legend() if legend: legend.draggable(True) @property def xLim(self): return self.ax.get_xlim() @xLim.setter def xLim(self, xRange): self.ax.set_xlim(xRange) @property def yLim(self): return self.ax.get_ylim() @yLim.setter def yLim(self, yRange): self.ax.set_ylim(yRange) @property def title(self): return self.ax.get_title() @title.setter def title(self, value): self.ax.set_title(value, weight='bold') @property def xLabel(self): return self.ax.get_xlabel() @xLabel.setter def xLabel(self, value): self.ax.set_xlabel(value) @property def yLabel(self): return self.ax.get_ylabel() @yLabel.setter def yLabel(self, value): self.ax.set_ylabel(value) @property def legendVisible(self): return self.ax.get_legend().get_visible() if self.ax.get_legend( ) else False @legendVisible.setter def legendVisible(self, value): if value: self.updateLegend() try: self.ax.get_legend().set_visible(value) except: pass @property def gridVisible(self): return self.grid @gridVisible.setter def gridVisible(self, value): self.grid = value self.ax.grid(self.grid) def draw(self): self.canvas.draw() self.axisChanged.emit(self.ax.get_xlim(), self.ax.get_ylim())