如何基于Groupby结果为每个$etf_asset_class分组绘制直方图?
按ETF资产类别绘制等级计数直方图的实现方法
首先明确:由于ETF_Quintiled_Grades是1-5的离散等级,用柱状图替代直方图更贴合数据类型(直方图多用于连续数据分布),以下提供两种实现方案,基于pandas、matplotlib和seaborn库。
先构造示例数据(匹配你的数据结构)
假设你的DataFrame经过groupby和计数后结构如下,先构造模拟数据方便测试:
import pandas as pd import numpy as np data = { '$etf_asset_class': np.repeat(['股票', '债券', '商品'], 5), 'ETF_Quintiled_Grades': np.tile([1,2,3,4,5], 3), 'Counts': np.random.randint(10, 100, 15) } df = pd.DataFrame(data) # 如果你的groupby结果是多级索引,先重置索引: # df = df.reset_index()
方案1:Matplotlib手动循环绘制
适合需要精细控制每个子图样式的场景:
import matplotlib.pyplot as plt # 获取所有唯一的资产类别 asset_classes = df['$etf_asset_class'].unique() # 计算子图布局,这里按2列排列 row_num = (len(asset_classes) + 1) // 2 fig, axes = plt.subplots(row_num, 2, figsize=(12, 8)) axes = axes.flatten() # 扁平化子图数组,方便遍历 for idx, asset in enumerate(asset_classes): # 筛选当前资产类别的数据 subset = df[df['$etf_asset_class'] == asset] # 绘制柱状图 axes[idx].bar(subset['ETF_Quintiled_Grades'], subset['Counts'], color='skyblue') # 设置子图属性 axes[idx].set_title(f'资产类别:{asset}') axes[idx].set_xlabel('ETF等级(1-5)') axes[idx].set_ylabel('计数') axes[idx].set_xticks([1,2,3,4,5]) # 固定x轴刻度为1-5 # 隐藏多余的空图(如果类别数为奇数) for j in range(idx + 1, len(axes)): axes[j].axis('off') plt.tight_layout() plt.show()
方案2:Seaborn FacetGrid快速分面绘制
代码更简洁,适合快速生成标准化的分面图:
import seaborn as sns # 按资产类别分面,每行2个图 g = sns.FacetGrid(df, col='$etf_asset_class', col_wrap=2, height=4) # 映射柱状图,指定等级顺序避免乱序 g.map(sns.barplot, 'ETF_Quintiled_Grades', 'Counts', order=[1,2,3,4,5], palette='viridis') # 设置统一的轴标签和子图标题 g.set_axis_labels('ETF等级(1-5)', '计数') g.set_titles('资产类别:{col_name}') plt.tight_layout() plt.show()
注意事项
- 如果你的
groupby结果是多级索引($etf_asset_class和ETF_Quintiled_Grades是索引),必须先执行df = df.reset_index()将索引转为列,否则无法直接通过列名筛选数据 - 可根据需求调整颜色方案、子图大小、标题字体等样式参数
内容的提问来源于stack exchange,提问作者Zachary Marx
相关产品推荐
相关产品推荐

