Issue
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!
Solution
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)
Answered By - JohanC
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.