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が適している場面を紹介します。
回転しない場合、月の名前のようなカテゴリ名は水平のまま軸の幅全体を占めるため、名前が長い場合や図が狭い場合には隣り合うラベル同士がくっついてしまいます:
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()
現在の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)
日付を使う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()
目盛り位置とラベルは同じ順序にしてください。後からプロットの目盛りを変更した場合は、それに合わせて独自のラベルも更新します。
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()
ここでは、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()
すでに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()
ラベルのどこを基準に配置するかに応じて揃え方を選びます。それでもラベルが詰まって見える場合は、回転に加えて図の幅を広げたり、ラベルの文言を短くしたりしてください。
切り取られたラベルとラベル数の不一致エラーを処理する
回転自体が機能していても、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ピクセルはみ出し、テキストの途中で切り取られます:
fig.tight_layout() は、すべてのラベルが収まるように図の枠を再計算します。同じ方法で測定すると、ラベルは図の端ちょうどで終わり、外にはみ出すものはありません。fig.autofmt_xdate は日付軸について同様の余白調整を行います。レイアウト調整後もラベル同士が衝突する場合は、角度を大きくするのではなく、ラベルテキストを短くするか図を広げてください。