Настройка осей диаграмм в презентациях с использованием Python

Обзор

В этой статье объясняется, как настраивать оси диаграмм с помощью Aspose.Slides для Python через Java. Описываются вычисленные значения осей, переключение строк и столбцов диаграммы, видимость осей, интервалы меток категорий и делений, даты категорий и их форматирование, поворот заголовка, позиционирование осей и единицы отображения.

Получить максимальные значения на вертикальной оси диаграммы

Создайте Presentation и добавьте областьную диаграмму с данными по умолчанию. Вызовите validateChartLayout перед чтением вычисленных значений осей, чтобы макет диаграммы был актуален.

Прочитайте getActualMaxValue, getActualMinValue, а также getActualMajorUnit, getActualMinorUnit для пределов осей и интервалы делений. getActualMajorUnitScale, getActualMinorUnitScale предоставляют масштабы единиц времени, которые актуальны для осей дат. Пример сохраняет эти значения в локальные переменные и сохраняет диаграмму.

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import Presentation, ChartType, SaveFormat

presentation = Presentation()
try:
    slide = presentation.getSlides().get_Item(0)

    chart = slide.getShapes().addChart(ChartType.Area, 100, 100, 500, 350)
    chart.validateChartLayout()

    max_value = chart.getAxes().getVerticalAxis().getActualMaxValue()
    min_value = chart.getAxes().getVerticalAxis().getActualMinValue()

    major_unit = chart.getAxes().getVerticalAxis().getActualMajorUnit()
    minor_unit = chart.getAxes().getVerticalAxis().getActualMinorUnit()

    major_unit_scale = chart.getAxes().getVerticalAxis().getActualMajorUnitScale()
    minor_unit_scale = chart.getAxes().getVerticalAxis().getActualMinorUnitScale()

    presentation.save("AxisValues_out.pptx", SaveFormat.Pptx)
finally:
    presentation.dispose()

Переключить данные между осями

Используйте switchRowColumn для обмена ролями серий и категорий в данных диаграммы. Каждая прежняя категория становится серией, а каждая прежняя серия — категорией. Это меняет способ группировки данных; оси горизонтальная и вертикальная не меняются местами. В примере используется setRange, чтобы привязать данные по умолчанию к Sheet1!A1:D5, включая строку заголовка и столбец категорий, перед переключением строк и столбцов. Сохраняется диаграмма с четырьмя сериями и тремя категориями.

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import Presentation, ChartType, SaveFormat

presentation = Presentation()
try:
    slide = presentation.getSlides().get_Item(0)

    chart = slide.getShapes().addChart(ChartType.ClusteredColumn, 100, 100, 400, 300)
    chart.getChartData().setRange("Sheet1!A1:D5")
    chart.getChartData().switchRowColumn()

    presentation.save("SwitchChartRowColumns_out.pptx", SaveFormat.Pptx)
finally:
    presentation.dispose()

Отключить вертикальную ось для линейных диаграмм

Вызовите setVisible с False для вертикальной оси, чтобы скрыть её. В примере создаётся линейная диаграмма с данными по умолчанию и сохраняется с скрытой вертикальной осью.

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import Presentation, ChartType, SaveFormat

presentation = Presentation()
try:
    slide = presentation.getSlides().get_Item(0)

    chart = slide.getShapes().addChart(ChartType.Line, 100, 100, 400, 300)
    chart.getAxes().getVerticalAxis().setVisible(False)

    presentation.save("HiddenVerticalAxis.pptx", SaveFormat.Pptx)
finally:
    presentation.dispose()

Отключить горизонтальную ось для линейных диаграмм

Вызовите setVisible с False для горизонтальной оси, чтобы скрыть её. В примере создаётся линейная диаграмма с данными по умолчанию и сохраняется с скрытой горизонтальной осью.

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import Presentation, ChartType, SaveFormat

presentation = Presentation()
try:
    slide = presentation.getSlides().get_Item(0)

    chart = slide.getShapes().addChart(ChartType.Line, 100, 100, 400, 300)
    chart.getAxes().getHorizontalAxis().setVisible(False)

    presentation.save("HiddenHorizontalAxis.pptx", SaveFormat.Pptx)
