Trazar un mapa de calor 2D

4 minutos de lectura

Avatar de usuario de Karnivaurus
Karnivaurus

Usando Matplotlib, quiero trazar un mapa de calor 2D. Mis datos son una matriz Numpy n por n, cada una con un valor entre 0 y 1. Entonces, para el elemento (i, j) de esta matriz, quiero trazar un cuadrado en la coordenada (i, j) en mi mapa de calor, cuyo color es proporcional al valor del elemento en la matriz.

¿Cómo puedo hacer esto?

Avatar de usuario de P. Camilleri
P.Camilleri

los imshow() funcion con parametros interpolation='nearest' y cmap='hot' deberías hacer lo que quieras.

Por favor revise el interpolation detalles del parámetro y ver Interpolaciones para imshow y Suavizado de imágenes.

import matplotlib.pyplot as plt
import numpy as np

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

Un mapa de color de muestra producido por el código de ejemplo

Avatar de usuario de PyRsquared
PyRcuadrado

nacido en el mar es una API de alto nivel para matplotlib, que se encarga de gran parte del trabajo manual.

seaborn.heatmap traza automáticamente un gradiente al lado del gráfico, 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()

ingrese la descripción de la imagen aquí

Incluso puede trazar triángulos superior/inferior izquierdo/derecho de matrices cuadradas. Por ejemplo, una matriz de correlación, que es cuadrada y simétrica, por lo que trazar todos los valores sería redundante.

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

ingrese la descripción de la imagen aquí

Yo usaría matplotlib color/pcolormesh ya que permite un espaciado no uniforme de los datos.

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

salida de gráfico pcolormesh

para un 2d numpy matriz, simplemente use imshow() puede ayudarte:

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)

El mapa de calor del código de ejemplo.

Este código produce un mapa de calor continuo.

Puede elegir otro incorporado colormap de aquí.

avatar de usuario de kilojulios
kilojulios

He aquí cómo hacerlo desde 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)

# Interpolate for plotting
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()

dónde dat.xyz está en forma

x1 y1 z1
x2 y2 z2
...

avatar de usuario de mamaj
mamaj

Usar matshow() que es un envoltorio alrededor imshow para establecer valores predeterminados útiles para mostrar una matriz.

a = np.diag(range(15))
plt.matshow(a)

ingrese la descripción de la imagen aquí

https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.matshow.html

Esta es solo una función de conveniencia que envuelve imshow para establecer valores predeterminados útiles para mostrar una matriz. En particular:

  • Establecer origin='upper'.
  • Establecer interpolation='nearest'.
  • Establecer aspect="equal".
  • Las garrapatas se colocan a la izquierda y arriba.
  • Los ticks están formateados para mostrar índices enteros.

¿Ha sido útil esta solución?