使用 python-pptx 的自定义图例位置

Custom legend position with python-pptx

我想在自定义位置上设置图例。

我的最终目标是获取现有图表的设置并将相同的设置用于新图表。

我在文档中看到可以这样设置图例:

(http://python-pptx.readthedocs.io/en/latest/api/enum/XlLegendPosition.html#xllegendposition)

from pptx.enum.chart import XL_LEGEND_POSITION

chart.has_legend = True
chart.legend.position = XL_LEGEND_POSITION.CUSTOM

但是我得到一个 ValueError:

ValueError: CUSTOM (-4161) not a member of XL_LEGEND_POSITION enumeration

我是不是漏掉了什么或者如何在自定义位置上设置图例?

XL_LEGEND_POSITION.CUSTOM 成员只是报告成员(大致类似于 "read-only")。当手动调整图例(使用 UI 用鼠标拖放)时,它旨在作为 Legend.position 属性 的值。与该枚举的其他成员不同,它不是 "assignable",当然不能单独将位置设置到您想要的位置。

python-pptxAPI 尚不支持图例的自定义放置。如果您想这样做,您必须使用低级 lxml 调用来操纵底层 XML。您需要了解相关的 XML 模式和语义才能知道如何处理 XML 以产生您想要的结果。这种东西在 python-pptxpython-docx 中通常称为 "workaround function"(它们基于相同的体系结构,工作方式非常相似)。 Google 搜索 "python-pptx" 或 "python-docx" 变通方法 会发现一些用于其他目的的示例,如果您决定采用这些示例可能会有所帮助这种方法。

我找不到完整的答案,所以我认为值得发布我使用的解决方法:

from pptx.oxml.xmlchemy import OxmlElement

def SubElement(parent, tagname, **kwargs):
        element = OxmlElement(tagname)
        element.attrib.update(kwargs)
        parent.append(element)
        return element

def manuallySetLegendPosition(
                chart,
                x,
                y,
                w,
                h
                ):
    ## Inside layout, add manualLayout
    L = chart.legend._element.get_or_add_layout()
    mL = L.get_or_add_manualLayout()
    ## Add xMode and yMode and set vals to edge
    xM = SubElement(mL, 'c:xMode', val="edge")
    xY = SubElement(mL, 'c:yMode', val="edge")
    ## Add x, value is between -1 and 1 as a proportion of the chart width
    ##    point of reference on the legend is its centre, not top left
    xE = SubElement(mL, 'c:x', val=str(x))
    ## Add y, same concept as above
    yE = SubElement(mL, 'c:y', val=str(y))
    ## Add w, legend height as a proportion of chart height
    wE = SubElement(mL, 'c:w', val=str(w))
    ## Add h, same concept as above
    hE = SubElement(mL, 'c:h', val=str(h))