Пользовательские интервалы цветовой палитры в морской карте. - PullRequest
0 голосов
/ 05 мая 2018

Я пытаюсь построить карту тепла , используя библиотеку seaborn.

Функция построения графика выглядит следующим образом:

def plot_confusion_matrix(data, labels, **kwargs):
    """Visualize confusion matrix as a heat map."""
    col_map = kwargs.get('color_palette', sns.light_palette('navy', n_colors=5, as_cmap=False))

    sns.heatmap(
        vmin=0.0,
        vmax=1.0,
        data=data,
        cmap=col_map,
        xticklabels=labels,
        yticklabels=labels,
        linewidths=0.75,
    )

Гистограмма data, однако, выглядит следующим образом: Histogram

Теперь проблема, с которой я сталкиваюсь, заключается в том, что тепловая карта морского побережья (см. Ниже) равномерно разделяет цветовую шкалу, и, следовательно, большинство данных имеют одинаковый цвет (поскольку данные распределены неравномерно).

Мне не удалось выяснить, как установить какие-то интервалы или границы для уровней цвета.

Предположим, у меня есть следующий массив шестнадцатеричных значений цвета:

['#e5e5ff', '#acacdf', '#7272bf', '#39399f', '#000080']

Есть ли способ настроить цвет, например

[(threshold_0, hex_0), (threshold_1, hex_1), ..., (threshold_n, hex_n)]

, где threshold_i - значение в диапазоне [0, 1)


Цени любую помощь.

PS: текущая тепловая карта для иллюстрации:

enter image description here

Ответы [ 3 ]

0 голосов
/ 08 мая 2018

Мне удалось найти (не очень чистое, на мой взгляд) решение этой проблемы, использующее matplotlib.colors.LinearSegmentedColormap.

Код выглядит так:

# NOTE: jupyter notebook mode
%matplotlib inline

import seaborn as sns
from matplotlib.colors import LinearSegmentedColormap

boundaries = [0.0, 0.05, 0.1, 0.25, 0.5, 0.75, 0.9, 1.0]  # custom boundaries

# here I generated twice as many colors, 
# so that I could prune the boundaries more clearly
hex_colors = sns.light_palette('navy', n_colors=len(boundaries) * 2 + 2, as_cmap=False).as_hex()
hex_colors = [hex_colors[i] for i in range(0, len(hex_colors), 2)]

colors=list(zip(boundaries, hex_colors))

custom_color_map = LinearSegmentedColormap.from_list(
    name='custom_navy',
    colors=colors,
)

 sns.heatmap(
        vmin=0.0,
        vmax=1.0,
        data=data,
        cmap=custom_color_map,
        xticklabels=labels,
        yticklabels=labels,
        linewidths=0.75,
  )
0 голосов
/ 08 мая 2018

хорошо, в отношении этой документации здесь: https://matplotlib.org/gallery/images_contours_and_fields/custom_cmap.html#sphx-glr-gallery-images-contours-and-fields-custom-cmap-py

Вы можете создать свой собственный словарь цветов. Это должны быть значения rgb-значений, поэтому я написал первую тестовую функцию для генерации из Hex_colors и ваших желаемых порогов:

def NonLinCdict(steps, hexcol_array):
    cdict = {'red': (), 'green': (), 'blue': ()}
    for s, hexcol in zip(steps, hexcol_array):
        rgb =matplotlib.colors.hex2color(hexcol)
        cdict['red'] = cdict['red'] + ((s, rgb[0], rgb[0]),)
        cdict['green'] = cdict['green'] + ((s, rgb[1], rgb[1]),)
        cdict['blue'] = cdict['blue'] + ((s, rgb[2], rgb[2]),)
    return cdict

hc = ['#e5e5ff', '#acacdf', '#7272bf', '#39399f', '#000080']
th = [0, 0.1, 0.5, 0.9, 1]

cdict = NonLinCdict(th, hc)
cm = mc.LinearSegmentedColormap('test', cdict)

plt.figure()
sns.heatmap(
        vmin=0.0,
        vmax=1.0,
        data=data,
        cmap=cm,
        linewidths=0.75)

, который генерирует:

enter image description here

Можно сделать еще больше (например, в отношении дискретных переходов, просто взгляните на документы ...), но это должно ответить на ваш первоначальный вопрос - на этот раз "custom" включено ...

Однако я должен добавить свое личное мнение: карты цветов, которые растянуты вот так, могут быть «приятными», но следует обратить внимание, что они не вводят глаз зрителя в заблуждение.

Надеюсь, это поможет.

0 голосов
/ 07 мая 2018

Сознательно не обращаясь к «обычаю» в вашем вопросе - возможно, это поможет тем временем:

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

См. Также https://matplotlib.org/examples/color/colormaps_reference.html

enter image description here

создано с помощью

sns.heatmap(vmin=0.0, vmax=1.0, data=data,  cmap='gist_ncar', linewidths=0.75)
...