Pcolor ile matplotlib'de ısı haritası?


100

Bunun gibi bir ısı haritası yapmak istiyorum ( FlowingData'da gösterilir ): sıcaklık haritası

Kaynak veriler buradadır , ancak rastgele veriler ve etiketlerin kullanılması uygundur, yani

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

Isı haritasını yapmak matplotlib'de yeterince kolaydır:

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

Ve hatta doğru görünen bir renk haritası argümanı buldum :heatmap = plt.pcolor(data, cmap=matplotlib.cm.Blues)

Ancak bunun ötesinde, sütunlar ve satırlar için etiketleri nasıl görüntüleyeceğimi ve verileri doğru yönde nasıl görüntüleyeceğimi bulamıyorum (başlangıç ​​sol alt yerine sol üstte).

Manipüle etme girişimleri heatmap.axes(örneğin heatmap.axes.set_xticklabels = column_labels) başarısız oldu. Burada neyi özlüyorum?


Bu ısı haritası sorusuyla pek çok örtüşme var - orada sizin için bazı iyi bilgiler olabilir.
John Lyon

Yanıtlar:


123

Bu çok geç, ama işte flowingdata NBA ısı haritasının python uygulamam.

güncelleme: 1/4/2014 : herkese teşekkürler

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

Çıktı şuna benzer: flowingdata benzeri nba ısı haritası

Burada tüm bu kodun bulunduğu bir ipython not defteri var . 'Overflow'dan çok şey öğrendim, bu yüzden umarım birisi bunu faydalı bulacaktır.


1
Yukarıdaki kod iPythnon dizüstü bilgisayarda çalışmadı. Nba_sort = nba_norm.sort ('PTS', artan = True, inplace = True) 'yi nba_sort = nba_norm.copy () nba_sort.sort (' PTS ', artan = True, inplace = True) olarak değiştirerek küçük bir değişiklik yaptım sıralama yan etkiye göre çalıştığı için dönüş işlevine göre değil! Harika konser örneği için teşekkürler!
Yu Shen

1
Hmmm ... haklı görünüyorsun. Bunun ne hakkında olduğundan emin değilim. Kodu düzelteceğim. Teşekkürler!
BubbleGuppies

Tabloda istatistiğin değerini göstererek böyle bir grafik oluşturmanın en kolay yolu ne olabilir? Yani bunun pcolorgibi bir şey yapmak istiyorum ama bunun da gösterilen sayısal değerleri var. VEYA: tableHücrelerini renklendiren bir matplotlib yapmak istiyorum . Diğer problemin çözümlerini gördüm ve estetik açıdan çirkinler. Bu harika görünüyor, keşke sayıları nasıl üst üste koyacağımı bilseydim.
8one6

Evet. Başka birinin sorusunu yanıtlarken tökezledim: stackoverflow.com/a/21167108/2501018
8one6

@joelotz Bunun (değiştirilmiş) bir versiyonunu matplotlib dokümanlarına eklemeye istekli misiniz? Öyleyse, bir PR açın veya bana e-posta yoluyla ping atın (profilime bakın).
tacaswell

12

Python seaborn modülü matplotlib'e dayalıdır ve çok güzel bir ısı haritası oluşturur.

Aşağıda, ipython / jupyter not defteri için tasarlanmış seaborn ile bir uygulama bulunmaktadır.

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

Çıktı şuna benzer: seaborn nba ısı haritası Matplotlib Blues renk haritasını kullandım, ancak kişisel olarak varsayılan renkleri oldukça güzel buldum. Seaborn sözdizimini bulamadığım için x ekseni etiketlerini döndürmek için matplotlib kullandım. Grexor'un belirttiği gibi, biraz sinir bozucu bulduğum boyutları (fig.set_size_inches) deneme yanılma yoluyla belirtmek gerekiyordu.

Paul H'nin belirttiği gibi, değerleri ısı haritalarına kolayca ekleyebilirsiniz (annot = True), ancak bu durumda rakamı iyileştirdiğini düşünmemiştim. Joelotz'un mükemmel cevabından birkaç kod parçacığı alındı.


11

Temel sorun, önce x ve y işaretlerinizin konumunu ayarlamanız gerektiğidir. Ayrıca, matplotlib için daha nesneye yönelik arayüzün kullanılmasına yardımcı olur. Yani axesdoğrudan nesne ile etkileşime geçin .

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

Umarım yardımcı olur.


Teşekkürler @ Paul H, çok güzel çalışıyor. Bir heatmap.axesnedenden dolayı hiçbir şey yapmayan mülkü kullanıyordum .
Jason Sundram

X ekseni etiketlerini en üstte olacak şekilde nasıl taşıyacağınızı biliyor musunuz? Açık ax.xaxis.set_label_position('top')olanı boşuna denedim .
Jason Sundram

@JasonSundram Etiket konumlandırmasını hareket ettirmek için yeni bir soru açmalısınız, çünkü bu işe yaramalı ve tuhaf değil.
tacaswell

1
@tcaswell, iyi nokta. Yeni Soru burada: stackoverflow.com/questions/14406214/…
Jason Sundram

1
@ Tgsmith61591 Seaborn'un ısı haritası işlevini kullanacağım, annot=Trueçağrıldığında ayarlayacağım ( stanford.edu/~mwaskom/software/seaborn/generated/… )
Paul H

3

Birisi bu soruyu kullandığım kodu kaldırmak için düzenledi, bu yüzden onu yanıt olarak eklemek zorunda kaldım. Bu soruyu yanıtlayan herkese teşekkürler! Diğer cevapların çoğunun bu koddan daha iyi olduğunu düşünüyorum, bunu sadece referans amacıyla burada bırakıyorum.

İçin teşekkür grubu Paul H ve unutbu cevap ( bu soruyu ), bazı çok güzel görünümlü çıkışı vardır:

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

Ve işte çıktı:

Matplotlib Isı Haritası

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.