You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Matplotlib在Python中清晰展示双曲线数据点数值

解决训练/验证损失曲线数值重叠的可视化优化方案

我来帮你搞定这个损失曲线数值重叠的问题,这是可视化中很常见的小困扰,给你几个实用的优化方案,附上修改后的代码示例:

方案1:上下错开文本位置

给其中一条曲线的文本添加固定的Y轴偏移量,让两个数值一上一下分开。比如给验证损失的文本往上挪一点:

import matplotlib.pyplot as plt
plt.rcParams.update(plt.rcParamsDefault)
plt.style.use(['default'])
a=[1.23,2.24,3.12,1.11,2.46]
b=[1.24,2.23,3.15,1.25,2.78]
xc=range(5)
plt.figure(figsize=(5,5))

# 训练损失文本:默认位置
for x,y in zip(xc,a):
    plt.text(x, y, '%.2f' % y, ha='center', va= 'bottom')
# 验证损失文本:向上偏移0.08,避免重叠
for x,y in zip(xc,b):
    plt.text(x, y + 0.08, '%.2f' % y, ha='center', va= 'bottom')

plt.plot(xc,a)
plt.plot(xc,b)
plt.xlabel('num of Epochs')
plt.ylabel('loss')
plt.title('train_loss vs val_loss')
plt.legend(['train','val'])
plt.show()

方案2:使用相反的垂直对齐方式

让训练损失的文本显示在数据点上方,验证损失的文本显示在数据点下方,利用垂直方向的空间错开:

import matplotlib.pyplot as plt
plt.rcParams.update(plt.rcParamsDefault)
plt.style.use(['default'])
a=[1.23,2.24,3.12,1.11,2.46]
b=[1.24,2.23,3.15,1.25,2.78]
xc=range(5)
plt.figure(figsize=(5,5))

# 训练损失文本:显示在点上方(va='bottom')
for x,y in zip(xc,a):
    plt.text(x, y, '%.2f' % y, ha='center', va= 'bottom')
# 验证损失文本:显示在点下方(va='top')
for x,y in zip(xc,b):
    plt.text(x, y, '%.2f' % y, ha='center', va= 'top')

plt.plot(xc,a)
plt.plot(xc,b)
plt.xlabel('num of Epochs')
plt.ylabel('loss')
plt.title('train_loss vs val_loss')
plt.legend(['train','val'])
plt.show()

方案3:左右错开文本位置

给两条曲线的文本添加微小的X轴偏移,让它们在水平方向上分开,适合Y轴数值非常接近的场景:

import matplotlib.pyplot as plt
plt.rcParams.update(plt.rcParamsDefault)
plt.style.use(['default'])
a=[1.23,2.24,3.12,1.11,2.46]
b=[1.24,2.23,3.15,1.25,2.78]
xc=range(5)
plt.figure(figsize=(5,5))

# 训练损失文本:向左偏移0.1
for x,y in zip(xc,a):
    plt.text(x - 0.1, y, '%.2f' % y, ha='center', va= 'bottom')
# 验证损失文本:向右偏移0.1
for x,y in zip(xc,b):
    plt.text(x + 0.1, y, '%.2f' % y, ha='center', va= 'bottom')

plt.plot(xc,a)
plt.plot(xc,b)
plt.xlabel('num of Epochs')
plt.ylabel('loss')
plt.title('train_loss vs val_loss')
plt.legend(['train','val'])
plt.show()

方案4:使用交互式可视化(推荐)

如果不想在图上直接显示所有数值,可以用Plotly制作交互式图表,鼠标悬停时自动显示对应数值,同时也支持自定义文本位置:

import plotly.graph_objects as go

a = [1.23,2.24,3.12,1.11,2.46]
b = [1.24,2.23,3.15,1.25,2.78]
xc = list(range(5))

fig = go.Figure()
# 训练损失:文本在点上方
fig.add_trace(go.Scatter(
    x=xc, y=a, 
    mode='lines+markers+text',
    text=[f'{y:.2f}' for y in a],
    textposition='top center',
    name='train'
))
# 验证损失:文本在点下方
fig.add_trace(go.Scatter(
    x=xc, y=b, 
    mode='lines+markers+text',
    text=[f'{y:.2f}' for y in b],
    textposition='bottom center',
    name='val'
))

fig.update_layout(
    xaxis_title='num of Epochs',
    yaxis_title='loss',
    title='train_loss vs val_loss'
)
fig.show()

你可以根据自己的需求选择最合适的方案,前三种适合静态图表,第四种适合需要交互查看的场景。

内容的提问来源于stack exchange,提问作者Hitesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:31:22