如何用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
相关产品推荐
相关产品推荐

