使用 python 中的 matplotlib 按源列表对条形图中的列进行分组

问题描述 投票:0回答:1

我对在不同冷却剂中淬火后的钢的硬度进行了一些测量:水、油和空气(只是让它冷却)。测量的组织方式如下:一个名为

coolant_data
的字典包含三个 string:list 对。每根弦都是冷却剂,每个列表都是它的测量值。每个列表内都有三个列表,其中包含三个样本的所有测量值。

我计算了每个样本测量值的平均值和标准差,并将它们相应地放在

coolant_samples
coolant_samples_stds
中。我想使用 plt. 在条形图中绘制来自
coolant_samples
的所有数据,并以
coolant_samples_stds
作为误差线。到目前为止很简单。

我遇到麻烦的部分是:每个列表中的列应该是相邻的,在同一组中。这意味着,组应按冷却剂组织,每组包含三列,用于表示三个样品的测量平均值。

到目前为止我有以下代码:

# Hardness data [HRC]
coolant_data = {
    "Water": [[27.0, 29.0, 30.0, 28.5, 27.5], [21.5, 29.0, 28.5, 21.0, 30.0], [25.0, 22.0, 28.0, 31.0, 26.0]],
    "Oil": [[11.5, 10.0, 11.5, 9.5, 4.5], [11.0, 12.0, 12.0, 11.0, 12.0], [9.5, 10.0, 11.0, 10.5, 11.0]],
    "Air": [[2.5, 3.0, 3.0, 3.5, 1.0], [2.0, 1.5, 3.0, 4.0, 3.5], [2.0, 1.5, 3.0, 2.0, 1.5]]}

# Calculate means and standard deviations
coolant_samples = {coolant: [np.mean(sample) for sample in measurements] for coolant, measurements in coolant_data.items()}
coolant_sample_stds = {coolant: [np.std(sample) for sample in measurements] for coolant, measurements in coolant_data.items()}

# Plot the hardness data as a bar chart with error bars for each sample and the mean
plt.figure()
plt.title("Hardness of Samples After Quenching in Different Coolants")
plt.ylabel("Hardness [HRC]")
labels = coolant_samples.keys()

# Create the bars with grouped x-axis values
x = range(len(labels))
width = 0.25  # Width of each bar
plt.bar_label(plt.bar([i - width for i in x], coolant_samples['Water'], width, label='Sample 1', yerr=coolant_sample_stds['Water']), padding=3)
plt.bar_label(plt.bar([i for i in x], coolant_samples['Oil'], width, label='Sample 2', yerr=coolant_sample_stds['Oil']), padding=3)
plt.bar_label(plt.bar([i + width for i in x], coolant_samples['Air'], width, label='Sample 3', yerr=coolant_sample_stds['Air']), padding=3)

plt.xticks(x, labels)
plt.ylim(bottom=0, top=35)
plt.legend(loc='upper left', ncols=3)
plt.show()

我得到了这张图:

A bar chart with the data grouped incorrectly

如您所见,列的分组不正确。我非常感谢对此的帮助。

python dictionary matplotlib plot bar-chart
1个回答
1
投票

一个简单的选择是使用。虽然处理列表的性能并不理想,但使用

map
:

可以轻松完成此操作
import pandas as pd

df = pd.DataFrame(coolant_data).T

avg = df.map(np.mean)
std = df.map(np.std)

ax = avg.plot.bar()
for c in ax.containers:
    ax.bar_label(c)

输出:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.