【问题标题】:LineCollections for few lines with a single colorbar带有单个颜色条的几行的 LineCollections
【发布时间】:2021-07-19 00:47:57
【问题描述】:

我正在尝试在绘图中使用 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()

【问题讨论】:

    标签: numpy matplotlib matplotlib-basemap


    【解决方案1】:

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

    这样

    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()
    

    【讨论】:

    • 我认为只是小注释,直接设置颜色值会使 linecollection 中的 norm 和 cmap 变得多余。
    猜你喜欢
    • 1970-01-01
    • 2018-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-28
    • 2021-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多