Используя цветовые схемы, чтобы задать цвет линии в библиотек matplotlib


Как установить цвет строки в matplotlib со скалярными значениями, предоставленными во время выполнения с помощью цветовой карты (скажем jet)? Я попробовал несколько разных подходов здесь, и я думаю, что я в тупике. values[] - это стортированный массив скаляров. кривые представляют собой набор одномерных массивов, а метки-массив текстовых строк. Каждый из массивов имеет одинаковую длину.

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

4 ответа:

ошибка, которую вы получаете из-за того, как вы определяете jet. Вы создаете базовый класс Colormap С именем "jet", но это очень отличается от получения определения по умолчанию цветовой карты "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 - это улучшение по сравнению с подходом, представленным в моей теме отвечай: создание более 20 уникальных цветов легенды с помощью matplotlib

Я подумал, что было бы полезно включить то, что я считаю более простым методом, используя linspace numpy в сочетании с объектом cm-типа matplotlib. Возможно, что вышеуказанное решение предназначено для более старой версии. Я использую 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 уникально окрашенных линий, которые охватывают весь см.jet colormap, как показано на рисунке ниже. Если вы запустите этот скрипт, вы обнаружите, что можете увеличьте масштаб отдельных линий.

см.самолет между 0.0 и 1.0 с 1000 градуировка

Теперь скажите, что я хочу, чтобы мои 1000 цветов линии просто охватывали зеленоватую часть между линиями 400 до 600. Я просто изменяю свои значения start и stop на 0.4 и 0.6, и это приводит к использованию только 20% cm.двигателя цвет карты между 0,4 и 0,6.

см.самолет между 0,4 и 0,6 с 1000 градуировка

Так что в одной строке резюме вы можете создайте список цветов rgba из a matplotlib.cm цветовая карта соответственно:

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

в этом случае я использую обычно вызываемую карту с именем jet, но вы можете найти полный список цветных карт, доступных в вашей версии matplotlib, вызвав:

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

сочетание стилей линий, маркеров и качественных цветов от 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

U может сделать так, как я написал из моей удаленной учетной записи (бан для новых сообщений :( было). Его довольно простой и красивый вид.

Я использую 3-й один из этих 3-х обычно, также я проверял версию 1 и 2.

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:

корабль РАО крена против Икэда амортизируя в функции амплитуды крена А44