从多索引数据框中进行多次绘图

Posted

技术标签:

【中文标题】从多索引数据框中进行多次绘图【英文标题】:Multiple plotting from multi-index dataframe 【发布时间】:2021-10-11 01:56:59 【问题描述】:

我想通过Step TypTractionStribeck 进行绘图。不同的负载阶段应该有自己的情节。在相应的负载水平下,线图应按温度细分。 y 轴是Traction (-),x 轴是对应的SRR (%)Rolling speed (mm/s)(分别对应TractionStribeck)。最后,我应该有四个不同的情节。

例如,它应该是什么样子:

到目前为止我的尝试,导致一个空的情节。

import pandas as pd
import matplotlib.pyplot as plt

data = 'Step 1': 'Step Typ': 'Traction', 'SRR (%)': 1: 8.384, 2: 9.815, 3: 7.531, 4: 10.209, 5: 7.989, 6: 7.331, 7: 5.008, 8: 2.716, 9: 9.6, 10: 7.911, 'Traction (-)': 1: 5.602, 2: 6.04, 3: 2.631, 4: 2.952, 5: 8.162, 6: 9.312, 7: 4.994, 8: 2.959, 9: 10.075, 10: 5.498, 'Temperature': 30, 'Load': 40, 'Step 3': 'Step Typ': 'Traction', 'SRR (%)': 1: 2.909, 2: 5.552, 3: 5.656, 4: 9.043, 5: 3.424, 6: 7.382, 7: 3.916, 8: 2.665, 9: 4.832, 10: 3.993, 'Traction (-)': 1: 9.158, 2: 6.721, 3: 7.787, 4: 7.491, 5: 8.267, 6: 2.985, 7: 5.882, 8: 3.591, 9: 6.334, 10: 10.43, 'Temperature': 80, 'Load': 40, 'Step 5': 'Step Typ': 'Traction', 'SRR (%)': 1: 4.765, 2: 9.293, 3: 7.608, 4: 7.371, 5: 4.87, 6: 4.832, 7: 6.244, 8: 6.488, 9: 5.04, 10: 2.962, 'Traction (-)': 1: 6.656, 2: 7.872, 3: 8.799, 4: 7.9, 5: 4.22, 6: 6.288, 7: 7.439, 8: 7.77, 9: 5.977, 10: 9.395, 'Temperature': 30, 'Load': 70, 'Step 7': 'Step Typ': 'Traction', 'SRR (%)': 1: 9.46, 2: 2.83, 3: 3.249, 4: 9.273, 5: 8.792, 6: 9.673, 7: 6.784, 8: 3.838, 9: 8.779, 10: 4.82, 'Traction (-)': 1: 5.245, 2: 8.491, 3: 10.088, 4: 9.988, 5: 4.886, 6: 4.168, 7: 8.628, 8: 5.038, 9: 7.712, 10: 3.961, 'Temperature': 80, 'Load': 70, 'Step 2': 'Step Typ': 'Stribeck', 'Rolling Speed (mm/s)': 1: 4.862, 2: 4.71, 3: 4.537, 4: 6.35, 5: 6.691, 6: 5.337, 7: 8.419, 8: 10.303, 9: 5.018, 10: 10.195, 'Traction (-)': 1: 6.674, 2: 10.137, 3: 2.822, 4: 5.494, 5: 9.986, 6: 9.095, 7: 3.53, 8: 6.96, 9: 8.251, 10: 7.836, 'Temperature': 30, 'Load': 40, 'Step 4': 'Step Typ': 'Stribeck', 'Rolling Speed (mm/s)': 1: 4.04, 2: 8.288, 3: 3.731, 4: 10.137, 5: 5.32, 6: 8.504, 7: 5.917, 8: 9.677, 9: 8.641, 10: 7.685, 'Traction (-)': 1: 9.522, 2: 4.749, 3: 3.46, 4: 3.21, 5: 5.005, 6: 9.886, 7: 8.023, 8: 5.935, 9: 8.74, 10: 5.117, 'Temperature': 80, 'Load': 40, 'Step 6': 'Step Typ': 'Stribeck', 'Rolling Speed (mm/s)': 1: 6.244, 2: 7.015, 3: 5.998, 4: 4.894, 5: 6.117, 6: 6.644, 7: 7.619, 8: 10.477, 9: 9.61, 10: 2.958, 'Traction (-)': 1: 7.353, 2: 7.98, 3: 6.675, 4: 8.853, 5: 7.537, 6: 5.256, 7: 4.923, 8: 10.293, 9: 2.873, 10: 10.407, 'Temperature': 30, 'Load': 70, 'Step 8': 'Step Typ': 'Stribeck', 'Rolling Speed (mm/s)': 1: 3.475, 2: 2.756, 3: 7.809, 4: 9.449, 5: 2.72, 6: 4.133, 7: 10.139, 8: 10.0, 9: 3.71, 10: 8.267, 'Traction (-)': 1: 6.307, 2: 2.83, 3: 9.258, 4: 3.405, 5: 9.659, 6: 6.662, 7: 6.413, 8: 6.488, 9: 7.972, 10: 6.288, 'Temperature': 80, 'Load': 70 

