使用matplotlib颜色映射进行颜色循环

Mor*_*itz 8 python matplotlib

如果我通过例如:import numpy as np从matplotlib import pyplot创建颜色为plt

n = 6
color = plt.cm.coolwarm(np.linspace(0.1,0.9,n))
color
Run Code Online (Sandbox Code Playgroud)

颜色是一个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. ]])

但是,如果我在我的.mplstyle文件(map(tuple,color[:,0:-1]))中插入RGB值(没有alpha值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))

任何想法为什么?

Imp*_*est 19

“连续”颜色图

如果您想N从“连续”颜色图中循环颜色,例如默认的 viridis 地图,@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()
Run Code Online (Sandbox Code Playgroud)

“离散”颜色图

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()
Run Code Online (Sandbox Code Playgroud)

请注意,只有ListedColormaps具备.colors的属性,所以这仅适用于那些颜色表,而不是例如在jet地图。

组合方案

下面是一个通用函数,它将颜色图作为输入并输出相应的循环器。我最初在这个 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)
Run Code Online (Sandbox Code Playgroud)

“连续”情况的用法:

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()
Run Code Online (Sandbox Code Playgroud)

用于“离散”情况

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()
Run Code Online (Sandbox Code Playgroud)


Ger*_*ges 13

对于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)
Run Code Online (Sandbox Code Playgroud)


cph*_*wis 6

编辑 04/2021:从 matplotlib 2.2.0 开始,该密钥axes.color_cycle已被弃用(来源:API 更改)。新方法是使用set_prop_cycle来源: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()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述 在此输入图像描述 在此输入图像描述