2012-01-19 79 views
53

如何設置matplotlib中的線條顏色以及運行時使用顏色貼圖提供的標量值(如jet)?我在這裏嘗試了幾種不同的方法,我想我很難過。 values[]是一個標量數組。曲線是一組一維數組,標籤是一組文本字符串。每個陣列具有相同的長度。使用Colormaps設置matplotlib中的線條顏色

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

回答

66

您收到的錯誤是由於您如何定義jet。您正在創建名爲'jet'的基類Colormap,但這與獲得'jet'顏色表的默認定義完全不同。永遠不要直接創建這個基類,只應該實例化子類。

你發現你的例子是Matplotlib中的一個錯誤行爲。此代碼運行時應該生成更清晰的錯誤消息。

這是你的榜樣的更新版本:

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結束了在我相關答案提出的方法的改進: creating over 20 unique legend colors using matplotlib

35

我認爲這將是有益的包括瓦特我認爲這是一個更簡單的方法,使用numpy的linspace和matplotlib的cm類型對象。上述解決方案可能適用於舊版本。我使用python 3.4.3,matplotlib 1.4.3和numpy 1.9.3,我的解決方案如下。

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,這導致使用僅20%之間的綠色部分cm.jet彩色圖在0.4和0.6之間。

cm.jet between 0.4 and 0.6 with 1000 graduations

因此,在一個行彙總,您可以創建從matplotlib的RGBA顏色列表。釐米顏色映射因此:

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

在這種情況下,我使用了常用調用的地圖命名爲噴氣機,但你可以通過調用找到您matplotlib版本色彩映射的完整列表:

>>> from matplotlib import cm 
>>> dir(cm) 
+0

這隻適用於你的'stop'是1 – Eric

+1

當然1是最好的價值。如果你想要更大範圍的顏色,你只需要增加'number_of_lines'。如果您只想要樂隊中的一部分顏色,可以根據需要減少「停止」並增加「開始」。 – Parousia

+0

一個簡單的問題:如何將顏色條而不是圖例添加到您的情節? –

7

線的組合樣式,標記和定性顏色matplotlib

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