df = pd.DataFrame(data)
items = list()
series = list()

for item, d in data.items():
    items.append(item)
    series.append(pd.DataFrame.from_dict(d))

df = pd.concat(series, keys=items)
df.set_index(['Step Typ', 'Load', 'Temperature'], inplace=True)
df.loc[('Stribeck')]
for force, _ in df.groupby(level=1):
    plt.figure(figsize=(15, 12))

    for i, row in df.loc[('Traction'), force].iterrows():
        plt.ylim(0, 0.1)
        plt.ylabel('Traction Coeff (-)')
        plt.xlabel('Rolling Speed (mm/s)')
        plt.title('Title comes later', loc='left')
        plt.plot(row['Rolling Speed (mm/s)'], row['Traction (-)'], label=f"i - force")
    print(f"i - force")
    plt.show()

【问题讨论】:

'Rolling Speed (mm/s)' column is NaN for 'Traction' index 【参考方案1】:

我改变了你的绘图循环。下面的代码将为Traction 生成两个图(每个Load 值一个),其中每个都有两条曲线(每个温度一个)。我已经评论了您设置ylim(a, b) 的行,因为如果数据超出(a, b) 范围,这可能会导致空图。

import pandas as pd
import matplotlib.pyplot as plt

data = 'Step 1': 'Step Typ': 'Traction', 'SRR (%)': 1: 8.384, 2: 9.815, 3: 7.531, 4: 10.209, 5: 7.989, 6: 7.331, 7: 5.008, 8: 2.716, 9: 9.6, 10: 7.911, 'Traction (-)': 1: 5.602, 2: 6.04, 3: 2.631, 4: 2.952, 5: 8.162, 6: 9.312, 7: 4.994, 8: 2.959, 9: 10.075, 10: 5.498, 'Temperature': 30, 'Load': 40, 'Step 3': 'Step Typ': 'Traction', 'SRR (%)': 1: 2.909, 2: 5.552, 3: 5.656, 4: 9.043, 5: 3.424, 6: 7.382, 7: 3.916, 8: 2.665, 9: 4.832, 10: 3.993, 'Traction (-)': 1: 9.158, 2: 6.721, 3: 7.787, 4: 7.491, 5: 8.267, 6: 2.985, 7: 5.882, 8: 3.591, 9: 6.334, 10: 10.43, 'Temperature': 80, 'Load': 40, 'Step 5': 'Step Typ': 'Traction', 'SRR (%)': 1: 4.765, 2: 9.293, 3: 7.608, 4: 7.371, 5: 4.87, 6: 4.832, 7: 6.244, 8: 6.488, 9: 5.04, 10: 2.962, 'Traction (-)': 1: 6.656, 2: 7.872, 3: 8.799, 4: 7.9, 5: 4.22, 6: 6.288, 7: 7.439, 8: 7.77, 9: 5.977, 10: 9.395, 'Temperature': 30, 'Load': 70, 'Step 7': 'Step Typ': 'Traction', 'SRR (%)': 1: 9.46, 2: 2.83, 3: 3.249, 4: 9.273, 5: 8.792, 6: 9.673, 7: 6.784, 8: 3.838, 9: 8.779, 10: 4.82, 'Traction (-)': 1: 5.245, 2: 8.491, 3: 10.088, 4: 9.988, 5: 4.886, 6: 4.168, 7: 8.628, 8: 5.038, 9: 7.712, 10: 3.961, 'Temperature': 80, 'Load': 70, 'Step 2': 'Step Typ': 'Stribeck', 'Rolling Speed (mm/s)': 1: 4.862, 2: 4.71, 3: 4.537, 4: 6.35, 5: 6.691, 6: 5.337, 7: 8.419, 8: 10.303, 9: 5.018, 10: 10.195, 'Traction (-)': 1: 6.674, 2: 10.137, 3: 2.822, 4: 5.494, 5: 9.986, 6: 9.095, 7: 3.53, 8: 6.96, 9: 8.251, 10: 7.836, 'Temperature': 30, 'Load': 40, 'Step 4': 'Step Typ': 'Stribeck', 'Rolling Speed (mm/s)': 1: 4.04, 2: 8.288, 3: 3.731, 4: 10.137, 5: 5.32, 6: 8.504, 7: 5.917, 8: 9.677, 9: 8.641, 10: 7.685, 'Traction (-)': 1: 9.522, 2: 4.749, 3: 3.46, 4: 3.21, 5: 5.005, 6: 9.886, 7: 8.023, 8: 5.935, 9: 8.74, 10: 5.117, 'Temperature': 80, 'Load': 40, 'Step 6': 'Step Typ': 'Stribeck', 'Rolling Speed (mm/s)': 1: 6.244, 2: 7.015, 3: 5.998, 4: 4.894, 5: 6.117, 6: 6.644, 7: 7.619, 8: 10.477, 9: 9.61, 10: 2.958, 'Traction (-)': 1: 7.353, 2: 7.98, 3: 6.675, 4: 8.853, 5: 7.537, 6: 5.256, 7: 4.923, 8: 10.293, 9: 2.873, 10: 10.407, 'Temperature': 30, 'Load': 70, 'Step 8': 'Step Typ': 'Stribeck', 'Rolling Speed (mm/s)': 1: 3.475, 2: 2.756, 3: 7.809, 4: 9.449, 5: 2.72, 6: 4.133, 7: 10.139, 8: 10.0, 9: 3.71, 10: 8.267, 'Traction (-)': 1: 6.307, 2: 2.83, 3: 9.258, 4: 3.405, 5: 9.659, 6: 6.662, 7: 6.413, 8: 6.488, 9: 7.972, 10: 6.288, 'Temperature': 80, 'Load': 70 

