web-dev-qa-db-ja.com

各xticklabel間の間隔が等しくなるようにmatplotlibでxticklabelsを回転するにはどうすればよいですか?

各xticklabel間の間隔が等しくなるようにmatplotlibでxticklabelsを回転するにはどうすればよいですか?

たとえば、次のコードの場合:

import matplotlib.pyplot as plt
import numpy as np

# Data + parameters
fontsize = 20
t = np.arange(0.0, 6.0, 1)
xticklabels = ['Full', 'token emb', 'char emb', 'char LSTM', 
               'token LSTM', 'feed forward','ANN']

# Plotting
fig = plt.figure(1)
ax = fig.add_subplot(111)
plt.plot(t, t)
plt.xticks(range(0, len(t) + 1))
ax.tick_params(axis='both', which='major', labelsize=fontsize)
ax.set_xticklabels(xticklabels, rotation = 45)
fig.savefig('test_rotation.png', dpi=300, format='png', bbox_inches='tight')

私が取得します:

enter image description here

各xticklabel間の間隔は等しくありません。たとえば、「Full」と「token emb」の間隔は、「feed forward」と「ANN」の間隔よりもはるかに大きくなります。

Matplotlib 2.0.0とPython 3.5 64ビットWindows 7 SP1 x64 Ultimateで使用しています。

15

ラベルは目盛りの位置の中央に配置されます。境界ボックスの幅は等しくなく、重なり合うことさえあり、不等間隔に見えます。

enter image description here

常に目盛りラベルを目盛りにリンクする必要があるため、間隔の変更は実際にはオプションではありません。

ただし、右上隅が目盛りの下の位置の参照となるように配置することもできます。

そのためにhorizontalalignmentまたはha引数を使用し、"right"に設定します。

ax.set_xticklabels(xticklabels, rotation = 45, ha="right")

これにより、次のプロットが得られます。

enter image description here

別の方法として、目盛りラベルを水平方向の中央に配置するだけでなく、垂直方向に中央に配置することもできます。これにより、等間隔になりますが、軸に対する垂直位置をさらに調整する必要があります。

ax.set_xticklabels(xticklabels, rotation = 45, va="center", position=(0,-0.28))

enter image description here


enter image description here

質問のように目盛りを手動で指定する場合(たとえば、plt.xticksまたはax.set_xticks経由)、またはカテゴリプロットを使用する場合は、上記を使用できます。
代わりにラベルが自動的に表示される場合、1つは使用しないでくださいset_xticklabelsset_xticklabelsが軸のフォーマッタをFixedFormatterに設定し、ロケーターが自動AutoLocatorのままであるため、これにより一般にラベルと目盛りの位置が同期しなくなります。その他の自動ロケーター。

これらの場合は、plt.setpを使用して既存のラベルの回転と配置を設定するか、

plt.setp(ax.get_xticklabels(), ha="right", rotation=45)

またはそれらをループしてそれぞれのプロパティを設定します。

for label in ax.get_xticklabels():
    label.set_ha("right")
    label.set_rotation(45)

例は

import numpy as np; np.random.seed(42)
import matplotlib.pyplot as plt

t = np.arange("2018-01-01", "2018-03-01", dtype="datetime64[D]")
x = np.cumsum(np.random.randn(len(t)))

fig, ax = plt.subplots()
ax.plot(t, x)

for label in ax.get_xticklabels():
    label.set_ha("right")
    label.set_rotation(45)

plt.tight_layout()
plt.show()