web-dev-qa-db-fra.com

Tracer une carte thermique 2D avec Matplotlib

En utilisant Matplotlib, je veux tracer une carte thermique 2D. Mes données sont un tableau Numpy n-par-n, chacune avec une valeur comprise entre 0 et 1. Ainsi, pour l'élément (i, j) de ce tableau, je souhaite tracer un carré à la coordonnée (i, j) dans mon carte thermique, dont la couleur est proportionnelle à la valeur de l'élément dans le tableau.

Comment puis-je faire ceci?

91
Karnivaurus

La fonction imshow() avec les paramètres interpolation='nearest' et cmap='hot' devrait faire ce que vous voulez.

import matplotlib.pyplot as plt
import numpy as np

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

enter image description here

145
P. Camilleri

Seaborn s'occupe beaucoup du travail manuel et trace automatiquement une pente sur le côté du graphique, etc.

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

enter image description here

Ou, vous pouvez même tracer des triangles supérieur/inférieur gauche/droit de matrices carrées, par exemple une matrice de corrélation carrée et symétrique, de sorte que le traçage de toutes les valeurs serait de toute façon redondant.

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

enter image description here

38
PyRsquared

Voici comment le faire à partir d'un 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()

dat.xyz est sous la forme

x1 y1 z1
x2 y2 z2
...
12
kilojoules

J'utiliserais la fonction pcolor / pcolormesh de matplotlib car elle permet un espacement non uniforme des données.

Exemple tiré de 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()

pcolormesh plot output

9
Erasmus Cedernaes

Pour un tableau 2d numpy, il suffit d'utiliser imshow() pour vous aider:

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)

The heatmap of the example code

Ce code produit une carte thermique continue.

Vous pouvez choisir un autre colormap intégré de ici .

5
Huang Yuheng