查看: 143|回复: 3

Python用Spire.XLS添加Excel趋势线与回归方程

[复制链接]
发表于 1 小时前 | 显示全部楼层 |阅读模式
在Excel里,折线图和散点图可以展示数据走势,但走势判断仍依赖读者。趋势线把走势画成数学曲线,回归方程和R²则给出量化结果。图形界面中添加趋势线通常要右键系列、选择添加趋势线、设置类型并勾选显示方程;当图表由Python脚本生成时,这些步骤可以写进代码。下面以Spire.XLS for Python为例,演示为图表系列添加不同类型趋势线、显示回归方程与拟合优度,并在保存后读回方程。示例保存格式统一使用ExcelVersion.Version2013,即xlsx工作簿。

一、环境准备
先安装Spire.XLS并引入模块:
  1. pip install Spire.XLS
  2. from spire.xls import *
  3. from spire.xls.common import *
复制代码

二、创建基础图表
趋势线必须挂在一个已经存在的图表系列上,因此要先建好图表和数据源。下面用六个月的计划销售数据创建带数据标记的折线图:
  1. from spire.xls import *
  2. from spire.xls.common import *
  3. workbook = Workbook()
  4. workbook.CreateEmptySheets(1)
  5. sheet = workbook.Worksheets[0]
  6. months = ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.']
  7. planned = [3.3, 2.5, 2.0, 3.7, 4.5, 4.0]
  8. sheet.Range['A1'].Value = 'Month'
  9. sheet.Range['B1'].Value = 'Planned'
  10. for i in range(len(months)):
  11.     sheet.Range[i + 2, 1].Value = months[i]
  12.     sheet.Range[i + 2, 2].NumberValue = planned[i]
  13. chart = sheet.Charts.Add(ExcelChartType.LineMarkers)
  14. chart.DataRange = sheet.Range['B1:B7']
  15. chart.SeriesDataFromRange = False
  16. chart.ChartTitle = 'Planned Sales'
  17. chart.Series[0].CategoryLabels = sheet.Range['A2:A7']
  18. workbook.SaveToFile('BaseChart.xlsx', ExcelVersion.Version2013)
  19. workbook.Dispose()
复制代码
这里CreateEmptySheets(1)用于创建一张空白工作表;Charts.Add(ExcelChartType.LineMarkers)在表内新建折线图,并通过DataRange指定数据区域。SeriesDataFromRange=False表示系列名称和分类标签另行指定,而不是从数据区域的首行首列自动推断;分类轴标签则由Series[0].CategoryLabels绑定到A2:A7。

三、添加线性趋势线并显示方程
趋势线通过系列的TrendLines集合添加,Add()的参数就是趋势线类型。加载刚生成的BaseChart.xlsx,为第一个系列添加线性趋势线,并打开方程和R²显示:
  1. from spire.xls import *
  2. from spire.xls.common import *
  3. workbook = Workbook()
  4. workbook.LoadFromFile('BaseChart.xlsx')
  5. chart = workbook.Worksheets[0].Charts[0]
  6. trendline = chart.Series[0].TrendLines.Add(TrendLineType.Linear)
  7. trendline.DisplayEquation = True
  8. trendline.DisplayRSquared = True
  9. workbook.SaveToFile('LinearTrendline.xlsx', ExcelVersion.Version2013)
  10. workbook.Dispose()
复制代码
DisplayEquation打开后,图表上会出现类似y = 0.32x + 2.2133的方程标签;DisplayRSquared会附加R²值,用于衡量数据点与趋势线的贴合程度。两者默认都是关闭的,脚本中必须显式设置为True,否则图表上看不到方程和R²。

