如何使用 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 值。
步骤是:
- 定义一个
LineChart
- 为 X 和 Y 值的单元格范围定义
Reference
。
- 使用
.add_data
或 .append
将 Y 值添加为 Series
- 使用
.set_categories
添加 X 值(作为标签)
- 使用
.add_chart
将图表添加到 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')
备注:
- Rows/Columns 从 1 开始(不像典型数组中的 0)。因此,例如,
actual_values
引用范围 B 列和第 1-13 行。
- 包含 header“实际”和“预测”的行是因为在创建
Series
时我们使用了 title_from_data=True
。您可以省略 header 行并使用 title=
参数单独设置 Series
标题。
- 不要忘记调用
.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。
我有一些数据,其中有实际值和预测值。有什么方法可以使用 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 值。
步骤是:
- 定义一个
LineChart
- 为 X 和 Y 值的单元格范围定义
Reference
。 - 使用
.add_data
或.append
将 Y 值添加为Series
- 使用
.set_categories
添加 X 值(作为标签) - 使用
.add_chart
将图表添加到 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')
备注:
- Rows/Columns 从 1 开始(不像典型数组中的 0)。因此,例如,
actual_values
引用范围 B 列和第 1-13 行。 - 包含 header“实际”和“预测”的行是因为在创建
Series
时我们使用了title_from_data=True
。您可以省略 header 行并使用title=
参数单独设置Series
标题。 - 不要忘记调用
.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。