Search code examples
pythonpowerpointpython-pptx

How to add a data label that sum my stack histogram


I'm working with pptx to create PowerPoint presentation. I want to add a data label that is the sum of each stack.

I successfully added the value on each different data with this.

if isValueOnGraph :
        plot = chart.plots[0]
        plot.has_data_labels = True
        data_labels = plot.data_labels
        data_labels.font.size = Pt(7)
        data_labels.font.color.rgb = RGBColor(0x0A, 0x42, 0x80)
        if million:
            
            data_labels.number_format = "0.0,,\"M\""
        else:
            data_labels.number_format = '0.00'

Result : my  PowerPoint generation

And here is what I want enter image description here

Bonus point if the totals do not scale up my y axis

Thank you


Solution

  • EDIT:

    As a disclaimer I have to say that this is a workaround, but I couldn't achieve what I suggested with the XL_LABEL_POSITION in conbination with XL_CHART_TYPE.COLUMN_STACKED.

    I've tried to add another Series to use its text frame as OP intended. Said Series can have different values to increment or decrement its y-axis, since its colour is set to transparent. This is the code with the docs examples:

    from pptx import Presentation
    from pptx.dml.color import RGBColor
    from pptx.chart.data import ChartData
    from pptx.enum.chart import XL_LABEL_POSITION
    from pptx.enum.chart import XL_CHART_TYPE
    from pptx.util import Inches, Pt
    
    prs = Presentation()
    slide = prs.slides.add_slide(prs.slide_layouts[5])
    
    
    chart_data = ChartData()
    chart_data.categories = ['East', 'West', 'Midwest']
    chart_data.add_series('Q1 Sales', (19.2, 21.4, 16.7))
    chart_data.add_series('Q2 Sales', (22.3, 28.6, 15.2))
    chart_data.add_series('Q3 Sales', (20.4, 26.3, 14.2))
    # Change these values to adjust the labels hight
    chart_data.add_series('Total', (10, 10, 10))
    
    x, y, cx, cy = Inches(2), Inches(2), Inches(6), Inches(4.5)
    
    graphic_frame = slide.shapes.add_chart(
        XL_CHART_TYPE.COLUMN_STACKED, x, y, cx, cy, chart_data
    )
    
    chart = graphic_frame.chart
    
    plot = chart.plots[0]
    plot.has_data_labels = True
    data_labels = plot.data_labels
    
    data_labels.font.size = Pt(13)
    data_labels.font.color.rgb = RGBColor(0x0A, 0x42, 0x80)
    # Workaround:
    for point in plot.series[-1].points:
        # Setting each point's bg to transparent
        point.format.fill.background()
        point.data_label.has_text_frame = True
        # Value to display
        point.data_label.text_frame.text = '10000M'
    
    prs.save('chart-01.pptx')
    

    Output: Workaround output with op's desired labels

    Original post:

    You have to simply specify the location of your data_labels, in your case I think you want to add another label and specify its position with XL_LABEL_POSITION.OUTSIDE_END.

    This is my output using the example in the docs

    from pptx import Presentation
    from pptx.dml.color import RGBColor
    from pptx.chart.data import CategoryChartData, ChartData
    from pptx.enum.chart import XL_LABEL_POSITION
    from pptx.enum.chart import XL_CHART_TYPE
    from pptx.util import Inches, Pt
    
    prs = Presentation()
    slide = prs.slides.add_slide(prs.slide_layouts[5])
    
    
    chart_data = ChartData()
    chart_data.categories = ['East', 'West', 'Midwest']
    chart_data.add_series('Q1 Sales', (19.2, 21.4, 16.7))
    chart_data.add_series('Q2 Sales', (22.3, 28.6, 15.2))
    chart_data.add_series('Q3 Sales', (20.4, 26.3, 14.2))
    
    x, y, cx, cy = Inches(2), Inches(2), Inches(6), Inches(4.5)
    slide.shapes.add_chart(
        XL_CHART_TYPE.COLUMN_CLUSTERED, x, y, cx, cy, chart_data
    )
    
    graphic_frame = slide.shapes.add_chart(
        XL_CHART_TYPE.COLUMN_CLUSTERED, x, y, cx, cy, chart_data
    )
    
    chart = graphic_frame.chart
    
    plot = chart.plots[0]
    plot.has_data_labels = True
    data_labels = plot.data_labels
    
    data_labels.font.size = Pt(13)
    data_labels.font.color.rgb = RGBColor(0x0A, 0x42, 0x80)
    data_labels.position = XL_LABEL_POSITION.OUTSIDE_END
    
    
    prs.save('chart-01.pptx')
    

    Example of the upstated XL_LABEL_POSITION.OUTSIDE_END using the example on the ufficial docs of python-pptx