使用Matplotlib绘制2D热图


139

我想使用Matplotlib绘制2D热图。我的数据是一个n×n的Numpy数组,每个数组的值都在0到1之间。因此,对于该数组的(i,j)元素,我想在我的(i,j)坐标上绘制一个正方形热图,其颜色与数组中元素的值成比例。

我怎样才能做到这一点?


2
在发布之前,您是否完全看过matplotlib画廊?有使用一些很好的例子imshowpcolor并且pcolormesh是你想要做什么
tmdavison

Answers:


187

imshow()函数带有参数interpolation='nearest'cmap='hot'应该执行您想要的操作。

import matplotlib.pyplot as plt
import numpy as np

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

在此处输入图片说明


1
我认为没有必要指定插值。
miguel.martin

2
根据pyplot的文档@ miguel.martin:“如果插值为None(其默认值),则默认为rc image.interpolation”。因此,我认为有必要将其包括在内。
P. Camilleri

@ P.Camilleri如何缩放X和Y轴?(仅更改数字,不缩放)。
多尔

64

Seaborn负责许多手动工作,并自动在图表的侧面绘制渐变等。

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

在此处输入图片说明

或者,您甚至可以绘制正方形矩阵的上/下左/右三角形,例如,一个正方形且对称的相关矩阵,因此绘制所有值无论如何都是多余的。

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

在此处输入图片说明


1
我非常喜欢绘图类型,半矩阵很有用。两个问题:1)在第一个情节中,小方块之间用白线隔开,可以合并吗?2)白线宽度似乎有所不同,这是人工制品吗?
P. Camilleri '18

1
您可以将我在第一个绘图中使用的“ linewidth”参数用于其他任何绘图(例如在第二个绘图中),以得到间隔开的正方形。由于屏幕截图问题,线宽仅在第一幅图中看起来有所变化,实际上它们实际上并没有变化,它们应保持您设置的常数。
PyRsquared

虽然这是真的-我认为对于具体说明matplotlib的问题,我不认为使用seaborn的回答会被认为是充分的。
baxx

28

对于二维numpy数组,简单地使用imshow()可能会帮助您:

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)

示例代码的热图

此代码产生连续的热图。

您可以colormap这里选择另一个内置的。


18

我会使用matplotlib的pcolor / pcolormesh函数,因为它允许数据间距不均匀。

取自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图输出


12

这是从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形式在哪里

x1 y1 z1
x2 y2 z2
...

1
提醒一下:我必须将方法从三次更改为最接近或线性,因为三次导致大量的NaN,因为我使用的值介于0..1
Maikefer '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.