Heatmap w matplotlib z pcolor?

Chciałbym zrobić taką heatmapę (pokazaną na FlowingData ): heatmap

Dane źródłowe są tutaj , ale przypadkowe Dane i etykiety byłyby w porządku, tj.

import numpy
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = numpy.random.rand(4,4)
Tworzenie heatmapy jest dość łatwe w matplotlib:
from matplotlib import pyplot as plt
heatmap = plt.pcolor(data)

I znalazłem nawet colormap argumenty, które wyglądają dobrze: heatmap = plt.pcolor(data, cmap=matplotlib.cm.Blues)

Ale poza tym, nie mogę dowiedzieć się, jak wyświetlać etykiety dla kolumn i wierszy i wyświetlać dane w odpowiedniej orientacji (pochodzenie w lewym górnym rogu zamiast w lewym dolnym rogu).

Próby manipulacji heatmap.axes (np. heatmap.axes.set_xticklabels = column_labels) zakończyły się niepowodzeniem. Co mi umyka?

Author: MERose, 2013-01-18

4 answers

Jest późno, ale oto moja implementacja Pythona flowingdata NBA heatmap.

Zaktualizowano: 1/4/2014: dzięki wszystkim

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

Wyjście wygląda tak: flowingdata-jak nba heatmap

Jest notatnik ipython z całym tym kodem tutaj . Wiele się nauczyłem od ' overflow, więc mam nadzieję, że ktoś uzna to za przydatne.

 119
Author: joelotz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-05 02:15:33

Główny problem polega na tym, że najpierw musisz ustawić lokalizację Twoich kleszczy x i Y. Ponadto, pomaga używać bardziej obiektowego interfejsu do matplotlib. Mianowicie, interakcja z obiektem axes bezpośrednio.

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()
Mam nadzieję, że to pomoże.
 11
Author: Paul H,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-02 20:48:00

Moduł python seaborn jest oparty na matplotlib i tworzy bardzo ładną heatmapę.

Poniżej znajduje się implementacja z seaborn, przeznaczona dla notebooka ipython / jupyter.

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

Wyjście wygląda tak: seaborn nba heatmap Użyłem mapy kolorów matplotlib Blues, ale osobiście uważam, że domyślne kolory są dość piękne. Używałem matplotlib do obracania etykiet osi x, ponieważ nie mogłem znaleźć składni seaborn. Jak zauważył grexor, konieczne było określenie wymiarów (rys.set_size_inches) metodą prób i błędów, które uznałem za nieco frustrujące.

Jak zauważył Paul H, można łatwo dodać wartości do map ciepła (annot = True), ale w tym przypadku nie myślałem, że poprawiło to figurę. Kilka fragmentów kodu zostało zaczerpniętych z doskonałej odpowiedzi joelotza.

 10
Author: Mark Teese,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-09 00:31:03

Ktoś edytował to pytanie, aby usunąć kod, którego użyłem, więc byłem zmuszony dodać go jako odpowiedź. Dziękujemy wszystkim, którzy wzięli udział w odpowiedzi na to pytanie! Myślę, że większość innych odpowiedzi jest lepsza niż ten kod, po prostu zostawiam to tutaj w celach informacyjnych.

Dzięki Paulowi H i unutbu (który odpowiedział na to pytanie ), mam całkiem ładne wyjście:

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

A oto wyjście:

Matplotlib HeatMap

 3
Author: Jason Sundram,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:14