I am working on a Python script that generates a PowerPoint presentation with a table containing tickers. I am using the python-pptx library for this task. However, I am facing an issue in arranging the tickers side-by-side within each cell of the table.
I have a dictionary (segregated_data) containing sectors and their respective rankings, where each combination has a list of tickers. The tickers are currently displayed in a column within each cell, but I want them to be arranged side-by-side.
import pandas as pd
from pptx import Presentation
from pptx.util import Inches
from pptx.enum.text import PP_ALIGN
from pptx.enum.text import MSO_AUTO_SIZE
from pptx.util import Pt
from datetime import date
big_grid = pd.read_excel("Testing.xlsx")
sector_definitions = {
100: 'Energy',
200: 'Basic Materials',
300: 'Industrial Manufacturing',
400: 'Utilities',
500: 'Services',
600: 'Financials',
700: 'Transportation',
800: 'HealthCare',
900: 'Consumer Staples',
1000: 'Consumer Cyclicals',
1200: 'Technology',
1400: 'Communication / Media'
}
ranking_definitions = {
1: 'Bottom Fishing',
2: 'Positive Developing',
3: 'Positive Trending',
4: 'Pullback Opportunity',
5: 'Negative Developing',
6: 'Negative Trending'
}
# Segregate the data based on sector and ranking definitions
segregated_data = {}
for sector_code, sector_name in sector_definitions.items():
sector_data = big_grid[big_grid['Sector'] == sector_code]
for ranking_code, ranking_name in ranking_definitions.items():
ranking_data = sector_data[sector_data['Ranking'] == ranking_code]
if not ranking_data.empty:
key = f'{ranking_name} - {sector_name}'
segregated_data[key] = ranking_data['Tickers'].tolist()
# Create a PowerPoint presentation
presentation = Presentation()
slide = presentation.slides.add_slide(presentation.slide_layouts[6])
# Get the dimensions of the slide
slide_width = presentation.slide_width
slide_height = presentation.slide_height
# Set the margins and padding
margin_left = Inches(0.3)
margin_right = Inches(0.3)
margin_top = Inches(1.2)
margin_bottom = Inches(0.7)
# Calculate the available width and height for the table
available_width = slide_width - margin_left - margin_right
available_height = slide_height - margin_top - margin_bottom
top_left_text = slide.shapes.add_textbox(left=Inches(0.3), top=Inches(0.3), width=Inches(2), height=Inches(0.1)).text_frame
top_left_text.text = "Macro Research | Technical Research"
for paragraph in top_left_text.paragraphs:
paragraph.font.size = Pt(12)
paragraph.font.bold = True
top_right_text = slide.shapes.add_textbox(left=Inches(8.7), top=Inches(0.3), width=Inches(2), height=Inches(0.1)).text_frame
top_right_text.text = date.today().strftime('%B %d, %Y')
for paragraph in top_right_text.paragraphs:
paragraph.font.size = Pt(8)
title = slide.shapes.add_textbox(left=margin_left, top=margin_top / 2, width=available_width, height=Inches(0.5)).text_frame
title.text = "Weekly Homework Grids"
title.paragraphs[0].alignment = PP_ALIGN.CENTER
for paragraph in title.paragraphs:
paragraph.font.size = Pt(16)
paragraph.font.bold = True
# Determine the number of columns and rows based on the data
num_columns = len(ranking_definitions) + 1
num_rows = len(sector_definitions) + 1
# Add a table to the slide
table_left = margin_left
table_top = margin_top
table_width = available_width
table_height = available_height
shape = slide.shapes.add_table(rows=num_rows, cols=num_columns, left=table_left, top=table_top, width=table_width, height=table_height)
tbl = shape._element.graphic.graphicData.tbl
style_id = "{5940675A-B579-460E-94D1-54222C63F5DA}"
tbl[0][-1].text = style_id
table = shape.table
for row in table.rows:
for cell in row.cells:
cell.text_frame.auto_size = MSO_AUTO_SIZE.SHAPE_TO_FIT_TEXT
cell.text_frame.word_wrap = True
# Set header row style
header_row = table.rows[0]
for i, (ranking_code, ranking_name) in enumerate(ranking_definitions.items()):
cell = header_row.cells[i + 1] # Shift by 1 to accommodate row names
cell.text = ranking_name
cell.text_frame.paragraphs[0].font.size = Pt(7) # Adjust the font size for the header row
cell.text_frame.paragraphs[0].font.bold = True
cell.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
# Populate table with sector data
for i, (sector_code, sector_name) in enumerate(sector_definitions.items()):
row = table.rows[i + 1]
row.cells[0].text = sector_name
row.cells[0].text_frame.text = sector_name
row.cells[0].text_frame.paragraphs[0].font.size = Pt(7) # Adjust the font size for data rows
row.cells[0].text_frame.paragraphs[0].font.bold = True
row.cells[0].text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
for j, (ranking_code, ranking_name) in enumerate(ranking_definitions.items()):
key = f'{ranking_name} - {sector_name}'
tickers = segregated_data.get(key, [])
cell = row.cells[j + 1] # Shift by 1 to accommodate row names
cell.text = "\n".join(tickers)
for paragraph in cell.text_frame.paragraphs:
paragraph.font.size = Pt(5)
I have tried adjusting paragraph alignment and using line breaks ("\n"), but I haven't been successful in achieving the desired side-by-side arrangement.
Any guidance on how to modify the code to arrange tickers side-by-side within each table cell would be greatly appreciated. Thank you!

