从pandas DataFrame制作热图

Cur*_*ous 94 python heatmap dataframe pandas

我有一个从Python的Pandas包生成的数据帧.如何使用pandas包中的DataFrame生成热图.

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
>>> 
Run Code Online (Sandbox Code Playgroud)

Bri*_*eau 149

对于今天看到这个的人,我会推荐这里heatmap()记录的Seaborn .

上面的例子将按如下方式完成:

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)
Run Code Online (Sandbox Code Playgroud)

%matplotlib对于那些不熟悉的人来说,IPython魔术功能在哪里?

  • Seaborn和Pandas可以很好地协同工作,因此您仍然可以使用Pandas将数据设置为正确的形状.Seaborn虽然专注于静态图表,但却使Pandas DataFrame的热图变得简单. (8认同)
  • 使用“import matplotlib.pyplot as plt”而不是“%matplotlib inline”并使用“plt.show()”完成以便实际查看绘图。 (2认同)

cht*_*mon 70

你想要matplotlib.pcolor:

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

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

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()
Run Code Online (Sandbox Code Playgroud)

  • 关于`pcolor`与`imshow`有一些有趣的讨论[这里](http://stackoverflow.com/questions/21166679/when-to-use-imshow-over-pcolormesh). (5认同)
  • ...还有 [`pcolormesh`](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.pcolormesh.html#differences-pcolor-pcolormesh),它针对这种图形进行了优化。 (2认同)

joe*_*lom 52

如果您不需要每个说法的情节,并且您只想添加颜色来表示表格格式的值,则可以使用style.background_gradient()pandas数据框的方法.此方法着色在查看例如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')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

这个相关的答案中还有一些细节,pandas文档样式部分深入介绍了许多选项.

  • 该死的,这个答案实际上是我正在寻找的答案。IMO,应该更高(+1)。 (5认同)
  • 此答案不是已发布问题的有效解决方案。熊猫背景渐变着色分别考虑了每一行或每一列,而matplotlib的pcolor或pcolormesh着色考虑了整个矩阵。例如,以下代码`pd.DataFrame([[1,1],[0,3]])。style.background_gradient(cmap ='summer')`生成一个包含两个表的表,每个表都有一个不同的颜色。 (4认同)
  • @ ToniPenya-Alba问题是关于如何从熊猫数据帧生成热图,而不是如何复制pcolor或pcolormesh的行为。如果您出于个人目的对后者感兴趣,则可以使用“ axis = None”(因为pandas为0.24.0)。 (3认同)
  • @joelostblom我的意思不是“复制一种工具或另一种行为”中的注释,而是“通常情况下,矩阵中的所有元素都遵循相同的比例,而不是每行/列具有不同的比例”。正如您所指出的,“ axis = None”可以实现这一目标,我认为,这应该是您的答案的一部分(特别是因为似乎没有记录在案[0](https://pandas.pydata.org/pandas -docs / stable / reference / api / pandas.io.formats.style.Styler.background_gradient.html)) (2认同)
  • @ToniPenya-Alba 我已经将 `axis=None` 作为我上面链接的详细答案的一部分,以及其他一些选项,因为我同意你的看法,其中一些选项可以实现通常所需的行为。我昨天也注意到缺少文档并[打开了一个 PR](https://github.com/pandas-dev/pandas/pull/25551)。 (2认同)

Bra*_*mon 15

有用的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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Nic*_*dez 6

如果你想从一个熊猫数据帧的互动热图和你正在运行一个Jupyter笔记本电脑,你可以试试交互式控件Clustergrammer的小部件,见互动笔记本上NBViewer这里,文件在这里

在此处输入图片说明

对于更大的数据集,您可以尝试开发中的Clustergrammer2 WebGL 小部件(此处为示例笔记本)

  • 哇这很整洁!很高兴看到一些不错的包来到 python - 厌倦了不得不使用 R 魔法 (2认同)

Ora*_*bet 6

请注意,作者seaborn只想使用 seaborn.heatmap分类数据框。这不是一般的。

如果您的索引和列是数字和/或日期时间值,那么此代码将为您提供很好的帮助。

Matplotlib 热图函数pcolormesh需要bins而不是索引,因此有一些奇特的代码可以从数据帧索引构建 bin(即使您的索引不是均匀分布的!)。

剩下的就是简单的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)
Run Code Online (Sandbox Code Playgroud)

调用它 using heatmap(df),并查看它 using plt.show()

在此输入图像描述


Ham*_*mza 6

惊讶地发现没有人提到更强大、更具交互性和更易于使用的替代方案。

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()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述