0

I would like to add a title (from a list titles) to each of my charts in a loop, but the loop is failing when I try to add a text box to the chart (with iterator). Are iterator values allowed to serve as titles for charts? I'm using Python 3.6. Any ideas?

cleaned = [['AF In', 0.281777948141098],  ['AF Top', 0.11941492557525635],  ['AF View', 12.46446630278714],  ['AF  Non',   'AF V', 0.6745020151138306, 0.6817344427108765],  ['AF Cab',   'AF N',   'AF HB', 0.6878681182861328, 0.2603790760040283, 0.05175277590751648]]

titles = ['first', 'second', 'third', 'fourth', 'fifth']

from pptx import Presentation
from pptx.chart.data import ChartData
from pptx.chart.data import XyChartData
from pptx.enum.chart import XL_CHART_TYPE
from pptx.util import Inches,Pt
from pptx.enum.chart import XL_LABEL_POSITION
from pptx.dml.color import RGBColor
from pptx.dml import fill
from pptx.chart.chart import ChartTitle
from pptx.chart.chart import Chart

# create presentation
prs = Presentation()

#For each list items from query_results (cleaned)
for idx, (chart_result, t) in enumerate(zip(cleaned, titles)):
    #define size of chart
    x, y, cx, cy = Inches(2), Inches(2), Inches(6), Inches(4.5)

    try:

        #split the results into two arrays
        arr1, arr2 = np.array_split(chart_result,2)
        #create a table for chart data
        chart_data = CategoryChartData()
        #assign arr1 to categories
        chart_data.categories = arr1
        #assign arr2 to series
        chart_data.add_series('series_1',(float(x) for x in arr2))

        #add slide
        prs.slides.add_slide(prs.slide_layouts[6])
        #add chart to slide by index
        prs.slides[idx].shapes.add_chart(XL_CHART_TYPE.COLUMN_CLUSTERED, x, y, cx, cy, chart_data)
        #chart = shapes[0].chart
        chart.chart_title.text_frame.text = t

    except:
        print(f'chart load failed {idx}')
SoSincere3
  • 117
  • 1
  • 10

2 Answers2

1

Make sure you actually have a reference to the chart object; I don't see the lines that would give that to you in your code. I recommend:

chart = prs.slides[idx].shapes.add_chart(...).chart

The object returned by .add_chart() is a graphic-frame shape. This shape contains the chart, which is obtained using the .chart property.

Then your assignment in the last line of the try block should succeed.

scanny
  • 26,423
  • 5
  • 54
  • 80
  • This worked for adding the chart titles but it creates the chart without a title and then adds a chart with the title on top of it. How do I get just one chart to add instead of two? – SoSincere3 Feb 28 '19 at 23:47
0

I figured out that the code I had was iterating through the slides twice. I replaced the following code:

    #add slide
    prs.slides.add_slide(prs.slide_layouts[6])
    #add chart to slide by index
    prs.slides[idx].shapes.add_chart(XL_CHART_TYPE.COLUMN_CLUSTERED, x, y, cx, cy, chart_data)
    #chart = shapes[0].chart
    chart.chart_title.text_frame.text = t

With the following code:

    #add slide
    slide = prs.slides.add_slide(prs.slide_layouts[6])
    #add chart to slide with title
    chart = slide.shapes.add_chart(XL_CHART_TYPE.COLUMN_CLUSTERED, x, y, cx, cy, chart_data).chart
    chart.chart_title.text_frame.text = t

I think the prs.slides[idx] was messing it up.

SoSincere3
  • 117
  • 1
  • 10