ChannelCovPainter.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. from .DataStream import EChPosmap as pos_map
  2. from .ChannelReader import ChannelReader, ChPlotFilter
  3. from .ChannelPainter import ChannelPainter, chratios_pathes
  4. from matplotlib.figure import Figure
  5. from matplotlib import ticker
  6. from io import BytesIO
  7. import numpy as np
  8. from .algorithm import calc_cov_chratios, calc_count_cdf
  9. import time as time
  10. import logging
  11. logger = logging.getLogger('ChannelCumPainter')
  12. class ChannelCovPainter(ChannelPainter):
  13. def __init__(self, start_time: int, end_time: int, chnames: set = None, card_types: set = None, spec: int = None, filter_wave: int = None,
  14. all_show_type: int = 3):
  15. self._reader = ChannelReader()
  16. filter_wave = filter_wave or 3600
  17. self._chnames, self._card_types, self._spec, self._filter_wave = chnames, card_types, spec, filter_wave
  18. days, self._start_time, self._end_time, self._interval = self.calc_time(self._reader, start_time, end_time)
  19. self._filter = ChPlotFilter(self._chnames, self._card_types, self._spec, all_show_type)
  20. pass
  21. def _fig_create(self):
  22. fig = Figure(figsize=(16, 12))
  23. gs = fig.add_gridspec(nrows=3, height_ratios=(4, 4, 4))
  24. ax_succ_cdf = fig.add_subplot(gs[0, :], )
  25. ax_commit_cdf = fig.add_subplot(gs[1, :], sharex=ax_succ_cdf)
  26. ax_ratio = fig.add_subplot(gs[2, :], sharex=ax_succ_cdf)
  27. ax_succ_cdf.set_title('succ orders vs time (cdf)')
  28. ax_commit_cdf.set_title('commit orders vs time (cdf)')
  29. ax_ratio.set_title('success ratio vs time')
  30. return fig, ax_succ_cdf, ax_commit_cdf, ax_ratio
  31. def _flush(self, fig, ax_succ_cdf, ax_commit_cdf, ax_ratio, xticks, xlables, line_lables):
  32. def show_legent(ax, labels):
  33. size = len(line_lables)
  34. if size == 0:
  35. return False
  36. max_col = 8
  37. s = int(size / max_col)
  38. m = size % max_col
  39. if s == 0 and m > 0:
  40. ncol = m
  41. else:
  42. ncol = max_col
  43. leg = ax_ratio.legend(tuple(line_lables), loc='upper left', ncol=8, mode="expand", shadow=True, fancybox=False)
  44. leg.get_frame().set_alpha(0.2)
  45. return True
  46. ax_succ_cdf.grid()
  47. ax_commit_cdf.set_xticks(ticks=xticks)
  48. ax_commit_cdf.set_xticklabels(xlables)
  49. ax_commit_cdf.grid()
  50. ax_ratio.yaxis.set_major_formatter(ticker.PercentFormatter(xmax=1, decimals=4))
  51. ax_ratio.grid()
  52. show_legent(ax_ratio, line_lables)
  53. fig.autofmt_xdate()
  54. fig.tight_layout()
  55. buf = BytesIO()
  56. fig.savefig(buf, format="png")
  57. return buf
  58. def paint(self):
  59. reader = self._reader
  60. days, _start_time, _end_time, _interval = self.calc_time(self._reader, self._start_time - self._filter_wave, self._end_time)
  61. if len(days) == 0:
  62. return BytesIO()
  63. tuple_pathes = reader.many_tuple_path(days, self._chnames, self._card_types, self._spec)
  64. gen = chratios_pathes(reader, tuple_pathes, days)
  65. day_stamp = days[0]
  66. x = np.array([d - self._start_time for d in range(self._start_time, self._end_time)])
  67. window = np.ones(self._filter_wave)
  68. left_len = self._start_time - _start_time
  69. right_len = 0
  70. stime = lambda t: time.strftime('%d-%H:%M:%S', time.localtime(t))
  71. logger.debug("start_time %d, %s end_time=%s left_len=%d right_len=%d",
  72. self._start_time, stime(self._start_time), stime(self._end_time), left_len, right_len)
  73. chname_ratios = []
  74. fig, ax_succ_cdf, ax_commit_cdf, ax_ratio = self._fig_create()
  75. line_lables = []
  76. filter = self._filter
  77. icolor = 0
  78. for _chname, _card_type, _spec, _data in gen:
  79. show_plot = filter.show_plot(_chname,_card_type,_spec)
  80. show_ratio = _card_type is None and _spec is None
  81. if show_plot or show_ratio:
  82. logger.debug(f'chname={_chname}, card_type={_card_type}, spec={_spec} show_plot ={show_plot}')
  83. _succ, _commit, y, _succ_period, _fail_period = calc_cov_chratios(_data, pos_map, _start_time - day_stamp, _end_time - day_stamp, window,
  84. left_len, right_len)
  85. _succs, _commits = calc_count_cdf(_data, pos_map, _start_time - day_stamp, _end_time - day_stamp, left_len, right_len)
  86. if show_plot:
  87. color = self.color(icolor)
  88. icolor += 1
  89. label = self._label_simple(chname=_chname, filter=filter, card_type=_card_type, spec=_spec)
  90. line_lables.append(label)
  91. ax_ratio.plot(x, y, ls='-', color=color)
  92. ax_succ_cdf.plot(x, _succs, ls='-', color=color)
  93. ax_commit_cdf.plot(x, _commits, ls='-', color=color)
  94. if show_ratio:
  95. _ratio = _succ / (_commit + 0.00001)
  96. _ratio = round(_ratio, 5)
  97. chname_ratios.append((_chname, _ratio, _succ, _commit, _succ_period, _fail_period))
  98. xticks, xlables = self.clac_xlables(self._start_time, self._end_time, self._interval)
  99. buf = self._flush(fig, ax_succ_cdf, ax_commit_cdf, ax_ratio, xticks, xlables, line_lables)
  100. chname_ratios = sorted(chname_ratios, key=lambda x: x[1], reverse=True)
  101. result = {}
  102. ratios = {}
  103. for _chname, _ratio, _succ, _commit, _succ_period, _fail_period in chname_ratios:
  104. ratios[_chname] = [_ratio, _succ, _commit, _succ_period, _fail_period]
  105. result['detail'] = ratios
  106. return buf, result