import base64 from datetime import date from io import BytesIO from matplotlib.ticker import MaxNLocator def fig_to_html(fig): """ Convert a matplotlib.Figure object to html image source :param fig: :return: the returned value can be used in html like this: <img src="data:image/png;base64,<return value>"/> """ buf = BytesIO() fig.savefig(buf, format="png") figure = base64.b64encode(buf.getbuffer()).decode("ascii") return figure def axes_show_y_value(axes, x_data, y_data): for x, y in zip(x_data, y_data): axes.annotate(str(y), # this is the text (x, y), # these are the coordinates to position the label textcoords="offset points", # how to position the text xytext=(0, 4), # distance from text to points (x,y) size=8, # font size of the text ha='center') # horizontal alignment can be left, right or center def axes_rotate_xticklabels(axes): for tick in axes.get_xticklabels(): tick.set_rotation(45) tick.set_size(8) tick.set_ha('right') def axes_general_setting(axes): axes.grid(axis='y', linestyle='--', alpha=0.5) axes.set_title(axes.get_title(), pad=15) axes.set_ylim(ymin=0) # make y=0 start from bottom axes.yaxis.set_major_locator(MaxNLocator(min_n_ticks=1, integer=True)) _, y_max = axes.get_ylim() if y_max > 1000: space = 150 elif y_max > 100: space = 50 elif y_max > 10: space = 5 else: space = 2 axes.set_ylim(ymax=y_max+space) # add some space at the top def fig_adjust_width(fig, data_points_num, interval=6.4/20): if data_points_num * interval > 6.4: fig.set_figwidth(data_points_num * interval) def axes_adjust_xmargins(ax, fig_width, margin=6.4*0.05): ax.margins(x=margin/fig_width) def fig_adjust_xpaddings(fig, padding=6.4*0.1): left = padding / fig.get_figwidth() right = 1 - left fig.subplots_adjust(left=left, right=right) def get_first_day_of_month(dt: date): return date(dt.year, dt.month, 1) def get_list_span(l: list): """ :param l: :return: Example: For list ['a', 'a', 'a', 'b', 'c', 'c', 'd', 'd', 'd', 'd'], its span list is [3, 0, 0, 1, 2, 0, 4, 0, 0, 0] . """ span_list = [] span = 1 for i in range(len(l)): if i == 0: # 第一项span设为1 span_list.append(1) else: if l[i] == l[i-span]: # 与之前项相等,之前项的span值加1,本项span设为0,span值加1 span_list[i-span] += 1 span_list.append(0) span += 1 else: # 与之前项不等,本项span设为1,span值恢复为1 span_list.append(1) span = 1 return span_list def get_rows_span(rows): col_1_list = [row[0] for row in rows] return get_list_span(col_1_list)