簡體   English   中英

從 pandas DataFrame 制作熱圖

[英]Making heatmap from pandas DataFrame

我有一個 dataframe 從 Python 的 Pandas package 生成。如何使用 DataFrame 從 pandas package 生成熱圖。

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
>>> 

對於今天看這個的人,我會推薦這里記錄的 Seaborn 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 魔法函數。

如果您不需要每個人的繪圖,並且您只是對添加顏色以表示表格格式中的值感興趣,則可以使用 pandas 數據框的style.background_gradient()方法。 此方法對在 JupyterLab Notebook 等查看 Pandas 數據框時顯示的 HTML 表格進行着色,結果類似於在電子表格軟件中使用“條件格式”:

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')

在此處輸入圖片說明

有關詳細用法,請參閱我之前針對同一主題提供的更詳細的答案以及pandas 文檔樣式部分

你想要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()

這給出:

輸出樣本

有用的sns.heatmap api 在這里 查看參數,其中有很多。 例子:

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)

在此處輸入圖片說明

如果你想從一個熊貓數據幀的互動熱圖和你正在運行一個Jupyter筆記本電腦,你可以試試交互式控件Clustergrammer的小部件,見互動筆記本上NBViewer 這里,文件在這里

在此處輸入圖片說明

對於更大的數據集,您可以嘗試開發中的Clustergrammer2 WebGL 小部件(示例筆記本在這里

請注意, seaborn的作者只希望seaborn.heatmap與分類數據seaborn.heatmap一起使用。 這不是一般的。

如果您的索引和列是數字和/或日期時間值,則此代碼將很好地為您服務。

Matplotlib 熱映射函數pcolormesh需要bins而不是indices ,所以有一些花哨的代碼可以從你的數據幀索引構建 bins (即使你的索引不是均勻間隔的!)。

剩下的就是np.meshgridplt.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)

使用plt.show() heatmap(df)調用它,並使用plt.show()查看它。

在此處輸入圖片說明

驚訝地發現沒有人提到功能更強大、交互性更強且更易於使用的替代品。

A)您可以使用情節:

  1. 只需兩行,你就會得到:

  2. 互動性,

  3. 平滑的尺度,

  4. 基於整個數據框而不是單個列的顏色,

  5. 軸上的列名和行索引,

  6. 放大,

  7. 平移,

  8. 內置一鍵式將其另存為 PNG 格式的功能,

  9. 自動縮放,

  10. 懸停對比,

  11. 氣泡顯示值,因此熱圖看起來仍然不錯,您可以在任何地方看到值:

import plotly.express as px
fig = px.imshow(df.corr())
fig.show()

在此處輸入圖片說明

B) 您也可以使用散景:

所有相同的功能,但有點麻煩。 但如果你不想選擇加入情節並且仍然想要所有這些東西,那么仍然值得:

from bokeh.plotting import figure, show, output_notebook
from bokeh.models import ColumnDataSource, LinearColorMapper
from bokeh.transform import transform
output_notebook()
colors = ['#d7191c', '#fdae61', '#ffffbf', '#a6d96a', '#1a9641']
TOOLS = "hover,save,pan,box_zoom,reset,wheel_zoom"
data = df.corr().stack().rename("value").reset_index()
p = figure(x_range=list(df.columns), y_range=list(df.index), tools=TOOLS, toolbar_location='below',
           tooltips=[('Row, Column', '@level_0 x @level_1'), ('value', '@value')], height = 500, width = 500)

p.rect(x="level_1", y="level_0", width=1, height=1,
       source=data,
       fill_color={'field': 'value', 'transform': LinearColorMapper(palette=colors, low=data.value.min(), high=data.value.max())},
       line_color=None)
color_bar = ColorBar(color_mapper=LinearColorMapper(palette=colors, low=data.value.min(), high=data.value.max()), major_label_text_font_size="7px",
                     ticker=BasicTicker(desired_num_ticks=len(colors)),
                     formatter=PrintfTickFormatter(format="%f"),
                     label_standoff=6, border_line_color=None, location=(0, 0))
p.add_layout(color_bar, 'right')

show(p)

在此處輸入圖片說明

您可以使用 seaborn 和 DataFrame corr() 來查看列之間的相關性

sns.heatmap(df.corr())
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

Index= ['aaa', 'bbb', 'ccc', 'ddd', 'eee']
Cols = ['A', 'B', 'C', 'D']
plt.figure(figsize=(20,6))
df = pd.DataFrame(abs(np.random.randn(5, 4)), index=Index, columns=Cols)
sns.heatmap(df , annot=True)
plt.yticks(rotation='horizontal')
plt.show()

它會看起來像這樣單擊此處

您可以使用 python package PyComplexHeatmap 從數據框中生成 plot 非常復雜的熱圖: https://github.com/DingWB/PyComplexHeatmap https://github.com/DingWB/mainbloamp/pyComplexHeatmap

PyComplex 熱圖

在處理大量特征之間的相關性時,我發現將相關特征聚類在一起很有用。 這可以通過 seaborn clustermap plot 來完成。

import seaborn as sns
import matplotlib.pyplot as plt

g = sns.clustermap(df.corr(), 
                   method = 'complete', 
                   cmap   = 'RdBu', 
                   annot  = True, 
                   annot_kws = {'size': 8})
plt.setp(g.ax_heatmap.get_xticklabels(), rotation=60);

在此處輸入圖像描述

clustermap function 使用層次聚類將相關特征排列在一起並生成樹狀樹狀圖。

在這個 plot 中有兩個值得注意的集群:

  1. y_desdew.point_des
  2. irradiancey_seasonaldew.point_seasonal

FWIW 可以使用這個 Jupyter notebook訪問生成此圖的氣象數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM