use matplotlib color map for color cycle

后端 未结 3 485
夕颜
夕颜 2020-11-30 05:29

If I create colors by e.g:

import numpy as np
from matplotlib import pyplot as plt

n = 6
color = plt.cm.coolwarm(np.linspace(0.1,0.9,n))
color
3条回答
  •  醉梦人生
    2020-11-30 05:55

    "Continuous" colormap

    If you want to cycle through N colors from a "continous" colormap, like e.g. the default viridis map, the solution by @Gerges works nicely.

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

    "Discrete" colormap

    Matplotlib provides a few colormap that are "discrete" in the sense that they hold some low number of distinct colors for qualitative visuals, like the tab10 colormap. To cycle through such colormap, the solution might be to not use N but just port all colors of the map to the cycler.

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

    Note that only ListedColormaps have the .colors attribute, so this only works for those colormap, but not e.g. the jet map.

    Combined solution

    The following is a general purpose function that takes a colormap as input and outputs a corresponding cycler. I originally proposed this solution in 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)
    

    Usage for the "continuous" case:

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

    Usage for the "discrete" case

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

提交回复
热议问题