Проблема с установочным значением, при котором ось категории пересекает ось значения - PullRequest
0 голосов
/ 11 сентября 2018

Я столкнулся с проблемой установки значения, при котором ось категории пересекает ось значения.Ниже примера кода

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 (последний вызов был последним): файл "", строка 56, в chart.value_axis.crosses= XL_AXIS_CROSSES.MINIMUM Файл "C: \ Users * \ AppData \ Local \ Continuum \ anaconda3 \ lib \ site-packages \ pptx \ chart \ axis.py", строка 433, в крестиках cross_xAx = self._cross_xAx Файл "C: \Пользователи * \ AppData \ Local \ Continuum \ anaconda3 \ lib \ site-packages \ pptx \ chart \ axis.py ", строка 512, в _cross_xAx cross_axId = self._element.xpath (expr) [0] IndexError: список индексов издиапазон

Я думаю, что проблема заключается в работе со значениями даты и времени на оси категорий.Потому что если я создам эту ось на основе другого типа объекта (string, float или int), все будет хорошо!

Любая помощь будет принята с благодарностью!

1 Ответ

0 голосов
/ 13 сентября 2018

Хорошо, похоже, это пробел в коде 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)

И посмотри, поможет ли это.

Если это сработает, дайте мне знать, и я открою дело, чтобы включить изменения в следующую версию.

...