Изменения в стандартном графике тепловой карты – симметричные цвета столбцов, показывать только диагональные значения и имена столбцов на отметках осей x, y.

Вопрос или проблема

У меня есть изображение тепловой карты (корреляция между всеми столбцами матрицы), и я не могу выполнить все изменения, указанные ниже, в одном и том же изображении:

  1. Цвета столбцов должны быть симметричны относительно нуля (например, корреляция 1 и -1 должна быть одного цвета)
  2. Измените корреляционную матрицу на диагональную матрицу, так как значения корреляции симметричны, и покажите только верхний треугольник матрицы (замаскируйте нижний треугольник)
  3. Покажите значения корреляции в каждой ячейке диагональной матрицы
  4. Подписи осей x, y – покажите названия столбцов (вместо.serial номера)

Вот код:

def generate_heatmap(X):

    """
    График тепловой карты корреляции Пирсона

    :return:
    """
    print("Начало построения тепловой карты корреляции Пирсона  .. ", datetime.now())

    plt.figure(figsize=(10,8))
    plt.title('Корреляция Пирсона miRNAs', y=1.05, size=15)

    # Корреляционная матрица для тепловой карты
    corr = np.corrcoef(X.transpose())

    plt.imshow(corr, cmap='BuPu', interpolation='nearest')
    plt.colorbar()
    plt.show()

Это то, как я получил желаемый график:

def generate_heatmap(X):

    """
    График тепловой карты корреляции Пирсона

    :return:
    """
    #from matplotlib import cm as CM
    from matplotlib.colors import LinearSegmentedColormap

    print("Начало построения тепловой карты корреляции Пирсона  .. ", datetime.now())

    # получение имен столбцов
    cols = X.columns
    # определите график для тепловой карты
    fig, ax = plt.subplots(figsize=(16,16))

    # ------------------------------------------------------------
    # Корреляционная матрица для тепловой карты. Транспонирование, потому что нам нужна матрица pxp (а не nxn)
    corr = np.corrcoef(X, rowvar=False)
    # показываем только верхний треугольник матрицы - замаскируем нижний треугольник данных корреляции
    corr = np.triu(corr, k=0) 

    # ------------------------------------------------------------
    # Редактирование графики графика
    plt.title('Корреляция Пирсона ' + str(len(cols)) + ' miRNAs', y=1.05, size=15, fontsize=32)

    # цвета столбцов должны быть симметричны относительно нуля!
    colors = [(1, 0, 0), 'w', (1, 0, 0)] 
    cm = LinearSegmentedColormap.from_list('heatmap', colors, N=20)    

    # ------------------------------------------------------------
    # Тепловая карта на основе матрицы корреляции, которую мы предоставили
    c = plt.pcolor(corr, edgecolors="w", linewidths=2, cmap=cm, vmin=-1.0, vmax=1.0)

    # ------------------------------------------------------------
    # Редактирование дополнительной графики графика (если она не слишком большая)
    if len(cols) < 50:

        # установка названий меток осей
        ax.set_xticks(np.arange(len(cols)))
        ax.set_xticklabels(labels=cols, rotation=45, fontsize=12, ha="center")

        ax.set_yticks(np.arange(len(cols)))
        ax.set_yticklabels(labels=cols, rotation=45, fontsize=12)

        # показ значений корреляции в каждой ячейке
        for (i, j), z in np.ndenumerate(corr):
            # в симметричных значениях не аннотируем ячейку значением корреляции
            if (i > j): 
                continue
            else:
                # va и ha не работают, мы добавляем +0.4, чтобы обойти центровку значений 
                ax.text(j+0.4, i+0.4, '{:0.2f}'.format(z), ha="center", va="bottom", fontsize=11)

    plt.colorbar(c)
    plt.show()

#generate_heatmap(miRNA_data[selected_mir_columns])

Ответ или решение

Для создания изменённого графика тепловой карты (heatmap) корреляции между столбцами матрицы, следует внести несколько точечных изменений в исходный код. Давайте разберём каждый из пунктов требований.

1. Симметричные цвета для значений

Чтобы цвета на тепловой карте были симметричными относительно нуля (т.е. корреляция +1 и -1 имела бы одинаковый цвет), необходимо изменить цветовую карту, используя градиент от красного через белый к красному. Этот градиент будет указывать на положительные и отрицательные корреляции.

2. Отображение только диагональных значений

Смещение для отображения только позвоночных значений матрицы корреляции можно достичь с помощью функции np.triu, которая маскирует нижнюю триугольную часть матрицы. Таким образом, мы будем отображать только верхнюю треугольную часть, где находятся все интересные значения, сохраняющие симметрию.

3. Показ значений в каждой ячейке

Для отображения значений корреляции в каждом соответствующем элементе диагональной матрицы необходимо использовать функцию для аннотирования графика. Однако нужно убедиться, что аннотация происходит только для верхней части матрицы.

4. Подписи осей и отображение названий столбцов

Этикетки по оси X и Y следует настроить таким образом, чтобы они отображали названия соответствующих колонок из оригинального датафрейма.

Итоговый код

Вот обновлённый код функции generate_heatmap, который включает все вышеперечисленные требования:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
from datetime import datetime

def generate_heatmap(X):
    """
    Построение тепловой карты корреляции Пирсона.

    :param X: Входные данные (DataFrame)
    :return: Отображение тепловой карты
    """
    print("Начало построения тепловой карты корреляции Пирсона ..", datetime.now())

    # Получаем названия колонок
    cols = X.columns

    # Определяем график для тепловой карты
    fig, ax = plt.subplots(figsize=(16, 16))

    # Корреляционная матрица
    corr = np.corrcoef(X, rowvar=False)
    # Маскируем нижнюю треугольную матрицу
    corr = np.triu(corr, k=0)

    # Заголовок графика
    plt.title('Корреляция Пирсона для ' + str(len(cols)) + ' miRNA', y=1.05, size=15, fontsize=32)

    # Симметричные цвета
    colors = [(1, 0, 0), 'w', (1, 0, 0)]
    cm = LinearSegmentedColormap.from_list('heatmap', colors, N=20)

    # Построение тепловой карты
    c = plt.pcolor(corr, edgecolors="w", linewidths=2, cmap=cm, vmin=-1.0, vmax=1.0)

    # Изменение графических настроек
    if len(cols) < 50:
        # Настройка меток осей
        ax.set_xticks(np.arange(len(cols)))
        ax.set_xticklabels(labels=cols, rotation=45, fontsize=12, ha="center")

        ax.set_yticks(np.arange(len(cols)))
        ax.set_yticklabels(labels=cols, rotation=45, fontsize=12)

        # Показ значений корреляции в каждой ячейке
        for (i, j), z in np.ndenumerate(corr):
            if i > j:
                continue
            ax.text(j + 0.4, i + 0.4, '{:0.2f}'.format(z), ha="center", va="bottom", fontsize=11)

    plt.colorbar(c)
    plt.show()

# Применение функции на вашем наборе данных
# generate_heatmap(miRNA_data[selected_mir_columns])

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...