首页 文章

使用matplotlib创建超过20种独特的图例颜色

提问于
浏览
33

我正在使用matplotlib在一个图上绘制20条不同的线 . 我使用for循环绘制并用其键标记每一行,然后使用图例功能

for key in dict.keys():
    plot(x,dict[key], label = key)
graph.legend()

但是使用这种方式,图表在图例中重复了很多颜色 . 有没有办法确保使用matplotlib和超过20行为每条线分配一个独特的颜色?

谢谢

3 回答

  • 11

    您的问题的答案与另外两个SO问题有关 .

    How to pick a new color for each plotted line within a figure in matplotlib?的答案解释了如何定义循环的颜色的默认列表,以选择要绘制的下一种颜色 . 这是通过 Axes.set_color_cycle method完成的 .

    您希望获得正确的颜色列表,这最容易使用颜色映射完成,如此问题的答案中所述:Create a color generator from given colormap in matplotlib . 颜色贴图的值从0到1并返回颜色 .

    因此,对于20行,您希望以1/20的步长从0循环到1 . 具体来说,您希望将表单0循环到19/20,因为1映射回0 .

    这是在这个例子中完成的:

    import matplotlib.pyplot as plt
    import numpy as np
    
    NUM_COLORS = 20
    
    cm = plt.get_cmap('gist_rainbow')
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.set_color_cycle([cm(1.*i/NUM_COLORS) for i in range(NUM_COLORS)])
    for i in range(NUM_COLORS):
        ax.plot(np.arange(10)*(i+1))
    
    fig.savefig('moreColors.png')
    plt.show()
    

    这是结果图:

    Yosemitebear Mountain Giant Double Rainbow 1-8-10

    Alternative, better (debatable) solution

    有一种替代方法可以使用 ScalarMappable 对象将一系列值转换为颜色 . 此方法的优点是您可以使用非线性 Normalization 将线索引转换为实际颜色 . 以下代码生成相同的确切结果:

    import matplotlib.pyplot as plt
    import matplotlib.cm as mplcm
    import matplotlib.colors as colors
    import numpy as np
    
    NUM_COLORS = 20
    
    cm = plt.get_cmap('gist_rainbow')
    cNorm  = colors.Normalize(vmin=0, vmax=NUM_COLORS-1)
    scalarMap = mplcm.ScalarMappable(norm=cNorm, cmap=cm)
    fig = plt.figure()
    ax = fig.add_subplot(111)
    # old way:
    #ax.set_color_cycle([cm(1.*i/NUM_COLORS) for i in range(NUM_COLORS)])
    # new way:
    ax.set_color_cycle([scalarMap.to_rgba(i) for i in range(NUM_COLORS)])
    for i in range(NUM_COLORS):
        ax.plot(np.arange(10)*(i+1))
    
    fig.savefig('moreColors.png')
    plt.show()
    

    Deprecation Note
    在mplib(1.5)的更新版本中, set_color_cycle 函数已被弃用,而有利于 ax.set_prop_cycle(color=[...]) .

  • 80

    我有一个12行的情节,当我尝试Yann's technique时,我发现很难区分具有相似颜色的线条 . 我的线也成对出现,所以我对每对中的两条线使用相同的颜色,并使用两种不同的线宽 . 您还可以改变线条样式以获得更多组合 .

    您可以使用set_prop_cycle(),但我只是在调用 plot() 后修改了线对象 .

    这是Yann的三个不同线宽的例子:

    import matplotlib.pyplot as plt
    import numpy as np
    
    NUM_COLORS = 20
    
    cm = plt.get_cmap('gist_rainbow')
    fig = plt.figure()
    ax = fig.add_subplot(111)
    for i in range(NUM_COLORS):
        lines = ax.plot(np.arange(10)*(i+1))
        lines[0].set_color(cm(i//3*3.0/NUM_COLORS))
        lines[0].set_linewidth(i%3 + 1)
    
    fig.savefig('moreColors.png')
    plt.show()
    

    Example plot with line widths

    这是具有不同线型的相同示例 . 当然,如果你愿意,你可以将两者结合起来 .

    import matplotlib.pyplot as plt
    import numpy as np
    
    NUM_COLORS = 20
    LINE_STYLES = ['solid', 'dashed', 'dashdot', 'dotted']
    NUM_STYLES = len(LINE_STYLES)
    
    cm = plt.get_cmap('gist_rainbow')
    fig = plt.figure()
    ax = fig.add_subplot(111)
    for i in range(NUM_COLORS):
        lines = ax.plot(np.arange(10)*(i+1))
        lines[0].set_color(cm(i//NUM_STYLES*float(NUM_STYLES)/NUM_COLORS))
        lines[0].set_linestyle(LINE_STYLES[i%NUM_STYLES])
    
    fig.savefig('moreColors.png')
    plt.show()
    

    Example plot with line styles

  • 4

    要 Build Don Kirkby's answer,如果你愿意安装/使用seaborn,那么你可以为你计算颜色:

    import matplotlib.pyplot as plt
    import seaborn as sns
    import numpy as np
    
    NUM_COLORS = 20
    LINE_STYLES = ['solid', 'dashed', 'dashdot', 'dotted']
    NUM_STYLES = len(LINE_STYLES)
    
    sns.reset_orig()  # get default matplotlib styles back
    clrs = sns.color_palette('husl', n_colors=NUM_COLORS)  # a list of RGB tuples
    fig, ax = plt.subplots(1)
    for i in range(NUM_COLORS):
        lines = ax.plot(np.arange(10)*(i+1))
        lines[0].set_color(clrs[i])
        lines[0].set_linestyle(LINE_STYLES[i%NUM_STYLES])
    
    fig.savefig('moreColors.png')
    plt.show()
    

    除了能够使用seaborn的各种调色板外,您还可以获得 list of RGB tuples ,如果需要,可以在以后使用/操作 . 显然,你可以使用matplotlib的色彩图来计算类似的东西,但我觉得这很方便 .
    seaborn husl color map with 20 colors

相关问题