Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

การเพิ่มหน่วย (Units) ใน Heatmap Annotation ด้วย Seaborn

Seaborn heatmap() มีพารามิเตอร์ annot=True และ fmt สำหรับจัดรูปแบบตัวเลข แต่ไม่มีพารามิเตอร์โดยตรงสำหรับเพิ่มหน่วย (Units) ต้องปรับ Text Objects หลังสร้าง Heatmap

วิธีการ

  1. สร้าง Heatmap ด้วย sns.heatmap(annot=True, fmt='.1f')
  2. เข้าถึง Text Objects ผ่าน ax.texts
  3. วนลูปเพิ่มหน่วย (เช่น " %", " °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 decimal25.3
'.0f'Integer (ไม่มีทศนิยม)25
'.2%'Percentage (×100 + %)25.30%
'd'Integer (สำหรับ int)25
'.2e'Scientific notation2.53e+01

คำแนะนำ

  • ใช้ ax.texts หลัง sns.heatmap() เพื่อแก้ไข Annotation ที่สร้างอัตโนมัติ
  • สำหรับหน่วยที่ซับซ้อน ใช้ annot=False แล้ววาด Text เองด้วย ax.text() ควบคุมได้เต็มที่
  • ตั้ง square=True ให้เซลล์เป็นสี่เหลี่ยมจัตุรัส สวยกว่า
  • linewidths และ linecolor ทำให้ขอบเซลล์ชัดเจน