MerchantAmountPainter.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. from .DataStream import EMchPosmap as pos_map, span_days, time_border, calc_interval
  2. from .MerchantReader import MerchantReader
  3. from .MerchantPainter import MerchantPainter, allpathes
  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_morder_send
  9. import time as time
  10. import logging
  11. logger = logging.getLogger('painter')
  12. class MerchantAmountPainter(MerchantPainter):
  13. def __init__(self, start_time: int, end_time: int, mchids: set = None, card_types: set = None, spec: int = None, filter_wave: int = None):
  14. self._reader = MerchantReader()
  15. self._mchids, self._card_types, self._spec, self._filter_wave = mchids, card_types, spec, filter_wave
  16. self._days, self._start_time, self._end_time, self._interval = self.calc_time(self._reader, start_time, end_time)
  17. pass
  18. def _fig_bar_funs(self):
  19. def create():
  20. fig = Figure(figsize=(19, 16))
  21. ax_count, ax_amount = fig.subplots(2, 1)
  22. ax_count.set_title('sending order count monitor')
  23. ax_count.set(xlabel='merchant id', ylabel='count')
  24. ax_amount.set_title('sending order amount monitor')
  25. ax_amount.set(xlabel='merchant id', ylabel='amount')
  26. return ax_count, ax_amount, fig
  27. def end(ax, xticks=None, xlables=None, yticks=None, ylables=None):
  28. if xticks is not None:
  29. ax.set_xticks(ticks=xticks)
  30. if xlables is not None:
  31. ax.set_xticklabels(xlables)
  32. if yticks is not None:
  33. ax.set_yticks(ticks=yticks)
  34. if ylables is not None:
  35. ax.set_yticklabels(ylables)
  36. ax.legend()
  37. ax.grid()
  38. def flush(fig):
  39. fig.autofmt_xdate()
  40. buf = BytesIO()
  41. fig.savefig(buf, format="png")
  42. return buf
  43. return create, end,flush
  44. def paint(self):
  45. tuple_pathes = self._reader.many_tuple_path(self._days, self._mchids, self._card_types, self._spec)
  46. gen = allpathes(self._reader, tuple_pathes, self._days, self._spec)
  47. if len(self._days) == 0:
  48. return BytesIO()
  49. day_stamp = self._days[0]
  50. fig_create, fig_end, fig_flush = self._fig_bar_funs()
  51. ax_count, ax_amount, fig = fig_create()
  52. lables = list()
  53. datas = list()
  54. mchids = list()
  55. for _mchid, _card_type, _spec, _data in gen:
  56. lables.append(f"{_mchid}")
  57. logger.debug(_mchid)
  58. mchids.append(_mchid)
  59. ret = calc_morder_send(_data, pos_map, self._start_time - day_stamp, self._end_time - day_stamp)
  60. datas.append(ret)
  61. send_count, submit_count, succ_count, fail_count, submit_amount, succ_amount, fail_amount, send_amount, lack = ret
  62. logger.debug("send=%d submit=%d succ=%d fail=%d",send_count, submit_count, succ_count, fail_count)
  63. cratio = succ_count / (succ_count + fail_count + 0.0001)
  64. aratio = succ_amount / (succ_amount + fail_amount + 0.0001)
  65. logger.debug("cratio=%.2f aratio=%.2f", cratio, aratio)
  66. send_count, submit_count, succ_count, fail_count, submit_amount, succ_amount, fail_amount, send_amount, lack = zip(*datas)
  67. self.draw_count(ax_count, lables, send_count, submit_count, succ_count, fail_count, fig_end)
  68. self.draw_amount(ax_amount, lables, submit_amount, succ_amount, fail_amount, send_amount, lack, fig_end)
  69. return fig_flush(fig), mchids
  70. def draw_count(self, ax, lables, send_count, submit_count, succ_count, fail_count, fig_end):
  71. width = 0.24
  72. x_asix = np.arange(len(lables))
  73. rect_send = ax.bar(x_asix - width * 0.5, list(send_count), width, label='sending', align='center')
  74. rect_submit = ax.bar(x_asix - width * 1.5, list(submit_count), width, label='summit',align='center')
  75. rect_succ = ax.bar(x_asix + width * 0.5, list(succ_count), width, label='succ',align='center')
  76. rect_fail = ax.bar(x_asix + width * 1.5, list(fail_count), width, label='fail', align='center')
  77. ax.bar_label(rect_send, padding=0, rotation=270, fmt='%d')
  78. ax.bar_label(rect_submit, padding=0, rotation=270, fmt='%d')
  79. ax.bar_label(rect_succ, padding=0, rotation=270, fmt='%d')
  80. ax.bar_label(rect_fail, padding=0, rotation=270, fmt='%d')
  81. fig_end(ax, xticks=x_asix, xlables=lables)
  82. pass
  83. def draw_amount(self, ax, lables, submit_amount, succ_amount, fail_amount, send_amount, lack, fig_end):
  84. width = 0.18
  85. x_asix = np.arange(len(lables))
  86. rect_submit = ax.bar(x_asix - width * 2, list(submit_amount), width, label='summit',align='center')
  87. rect_send = ax.bar(x_asix - width, list(send_amount), width, label='sending', align='center')
  88. rect_msucc = ax.bar(x_asix, list(lack), width, label='may succ', align='center')
  89. rect_succ = ax.bar(x_asix + width, list(succ_amount), width, label='succ',align='center')
  90. rect_fail = ax.bar(x_asix + width * 2, list(fail_amount), width, label='fail', align='center')
  91. ax.bar_label(rect_submit, padding=0, rotation=270, fmt='%.2f')
  92. ax.bar_label(rect_send, padding=0, rotation=270, fmt='%.2f')
  93. ax.bar_label(rect_msucc, padding=0, rotation=270, fmt='%.2f')
  94. ax.bar_label(rect_succ, padding=0, rotation=270, fmt='%.2f')
  95. ax.bar_label(rect_fail, padding=0, rotation=270, fmt='%.2f')
  96. fig_end(ax, xticks=x_asix, xlables=lables)
  97. pass