【问题标题】:Combining a grouped bar plot with a truncated line chart将分组条形图与截断折线图相结合
【发布时间】:2020-12-08 11:14:27
【问题描述】:

我知道如何创建 grouped bar plot 并且我知道如何在 matplotlib 中创建 line plot 但不幸的是,我不知道如何以根据条形图对线图进行分组的方式将两者结合起来组,同时保留两个轴。以下草图(希望)说明了我试图实现的目标:

这就是我到目前为止所做的:

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

labels = ['G1', 'G2', 'G3', 'G4', 'G5']
men_means = [20, 34, 30, 35, 27]
women_means = [25, 32, 34, 20, 25]

YearGroup1 = ['G11','G12']
Unemployment_RateGroup1 = [31,32]

x = np.arange(len(labels))  # the label locations
width = 0.35  # the width of the bars

fig, ax = plt.subplots()
rects1 = ax.bar(x - width/2, men_means, width, label='Men')
rects2 = ax.bar(x + width/2, women_means, width, label='Women')

# Add some text for labels, title and custom x-axis tick labels, etc.
ax.set_ylabel('Scores')
ax.set_title('Scores by group and gender')
ax.set_xticks(x)
ax.set_xticklabels(labels)
ax.legend()

def autolabel(rects):
    """Attach a text label above each bar in *rects*, displaying its height."""
    for rect in rects:
        height = rect.get_height()
        ax.annotate('{}'.format(height),
                    xy=(rect.get_x() + rect.get_width() / 2, height),
                    xytext=(0, 3),  # 3 points vertical offset
                    textcoords="offset points",
                    ha='center', va='bottom')

autolabel(rects1)
autolabel(rects2)

fig.tight_layout()

plt.plot(YearGroup1, Unemployment_RateGroup1)
plt.show()

但是,我不知道如何手动重新定位折线图的 x 位置。这些线应该在组内,并且应该在第二个 y 轴上。

整个图旨在显示不同算法(X_1、X_2、X_3、...)在不同数据类型(红条、绿条、蓝条)上的结果。第二个 y 轴上的分组折线图应该代表每个算法所需的时间。

非常感谢任何帮助。

【问题讨论】:

  • 您可以先绘制条形,然后再绘制线条。行的 x 位置应该类似于 [x1 - width, x1, x1 + width] 等。
  • 非常感谢您的评论。我在我的问题中添加了一个初始 MWE。但是,我不知道如何手动移动 xticks。您的方法在代码中的表现如何?
  • 感谢您提出问题。 “移动 xticks”是什么意思?你想移动 xtick 标签吗,f.i.交换 G1、G2 等还是要移动标签的位置?你想用线条绘制什么?这些行是否应该在组内,f.i.显示从 G1 的男性到女性的趋势,或跨越多个组,f.i.显示 G1 到 G5 组男性的趋势?
  • 哦,那么第二个 y 轴呢?线条是否应该在第二个 y 轴上?
  • 我再次编辑了我的问题以解决您的问题。

标签: python matplotlib bar-chart linechart


【解决方案1】:

假设线图应该显示组内数据,您可以这样绘制:

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

labels = ['G1', 'G2', 'G3', 'G4', 'G5']
men_means = [20, 34, 30, 35, 27]
women_means = [25, 32, 34, 20, 25]

YearGroup1 = ['G11','G12']
Unemployment_RateGroup1 = [31,32]

x = np.arange(len(labels))  # the label locations
width = 0.35  # the width of the bars

fig, ax = plt.subplots()
ax2 = ax.twinx()  # <--- make a second y-axis
rects1 = ax.bar(x - width/2, men_means, width, label='Men')
rects2 = ax.bar(x + width/2, women_means, width, label='Women')

# Add some text for labels, title and custom x-axis tick labels, etc.
ax.set_ylabel('Scores')
ax.set_title('Scores by group and gender')
ax.set_xticks(x)
ax.set_xticklabels(labels)
ax.legend()

def autolabel(rects):
    """Attach a text label above each bar in *rects*, displaying its height."""
    for rect in rects:
        height = rect.get_height()
        ax.annotate('{}'.format(height),
                    xy=(rect.get_x() + rect.get_width() / 2, height),
                    xytext=(0, 3),  # 3 points vertical offset
                    textcoords="offset points",
                    ha='center', va='bottom')

autolabel(rects1)
autolabel(rects2)

# plot lines    
for i in range(len(labels)):
    ax2.plot(
        [x[i] - width / 2, x[i] + width / 2], 
        Unemployment_RateGroup1, 
        color='C3', marker='+', mec='k'
    )

fig.tight_layout()

请注意我删除了plt.show()。如果您需要此行,请不要忘记添加它。

如果您有每个组的 Unemployment_Rate 单独数据,f.i.

Unemployment_Rate = [[31, 32], [7, 12], [23, 9], [0, 1], [32, 0]]

您可以将线图替换为:

ax2.plot(
    [x[i] - width / 2, x[i] + width / 2], 
    Unemployment_Rate[i], 
    color='C3', marker='+', mec='k'
)

这将产生:

【讨论】:

    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 2013-06-29
    • 2020-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-13
    相关资源
    最近更新 更多