我有以下代码来绘制箱线图并将所有数据点覆盖在条形图上。
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy.random as rnd
f = plt.figure(figsize=[18,12])
ax = f.add_subplot(111)
sns.boxplot(x='month', y='ffdi', hue='scenario', data=df_diff_concat, ax=ax)
sns.stripplot(x="month", y="ffdi",hue='scenario', data=df_diff_concat, ax=ax)
数据点未与其所属条形的中线垂直对齐。
如何解决这个问题?
dodge=True
中使用
seaborn.stripplot
,否则这些值将绘制为以 x 刻度为中心的单个组kind='bar'
可以替换为 kind='box'
python 3.8.11
、matplotlib 3.4.3
、seaborn 0.11.2
import seaborn as sns
# load the dataframe
tips = sns.load_dataset('tips')
ax = sns.boxplot(x="day", y="total_bill", hue="smoker", data=tips, palette="GnBu")
# add stripplot with dodge=True
sns.stripplot(x="day", y="total_bill", hue="smoker", data=tips, palette="GnBu", dodge=True, ax=ax, ec='k', linewidth=1)
# remove extra legend handles
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[:2], labels[:2], title='Smoker', bbox_to_anchor=(1, 1.02), loc='upper left')
jitter=False
,但当有重叠时,所有数据点都不会显示。ax = sns.boxplot(x="day", y="total_bill", hue="smoker", data=tips, palette="GnBu")
# add stripplot with dodge=True
sns.stripplot(x="day", y="total_bill", hue="smoker", data=tips, palette="GnBu",
dodge=True, ax=ax, ec='k', linewidth=1, jitter=False)
# remove extra legend handles
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[:2], labels[:2], title='Smoker', bbox_to_anchor=(1, 1.02), loc='upper left')
seaborn.swarmplot
,与 stripplot()
类似,但点会被调整(仅沿着分类轴),以便它们不会重叠。ax = sns.boxplot(x="day", y="total_bill", hue="smoker", data=tips, palette="GnBu")
# add stripplot with dodge=True
sns.swarmplot(x="day", y="total_bill", hue="smoker", data=tips, palette="GnBu",
dodge=True, ax=ax, ec='k', linewidth=1, size=3)
# remove extra legend handles
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[:2], labels[:2], title='Smoker', bbox_to_anchor=(1, 1.02), loc='upper left')
同意特伦顿的解决方案,但我想指出的一件事是,如果你的箱线图使用你自己的宽度,那么箱线图和条形图之间的对齐将需要比简单地使用更多的调整
dodge = True