[英]How to boxplot multiple dictionaries on the same plot
對於變化點檢測任務,我正在根據基線測試我自己的算法,並且我想將兩種算法的結果繪制在同一個箱線圖上。
我的結果(F 分數值)存儲在字典中,其中鍵是兩個參數a
和b
(都有 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
其中results
是resultsOwnAlgorithm
或resultsBaseline
, keys
是字典鍵,因此a
和b
的不同組合和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
。 這將使數據易於分析和繪圖。
pd.concat
結合,並重置索引。pd.DataFrame.melt
將 DataFrame 重塑為長形hue
參數分隔組。
kind='box'
的圖形級繪圖sns.catplot
,或使用軸級繪圖sns.boxplot
。matplotlib.axes.Axes.boxplot
更容易擴展,其中每個額外的箱線圖組必須指定positions=
。python 3.10
、 pandas 1.4.2
、 matplotlib 3.5.1
、 seaborn 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.