[英]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.