如何使用 openpyxl 创建预测值图表?

How to create forecasted values chart using openpyxl?

我有一些数据,其中有实际值和预测值。有什么方法可以使用 openpyxl 来表示吗?

数据

    Actual   Forecast
jan 100k  
feb 115k
mar 121k
apr 150k
may 137k
jun 125k
jul          167k
aug          184k
sep          202k
oct          223k
nov          245k
dec          269k

想要

正在做

from openpyxl import Workbook
from openpyxl.chart import (
    LineChart,
    BarChart,
    Reference,
    Series,
)

wb = Workbook()
ws = wb.active

path = "C:/Users/tanisha.hudson/wb1.xlsx"
wb_obj = load_workbook(path)
sheet_obj = wb_obj.active

c1 = LineChart()

v1 = Reference(ws, min_col=1, min_row=1, max_col=13)
c1.add_data(v1, titles_from_data=True, from_rows=True)

c1.x_axis.title = 'Chart Title'
c1.y_axis.majorGridlines = None

欢迎任何建议

您可以创建一个包含 2 个系列的 Line Chart:1 个 Y-axis 值来自实际列的系列和 1 个 Y-axis 值来自预测列的系列。这两个系列都将使用第一列中的月份作为 X-axis 值。

步骤是:

  1. 定义一个LineChart
  2. 为 X 和 Y 值的单元格范围定义 Reference
  3. 使用 .add_data.append 将 Y 值添加为 Series
  4. 使用 .set_categories 添加 X 值(作为标签)
  5. 使用 .add_chart
  6. 将图表添加到 sheet

你的数据的问题是你所有的数字都有一个 k 后缀,这使得它成为 non-numeric 并且不能被 openpyxl 正确绘制(即使在 Excel,它被视为文本,在绘制时相当于 0)。我假设“100k”的意思是“100,000”,所以为了让事情更简单,我们只使用“100”而不是“100k”,并将“k”放在标签中,如“Actual (k)”。

如果您已经在这样的 Excel 文件中拥有该数据:

然后在LineChart中绘制的代码如下:

from openpyxl import load_workbook
from openpyxl.chart import LineChart, Reference, Series

# path = "C:/Users/tanisha.hudson/wb1.xlsx"
path = 'wb1.xlsx'
wb = load_workbook(path)
ws = wb.active

c1 = LineChart()
c1.title = 'Chart Title'
c1.legend.position = 'b'  # https://openpyxl.readthedocs.io/en/stable/charts/chart_layout.html#legend-layout

actual_values = Reference(ws, min_col=2, max_col=2, min_row=1, max_row=13)
actual_series = Series(actual_values, title_from_data=True)
c1.append(actual_series)

forecast_values = Reference(ws, min_col=3, max_col=3, min_row=1, max_row=13)
forecast_series = Series(forecast_values, title_from_data=True)
c1.append(forecast_series)

xaxis_values = Reference(ws, min_col=1, max_col=1, min_row=2, max_row=13)
c1.set_categories(xaxis_values)

ws.add_chart(c1, 'E2')
wb.save('wb1-chart.xlsx')

备注:

  1. Rows/Columns 从 1 开始(不像典型数组中的 0)。因此,例如,actual_values 引用范围 B 列和第 1-13 行。
  2. 包含 header“实际”和“预测”的行是因为在创建 Series 时我们使用了 title_from_data=True。您可以省略 header 行并使用 title= 参数单独设置 Series 标题。
  3. 不要忘记调用 .add_chart 将折线图添加到 sheet。此外,最好 .save 它作为一个单独的文件,以防你弄乱原来的 sheet.

输出:

请注意 2 个系列没有连接,因为实际数据值和预测数据值也没有连接。解决方法是添加一个公共数据点。例如,将 Jun=125 添加到 Forecast 列 ():

wb = load_workbook(path)
ws = wb.active
ws['C7'].value = ws['B7'].value  # Copy last Actual as Forecast

...

现在,如果您的输入数据确实有一个 k 后缀,并且您不想手动修改它们以摆脱 k,只需在绘图之前使用 openpyxl 重写这些值:

for row in range(2, 14):  # B2-B13, C2-C13
    for col in range(2, 4):  # B-C
        cell = ws.cell(column=col, row=row)
        old_val = cell.value
        new_val = int(old_val.replace('k', '')) if old_val else ''
        cell.value = new_val
ws['C7'].value = ws['B7'].value

有关详细信息,请参阅 openpyxl 文档的 Charts 部分。
如果某些功能是 version-specific:Python 3.8.8、openpyxl 3.0.7、Office 2016。