Python 画一组曲线,并把文字散开
用 Python 画一组曲线, 但是这组曲线比较接近,上面放文字容易混淆,看不清.
比较好的办法是用线连接,并分散开,把文字写在别处.
以下是样例代码,来自 AI.
import numpy as np
import matplotlib.pyplot as plt
# 设置中文字体(可选,若无中文字体需求可注释)
plt.rcParams ['font.sans-serif'] = ['SimHei'] # 用于正常显示中文标签
plt.rcParams ['axes.unicode_minus'] = False # 解决负号显示问题
# 生成示例数据:4条损失曲线,共100个epoch
np.random.seed (42)
epochs = np.arange (1, 101) # 横坐标:epoch
# 模拟损失曲线(逐渐下降并收敛)
losses = []
for i in range (4):
# 基线 + 随机噪声
base = 2.0 - 0.015 * epochs + 0.00005 * epochs**2 # 平滑下降
noise = np.random.normal (0, 0.05, size=len (epochs))
# 使四条曲线稍有区别
offset = i * 0.15 - 0.225
losses.append (base + offset + noise)
# 创建图形
fig, ax = plt.subplots (figsize= (10, 6))
# 颜色列表
colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']
# 绘制损失曲线
for i, loss in enumerate (losses):
ax.plot (epochs, loss, label=f'曲线 {i+1}', color=colors [i], linewidth=2)
# 最后一个epoch的横坐标
last_epoch = epochs [-1]
# 画竖直虚线
ax.axvline (x=last_epoch, linestyle='--', color='gray', alpha=0.7, linewidth=1.5)
# 获取四条曲线在最后一个epoch上的损失值
last_losses = [loss [-1] for loss in losses]
# 为每个曲线添加交点标记及引出标注
# 为了避免文字重叠,根据损失值的高低动态分配文本的纵向偏移量
# 将损失值从小到大排序,依次分配较高的偏移位置(损失小则向上偏移,损失大则向下偏移)
sorted_indices = np.argsort (last_losses) # 升序,索引0对应最小损失
y_offsets = np.linspace (-0.3, 0.3, len (losses)) # 偏移范围 [-0.3, 0.3]
# 使最小损失对应最大偏移(向上),最大损失对应最小偏移(向下)
offset_map = {idx: y_offsets [rank] for rank, idx in enumerate (sorted_indices)}
# 标注的起始偏移参数
x_offset_slope = 15 # 斜线水平方向延伸长度(单位:epoch)
x_offset_text = 25 # 文本水平方向延伸总长度(从交点算起)
for i, (loss_val, color) in enumerate (zip (last_losses, colors)):
# 交点的坐标
x_start = last_epoch
y_start = loss_val
# 绘制交点小圆点
ax.scatter (x_start, y_start, s=50, color=color, zorder=5, edgecolors='white', linewidth=1)
# 确定文本最终位置(y方向根据偏移量调整)
y_text = y_start + offset_map [i]
# 文本最终x坐标
x_text = last_epoch + x_offset_text
# 斜线终点(先斜线再横线)
x_mid = last_epoch + x_offset_slope
y_mid = y_text # 斜线终点与文本同高,然后水平连接到文本
# 绘制斜线(从交点到x_mid处)
ax.plot ( [x_start, x_mid], [y_start, y_mid], color=color, linestyle='-', linewidth=1.5, alpha=0.7)
# 绘制水平线(从x_mid到文本位置)
ax.plot ( [x_mid, x_text], [y_text, y_text], color=color, linestyle='-', linewidth=1.5, alpha=0.7)
# 添加文本标签(曲线标识)
ax.text (x_text, y_text, f' L{i+1}', va='center', ha='left', fontsize=10, color=color,
bbox=dict (boxstyle='round,pad=0.2', facecolor='white', edgecolor='none', alpha=0.7))
# 设置坐标轴标签和标题
ax.set_xlabel ('Epoch', fontsize=12)
ax.set_ylabel ('Loss', fontsize=12)
ax.set_title ('四条损失曲线及最后一个epoch的标注', fontsize=14)
# 显示图例(可选,如果不需要可注释)
ax.legend (loc='upper right', fontsize=10)
# 增加右侧空白区域,为文本预留空间
plt.subplots_adjust (right=0.85)
# 显示网格
ax.grid (True, linestyle=':', alpha=0.5)
plt.tight_layout ()
plt.show ()
浙公网安备 33010602011771号