from .DataStream import EChPosmap as pos_map from .ChannelReader import ChannelReader, ChPathFilter from .ChannelPainter import ChannelPainter, detail_pathes, get_channels from matplotlib.figure import Figure from matplotlib import ticker from io import BytesIO import numpy as np from .algorithm import calc_chspeed_ratio import time as time import logging logger = logging.getLogger('ChannelSpeedAnalyzePainter') class ChannelSpeedAnalyzePainter(ChannelPainter): def __init__(self, start_time: int, end_time: int, chnames: set = None, card_types: set = None, spec: int = None, period: int = 60): self._reader = ChannelReader() self._chnames, self._card_types, self._spec, self._period = chnames, card_types, spec, period days, self._start_time, self._end_time, self._interval = self.calc_time(self._reader, start_time, end_time) secs = self._end_time - self._start_time if secs % period > 0: self._start_time = self._start_time -(period - secs % period) pass def _succ_hist(self, y, ax_histx): vals,pos,_1 = ax_histx.hist(y) if len(pos) >= 2: interval = (pos[1] - pos[0]) / 5 else: interval = 0 for i in range(len(vals)): ax_histx.annotate(text=int(vals[i]),xy = (pos[i] + interval,vals[i])) ax_histx.grid() def _fig_create(self): fig = Figure(figsize=(16, 6)) gs = fig.add_gridspec(nrows=2, ncols=4, height_ratios=(2, 4), width_ratios=(4, 4, 4, 4)) ax_hist_succs = fig.add_subplot(gs[0, :]) ax_scatter = fig.add_subplot(gs[1, 0]) ax_succ_cdf = fig.add_subplot(gs[1, 1]) ax_ratio_cdf = fig.add_subplot(gs[1, 2]) ax_ratio_latest = fig.add_subplot(gs[1, 3]) return fig, ax_hist_succs, ax_scatter, ax_succ_cdf, ax_ratio_cdf, ax_ratio_latest def _flush(self, fig, ax_scatter, ax_succ_cdf, ax_hist_succs, ax_ratio_cdf, ax_ratio_latest): ax_scatter.grid() ax_hist_succs.grid() ax_ratio_cdf.grid() ax_ratio_latest.grid() ax_succ_cdf.grid() fig.tight_layout() buf = BytesIO() fig.savefig(buf, format="png") return buf def _succ_cdf(self, succs, commits, ax_count, ax_ratio,ax_latest): min = np.min(commits) max = np.max(commits) x = [i for i in range(0, max + 1, 1)] y = [] for i in x: pos = np.where(commits == i) succ = succs[pos] count = np.sum(succ) y.append(count) y = np.array(y) succ = np.sum(y) y = np.cumsum(y) ax_count.plot(x, y, ls='-') ratio = y / (succ + 0.00000001) ax_ratio.plot(x, ratio, ls='-') pos = np.where(y == succ) if len(pos[0]) > 1: end = pos[0][1] x = x[:end] ratio = ratio[:end] ax_latest.plot(x, ratio, ls='-') pass def paint(self): reader = self._reader days, _start_time, _end_time, _interval = self.calc_time(self._reader, self._start_time, self._end_time) if len(days) == 0: return BytesIO() tuple_pathes = reader.many_tuple_path(days, self._chnames, self._card_types, self._spec) filter = ChPathFilter(self._chnames, self._card_types, self._spec) gen = detail_pathes(reader, tuple_pathes, days) day_stamp = days[0] channels = {} commits = [] succs = [] ratios = [] fig, ax_hist_succs, ax_scatter, ax_succ_cdf, ax_ratio_cdf, ax_ratio_latest = self._fig_create() for _chname, _card_type, _spec, _data in gen: logger.debug(f'chname={_chname} card_type={_card_type} spec={_spec}') if _chname != 'all' and _card_type is not None and _spec is not None: _commits, _succs, _ratios = calc_chspeed_ratio(_data, pos_map, _start_time - day_stamp, _end_time - day_stamp, self._period) ax_scatter.scatter(_commits, _succs) commits.extend(_commits) succs.extend(_succs) ratios.extend(ratios) if len(succs) > 0 and len(commits) > 0: succs = np.array(succs).astype(int) commits = np.array(commits).astype(int) self._succ_hist(succs,ax_hist_succs) self._succ_cdf(succs,commits,ax_succ_cdf,ax_ratio_cdf,ax_ratio_latest) buf = self._flush(fig, ax_scatter, ax_succ_cdf, ax_hist_succs, ax_ratio_cdf, ax_ratio_latest) result = [] channels = get_channels() for name in channels: result.append(f'{name}:0.00') return buf,result