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

如何为MultiIndex Series绘制带趋势线的图表?

解决MultiIndex分组数据添加趋势线的方法

核心思路

把MultiIndex转换成连续的时间序列索引,让工具能识别时间维度的连续性,进而拟合趋势线。

具体步骤

1. 将MultiIndex转换为DatetimeIndex

假设你的目标Series名为yes_freq,先把年和月组合成标准日期格式(比如每月第一天):

import pandas as pd

# 从MultiIndex提取年、月,拼接为日期字符串后转成Datetime类型
dates = pd.to_datetime([f"{year}-{month}-01" for year, month in yes_freq.index])
# 重置索引为DatetimeIndex
yes_freq = yes_freq.reset_index(drop=True).set_index(dates)

2. 绘制柱状图+趋势线

用Matplotlib实现

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(figsize=(12,6))

# 绘制基础柱状图
yes_freq.plot(kind='bar', ax=ax, color='skyblue', label='Yes相对频率')

# 把时间轴转为连续数值(用于拟合)
x = np.arange(len(yes_freq))
y = yes_freq.values
# 拟合线性趋势线(可调整多项式阶数实现非线性趋势)
z = np.polyfit(x, y, 1)
p = np.poly1d(z)

# 绘制趋势线
ax.plot(x, p(x), color='red', linestyle='--', label=f'线性趋势: y={z[0]:.4f}x + {z[1]:.4f}')

# 调整图表样式
ax.set_xlabel('年月')
ax.set_ylabel('相对频率')
ax.set_title('各年月Yes相对频率及趋势')
ax.legend()
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

用Seaborn实现

先把Series转为带辅助列的DataFrame,适配Seaborn的API:

import seaborn as sns

# 转换为DataFrame并添加连续索引列
df = yes_freq.reset_index()
df.columns = ['Date', 'Yes_Freq']
df['Seq'] = np.arange(len(df))

fig, ax = plt.subplots(figsize=(12,6))

# 绘制柱状图
sns.barplot(data=df, x='Date', y='Yes_Freq', ax=ax, color='skyblue')

# 绘制趋势线(scatter=False只显示拟合线)
sns.regplot(data=df, x='Seq', y='Yes_Freq', ax=ax, scatter=False, color='red', label='趋势线')

# 调整样式
ax.set_xlabel('年月')
ax.set_ylabel('相对频率')
ax.set_title('各年月Yes相对频率及趋势')
ax.legend()
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

3. 高阶趋势拟合(可选)

如果数据呈现非线性趋势,只需修改多项式阶数即可,比如二次趋势:

# 拟合二次多项式
z = np.polyfit(x, y, 2)
p = np.poly1d(z)
ax.plot(x, p(x), color='green', linestyle='-.', label=f'二次趋势: y={z[0]:.6f}x² + {z[1]:.4f}x + {z[2]:.4f}')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 13:50:34