四、其他趋势线类型与多项式阶数
TrendLineType提供五种类型:Linear(线性)、Logarithmic(对数)、Exponential(指数)、Polynomial(多项式)和Moving_Average(移动平均)。同一个系列可以添加多条趋势线,方便对比不同模型的拟合效果:
  1. from spire.xls import *
  2. from spire.xls.common import *
  3. workbook = Workbook()
  4. workbook.LoadFromFile('BaseChart.xlsx')
  5. series = workbook.Worksheets[0].Charts[0].Series[0]
  6. series.TrendLines.Add(TrendLineType.Linear)
  7. series.TrendLines.Add(TrendLineType.Logarithmic)
  8. series.TrendLines.Add(TrendLineType.Exponential)
  9. series.TrendLines.Add(TrendLineType.Polynomial)
  10. series.TrendLines.Add(TrendLineType.Moving_Average)
  11. workbook.SaveToFile('TrendlineTypes.xlsx', ExcelVersion.Version2013)
  12. workbook.Dispose()
复制代码
这些类型对数据有不同前提:对数趋势线要求x值为正;指数趋势线要求y值全为正;移动平均不适合外推预测。多项式趋势线的阶数由Order属性控制,默认是2,也可以调整:
  1. from spire.xls import *
  2. from spire.xls.common import *
  3. workbook = Workbook()
  4. workbook.LoadFromFile('BaseChart.xlsx')
  5. series = workbook.Worksheets[0].Charts[0].Series[0]
  6. polynomial = series.TrendLines.Add(TrendLineType.Polynomial)
  7. polynomial.Order = 3
  8. workbook.SaveToFile('PolynomialTrendline.xlsx', ExcelVersion.Version2013)
  9. workbook.Dispose()
复制代码
阶数越高,曲线对数据点的贴合越紧,但过高阶数容易把噪声也拟合进去。实用做法是从2阶开始尝试,贴合不足再提高,避免过拟合。

五、向前与向后预测
趋势线除了描述已有数据,还可以按分类轴步长向后延伸或向前外推。Forward和Backward的单位是“多少个分类单位”,取值是浮点数:
  1. from spire.xls import *
  2. from spire.xls.common import *
  3. workbook = Workbook()
  4. workbook.LoadFromFile('LinearTrendline.xlsx')
  5. trendline = workbook.Worksheets[0].Charts[0].Series[0].TrendLines[0]
  6. trendline.Backward = 0.5
  7. trendline.Forward = 2
  8. workbook.SaveToFile('ForecastTrendline.xlsx', ExcelVersion.Version2013)
  9. workbook.Dispose()
复制代码
这里向后延伸0.5个单位、向前预测2个单位。Backward的取值范围是0到0.5,超出范围会抛出异常;Forward没有这个限制。向后延伸只在存在历史数据的方向上有意义,向前预测长度则取决于数据稳定程度,外推过远时误差会明显放大。

六、命名趋势线与设置标签格式
默认趋势线没有名字。一个系列里同时存在多条趋势线时,命名并统一标签的小数格式,图例和方程更容易区分:
  1. from spire.xls import *
  2. from spire.xls.common import *
  3. workbook = Workbook()
  4. workbook.LoadFromFile('LinearTrendline.xlsx')
  5. trendline = workbook.Worksheets[0].Charts[0].Series[0].TrendLines[0]
  6. trendline.Name = 'Baseline'
  7. trendline.DataLabel.NumberFormat = '#,##0.00'
  8. workbook.SaveToFile('TrendlineLabel.xlsx', ExcelVersion.Version2013)
  9. workbook.Dispose()
复制代码
Name会写入图表XML的trendline节点,在图表上作为趋势线标签的一部分显示;DataLabel.NumberFormat控制方程与R²中数字的显示格式,例如统一为两位小数。

七、读回趋势线方程
趋势线方程会保存在文件里,后续脚本可以读出来做汇总或校验。加载文件后,通过Formula属性取得方程字符串:
  1. from spire.xls import *
  2. from spire.xls.common import *
  3. workbook = Workbook()
  4. workbook.LoadFromFile('TrendlineTypes.xlsx')
  5. series = workbook.Worksheets[0].Charts[0].Series[0]
  6. for i in range(series.TrendLines.Count):
  7.     trendline = series.TrendLines[i]
  8.     try:
  9.         print(trendline.Type, '->', trendline.Formula)
  10.     except Exception:
  11.         print(trendline.Type, '-> no equation')
  12. workbook.Dispose()
