Створення теплової карти з панд DataFrame


112

У мене є кадр даних, згенерований з пакету Pandas Python. Як я можу генерувати теплову карту за допомогою DataFrame з пакету pandas.

import numpy as np 
from pandas import *

Index= ['aaa','bbb','ccc','ddd','eee']
Cols = ['A', 'B', 'C','D']
df = DataFrame(abs(np.random.randn(5, 4)), index= Index, columns=Cols)

>>> df
          A         B         C         D
aaa  2.431645  1.248688  0.267648  0.613826
bbb  0.809296  1.671020  1.564420  0.347662
ccc  1.501939  1.126518  0.702019  1.596048
ddd  0.137160  0.147368  1.504663  0.202822
eee  0.134540  3.708104  0.309097  1.641090
>>> 

Що ви спробували у створенні теплової карти чи дослідження? Не знаючи більше, я рекомендую перетворити ваші дані та скористатися цим методом
учень

@joelostblom Це не відповідь, це коментар, але проблема полягає в тому, що у мене недостатньо репутації, щоб можна було коментувати. Я трохи збентежений, оскільки вихідне значення матриці та вихідного масиву абсолютно різні. Я хотів би надрукувати на тепловій карті реальні значення, а не деякі інші. Хтось може мені пояснити, чому це відбувається. Наприклад: * вихідні індексовані дані: aaa / A = 2,431645 * друковані значення в тепловій карті: aaa / A = 1.06192
Monitotier

@Monitotier Будь ласка, задайте нове запитання та включіть повний приклад коду того, що ви спробували. Це найкращий спосіб змусити когось допомогти вам зрозуміти, що не так! Ви можете посилання на це питання, якщо вважаєте, що це актуально.
joelostblom

Відповіді:


82

Ви хочете matplotlib.pcolor:

import numpy as np 
from pandas import DataFrame
import matplotlib.pyplot as plt

index = ['aaa', 'bbb', 'ccc', 'ddd', 'eee']
columns = ['A', 'B', 'C', 'D']
df = DataFrame(abs(np.random.randn(5, 4)), index=index, columns=columns)

plt.pcolor(df)
plt.yticks(np.arange(0.5, len(df.index), 1), df.index)
plt.xticks(np.arange(0.5, len(df.columns), 1), df.columns)
plt.show()

Це дає:

Вихідний зразок


5
Там яке - то цікаве обговорення тут про pcolorпорівнянні imshow.
LondonRob

1
… А також pcolormesh, який оптимізований для цього виду графіки.
Ерік О Лебігот

180

Для тих , хто хоче на цьому сьогодні, я б рекомендував Сіборн heatmap()як описано тут .

Наведений вище приклад робиться наступним чином:

import numpy as np 
from pandas import DataFrame
import seaborn as sns
%matplotlib inline

Index= ['aaa', 'bbb', 'ccc', 'ddd', 'eee']
Cols = ['A', 'B', 'C', 'D']
df = DataFrame(abs(np.random.randn(5, 4)), index=Index, columns=Cols)

sns.heatmap(df, annot=True)

Де %matplotlibмагічна функція IPython для незнайомих.


Чому б ти не використовував панди?
tommy.carstensen

9
Seaborn і Pandas прекрасно працюють разом, тому ви все одно використовуєте Pandas, щоб отримати ваші дані в потрібній формі. Seaborn спеціалізується на статичних діаграмах і робить простою створення теплової карти з Pandas DataFrame мертвою простою.
Бридо

Здається, це посилання мертве; Ви можете оновити його? Крім того, як би я запустив вищевказаний код import matplotlib.pyplot as plt?
Клеб

Привіт @Cleb, мені довелося оновити його до заархівованої сторінки, оскільки вона не схожа ніде. Погляньте на їхні документи для його використання з pyplot: stanford.edu/~mwaskom/software/seaborn-dev/tutorial/…
Brideau,

Використовуйте import matplotlib.pyplot as pltзамість цього %matplotlib inlineі закінчіть plt.show(), щоб насправді побачити сюжет.
tsveti_iko

83

Якщо вам не потрібен графік на вимову, і вас просто цікавить додавання кольору для представлення значень у форматі таблиці, ви можете скористатися style.background_gradient()методом кадру даних панди. Цей метод розфарбовує таблицю HTML, яка відображається при перегляді кадрів даних панди, наприклад, у Блокноті JupyterLab, і результат аналогічний використанню "умовного форматування" в програмному забезпеченні електронних таблиць:

import numpy as np 
import pandas as pd


index= ['aaa', 'bbb', 'ccc', 'ddd', 'eee']
cols = ['A', 'B', 'C', 'D']
df = pd.DataFrame(abs(np.random.randn(5, 4)), index=index, columns=cols)
df.style.background_gradient(cmap='Blues')

введіть тут опис зображення

Для детального використання, будь ласка, дивіться більш детальну відповідь, яку я наводив на ту саму тему раніше, і розділ про стилістику документації на панди .


4
Чорт, ця відповідь насправді така, яку я шукав. ІМО, має бути вище (+1).
понадто

