具有单个颜色条的几行的 LineCollections

LineCollections for few lines with a single colorbar

我正在尝试在绘图中使用 LineCollection 绘制一些线条。这些线中的每一条都需要映射到颜色条,颜色条的范围因每条线而异。我按照此处的说明进行了尝试

https://matplotlib.org/stable/gallery/lines_bars_and_markers/multicolored_line.html?highlight=line%20collection

最后,我想要一个颜色条,比方说三行,覆盖所有范围。但是,颜色条是为最后一行值设置的。所以我看了这里

https://matplotlib.org/stable/gallery/images_contours_and_fields/multi_image.html

但我没有成功,因为我对 Matplotlib 还很陌生。我在下面粘贴我的代码。我只是想在所有三行的颜色栏中映射行的值(也显示在 y 轴上)。感谢任何帮助。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
from matplotlib import colors

lineSegments = [np.linspace(0,1,10),
                np.linspace(0,5,10),
                np.linspace(0,2,10)]

xVec = np.linspace(0,1,10)

fig, ax = plt.subplots()
for i in range(0, len(lineSegments)):
    
    
    cValue = np.linspace( min(lineSegments[i]), max(lineSegments[i]) )
    norm = colors.Normalize(vmin=cValue.min(), vmax=cValue.max() )
    
    Points = np.array([xVec, lineSegments[i]]).T.reshape(-1,1,2)
    PointSegments = np.concatenate([Points[:-1],Points[1:]], axis=1)
    lc = LineCollection(PointSegments, cmap=plt.get_cmap('jet'), 
                        norm=norm) 
    #plt.gca().add_collection(lc)
    ax.add_collection(lc)
    ax.set_xlim( min(xVec), max(xVec) ) 
    ax.set_ylim( np.amin(lineSegments), np.amax(lineSegments) )
    lc.set_array(cValue)
 
fig.colorbar(lc)

def update(changed_lines):
    for i in range(0, len(lineSegments)):
        if (changed_lines.get_cmap() != lc.get_cmap()
            or changed_lines.get_clim() != lc.get_clim()):
          lc.set_cmap(changed_lines.get_cmap())
          lc.set_clim(changed_lines.get_clim())
          
        
for i in range(0, len(lineSegments)):
    lc.callbacksSM.connect('changed',update)

plt.show()

我已经修改了你的代码。本质上,您需要做的是为整个数据集创建一个范数实例,然后根据给定范数的颜色图为段分配颜色值。然后您可以将其相应地传递给颜色条。

如此

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
from matplotlib import colors

lineSegments = [np.linspace(0,1,10),
                np.linspace(0,5,10),
                np.linspace(0,2,10)]

xVec = np.linspace(0,1,10)

fig, ax = plt.subplots()


norm = colors.Normalize(vmin=min([ i.min() for i in lineSegments ]),
                        vmax=max([i.max() for i in lineSegments]))
cmap = plt.get_cmap('jet')
for i in range(0, len(lineSegments)):
    cValue = norm(lineSegments[i])
    c = cmap(cValue)
    Points = np.array([xVec, lineSegments[i]]).T.reshape(-1,1,2)
    PointSegments = np.concatenate([Points[:-1],Points[1:]], axis=1)
    lc = LineCollection(PointSegments, cmap=cmap,
                        norm=norm, colors = c)
    #plt.gca().add_collection(lc)
    ax.add_collection(lc)
    ax.set_xlim( min(xVec), max(xVec) )
    ax.set_ylim( np.amin(lineSegments), np.amax(lineSegments) )
    # lc.set_array(cValue)
sc = plt.cm.ScalarMappable(norm = norm, cmap = cmap)
fig.colorbar(sc)

def update(changed_lines):
    for i in range(0, len(lineSegments)):
        if (changed_lines.get_cmap() != lc.get_cmap()
            or changed_lines.get_clim() != lc.get_clim()):
            lc.set_cmap(changed_lines.get_cmap())
            lc.set_clim(changed_lines.get_clim())


for i in range(0, len(lineSegments)):
    lc.callbacksSM.connect('changed',update)

plt.show()