Python同图绘制双直方图:添加Y2轴区间点击占比图的方法
实现双Y轴直方图:总用户占比 + 各区间点击用户占比
步骤说明
要在同一张图上添加显示每个区间点击用户占比的第二Y轴,需要完成两个核心任务:计算每个区间的点击用户百分比,以及创建双Y轴并绘制对应的图表。
完整代码示例
import pandas as pd import numpy as np import matplotlib.pyplot as plt from matplotlib.ticker import PercentFormatter # 创建示例数据集 sample_df = pd.DataFrame({ 'user_id': np.arange(0, 1000), 'sent_click_diff': np.random.randint(400, size=1000), 'clicked_or_not': np.random.choice(['clicked', 'not clicked'], 1000), }) # 设置区间步长和X轴区间 stepsize = 10 x_axis_values = np.arange(1, 400, stepsize) # 创建画布和第一个坐标轴(总用户占比) fig, ax1 = plt.subplots(figsize=(10, 6)) # 绘制总用户占比直方图 n, bins, patches = ax1.hist( sample_df['sent_click_diff'], weights=np.ones(len(sample_df)) / len(sample_df), # 转换为占比(0-1) bins=x_axis_values, color='skyblue', alpha=0.6, label='% 总用户' ) # 格式化Y1轴为百分比 ax1.yaxis.set_major_formatter(PercentFormatter(1)) ax1.set_xlim(1, 400) ax1.set_title('距上次点击天数分布 & 点击用户占比') ax1.set_xlabel('距上次点击天数') ax1.set_ylabel('% 总用户') ax1.legend(loc='upper left') # 创建第二个Y轴(点击用户占比) ax2 = ax1.twinx() # 为每条数据分配对应的区间 sample_df['bin'] = pd.cut(sample_df['sent_click_diff'], bins=bins) # 计算每个区间的总用户数、点击用户数及点击占比 clicked_stats = sample_df.groupby('bin').agg( 总用户数=('user_id', 'count'), 点击用户数=('clicked_or_not', lambda x: (x == 'clicked').sum()) ).reset_index() # 计算点击占比(避免除以零,过滤空区间) clicked_stats = clicked_stats[clicked_stats['总用户数'] > 0] clicked_stats['点击占比'] = (clicked_stats['点击用户数'] / clicked_stats['总用户数']) * 100 # 获取区间中点用于对齐绘图 bin_midpoints = (bins[:-1] + bins[1:]) / 2 # 绘制点击用户占比柱状图(可替换为ax2.plot改为折线图) ax2.bar( bin_midpoints, clicked_stats['点击占比'], width=stepsize * 0.8, color='orange', alpha=0.5, label='% 点击用户' ) # 格式化Y2轴为百分比 ax2.yaxis.set_major_formatter(PercentFormatter()) ax2.set_ylabel('% 点击用户') ax2.legend(loc='upper right') # 调整布局避免标签重叠 plt.tight_layout() plt.show()
关键部分解释
计算点击用户占比
- 使用
pd.cut将sent_click_diff划分到与直方图一致的区间中 - 通过分组聚合计算每个区间的总用户数和点击用户数
- 点击占比公式:
(点击用户数 / 区间总用户数) * 100,同时过滤掉无用户的区间避免错误
- 使用
双Y轴实现
- 使用
ax1.twinx()创建与X轴共享的第二个Y轴 - 用区间中点作为X坐标,确保点击占比的柱状图与原直方图区间对齐
- 分别设置两个Y轴的标签、格式化方式和图例位置,避免视觉冲突
- 使用
自定义选项
- 若偏好折线图展示点击占比,可将
ax2.bar替换为ax2.plot(bin_midpoints, clicked_stats['点击占比'], color='red', marker='o', label='% 点击用户') - 可调整
alpha参数控制图表透明度,提升叠加后的可读性
- 若偏好折线图展示点击占比,可将
内容的提问来源于stack exchange,提问作者Patthebug
相关产品推荐
相关产品推荐