finally:
    presentation.dispose()

Изменить ось категорий

Используйте setCategoryAxisType, чтобы выбрать ось категорий типа дата или текст. В этом примере требуется ExistingChart.pptx, где диаграмма является первой фигурой на первом слайде, а ячейки категорий содержат числовые значения дат Excel. Ось горизонтальная меняется на ось дат. Вызов setAutomaticMajorUnit с False, setMajorUnit с 1 и setMajorUnitScale с TimeUnitType.Months размещает основные деления с интервалом в один месяц.

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import Presentation, SaveFormat, CategoryAxisType, TimeUnitType

presentation = Presentation("ExistingChart.pptx")
try:
    slide = presentation.getSlides().get_Item(0)

    chart = slide.getShapes().get_Item(0)
    chart.getAxes().getHorizontalAxis().setCategoryAxisType(CategoryAxisType.Date)
    chart.getAxes().getHorizontalAxis().setAutomaticMajorUnit(False)
    chart.getAxes().getHorizontalAxis().setMajorUnit(1)
    chart.getAxes().getHorizontalAxis().setMajorUnitScale(TimeUnitType.Months)

    presentation.save("ChangeChartCategoryAxis_out.pptx", SaveFormat.Pptx)
finally:
    presentation.dispose()

Управление интервалами меток оси категорий

Когда диаграмма имеет много категорий, уменьшите количество видимых меток оси, не удаляя категории и точки данных. Вызовите setAutomaticTickLabelSpacing с False, затем передайте желаемый интервал категории в setTickLabelSpacing. Для текстовых категорий в их обычном порядке отсчёт начинается с первой категории:

Интервал Отображаемые метки в примере
1 Категория 1, Категория 2, Категория 3, … Категория 24
2 Категория 1, Категория 3, Категория 5, … Категория 23
3 Категория 1, Категория 4, Категория 7, … Категория 22

Интервал 3 отображает каждую третью метку, между отображаемыми метками скрываются две. Это не удаляет соответствующие столбцы. Автоматический интервал выбирает значение исходя из доступного пространства; он не обязательно отображает каждую метку.

Для делений существуют отдельные настройки. Вызовите setAutomaticTickMarksSpacing с False и используйте setTickMarksSpacing для задания их интервала. Например, 1 оставляет деление на каждом интервале категории, в то время как метки появляются лишь каждые три категории. Используйте setMajorTickMark с видимым стилем, чтобы увидеть результат. Повторный вызов любого из автоматических параметров с True позволяет диаграмме снова подобрать автоматический интервал.

Следующий самостоятельный пример создаёт 24 категории и одну серию, затем сохраняет три слайда в CategoryAxisIntervals.pptx: автоматический интервал, ручная настройка интервала меток при независимых делениях и восстановленный автоматический интервал. Две копии сохраняют исходные данные диаграммы. Исходная презентация не требуется. Горизонтальный текст меток упрощает визуальное восприятие плотности.

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import Presentation, ChartType, SaveFormat, CategoryAxisType, TickMarkType

