【问题标题】:use matplotlib color map for color cycle使用 matplotlib 颜色图进行颜色循环
【发布时间】:2015-05-06 14:24:57
【问题描述】:

如果我通过例如创建颜色:

import numpy as np
from matplotlib import pyplot as plt

n = 6
color = plt.cm.coolwarm(np.linspace(0.1,0.9,n))
color

color 是一个 numpy 数组:

array([[ 0.34832334,  0.46571115,  0.88834616,  1.        ],
       [ 0.56518158,  0.69943844,  0.99663507,  1.        ],
       [ 0.77737753,  0.84092121,  0.9461493 ,  1.        ],
       [ 0.93577377,  0.8122367 ,  0.74715647,  1.        ],
       [ 0.96049006,  0.61627642,  0.4954666 ,  1.        ],
       [ 0.83936494,  0.32185622,  0.26492398,  1.        ]])

但是,如果我将 RGB 值(没有 alpha 值 1)作为元组插入到我的 .mplstyle 文件 (map(tuple,color[:,0:-1])) 中,我会收到与此类似的错误:

in file "/home/moritz/.config/matplotlib/stylelib/ggplot.mplstyle"
    Key axes.color_cycle: [(0.34832334141176474 does not look like a color arg
  (val, error_details, msg))

有什么想法吗?

【问题讨论】:

  • 颜色参数应该以( 开头,而不是[(,是吗?
  • 还是不行。我试过 ( (...), (...) ) ; (...), (...); (...) (...)

标签: python matplotlib


【解决方案1】:

对于 Matplotlib 2.2,使用 cycler 模块即可,无需转换为十六进制值。

import cycler

n = 100
color = pyplot.cm.viridis(np.linspace(0, 1,n))
mpl.rcParams['axes.prop_cycle'] = cycler.cycler('color', color)

【讨论】:

    【解决方案2】:

    “连续”颜色图

    如果您想从“连续”颜色图中循环显示N 颜色,例如默认的 viridis 映射 the solution by @Gerges 效果很好。

    import matplotlib.pyplot as plt
    
    N = 6
    plt.rcParams["axes.prop_cycle"] = plt.cycler("color", plt.cm.viridis(np.linspace(0,1,N)))
    
    fig, ax = plt.subplots()
    for i in range(N):
        ax.plot([0,1], [i, 2*i])
    
    plt.show()
    

    “离散”颜色图

    Matplotlib 提供了一些“离散”的颜色图,因为它们为定性视觉效果保留了少量不同的颜色,例如 tab10 颜色图。要循环通过这样的颜色图,解决方案可能是不使用N,而只是将地图的所有颜色移植到循环器。

    import matplotlib.pyplot as plt
    
    plt.rcParams["axes.prop_cycle"] = plt.cycler("color", plt.cm.tab20c.colors)
    
    fig, ax = plt.subplots()
    for i in range(15):
        ax.plot([0,1], [i, 2*i])
    
    plt.show()
    

    请注意,只有 ListedColormaps 具有 .colors 属性,因此这仅适用于那些颜色图,但不适用于例如jet 地图。

    组合解决方案

    以下是一个通用函数,它将颜色图作为输入并输出相应的循环器。我最初在this matplotlib issue 中提出了这个解决方案。

    from matplotlib.pyplot import cycler
    import numpy as np
    from matplotlib.colors import LinearSegmentedColormap, ListedColormap
    import matplotlib.cm
    
    def get_cycle(cmap, N=None, use_index="auto"):
        if isinstance(cmap, str):
            if use_index == "auto":
                if cmap in ['Pastel1', 'Pastel2', 'Paired', 'Accent',
                            'Dark2', 'Set1', 'Set2', 'Set3',
                            'tab10', 'tab20', 'tab20b', 'tab20c']:
                    use_index=True
                else:
                    use_index=False
            cmap = matplotlib.cm.get_cmap(cmap)
        if not N:
            N = cmap.N
        if use_index=="auto":
            if cmap.N > 100:
                use_index=False
            elif isinstance(cmap, LinearSegmentedColormap):
                use_index=False
            elif isinstance(cmap, ListedColormap):
                use_index=True
        if use_index:
            ind = np.arange(int(N)) % cmap.N
            return cycler("color",cmap(ind))
        else:
            colors = cmap(np.linspace(0,1,N))
            return cycler("color",colors)
    

    用于“连续”情况:

    import matplotlib.pyplot as plt
    N = 6
    plt.rcParams["axes.prop_cycle"] = get_cycle("viridis", N)
    
    fig, ax = plt.subplots()
    for i in range(N):
        ax.plot([0,1], [i, 2*i])
    
    plt.show()
    

    用于“离散”情况

    import matplotlib.pyplot as plt
    
    plt.rcParams["axes.prop_cycle"] = get_cycle("tab20c")
    
    fig, ax = plt.subplots()
    for i in range(15):
        ax.plot([0,1], [i, 2*i])
    
    plt.show()
    

    【讨论】:

    • plt.rcParams["axes.prop_cycle"] = plt.cycler("color", plt.cm.tab20c.colors) 是我正在寻找的线路!
    • 这太棒了!感谢您的综合解决方案!
    【解决方案3】:

    编辑 04/2021: 从 matplotlib 2.2.0 开始,密钥 axes.color_cycle 已被弃用 (source: API changes)。 新方法是使用set_prop_cycle(source: matplotlib.axes.Axes.set_prop_cycle API)


    细节在 matplotlibrc 本身,实际上:它需要一个字符串代表(十六进制或字母或单词,而不是元组)。

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib as mpl
    
    fig, ax1 = plt.subplots(1,1)
    
    ys = np.random.random((5, 6))
    ax1.plot(range(5), ys)
    ax1.set_title('Default color cycle')
    plt.show()
    
    # From the sample matplotlibrc:
    #axes.color_cycle    : b, g, r, c, m, y, k  # color cycle for plot lines
                                                # as list of string colorspecs:
                                                # single letter, long name, or
                                                # web-style hex
    
    # setting color cycle after calling plt.subplots doesn't "take"
    # try some hex values as **string** colorspecs
    mpl.rcParams['axes.color_cycle'] = ['#129845','#271254', '#FA4411', '#098765', '#000009']
    
    fig, ax2 = plt.subplots(1,1)
    ax2.plot(range(5), ys)
    ax2.set_title('New color cycle')
    
    
    n = 6
    color = plt.cm.coolwarm(np.linspace(0.1,0.9,n)) # This returns RGBA; convert:
    hexcolor = map(lambda rgb:'#%02x%02x%02x' % (rgb[0]*255,rgb[1]*255,rgb[2]*255),
                   tuple(color[:,0:-1]))
    
    mpl.rcParams['axes.color_cycle'] = hexcolor
    
    fig, ax3 = plt.subplots(1,1)
    ax3.plot(range(5), ys)
    ax3.set_title('Color cycle from colormap')
    
    plt.show()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-05
      • 2015-04-10
      • 2015-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多