类别轴与值轴相交的设置值问题

Problem with setting value at which category axis intersect value axis

我在设置类别轴与值轴相交的值时遇到问题。 下面是代码示例

import time
import datetime


import traceback
import sys
from pptx import Presentation
from pptx.chart.data import ChartData
from pptx.enum.chart import XL_CHART_TYPE,XL_AXIS_CROSSES
from pptx.util import Inches
import pptx
from pptx import Presentation
from pptx.util import Cm, Pt
from pptx.enum.text import MSO_ANCHOR,MSO_VERTICAL_ANCHOR, MSO_AUTO_SIZE,PP_ALIGN
from pptx.chart.data import CategoryChartData, ChartData
from pptx.enum.chart import XL_CHART_TYPE
from pptx.enum.chart import XL_TICK_MARK, XL_MARKER_STYLE
from pptx.enum.chart import XL_LEGEND_POSITION
from pptx.dml.chtfmt import ChartFormat
from pptx.dml.line import LineFormat
from pptx.dml.color import ColorFormat, RGBColor
from pptx.enum.dml import MSO_LINE
prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[5])
chart_data = ChartData()


chart_data.categories = [datetime.datetime.strptime('2012-02-09', '%Y-%m-%d'), datetime.datetime.strptime('2012-04-09', '%Y-%m-%d'), datetime.datetime.strptime('2012-09-09', '%Y-%m-%d')]
chart_data.add_series('West',    (32.2, 28.4, 34.7))
chart_data.add_series('East',    (24.3, 30.6, 20.2))
chart_data.add_series('Midwest', (20.4, 18.3, 26.2))
x, y, cx, cy = Inches(2), Inches(2), Inches(6), Inches(4.5)
chart = slide.shapes.add_chart(
    XL_CHART_TYPE.LINE_MARKERS, x, y, cx, cy, chart_data
).chart
chart.has_legend = True
chart.legend.include_in_layout = False
chart.series[0].smooth = True
points = chart.plots[0].series[0].points
ccount = 1;
period = int(len(points)/1.0)
chart.plots[0].series[0].marker.style = XL_MARKER_STYLE.NONE
for point in points:
    if ccount== period:
        point.marker.style = 8
        fill = point.marker.format.fill
        fill.solid()
        fill.fore_color.rgb = RGBColor(*[0,0,0])
        point.marker.format.line.color.rgb = RGBColor(*[0,0,0])
        ccount = 1
    else:
        ccount +=1

try:
    chart.value_axis.crosses = XL_AXIS_CROSSES.MINIMUM
except Exception as error:
    traceback.print_exc()


chart.has_legend = True
chart.legend.include_in_layout = False
chart.legend.position = XL_LEGEND_POSITION.BOTTOM
chart.legend.font.size = Pt(6)

prs.save('chart-01.pptx')

Python iterpreter 显示这样的错误:

Traceback (most recent call last): File "", line 56, in chart.value_axis.crosses = XL_AXIS_CROSSES.MINIMUM File "C:\Users*\AppData\Local\Continuum\anaconda3\lib\site-packages\pptx\chart\axis.py", line 433, in crosses cross_xAx = self._cross_xAx File "C:\Users*\AppData\Local\Continuum\anaconda3\lib\site-packages\pptx\chart\axis.py", line 512, in _cross_xAx cross_axId = self._element.xpath(expr)[0] IndexError: list index out of range

我认为问题在于类别轴内的日期时间值。因为如果我根据另一种类型的对象(字符串、浮点数或整数)创建这个轴,一切都会好的!

如有任何帮助,我们将不胜感激!

好的,这看起来像是 ValueAxis 代码中的一个空白,我们在前一段时间添加 DateAxis 时遗漏了。

试试这个。将此函数添加到代码中方便的地方:

from ..enum.chart import XL_AXIS_CROSSES


def set_date_crosses(value_axis, value):
    """*value* is a member of XL_AXIS_CROSSES."""
    xAx = value_axis._elemement

    def _cross_xAx(self):
        """Axis element in same group (pri/sec) that crosses this axis."""
        crossAx_id = xAx.crossAx.val
        expr = (
            '(../c:catAx | ../c:valAx | ../c:dateAx)/c:axId[@val="%d"]'
            % crossAx_id
        )
        cross_axId = xAx.xpath(expr)[0]
        return cross_axId.getparent()

    cross_xAx = _cross_xAx()

    if value == XL_AXIS_CROSSES.CUSTOM:
        if cross_xAx.crossesAt is not None:
            return

    cross_xAx._remove_crosses()
    cross_xAx._remove_crossesAt()

    if value == XL_AXIS_CROSSES.CUSTOM:
        cross_xAx._add_crossesAt(val=0.0)
        return

    cross_xAx._add_crosses(val=value)

然后将 chart.value_axis.crosses = XL_AXIS_CROSSES.MINIMUM 更改为:

set_date_crosses(chart.value_axis, XL_AXIS_CROSSES.MINIMUM)

看看是否能解决问题。

如果可行,请告诉我,我会开一个案例将更改合并到下一个版本中。