How can I rotate the xticklabels in matplotlib so that the distance between each xtlllabel is equal?
How can I rotate the xticklabels in matplotlib so that the distance between each xticklabel is the same?
For example with this code:
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')
I get:
The spacing between each xticklabel is not equal. For example, the interval between 'Full' and 'token emb' is much longer than the interval between 'feed forward' and 'ANN'.
I am using Matplotlib 2.0.0 and Python 3.5 64-bit on Windows 7 SP1 x64 Ultimate.
source to share
The marks are centered at the mark position. Their bounding boxes are not the same width and may even overlap, making them look uneven.
Since you always want the labels to be tagged with links to their labels, changing the spacing is not really an option.
However, you can align them so that the top-right corner is a guide for positioning them under the checkmark.
Use horizontalalignment
either an argument for this ha
and set a value for it "right"
:
ax.set_xticklabels(xticklabels, rotation = 45, ha="right")
This leads to the following plot:
An alternative would be to keep the labels centered horizontally, but also centered vertically. This results in the same distance, but is required to further adjust their vertical position relative to the axis.
ax.set_xticklabels(xticklabels, rotation = 45, va="center", position=(0,-0.28))
The above can be used if plt.xticks
specified manually, as in the question (e.g. via plt.xticks
or via ax.set_xticks
), or if a categorical graph is used.
If the labels are displayed automatically instead, do not use set_xticklabels
. This is, in general, let labels and mark the out of sync positions, because it set_xticklabels
sets the axis formatter to view FixedFormatter
while the locator remains automatic AutoLocator
, or any other automatic locator.
In these cases, either use plt.setp
to set rotation and alignment of existing marks,
plt.setp(ax.get_xticklabels(), ha="right", rotation=45)
or loop them to set the corresponding properties,
for label in ax.get_xticklabels():
label.set_ha("right")
label.set_rotation(45)
An example would be
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()
source to share