【问题标题】:Seaborn plot list of values vs. their indexesSeaborn 绘制值列表与其索引
【发布时间】:2021-03-21 00:58:01
【问题描述】:

我正在尝试利用 seaborn 绘制线图的潜力,但似乎我不断收到错误“TypeError: unhashable type:'list'”,我知道数据框值存在问题准确度是列表,虽然我不知道如何根据索引正确绘制列表(我也将其放入名为“Accuracy_Indexes”的列表中)。基本上,我只是想在 X 轴上打印每个“精度”,在 Y 轴上打印它们的索引,色调为“Bin”。所以它是 X 和 Y 轴大小相同的两个列表。不确定 Catplot 是否是获得诸如线图之类的正确图,但我收到警告说它已经过时并且将来会被删除。

import pandas as pd
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt

N=7
Accuracy_Indexes = list(range(1, 5))
df = pd.DataFrame({'Bin': np.random.randint(1,10,N)})
TheList = []
for item in range(N):
    TheList.append([item+1, np.random.random_sample(size=len(Accuracy_Indexes)).tolist()])
print(TheList)

df = pd.DataFrame.from_records(TheList,columns=['Bin','Accuracies'])
print(df)

g = sns.catplot(x=Accuracy_Indexes, y='Accuracies', hue="Bin",
                data=df, height=5, aspect=.8)
plt.show()

感谢您的建议。

【问题讨论】:

    标签: python-3.x list plot seaborn


    【解决方案1】:

    Pandas 的explode() 可用于将列表转换为单独的行。以相同的顺序平铺Accuracy_Indexes 可以使用这些索引创建一个新列。

    这里有一些示例代码来说明这个想法:

    import pandas as pd
    import seaborn as sns
    import numpy as np
    import matplotlib.pyplot as plt
    
    N = 7
    Accuracy_Indexes = list(range(1, 5))
    df = pd.DataFrame({'Bin': np.random.randint(1, 10, N)})
    TheList = []
    for item in range(N):
        TheList.append([item + 1, np.random.random_sample(size=len(Accuracy_Indexes)).tolist()])
    
    df = pd.DataFrame.from_records(TheList, columns=['Bin', 'Accuracies'])
    
    df_long = df.explode('Accuracies', ignore_index=True)
    df_long['Accuracy_Indexes'] = np.tile(Accuracy_Indexes, len(df))
    df_long['Accuracies'] = df_long['Accuracies'].astype(float)
    
    g = sns.catplot(x='Accuracy_Indexes', y='Accuracies', hue="Bin",
                    data=df_long, height=5, aspect=.8)
    plt.tight_layout()
    plt.show()
    

    从同一个数据框,你也可以通过

    创建一个线图
    g = sns.relplot(x='Accuracy_Indexes', y='Accuracies', hue="Bin",
                    data=df_long, height=5, aspect=.8, kind='line')
    

    请注意 relplotcatplot"figure-level functions" 一次创建一个完整的“图形”,带有一个或多个子图。如果要创建单个子图,可以使用轴级函数lineplot。控制图形大小的方法有点不同。

    from matplotlib.ticker import MaxNLocator
    
    plt.figure(figsize=(4, 5))
    ax = sns.lineplot(x='Accuracy_Indexes', y='Accuracies', hue="Bin", data=df_long)
    ax.xaxis.set_major_locator(MaxNLocator(integer=True))
    

    【讨论】:

    • 谢谢!我现在意识到,如果我想获得连接索引的线,我可能需要 relplot 或类似的东西,例如对于 Bin 1,点 1 的 Accuracy_indexes 应该连接到点 2,点 3 到点 4。我试过:sns.relplot(data=df_long, x='Accuracy_Indexes', y='Accuracies', hue=" Bin", kind="line") 但这会引发“没有数字类型来聚合错误”。知道如何获得连接点吗?
    • 我尝试使用您提供的示例代码,但无法创建第二个图形,lineplot 和 relplot 似乎都不起作用 - 尽管两者都给出错误:“pandas.core.base.DataError: No numeric要聚合的类型”。猫图虽然有效。
    • 好的。更多测试表明explode 创建了object 类型的列,而我们需要一个数字类型。根据确切的 seaborn 和 pandas 版本,自动转换为数字。最好的是显式转换:df_long['Accuracies'] = df_long['Accuracies'].astype(float)。你能检查一下这是否适合你吗?
    • 成功了!感谢您花时间帮助我完成这一切。
    猜你喜欢
    • 1970-01-01
    • 2019-10-23
    • 2020-04-05
    • 2018-03-29
    • 1970-01-01
    • 2020-09-19
    • 2015-10-24
    • 1970-01-01
    • 2018-05-13
    相关资源
    最近更新 更多