from .DataStream import EMchPosmap as pos_map, span_days, time_border, calc_interval from .MerchantReader import MerchantReader from .MerchantPainter import MerchantPainter, allpathes from matplotlib.figure import Figure from matplotlib import ticker from io import BytesIO import numpy as np from .algorithm import calc_mchratios, calc_morder_send import time as time import logging logger = logging.getLogger('MerchantCumRatioPainter') class MerchantCumRatioPainter(MerchantPainter): def __init__(self, start_time: int, end_time: int, mchids: set = None, card_types: set = None, spec: int = None, filter_wave: int = None): self._reader = MerchantReader() self._mchids, self._card_types, self._spec, self._filter_wave = mchids, card_types, spec, filter_wave self._days, self._start_time, self._end_time, self._interval = self.calc_time(self._reader, start_time, end_time) pass def _fig_funs(self): def create(): fig = Figure(figsize=(19, 8)) ax = fig.subplots() ax.set_title('success ratio') ax.set(xlabel='time', ylabel='ratio') return ax, fig def flush(ax, fig, xticks=None, xlables=None, yticks=None, ylables=None): ax.yaxis.set_major_formatter(ticker.PercentFormatter(xmax=1, decimals=4)) if xticks is not None: ax.set_xticks(ticks=xticks) if xlables is not None: ax.set_xticklabels(xlables) if yticks is not None: ax.set_yticks(ticks=yticks) if ylables is not None: ax.set_yticklabels(ylables) fig.autofmt_xdate() ax.grid() fig.subplots_adjust(left=0.1, right=0.8, top=0.95, bottom=0.1) ax.legend(bbox_to_anchor=(1, 1), loc='upper left') buf = BytesIO() fig.savefig(buf, format="png") return buf return create, flush def paint(self): tuple_pathes = self._reader.many_tuple_path(self._days, self._mchids, self._card_types, self._spec) gen = allpathes(self._reader, tuple_pathes, self._days, self._spec) if len(self._days) == 0: return BytesIO() day_stamp = self._days[0] fig_create, fig_flush = self._fig_funs() ax, fig = fig_create() x = np.array([d - self._start_time for d in range(self._start_time, self._end_time)]) if self._filter_wave is not None and self._filter_wave > 1: window = np.ones(self._filter_wave) / self._filter_wave else: window = None mchid_ratios = [] for _mchid, _card_type, _spec, _data in gen: succ, count, y = calc_mchratios(_data, pos_map, self._start_time - day_stamp, self._end_time - day_stamp) y = np.convolve(y, window, 'same') if window is not None else y label, ratio = self._label(chname=_mchid, succ=succ, count=count, card_type=_card_type, spec=_spec) ax.plot(x, y, ls='-', label=label) if _card_type is None and _spec is None and type(_mchid) is int: mchid_ratios.append((_mchid, ratio)) xticks = [d - self._start_time for d in range(self._start_time, self._end_time + 1, self._interval)] xlables = [time.strftime('%d-%H:%M:%S', time.localtime(d + self._start_time)) for d in xticks] buf = fig_flush(ax, fig, xticks=xticks, xlables=xlables) mchid_ratios = sorted(mchid_ratios, key=lambda x: (x[1], x[0]), reverse=True) result = [] for mchid,ratio in mchid_ratios: result.append(f'{mchid}:{ratio}') return buf, result