การพล็อตแผนที่ความร้อน 2D ด้วย Matplotlib


148

ใช้ Matplotlib ฉันต้องการพล็อตแผนที่ความร้อน 2D ข้อมูลของฉันคืออาร์เรย์ N-by-n Numpy แต่ละรายการมีค่าระหว่าง 0 ถึง 1 ดังนั้นสำหรับองค์ประกอบ (i, j) ของอาร์เรย์นี้ฉันต้องการลงจุดสี่เหลี่ยมที่พิกัด (i, j) ในพิกัดของฉัน แผนที่ความร้อนซึ่งมีสีเป็นสัดส่วนกับค่าขององค์ประกอบในอาร์เรย์

ฉันจะทำเช่นนี้ได้อย่างไร?


2
คุณได้ดูmatplotlibแกลเลอรีก่อนโพสต์หรือไม่? มีบางตัวอย่างที่ดีโดยใช้มีimshow, pcolorและpcolormeshที่ทำในสิ่งที่คุณต้องการ
tmdavison

คำตอบ:


197

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
@ miguel.martin ตามเอกสารของ pyplot: "If interpolation is None (its default value), default to rc image.interpolation". ดังนั้นฉันคิดว่าจำเป็นต้องรวมไว้ด้วย
P. Camilleri

@ P.Camilleri จะปรับขนาดแกน X และ Y อย่างไร? (เปลี่ยนเฉพาะตัวเลขไม่มีการซูม)
โดล

70

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
ฉันชอบพล็อตประเภทมากและ half matrix ก็มีประโยชน์ คำถามสองข้อ: 1) ในพล็อตแรกสี่เหลี่ยมเล็ก ๆ จะถูกคั่นด้วยเส้นสีขาวมันอาจเป็นรอยต่อ 2) ความกว้างของเส้นสีขาวดูเหมือนจะแตกต่างกันไปนี่เป็นสิ่งประดิษฐ์หรือไม่?
P. Camilleri

1
คุณสามารถใช้อาร์กิวเมนต์ 'linewidth' ที่ฉันใช้ในพล็อตแรกสำหรับพล็อตอื่น ๆ (ในพล็อตที่สองเป็นต้น) เพื่อเว้นระยะห่างกำลังสอง ความกว้างของเส้นดูเหมือนจะแตกต่างกันไปในพล็อตแรกเท่านั้นเนื่องจากปัญหาของภาพหน้าจอซึ่งไม่ได้แตกต่างกันในความเป็นจริง แต่ควรอยู่ที่ค่าคงที่ที่คุณตั้งไว้
PyRsquared

แม้ว่านี่จะเป็นความจริง - ฉันไม่คิดว่าการตอบสนองโดยใช้ซีบอร์นควรได้รับการพิจารณาว่าครบถ้วนสำหรับคำถามที่ระบุเฉพาะ matplotlib
baxx

28

สำหรับnumpyอาร์เรย์2d เพียงแค่ใช้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จากที่นี่


23

ฉันจะใช้ฟังก์ชันpcolor / pcolormeshของ matplotlib เนื่องจากอนุญาตให้มีการเว้นระยะห่างของข้อมูลที่ไม่สม่ำเสมอ

ตัวอย่างจาก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


13

นี่คือวิธีการทำจาก 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.