ConanG ConanG - 11 months ago 107
Python Question

Matplotlib: Set manual x-axis labels given string label array input, but only on major ticks

I tried this but the labels are not printing in the right location. Some of the labels are not printed and are not printed in the right position.

I have an array of labels that correspond to each data point. I only want some of the labels to be printed and printed only on major ticks. But I do not know how to set major ticks and still keep the labels in correct positions.

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
fig, ax1 = plt.subplots(1, 1)
top = np.arange(100)
btm = top-2
x = np.arange(len(top))
ax1.vlines(x, top, btm, color='r', linewidth=1)

labels = np.linspace(200,300,100).astype(np.int).astype(np.str)
factor = 10
labels = [label for i,label in enumerate(labels) if ((i+1)%factor==1)]
plt.xticks(x, labels, rotation='horizontal')
from matplotlib.ticker import MultipleLocator, FormatStrFormatter, FixedFormatter
majorLocator = MultipleLocator(factor)
majorFormatter = FixedFormatter(labels)
minorLocator = MultipleLocator(1)
ax1.xaxis.set_minor_locator(minorLocator)
ax1.xaxis.set_major_formatter(majorFormatter)
ax1.xaxis.set_major_locator(majorLocator)
plt.tick_params(axis='both', which='major', labelsize=9, length=10)
plt.tick_params(axis='both', which='minor', labelsize=5, length=4)


Help. Thanks.

EDIT:
The labels array is of the same length as the number of data points, which is equal to the length of the x axis. So for every increment in position of the x-axis I have the corresponding label. So for the ith position or tick on the x-axis should have either an empty label or the label equal to ith element of label array. It should be empty if it does not fall on a major tick. The labels are not simply integers, but strings. To be more specific, they are datetime strings.

Answer Source

enter image description hereWhat I needed was the FixedLocator with the FixedFormatter, and also an array of integers, majorpos, which specify the indices where the major ticks are located. The other answer using FuncFormatter would introduce some problems.

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
fig, ax1 = plt.subplots(1, 1)
top = np.arange(100)
btm = top-2
x = np.arange(len(top))
ax1.vlines(x, top, btm, color='r', linewidth=1)

labels = np.linspace(200,300,100).astype(np.int).astype(np.str)
print(labels)
factor = 10
plt.xticks(x, labels, rotation='horizontal')

from matplotlib.ticker import MultipleLocator, FormatStrFormatter, FixedFormatter, FixedLocator
majorpos = np.arange(0,len(labels),int(len(labels)/10))
ax1.xaxis.set_major_locator(FixedLocator((majorpos)))
ax1.xaxis.set_major_formatter(FixedFormatter((labels[majorpos])))
ax1.xaxis.set_minor_locator(MultipleLocator(1))
plt.tick_params(axis='both', which='major', labelsize=9, length=10)
plt.tick_params(axis='both', which='minor', labelsize=5, length=4)
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download