I am trying to set x tick labels, but allowing matplotlib to decide where to place the ticks. Unfortunately, when I set the x tick labels, matplotlib will use the label strings only for the ticks that have been displayed.
Example:
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
xs = range(26)
ys = range(26)
ax.plot(xs, ys)
ax.set_xticklabels(list('abcdefghijklmnopqrstuvwxyz'))
plt.show()
This gives:
This for me is quite unintuitive; I would expect the labels to correspond to the points that they are showing. (I can however understand this behavior is more useful when plotting multiple series which do not use the same x values.)
NB: I do not want all 26 letters as ticks. Rather, I want just the 6 (as matplotlib has suggested), but those 6 should be appropriate for their positions. This should then make it easy to change the fig size without having to manually recalculate the new tick labels.
How could I achieve the desired result?
xticks( ticks ) sets the x-axis tick values, which are the locations along the x-axis where the tick marks appear. Specify ticks as a vector of increasing values; for example, [0 2 4 6] . This command affects the current axes. xt = xticks returns the current x-axis tick values as a vector.
To add extra ticks, use xticks() method and increase the range of ticks to 1 to 20 from 1 to 10. To display the figure, use the show() method.
MatPlotLib with Python Using subplot() method, add a subplot to the current figure. Plot x and log(x) using plot() method. Set the label on X-axis using set_label() method, with fontsize=16, loc=left, and color=red. To set the xlabel at the end of X-axis, use the coordinates, x and y.
You need to assign the tick location prior to the labels. The easiest way to get the desired result for your example would be to add ax.set_xticks(xs)
before you set the tick labels.
import matplotlib.pyplot as pl
fig = pl.figure()
ax = fig.add_subplot(111)
xs = range(26)
ys = range(26)
_ = ax.plot(xs, ys)
alph = list('abcdefghijklmnopqrstuvwxyz')
ax.set_xticks(xs)
ax.set_xticklabels(alph)
pl.savefig('ticklabels.png', dpi=300)
Edit: I'd suggest the following to address your wish for a more general solution:
from matplotlib.ticker import MaxNLocator
import matplotlib.pyplot as pl
import numpy as np
alph = list('abcdefghijklmnopqrstuvwxyz')
nticks = 8
fig, ax = pl.subplots()
xs = np.linspace(-10., 10., 100)
ys = np.polyval([1., 2., 3.], xs)
_ = ax.plot(xs, ys)
ax.xaxis.set_major_locator(MaxNLocator(nticks))
ax.set_xticklabels(alph[::int(len(alph)/nticks)])
pl.savefig('ticklabels.png', dpi=300)
You specify the number of ticks with the MaxNLocator and map them to the alphabet via slicing.
I'm not sure about how reliable MaxNLocator is in returning exactly the desired number of ticks, though. As mentioned in the comments, you could simply use len(ax.get_xticks())
to get the number of ticks.
I think the most appropriate solution is to use FuncFormatter
which will allow you to look up the tick label value you need, and allow matplotlib to determine positions and number of ticks:
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter, MaxNLocator
fig = plt.figure()
ax = fig.add_subplot(111)
xs = range(26)
ys = range(26)
labels = list('abcdefghijklmnopqrstuvwxyz')
def format_fn(tick_val, tick_pos):
if int(tick_val) in xs:
return labels[int(tick_val)]
else:
return ''
ax.xaxis.set_major_formatter(FuncFormatter(format_fn))
ax.xaxis.set_major_locator(MaxNLocator(integer=True))
ax.plot(xs, ys)
plt.show()
This will give you:
(Thanks Daniel Lenz for the pointers and other suggestions).
NB:
As mentioned by tcaswell, xaxis.set_major_locator(MaxNLocator(integer=True))
is used to ensure ticks are placed at integer values only.
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