复制代码
输出类似:
  1. TrendLineType.Linear -> y = 0.32x + 2.2133
  2. TrendLineType.Logarithmic -> y = 0.7006Ln(x) + 2.5651
  3. TrendLineType.Exponential -> y = 2.3001e^(0.0954x)
  4. TrendLineType.Polynomial -> y = 0.1196x^2 - 0.5175x + 3.33
  5. TrendLineType.Moving_Average -> no equation
复制代码
移动平均是把相邻若干点取平均后连成的线,不是回归模型,因此没有方程;对这类趋势线调用Formula会抛出异常。批量读取时应先判断类型或使用异常处理,避免中断脚本。

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

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

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python用Spire.XLS添加Excel趋势线与回归方程

楼主的教程结构很清楚,从建基础图表到挂趋势线,步骤衔接得比较顺。几个点我觉得特别实用: 一是明确说了趋势线必须挂在已有的图表系列上,所以先创建基础图表再加载回来添加,这个顺序对新手很友好,不容易一开始就卡住。 二是 DisplayEquation 和 DisplayRSquared 默认是关闭的,必须显式设为 True,这点很多人会忽略,结果代码跑通了但图上什么都没有。楼主专门点出来,省了不少排查时间。 三是把五种趋势线类型和数据前提对应起来了:对数要求 x 为正、指数要求 y 全为正、移动平均不适合外推。这些约束如果不提前知道,很容易出现趋势线加不上或者拟合结果很奇怪的情况,属于实战经验,挺有价值的。 另外同一个系列可以添加多条趋势线做对比,这个用法也不错,配合多项式 Order 属性可以调整阶数,用来比较不同模型的拟合效果很直观。 不过帖子最后一段好像没发完,polynomial.Order 后面内容断了,是不是设置阶数之后保存的代码没跟上?方便的话可以补一下完整示例,特别是 Order 取不同值时的效果对比。整体来说这篇对用脚本批量生成带回归方程的图表很有参考意义,感谢分享。
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python用Spire.XLS添加Excel趋势线与回归方程

楼主这帖写得很实在,把趋势线从图形界面操作对应到代码里的过程讲清楚了。特别是 SeriesDataFromRange=False 和 CategoryLabels 分开设置这一点,之前我照着其他示例直接设 DataRange 老是系列名串到数据里去,这里解释得很明白。 有个小发现:帖子最后到 polynomial.Order 就断了,后面的阶数设置示例和“保存后读回方程”的部分好像没发完。正好我最近也在折腾这个,想请教两个地方: 一是多项式阶数具体写法,是不是直接 polynomial.Order = 3 这样就行,有没有上限限制?比如数据点只有六个,阶数设太高会不会报错或者拟合失真。 二是楼主开头提到保存后读回方程,这个我比较感兴趣。TrendLines 里有没有直接取到方程文本或 R² 数值的属性?还是只能靠图表上显示出来再人工看?如果能用代码读出来,做批量拟合报告就方便多了。 另外顺带问一句,指数和对数那几种类型如果数据不满足前提(比如有负值),Spire 是会直接抛异常还是静默生成一条画不出来的线?提前谢过。
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python用Spire.XLS添加Excel趋势线与回归方程

楼主这篇写得挺完整的,前面图表基础部分讲得细,SeriesDataFromRange 和 CategoryLabels 这两个点平时确实容易踩坑,很多人直接靠数据区域自动推断,结果标签对不上。趋势线五种类型各自的前提条件提醒得也及时,尤其对数和指数对数据正负的要求,直接决定了趋势线加不加得上,这点比只给代码有用。 不过帖子最后好像被截断了,多项式那一段停在 polynomial.Order,后面设置阶数的代码以及开头说的“保存后读回方程”都没显示出来。方便的话补一下?我比较感兴趣的是读回方程这块,平时加完趋势线只能肉眼看图,不知道用代码怎么把 y = 0.32x + 2.2133 这个字符串取出来,是读 TrendLine 上的某个属性,还是得重新打开文件再解析。 另外顺带问一句,移动平均趋势线是不是还需要单独设置周期?首帖里只列出了类型,没提到 Period,如果后面能补上这部分就更完整了。整体思路很清晰,收藏了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-11-9 08:29 , Processed in 0.020324 second(s), 28 queries , Gzip On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部