e9e9s
e9e9s

Reputation: 955

Passing same x axis label to matplotlib subplots of barplots

I'm trying to create subplots of barplots. matplotlib is funny with labeling the x axis of barplots so you need to pass an index then use the xticks function to pass the labels. I want to create 2 subplots that each have the same x axis labels but with the code below I can only pass the labels onto the last bar plot. My question is how can I pass the labels to both bar plots?

fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(18,15))

r1 = axes[0].bar(idx, data1, align='center')
axes[0].set_title('title1')

r2 = axes[1].bar(idx, data2, align='center')
axes[1].set_title('title2')

plt.xticks(idx, idx_labels, rotation=45)

Upvotes: 1

Views: 1485

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339570

plt.xticks as all other pyplot commands relate to the currently active axes. Having produced several axes at once via plt.subplots(), the last of them is the current axes, and thus the axes for which plt.xticks would set the ticks.

You may set the current axes using plt.sca(axes):

import matplotlib.pyplot as plt

idx, data1, data2, idx_labels = [1,2,3], [3,4,2], [2,5,4], list("ABC")

fig, axes = plt.subplots(nrows=2, ncols=1)

r1 = axes[0].bar(idx, data1, align='center')
axes[0].set_title('title1')

plt.sca(axes[0])
plt.xticks(idx, idx_labels, rotation=45)

r2 = axes[1].bar(idx, data2, align='center')
axes[1].set_title('title2')

plt.sca(axes[1])
plt.xticks(idx, idx_labels, rotation=45)

plt.show()

However, when working with subplots, it is often easier to use the object-oriented API of matplotlib instead of the pyplot statemachine. In that case you'd use ax.set_xticks and ax.set_xticklabels, where ax is the axes for which you want to set some property. This is more intuitive, since it is easily seen from the code which axes it being worked on.

import matplotlib.pyplot as plt

idx, data1, data2, idx_labels = [1,2,3], [3,4,2], [2,5,4], list("ABC")

fig, axes = plt.subplots(nrows=2, ncols=1)

r1 = axes[0].bar(idx, data1, align='center')
axes[0].set_title('title1')

r2 = axes[1].bar(idx, data2, align='center')
axes[1].set_title('title2')

for ax in axes:
    ax.set_xticks(idx)
    ax.set_xticklabels(idx_labels, rotation=45)

plt.show()

Upvotes: 4

Related Questions