在Excel里,折线图和散点图可以展示数据走势,但走势判断仍依赖读者。趋势线把走势画成数学曲线,回归方程和R²则给出量化结果。图形界面中添加趋势线通常要右键系列、选择添加趋势线、设置类型并勾选显示方程;当图表由Python脚本生成时,这些步骤可以写进代码。下面以Spire.XLS for Python为例,演示为图表系列添加不同类型趋势线、显示回归方程与拟合优度,并在保存后读回方程。示例保存格式统一使用ExcelVersion.Version2013,即xlsx工作簿。
一、环境准备
先安装Spire.XLS并引入模块:- pip install Spire.XLS
- from spire.xls import *
- from spire.xls.common import *
复制代码
二、创建基础图表
趋势线必须挂在一个已经存在的图表系列上,因此要先建好图表和数据源。下面用六个月的计划销售数据创建带数据标记的折线图:- 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]
- 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表示系列名称和分类标签另行指定,而不是从数据区域的首行首列自动推断;分类轴标签则由Series[0].CategoryLabels绑定到A2:A7。
三、添加线性趋势线并显示方程
趋势线通过系列的TrendLines集合添加,Add()的参数就是趋势线类型。加载刚生成的BaseChart.xlsx,为第一个系列添加线性趋势线,并打开方程和R²显示:- 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)
- trendline.DisplayEquation = True
- trendline.DisplayRSquared = True
- workbook.SaveToFile('LinearTrendline.xlsx', ExcelVersion.Version2013)
- workbook.Dispose()
复制代码 DisplayEquation打开后,图表上会出现类似y = 0.32x + 2.2133的方程标签;DisplayRSquared会附加R²值,用于衡量数据点与趋势线的贴合程度。两者默认都是关闭的,脚本中必须显式设置为True,否则图表上看不到方程和R²。
四、其他趋势线类型与多项式阶数
TrendLineType提供五种类型:Linear(线性)、Logarithmic(对数)、Exponential(指数)、Polynomial(多项式)和Moving_Average(移动平均)。同一个系列可以添加多条趋势线,方便对比不同模型的拟合效果:- 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,也可以调整:- 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的单位是“多少个分类单位”,取值是浮点数:- 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.Backward = 0.5
- trendline.Forward = 2
- workbook.SaveToFile('ForecastTrendline.xlsx', ExcelVersion.Version2013)
- workbook.Dispose()
复制代码 这里向后延伸0.5个单位、向前预测2个单位。Backward的取值范围是0到0.5,超出范围会抛出异常;Forward没有这个限制。向后延伸只在存在历史数据的方向上有意义,向前预测长度则取决于数据稳定程度,外推过远时误差会明显放大。
六、命名趋势线与设置标签格式
默认趋势线没有名字。一个系列里同时存在多条趋势线时,命名并统一标签的小数格式,图例和方程更容易区分:- 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属性取得方程字符串:- 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()
复制代码 输出类似:- 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会抛出异常。批量读取时应先判断类型或使用异常处理,避免中断脚本。
八、实用技巧与排查要点
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读回方程。把这些步骤放进报表生成脚本,图表不仅能展示数据,还能直接给出趋势的量化结论。 |