如何取消 python-pptx 中具有时间相关值的图表数据分组
HOW TO Ungroup chartdata with time-dependent values in python-pptx
我尝试输出带有日期类型类别轴的 XY 数据(datetime.datetime 个沿 X 轴的对象)。我需要查看 chart_data 中包含的 所有 个数据点 (X,Y)。但是,不幸的是,它们在展示中按年份分组。如何更改 XY 图表的 'gruoing option'?
我已经改了
chart.category_axis.category_type = XL_CATEGORY_TYPE.CATEGORY_SCALE
但没有成功
有代码示例:
# -*- coding: utf-8 -*-
"""
Created on Wed May 30 14:46:28 2018
"""
import datetime, time
import xlrd
import pptx
from pptx import Presentation
from pptx.util import Cm, Pt
from pptx.enum.text import MSO_ANCHOR, MSO_AUTO_SIZE,PP_ALIGN
from pptx.chart.data import ChartData, XyChartData
from pptx.enum.chart import XL_CHART_TYPE
from pptx.enum.chart import XL_TICK_MARK
from pptx.enum.chart import XL_LEGEND_POSITION
from pptx.enum.chart import XL_CATEGORY_TYPE
prs = Presentation('templae.pptx')
def FonST(obj, s, t):
try:
obj.text_frame.paragraphs[0].font.size = Pt(s)
obj.text_frame.paragraphs[0].font.typeface = t
except AttributeError:
obj.font.size=Pt(s)
obj.font.typeface=t
title_slide_layout = prs.slide_masters[1].slide_layouts[1]
slide = prs.slides.add_slide(title_slide_layout)
shapes = slide.shapes
title = shapes.title
class MyXySeriesData(pptx.chart.data.XySeriesData):
"""
The data specific to a particular XY chart series. It provides access to
the series label, the series data points, and an optional number format
to be applied to each data point not having a specified number format.
The sequence of data points in an XY series is significant; lines are
plotted following the sequence of points, even if that causes a line
segment to "travel backward" (implying a multi-valued function). The data
points are not automatically sorted into increasing order by X value.
"""
def add_data_vector(self, vec1, vec2):
if len(vec1) != len(vec2):
return -1
else:
for i in range(0, len(vec1)):
self.add_data_point(vec1[i], vec2[i])
class MyXyChartData(pptx.chart.data.XyChartData):
"""
Переопределяем класс библиотеки pptx
"""
def add_series(self, name, number_format=None):
"""
Return an |XySeriesData| object newly created and added at the end of
this sequence, identified by *name* and values formatted with
*number_format*.
"""
series_data = MyXySeriesData(self, name, number_format)
self.append(series_data)
return series_data
# Open the workbook
xl_workbook = xlrd.open_workbook('bookxl.xlsx')
# Grab the first sheet by index
# (sheets are zero-indexed)
#
xl_sheet = xl_workbook.sheet_by_index(0)
#print ('Sheet name: %s' % xl_sheet.name)
# define chart data ---------------------
chart_data = MyXyChartData()
vec1 = [ datetime.datetime.fromordinal(int(693594+i.value )) for i in xl_sheet.col(0)]
vec2 = [ float(i.value) for i in xl_sheet.col(1)]
series_1 = chart_data.add_series('Model 1')
series_1.add_data_vector(vec1 , vec2)
# add chart to slide --------------------
x, y, cx, cy = Cm(10), Cm(3), Cm(10), Cm(8)
chart = slide.shapes.add_chart(
XL_CHART_TYPE.XY_SCATTER_SMOOTH_NO_MARKERS, x, y, cx, cy, chart_data
).chart
chart.chart_title.text_frame.text = 'YTD COMPLETION TO PLAN'
FonST(chart.chart_title, 12, 'Times New Roman')
#chart.chart_title.text_frame.paragraphs[0].font.size = Pt(12)
#chart.chart_title.text_frame.paragraphs[0].font = Pt(12)
chart.has_legend = True
chart.legend.include_in_layout = False
FonST(chart.legend, 12, 'Times New Roman')
#chart.legend.font.size = Pt(12)
chart.legend.position = XL_LEGEND_POSITION.BOTTOM
chart.series[0].smooth = True
#chart.category_axis.tick_labels.font.size=Pt(10)
#chart.value_axis.tick_labels.font.size=Pt(10)
FonST(chart.category_axis.tick_labels, 10, 'Times New Roman')
FonST(chart.value_axis.tick_labels, 10, 'Times New Roman')
#chart.category_axis.tick_labels.number_format = '0.00'
chart.value_axis.tick_labels.number_format = '0.00'
chart.value_axis.axis_title.text_frame.text = 'Something'
FonST(chart.value_axis.axis_title, 10, 'Times New Roman')
chart.category_axis.axis_title.text_frame.text = 'Дата'
FonST(chart.category_axis.axis_title, 10, 'Times New Roman')
chart.category_axis.category_type = XL_CATEGORY_TYPE.CATEGORY_SCALE
prs.save('testout.pptx')
第一个列表 'bookxl.xlsx' 的内容是:input data example,
为方便起见,输入数据如下:
01.11.2017 6.660761604
06.11.2017 7.012580588
11.11.2017 6.941095486
17.11.2017 6.85236787
20.11.2017 6.807413035
22.11.2017 6.777194047
26.11.2017 6.716288151
29.11.2017 6.670361491
01.12.2017 6.639671179
01.01.2018 6.13350148
01.02.2018 6.31542197
01.03.2018 4.600364229
01.04.2018 4.152160143
29.04.2018 3.442227537
30.04.2018 3.43343609
01.05.2018 3.425108975
01.06.2018 3.396918009
01.07.2018 3.369342609
01.08.2018 3.35360536
01.09.2018 3.351036414
01.10.2018 3.358021731
01.11.2018 3.371659755
01.12.2018 3.38805915
01.01.2019 3.406137358
01.02.2019 3.423831347
01.03.2019 3.438710981
01.04.2019 3.452972517
01.05.2019 3.464318611
01.06.2019 3.473092026
01.07.2019 3.478872101
01.08.2019 3.481948962
01.09.2019 3.482171692
01.10.2019 3.479855714
01.11.2019 3.475044618
01.12.2019 3.46824709
01.01.2020 3.459274478
现在的结果是:
Stair-like plot
我想查看这样的内容:
Desired result
我认为问题在于您创建的是 X/Y 图表而不是类别图表。如果您将日期值作为类别图表中的类别输入,X 轴会自动变成日期轴,并显示我认为您正在寻找的行为。
此处的项目技术文档中有一些附加信息:http://python-pptx.readthedocs.io/en/latest/dev/analysis/cht-date-axis.html
简而言之,食谱是:
- 使用 CategoryChartData 对象而不是 XyChartData
- 添加图表时使用其中一种折线图类型而不是 XY 类型(可能是 LINE 或 LINE_MARKERS)。
- 使用 datetime.date 或 datetime.datetime 对象作为类别值(而不是通常的 str 标签)。
- 可能会更改 LineSeries.smooth 以适应(可能
series.smooth = True
)。
我想这会给你想要的东西。
我尝试输出带有日期类型类别轴的 XY 数据(datetime.datetime 个沿 X 轴的对象)。我需要查看 chart_data 中包含的 所有 个数据点 (X,Y)。但是,不幸的是,它们在展示中按年份分组。如何更改 XY 图表的 'gruoing option'?
我已经改了
chart.category_axis.category_type = XL_CATEGORY_TYPE.CATEGORY_SCALE
但没有成功
有代码示例:
# -*- coding: utf-8 -*-
"""
Created on Wed May 30 14:46:28 2018
"""
import datetime, time
import xlrd
import pptx
from pptx import Presentation
from pptx.util import Cm, Pt
from pptx.enum.text import MSO_ANCHOR, MSO_AUTO_SIZE,PP_ALIGN
from pptx.chart.data import ChartData, XyChartData
from pptx.enum.chart import XL_CHART_TYPE
from pptx.enum.chart import XL_TICK_MARK
from pptx.enum.chart import XL_LEGEND_POSITION
from pptx.enum.chart import XL_CATEGORY_TYPE
prs = Presentation('templae.pptx')
def FonST(obj, s, t):
try:
obj.text_frame.paragraphs[0].font.size = Pt(s)
obj.text_frame.paragraphs[0].font.typeface = t
except AttributeError:
obj.font.size=Pt(s)
obj.font.typeface=t
title_slide_layout = prs.slide_masters[1].slide_layouts[1]
slide = prs.slides.add_slide(title_slide_layout)
shapes = slide.shapes
title = shapes.title
class MyXySeriesData(pptx.chart.data.XySeriesData):
"""
The data specific to a particular XY chart series. It provides access to
the series label, the series data points, and an optional number format
to be applied to each data point not having a specified number format.
The sequence of data points in an XY series is significant; lines are
plotted following the sequence of points, even if that causes a line
segment to "travel backward" (implying a multi-valued function). The data
points are not automatically sorted into increasing order by X value.
"""
def add_data_vector(self, vec1, vec2):
if len(vec1) != len(vec2):
return -1
else:
for i in range(0, len(vec1)):
self.add_data_point(vec1[i], vec2[i])
class MyXyChartData(pptx.chart.data.XyChartData):
"""
Переопределяем класс библиотеки pptx
"""
def add_series(self, name, number_format=None):
"""
Return an |XySeriesData| object newly created and added at the end of
this sequence, identified by *name* and values formatted with
*number_format*.
"""
series_data = MyXySeriesData(self, name, number_format)
self.append(series_data)
return series_data
# Open the workbook
xl_workbook = xlrd.open_workbook('bookxl.xlsx')
# Grab the first sheet by index
# (sheets are zero-indexed)
#
xl_sheet = xl_workbook.sheet_by_index(0)
#print ('Sheet name: %s' % xl_sheet.name)
# define chart data ---------------------
chart_data = MyXyChartData()
vec1 = [ datetime.datetime.fromordinal(int(693594+i.value )) for i in xl_sheet.col(0)]
vec2 = [ float(i.value) for i in xl_sheet.col(1)]
series_1 = chart_data.add_series('Model 1')
series_1.add_data_vector(vec1 , vec2)
# add chart to slide --------------------
x, y, cx, cy = Cm(10), Cm(3), Cm(10), Cm(8)
chart = slide.shapes.add_chart(
XL_CHART_TYPE.XY_SCATTER_SMOOTH_NO_MARKERS, x, y, cx, cy, chart_data
).chart
chart.chart_title.text_frame.text = 'YTD COMPLETION TO PLAN'
FonST(chart.chart_title, 12, 'Times New Roman')
#chart.chart_title.text_frame.paragraphs[0].font.size = Pt(12)
#chart.chart_title.text_frame.paragraphs[0].font = Pt(12)
chart.has_legend = True
chart.legend.include_in_layout = False
FonST(chart.legend, 12, 'Times New Roman')
#chart.legend.font.size = Pt(12)
chart.legend.position = XL_LEGEND_POSITION.BOTTOM
chart.series[0].smooth = True
#chart.category_axis.tick_labels.font.size=Pt(10)
#chart.value_axis.tick_labels.font.size=Pt(10)
FonST(chart.category_axis.tick_labels, 10, 'Times New Roman')
FonST(chart.value_axis.tick_labels, 10, 'Times New Roman')
#chart.category_axis.tick_labels.number_format = '0.00'
chart.value_axis.tick_labels.number_format = '0.00'
chart.value_axis.axis_title.text_frame.text = 'Something'
FonST(chart.value_axis.axis_title, 10, 'Times New Roman')
chart.category_axis.axis_title.text_frame.text = 'Дата'
FonST(chart.category_axis.axis_title, 10, 'Times New Roman')
chart.category_axis.category_type = XL_CATEGORY_TYPE.CATEGORY_SCALE
prs.save('testout.pptx')
第一个列表 'bookxl.xlsx' 的内容是:input data example, 为方便起见,输入数据如下:
01.11.2017 6.660761604
06.11.2017 7.012580588
11.11.2017 6.941095486
17.11.2017 6.85236787
20.11.2017 6.807413035
22.11.2017 6.777194047
26.11.2017 6.716288151
29.11.2017 6.670361491
01.12.2017 6.639671179
01.01.2018 6.13350148
01.02.2018 6.31542197
01.03.2018 4.600364229
01.04.2018 4.152160143
29.04.2018 3.442227537
30.04.2018 3.43343609
01.05.2018 3.425108975
01.06.2018 3.396918009
01.07.2018 3.369342609
01.08.2018 3.35360536
01.09.2018 3.351036414
01.10.2018 3.358021731
01.11.2018 3.371659755
01.12.2018 3.38805915
01.01.2019 3.406137358
01.02.2019 3.423831347
01.03.2019 3.438710981
01.04.2019 3.452972517
01.05.2019 3.464318611
01.06.2019 3.473092026
01.07.2019 3.478872101
01.08.2019 3.481948962
01.09.2019 3.482171692
01.10.2019 3.479855714
01.11.2019 3.475044618
01.12.2019 3.46824709
01.01.2020 3.459274478
现在的结果是: Stair-like plot
我想查看这样的内容: Desired result
我认为问题在于您创建的是 X/Y 图表而不是类别图表。如果您将日期值作为类别图表中的类别输入,X 轴会自动变成日期轴,并显示我认为您正在寻找的行为。
此处的项目技术文档中有一些附加信息:http://python-pptx.readthedocs.io/en/latest/dev/analysis/cht-date-axis.html
简而言之,食谱是:
- 使用 CategoryChartData 对象而不是 XyChartData
- 添加图表时使用其中一种折线图类型而不是 XY 类型(可能是 LINE 或 LINE_MARKERS)。
- 使用 datetime.date 或 datetime.datetime 对象作为类别值(而不是通常的 str 标签)。
- 可能会更改 LineSeries.smooth 以适应(可能
series.smooth = True
)。
我想这会给你想要的东西。