2
votes

I have a single layout that will be used to generate hundreds of slides displaying data contained on an Excel file.

I've been able to write a macro with python-pptx (I'm not familiar with VBA) generating slides with the required text, using PowerPoint Layout Placeholders.

Now I need to add a chart on each slide (each chart containing specific data series), based on a chart specified in my Layout. Is possible to achieve that with python-pptx? If not, what would be the alternative (using Python)?

1

1 Answers

2
votes

It is possible. You can either work with chart placeholders or you can get your parameters from the specified layout chart and create a new chart based on the layout chart.

All the parameters are well documented at https://python-pptx.readthedocs.io/en/latest/.

Here is a example more or less taken from the documentation for working with chart placeholders:

from pptx import Presentation
from pptx.chart.data import CategoryChartData
from pptx.enum.chart import XL_CHART_TYPE

prs = Presentation('test.pptx')

# either add slide with chart placeholder layout 
slide = prs.slides.add_slide(prs.slide_layouts[1])
# or choose existing slide
slide = prs.slides[3]

# get the relevant placeholder object
for shape in slide.placeholders:
        print( '%d %s' % (shape.placeholder_format.idx, shape.name))
placeholder = prs.slides[3].placeholders[10]  # idx key, not position

# it's important to have chart placeholder 
placeholder.name
# 'Chart Placeholder 1'
placeholder.placeholder_format.type
# CHART (12)

# fill ChartData object with your data
chart_data = CategoryChartData()
chart_data.categories = ['East', 'West', 'Midwest']
chart_data.add_series('Series 1', (19.2, 21.4, 16.7))

graphic_frame = placeholder.insert_chart(XL_CHART_TYPE.COLUMN_CLUSTERED, chart_data)

The other possibility is more complicated but you can define nearly every detail of the produced chart based on the defined 'layout'. For this case you need a powerpoint slide with an appropriate formatted example chart.

# presentation with example chart
prs = Presentation('chart-01.pptx')
# presentation to add the new chart to
prs2 = Presentation('test1.pptx')
blank_slide_layout = prs2.slide_layouts[6]

# get information from the example chart
# shape which contains chart
bchart = prs.slides[3].shapes[0]

cx = deepcopy(bchart.width)
cy = deepcopy(bchart.height)
x = deepcopy(bchart.left)
y = deepcopy(bchart.top)

chart_type = bchart.chart.chart_type

# further formatting information possible:
# bchart.chart.has_legend, bchart.chart.legend..., bchart.chart.value_axis..., bchart.chart.category_axis...

# define chart area
chart_pl_area = deepcopy(bchart.chart._chartSpace.chart.plotArea[0]) 


# define chart data
chart_data = CategoryChartData()
chart_data.categories = ['East', 'West', 'Midwest']
chart_data.add_series('Series 1', (19.2, 21.4, 16.7))

# add new slide without chart/blank
new_sli = prs2.slides.add_slide(blank_slide_layout)
# add chart with defined parameters and data
new_chart = new_sli.shapes.add_chart(
        chart_type, x, y, cx, cy, chart_data
        ) 

I hope the idea gets clear. The placeholder-way is easier to go, but if you need to specify more than what is possible in a placeholder, you need to go the second way.