import gradio as gr import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import os from pptx import Presentation from pptx.util import Inches from matplotlib import style import tempfile # Global setup sns.set(style="whitegrid") plt.rcParams.update({'figure.max_open_warning': 0}) os.makedirs("charts", exist_ok=True) def save_chart(fig, name): path = f"charts/{name}.png" fig.savefig(path, bbox_inches='tight', dpi=300) plt.close(fig) return path def trim(df, n=500): return df.sample(n=n, random_state=42) if len(df) > n else df def create_plot(df, title, func, style_name, fs, lw, legend, cmap='Set2'): plt.style.use(style_name) fig, ax = plt.subplots(figsize=(10, 6)) func(df, ax, lw, cmap) ax.set_title(title, fontsize=fs+4) ax.tick_params(labelsize=fs) if legend: ax.legend(loc="best", fontsize=fs-2) return save_chart(fig, title.lower().replace(" ", "_")) # Plot types def line(df, ax, lw, cmap): trim(df).plot(ax=ax, lw=lw, marker='o', markersize=4, colormap=cmap) def scatter(df, ax, lw, cmap): data = trim(df) if df.shape[1] >= 2: sns.scatterplot(x=data.columns[0], y=data.columns[1], data=data, ax=ax, s=60, alpha=0.6, palette=cmap) def hist(df, ax, lw, cmap): num = df.select_dtypes('number') num.hist(ax=ax, bins=30, grid=True) if not num.empty else ax.text(0.5, 0.5, "No numerical data", ha='center') def pie(df, ax, lw, cmap): col = df.select_dtypes('object').columns[0] if not df.select_dtypes('object').empty else df.columns[0] sizes = df[col].value_counts().head(10) sizes.plot.pie(autopct='%1.1f%%', ax=ax, startangle=90) if not sizes.empty else ax.text(0.5, 0.5, "No data", ha='center') def bar(df, ax, lw, cmap): df[df.columns[0]].value_counts().head(10).plot(kind='barh', ax=ax, color='skyblue') def box(df, ax, lw, cmap): num = df.select_dtypes('number') sns.boxplot(data=num, ax=ax, palette=cmap) if not num.empty else ax.text(0.5, 0.5, "No numerical data", ha='center') plot_map = { "Line Plot": line, "Scatter": scatter, "Histogram": hist, "Pie": pie, "Bar": bar, "Box": box, } def generate_ppt(file): df = pd.read_excel(file) prs = Presentation() slide_layout = prs.slide_layouts[5] styles_available = style.available[:2] thicknesses = [2] font_sizes = [12] legends = [True] for title, func in plot_map.items(): for st in styles_available: for lw in thicknesses: for fs in font_sizes: for lg in legends: img = create_plot(df, title, func, st, fs, lw, lg) slide = prs.slides.add_slide(slide_layout) slide.shapes.add_textbox(Inches(0.5), Inches(0.3), Inches(9), Inches(1)).text_frame.text = f"{title} | {st} | lw:{lw} | fs:{fs} | legend:{lg}" slide.shapes.add_picture(img, Inches(1), Inches(1.5), width=Inches(8), height=Inches(5.5)) # Save to temporary file pptx_path = tempfile.NamedTemporaryFile(delete=False, suffix=".pptx").name prs.save(pptx_path) return pptx_path iface = gr.Interface( fn=generate_ppt, inputs=gr.File(file_types=[".xlsx"], label="Upload Excel File"), outputs=gr.File(label="Download PowerPoint"), title="📊 Auto-Chart to PowerPoint Generator", description="Upload your Excel file and get a ready-to-go .pptx with auto-generated visualizations. No effort, just vibes." ) if __name__ == "__main__": iface.launch()