线条中间
使用 matplotlib-label-lines 库
from labellines import labelLines # pip install matplotlib-label-lines
from matplotlib.dates import date2num
from datetime import datetime
df = pd.DataFrame([[0, 2, 4], [3, 3, 3], [4, 3, 2]],
columns=['A', 'B', 'C'],
index=['2020-1-1', '2020-1-2', '2020-1-3'])
# 日期格式转换
df.index = pd.to_datetime(df.index)
print(df)
# 输出
A B C
2020-01-01 0 3 4
2020-01-02 2 3 3
2020-01-03 4 3 2
time_x = df.index.to_pydatetime() # datetime格式
print(time_x)
# 输出
[datetime.datetime(2020, 1, 1, 0, 0) datetime.datetime(2020, 1, 2, 0, 0)
datetime.datetime(2020, 1, 3, 0, 0)]
for col in df:
plt.plot(time_x, df[col], label=col)
labelLines(plt.gca().get_lines(), xvals=(date2num(time_x[0]),
date2num(time_x[-1]))) # xvals标签显示范围
线条右端
前提要数据是不断上升的,右端即最大值,用最大值确定位置
df = pd.DataFrame({'A': [0, 2, 4, 6], 'B': [2, 2.5, 5, 8], 'C': [1, 2, 3, 4]},
index=['2020-1-1', '2020-1-2', '2020-1-3', '2020-1-4'])
for col in df:
plt.plot(df[col], label=col)
for name, value in df.max().items():
plt.text(3.05, value, name, size=10, ha='left', va='center')
终点对齐的情况,用plt.text找好位置写上即可。
现在模仿确诊2例开始统计的分析图
start_num = 1
# 排序一:按最大值,最长不是最大时会被裁掉
col_sorted = df.iloc[-1].sort_values(ascending=False).index
# 排序二:按时长
col_sorted = [[col, len(df[col][df[col] > start_num])] for col in df]
col_sorted.sort(key=lambda x:x[1], reverse=True)
col_sorted = [i[0] for i in col_sorted]
df_new = pd.DataFrame()
for col in col_sorted:
df_new[col] = df[col][df[col] > start_num].reset_index(drop=True) # 从大于1开始统计
plt.plot(df_new[col], label=col)
max_value = df_new.max() # 各列数据的最大值
max_index = df_new.idxmax() # 各列数据最大索引,非nan
for (name, index), value in zip(max_index.items(), max_value):
plt.text(index + 0.05, value, name, size=10, ha='left', va='center')