I have a simple plot, with x labels of 1, 1.25, 1.5, 1.75, 2 etc. up to 15:
The plot was created from a pandas.DataFrame
without specifying the xtick interval:
speed.plot(kind='bar',figsize=(15, 7))
Now I would like the x-interval to be in increments of 1 rather than 0.25, so the labels would read 1,2,3,4,5 etc.
I'm sure this is easy but I cannot for the life of me figure it out.
I've found plt.xticks()
which seems like it's the right call but maybe it's set_xticks
?
I've changed the x ticks a great amount without doing what I wanted up until this point. Any help would be greatly appreciated.
The way that pandas handles x-ticks for bar plots can be quite confusing if your x-labels have numeric values. Let's take this example:
import pandas as pd
import numpy as np
x = np.linspace(0, 1, 21)
y = np.random.rand(21)
s = pd.Series(y, index=x)
ax = s.plot(kind='bar', figsize=(10, 3))
ax.figure.tight_layout()
You might expect the tick locations to correspond directly to the values in x
, i.e. 0, 0.05, 0.1, ..., 1.0. However, this isn't the case:
print(ax.get_xticks())
# [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20]
Instead pandas sets the tick locations according to the indices of each element in x
, but then sets the tick labels according to the values in x
:
print(' '.join(label.get_text() for label in ax.get_xticklabels()))
# 0.0 0.05 0.1 0.15 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1.0
Because of this, setting the tick positions directly (either by using ax.set_xticks
) or passing the xticks=
argument to pd.Series.plot()
will not give you the effect you are expecting:
new_ticks = np.linspace(0, 1, 11) # 0.0, 0.1, 0.2, ..., 1.0
ax.set_xticks(new_ticks)
Instead you would need to update the positions and the labels of your x-ticks separately:
# positions of each tick, relative to the indices of the x-values
ax.set_xticks(np.interp(new_ticks, s.index, np.arange(s.size)))
# labels
ax.set_xticklabels(new_ticks)
This behavior actually makes a lot of sense in most cases. For bar plots it is common for the x-labels to be non-numeric (e.g. strings corresponding to categories), in which case it wouldn't be possible to use the values in x
to set the tick locations. Without introducing another argument to specify their locations, the most logical choice would be to use their indices instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With