presentation = Presentation()
try:
    slide = presentation.getSlides().get_Item(0)

    chart = slide.getShapes().addChart(ChartType.ClusteredColumn, 30, 40, 660, 320)

    chart.setLegend(False)
    chart.getChartData().getCategories().clear()
    chart.getChartData().getSeries().clear()

    workbook = chart.getChartData().getChartDataWorkbook()
    workbook.clear(0)

    series = chart.getChartData().getSeries().add(ChartType.ClusteredColumn)
    for i in range(24):
        category_cell = workbook.getCell(0, i + 1, 0, f"Category {i + 1}")
        chart.getChartData().getCategories().add(category_cell)
        value_cell = workbook.getCell(0, i + 1, 1, float(10 + i % 6 * 5))
        series.getDataPoints().addDataPointForBarSeries(value_cell)

    axis = chart.getAxes().getHorizontalAxis()
    axis.setCategoryAxisType(CategoryAxisType.Text)
    axis.getTextFormat().getTextBlockFormat().setRotationAngle(0)
    axis.getTextFormat().getPortionFormat().setFontHeight(12)
    axis.setMajorTickMark(TickMarkType.Outside)
    axis.setAutomaticTickLabelSpacing(True)
    axis.setAutomaticTickMarksSpacing(True)

    # Слайд 2: показывать каждую третью метку, но оставлять деление для каждой категории.
    manual_slide = presentation.getSlides().addClone(slide)
    manual_chart = manual_slide.getShapes().get_Item(0)
    manual_axis = manual_chart.getAxes().getHorizontalAxis()
    manual_axis.setAutomaticTickLabelSpacing(False)
    manual_axis.setTickLabelSpacing(3)
    manual_axis.setAutomaticTickMarksSpacing(False)
    manual_axis.setTickMarksSpacing(1)

    # Слайд 3: позволить диаграмме снова выбрать оба интервала.
    restored_slide = presentation.getSlides().addClone(manual_slide)
    restored_chart = restored_slide.getShapes().get_Item(0)
    restored_chart.getAxes().getHorizontalAxis().setAutomaticTickLabelSpacing(True)
    restored_chart.getAxes().getHorizontalAxis().setAutomaticTickMarksSpacing(True)

    presentation.save("CategoryAxisIntervals.pptx", SaveFormat.Pptx)
finally:
    presentation.dispose()

Автоматический интервал (слайд 1): В этом отображении каждая вторая метка категории отображается и переносится на две строки. Автоматический результат может различаться в зависимости от размера диаграммы, шрифтов и рендерера.

Автоматическое размещение меток категорий при отображении всех 24 столбцов

Ручной интервал (слайд 2): Каждая третья метка отображается в одну строку, в то время как деления остаются на каждом интервале категории. Все 24 столбца, включая те, у которых нет меток, остаются видимыми с теми же значениями. Слайд 3 восстанавливает автоматический вид, показанный выше.

Ручной интервал меток категории в три при отображении всех 24 столбцов

Выберите правильную ось и интервал

Используйте этот интервал по количеству категорий для текстовой оси категорий, например для оси категорий столбчатой, линейной, областной или гистограммы. В столбчатой диаграмме это горизонтальная ось. В горизонтальной гистограмме ось категорий вертикальна, поэтому применяйте эти параметры к оси, возвращаемой методом getVerticalAxis. Интервалы делений также применимы к оси серии в диаграммах, где она присутствует.

Не используйте интервал меток категории для задания числовой шкалы оси значений. На оси значений setMajorUnit задаёт разницу в значениях: например, основной шаг 10 создаёт деления 0, 10, 20 и т.д., если ось начинается с нуля. Интервал меток категории 3 считает позиции категорий независимо от их значений. Точечные и пузырьковые диаграммы используют оси значений, а не текстовую ось категорий. Для оси дат используйте основанные на времени основные единицы и масштабы, как описано в разделе Change a Category Axis.

from datetime import date

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import Presentation, ChartType, SaveFormat, CategoryAxisType

presentation = Presentation()
try:
    slide = presentation.getSlides().get_Item(0)

    chart = slide.getShapes().addChart(ChartType.Line, 50, 50, 450, 300)

    chart.getChartData().getCategories().clear()
    chart.getChartData().getSeries().clear()

    workbook = chart.getChartData().getChartDataWorkbook()
    workbook.clear(0)

    base_date = date(1899, 12, 30)

    series = chart.getChartData().getSeries().add(ChartType.Line)
    for i in range(4):
        category_date = date(2015 + i, 1, 1)
        category_value = float((category_date - base_date).days)
        category_cell = workbook.getCell(0, i + 1, 0, category_value)
        chart.getChartData().getCategories().add(category_cell)

        value_cell = workbook.getCell(0, i + 1, 1, float(i + 1))
        series.getDataPoints().addDataPointForLineSeries(value_cell)

    chart.getAxes().getHorizontalAxis().setCategoryAxisType(CategoryAxisType.Date)
    chart.getAxes().getHorizontalAxis().setNumberFormatLinkedToSource(False)
    chart.getAxes().getHorizontalAxis().setNumberFormat("yyyy")

    presentation.save("DateAxisFormat.pptx", SaveFormat.Pptx)
