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:
"""
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)