Как получить часть цветовой карты - PullRequest
4 голосов
/ 28 января 2020

Я строю некоторые кривые из фрейма данных "self.data" в классе. Каждый столбец данных - это кривая, а имя столбца пишется в конце строки.

Я сделал эту программу для этого:

cmap = plt.cm.get_cmap('brg', len(self.data.columns)+1)

for i in range(len(self.data.columns)): #plot curves and add legend
        self.courbe.plot(self.data[self.data.columns[i]],c=cmap(i))

        angle=20
        self.courbe.annotate(self.data.columns[i], 
                    xy= (max(self.data.index),self.data.at[max(self.data.index),self.data.columns[i]]),
                    textcoords='offset points',
                    xytext=(2, 0),
                    va='bottom',
                    rotation=angle,c=cmap(i))

Поэтому я использовал "brg "colormap, но я бы хотел использовать только часть этой цветовой карты (например, удалив светло-зеленую часть).

Я попробовал некоторые предложенные решения для stackoverflow, как , как извлечь подмножество colormap как новая colormap в matplotlib? , но все кривые были одного цвета. Кто-нибудь знает другой способ сделать это?

Спасибо и хорошего дня:)

Ответы [ 2 ]

3 голосов
/ 28 января 2020

Фактор, используемый другим ответом, может быть немного не интуитивным; следовательно, здесь то же самое, просто без какой-либо нормы или фактора. Вы по-прежнему выбираете нижнее и верхнее значения от 0 до 1 и просто получаете цвета в этом диапазоне из цветовой карты. Тогда l oop над ними:

import matplotlib.pyplot as plt
import numpy as np

cmap = plt.cm.get_cmap('brg')

# between 0 and 1, 0 for the leftmost color of the range, 1 for the rightmost, upper > lower
upper_color = 0.8
lower_color = 0.3
num_colors =  20 # len(self.data.columns)
colors = cmap(np.linspace(lower_color, upper_color, num_colors))

for i, color in enumerate(colors):
    plt.plot([0, 1], [0, i], color=color)

plt.show()

enter image description here

3 голосов
/ 28 января 2020

A norm используется для сопоставления диапазона чисел с диапазоном 0..1, необходимым для цветовой карты. Мы можем создать специальную норму, чтобы получить желаемый эффект.

Норма зависит от vmin, самого низкого индекса, и vmax, самого высокого индекса. vmin будет отображаться в 0, а vmax в 1.

Выбор верхнего и нижнего цветов (каждый между 0 и 1), например, верхнего = 0,9, чтобы остановиться на светло-зеленых в бгр . И ниже = 0, чтобы получить все цвета вплоть до темно-синего.

Формула находит значения vmin и vmax, которые бы отображали индекс i=0 на lower_color и индекс i=num_colors-1 на upper_color. Формула следует из единственного линейного уравнения, которое отображает:

  • 0 на lower_color
  • num_colors - 1 на upper_color
  • vmin на 0
  • vmax до 1

Вы найдете индекс цвета для значения i=0..num_colors-1 как norm(i) и соответствующий цвет как cmap(norm(i)).

import matplotlib.pyplot as plt
import matplotlib as mpl

cmap = plt.cm.get_cmap('brg')

# between 0 and 1, 0 for the leftmost color of the range, 1 for the rightmost, upper > lower
upper_color = 0.8
lower_color = 0.3
num_colors =  20 # len(self.data.columns)
factor = (num_colors - 1)/(upper_color - lower_color)
norm = mpl.colors.Normalize(vmin=-lower_color*factor, vmax=(1 - lower_color)*factor)

for i in range(num_colors):
    plt.plot([0, 1], [0, i], c=cmap(norm(i)))

plt.show()

Пример с картой brg и выбором цветов от 0,3 до 0,8, просто чтобы показать, как это работает. Для справки есть цветовая шкала с теми же ограничениями. И полная цветовая полоса для brg.

example plot

Цветные полосы были сгенерированы следующим образом:

c_map_ax = plt.gcf().add_axes([0.84, 0.1, 0.02, 0.8])
mpl.colorbar.ColorbarBase(c_map_ax, cmap=cmap, orientation='vertical')
c_map_ax.axes.set_ylim(lower_color, upper_color)
c_map_ax2 = plt.gcf().add_axes([0.92, 0.1, 0.02, 0.8])
mpl.colorbar.ColorbarBase(c_map_ax2, cmap=cmap, orientation='vertical')
plt.subplots_adjust(right=0.8)
...