Seaborn heatmap() มีพารามิเตอร์ annot=True และ fmt สำหรับจัดรูปแบบตัวเลข แต่ไม่มีพารามิเตอร์โดยตรงสำหรับเพิ่มหน่วย (Units) ต้องปรับ Text Objects หลังสร้าง Heatmap
วิธีการ
- สร้าง Heatmap ด้วย
sns.heatmap(annot=True, fmt='.1f') - เข้าถึง Text Objects ผ่าน
ax.texts - วนลูปเพิ่มหน่วย (เช่น " %", " °C", " kg") เข้าไปในข้อความแต่ละตัว
ตัวอย่างโค้ด
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
plt.rcParams["figure.figsize"] = [10, 8]
plt.rcParams["figure.autolayout"] = True
# สร้างข้อมูล 5x5
np.random.seed(42)
data = np.random.rand(5, 5) * 100 # 0-100
fig, ax = plt.subplots()
# สร้าง Heatmap พร้อม Annotation
hm = sns.heatmap(data,
annot=True, # แสดงตัวเลข
fmt='.1f', # Format: 1 ตำแหน่งทศนิยม
cmap='RdYlBu_r', # Colormap
square=True, # ทำให้เซลล์เป็นสี่เหลี่ยมจัตุรัส
linewidths=1.5, # ความหนาขอบเซลล์
linecolor='white', # สีขอบ
cbar_kws={'label': 'Value (%)'}, # Colorbar Label
ax=ax)
# เพิ่มหน่วย "%" ให้กับ Annotation ทุกตัว
for text in ax.texts:
current_text = text.get_text()
text.set_text(f"{current_text} %")
# ปรับ Font Size (Optional)
text.set_fontsize(11)
text.set_fontweight('bold')
ax.set_title('Heatmap with Unit Annotations (%)', fontsize=16, pad=20)
ax.set_xlabel('X Axis', fontsize=12)
ax.set_ylabel('Y Axis', fontsize=12)
plt.show()
ตัวอย่างขั้นสูง: หน่วยต่างกันต่อ Row/Column
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
plt.rcParams["figure.figsize"] = [12, 8]
plt.rcParams["figure.autolayout"] = True
# ข้อมูล: Row 0-1 = Temperature (°C), Row 2-3 = Pressure (hPa), Row 4 = Humidity (%)
data = np.array([
[25.3, 26.1, 24.8, 27.2, 25.9], # Temp
[24.5, 25.8, 23.9, 26.5, 25.1], # Temp
[1013, 1015, 1012, 1018, 1014], # Pressure
[1010, 1012, 1009, 1014, 1011], # Pressure
[65, 70, 60, 75, 68] # Humidity
])
fig, ax = plt.subplots()
# Heatmap โดยไม่ annot ก่อน
hm = sns.heatmap(data,
annot=False,
cmap='RdYlBu_r',
square=True,
linewidths=1,
linecolor='white',
ax=ax)
# เพิ่ม Annotation เองพร้อมหน่วย
row_units = ['°C', '°C', 'hPa', 'hPa', '%']
for i in range(data.shape[0]):
for j in range(data.shape[1]):
val = data[i, j]
unit = row_units[i]
# Format ตามประเภท
if unit == 'hPa':
txt = f"{val:.0f}{unit}"
else:
txt = f"{val:.1f}{unit}"
# วางข้อความตรงกลางเซลล์
ax.text(j + 0.5, i + 0.5, txt,
ha='center', va='center',
fontsize=10, fontweight='bold',
color='white' if val > data.max()*0.6 else 'black')
ax.set_yticklabels(['Temp 1', 'Temp 2', 'Press 1', 'Press 2', 'Humidity'], rotation=0)
ax.set_title('Heatmap with Row-Specific Units', fontsize=16)
plt.show()
ผลลัพธ์
Heatmap แสดงค่าในแต่ละเซลล์พร้อมหน่วย "%" (หรือ °C, hPa ตาม Row) ตรงกลางเซลล์ สีข้อความปรับตามพื้นหลังอัตโนมัติ
การปรับ fmt ใน sns.heatmap()
| fmt | คำอธิบาย | ตัวอย่าง |
|---|---|---|
'.1f' | Fixed point, 1 decimal | 25.3 |
'.0f' | Integer (ไม่มีทศนิยม) | 25 |
'.2%' | Percentage (×100 + %) | 25.30% |
'd' | Integer (สำหรับ int) | 25 |
'.2e' | Scientific notation | 2.53e+01 |
คำแนะนำ
- ใช้
ax.textsหลังsns.heatmap()เพื่อแก้ไข Annotation ที่สร้างอัตโนมัติ - สำหรับหน่วยที่ซับซ้อน ใช้
annot=Falseแล้ววาด Text เองด้วยax.text()ควบคุมได้เต็มที่ - ตั้ง
square=Trueให้เซลล์เป็นสี่เหลี่ยมจัตุรัส สวยกว่า linewidthsและlinecolorทำให้ขอบเซลล์ชัดเจน