3

I would like to update data in a Bar chart, but I am getting error at the step of accessing the object holding the chart. Here is code that gives me shape_id:

shp=prs.slides[0].shapes
for shape in shp:
    print(
        "id: %s, type: %s, name: %s"
        % (shape.shape_id, shape.shape_type, shape.name)
    )

# => **Output:** id: 7, type: CHART (3), name: Chart 6

But, when I try to use shape_id to define chart object, I am getting below error: chart = prs.slides[0].shapes[7].chart

Error:

raise IndexError("shape index out of range")
IndexError: shape index out of range

I also tried this code: chart = shp._spTree.shape_id[7].chart

Error:

TypeError: 'int' object is not subscriptable
scanny
  • 26,423
  • 5
  • 54
  • 80
Sveta
  • 161
  • 1
  • 2
  • 11

1 Answers1

2

The problem is you are using the shape-id as an index into the shapes sequence. The shape-id does not correspond to the position of that shape in the shapes "list".

To look up a shape by id (or name) you need code like this:

def find_shape_by_id(shapes, shape_id):
    """Return shape by shape_id."""
    for shape in shapes:
        if shape.shape_id == shape_id:
            return shape
    return None

or if you doing a lot of it you can use a dict for that job:

shapes_by_id = dict((s.shape_id, s) for s in shapes)

Which then gives you all the handy dict methods like:

>>> 7 in shapes_by_id
True
>>> shapes_by_id[7]
<pptx.shapes.Shape object at 0x...>
scanny
  • 26,423
  • 5
  • 54
  • 80
  • Thank you. When I used a dictionary approach, I received below output. How can it be used to access an object? (possibly chart to update) – Sveta Oct 24 '19 at 03:30
  • {4: , 5: , 13: , 6: , 7: , 8: , 77: } – Sveta Oct 24 '19 at 03:30
  • `chart = shapes_by_id[7].chart`. The returned object is a `GraphicFrame` shape which is the _container_ of the actual chart object. The extra `.chart` is required to access the chart object within the graphic-frame container: https://python-pptx.readthedocs.io/en/latest/dev/analysis/shp-graphfrm.html – scanny Oct 24 '19 at 03:41