Vẽ sơ đồ nhiệt 2D với Matplotlib


139

Sử dụng Matplotlib, tôi muốn vẽ sơ đồ nhiệt 2D. Dữ liệu của tôi là một mảng Numpy n-by-n, mỗi mảng có giá trị từ 0 đến 1. Vì vậy, đối với phần tử (i, j) của mảng này, tôi muốn vẽ một hình vuông tại tọa độ (i, j) trong bản đồ nhiệt, có màu tỷ lệ với giá trị của phần tử trong mảng.

Tôi có thể làm cái này như thế nào?


2
bạn đã nhìn vào matplotlibbộ sưu tập trước khi đăng? Có một số ví dụ điển hình sử dụng imshow, pcolorpcolormeshrằng làm những gì bạn muốn
tmdavison

Câu trả lời:


187

Các imshow()chức năng với các tham số interpolation='nearest'cmap='hot'nên làm những gì bạn muốn.

import matplotlib.pyplot as plt
import numpy as np

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

nhập mô tả hình ảnh ở đây


1
Tôi không nghĩ việc chỉ định nội suy là cần thiết.
Miguel.martin

2
@ Miguel.martin theo tài liệu của pyplot: "Nếu phép nội suy là Không có (giá trị mặc định của nó), mặc định là RC image.interpolation". Vì vậy, tôi nghĩ rằng nó là cần thiết để bao gồm nó.
P. Camilleri

@ P.Camilleri Làm thế nào để chia tỷ lệ trục X và Y? (Chỉ thay đổi số, không phóng to).
Dole

63

Seaborn chăm sóc rất nhiều công việc thủ công và tự động vẽ một gradient ở bên cạnh biểu đồ, v.v.

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

nhập mô tả hình ảnh ở đây

Hoặc, bạn thậm chí có thể vẽ các tam giác vuông trên / dưới trái / phải của ma trận vuông, ví dụ ma trận tương quan là hình vuông và đối xứng, do đó, vẽ đồ thị tất cả các giá trị sẽ là dự phòng.

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

nhập mô tả hình ảnh ở đây


1
Tôi rất thích kiểu cốt truyện, và nửa ma trận rất hữu ích. Hai câu hỏi: 1) trong ô đầu tiên, các ô vuông nhỏ được phân cách bằng các vạch trắng, chúng có thể được nối không? 2) chiều rộng đường trắng dường như thay đổi, đây có phải là vật phẩm không?
P. Camilleri

1
Bạn có thể sử dụng đối số 'đường truyền' mà tôi đã sử dụng trong âm mưu đầu tiên cho bất kỳ âm mưu nào khác (ví dụ trong âm mưu thứ hai), để có được các ô vuông cách nhau. Độ rộng đường chỉ xuất hiện thay đổi trong âm mưu đầu tiên do các vấn đề về chụp màn hình, chúng không thực sự khác nhau trong thực tế, chúng nên giữ nguyên ở mức bạn đặt chúng.
PyRsquared

trong khi điều này là đúng - tôi không nghĩ rằng một câu trả lời sử dụng seaborn nên được xem là đầy đủ cho một câu hỏi có nội dung cụ thể là matplotlib.
baxx

28

Đối với numpymảng 2d , chỉ cần sử dụng imshow()có thể giúp bạn:

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)

Sơ đồ nhiệt của mã ví dụ

Mã này tạo ra một bản đồ nhiệt liên tục.

Bạn có thể chọn một tích hợp khác colormaptừ đây .


18

Tôi sẽ sử dụng matplotlib của pcolor / pcolormesh chức năng vì nó cho phép khoảng cách không đồng dạng của dữ liệu.

Ví dụ lấy từ 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()

đầu ra cốt truyện pcolormesh


12

Đây là cách để làm điều đó từ một 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()

ở đâu dat.xyztrong mẫu

x1 y1 z1
x2 y2 z2
...

1
Chỉ cần một cái đầu ngắn lên: Tôi đã phải thay đổi phương pháp từ khối sang gần nhất hoặc tuyến tính vì khối này tạo ra rất nhiều NaN vì tôi đang làm việc với các giá trị khá nhỏ trong khoảng từ 0..1
Maikefer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.