HOWTO · Matplotlib

Matplotlib で X 軸の目盛りラベルテキストを回転させる方法

長いラベルが重なる場合に、Matplotlib の x 軸の目盛りラベルを回転させて配置を調整する 5 つの方法を紹介します。

このページの内容

Matplotlibでx軸の目盛りラベルを回転するには、plt.xticks、fig.autofmt_xdate、ax.set_xticklabels、plt.setp、ax.tick_paramsに、たとえばrotation=45のように角度を指定します。長いラベルを水平に並べると重なる場合は、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度回転し、右揃えで各ラベルが目盛りの位置で終わっている。

現在のAxesを手早く変更するなら、plt.xticksを使います。コードですでにAxesオブジェクトを使っている場合は、以下のメソッドを使うと対象のAxesを明示できます。

fig.autofmt_xdateで日付軸のラベルを回転する

日付を扱うプロットでは、fig.autofmt_xdateを使うと図の日付ラベルの書式が整い、読みやすくなるよう回転されます。デフォルトでは配置と下部の余白も調整されます。角度を指定したい場合は、rotationを明示できます。動作は図のAxesや日付の書式によって異なるため、すべての目盛りラベル設定の代わりとしてではなく、日付軸に使ってください。

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月の6つの週次日付に対する折れ線グラフ。autofmt_xdate により日付ラベルが45度回転している。

日付を使うx軸で、書式設定されたラベルの回転や間隔調整が必要なときに便利です。通常のカテゴリ軸には、ほかのセクションで紹介する目盛りラベル用のメソッドを選んでください。

ax.set_xticklabelsでラベルと回転を設定する

独自のラベル文字列を指定し、回転も設定したい場合はax.set_xticklabelsを使います。まず目盛り位置を明示的に設定し、各位置に対応するラベルを1つずつ渡してください。そうすると、それぞれの文字列が意図した目盛りに対応します。回転するだけならラベルを置き換える必要はありません。既存の文字列を保つには、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は、ax.get_xticklabels()が返す現在のx軸目盛りラベルオブジェクトなど、既存のMatplotlibアーティストのプロパティを更新します。ラベルがすでに設定されていて、見た目だけを変更したい場合に便利です。

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

4つのプロジェクトフェーズの折れ線グラフ。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 を比較する3つの並んだ折れ線グラフ。

ラベルのどこを基準に配置するかに応じて揃え方を選びます。それでもラベルが詰まって見える場合は、回転に加えて図の幅を広げたり、ラベルの文言を短くしたりしてください。

切り取られたラベルとラベル数の不一致エラーを処理する

回転自体が機能していても、2つの失敗が残ります。第一に、ax.set_xticklabels はラベルテキストを置き換えるため、ラベルの数は目盛り位置の数と一致しなければなりません。4つの位置に対して3つのラベルを渡すと、何も描画される前に呼び出しが失敗します:

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

不足しているラベルを追加し、2つのシーケンスが同じ順序で同じ長さになるようにしてください。既存のテキストを回転させるだけなら、代わりに plt.setp または ax.tick_params を使ってください。現在のラベルが保持されるため、この不一致は発生しません。

第二に、回転は角度を変えますが、軸の下に余地を作るわけではありません。上の set_xticklabels の例を fig.tight_layout() の呼び出しなしで描画すると、回転したラベルが図の下端をはみ出します。デフォルトサイズの描画では約31ピクセルはみ出し、テキストの途中で切り取られます:

tight_layout が適用されていないため、45度の地域ラベルが図の下端で切り取られた折れ線グラフ。

fig.tight_layout() は、すべてのラベルが収まるように図の枠を再計算します。同じ方法で測定すると、ラベルは図の端ちょうどで終わり、外にはみ出すものはありません。fig.autofmt_xdate は日付軸について同様の余白調整を行います。レイアウト調整後もラベル同士が衝突する場合は、角度を大きくするのではなく、ラベルテキストを短くするか図を広げてください。