finally:
    presentation.dispose()

Установить формат даты для значений оси категорий

Пример заменяет данные диаграммы по умолчанию четырьмя годовыми значениями. Даты хранятся как серийные номера OLE Automation в первом листе (индекс 0), вычисляемые как количество дней, прошедших с 30 декабря 1899 года. Используйте setCategoryAxisType с CategoryAxisType.Date, вызовите setNumberFormatLinkedToSource с False и передайте yyyy в setNumberFormat, чтобы метки категорий отображали четырёхзначный год независимо от форматирования ячейки.

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import Presentation, ChartType, SaveFormat

presentation = Presentation()
try:
    slide = presentation.getSlides().get_Item(0)

    chart = slide.getShapes().addChart(ChartType.ClusteredColumn, 50, 50, 450, 300)
    chart.getAxes().getVerticalAxis().setTitle(True)
    chart.getAxes().getVerticalAxis().getTitle().addTextFrameForOverriding("Value")
    chart.getAxes().getVerticalAxis().getTitle().getTextFormat().getTextBlockFormat().setRotationAngle(90)

    presentation.save("RotatedAxisTitle.pptx", SaveFormat.Pptx)
finally:
    presentation.dispose()

Установить угол вращения заголовка оси диаграммы

Вызовите setTitle с True для вертикальной оси, задайте текст заголовка и установите угол вращения в форматировании текстового блока заголовка. Угол измеряется в градусах; в этом примере сохраняется столбчатая диаграмма с заголовком оси значений, повернутым на 90 градусов.

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import Presentation, ChartType, SaveFormat

presentation = Presentation()
try:
    slide = presentation.getSlides().get_Item(0)

    chart = slide.getShapes().addChart(ChartType.ClusteredColumn, 50, 50, 450, 300)
    chart.getAxes().getHorizontalAxis().setAxisBetweenCategories(True)

    presentation.save("AxisBetweenCategories.pptx", SaveFormat.Pptx)
finally:
    presentation.dispose()

Установить позицию оси на оси категории или значения

Используйте setAxisBetweenCategories, чтобы контролировать, пересекает ли ось значений ось категорий между категориями или на делениях категории. Эта настройка применяется к осям категорий. В примере параметр установлен в True для горизонтальной оси категории в столбчатой диаграмме и результат сохраняется.

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import Presentation, ChartType, SaveFormat, DisplayUnitType

presentation = Presentation()
try:
    slide = presentation.getSlides().get_Item(0)

    chart = slide.getShapes().addChart(ChartType.ClusteredColumn, 50, 50, 450, 300)
    chart.getAxes().getVerticalAxis().setDisplayUnit(DisplayUnitType.Millions)

    presentation.save("Result.pptx", SaveFormat.Pptx)
finally:
    presentation.dispose()

Установить единицу отображения на оси значений диаграммы

Используйте setDisplayUnit для масштабирования меток на оси значений без изменения исходных данных. При установке DisplayUnitType в Millions значение 60 000 000 отображается как 60. В примере создаётся столбчатая диаграмма и к её вертикальной оси применяется единица отображения «миллионы».

FAQ

Как задать значение пересечения одной оси с другой (пересечение осей)?

Используйте setCrossType для выбора поведения пересечения. Чтобы задать числовое значение пересечения, используйте setCrossAt. Эти настройки позволяют переместить пересечение осей к подходящей базовой линии.

Как позиционировать метки делений относительно оси?

Вызовите setTickLabelPosition с использованием TickLabelPositionType: Low, High, NextTo или None. Чтобы управлять самими делениями, используйте setMajorTickMark или setMinorTickMark; они независимы от позиционирования меток.