是否可以使用 python-pptx 更改图表的绘图区域大小?
Is it possible to alter the plot area size of a chart using python-pptx?
我有以下代码:
import pptx
from pptx.util import Cm
from pptx.enum.chart import XL_CHART_TYPE
from pptx.chart.data import ChartData
from random import randrange
## Select path from which the deck will be imported
path_import = r"XXX.pptx"
## Select layout
SLD_LAYOUT_TITLE_AND_CONTENT = 6 #Empty template
## Create presentation
prs = pptx.Presentation(path_import)
slide_layout = prs.slide_layouts[SLD_LAYOUT_TITLE_AND_CONTENT]
slide = prs.slides.add_slide(slide_layout)
## Create chart data
chart_data1 = ChartData()
chart_data1.categories = [f"TM {i}" for i in range(1,21)]
chart_data1.add_series('Series 1', [randrange(10) for x in range(20)])
## Add chart
chart1 = slide.shapes.add_chart(chart_type=XL_CHART_TYPE.COLUMN_CLUSTERED,
x=Cm(0.75),
y=Cm(4.71),
cx=Cm(32.12),
cy=Cm(1.76),
chart_data=chart_data1)
## Save deck to path
path_export = r"YYY.pptx"
prs.save(path_export)
所以我现在有一张带有图表的幻灯片,"chart area" 尺寸为 32.12 厘米长和 1.76 厘米宽。但是,"plot area" 维度相对较小,我想增加它们,以便它们在图表中占据更大的比例。我在文档中找不到对此的任何参考,这可能吗?
python-pptx
API 不支持覆盖图表绘图区域的自动调整大小。可以通过编写一些 low-level lxml
代码来修补某些内容,因为 PPTX 格式支持这种调整大小。但它并没有出现太多。事实上,我认为这是我第一次听到有人要求它。
在此处或其他图表组件上使用 "hard" 调整大小的缺点是您会失去一些图表自动 "internal component" 调整大小的功能。
一般来说,首选方法是在 auto-resizing 行为范围内工作,可能通过删除图例 and/or 图表标题、删除轴 tick-labels 或减小其字体大小等。您删除的每个其他组件都会为未调整的图表区域自动扩展腾出空间。
当然,我不能说哪种方法适合您的应用,因此决定权在您。但是后一种方法是最常见的,并且可以在不诉诸 low-level XML 操作的情况下完成。
我的解决方案:
from pptx.oxml.xmlchemy import OxmlElement
def SubElement(parent, tagname, **kwargs):
element = OxmlElement(tagname)
element.attrib.update(kwargs)
parent.append(element)
return element
def alterChartPlotAreaSize(
chart,
x,
y,
w,
h
):
## Get layout
plotArea = chart.chart_part._element.chart.plotArea
plotAreaChildren = plotArea.getchildren()
pacLayout = [x
for x in plotAreaChildren
if isinstance(x,pptx.oxml.chart.shared.CT_Layout)]
if len(pacLayout) == 1:
layout = pacLayout[0]
else:
layout = SubElement(plotArea, 'c:layout', val='inner')
## Get manualLayout
mL = layout.get_or_add_manualLayout()
## Remove the current values
mL.remove_if_present(*['c:layoutTarget',
'c:xMode',
'c:yMode',
'c:x',
'c:y',
'c:w',
'c:h'])
## Add layoutTarget and set val to inner
_ = SubElement(mL, 'c:layoutTarget', val='inner')
## Add xMode and yMode and set vals to edge
_ = SubElement(mL, 'c:xMode', val="edge")
_ = SubElement(mL, 'c:yMode', val="edge")
## Add x, value is between 0 and 1, where 0 is far left of chart area
## and 1 is far right of chart area
_ = SubElement(mL, 'c:x', val=str(x))
## Add y, same concept as above
_ = SubElement(mL, 'c:y', val=str(y))
## Add x, value is between 0 and 1, where 0 is very top of chart area
## and 1 is very bottom of chart area
_ = SubElement(mL, 'c:w', val=str(w))
## Add h, same concept as above
_ = SubElement(mL, 'c:h', val=str(h))
我有以下代码:
import pptx
from pptx.util import Cm
from pptx.enum.chart import XL_CHART_TYPE
from pptx.chart.data import ChartData
from random import randrange
## Select path from which the deck will be imported
path_import = r"XXX.pptx"
## Select layout
SLD_LAYOUT_TITLE_AND_CONTENT = 6 #Empty template
## Create presentation
prs = pptx.Presentation(path_import)
slide_layout = prs.slide_layouts[SLD_LAYOUT_TITLE_AND_CONTENT]
slide = prs.slides.add_slide(slide_layout)
## Create chart data
chart_data1 = ChartData()
chart_data1.categories = [f"TM {i}" for i in range(1,21)]
chart_data1.add_series('Series 1', [randrange(10) for x in range(20)])
## Add chart
chart1 = slide.shapes.add_chart(chart_type=XL_CHART_TYPE.COLUMN_CLUSTERED,
x=Cm(0.75),
y=Cm(4.71),
cx=Cm(32.12),
cy=Cm(1.76),
chart_data=chart_data1)
## Save deck to path
path_export = r"YYY.pptx"
prs.save(path_export)
所以我现在有一张带有图表的幻灯片,"chart area" 尺寸为 32.12 厘米长和 1.76 厘米宽。但是,"plot area" 维度相对较小,我想增加它们,以便它们在图表中占据更大的比例。我在文档中找不到对此的任何参考,这可能吗?
python-pptx
API 不支持覆盖图表绘图区域的自动调整大小。可以通过编写一些 low-level lxml
代码来修补某些内容,因为 PPTX 格式支持这种调整大小。但它并没有出现太多。事实上,我认为这是我第一次听到有人要求它。
在此处或其他图表组件上使用 "hard" 调整大小的缺点是您会失去一些图表自动 "internal component" 调整大小的功能。
一般来说,首选方法是在 auto-resizing 行为范围内工作,可能通过删除图例 and/or 图表标题、删除轴 tick-labels 或减小其字体大小等。您删除的每个其他组件都会为未调整的图表区域自动扩展腾出空间。
当然,我不能说哪种方法适合您的应用,因此决定权在您。但是后一种方法是最常见的,并且可以在不诉诸 low-level XML 操作的情况下完成。
我的解决方案:
from pptx.oxml.xmlchemy import OxmlElement
def SubElement(parent, tagname, **kwargs):
element = OxmlElement(tagname)
element.attrib.update(kwargs)
parent.append(element)
return element
def alterChartPlotAreaSize(
chart,
x,
y,
w,
h
):
## Get layout
plotArea = chart.chart_part._element.chart.plotArea
plotAreaChildren = plotArea.getchildren()
pacLayout = [x
for x in plotAreaChildren
if isinstance(x,pptx.oxml.chart.shared.CT_Layout)]
if len(pacLayout) == 1:
layout = pacLayout[0]
else:
layout = SubElement(plotArea, 'c:layout', val='inner')
## Get manualLayout
mL = layout.get_or_add_manualLayout()
## Remove the current values
mL.remove_if_present(*['c:layoutTarget',
'c:xMode',
'c:yMode',
'c:x',
'c:y',
'c:w',
'c:h'])
## Add layoutTarget and set val to inner
_ = SubElement(mL, 'c:layoutTarget', val='inner')
## Add xMode and yMode and set vals to edge
_ = SubElement(mL, 'c:xMode', val="edge")
_ = SubElement(mL, 'c:yMode', val="edge")
## Add x, value is between 0 and 1, where 0 is far left of chart area
## and 1 is far right of chart area
_ = SubElement(mL, 'c:x', val=str(x))
## Add y, same concept as above
_ = SubElement(mL, 'c:y', val=str(y))
## Add x, value is between 0 and 1, where 0 is very top of chart area
## and 1 is very bottom of chart area
_ = SubElement(mL, 'c:w', val=str(w))
## Add h, same concept as above
_ = SubElement(mL, 'c:h', val=str(h))