scanny / python-pptx

Create Open XML PowerPoint documents in Python
MIT License
2.44k stars 528 forks source link

Accessing points in pie charts using category name as an indexer #737

Closed manuelpetra27 closed 3 years ago

manuelpetra27 commented 3 years ago

Hi Scanny,

Awesome work on the pptx library ! However I've got a question: I want to edit the color of a certain category in pie chart chart based on the name of the category (since I will iterate the code for different sets of data where they may have different category names.

So for example, instead of writing:

points = pie_chart.plots[0].series[0].points fill = points[0].format.fill fill.solid() fill.fore_color.rgb = RGBColor(255, 0, 0)

Can we use the chart data category as the index for the point? Something like this: points = pie_chart.plots[0].series[0].points fill = points['the name of a category'].format.fill

So that I can have a consistent color for a certain category regardless of different category length. I have seen this thread - (https://stackoverflow.com/questions/34264715/python-pptx-custom-color-for-each-category) but it seems have not answered my question.

Thank you very much ! Regards, Petra

scanny commented 3 years ago

No. Points are accessed by position and do not have a name.

But you can whip up something of your own to do that if you want, perhaps something like this:

plot = pie_chart.plots[0]
points = plot.series[0].points

points_by_category = {
    category: points[i]
    for i, category in enumerate(plot.categories)
}

fill = points_by_category["the name of a category"].format.fill
fill.solid()
fill.fore_color.rgb = RGBColor(255, 0, 0)
manuelpetra27 commented 3 years ago

Hi Scanny, thanks ! One more question if you dont mind: Is there a way to delete a specific point/category in a chart after a chart is made? I tried to use points_by_category.["the name of a category"].pop() and .remove() and also del points_by_category.["the name of a category"], but none of them work.

The problem with the solution you mentioned last time is that some files that i iterate have different category names, so it gives me an error. So I tried to add zeros to the category without any values and removing the categories with zero values after coloring all of the categories. Hope that makes sense.

Thank you very much ! Cheers, Petra

scanny commented 3 years ago

No. If you want to remove a point you need to replace the data for the whole chart (with a ChartData object having one fewer categories).

Instead you could look up colors by category instead of looking up points by category name:

colors_by_category = {
    "cat-name-1": RGBColor(0x0F, 0x2B, 0x17"),
    "cat-name-2": RGBColor(0x2B, 0x0F, 0x17"),
    "cat-name-3": RGBColor(0x17, 0x2B, 0x0F"),
    ...
}

plot = pie_chart.plots[0]
points = plot.series[0].points

for i, category in enumerate(plot.categories):
    color = colors_by_category.get(category)
    if color is None:
        continue
    fill = points[i].format.fill
    fill.solid()
    fill.fore_color.rgb = color
manuelpetra27 commented 3 years ago

Thank you Scanny ! It works !

Cheers