是否可以使用python-pptx更改图表的绘图区域大小?

时间:2019-07-25 14:49:30

标签: python 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)

因此,我现在有一张带有图形的幻灯片,“图表区域”的尺寸为32.12厘米长和1.76厘米宽。但是,“绘图区域”的尺寸相对较小,我想增加它们的大小,以便它们在图表中占更大的比例。我在文档中找不到对此的任何引用,这可能吗?

2 个答案:

答案 0 :(得分:1)

python-pptx不支持API来覆盖自动绘制图表区域的大小。可以通过编写一些低级lxml代码来修补某些内容,因为PPTX格式支持这种大小调整。但这并没有太多。实际上,我认为这是我第一次听到有人要它。

在此处或在其他图表组件上使用“硬”大小调整的缺点是,您会失去一些图表会自动进行的“内部组件”大小调整。

通常,首选方法是在这种自动调整大小的行为内工作,方法可能是删除图例和/或图表标题,删除轴刻度标签或减小其字体大小等。要删除的每个其他组件都会使调整后的图表区域将自动扩展到的空间。

我当然不能说哪种方法最适合您的应用,所以该决定取决于您。但是,后一种方法最为常见,无需借助低级XML操作即可完成。

答案 1 :(得分:0)

我的解决方案:

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))