Python 带 pcolor 的 matplotlib 中的热图?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14391959/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 11:17:06  来源:igfitidea点击:

Heatmap in matplotlib with pcolor?

pythonmatplotlibdata-visualizationheatmap

提问by Jason Sundram

I'd like to make a heatmap like this (shown on FlowingData): heatmap

我想制作这样的热图(显示在FlowingData 上): 热图

The source data is here, but random data and labels would be fine to use, i.e.

源数据在这里,但随机数据和标签可以使用,即

import numpy
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = numpy.random.rand(4,4)

Making the heatmap is easy enough in matplotlib:

在 matplotlib 中制作热图很容易:

from matplotlib import pyplot as plt
heatmap = plt.pcolor(data)

And I even found a colormaparguments that look about right: heatmap = plt.pcolor(data, cmap=matplotlib.cm.Blues)

我什至发现了一个看起来正确的颜色图参数:heatmap = plt.pcolor(data, cmap=matplotlib.cm.Blues)

But beyond that, I can't figure out how to display labels for the columns and rows and display the data in the proper orientation (origin at the top left instead of bottom left).

但除此之外,我无法弄清楚如何显示列和行的标签并以正确的方向显示数据(原点在左上角而不是左下角)。

Attempts to manipulate heatmap.axes(e.g. heatmap.axes.set_xticklabels = column_labels) have all failed. What am I missing here?

试图操纵heatmap.axes(例如heatmap.axes.set_xticklabels = column_labels)都失败了。我在这里缺少什么?

采纳答案by BubbleGuppies

This is late, but here is my python implementation of the flowingdata NBA heatmap.

这已经很晚了,但这是我对 flowdata NBA 热图的 Python 实现。

updated:1/4/2014: thanks everyone

更新:1/4/2014:谢谢大家

# -*- coding: utf-8 -*-
# <nbformat>3.0</nbformat>

# ------------------------------------------------------------------------
# Filename   : heatmap.py
# Date       : 2013-04-19
# Updated    : 2014-01-04
# Author     : @LotzJoe >> Joe Lotz
# Description: My attempt at reproducing the FlowingData graphic in Python
# Source     : http://flowingdata.com/2010/01/21/how-to-make-a-heatmap-a-quick-and-easy-solution/
#
# Other Links:
#     http://stackoverflow.com/questions/14391959/heatmap-in-matplotlib-with-pcolor
#
# ------------------------------------------------------------------------

import matplotlib.pyplot as plt
import pandas as pd
from urllib2 import urlopen
import numpy as np
%pylab inline

page = urlopen("http://datasets.flowingdata.com/ppg2008.csv")
nba = pd.read_csv(page, index_col=0)

# Normalize data columns
nba_norm = (nba - nba.mean()) / (nba.max() - nba.min())

# Sort data according to Points, lowest to highest
# This was just a design choice made by Yau
# inplace=False (default) ->thanks SO user d1337
nba_sort = nba_norm.sort('PTS', ascending=True)

nba_sort['PTS'].head(10)

# Plot it out
fig, ax = plt.subplots()
heatmap = ax.pcolor(nba_sort, cmap=plt.cm.Blues, alpha=0.8)

# Format
fig = plt.gcf()
fig.set_size_inches(8, 11)

# turn off the frame
ax.set_frame_on(False)

# put the major ticks at the middle of each cell
ax.set_yticks(np.arange(nba_sort.shape[0]) + 0.5, minor=False)
ax.set_xticks(np.arange(nba_sort.shape[1]) + 0.5, minor=False)

# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.tick_top()

# Set the labels

# label source:https://en.wikipedia.org/wiki/Basketball_statistics
labels = [
    'Games', 'Minutes', 'Points', 'Field goals made', 'Field goal attempts', 'Field goal percentage', 'Free throws made', 'Free throws attempts', 'Free throws percentage',
    'Three-pointers made', 'Three-point attempt', 'Three-point percentage', 'Offensive rebounds', 'Defensive rebounds', 'Total rebounds', 'Assists', 'Steals', 'Blocks', 'Turnover', 'Personal foul']

# note I could have used nba_sort.columns but made "labels" instead
ax.set_xticklabels(labels, minor=False)
ax.set_yticklabels(nba_sort.index, minor=False)

# rotate the
plt.xticks(rotation=90)

ax.grid(False)

# Turn off all the ticks
ax = plt.gca()

for t in ax.xaxis.get_major_ticks():
    t.tick1On = False
    t.tick2On = False
for t in ax.yaxis.get_major_ticks():
    t.tick1On = False
    t.tick2On = False

The output looks like this: flowingdata-like nba heatmap

输出如下所示: 类似流动数据的 nba 热图

