HOWTO · Matplotlib

如何在 Matplotlib 中旋轉 X 軸刻度標籤文字

學習旋轉 Matplotlib x 軸刻度標籤的五種方法,以及在長標籤重疊時如何對齊標籤。

本頁內容

在 Matplotlib 中旋轉 x 軸刻度標籤時,可將 rotation=45 這類角度傳給 plt.xticks、fig.autofmt_xdate、ax.set_xticklabels、plt.setp 或 ax.tick_params。當較長的水平標籤彼此重疊時,45 度是個實用的起點;搭配 ha="right" 對齊旋轉後的標籤,能讓標籤末端靠近對應刻度。以下範例會說明各 API 適合的情境。

不旋轉時,月份名稱等類別名稱會水平排列並佔滿整個軸寬,因此名稱較長或圖形較窄時,相鄰標籤就會擠在一起:

月度數值折線圖,水平刻度標籤 January、February、March、April 佔滿整個軸寬。

使用 plt.xticks 旋轉 x 軸刻度標籤

使用 pyplot 時,plt.xticks 是簡潔的選項。它的 rotation 關鍵字可設定角度,單位為度;預設方向為水平。這個範例會繪製分類資料,並將標籤旋轉 45 度。

import matplotlib.pyplot as plt

months = ["January", "February", "March", "April"]
values = [12, 18, 15, 22]

fig, ax = plt.subplots()
ax.plot(months, values, marker="o")
plt.xticks(rotation=45, ha="right")
ax.grid(True)
fig.tight_layout()

相同的月度折線圖,刻度標籤旋轉 45 度並右對齊,使每個標籤都在其刻度處結束。

若要快速變更目前的座標軸,可使用 plt.xticks。如果程式已使用 Axes 物件,以下對應的方法則能明確指定要操作的座標軸。

使用 fig.autofmt_xdate 旋轉日期軸標籤

對於日期圖表,fig.autofmt_xdate 會格式化圖表中的日期標籤並旋轉標籤,以提升可讀性。它的預設設定也會調整對齊方式與底部邊界;若需要特定角度,可以明確設定 rotation。實際效果取決於圖表的座標軸與日期格式,因此應用於日期軸,不宜將它視為所有刻度標籤設定的一般替代方法。

import matplotlib.pyplot as plt
from datetime import date, timedelta

start = date(2024, 1, 1)
dates = [start + timedelta(days=7 * i) for i in range(6)]
values = [3, 5, 4, 7, 6, 9]

fig, ax = plt.subplots()
ax.plot(dates, values, marker="o")
fig.autofmt_xdate(rotation=45)
ax.grid(True)

2024 年 1 月與 2 月六個每週日期的折線圖,日期標籤經 autofmt_xdate 旋轉 45 度。

當 x 軸使用日期,且格式化後的標籤需要旋轉與調整間距時,這個方法很方便。若 x 軸顯示一般分類,請改用其他章節介紹的刻度標籤方法。

使用 ax.set_xticklabels 設定標籤與旋轉角度

若需要自訂標籤文字並設定其旋轉角度,可使用 ax.set_xticklabels。請先明確設定刻度位置,再為每個位置提供一個標籤,讓每段文字都對應到預期的刻度。若只需旋轉標籤,不必替換標籤文字;使用 tick_params 或 plt.setp 即可保留原有文字。

import matplotlib.pyplot as plt

positions = [0, 1, 2, 3]
labels = ["North region", "South region", "East region", "West region"]
values = [8, 5, 9, 6]

fig, ax = plt.subplots()
ax.plot(positions, values, marker="o")
ax.set_xticks(positions)
ax.set_xticklabels(labels, rotation=45, ha="right")
ax.grid(True)
fig.tight_layout()

折線圖,自訂標籤 North region、South region、East region、West region 旋轉 45 度並右對齊。

刻度位置與標籤的順序必須一致。若之後圖表的刻度有所變動,也要同步更新自訂標籤。

使用 plt.setp 設定標籤屬性

plt.setp 可更新現有 Matplotlib 圖形物件的屬性,包括由 ax.get_xticklabels() 傳回的目前 x 軸刻度標籤物件。當標籤已經設定完成,而你只想調整外觀時,這個方法就很實用。

import matplotlib.pyplot as plt

categories = ["First quarter", "Second quarter", "Third quarter", "Fourth quarter"]
values = [14, 17, 13, 21]

