I am trying to add two tiers of labels to this stacked grouped barplot using matplotlib. Each bar in each respective position of each group should have the same label (i.e. the first bar in each group should be labeled "1", the second bar in each group "2", etc.). Then I would like there to be a second tier of labels for each group. So far, this is what I have:
width = 0.25
x = np.arange(1, 7)
fig = plt.figure(figsize=(10,6))
ax = plt.axes()
ax.bar(x-0.4, shift1_rbc, width, color='red', tick_label='1')
ax.bar(x-0.1, shift2_rbc, width, color='red')
ax.bar(x 0.2, shift3_rbc, width, color='red')
ax.bar(x-0.4, shift1_plt, width*.7, color='blue')
ax.bar(x-0.1, shift2_plt, width*.7, color='blue')
ax.bar(x 0.2, shift3_plt, width*.7, color='blue')
ax.bar(x-0.4, shift1_ffp, width*.5, color='green')
ax.bar(x-0.1, shift2_ffp, width*.5, color='green')
ax.bar(x 0.2, shift3_ffp, width*.5, color='green')
When I try to add a "tick_label" parameter to another set of bars, it replaces the previous label, like so:
width = 0.25
x = np.arange(1, 7)
fig = plt.figure(figsize=(10,6))
ax = plt.axes()
ax.bar(x-0.4, shift1_rbc, width, color='red', tick_label='1')
ax.bar(x-0.1, shift2_rbc, width, color='red', tick_label='1')
ax.bar(x 0.2, shift3_rbc, width, color='red')
ax.bar(x-0.4, shift1_plt, width*.7, color='blue')
ax.bar(x-0.1, shift2_plt, width*.7, color='blue')
ax.bar(x 0.2, shift3_plt, width*.7, color='blue')
ax.bar(x-0.4, shift1_ffp, width*.5, color='green')
ax.bar(x-0.1, shift2_ffp, width*.5, color='green')
ax.bar(x 0.2, shift3_ffp, width*.5, color='green')
I appreciate any help anyone can provide!
CodePudding user response:
A simple solution would be to concatenate all the x-values, all the bar-heights and all the tick labels. And then draw them in one go (there is no need for sorting):
import matplotlib.pyplot as plt
import numpy as np
width = 0.25
x = np.arange(1, 7)
fig, ax = plt.subplots(figsize=(10, 6))
tick_labels_1 = ['1'] * len(x)
tick_labels_2 = ['2'] * len(x)
tick_labels_3 = ['3'] * len(x)
shift1_rbc = np.random.uniform(1100, 1200, 6)
shift2_rbc = np.random.uniform(900, 1000, 6)
shift3_rbc = np.random.uniform(1000, 1100, 6)
shift1_plt = np.random.uniform(600, 700, 6)
shift2_plt = np.random.uniform(400, 500, 6)
shift3_plt = np.random.uniform(500, 600, 6)
shift1_ffp = np.random.uniform(250, 300, 6)
shift2_ffp = np.random.uniform(150, 200, 6)
shift3_ffp = np.random.uniform(200, 250, 6)
all_x = np.concatenate([x - 0.4, x - 0.1, x 0.2])
ax.bar(all_x, np.concatenate([shift1_rbc, shift2_rbc, shift3_rbc]), width,
tick_label=tick_labels_1 tick_labels_2 tick_labels_3,
color='crimson', label='red')
ax.bar(all_x, np.concatenate([shift1_plt, shift2_plt, shift3_plt]),
width * .7, color='dodgerblue', label='blue')
ax.bar(all_x, np.concatenate([shift1_ffp, shift2_ffp, shift3_ffp]),
width * .5, color='limegreen', label='green')
ax.margins(x=0.02)
ax.legend(title='Data', bbox_to_anchor=(0.99, 1), loc='upper left')
for spine in ['top', 'right']:
ax.spines[spine].set_visible(False)
ax.set_xticks(x - 0.1001, minor=True)
ax.set_xticklabels(['January', 'February', 'March', 'April', 'May', 'June'], minor=True)
ax.tick_params(axis='x', which='minor', length=0, pad=18)
plt.tight_layout()
plt.show()
PS: To get 3 layers of labels, one could use newlines:
tick_labels_1 = ['1\n4\n7'] * len(x)
tick_labels_2 = ['2\n5\n8'] * len(x)
tick_labels_3 = ['3\n6\n9'] * len(x)