There's an ipython notebook with all this code here. I've learned a lot from 'overflow so hopefully someone will find this useful.

有一个带有所有这些代码的 ipython 笔记本here。我从“溢出”中学到了很多东西,所以希望有人会发现这很有用。

回答by Paul H

Main issue is that you first need to set the location of your x and y ticks. Also, it helps to use the more object-oriented interface to matplotlib. Namely, interact with the axesobject directly.

主要问题是您首先需要设置 x 和 y 刻度的位置。此外,它有助于使用更面向对象的接口到 matplotlib。即,axes直接与对象交互。

import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = np.random.rand(4,4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data)

# put the major ticks at the middle of each cell, notice "reverse" use of dimension
ax.set_yticks(np.arange(data.shape[0])+0.5, minor=False)
ax.set_xticks(np.arange(data.shape[1])+0.5, minor=False)


ax.set_xticklabels(row_labels, minor=False)
ax.set_yticklabels(column_labels, minor=False)
plt.show()

Hope that helps.

希望有帮助。

回答by Mark Teese

The python seaborn module is based on matplotlib, and produces a very nice heatmap.

python seaborn 模块基于 matplotlib,并生成一个非常好的热图。

Below is an implementation with seaborn, designed for the ipython/jupyter notebook.

以下是 seaborn 的实现,专为 ipython/jupyter notebook 设计。

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
# import the data directly into a pandas dataframe
nba = pd.read_csv("http://datasets.flowingdata.com/ppg2008.csv", index_col='Name  ')
# remove index title
nba.index.name = ""
# normalize data columns
nba_norm = (nba - nba.mean()) / (nba.max() - nba.min())
# relabel columns
labels = ['Games', 'Minutes', 'Points', 'Field goals made', 'Field goal attempts', 'Field goal percentage', 'Free throws made', 
          'Free throws attempts', 'Free throws percentage','Three-pointers made', 'Three-point attempt', 'Three-point percentage', 
          'Offensive rebounds', 'Defensive rebounds', 'Total rebounds', 'Assists', 'Steals', 'Blocks', 'Turnover', 'Personal foul']
nba_norm.columns = labels
# set appropriate font and dpi
sns.set(font_scale=1.2)
sns.set_style({"savefig.dpi": 100})
# plot it out
ax = sns.heatmap(nba_norm, cmap=plt.cm.Blues, linewidths=.1)
# set the x-axis labels on the top
ax.xaxis.tick_top()
# rotate the x-axis labels
plt.xticks(rotation=90)
# get figure (usually obtained via "fig,ax=plt.subplots()" with matplotlib)
fig = ax.get_figure()
# specify dimensions and save
fig.set_size_inches(15, 20)
fig.savefig("nba.png")

The output looks like this: seaborn nba heatmapI used the matplotlib Blues color map, but personally find the default colors quite beautiful. I used matplotlib to rotate the x-axis labels, as I couldn't find the seaborn syntax. As noted by grexor, it was necessary to specify the dimensions (fig.set_size_inches) by trial and error, which I found a bit frustrating.

输出看起来像这样: seaborn nba 热图我使用了 matplotlib Blues 颜色图,但个人觉得默认颜色非常漂亮。我使用 matplotlib 旋转 x 轴标签,因为我找不到 seaborn 语法。正如 grexor 所指出的,有必要通过反复试验来指定尺寸 (fig.set_size_inches),我发现这有点令人沮丧。

As noted by Paul H, you can easily add the values to heat maps (annot=True), but in this case I didn't think it improved the figure. Several code snippets were taken from the excellent answer by joelotz.

正如 Paul H 所指出的,您可以轻松地将这些值添加到热图 (annot=True),但在这种情况下,我认为它没有改进数字。几个代码片段取自 joelotz 的优秀答案。

回答by Jason Sundram

Someone edited this question to remove the code I used, so I was forced to add it as an answer. Thanks to all who participated in answering this question! I think most of the other answers are better than this code, I'm just leaving this here for reference purposes.

有人编辑了这个问题以删除我使用的代码,因此我被迫将其添加为答案。感谢所有参与回答这个问题的人!我认为大多数其他答案都比此代码更好,我只是将其留在这里以供参考。

With thanks to Paul H, and unutbu(who answered this question), I have some pretty nice-looking output:

感谢Paul Hunutbu(他回答了这个问题),我有一些非常漂亮的输出:

import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = np.random.rand(4,4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)

# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[0])+0.5, minor=False)
ax.set_yticks(np.arange(data.shape[1])+0.5, minor=False)

# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.tick_top()

ax.set_xticklabels(row_labels, minor=False)
ax.set_yticklabels(column_labels, minor=False)
plt.show()

And here's the output:

这是输出:

Matplotlib HeatMap

Matplotlib 热图