fig, ax = plt.subplots()
ax.plot(categories, values, marker="o")
plt.setp(ax.get_xticklabels(), rotation=45, ha="right")
ax.grid(True)
fig.tight_layout()

季度數值折線圖,使用 plt.setp 將刻度標籤旋轉 45 度並右對齊。

此處以 rotation 變更角度,並以 ha 設定水平對齊方式。這會更新目前的刻度標籤物件,不會替換標籤文字。

使用 ax.tick_params 設定 x 軸標籤旋轉角度

ax.tick_params 可設定指定座標軸的刻度、刻度標籤與網格線屬性。傳入 axis="x" 和全小寫的 labelrotation 關鍵字,即可旋轉 x 軸標籤,同時保留原有文字與位置。

import matplotlib.pyplot as plt

categories = ["Planning", "Development", "Review", "Delivery"]
values = [2, 5, 3, 6]

fig, ax = plt.subplots()
ax.plot(categories, values, marker="o")
ax.tick_params(axis="x", labelrotation=45)
ax.grid(True)
fig.tight_layout()

四個專案階段的折線圖,使用 tick_params 的 labelrotation 關鍵字將刻度標籤旋轉 45 度。

若已持有 Axes 參照,可使用這個座標軸層級的方法。關鍵字拼法是全小寫的 labelrotation。

對齊旋轉後的刻度標籤

旋轉會改變標籤角度,水平對齊則會決定標籤的哪個部分落在刻度上。設定 ha="right" 時,標籤右端會對齊刻度;設定 ha="left" 時,左端會對齊刻度;設定 ha="center" 時,則以標籤中點對齊刻度。對於向刻度左側延伸的 45 度標籤,靠右對齊是常見的選擇。可依標籤長度與圖表版面試用不同設定。

import matplotlib.pyplot as plt

positions = [0, 1, 2, 3]
labels = ["January", "February", "March", "April"]
values = [4, 7, 5, 8]
alignments = ["right", "left", "center"]

fig, axes = plt.subplots(1, 3, figsize=(10, 3))
for ax, alignment in zip(axes, alignments):
    ax.plot(positions, values, marker="o")
    ax.set_xticks(positions)
    ax.set_xticklabels(labels, rotation=45, ha=alignment)
    ax.set_title(f'ha="{alignment}"')
    ax.grid(True)
fig.tight_layout()

三個並排的折線圖,比較 45 度刻度標籤在水平對齊 right、left、center 下的差異。

請依照希望標籤以哪一端或哪個位置為基準來選擇對齊方式。若標籤仍顯得擁擠,除了旋轉標籤,也可以加寬圖表或縮短標籤文字。

處理被截斷的標籤與標籤數量錯誤

即使旋轉本身正常,仍有兩種失敗可能。第一,ax.set_xticklabels 會替換標籤文字,因此標籤數量必須與刻度位置數量相等。為四個位置傳入三個標籤時,呼叫會在繪製任何內容之前失敗:

import matplotlib.pyplot as plt

positions = [0, 1, 2, 3]
labels = ["North", "South", "East"]
values = [8, 5, 9, 6]

fig, ax = plt.subplots()
ax.plot(positions, values, marker="o")
ax.set_xticks(positions)
ax.set_xticklabels(labels, rotation=45, ha="right")

呼叫以此錯誤結束:

ValueError: The number of FixedLocator locations (4), usually from a call to set_ticks, does not match the number of labels (3).

補上缺少的標籤,使兩個序列長度相同且順序一致。如果只需要旋轉既有文字,改用 plt.setp 或 ax.tick_params:它們會保留目前的標籤,因此不會出現這種不一致。

第二,旋轉只改變角度,並不會在軸下方創造空間。將上方 set_xticklabels 範例拿掉其 fig.tight_layout() 呼叫來轉譯,旋轉後的標籤會超出圖形下緣——在預設大小的轉譯中約超出 31 像素,並在文字中途被截斷:

折線圖,因未套用 tight_layout,45 度地區標籤在圖形下緣被截斷。

fig.tight_layout() 會重新計算圖形框,使每個標籤都能放下;以相同方式測量,標籤會恰好在圖形邊緣結束,外面不留任何部分。fig.autofmt_xdate 對日期軸做同類的邊距調整。如果佈局調整後標籤仍互相碰撞,應縮短標籤文字或加寬圖形,而不是加大角度。