from .DataStream import EChPosmap as pos_map from .ChannelReader import ChannelReader, ChPlotFilter from .ChannelPainter import ChannelPainter, chratios_pathes from matplotlib.figure import Figure from matplotlib import ticker from io import BytesIO import numpy as np from .algorithm import calc_cov_chratios, calc_count_cdf import time as time import logging logger = logging.getLogger('ChannelCumPainter') class ChannelCovPainter(ChannelPainter): def __init__(self, start_time: int, end_time: int, chnames: set = None, card_types: set = None, spec: int = None, filter_wave: int = None, all_show_type: int = 3): self._reader = ChannelReader() filter_wave = filter_wave or 3600 self._chnames, self._card_types, self._spec, self._filter_wave = chnames, card_types, spec, filter_wave days, self._start_time, self._end_time, self._interval = self.calc_time(self._reader, start_time, end_time) self._filter = ChPlotFilter(self._chnames, self._card_types, self._spec, all_show_type) pass def _fig_create(self): fig = Figure(figsize=(16, 12)) gs = fig.add_gridspec(nrows=3, height_ratios=(4, 4, 4)) ax_succ_cdf = fig.add_subplot(gs[0, :], ) ax_commit_cdf = fig.add_subplot(gs[1, :], sharex=ax_succ_cdf) ax_ratio = fig.add_subplot(gs[2, :], sharex=ax_succ_cdf) ax_succ_cdf.set_title('succ orders vs time (cdf)') ax_commit_cdf.set_title('commit orders vs time (cdf)') ax_ratio.set_title('success ratio vs time') return fig, ax_succ_cdf, ax_commit_cdf, ax_ratio def _flush(self, fig, ax_succ_cdf, ax_commit_cdf, ax_ratio, xticks, xlables, line_lables): def show_legent(ax, labels): size = len(line_lables) if size == 0: return False max_col = 8 s = int(size / max_col) m = size % max_col if s == 0 and m > 0: ncol = m else: ncol = max_col leg = ax_ratio.legend(tuple(line_lables), loc='upper left', ncol=8, mode="expand", shadow=True, fancybox=False) leg.get_frame().set_alpha(0.2) return True ax_succ_cdf.grid() ax_commit_cdf.set_xticks(ticks=xticks) ax_commit_cdf.set_xticklabels(xlables) ax_commit_cdf.grid() ax_ratio.yaxis.set_major_formatter(ticker.PercentFormatter(xmax=1, decimals=4)) ax_ratio.grid() show_legent(ax_ratio, line_lables) fig.autofmt_xdate() fig.tight_layout() buf = BytesIO() fig.savefig(buf, format="png") return buf def paint(self): reader = self._reader days, _start_time, _end_time, _interval = self.calc_time(self._reader, self._start_time - self._filter_wave, self._end_time) if len(days) == 0: return BytesIO() tuple_pathes = reader.many_tuple_path(days, self._chnames, self._card_types, self._spec) gen = chratios_pathes(reader, tuple_pathes, days) day_stamp = days[0] x = np.array([d - self._start_time for d in range(self._start_time, self._end_time)]) window = np.ones(self._filter_wave) left_len = self._start_time - _start_time right_len = 0 stime = lambda t: time.strftime('%d-%H:%M:%S', time.localtime(t)) logger.debug("start_time %d, %s end_time=%s left_len=%d right_len=%d", self._start_time, stime(self._start_time), stime(self._end_time), left_len, right_len) chname_ratios = [] fig, ax_succ_cdf, ax_commit_cdf, ax_ratio = self._fig_create() line_lables = [] filter = self._filter icolor = 0 for _chname, _card_type, _spec, _data in gen: show_plot = filter.show_plot(_chname,_card_type,_spec) show_ratio = _card_type is None and _spec is None if show_plot or show_ratio: logger.debug(f'chname={_chname}, card_type={_card_type}, spec={_spec} show_plot ={show_plot}') _succ, _commit, y, _succ_period, _fail_period = calc_cov_chratios(_data, pos_map, _start_time - day_stamp, _end_time - day_stamp, window, left_len, right_len) _succs, _commits = calc_count_cdf(_data, pos_map, _start_time - day_stamp, _end_time - day_stamp, left_len, right_len) if show_plot: color = self.color(icolor) icolor += 1 label = self._label_simple(chname=_chname, filter=filter, card_type=_card_type, spec=_spec) line_lables.append(label) ax_ratio.plot(x, y, ls='-', color=color) ax_succ_cdf.plot(x, _succs, ls='-', color=color) ax_commit_cdf.plot(x, _commits, ls='-', color=color) if show_ratio: _ratio = _succ / (_commit + 0.00001) _ratio = round(_ratio, 5) chname_ratios.append((_chname, _ratio, _succ, _commit, _succ_period, _fail_period)) xticks, xlables = self.clac_xlables(self._start_time, self._end_time, self._interval) buf = self._flush(fig, ax_succ_cdf, ax_commit_cdf, ax_ratio, xticks, xlables, line_lables) chname_ratios = sorted(chname_ratios, key=lambda x: x[1], reverse=True) result = {} ratios = {} for _chname, _ratio, _succ, _commit, _succ_period, _fail_period in chname_ratios: ratios[_chname] = [_ratio, _succ, _commit, _succ_period, _fail_period] result['detail'] = ratios return buf, result