簡體   English   中英

如何在同一個圖上對多個字典進行箱線圖

[英]How to boxplot multiple dictionaries on the same plot

對於變化點檢測任務,我正在根據基線測試我自己的算法,並且我想將兩種算法的結果繪制在同一個箱線圖上。

我的結果(F 分數值)存儲在字典中,其中鍵是兩個參數ab (都有 4 個不同的值):

resultsOwnAlgorithm = {'a1, b1': [0.8, 0.7, 0.6, ...], 'a1, b2': [...], ..., 'a2, b1': [...], ...}
resultsBaseline = {'a1, b1': [0.7, 0.6, ...], 'a1, b2': [...], ..., 'a2, b1': [...], ...}

現在,我有一個單獨繪制它們的功能。 我創建了 4 個子圖,其中設置a並且b正在更改,請參見圖像(值是隨機的,只是為了創建示例圖像)。 該函數如下所示:

def plotResults(results, keys, test):
    
    fig, axs = plt.subplots(2,2,figsize=(10,10))
    for ax in axs.flat:
        ax.set_ylim(0,1)
        ax.set_xticks(range(len(abrs)))
        ax.set_xticklabels(abrs)
    
    count = 0
    for i in (0,1):
        for j in (0,1):
            axs[i,j].set_title(str(test) + ', mean shift: ' + str(keys[count][0][0:2]).strip('x,') + ', iters=' + str(iterations), fontweight ="bold")
            l = keys[count]
            k = {k:results[k] for k in l if k in results}
            label, data = k.keys(), k.values()
            axs[i,j].boxplot(data,showfliers=False,patch_artist=True)
            axs[i,j].set_xticks(range(1, len(label) + 1))
            axs[i,j].set_xticklabels(label)
            count+=1

其中resultsresultsOwnAlgorithmresultsBaselinekeys是字典鍵,因此ab的不同組合和test僅用於將正在繪制的算法放在標題中。

我的問題是:我如何在同一個情節上並排繪制它們?

看圖片

您的繪圖功能中有一些錯誤,所以我可以在不做很大假設的情況下讓它工作,比如abrs是什么以及iterations是什么。 你應該在繼續你的工作之前修復它們,因為這個函數很可能從全局范圍(假設是一個 jupyter notebook)中獲取它們,這導致稍后出現錯誤,正如我以前痛苦地經歷過的那樣。

無論如何,您的問題可以首先通過調整您的代碼以使用 seaborn 來解決。 檢查此處的示例, “通過兩個分類變量繪制具有嵌套分組的箱線圖”

可以更輕松地修改以適合您的用例的方法是:生成一組將與每個箱線圖組關聯的x值。 然后,根據您要放置此箱線圖的位置,向左或向右添加偏移。 然后你必須修復蜱蟲等等,但你已經知道如何去做了。 這是一個盡可能多地維護您的結構的示例。

import matplotlib.pyplot as plt
import numpy as np

np.random.seed(42)
resultsOwnAlgorithm = {'a1, b1': np.random.normal(scale=2, size=20), 'a2, b2': np.random.normal(scale=1.5, size=20)}
resultsBaseline = {'a1, b1': np.random.normal(scale=2, size=20), 'a2, b2': np.random.normal(scale=1.5, size=20)}
x_vals = np.arange(0, len(resultsOwnAlgorithm))
xs = {key:val for key, val in zip(resultsOwnAlgorithm.keys(), x_vals)}
shift = 0.1

fig, ax = plt.subplots()
for key in resultsOwnAlgorithm.keys():
    ax.boxplot(resultsOwnAlgorithm[key], positions=[xs[key] - shift], boxprops=dict(color='r'))
    ax.boxplot(resultsBaseline[key], positions=[xs[key] + shift], boxprops=dict(color='b'))

ax.set_xticks(x_vals)
ax.set_xticklabels(resultsOwnAlgorithm.keys())

這會產生以下圖表: 在此處輸入圖像描述

  • 最簡單的解決方案可能是將所有字典組合成一個pands.DataFrame 這將使數據易於分析和繪圖。
    1. 遍歷字典列表,壓縮成一個字符串,用於識別數據的來源。
    2. 創建數據框。
    3. 添加一個新列來標識數據。
    4. 將數據框附加到列表中。
    5. 將 DataFrame 列表與pd.concat結合,並重置索引。
    6. 使用pd.DataFrame.melt將 DataFrame 重塑為長形
  • Seaborn是 matplotlib 的高級 api,可以輕松繪制長格式數據並通過hue參數分隔組。
  • python 3.10pandas 1.4.2matplotlib 3.5.1seaborn 0.11.2
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt

# create sample dictionaries
np.random.seed(2022)
custom = {f'a{v}, b{v}': np.random.normal(scale=v, size=100) for v in range(1, 5)}
baseline = {f'a{i}, b{i}': np.random.normal(scale=v, size=100) for i, v in enumerate(np.arange(1.5, 5.5), 1)}

# create and shape dataframe
dfs = list()
for d, _id in zip([resultsBaseline, resultsOwnAlgorithm], ['baseline', 'custom']):
    df = pd.DataFrame(d)
    df['Algorithm'] = _id
    dfs.append(df)
dfs = pd.concat(dfs).reset_index(drop=True)
dfm = dfs.melt(id_vars='Algorithm', var_name='Parameters', value_name='Score')

# plot
g = sns.catplot(kind='box', data=dfm, x='Parameters', y='Score', hue='Algorithm', height=6, aspect=2)
plt.show

在此處輸入圖像描述

數據框視圖

  • dfs.head()
     a1, b1    a2, b2    a3, b3    a4, b4 Algorithm
0  0.834463 -1.092923  4.875117 -4.946214  baseline
1  1.338891  0.225008 -0.305499  0.570333  baseline
2  0.261615  2.128844  2.194177  0.494803  baseline
3  0.273740 -2.395624 -3.495572  0.006312  baseline
4 -0.997368  0.984808 -3.956302  0.206667  baseline
  • dfm.head()
  Algorithm Parameters     Score
0  baseline     a1, b1  0.834463
1  baseline     a1, b1  1.338891
2  baseline     a1, b1  0.261615
3  baseline     a1, b1  0.273740
4  baseline     a1, b1 -0.997368

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM