2

I have a multi-line chart that I'm trying to update the data for. I can change the data for the data series (1 to 5) in my case using a dataframe; I'm unable to figure out how to change the range for the category axis. In the current scenario, I have the daterange starting from 2010; I can't figure out how to update that dynamically bases on input data

My chart is as shown below: Powerpoint Chart

My chart data is as below: Powerpoint chart data

My code is as below:

import pandas as pd
from pptx import Presentation
from pptx.chart.data import CategoryChartData, ChartData

df = pd.DataFrame({
    'Date':['2010-01-01','2010-02-01','2010-03-01','2010-04-01','2010-05-01'],
    'Series 1': [0.262918, 0.259484,0.263314,0.262108,0.252113],
    'Series 2': [0.372340,0.368741,0.375740,0.386040,0.388732],
    'Series 3': [0.109422,0.109256,0.112426,0.123932,0.136620],
    'Series 4': [0.109422,0.109256,0.112426,0.123932,0.136620], # copy of series 3 for easy testing
    'Series 5': [0.109422,0.109256,0.112426,0.123932,0.136620], # copy of series 3 for easy testing
})
prs = Presentation(presentation_path)    
   
def update_multiline(chart,df):
    plot = chart.plots[0]
    category_labels = [c.label for c in plot.categories]
    # series = plot.series[0]
    chart_data = CategoryChartData()
    chart_data.categories = [c.label for c in plot.categories]


    category_axis = chart.category_axis
    category_axis.minimum_scale = 1 # this should be a date
    category_axis.minimum_scale = 100 # this should be a date
    tick_labels = category_axis.tick_labels
    df = df.drop(columns=['Date'])

    for index in range(df.shape[1]):
        columnSeriesObj = df.iloc[:, index]
        chart_data.add_series(plot.series[index].name, columnSeriesObj)
    chart.replace_data(chart_data)

# ================================ slide index 3 =============================================

slide_3 = prs.slides[3]
slide_3_title = slide_3.shapes.title # assigning a title

graphic_frame = slide_3.shapes
# slide has only one chart and that's the 3rd shape, hence graphic_frame[2]
slide_3_chart = graphic_frame[2].chart
update_multiline(slide_3_chart, df)

prs.save(output_path)

How to update the date range if my date in the dataframe starts from say 2015 i.e. 'Date':['2015-01-01','2015-02-01','2015-03-01','2015-04-01','2015-05-01']

Rajat
  • 111
  • 13

1 Answers1

1

You are simply copying the categories of the old chart into the new chart with:

chart_data.categories = [c.label for c in plot.categories]

You must draw the category labels from the dataframe if you expect them to change.

scanny
  • 26,423
  • 5
  • 54
  • 80
  • Hey @scanny, thanks for the response. If my understanding is correct, the challenge is that the `Date` isn't a `category`, correct? The categories in my case would be Series 1, Series 2,... Series 5. Hence the confusion how to update the date in this scenario. – Rajat Mar 02 '21 at 19:41
  • I kind of got it. I did - new_dates = ['2021','2022','2023','2024','2025','2026','2027','2028','2029','2030'] and then chart_data.categories = new_dates. I think it need to use the "Interval between labels" property (I saw this in another answer of yours), figuring this out in the documentation as how this needs to be used. – Rajat Mar 02 '21 at 19:47
  • Is there a way to be able to display alternate labels on the category axis? I looked through the documentation and couldn't find anything. I looked at your post https://stackoverflow.com/questions/46026603/python-pptx-access-category-axis-elements-ticklblskip-tickmarkskip and you've mentioned there was nothing at that time but wondering if `python-pptx` supports it now. – Rajat Mar 02 '21 at 23:45
  • @Rajat if you mean label intervals, like only display each third category along the category axis, no, that feature is not yet present in the `python-pptx` API. – scanny Mar 03 '21 at 17:17
  • Yeah, I read that in your post. I just made mine work by passing a list to chart_data.categories like [2010, "","",""2011,"","",2012,.......2020,"",""]. Thanks for the answers though – Rajat Mar 03 '21 at 21:31