使用 Python 在 Excel 图表中添加趋势线与回归方程

折线图和散点图能显示数据的走势,但走势本身要靠读者自己判断:下个月会继续上升还是回落?两个季度的波动是否属于同一趋势?趋势线把这条走势画成一条数学曲线,回归方程和 R² 则给出量化的答案。

在 Excel 里添加趋势线原本要经过"右键系列 → 添加趋势线 → 选择类型 → 勾选显示方程"几个步骤。当图表由脚本生成时,这些操作都可以写进代码。这篇文章用 Spire.XLS for Python 演示如何为图表的各个系列添加不同类型的趋势线、显示回归方程与拟合优度,并在保存后读回方程。

环境准备

安装 Spire.XLS 并引入模块:

bash 复制代码
pip install Spire.XLS
python 复制代码
from spire.xls import *
from spire.xls.common import *

创建基础图表

先准备一组六个月的销售数据,并生成一张带数据点的折线图。趋势线必须挂在一个已经存在的系列上,所以图表要先建好:

python 复制代码
from spire.xls import *
from spire.xls.common import *

workbook = Workbook()
workbook.CreateEmptySheets(1)
sheet = workbook.Worksheets[0]

months = ["Jan.", "Feb.", "Mar.", "Apr.", "May.", "Jun."]
planned = [3.3, 2.5, 2.0, 3.7, 4.5, 4.0]

sheet.Range["A1"].Value = "Month"
sheet.Range["B1"].Value = "Planned"
for i in range(len(months)):
    sheet.Range[i + 2, 1].Value = months[i]
    sheet.Range[i + 2, 2].NumberValue = planned[i]

# 创建折线图,并以 B 列数据作为数据源
chart = sheet.Charts.Add(ExcelChartType.LineMarkers)
chart.DataRange = sheet.Range["B1:B7"]
chart.SeriesDataFromRange = False
chart.ChartTitle = "Planned Sales"

# 设置分类轴标签
chart.Series[0].CategoryLabels = sheet.Range["A2:A7"]

workbook.SaveToFile("BaseChart.xlsx", ExcelVersion.Version2013)
workbook.Dispose()

CreateEmptySheets(1) 创建一个空白工作表;Charts.Add(ExcelChartType.LineMarkers) 在表内新建图表,并从 DataRange 指定的区域读取数据。SeriesDataFromRange = False 表示数据的系列名称和分类标签另行指定,而不是从区域首行首列推断。

添加线性趋势线并显示方程

趋势线通过系列的 TrendLines 集合添加,Add() 的参数是趋势线类型。下面的代码在刚刚生成的 BaseChart.xlsx 上继续操作:

python 复制代码
from spire.xls import *
from spire.xls.common import *

workbook = Workbook()
workbook.LoadFromFile("BaseChart.xlsx")
chart = workbook.Worksheets[0].Charts[0]

# 为第一个系列添加线性趋势线
trendline = chart.Series[0].TrendLines.Add(TrendLineType.Linear)

# 在图表上显示回归方程和 R²
trendline.DisplayEquation = True
trendline.DisplayRSquared = True

workbook.SaveToFile("LinearTrendline.xlsx", ExcelVersion.Version2013)
workbook.Dispose()

DisplayEquation 打开后,图表上会出现形如 y = 0.32x + 2.2133 的标签;DisplayRSquared 则附加 R² 值,用来衡量数据点与趋势线的贴合程度。两者默认都是关闭的,需要显式打开。

其他趋势线类型

TrendLineType 提供五种类型:Linear(线性)、Logarithmic(对数)、Exponential(指数)、Polynomial(多项式)和 Moving_Average(移动平均)。同一个系列可以添加多条趋势线,用于对比不同模型的拟合效果:

python 复制代码
from spire.xls import *
from spire.xls.common import *

workbook = Workbook()
workbook.LoadFromFile("BaseChart.xlsx")
series = workbook.Worksheets[0].Charts[0].Series[0]

# 五种类型各加一条
series.TrendLines.Add(TrendLineType.Linear)
series.TrendLines.Add(TrendLineType.Logarithmic)
series.TrendLines.Add(TrendLineType.Exponential)
series.TrendLines.Add(TrendLineType.Polynomial)
series.TrendLines.Add(TrendLineType.Moving_Average)

workbook.SaveToFile("TrendlineTypes.xlsx", ExcelVersion.Version2013)
workbook.Dispose()

几种类型对数据有不同的前提:对数趋势线要求 x 值为正,指数趋势线要求 y 值全为正,移动平均则不适合外推预测。多项式趋势线还可以调整阶数,Order 属性控制最高次项,默认是 2:

python 复制代码
from spire.xls import *
from spire.xls.common import *

workbook = Workbook()
workbook.LoadFromFile("BaseChart.xlsx")
series = workbook.Worksheets[0].Charts[0].Series[0]

polynomial = series.TrendLines.Add(TrendLineType.Polynomial)
polynomial.Order = 3

workbook.SaveToFile("PolynomialTrendline.xlsx", ExcelVersion.Version2013)
workbook.Dispose()

阶数越高,曲线对数据点的贴合越紧,但过高的阶数容易把噪声也拟合进去,通常从 2 阶开始尝试即可。

向前与向后预测

趋势线除了描述已有数据,还可以按分类轴的步长向后延伸或向前外推。Forward 和 Backward 属性以"多少个分类单位"为单位:

python 复制代码
from spire.xls import *
from spire.xls.common import *

workbook = Workbook()
workbook.LoadFromFile("LinearTrendline.xlsx")
trendline = workbook.Worksheets[0].Charts[0].Series[0].TrendLines[0]

# 向后延伸 0.5 个单位、向前预测 2 个单位
trendline.Backward = 0.5
trendline.Forward = 2

workbook.SaveToFile("ForecastTrendline.xlsx", ExcelVersion.Version2013)
workbook.Dispose()

取值是浮点数,表示分类轴上的单位数。需要注意的是 Backward 的取值范围是 0 到 0.5,超出这个范围会抛出异常;Forward 没有这个限制。向后延伸只在有历史数据的方向上有意义,向前预测的长度则取决于数据的稳定程度------外推过远时,趋势线的误差会明显放大。

命名趋势线与设置标签格式

默认趋势线没有名字。系列中同时存在多条趋势线时,给它们命名并在标签上统一小数格式,图例和方程就更容易区分:

python 复制代码
from spire.xls import *
from spire.xls.common import *

workbook = Workbook()
workbook.LoadFromFile("LinearTrendline.xlsx")
trendline = workbook.Worksheets[0].Charts[0].Series[0].TrendLines[0]

# 命名趋势线,并把标签数字格式化为两位小数
trendline.Name = "Baseline"
trendline.DataLabel.NumberFormat = "#,##0.00"

workbook.SaveToFile("TrendlineLabel.xlsx", ExcelVersion.Version2013)
workbook.Dispose()

Name 会写入图表 XML 的 trendline 节点,在图表上作为趋势线标签的一部分显示;DataLabel.NumberFormat 则控制方程与 R² 中数字的显示格式。

读回趋势线方程

趋势线的方程也会保存在文件里,可以在后续脚本中读出来做汇总或校验。加载文件后,通过 Formula 属性取得方程字符串:

python 复制代码
from spire.xls import *
from spire.xls.common import *

workbook = Workbook()
workbook.LoadFromFile("TrendlineTypes.xlsx")
series = workbook.Worksheets[0].Charts[0].Series[0]

for i in range(series.TrendLines.Count):
    trendline = series.TrendLines[i]
    try:
        print(trendline.Type, "->", trendline.Formula)
    except Exception:
        # 移动平均没有回归方程
        print(trendline.Type, "-> no equation")

workbook.Dispose()

输出类似:

ini 复制代码
TrendLineType.Linear -> y = 0.32x + 2.2133
TrendLineType.Logarithmic -> y = 0.7006Ln(x) + 2.5651
TrendLineType.Exponential -> y = 2.3001e^(0.0954x)
TrendLineType.Polynomial -> y = 0.1196x^2 - 0.5175x + 3.33
TrendLineType.Moving_Average -> no equation

需要注意,移动平均是把相邻若干点取平均后连成的线,它不是回归模型,因此没有方程;对这类趋势线调用 Formula 会抛出异常,读取时要先判断类型或做异常处理。

实用技巧

  • 先建系列再加趋势线 :TrendLines 挂在 Series 上,图表和数据源准备好之后再添加。
  • 方程与 R² 要显式开启 :DisplayEquation、DisplayRSquared 默认关闭,不开就看不到标签。
  • 类型有前提条件:对数要求 x 为正、指数要求 y 为正,否则 Excel 会画出错误或空白的趋势线。
  • 阶数从低到高 :多项式趋势线先用 Order = 2,贴合不够再提高,避免过拟合。
  • 移动平均不能外推 :它没有方程,也不适合做 Forward 预测。
  • 读取方程时处理异常 :只有回归类趋势线有 Formula,批量读取时加类型判断。
  • 及时释放资源 :每个工作簿用完调用 Dispose()。

结论

这篇文章演示了在 Python 中为 Excel 图表添加趋势线:先创建带数据标签的折线图,再通过 Series.TrendLines.Add() 添加线性、对数、指数、多项式或移动平均趋势线,用 DisplayEquation 和 DisplayRSquared 在图上显示回归方程与拟合优度,用 Forward / Backward 做预测延伸,用 Name 与 DataLabel.NumberFormat 区分和格式化多条趋势线,最后在加载文件后通过 Formula 读回方程。把这些步骤放进报表生成脚本,图表就不只是展示数据,还能直接给出趋势的量化结论。

相关推荐
你三大爷24 分钟前
Netty / Kafka / Redis 保序问题的源码对比与 NIO 框架主流解法
后端·架构
特立独行的猫A26 分钟前
一份 Markdown 发十个平台:cspub 一稿多投
java·后端·python
3DGISer33 分钟前
不透明物体的渲染算法
后端
深蓝AI42 分钟前
HTTPX 超时 1 秒,接口为何还能跑 2.4 秒?
python
CyrusYiVPP1 小时前
哪个用户会再来买?RFM模型+plotly画出用户分层,数据分析实战第2期
人工智能·python
ServBay1 小时前
从代码到上线,Cursor Live Apps 能替独立开发者做什么
后端·ai编程·cursor
程序员cxuan1 小时前
LobeHub 是真的夯,简直 Super-Agent 最佳实现。
人工智能·后端·程序员
挖坑的张师傅2 小时前
开源一个 Managed Agents 云端托管智能体平台
后端·agent
挖坑的张师傅2 小时前
Agent 基建系列:用 MCP Tunnel 让云端 Agent 访问企业内网工具
后端·agent