如何将pandas分组键名设置为matplotlib对应子图标题
问题描述
已完成指定文件夹内所有CSV文件读取,实现数据合并、Gradient字段计算、日期格式转换等预处理操作后,按Beacon列对DataFrame进行分组,在同一画布的4行7列子图网格中绘制了所有分组的时序曲线,目前子图均未设置标题,需要将每个分组对应的Beacon键名设置为对应子图的标题。
DataFrame结构
Beacon Average Gradient Date 2017-06-10 A18 4.5566 1.11280 2017-06-10 B18 5.6694 -0.41125 2017-06-15 A18 4.5528 1.11350 2017-06-15 B18 5.6663 -0.41105 2017-06-15 C17 3.7307 -0.72965 ... ... ... 2017-08-16 SB01 3.8360 -0.10900 2017-08-16 SB02 3.7130 -0.13750 2017-08-16 SB03 3.5610 0.13300 2017-08-16 SB04 3.9790 0.08100 2017-08-16 SB05 3.7230 -0.25600
原有实现代码
import matplotlib.pyplot as plt import pandas as pd import glob import os import numpy as np ## chose directory path =r'C:\soc3\data\sb_measurements' globbed = glob.glob(path + "/*.csv") data = [] ## Select and modify all CSV files in directory for csv in globbed: df = pd.read_csv(csv, header=0, skiprows=(0), delimiter = ',', names = ['Beacon', 'Go', 'Return', 'Average']) df['Filename'] = os.path.basename(csv) data.append(df) for index in data: index['Gradient'] = (np.gradient(index['Average'])) df = pd.concat(data, axis=0, ignore_index=True) df = df.loc[:, df.columns.intersection(['Beacon', 'Average','Filename','Gradient'])] df = df.dropna() df = df.replace('.csv','', regex=True) df['Filename'] = df['Filename'].replace('SB','20', regex=True) df['Filename'] = df['Filename'].astype('|S') df['Filename'] = pd.to_datetime(df['Filename'], format='%Y%m%d') df.rename(columns = {'Filename':'Date'}, inplace = True) df.set_index('Date', inplace=True) counted_sets = df['Beacon'].nunique() df = df.dropna() grouped = df.groupby('Beacon') ncols= 7 nrows = 4 fig, axes = plt.subplots(nrows=nrows, ncols=ncols, figsize = (90,30) , constrained_layout = True) for (key, ax) in zip(grouped.groups.keys(), axes.flatten()): grouped.get_group(key).plot(ax=ax) # ============================================================================= # plt.savefig("output.jpg") # ============================================================================= ax.legend() plt.show() print(df)
当前绘图效果

解决方案
核心修改点是在遍历子图绘图的循环中,调用ax.set_title()方法将当前分组的Beacon键名设置为子图标题,修改后的循环代码如下:
for (key, ax) in zip(grouped.groups.keys(), axes.flatten()): grouped.get_group(key).plot(ax=ax) ax.set_title(key) # 新增该行,设置子图标题为当前Beacon分组名
可选优化项:
- 若Beacon分组总数小于28(4行*7列),可添加代码隐藏未使用的空白子图,避免画布出现空窗:
# 隐藏无数据的空白子图 group_count = len(grouped.groups.keys()) for idx, ax in enumerate(axes.flatten()): if idx >= group_count: ax.axis('off')
- 原代码中
ax.legend()仅会为最后一个子图添加图例,若需要每个子图显示对应图例,可将图例设置代码移入循环内;若不需要全局重复图例,可在plot方法中传入legend=False参数关闭图例。
内容的提问来源于stack exchange,提问作者SimonDL
相关产品推荐
相关产品推荐

