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

如何为2D折线图正确添加行内标签与对数颜色刻度并修复多标签问题

问题解决:折线图行内标签重复及对数颜色条实现

问题描述

需要绘制带有行内标签(inline label)和对数颜色条刻度的2D折线图,目前已实现行内标签,但每条折线显示多个标签;同时需要添加对数颜色条。当前效果如下:

当前折线图效果

原代码

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from labellines import labelLines

num=np.linspace(2, 10, 15)
en=[0.000001,0.00001, 0.0001, 0.001, 0.01, 0.1, 1, 10, 100, 1000]
dis=[]
for i in en:
    for j in num:
        dist=0.48*j -0.33*np.log10(i)  -1.4
        r=10**dist
        dis.append(r)
dd=np.array(dis)
AA=dd.reshape(10, 15)
D=pd.DataFrame(AA)
D=np.transpose(D)
m=pd.DataFrame(num)
fig, ax = plt.subplots(figsize=(12,8))
ax.plot(m[0], D[0], label='$0.000001{J/m^3}$',color='b', lw=2.5, linestyle='solid')
labelLines(plt.gca().get_lines(), zorder=2, align=True, fontsize=14)
ax.plot(m[0], D[1], label='$0.00001$',color='b', lw=2.5, linestyle='solid', alpha=0.8)
labelLines(plt.gca().get_lines(), zorder=2, align=True, fontsize=14)
ax.plot(m[0], D[2],label='$0.0001$',color='b', lw=2.5, linestyle='solid', alpha=0.6)
labelLines(plt.gca().get_lines(), zorder=2, align=True, fontsize=14)
ax.plot(m[0], D[3],label='$0.001$',color='b', lw=2.5, linestyle='solid', alpha=0.4)
labelLines(plt.gca().get_lines(), zorder=2, align=True, fontsize=14)
ax.plot(m[0], D[4],label='$0.01$',color='b', lw=2.5, linestyle='solid', alpha=0.4)
ax.plot(m[0], D[5],label='$0.1$',color='r', lw=2.5, linestyle='solid', alpha=0.2)
ax.plot(m[0], D[6], label='$1$',color='r', lw=2.5, linestyle='solid', alpha=0.4)
ax.plot(m[0], D[7], label='$10$',color='r', lw=2.5, linestyle='solid', alpha=0.6)
ax.plot(m[0], D[8], label='$100$',color='r', lw=2.5, linestyle='solid', alpha=0.8)
ax.plot(m[0], D[9],  label='$01000$',color='r', lw=2.5, linestyle='solid')
#ax.legend(inline=True, fontsize=10)
ax.set_yscale('log')
ax.set_xlim(2, 10)
ax.set_ylim(1, 20000)
ax.xaxis.set_tick_params(labelsize=14)
ax.yaxis.set_tick_params(labelsize=14)

for axis in ['top', 'bottom', 'left', 'right']:
    ax.spines[axis].set_linewidth(2)
plt.show()

解决方案

1. 解决行内标签重复问题

原代码每次绘制一条线后就调用labelLines,该函数会给当前所有已绘制的线条添加标签,导致重复标注。只需在所有线条绘制完成后,调用一次labelLines即可。

2. 实现对数颜色条

使用对数归一化的颜色映射,将en数组的值映射到colormap上,同时创建颜色条展示刻度对应关系。

修改后的完整代码

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
from matplotlib.cm import ScalarMappable
from labellines import labelLines

# 生成数据
num = np.linspace(2, 10, 15)
en = [0.000001, 0.00001, 0.0001, 0.001, 0.01, 0.1, 1, 10, 100, 1000]
dis = []
for i in en:
    for j in num:
        dist = 0.48 * j - 0.33 * np.log10(i) - 1.4
        r = 10 ** dist
        dis.append(r)
dd = np.array(dis)
AA = dd.reshape(10, 15)
D = pd.DataFrame(AA).T
m = pd.DataFrame(num)

# 创建绘图对象
fig, ax = plt.subplots(figsize=(12, 8))

# 配置对数颜色映射
norm = LogNorm(vmin=np.min(en), vmax=np.max(en))
cmap = plt.get_cmap('coolwarm')
sm = ScalarMappable(norm=norm, cmap=cmap)
sm.set_array([])

# 循环绘制所有折线,简化冗余代码
for idx, e in enumerate(en):
    color = cmap(norm(e))
    alpha = 0.2 + idx * 0.08 if idx < 5 else 0.2 + (9 - idx) * 0.08
    line, = ax.plot(m[0], D[idx], label=f'${e} J/m^3$', color=color, lw=2.5, linestyle='solid', alpha=alpha)

# 仅调用一次labelLines添加行内标签
labelLines(ax.get_lines(), zorder=2, align=True, fontsize=14)

# 添加对数颜色条
cbar = fig.colorbar(sm, ax=ax, orientation='vertical')
cbar.set_label('Energy ($J/m^3$)', fontsize=14)
cbar.ax.tick_params(labelsize=14)

# 设置坐标轴样式
ax.set_yscale('log')
ax.set_xlim(2, 10)
ax.set_ylim(1, 20000)
ax.set_xlabel('num', fontsize=14)
ax.set_ylabel('Distance', fontsize=14)
ax.xaxis.set_tick_params(labelsize=14)
ax.yaxis.set_tick_params(labelsize=14)

for axis in ['top', 'bottom', 'left', 'right']:
    ax.spines[axis].set_linewidth(2)

plt.tight_layout()
plt.show()

说明

  • 循环绘制折线减少了代码冗余,通过对数归一化colormap实现颜色与en值的对应。
  • 颜色条使用对数刻度,匹配数据的对数特性,直观展示能量值变化。
  • 仅调用一次labelLines,确保每条折线只显示一个行内标签。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 00:40:19