86 lines
2.2 KiB
Python
86 lines
2.2 KiB
Python
import matplotlib
|
|
|
|
matplotlib.use("Agg")
|
|
|
|
import matplotlib.pyplot as plt
|
|
from matplotlib import font_manager
|
|
import config
|
|
import logging
|
|
|
|
logging.getLogger("matplotlib").setLevel(logging.WARNING)
|
|
|
|
# 从字体文件创建字体对象
|
|
FONT = font_manager.FontProperties(fname=config.FONT_PATH)
|
|
|
|
# 负号修复
|
|
plt.rcParams["axes.unicode_minus"] = False
|
|
|
|
|
|
def plot_line(
|
|
times,
|
|
normal_values,
|
|
title,
|
|
ylabel,
|
|
out_path,
|
|
free_values=None, # ✅ 免费额度可选
|
|
):
|
|
has_free = free_values is not None and len(free_values) > 0
|
|
|
|
if has_free:
|
|
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 8), sharex=True)
|
|
else:
|
|
fig, ax1 = plt.subplots(1, 1, figsize=(14, 6))
|
|
ax2 = None
|
|
|
|
# ===== 普通额度 =====
|
|
ax1.plot(times, normal_values, marker="o")
|
|
ax1.set_title(
|
|
f"{title}(普通额度)" if has_free else title,
|
|
fontproperties=FONT,
|
|
)
|
|
ax1.set_ylabel(ylabel, fontproperties=FONT)
|
|
ax1.grid(True)
|
|
|
|
for i, (x, y) in enumerate(zip(times, normal_values)):
|
|
dy = 8 if i != 0 or y < normal_values[i - 1] else -16
|
|
|
|
ax1.annotate(
|
|
f"{y}",
|
|
(x, y),
|
|
textcoords="offset points",
|
|
xytext=(0, dy),
|
|
ha="center",
|
|
fontsize=10,
|
|
fontproperties=FONT,
|
|
)
|
|
|
|
# ===== 免费额度(可选) =====
|
|
if has_free and ax2:
|
|
ax2.plot(times, free_values, marker="o", linestyle="--")
|
|
ax2.set_title(f"{title}(免费额度)", fontproperties=FONT)
|
|
ax2.set_xlabel("时间", fontproperties=FONT)
|
|
ax2.set_ylabel(ylabel, fontproperties=FONT)
|
|
ax2.grid(True)
|
|
|
|
for i, (x, y) in enumerate(zip(times, free_values)):
|
|
# 免费额度同样根据趋势决定标注方向
|
|
if i == 0:
|
|
dy = -8
|
|
else:
|
|
dy = -8 if y <= free_values[i - 1] else 8
|
|
|
|
ax2.annotate(
|
|
f"{y}",
|
|
(x, y),
|
|
textcoords="offset points",
|
|
xytext=(0, dy),
|
|
ha="center",
|
|
fontsize=8,
|
|
fontproperties=FONT,
|
|
)
|
|
|
|
plt.xticks(rotation=45, fontproperties=FONT)
|
|
plt.tight_layout()
|
|
plt.savefig(out_path, dpi=150)
|
|
plt.close()
|