#!/usr/bin/env python # -*- coding: utf-8 -*- import matplotlib.pyplot as plt import matplotlib.ticker as plticker import numpy as np class SequencePlot(object): """Key class for visualizations with two axis""" def __init__(self, view, width=40, height=3): self.width = width self.height = height self._x = self.get_xpos(view) # outsourcen in Frames Class und dann hier löschen def get_xpos(self, view): """calculate frame numbers for x-ticks""" # TODO Die Frame No. Range könnte ich auch besser zu einer Methode von Frames machen return [nr for nr in range(view._frames.start, view._frames.end, view._frame_step)] # um X-Achse Minuten anzeigen zu lassen def _timelabels(self, val, pos): min, sec = divmod(int(val), 60) timelabel = "{0}:{1:02d}".format(min, sec) return timelabel # TODO styling und plotten sind hier noch etwas zusammengemischt def ittenstyle(self, ax, view): plt.style.use('ggplot') fig_coef = self.width / self.height tick_cnt = fig_coef / 0.3605405405 tick_step = int(view._frames.frm_cnt / tick_cnt) # loc = plticker.MultipleLocator(base=tick_freq) # this locator puts ticks at regular intervals (0.0005) loc = plticker.FixedLocator(range(0, view._frames.end, tick_step)) fmt = plticker.FuncFormatter(self._timelabels) ax.xaxis.set_major_locator(loc) ax.xaxis.set_major_formatter(fmt) ax.set_xlim(view._frames.start - 20, view._frames.end + 20) # Beschriftung der Y-Achse # TODO funktioniert nicht richtig ax.set_ylim(-1, view._bins + 1) loc = plticker.FixedLocator(range(0, view._bins + 1, int(view._bins / 8))) ax.yaxis.set_major_locator(loc) # TODO mit iter_ticks evtl noch die angegebenen Sekunden auf base 60 setzen # obere x-achse mit zeitlich versetzten werten axt = ax.twiny() axt.set_xlim(ax.get_xlim()) axt.set_ylim(ax.get_ylim()) # loc = plticker.MultipleLocator(base=tick_freq) # loc = plticker.LinearLocator(20) loc = plticker.FixedLocator(range(int(tick_step / 2), view._frames.end, tick_step)) fmt = plticker.FuncFormatter(self._timelabels) axt.xaxis.set_major_locator(loc) axt.xaxis.set_major_formatter(fmt) ax.set_axis_bgcolor((1, 1, 1)) # TODO: gradient chn_label = view._contrast ax.set_ylabel(chn_label, {'fontsize': 8}) ax.set_xlabel('Time', {'fontsize': 8}, y=0.5) ax.yaxis.grid(False) axt.yaxis.grid(False) ax.tick_params(length=0) axt.tick_params(length=0) ax.xaxis.grid(c=(0.90, 0.90, 0.90)) axt.xaxis.grid(c=(0.90, 0.90, 0.90)) return (ax, axt) # TODO Überführbar in Superclass? # evtl. auch eher feature drer View Klasse # TODO self._x sollte eine array sein def _vlines(self, view, mark, mark_gt, mark_lt): npx = np.array(self._x) if mark_gt: poss = npx[view > mark_gt] for pos in poss: self._ax.axvline(pos, color='#a6e22e', alpha=0.4, linewidth=3) if mark_lt: poss = npx[view < mark_lt] for pos in poss: self._ax.axvline(pos, color='#f92672', alpha=0.4, linewidth=3) if mark: for pos in mark: print(self._ax) self._ax.axvline(pos, color='#66d9ef', alpha=0.4, linewidth=3) def saveplt(self, title=False, fname='plot.png'): if title: self._ax.set_title(title, {'fontsize': 14}, y=1.18) self.fig.set_size_inches(self.width, self.height) self.fig.tight_layout() self.fig.savefig(fname, dpi=400) class MultivariatePlot(SequencePlot): """Scatterplot that shows n features per frame""" def __init__(self, view): super(MultivariatePlot, self).__init__(view) self.fig = plt.figure() self._ax = plt.axes() def plot(self, view, mark_gt=False, mark_lt=False, mark=False): x = view[:, 0] y = view[:, 1] value = view[:, 2] thickness = list([int((v - view._threshold) / 4000) for v in value]) self._ax, axt = self.ittenstyle(self._ax, view) # Plotten axt.scatter(x, y, c=(0, 0, 0), s=thickness, linewidths=0) # axt.scatter(x, y, c=y, cmap='Greys_r', s=thickness, linewidths=0) # DOC: vmin/vmax sorgt für die Verteilung der Fraben der Colorm # ax.scatter(x, y, c=y, cmap='hsv', s=thickness, linewidths=0) if mark: self._vlines(view, mark, False, False) self.fig.tight_layout() self.fig.set_size_inches(self.width, self.height) return self.fig, self._ax class UnivariatePlot(SequencePlot): """Lineplot that shows one featur per fram""" def __init__(self, view): super(UnivariatePlot, self).__init__(view) # TODO die können evtl. noch in die super class self.fig = plt.figure() self._ax = plt.axes() self._ax, self._axt = self.ittenstyle(self._ax, view) def plot(self, view, mark_gt=False, mark_lt=False, mark=False): # Interpolation mit savitzky_golay funktioniert nicht # contrast_points = savitzky_golay(np.array(contrast_points), 51, 7) self._axt.plot(self._x, view, label=view.feature) if any([mark, mark_gt, mark_lt]): self._vlines(view, mark, mark_gt, mark_lt) self._axt.legend() return self.fig