df = pd.DataFrame(data)
items = list()
series = list()


for item, d in data.items():
    items.append(item)
    series.append(pd.DataFrame.from_dict(d))

df = pd.concat(series, keys=items)
df.set_index(['Step Typ', 'Load', 'Temperature'], inplace=True)

for force, _ in df.groupby(level=1):
    fig, ax = plt.subplots(figsize=(8, 6))


    df_step = df.loc[('Traction'), force]
    for temperature in df_step.index.unique():
        df_temp = df_step.loc[temperature].sort_values('SRR (%)')
        # ax.set_ylim(0, 0.1)
        ax.set_ylabel('Traction Coeff (-)')
        ax.set_xlabel('SRR (%)')
        ax.set_title('Title comes later', loc='left')
        ax.plot(df_temp['SRR (%)'], df_temp['Traction (-)'], label = f'T = df_temp.index.unique().values[0]°C - Load = force')

    ax.legend(frameon = True)

    plt.show()

【讨论】:

有时你真的只见树木不见森林。非常感谢!

以上是关于从多索引数据框中进行多次绘图的主要内容,如果未能解决你的问题,请参考以下文章

Python,pandas:如何从对称的多索引数据框中提取值

如何从python中的数据框中删除多索引?

基于多索引列数据框中的列范围进行切片

在保持二级索引完整的同时对多索引数据框中的行进行排序

如何使用单个索引更新多索引数据框中的记录

如何从多索引中提取总年份行和列以在绘图中创建直方图