关于python:使用Colormaps在matplotlib中设置线条的颜色

Using Colormaps to set color of line in matplotlib

如何使用运行时使用颜色图(例如jet)使用提供的标量值在matplotlib中设置行的颜色? 我在这里尝试了几种不同的方法,但我觉得很困惑。 values[]是一个存储的标量数组。 曲线是一组一维数组,标签是文本字符串数组。 每个数组的长度相同。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
fig = plt.figure()
ax = fig.add_subplot(111)
jet = colors.Colormap('jet')
cNorm  = colors.Normalize(vmin=0, vmax=values[-1])
scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet)
lines = []
for idx in range(len(curves)):
    line = curves[idx]
    colorVal = scalarMap.to_rgba(values[idx])
    retLine, = ax.plot(line, color=colorVal)
    #retLine.set_color()
    lines.append(retLine)
ax.legend(lines, labels, loc='upper right')
ax.grid()
plt.show()

您收到的错误是由于如何定义jet而引起的。您正在创建名称为'jet'的基类Colormap,但这与获取'jet'颜色图的默认定义非常不同。永远不要直接创建此基类,而只能实例化子类。

在示例中发现的是Matplotlib中的错误行为。运行此代码时,应该会生成更清晰的错误消息。

这是您的示例的更新版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import matplotlib.cm as cmx
import numpy as np

# define some random data that emulates your indeded code:
NCURVES = 10
np.random.seed(101)
curves = [np.random.random(20) for i in range(NCURVES)]
values = range(NCURVES)

fig = plt.figure()
ax = fig.add_subplot(111)
# replace the next line
#jet = colors.Colormap('jet')
# with
jet = cm = plt.get_cmap('jet')
cNorm  = colors.Normalize(vmin=0, vmax=values[-1])
scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet)
print scalarMap.get_clim()

lines = []
for idx in range(len(curves)):
    line = curves[idx]
    colorVal = scalarMap.to_rgba(values[idx])
    colorText = (
        'color: (%4.2f,%4.2f,%4.2f)'%(colorVal[0],colorVal[1],colorVal[2])
        )
    retLine, = ax.plot(line,
                       color=colorVal,
                       label=colorText)
    lines.append(retLine)
#added this to get the legend to work
handles,labels = ax.get_legend_handles_labels()
ax.legend(handles, labels, loc='upper right')
ax.grid()
plt.show()

导致:

enter image description here

使用ScalarMappable是我相关答案中提出的方法的改进:
使用matplotlib创建20多种独特的图例颜色


我认为,使用numpy的linspace和matplotlib的cm型对象结合使用,我认为是更简单的方法将是有益的。上面的解决方案可能适用于旧版本。我正在使用python 3.4.3,matplotlib 1.4.3和numpy 1.9.3。,我的解决方案如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import matplotlib.pyplot as plt

from matplotlib import cm
from numpy import linspace

start = 0.0
stop = 1.0
number_of_lines= 1000
cm_subsection = linspace(start, stop, number_of_lines)

colors = [ cm.jet(x) for x in cm_subsection ]

for i, color in enumerate(colors):
    plt.axhline(i, color=color)

plt.ylabel('Line Number')
plt.show()

这将产生1000条独特的颜色线,这些颜色线将覆盖整个cm.jet色彩图,如下图所示。如果运行此脚本,则会发现您可以放大各行。

cm.jet between 0.0 and 1.0 with 1000 graduations

现在说我希望我的1000种线条颜色仅跨越400到600行之间的绿色部分。我只是将起始值和停止值更改为0.4和0.6,这导致在0.4和0.6之间仅使用了20%的cm.jet颜色图。 0.6。

enter image description here

因此,在一行摘要中,您可以从matplotlib.cm颜色表中相应地创建rgba颜色的列表:

1
colors = [ cm.jet(x) for x in linspace(start, stop, number_of_lines) ]

在这种情况下,我使用通常调用的名为jet的地图,但是您可以通过调用以下内容找到matplotlib版本中可用的颜色图的完整列表:

1
2
>>> from matplotlib import cm
>>> dir(cm)


来自matplotlib的线条样式,标记和定性颜色的组合:

1
2
3
4
5
6
7
8
9
10
import itertools
import matplotlib as mpl
import matplotlib.pyplot as plt
N = 8*4+10
l_styles = ['-','--','-.',':']
m_styles = ['','.','o','^','*']
colormap = mpl.cm.Dark2.colors   # Qualitative colormap
for i,(marker,linestyle,color) in zip(range(N),itertools.product(m_styles,l_styles, colormap)):
    plt.plot([0,1,2],[0,2*i,2*i], color=color, linestyle=linestyle,marker=marker,label=i)
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.,ncol=4);

enter image description here

更新:不仅支持ListedColormap,还支持LinearSegmentedColormap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import itertools
import matplotlib.pyplot as plt
Ncolors = 8
#colormap = plt.cm.Dark2# ListedColormap
colormap = plt.cm.viridis# LinearSegmentedColormap
Ncolors = min(colormap.N,Ncolors)
mapcolors = [colormap(int(x*colormap.N/Ncolors)) for x in range(Ncolors)]
N = Ncolors*4+10
l_styles = ['-','--','-.',':']
m_styles = ['','.','o','^','*']
fig,ax = plt.subplots(gridspec_kw=dict(right=0.6))
for i,(marker,linestyle,color) in zip(range(N),itertools.product(m_styles,l_styles, mapcolors)):
    ax.plot([0,1,2],[0,2*i,2*i], color=color, linestyle=linestyle,marker=marker,label=i)
ax.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.,ncol=3,prop={'size': 8})

enter image description here


您可能会按照我从已删除的帐户中写的来做(禁止发布新帖子:(曾经有)。它看起来相当简单和美观。

我通常使用这3个中的第3个,我也不想检查1和2版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from matplotlib.pyplot import cm
import numpy as np

#variable n should be number of curves to plot (I skipped this earlier thinking that it is obvious when looking at picture - sorry my bad mistake xD): n=len(array_of_curves_to_plot)
#version 1:

color=cm.rainbow(np.linspace(0,1,n))
for i,c in zip(range(n),color):
   ax1.plot(x, y,c=c)

#or version 2: - faster and better:

color=iter(cm.rainbow(np.linspace(0,1,n)))
c=next(color)
plt.plot(x,y,c=c)

#or version 3:

color=iter(cm.rainbow(np.linspace(0,1,n)))
for i in range(n):
   c=next(color)
   ax1.plot(x, y,c=c)

3的示例

侧倾振幅与池田阻尼的船舶RAO与侧倾振幅A44的函数