如何基于Pandas DataFrame动态生成Matplotlib子图?
解决方案
核心思路
先提取过滤后数据的唯一item和city列表,循环每个item对应的子图,筛选对应数据后将城市映射为y轴索引,再绘制散点。
完整代码
import matplotlib.pyplot as plt import pandas as pd import numpy as np # 1. 导入并整理数据 df = pd.read_csv(r'C:\Users\Ruth Pozuelo\Documents\python_examples\data\2018w48.csv', usecols=["city", "category","item", "cost"], index_col=False, decimal=",") # 2. Power BI动态过滤(示例用固定值,实际替换为Power BI的过滤逻辑) df = df[df.category=='Party night'] # 3. 准备基础信息 unique_items = df['item'].unique() # 获取所有要展示的item item_count = len(unique_items) unique_cities = df['city'].unique() # 统一y轴的城市列表 city_y_pos = np.arange(len(unique_cities)) # 城市对应的y轴位置索引 # 4. 创建子图框架 fig, axes = plt.subplots(nrows=1, ncols=item_count, figsize=(30,10), sharey=True) # 5. 循环绘制每个子图 for idx, (item, ax) in enumerate(zip(unique_items, axes.flatten())): # 筛选当前item的数据 item_data = df[df['item'] == item] # 将城市匹配到对应的y轴位置 y_pos = [np.where(unique_cities == city)[0][0] for city in item_data['city']] # 绘制散点(plot设置lw=0等同于散点) ax.plot(item_data['cost'], y_pos, marker='o', markersize=25, lw=0, color="green") # 设置子图标题 ax.set_title(item, fontsize=14) # 设置x轴标签 ax.set_xlabel('Cost', fontsize=12) # 统一设置y轴标签和刻度 fig.text(0.06, 0.5, 'City', va='center', rotation='vertical', fontsize=14) axes[0].set_yticks(city_y_pos) axes[0].set_yticklabels(unique_cities) # 调整布局,避免标题重叠 plt.tight_layout() plt.subplots_adjust(left=0.08) # 给y轴标签留出空间 plt.show()
关键说明
- 用
unique_items和axes.flatten()配对循环,确保每个子图对应一个item - 用
unique_cities统一y轴刻度,保证所有子图的城市顺序一致(sharey=True生效) - 将城市名称转换为y轴索引位置,解决分类数据的绘图定位问题
- 最后通过
tight_layout和subplots_adjust优化布局,避免标签重叠
内容的提问来源于stack exchange,提问作者ruthpozuelo
相关产品推荐
相关产品推荐

