如何点击堆叠条形图区块打印对应数据集子集?
解决堆叠条形图点击区块筛选对应数据集子集的问题
核心思路是给每个子图的堆叠元素绑定对应的筛选规则,在mplcursors的回调里区分点击的子图和堆叠层,再结合x轴标签筛选原始数据。
实现步骤与代码示例
- 先准备示例数据并绘制两个堆叠条形子图,同时保存每个子图的x轴标签、堆叠层对象及对应类别:
import pandas as pd import matplotlib.pyplot as plt import mplcursors # 构造示例数据集 data = pd.DataFrame({ 'month': ['January', 'January', 'February', 'February', 'March', 'March'], 'year': [2022, 2023, 2022, 2023, 2022, 2023], 'problem_code': ['A', 'B', 'A', 'B', 'A', 'B'], 'count': [10, 15, 8, 12, 5, 9] }) # 创建双列子图 fig, (ax_month, ax_year) = plt.subplots(1, 2, figsize=(12, 6)) # ---------------------- 第一个子图:月份-问题代码堆叠图 ---------------------- month_pivot = data.pivot(index='month', columns='problem_code', values='count').fillna(0) month_x_labels = month_pivot.index # 绘制各堆叠层并保存bars对象 bars_month_A = ax_month.bar(month_x_labels, month_pivot['A'], label='Problem A') bottom = month_pivot['A'] bars_month_B = ax_month.bar(month_x_labels, month_pivot['B'], bottom=bottom, label='Problem B') ax_month.set_title('Month vs Problem Code') ax_month.legend() # ---------------------- 第二个子图:年份-问题代码堆叠图 ---------------------- year_pivot = data.pivot(index='year', columns='problem_code', values='count').fillna(0) year_x_labels = year_pivot.index bars_year_A = ax_year.bar(year_x_labels, year_pivot['A'], label='Problem A') bottom = year_pivot['A'] bars_year_B = ax_year.bar(year_x_labels, year_pivot['B'], bottom=bottom, label='Problem B') ax_year.set_title('Year vs Problem Code') ax_year.legend()
- 定义回调函数,通过
sel.artist.axes区分子图,sel.artist判断堆叠层,sel.target.index获取x轴索引,最终筛选数据:
# 用字典存储子图对应的筛选信息,方便扩展 plot_configs = { ax_month: { 'x_labels': month_x_labels, 'bar_to_category': {bars_month_A: 'A', bars_month_B: 'B'}, 'filter_column': 'month' }, ax_year: { 'x_labels': year_x_labels, 'bar_to_category': {bars_year_A: 'A', bars_year_B: 'B'}, 'filter_column': 'year' } } def handle_click(sel): current_ax = sel.artist.axes config = plot_configs.get(current_ax) if not config: return # 获取x轴对应的筛选值 x_index = sel.target.index filter_value = config['x_labels'][x_index] # 获取堆叠层对应的问题代码 problem_code = config['bar_to_category'][sel.artist] # 筛选原始数据集 subset = data[(data[config['filter_column']] == filter_value) & (data['problem_code'] == problem_code)] print("\n=== 选中的数据集子集 ===") print(subset) # 绑定所有堆叠条到光标,关闭hover仅响应点击 cursor = mplcursors.cursor([bars_month_A, bars_month_B, bars_year_A, bars_year_B], hover=False) cursor.connect("add", handle_click) plt.tight_layout() plt.show()
关键说明
- 每个子图的堆叠层对象(
bars_month_A等)和对应的类别、筛选字段都存在plot_configs字典中,避免硬编码判断,方便后续添加更多堆叠层或子图。 - 通过
sel.artist直接定位点击的堆叠条,结合sel.target.index拿到x轴的位置,就能准确匹配到原始数据的筛选条件。 - 关闭
hover模式确保只有点击时才触发筛选,避免误操作。
内容的提问来源于stack exchange,提问作者Warehouse_Worker
相关产品推荐
相关产品推荐