7
Ця відповідь не є правильним рішенням розміщеного питання. Забарвлення фонового градієнта панди враховує кожен рядок або кожен стовпчик окремо, тоді як забарвлення pplolor або pcolormesh matplotlib враховує всю матрицю. Візьмемо для прикладу наступний код pd.DataFrame([[1, 1], [0, 3]]).style.background_gradient(cmap='summer') результатів у таблиці з двома, кожна з яких має інший колір.
Тоні Пеня-Альба

4
@ ToniPenya-Alba Питання полягає в тому, як генерувати теплову карту з фрейму даних панди, а не як реплікувати поведінку pcolor або pcolormesh. Якщо вас цікавить остання для власних цілей, ви можете використовувати axis=None(оскільки панди 0,24,0).
joelostblom

2
@joelostblom Я не мав на увазі мого коментаря, як "відтворювати той чи інший інструмент поведінки", але, як у "зазвичай потрібно, щоб усі елементи в матриці були за тією ж шкалою, а не мали різної шкали для кожного рядка / стовпця" Як ви зазначаєте, цього axis=Noneдосягаєте, і, на мою думку, це має бути частиною вашої відповіді (тим більше, що це, мабуть, не задокументовано 0 )
Toni Penya-Alba

2
@ ToniPenya-Alba Я вже зробив axis=Noneчастину детальної відповіді, на яку я посилаюсь вище, разом із кількома іншими варіантами, тому що я згоден з вами, що деякі з цих варіантів дозволяють загально бажану поведінку. Я також вчора помітив відсутність документації та відкрив піар .
joelostblom

17

Корисні sns.heatmapapi є тут . Ознайомтеся з параметрами, їх є хороша кількість. Приклад:

import seaborn as sns
%matplotlib inline

idx= ['aaa','bbb','ccc','ddd','eee']
cols = list('ABCD')
df = DataFrame(abs(np.random.randn(5,4)), index=idx, columns=cols)

# _r reverses the normal order of the color map 'RdYlGn'
sns.heatmap(df, cmap='RdYlGn_r', linewidths=0.5, annot=True)

введіть тут опис зображення


4

Якщо ви хочете інтерактивну теплову карту від Pandas DataFrame і у вас працює ноутбук Jupyter, ви можете спробувати інтерактивний віджет Clustergrammer-Widget , дивіться інтерактивний ноутбук на NBViewer тут , документацію тут

введіть тут опис зображення

А для більших наборів даних ви можете спробувати віджет Clustergrammer2 WebGL у процесі розробки (наприклад, ноутбук тут )


1
вау, це дуже акуратно! приємно бачити кілька приємних пакетів, що надходять на python - втомився від використання
Sos

2

Будь ласка , зверніть увагу , що автори seabornтільки хочуть seaborn.heatmap працювати з категоричним dataframes. Це не взагалі.

Якщо ваш індекс і стовпці мають числові значення та / або значення часу, цей код буде служити вам добре.

Функція теплопостачання Matplotlib pcolormeshвимагає бункери замість індексів , тому існує якийсь фантазійний код для складання бункерів з ваших індексів кадру даних (навіть якщо ваш індекс не рівномірно розташований!).

Решта просто np.meshgridі plt.pcolormesh.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

def conv_index_to_bins(index):
    """Calculate bins to contain the index values.
    The start and end bin boundaries are linearly extrapolated from 
    the two first and last values. The middle bin boundaries are 
    midpoints.

    Example 1: [0, 1] -> [-0.5, 0.5, 1.5]
    Example 2: [0, 1, 4] -> [-0.5, 0.5, 2.5, 5.5]
    Example 3: [4, 1, 0] -> [5.5, 2.5, 0.5, -0.5]"""
    assert index.is_monotonic_increasing or index.is_monotonic_decreasing

    # the beginning and end values are guessed from first and last two
    start = index[0] - (index[1]-index[0])/2
    end = index[-1] + (index[-1]-index[-2])/2

    # the middle values are the midpoints
    middle = pd.DataFrame({'m1': index[:-1], 'p1': index[1:]})
    middle = middle['m1'] + (middle['p1']-middle['m1'])/2

    if isinstance(index, pd.DatetimeIndex):
        idx = pd.DatetimeIndex(middle).union([start,end])
    elif isinstance(index, (pd.Float64Index,pd.RangeIndex,pd.Int64Index)):
        idx = pd.Float64Index(middle).union([start,end])
    else:
        print('Warning: guessing what to do with index type %s' % 
              type(index))
        idx = pd.Float64Index(middle).union([start,end])

    return idx.sort_values(ascending=index.is_monotonic_increasing)

def calc_df_mesh(df):
    """Calculate the two-dimensional bins to hold the index and 
    column values."""
    return np.meshgrid(conv_index_to_bins(df.index),
                       conv_index_to_bins(df.columns))

def heatmap(df):
    """Plot a heatmap of the dataframe values using the index and 
    columns"""
    X,Y = calc_df_mesh(df)
    c = plt.pcolormesh(X, Y, df.values.T)
    plt.colorbar(c)

Телефонуйте за допомогою heatmap(df)та перегляньте, як це використовується plt.show().

введіть тут опис зображення

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.