如何用Python自定义函数从宽格式DataFrame生成多子图并导出图表
完整可运行实现代码
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt from matplotlib.backends.backend_pdf import PdfPages # 示例数据集 df= { 'Gen':['M','M','M','M','F','F','F','F','M','M','M','M','F','F','F','F'], 'Site':['FRX','FRX','FRX','FRX','FRX','FRX','FRX','FRX','FRX','FRX','FRX','FRX','FRX','FRX','FRX','FRX'], 'Type':['L','L','L','L','L','L','L','L','R','R','R','R','R','R','R','R'], 'UID':[1001,1002,1003,1004,1001,1002,1003,1004,1001,1002,1003,1004,1001,1002,1003,1004], 'Time1':[100.78,112.34,108.52,139.19,149.02,177.77,79.18,89.10,106.78,102.34,128.52,119.19,129.02,147.77,169.18,170.11], 'Time2':[150.78,162.34,188.53,197.69,208.07,217.76,229.48,139.51,146.87,182.54,189.57,199.97,229.28,244.73,269.91,249.19], 'Time3':[250.78,262.34,288.53,297.69,308.07,317.7,329.81,339.15,346.87,382.54,369.59,399.97,329.28,347.73,369.91,349.12], 'Time4':[240.18,232.14,258.53,276.69,338.07,307.74,359.16,339.25,365.87,392.48,399.97,410.75,429.08,448.39,465.15,469.33], 'Time5':[270.84,282.14,298.53,306.69,318.73,327.47,369.63,389.59,398.75,432.18,449.78,473.55,494.85,509.39,515.52,539.23] } df = pd.DataFrame(df,columns = ['Gen','Site','Type','UID','Time1','Time2','Time3','Time4','Time5']) def graph2pdf(inputdata, export_type='pdf', export_path='turbidity_result', dpi=300, transparent=False): # 宽表转长表,保留所有需要的维度字段 df_long = pd.melt(inputdata, id_vars=['Gen', 'Type', 'UID', 'Site'], var_name='Time_str', value_name='Turbidity') # 提取时间数值,将X轴转为连续数值格式 df_long['Time'] = df_long['Time_str'].str.extract('(\d+)').astype(int) # 拼接生成图例标签 df_long['group'] = df_long['Gen'] + '+' + df_long['Type'] # 获取所有唯一UID uids = df_long['UID'].unique() # 配置白色基础样式 sns.set_style("whitegrid") # 导出PDF逻辑 if export_type == 'pdf': with PdfPages(f'{export_path}.pdf') as pdf: # 每页2行2列,固定放4张图 fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(12, 10), facecolor='white' if not transparent else 'none') axes = axes.flatten() for idx, uid in enumerate(uids): ax = axes[idx] # 筛选当前UID对应的数据 uid_data = df_long[df_long['UID'] == uid] # 绘制折线图,每个分组对应一条曲线 sns.lineplot(data=uid_data, x='Time', y='Turbidity', hue='group', marker='o', ax=ax) # 自动获取对应Site值生成标题 site = uid_data['Site'].iloc[0] ax.set_title(f'UID:{uid} + Site:{site}', fontsize=12) # 设置坐标轴标签 ax.set_xlabel('Time', fontsize=10) ax.set_ylabel('Turbidity', fontsize=10) # 调整图例位置 ax.legend(loc='upper left', title='Group') # 调整子图间距避免重叠 plt.tight_layout() # 保存到PDF pdf.savefig(fig, dpi=dpi, facecolor='white' if not transparent else 'none') plt.close() # 导出图片格式逻辑 else: fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(12, 10), facecolor='white' if not transparent else 'none') axes = axes.flatten() for idx, uid in enumerate(uids): ax = axes[idx] uid_data = df_long[df_long['UID'] == uid] sns.lineplot(data=uid_data, x='Time', y='Turbidity', hue='group', marker='o', ax=ax) site = uid_data['Site'].iloc[0] ax.set_title(f'UID:{uid} + Site:{site}', fontsize=12) ax.set_xlabel('Time', fontsize=10) ax.set_ylabel('Turbidity', fontsize=10) ax.legend(loc='upper left', title='Group') plt.tight_layout() plt.savefig(f'{export_path}.{export_type}', dpi=dpi, facecolor='white' if not transparent else 'none') plt.close() # 测试调用,可根据需要修改参数 # 导出PDF graph2pdf(df, export_type='pdf', export_path='turbidity_result', transparent=False) # 导出JPEG # graph2pdf(df, export_type='jpeg', export_path='turbidity_result', dpi=300) # 导出TIFF # graph2pdf(df, export_type='tiff', export_path='turbidity_result', dpi=300)
参数说明
export_type:支持传入pdf/jpeg/tiff三种导出格式export_path:自定义导出文件的保存路径和文件名dpi:导出图片的分辨率,默认300满足印刷需求transparent:设置为True即可导出透明背景图,默认白色背景
内容的提问来源于stack exchange,提问作者RayX500
相关产品推荐
相关产品推荐

