欢迎关注我的CSDN:https://spike.blog.csdn.net/
本文地址:https://blog.csdn.net/caroline_wendy/article/details/131061616
重叠柱状图 (Overlapped Bar) 是一种比较图,可以将两个柱状图叠加在一起,显示两个相关变量之间的差异。这种图表适合用于展示实际值和期望值之间的对比,例如实际销售额和目标销售额,实际支出和预算支出等。优点是可以直观地看出两个变量的贡献度和占比,也可以节省空间,避免使用双轴图或并列图。缺点是可能会造成视觉混淆,需要注意颜色和透明度的选择,以及图例和标签的清晰显示。
源码如下:
- 设置plt的尺寸,即
plt.figure(figsize=(10,6))
。 - 循环绘制 bar,即
plt.bar()
。 - 设置下标,即
plt.xticks()
。 - 当水平下标太多,影响排列,则关闭下标,即
plt.xticks([])
。 - df的排序逻辑,即
df.sort_values(by=["ratio"], ascending=True)
。
def overlapped_bar(
high_list, low_list, label_list,
width=0.75, alpha=.5,
title='', xlabel='', ylabel='', figsize=(10, 6),
hide_xsticks=True, show=False, save_name="",
**plot_kwargs
):
"""
绘制重叠条形图
:param high_list: 待处理数据, 数值较大的列表
:param low_list: 待处理数据, 数值较小的列表
:param label_list: 标签列表,默认2个字符串, 例如 ['A', 'B']
:param width: 每个 bin 的宽度
:param alpha: 透明度
:param title: 图表标题
:param xlabel: X 轴标签
:param ylabel: Y 轴标签
:param figsize: 图像尺寸
:param hide_xsticks: 是否隐藏 X 轴的索引,建议数据较多时,隐藏
:param show: 是否显示
:param save_name: 是否存储图像
:param plot_kwargs: 其余参数
:return:
"""
assert len(high_list) == len(low_list) and len(label_list) == 2
df = pd.DataFrame(np.matrix([high_list, low_list]).T, columns=label_list)
plt.figure(figsize=figsize) # 设置plt的尺寸
xlabel = xlabel or df.index.name # 标签
N = len(df) # 类别数
M = len(df.columns) # 列数
indices = np.arange(N)
colors = ['steelblue', 'firebrick', 'darksage', 'goldenrod', 'gray'] * int(M / 5. + 1) # 颜色
for i, label, color in zip(range(M), df.columns, colors):
kwargs = plot_kwargs
kwargs.update({'color': color, 'label': label})
plt.bar(indices, df[label], width=width, alpha=alpha if i else 1, **kwargs)
if not hide_xsticks: # 如果水平坐标太多,隐藏水平坐标
plt.xticks(indices + .5 * width, ['{}'.format(idx) for idx in df.index.values])
plt.legend()
plt.title(title)
plt.xlabel(xlabel)
plt.ylabel(ylabel)
if save_name:
# transparent=True
assert save_name.endswith("png") or save_name.endswith("jpg")
plt.savefig(save_name, bbox_inches='tight', format='png')
if show:
plt.show()
return plt.gcf()
def main():
df = read_excel_to_df(os.path.join(DATA_DIR, "msa_all_counts.xlsx"))
df["ratio"] = df["all_sum"] / df["sum"]
df = df.sort_values(by=["ratio"], ascending=True) # 从小到大排序
df_sum = df["sum"] / df["sum"]
df_all_sum = df["all_sum"] / df["sum"]
avg = round(np.average(df_all_sum), 4)
std = round(float(np.std(df_all_sum)), 4)
print(f"[Info] improve ratio: {avg}±{std}") # 获取比例
low_list = list(df_sum) # 低区数值
high_list = list(df_all_sum) # 高区数值
overlapped_bar(high_list, low_list, label_list=["Ours", "AF2"], xlabel="target", ylabel="times", show=True)
if __name__ == '__main__':
main()