Python时间序列图表添加次级X轴标签及柱子透明度调整
摄像头时间序列数据可视化优化方案
需求说明
- 数据背景:拥有多组摄像头的15分钟间隔时间序列数据,每个摄像头可采集4条腿部的3种运动类型数据,存在仅对单个摄像头生效1小时的
control_factor字段(取值True/False)。 - 可视化要求:
- 为每个摄像头单独生成图表,展示每15分钟内各腿部的计数总和;
- 在时间X轴下方添加次级标签:
control_factor=True时显示Yes,control_factor=False时显示No; - 将
control_factor=False对应的柱子调整为对应腿部色系的浅色。
优化后代码实现
基于你提供的数据生成代码,使用matplotlib和seaborn完成需求,代码如下:
import pandas as pd from datetime import datetime, timedelta import matplotlib.pyplot as plt import seaborn as sns from matplotlib.colors import to_rgb, to_hex # ---------------------- 复用你的数据生成代码 ---------------------- def create_date_range(start_date, end_date, interval): date_range = [] current_date = start_date while current_date <= end_date: date_range.append(current_date) current_date += interval return date_range def create_dataframe(start_date, end_date, interval): date_range = create_date_range(start_date, end_date, interval) data = [] for date_time in date_range: for camera in range(1, 5): for leg in range(1, 5): for movement in range(1, 4): count = 1 control_factor = True if date_time.hour == 14 and camera == 1 else False data.append([date_time, f'Cam{camera}', f'Leg{leg}', f'Move{movement}', count, control_factor]) columns = ['DateTime', 'Camera', 'Leg', 'Movement', 'Count', 'control_factor'] return pd.DataFrame(data, columns=columns) start_date = datetime(2024, 1, 27, 14, 0, 0) end_date = datetime(2024, 1, 27, 16, 0, 0) interval = timedelta(minutes=15) df = create_dataframe(start_date, end_date, interval) # ---------------------- 数据生成代码结束 ---------------------- # 获取所有摄像头列表 unique_cameras = df['Camera'].unique() # 为每个腿部定义基础颜色,后续生成浅色版本 leg_colors = { 'Leg1': '#1f77b4', 'Leg2': '#ff7f0e', 'Leg3': '#2ca02c', 'Leg4': '#d62728' } # 生成浅色版本:将RGB值调亮 light_leg_colors = {leg: to_hex([min(1, c + 0.3) for c in to_rgb(color)]) for leg, color in leg_colors.items()} for camera in unique_cameras: # 过滤当前摄像头数据,按时间和腿部聚合(求和所有运动类型的计数) df_camera = df[df['Camera'] == camera] grouped_df = df_camera.groupby(['DateTime', 'Leg']).agg( Count=('Count', 'sum'), control_factor=('control_factor', 'first') ).reset_index() # 获取时间点列表(用于X轴定位) time_points = grouped_df['DateTime'].unique() # 为每个时间点生成control_factor标签 control_labels = grouped_df.groupby('DateTime')['control_factor'].first().map({True: 'Yes', False: 'No'}).tolist() plt.figure(figsize=(15, 8)) ax = plt.gca() # 按时间分组绘制柱状图,每个时间点下的腿部柱子并排 sns.barplot( x='DateTime', y='Count', hue='Leg', data=grouped_df, ax=ax, palette=leg_colors, ci=None ) # 调整control_factor=False的柱子颜色为浅色 for bar, (_, row) in zip(ax.patches, grouped_df.iterrows()): if not row['control_factor']: bar.set_color(light_leg_colors[row['Leg']]) # 添加次级X轴,显示Yes/No标签 ax2 = ax.twiny() # 次级轴的位置与主X轴对齐 ax2.set_xlim(ax.get_xlim()) # 设置次级轴刻度位置(每个时间点的中心) ax2.set_xticks([i + (len(leg_colors)-1)/2 for i in range(0, len(time_points)*len(leg_colors), len(leg_colors))]) ax2.set_xticklabels(control_labels, fontsize=12, fontweight='bold') ax2.set_xlabel('Control Factor', labelpad=15) # 调整主X轴标签 ax.set_xticklabels([tp.strftime('%H:%M') for tp in time_points], rotation=45, ha='right') ax.set_title(f'{camera} - 各腿部每15分钟计数总和', fontsize=16) ax.set_xlabel('时间', labelpad=15) ax.set_ylabel('计数总和', labelpad=15) plt.tight_layout() plt.show()
关键优化点说明
- 数据聚合修正:原代码保留了
Movement维度,我们调整为按DateTime和Leg聚合,直接得到每个时间点各腿部的计数总和,符合需求。 - 颜色自定义:为每个腿部定义基础色和浅色,通过
control_factor判断替换柱子颜色,实现浅色区分效果。 - 次级X轴实现:通过
twiny()创建次级X轴,对齐主X轴的时间点位置,设置Yes/No标签,满足X轴下方添加次级标签的需求。 - 标签优化:将时间格式简化为
%H:%M,提升可读性,同时调整布局避免标签重叠。
内容的提问来源于stack exchange,提问作者GeoBeez
相关产品推荐
相关产品推荐

