cristie09
cristie09

Reputation: 331

Matplotlib set x tick labels does not swap order

I want to make a line graph where essentially (Dog,1), (Cat,2), (Bird,3) and so on are plotted and connected by line. In additional, I would like to be able to determine the order of the label in the X axis. Matplotlib auto-plotted with the order 'Dog', 'Cat', and 'Bird' label. Despite my attempt at re-arranging the order to 'Dog','Bird','Giraffe','Cat', the graph doesn't change (see image). What should I do to be able to arrange the graph accordingly?enter image description here

x = ['Dog','Cat','Bird','Dog','Cat','Bird','Dog','Cat','Cat','Cat']
y = [1,2,3,4,5,6,7,8,9,10]
x_ticks_labels = ['Dog','Bird','Giraffe','Cat']

fig, ax = plt.subplots(1,1) 
ax.plot(x,y)

# Set number of ticks for x-axis
ax.set_xticks(range(len(x_ticks_labels)))
# Set ticks labels for x-axis
ax.set_xticklabels(x_ticks_labels)

Upvotes: 2

Views: 7168

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339250

Use matplotlib's categorical feature

You may predetermine the order of categories on the axes by first plotting something in the correct order then removing it again.

import numpy as np
import matplotlib.pyplot as plt

x = ['Dog','Cat','Bird','Dog','Cat','Bird','Dog','Cat','Cat','Cat']
y = [1,2,3,4,5,6,7,8,9,10]
x_ticks_labels = ['Dog','Bird','Giraffe','Cat']

fig, ax = plt.subplots(1,1) 

sentinel, = ax.plot(x_ticks_labels, np.linspace(min(y), max(y), len(x_ticks_labels)))
sentinel.remove()
ax.plot(x,y, color="C0", marker="o")

plt.show()

Determine indices of values

The other option is to determine the indices that the values from x would take inside of x_tick_labels. There is unfortunately no canonical way to do so; here I take the solution from this answer using np.where. Then one can simply plot the y values against those indices and set the ticks and ticklabels accordingly.

import numpy as np
import matplotlib.pyplot as plt

x = ['Dog','Cat','Bird','Dog','Cat','Bird','Dog','Cat','Cat','Cat']
y = [1,2,3,4,5,6,7,8,9,10]
x_ticks_labels = ['Dog','Bird','Giraffe','Cat']

xarr = np.array(x)
ind = np.where(xarr.reshape(xarr.size, 1) == np.array(x_ticks_labels))[1]

fig, ax = plt.subplots(1,1) 

ax.plot(ind,y, color="C0", marker="o")
ax.set_xticks(range(len(x_ticks_labels)))
ax.set_xticklabels(x_ticks_labels)

plt.show()

Result in both cases

enter image description here

Upvotes: 4

Related Questions