3

Currently I am using the following code to define and replace Placeholder (Text data) in existing Powerpoint presentations.

current_dir = os.path.dirname(os.path.realpath(__file__))

prs = Presentation(current_dir + '/test2.pptx')

slides = prs.slides

title_slide_layout = prs.slide_layouts[0]
slide = slides[0]
for shape in slide.placeholders:
    print('%d %s' % (shape.placeholder_format.idx, shape.name))
title = slide.shapes.title
subtitle1 = slide.shapes.placeholders[0]
subtitle2 = slide.shapes.placeholders[10]
subtitle10 = slide.shapes.placeholders[11]
subtitle11 = slide.shapes.placeholders[12]

subtitle1.text = "1"
subtitle2.text = "2"
subtitle10.text = "3"
subtitle11.text = "4"


slide2 = slides[1]
for shape in slide2.placeholders:
    print('%d %s' % (shape.placeholder_format.idx, shape.name))
subtitle3 = slide2.shapes.placeholders[10]
subtitle4 = slide2.shapes.placeholders[11]
subtitle5 = slide2.shapes.placeholders[12]
subtitle6 = slide2.shapes.placeholders[13]
subtitle12 = slide2.shapes.placeholders[16]
companydate = slide2.shapes.placeholders[14]

subtitle3.text = "1"
subtitle4.text = "2"
subtitle5.text = "3"
subtitle6.text = "4"
subtitle12.text = "40%"
companydate.text = "Insert company"

slide3 = slides[2]
for shape in slide3.placeholders:
     print('%d %s' % (shape.placeholder_format.idx, shape.name))
subtitle7 = slide3.shapes.placeholders[10]
subtitle8 = slide3.shapes.placeholders[11]
subtitle9 = slide3.shapes.placeholders[12]
subtitle13 = slide3.shapes.placeholders[16]
companydate2 = slide3.shapes.placeholders[14]

subtitle7.text = "1"
subtitle8.text = "2"
subtitle9.text = "3"
subtitle13.text = "5x"
companydate2.text = "Insert Company"

slide4 = slides[3]
# for shape in slide4.placeholders:
#print('%d %s' % (shape.placeholder_format.idx, shape.name))
companydate3 = slide4.shapes.placeholders[14]
companydate3.text = "Insert Company"

"'Adapting Charts'"
from pptx.chart.data import ChartData
from pptx.enum.chart import XL_CHART_TYPE
from pptx.util import Pt

"Adapting Chart 1"

prs1 = Presentation(current_dir + '/output4.pptx')
slides1 = prs1.slides

chart1 = prs1.slides[0].chart

However, I am also running analytics in the background and I was wondering if it is possible to recognize (define) charts in the same presentation along with extracting and replacing the data in those charts. These chards are not embedded in the template. As plotting charts with plotly or mathplotlib does not render a compliant image I am not able to use these , unless fully modified into the following format:Graph budget Click Correl If yes, would it be possible to give concrete coding examples?

Thanks in advance!

MattDM
  • 31
  • 3

2 Answers2

3

Yes, it's possible to do that. The documentation will be your best source.

This will find the chart shapes:

for shape in slide.shapes:
    if shape.has_chart:
        chart = shape.chart
        print('found a chart')

Data is extracted from the chart series(es):

for series in chart.series:
    for value in series.values:
        print(value)

Data is replaced by creating a new ChartData object and calling .replace_data() on the chart using that chart data object:

chart_data = ChartData(...)
...  # add categories, series with values, etc.
chart.replace_data(chart_data)

http://python-pptx.readthedocs.io/en/latest/api/chart.html#pptx.chart.chart.Chart.replace_data

scanny
  • 26,423
  • 5
  • 54
  • 80
  • Hi Scanny , Thank you very much for the answer, I will try it out asap and let you know the results. – MattDM Jun 22 '17 at 09:11
  • 1
    @scanny is there a way to print all the categorical data of a chart?, It should print all the parameters of the charts. – R__raki__ Jun 11 '19 at 13:44
0

Adding to the answer by @scanny above, this worked for me:

    if shape.name == 'Chart1':
    chart = shape.chart
    print(shape.name)

    for series in chart.plots:
        print(list(series.categories))
        cat = list(series.categories)

    for series in chart.series:
        ser = series.values
        print(series.values)

    try:    
    # ---define new chart data---
        chart_data = CategoryChartData()
        chart_data.categories = cat
        chart_data.add_series('category', df['column'])
        # ---replace chart data---
        chart.replace_data(chart_data)
    except KeyError:
        continue

Using the code above, you can print the categories and the series values, then replace them with your new values (while keeping category the same).

I added the KeyError exception because without it, you get a "rId3" error. From the forums it seems like there is some XML writing issue in writing to PPTX.

noiivice
  • 400
  • 2
  • 15