如何为matplotlib stacked group barplot添加两层标签

How to add two tiers of labels for matplotlib stacked group barplot

我正在尝试使用 matplotlib 向这个堆叠分组的条形图添加两层标签。每个组的每个相应位置中的每个条都应具有相同的标签(即每个组中的第一个条应标记为“1”,每个组中的第二个条应标记为“2”,依此类推)。然后我希望每个组都有第二层标签。到目前为止,这就是我所拥有的:

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')

当我尝试将“tick_label”参数添加到另一组柱形图时,它会替换之前的标签,如下所示:

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')

感谢任何人提供的帮助!

一个简单的解决方案是连接所有 x 值、所有条形高度和所有刻度标签。然后一口气画出来(不需要排序):

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: 要得到 3 层标签,可以使用换行符:

tick_labels_1 = ['1\n4\n7'] * len(x)
tick_labels_2 = ['2\n5\n8'] * len(x)
tick_labels_3 = ['3\n6\n9'] * len(x)