You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Python实现按年度/季度的收益及PNL水平柱状图可视化

优化数据处理与自动化可视化实现

Hey there! Let's get your time-series visualization sorted out properly. First, let's clean up your data processing code—grouping multiple metrics in one pass is way more efficient than doing separate groupbys. Then we'll build those horizontal bar charts with all the annotations and reference lines you need.

第一步:优化数据处理代码

Your original code runs separate groupbys for each metric, which is redundant. Instead, we can group once per time period (year/quarter) and calculate all required aggregations in a single step. This saves computation time and keeps your code cleaner:

import pandas as pd

# 假设你的原始数据已经读入为df,先确保date字段是datetime类型
df['date'] = pd.to_datetime(df['date'])

# 按年度聚合:returns均值、pnl总和、no_trades总和
yearly_agg = df.groupby(df['date'].dt.year).agg(
    avg_returns=('returns', 'mean'),
    total_pnl=('pnl', 'sum'),
    total_trades=('no_trades', 'sum')
).reset_index().rename(columns={'date': 'year'})

# 按季度聚合:returns均值、pnl总和、no_trades总和
quarterly_agg = df.groupby(df['date'].dt.quarter).agg(
    avg_returns=('returns', 'mean'),
    total_pnl=('pnl', 'sum'),
    total_trades=('no_trades', 'sum')
).reset_index().rename(columns={'date': 'quarter'})
# 给季度添加Q前缀,让展示更直观(比如1→Q1)
quarterly_agg['quarter'] = 'Q' + quarterly_agg['quarter'].astype(str)

# 计算整体平均值(用于绘制参考虚线)
overall_avg_returns = df['returns'].mean()
overall_total_pnl = df['pnl'].sum()

This way, we have all aggregated metrics in two neat DataFrames instead of six separate ones—much easier to work with!

第二步:编写通用可视化函数

To avoid repeating code for each chart, let's create a reusable function that generates the horizontal bar chart with annotations and reference lines:

import matplotlib.pyplot as plt

def plot_horizontal_bar(data, x_col, label_col, annot_mid_col, annot_end_col, overall_mean, title):
    plt.figure(figsize=(10, 6))
    # 绘制水平柱状图
    bars = plt.barh(data[label_col], data[x_col], color='#4285F4')
    
    # 在柱子中间标注核心数值(比如returns均值或pnl总和)
    for bar, value in zip(bars, data[annot_mid_col]):
        width = bar.get_width()
        plt.text(width/2, bar.get_y() + bar.get_height()/2, 
                 f'{value:.4f}', ha='center', va='center', fontweight='bold')
    
    # 在柱子末端标注交易次数总和
    for bar, trades in zip(bars, data[annot_end_col]):
        width = bar.get_width()
        plt.text(width + 0.002, bar.get_y() + bar.get_height()/2, 
                 f'Trades: {trades}', ha='left', va='center', color='#666666')
    
    # 绘制贯穿柱子的整体平均值虚线
    plt.axvline(x=overall_mean, color='#EA4335', linestyle='--', label=f'Overall {x_col.replace("_", " ")}: {overall_mean:.4f}')
    
    # 调整图表样式,提升可读性
    plt.title(title, fontsize=14, pad=20)
    plt.xlabel(x_col.replace('_', ' ').title(), fontsize=12)
    plt.ylabel(label_col.title(), fontsize=12)
    plt.legend()
    plt.tight_layout()
    plt.show()

第三步:生成所有要求的图表

Now we can call this function for each of your required charts:

1. 年度Returns均值柱状图

plot_horizontal_bar(
    data=yearly_agg,
    x_col='avg_returns',
    label_col='year',
    annot_mid_col='avg_returns',
    annot_end_col='total_trades',
    overall_mean=overall_avg_returns,
    title='Annual Average Returns with Total Trades'
)

2. 年度PnL总和柱状图

plot_horizontal_bar(
    data=yearly_agg,
    x_col='total_pnl',
    label_col='year',
    annot_mid_col='total_pnl',
    annot_end_col='total_trades',
    overall_mean=overall_total_pnl,
    title='Annual Total PnL with Total Trades'
)

3. 季度Returns均值柱状图

plot_horizontal_bar(
    data=quarterly_agg,
    x_col='avg_returns',
    label_col='quarter',
    annot_mid_col='avg_returns',
    annot_end_col='total_trades',
    overall_mean=overall_avg_returns,
    title='Quarterly Average Returns with Total Trades'
)

4. 季度PnL总和柱状图

plot_horizontal_bar(
    data=quarterly_agg,
    x_col='total_pnl',
    label_col='quarter',
    annot_mid_col='total_pnl',
    annot_end_col='total_trades',
    overall_mean=overall_total_pnl,
    title='Quarterly Total PnL with Total Trades'
)

额外小提示

  • 代码里用的是Google品牌色,你可以根据喜好替换color参数的十六进制值
  • 如果你的数据有极端大的数值,可能需要微调末端标注的width + 0.002偏移量,避免文字重叠
  • tight_layout()会自动调整图表元素位置,防止标签或标题被截断

内容的提问来源于stack exchange,提问作者eternity1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:11:13