Merencanakan peta panas 2D dengan Matplotlib

139

Menggunakan Matplotlib, saya ingin memetakan peta panas 2D. Data saya adalah array N-by-n Numpy, masing-masing dengan nilai antara 0 dan 1. Jadi untuk elemen (i, j) dari array ini, saya ingin memplot persegi di koordinat (i, j) di peta panas, yang warnanya sebanding dengan nilai elemen dalam array.

Bagaimana saya bisa melakukan ini?

Karnivaurus
sumber
2
apakah Anda melihat matplotlibgaleri sama sekali sebelum memposting? Ada beberapa contoh bagus yang digunakan imshow, pcolordan pcolormeshlakukan apa yang Anda inginkan
tmdavison
Kemungkinan duplikat dari multi-peta Panas berwarna kesalahan Python
jkalden

Jawaban:

187

The imshow()fungsi dengan parameter interpolation='nearest'dan cmap='hot'harus melakukan apa yang Anda inginkan.

import matplotlib.pyplot as plt
import numpy as np

a = np.random.random((16, 16))
plt.imshow(a, cmap='hot', interpolation='nearest')
plt.show()

masukkan deskripsi gambar di sini

P. Camilleri
sumber
1
Saya tidak berpikir menentukan interpolasi diperlukan.
miguel.martin
2
@ miguel.martin sesuai dokumen pyplot: "Jika interpolasi adalah None (nilai default-nya), default ke rc image.interpolation". Jadi saya pikir perlu untuk memasukkannya.
P. Camilleri
@ P.Camilleri Bagaimana skala sumbu X dan Y? (Ubah hanya angka, tidak ada zoom).
Sedekah
64

Seaborn menangani banyak pekerjaan manual dan secara otomatis memplot gradien di sisi bagan dll.

import numpy as np
import seaborn as sns
import matplotlib.pylab as plt

uniform_data = np.random.rand(10, 12)
ax = sns.heatmap(uniform_data, linewidth=0.5)
plt.show()

masukkan deskripsi gambar di sini

Atau, Anda bahkan dapat memetakan segitiga atas / bawah kiri / kanan matriks kuadrat, misalnya matriks korelasi yang berbentuk persegi dan simetris, sehingga memplot semua nilai akan menjadi mubazir.

corr = np.corrcoef(np.random.randn(10, 200))
mask = np.zeros_like(corr)
mask[np.triu_indices_from(mask)] = True
with sns.axes_style("white"):
    ax = sns.heatmap(corr, mask=mask, vmax=.3, square=True,  cmap="YlGnBu")
    plt.show()

masukkan deskripsi gambar di sini

PyRsquared
sumber
1
Saya sangat menyukai tipe plot, dan setengah matriks berguna. Dua pertanyaan: 1) dalam plot pertama kotak kecil dipisahkan oleh garis putih, mungkinkah mereka bergabung? 2) lebar garis putih tampaknya bervariasi, apakah ini artefak?
P. Camilleri
1
Anda dapat menggunakan argumen 'linewidth' yang saya gunakan di plot pertama untuk plot lainnya (dalam plot kedua misalnya), untuk mendapatkan spasi kotak. Lebar garis hanya tampak bervariasi di plot pertama karena masalah tangkapan layar, sebenarnya tidak bervariasi, mereka harus tetap pada konstanta yang Anda tetapkan.
PyRsquared
sementara ini benar - saya tidak berpikir bahwa respons menggunakan seaborn harus dianggap penuh untuk pertanyaan yang secara khusus menyatakan matplotlib.
baxx
28

Untuk numpyarray 2d , cukup gunakan imshow()dapat membantu Anda:

import matplotlib.pyplot as plt
import numpy as np


def heatmap2d(arr: np.ndarray):
    plt.imshow(arr, cmap='viridis')
    plt.colorbar()
    plt.show()


test_array = np.arange(100 * 100).reshape(100, 100)
heatmap2d(test_array)

Heat map dari kode contoh

Kode ini menghasilkan peta panas berkelanjutan.

Anda dapat memilih built-in lain colormapdari sini .

huangbiubiu
sumber
18

Saya akan menggunakan matplotlib ini pcolor / pcolormesh fungsi karena memungkinkan jarak seragam dari data.

Contoh diambil dari matplotlib :

import matplotlib.pyplot as plt
import numpy as np

# generate 2 2d grids for the x & y bounds
y, x = np.meshgrid(np.linspace(-3, 3, 100), np.linspace(-3, 3, 100))

z = (1 - x / 2. + x ** 5 + y ** 3) * np.exp(-x ** 2 - y ** 2)
# x and y are bounds, so z should be the value *inside* those bounds.
# Therefore, remove the last value from the z array.
z = z[:-1, :-1]
z_min, z_max = -np.abs(z).max(), np.abs(z).max()

fig, ax = plt.subplots()

c = ax.pcolormesh(x, y, z, cmap='RdBu', vmin=z_min, vmax=z_max)
ax.set_title('pcolormesh')
# set the limits of the plot to the limits of the data
ax.axis([x.min(), x.max(), y.min(), y.max()])
fig.colorbar(c, ax=ax)

plt.show()

output plot pcolormesh

Erasmus Cedernaes
sumber
12

Berikut cara melakukannya dari csv:

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata

# Load data from CSV
dat = np.genfromtxt('dat.xyz', delimiter=' ',skip_header=0)
X_dat = dat[:,0]
Y_dat = dat[:,1]
Z_dat = dat[:,2]

# Convert from pandas dataframes to numpy arrays
X, Y, Z, = np.array([]), np.array([]), np.array([])
for i in range(len(X_dat)):
        X = np.append(X, X_dat[i])
        Y = np.append(Y, Y_dat[i])
        Z = np.append(Z, Z_dat[i])

# create x-y points to be used in heatmap
xi = np.linspace(X.min(), X.max(), 1000)
yi = np.linspace(Y.min(), Y.max(), 1000)

# Z is a matrix of x-y values
zi = griddata((X, Y), Z, (xi[None,:], yi[:,None]), method='cubic')

# I control the range of my colorbar by removing data 
# outside of my range of interest
zmin = 3
zmax = 12
zi[(zi<zmin) | (zi>zmax)] = None

# Create the contour plot
CS = plt.contourf(xi, yi, zi, 15, cmap=plt.cm.rainbow,
                  vmax=zmax, vmin=zmin)
plt.colorbar()  
plt.show()

dimana dat.xyzada dalam bentuk

x1 y1 z1
x2 y2 z2
...
kilojoule
sumber
1
Hanya kepala pendek ke atas: Saya harus mengubah metode dari kubik ke terdekat atau linier karena kubik menghasilkan banyak NaNs karena saya bekerja dengan nilai yang agak kecil antara
0,1