【问题标题】:How to get part of a colormap如何获取颜色图的一部分
【发布时间】:2020-05-14 04:25:48
【问题描述】:

我正在从一个类中的数据框“self.data”中绘制一些曲线。数据框的每一列都是一条曲线,列名写在行尾。

我为此制作了这个程序:

cmap = plt.cm.get_cmap('brg', len(self.data.columns)+1)

for i in range(len(self.data.columns)): #plot curves and add legend
        self.courbe.plot(self.data[self.data.columns[i]],c=cmap(i))

        angle=20
        self.courbe.annotate(self.data.columns[i], 
                    xy= (max(self.data.index),self.data.at[max(self.data.index),self.data.columns[i]]),
                    textcoords='offset points',
                    xytext=(2, 0),
                    va='bottom',
                    rotation=angle,c=cmap(i))

所以我使用了“brg”颜色图,但我只想使用该颜色图的一部分(例如删除浅绿色部分)。

我在 stackoverflow 上尝试了一些建议的解决方案,例如 how to extract a subset of a colormap as a new colormap in matplotlib?,但所有曲线的颜色都相同。有人知道另一种方法吗?

谢谢,祝你有美好的一天:)

【问题讨论】:

    标签: python python-3.x pandas matplotlib colormap


    【解决方案1】:

    norm 用于将一系列数字映射到颜色图所需的范围 0..1。我们可以创建一个特殊的规范来获得想要的效果。

    范数取决于最低索引 vmin 和最高索引 vmax。 vmin 将被映射到 0 和 vmax 到 1。

    选择上下颜色(均介于 0 和 1 之间),例如,upper=0.9 以在 bgr 中的浅绿色处停止。并且 lower=0 使所有颜色变为深蓝色。

    一个公式会找到 vmin 和 vmax,它们会将索引 i=0 映射到 lower_color 并将索引 i=num_colors-1 映射到 upper_color。该公式由映射的唯一线性方程得出:

    • 0lower_color
    • num_colors - 1upper_color
    • vmin0
    • vmax1

    您发现值i=0..num_colors-1 的颜色索引为norm(i),对应的颜色为cmap(norm(i))

    import matplotlib.pyplot as plt
    import matplotlib as mpl
    
    cmap = plt.cm.get_cmap('brg')
    
    # between 0 and 1, 0 for the leftmost color of the range, 1 for the rightmost, upper > lower
    upper_color = 0.8
    lower_color = 0.3
    num_colors =  20 # len(self.data.columns)
    factor = (num_colors - 1)/(upper_color - lower_color)
    norm = mpl.colors.Normalize(vmin=-lower_color*factor, vmax=(1 - lower_color)*factor)
    
    for i in range(num_colors):
        plt.plot([0, 1], [0, i], c=cmap(norm(i)))
    
    plt.show()
    

    brg 地图的示例并在 0.3 和 0.8 之间选择颜色,只是为了展示它的工作原理。作为参考,有一个应用了相同限制的颜色条。以及brg 的完整颜色条。

    颜色条生成如下:

    c_map_ax = plt.gcf().add_axes([0.84, 0.1, 0.02, 0.8])
    mpl.colorbar.ColorbarBase(c_map_ax, cmap=cmap, orientation='vertical')
    c_map_ax.axes.set_ylim(lower_color, upper_color)
    c_map_ax2 = plt.gcf().add_axes([0.92, 0.1, 0.02, 0.8])
    mpl.colorbar.ColorbarBase(c_map_ax2, cmap=cmap, orientation='vertical')
    plt.subplots_adjust(right=0.8)
    

    【讨论】:

    • 完美运行!非常感谢您的解决方案和解释!
    • 我不明白这里使用的因素。我认为lower_color=0.3 的底线是紫色,而不是顶部。
    【解决方案2】:

    另一个答案使用的因素可能有点不直观;因此这里是一样的,只是没有任何规范或因素。您仍然可以选择介于 0 和 1 之间的下限值和上限值,然后从颜色图中获取该范围内的颜色。然后循环它们:

    import matplotlib.pyplot as plt
    import numpy as np
    
    cmap = plt.cm.get_cmap('brg')
    
    # between 0 and 1, 0 for the leftmost color of the range, 1 for the rightmost, upper > lower
    upper_color = 0.8
    lower_color = 0.3
    num_colors =  20 # len(self.data.columns)
    colors = cmap(np.linspace(lower_color, upper_color, num_colors))
    
    for i, color in enumerate(colors):
        plt.plot([0, 1], [0, i], color=color)
    
    plt.show()
    

    【讨论】:

    • 不错。对于此解决方案,您不需要上限 > 下限的限制。您甚至可以使用它来简单地反转颜色数组。
    猜你喜欢
    • 1970-01-01
    • 2016-02-15
    • 2018-02-13
    • 1970-01-01
    • 2018-09-21
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多