Как я могу повернуть xticklabels в matplotlib, чтобы расстояние между каждой xtlllabel было равно?

Как я могу повернуть xticklabels в matplotlib так, чтобы расстояние между каждым xticklabel было одинаковым?

Например с этим кодом:

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-bit на Windows 7 SP1 x64 Ultimate.

Ответ 1

Метки расположены по центру в позиции отметки. Их ограничительные рамки имеют неодинаковую ширину и могут даже перекрываться, что делает их выглядящими неравномерно.

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 указаны вручную, как в вопросе (например, через plt.xticks или через ax.set_xticks), или если используется категориальный график.
Если вместо этого метки отображаются автоматически, не следует использовать set_xticklabels. Это, в общем пусть этикетки и отметьте позиции рассинхронизации, потому что set_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()

Ответ 2

Более простым решением является добавить plt.xticks(rotation=45) к вашему коду. Результат выглядит следующим образом:

Пример силовой барплоты с повернутой осью x