
Data Viz Deck
- 54 installs
- 93 repo stars
- Updated May 14, 2026
- thatrebeccarae/claude-marketing
Helps with ai & agent building tasks.
About
data-viz-deck is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- data-viz-deck
- AI & Agent Building
- AI-coding skill
Data Viz Deck by the numbers
- 54 all-time installs (skills.sh)
- +3 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #6,877 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/thatrebeccarae/claude-marketing --skill data-viz-deckAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 54 |
|---|---|
| repo stars | ★ 93 |
| Last updated | May 14, 2026 |
| Repository | thatrebeccarae/claude-marketing ↗ |
What it does
Helps with ai & agent building tasks.
Files
Data Visualization & Deck Builder
Transform structured data and analysis into polished visual deliverables: presentation decks, interactive dashboards, and visual reports.
Install
git clone https://github.com/thatrebeccarae/claude-marketing.git && cp -r claude-marketing/skills/data-viz-deck ~/.claude/skills/When to Use This Skill
- User has completed an audit or analysis and wants a visual deliverable
- User says "make a deck," "create a presentation," "build a dashboard," "visualize this"
- User wants to turn a markdown report into client-ready slides
- User needs charts, tables, or visual summaries from performance data
Output Formats
1. PPTX Deck (Primary)
Native PowerPoint with editable charts, styled tables, and professional layouts. Best for client handoffs and presentations.
Requires: python-pptx (installed), pandas (installed)
2. Interactive HTML Dashboard
Single-file HTML with plotly.js charts (loaded via CDN), filterable tables, and responsive layout. Best for sharing interactive reports.
Requires: jinja2 (installed), pandas (installed). Plotly.js loaded via CDN at runtime.
3. Visual Markdown Report
Enhanced markdown with embedded chart images (requires matplotlib: pip install matplotlib). Best for vault reports and documentation.
Workflow
Step 1: Identify the Data Source
Read the source file (audit markdown, CSV, JSON, or database query results). Parse the key metrics, tables, and findings into a pandas DataFrame or structured dict.
Step 2: Select Chart Types
| Data Pattern | Chart Type | When to Use |
|---|---|---|
| Categories with values | Bar chart (horizontal) | Revenue by category |
| Categories + benchmark | Bar chart with reference line | Performance vs benchmark |
| Parts of a whole | Doughnut/Pie chart | Revenue concentration, channel mix |
| Values over time | Line chart | Trend data, period-over-period |
| Two variables | Scatter plot | Correlation analysis |
| Performance scoring | Heatmap table | Color-coded metrics (green/amber/red) |
| Before/after or gaps | Waterfall chart | Revenue opportunity sizing |
| Ranked items | Horizontal bar | Top 10 sorted |
| Funnels | Funnel chart | Delivered > opened > clicked > converted |
| Status overview | Scorecard/KPI tiles | Executive summary metrics |
Step 3: Apply the Design System
All deliverables use a configurable design system. Override the color tokens and font choices to match your brand.
Color Palette
COLORS = {
# Brand accent -- change to your brand color
"accent": "#3D7A5C", # Forest green
"accent_light":"#6AB88A", # Light green
# Chart series (ordered for visual distinction)
"series": ["#3D7A5C", "#6AB88A", "#8B7EC8", "#D4845A", "#C9A84C", "#C75B6F", "#93C9A8", "#8B949E"],
# Semantic
"good": "#2E8B57", # Green -- above benchmark
"warning": "#D97706", # Amber -- watch
"critical": "#C0392B", # Red -- action needed
"neutral": "#8B949E", # Slate -- no judgment
# Dark mode (title slides, section dividers)
"bg_deep": "#141414",
"bg_surface": "#1E1E1E",
"text_bright": "#F0F3F6",
"text_secondary_dark": "#9CA3AF",
# Light mode (content slides -- the default)
"bg_light": "#FAF7F2", # Warm cream, NOT white
"bg_surface_light": "#F2EDE6",
"text_primary":"#0F0E0E",
"text_secondary": "#57606A",
"text_muted": "#8B949E",
}Color rules:
- Light mode (
#FAF7F2warm cream) is default for all content slides. NOT white. - Dark mode (
#141414) only for: title slides, section dividers, closing slides. - Accent color used sparingly: top-performing bars, key metrics, accent callouts.
- Semantic colors (green/amber/red) only for status indicators, never decoration.
Typography (PPTX)
FONTS = {
"title": "Switzer", # Slide titles -- Light (300), 28-36pt, NOT bold
"subtitle": "Switzer", # Subtitles -- Regular (400), 18-22pt
"body": "Switzer", # Body text -- Regular (400), 12-14pt
"data": "Cartograph CF", # Numbers, tables -- Regular/Bold, 11-12pt
"kpi": "Cartograph CF", # KPI big numbers -- Bold (700), 44-60pt
"label": "Cartograph CF", # ALL CAPS labels -- Regular, 9-10pt, +tracking
}
# Fallbacks: Switzer -> Inter -> system-ui | Cartograph CF -> Consolas -> monospaceCritical typography rules: 1. Headlines use Light weight, NOT Bold. Light at large sizes = confident, premium. 2. Monospace font for ALL numeric/data content. KPIs, table numbers, labels, footers. 3. Negative tracking on headlines. -0.03em to -0.04em. 4. Positive tracking on ALL CAPS labels. +0.08em to +0.1em.
Slide Layouts
Every deck follows this structure:
1. Title Slide -- Report name, date (dark mode)
2. Executive Summary -- 3-5 KPI tiles + key findings bullets
3. Scorecard -- Color-coded performance overview table
4. Deep Dive slides -- One per major finding (chart + insight + recommendation)
5. Opportunity Sizing -- Waterfall or bar chart of revenue opportunities
6. Recommendations -- Prioritized table (Quick Wins / Strategic / Maintenance)
7. Appendix -- Full data tablesSlide Dimensions (python-pptx)
Width: 13.333"
Height: 7.5"
Aspect: 16:9Step 4: Generate the Deliverable
Follow the code patterns in REFERENCE.md for the chosen output format.
Key Principles
1. One insight per slide. Never cram multiple findings onto one slide. Each deep-dive slide has: chart (left 60%), insight + recommendation (right 40%).
2. Lead with the number. Every slide title should contain the key metric: "Post-Purchase RPR at $0.07 -- 14x Below Benchmark" not "Post-Purchase Flow Analysis."
3. Benchmark everything. Never show a metric without context. Show the benchmark, the gap, and what closing the gap is worth.
4. Color = meaning. Green means good/above benchmark. Amber means watch. Red means action needed. Never use color decoratively in data slides.
5. Simplify chart data. Max 6-8 items per chart. Aggregate the tail into "Other."
6. Executive summary is the deck. If someone only reads slide 2, they should understand the full story.
7. Never estimate when actuals exist. If the data has exact values, compute precise totals.
8. No white backgrounds. Always warm cream #FAF7F2 for light content.
9. No bold headlines. Light weight for all hero/section titles.
For complete code templates and reference, see REFERENCE.md.
Data Viz Deck — Examples
Example 1: Email Marketing Audit Deck (PPTX)
Prompt
Create a presentation deck from this Klaviyo audit data. The account has 8 flows (3 missing essential ones), $140K flow revenue, $918K campaign revenue. Open rate is 22% (benchmark 25%), click rate 1.8% (benchmark 3%). Include title slide, KPI scorecard, flow performance chart, and recommendations.
What the skill does
1. Parses the audit metrics into structured data 2. Creates a PPTX with python-pptx:
- Slide 1 (dark): Title slide with report name, date, brand lockup
- Slide 2 (light): Executive Summary with 4 KPI tiles ($1.06M total revenue, $140K flow revenue, 22% open rate in amber, 1.8% click rate in red)
- Slide 3 (light): Horizontal bar chart of flow revenue (sorted descending), insight panel noting 3 missing flows
- Slide 4 (light): Benchmark comparison table (flows x metrics, color-coded cells)
- Slide 5 (light): Recommendations table (Quick Wins / Strategic / Maintenance)
- Slide 6 (dark): Closing slide
Key code pattern
from pptx import Presentation
from pptx.util import Inches, Pt
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
# KPI tiles
kpis = [
{"label": "Total Revenue", "value": "$1,058,829", "color": ACCENT},
{"label": "Flow Revenue", "value": "$140,149", "subtitle": "13.2% of total"},
{"label": "Open Rate", "value": "22.4%", "color": AMBER, "subtitle": "Benchmark: 25%"},
{"label": "Click Rate", "value": "1.8%", "color": RED, "subtitle": "Benchmark: 3%"},
]
make_kpi_slide(prs, "Executive Summary", kpis)
prs.save("email-audit-deck.pptx")---
Example 2: Interactive Campaign Dashboard (HTML)
Prompt
Build an HTML dashboard showing campaign performance across 4 channels (Email, SMS, Social, Paid) with KPI tiles for total revenue, average ROI, and conversion rate. Include a bar chart comparing channel revenue and a funnel chart showing the email conversion path.
What the skill does
1. Structures the data as JSON for plotly.js 2. Generates a single-file HTML dashboard with:
- Dark header with title and date
- KPI row (3 tiles: $285K revenue in green, 4.2x ROI, 2.8% conversion)
- 2-column grid layout:
- Left: Channel revenue bar chart (plotly.js)
- Right: Email funnel chart (Sent > Delivered > Opened > Clicked > Converted)
- Insight boxes with left accent borders
- Responsive layout (collapses to single column on mobile)
3. All CSS is inline, plotly.js loaded via CDN
Key code pattern
chart_configs = {
"channel-revenue": bar_chart_config(
categories=["Email", "SMS", "Social", "Paid"],
values=[142000, 58000, 45000, 40000],
title="Revenue by Channel"
),
"email-funnel": funnel_chart_config(
stages=["Sent", "Delivered", "Opened", "Clicked", "Converted"],
values=[50000, 48500, 12125, 2182, 654],
title="Email Conversion Funnel"
)
}---
Example 3: Monthly Performance Report with Charts (Markdown + Images)
Prompt
Generate a visual markdown report with embedded charts showing month-over-month trends for revenue, subscriber growth, and engagement rates over the last 6 months. Include benchmark comparison bars.
What the skill does
1. Creates matplotlib charts saved as PNG:
- Line chart: Revenue trend (6 months) with benchmark reference line
- Grouped bar chart: Subscriber growth (new vs churned) per month
- Benchmark comparison: Current metrics vs industry averages
2. Generates a markdown report with ![]() image embeds:
# Monthly Performance Report — March 2026
## Revenue Trend

**Key Insight:** Revenue grew 18% MoM, crossing the $50K benchmark in February.
## Subscriber Health

**Key Insight:** Net subscriber growth turned positive in January after 3 months of decline.Key code pattern
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
months = ["Oct", "Nov", "Dec", "Jan", "Feb", "Mar"]
revenue = [38200, 41500, 39800, 44100, 51200, 52400]
save_horizontal_bar(
categories=months,
values=revenue,
title="Monthly Email Revenue",
filepath="./charts/revenue-trend.png",
value_format="${:,.0f}"
)MIT License
Copyright (c) 2026 Rebecca Rae Barton
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Data Viz Deck — Technical Reference
PPTX Generation with python-pptx
Slide Dimensions & Setup
from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.enum.chart import XL_CHART_TYPE, XL_LEGEND_POSITION, XL_LABEL_POSITION
from pptx.enum.shapes import MSO_SHAPE
from pptx.chart.data import CategoryChartData, ChartData
prs = Presentation()
prs.slide_width = Inches(13.333) # 16:9 widescreen
prs.slide_height = Inches(7.5)
SLIDE_LAYOUT = prs.slide_layouts[6] # Blank layoutColor Constants
from pptx.dml.color import RGBColor
# Brand accent -- customize to match your brand
ACCENT = RGBColor(0x3D, 0x7A, 0x5C)
ACCENT_LIGHT = RGBColor(0x6A, 0xB8, 0x8A)
# Semantic
GREEN = RGBColor(0x2E, 0x8B, 0x57)
AMBER = RGBColor(0xD9, 0x77, 0x06)
RED = RGBColor(0xC0, 0x39, 0x2B)
SLATE = RGBColor(0x8B, 0x94, 0x9E)
# Chart series colors (use in order)
SERIES_COLORS = [
ACCENT, ACCENT_LIGHT,
RGBColor(0x8B, 0x7E, 0xC8), # Lavender
RGBColor(0xD4, 0x84, 0x5A), # Terracotta
RGBColor(0xC9, 0xA8, 0x4C), # Gold
RGBColor(0xC7, 0x5B, 0x6F), # Dusty Rose
RGBColor(0x93, 0xC9, 0xA8), # Mist
SLATE,
]
# Dark mode (title slides, section dividers)
BG_DEEP = RGBColor(0x14, 0x14, 0x14)
BG_SURFACE = RGBColor(0x1E, 0x1E, 0x1E)
TEXT_BRIGHT = RGBColor(0xF0, 0xF3, 0xF6)
TEXT_SEC_DK = RGBColor(0x9C, 0xA3, 0xAF)
TEXT_MUTED_DK= RGBColor(0x6E, 0x76, 0x81)
# Light mode (content slides)
BG_LIGHT = RGBColor(0xFA, 0xF7, 0xF2) # Warm cream
BG_CARD = RGBColor(0xF2, 0xED, 0xE6)
TEXT_PRIMARY = RGBColor(0x0F, 0x0E, 0x0E)
TEXT_SECONDARY= RGBColor(0x57, 0x60, 0x6A)
TEXT_MUTED = RGBColor(0x8B, 0x94, 0x9E)Helper Functions
def add_textbox(slide, left, top, width, height, text, font_size=12,
bold=False, color=TEXT_PRIMARY, alignment=PP_ALIGN.LEFT,
font_name="Switzer"):
txBox = slide.shapes.add_textbox(Inches(left), Inches(top), Inches(width), Inches(height))
tf = txBox.text_frame
tf.word_wrap = True
p = tf.paragraphs[0]
p.text = text
p.font.size = Pt(font_size)
p.font.bold = bold
p.font.color.rgb = color
p.font.name = font_name
p.alignment = alignment
return txBox
def add_shape_bg(slide, left, top, width, height, fill_color=BG_CARD, corner_radius=None):
shape = slide.shapes.add_shape(
MSO_SHAPE.ROUNDED_RECTANGLE, Inches(left), Inches(top), Inches(width), Inches(height)
)
shape.fill.solid()
shape.fill.fore_color.rgb = fill_color
shape.line.fill.background()
if corner_radius:
shape.adjustments[0] = corner_radius
return shape
def set_cell_style(cell, text, font_size=11, bold=False, color=TEXT_PRIMARY,
alignment=PP_ALIGN.LEFT, font_name="Switzer", fill_color=None):
cell.text = str(text)
for paragraph in cell.text_frame.paragraphs:
paragraph.font.size = Pt(font_size)
paragraph.font.bold = bold
paragraph.font.color.rgb = color
paragraph.font.name = font_name
paragraph.alignment = alignment
cell.vertical_anchor = MSO_ANCHOR.MIDDLE
if fill_color:
cell.fill.solid()
cell.fill.fore_color.rgb = fill_color
def benchmark_color(value, good_threshold, warning_threshold, higher_is_better=True):
if higher_is_better:
return GREEN if value >= good_threshold else (AMBER if value >= warning_threshold else RED)
else:
return GREEN if value <= good_threshold else (AMBER if value <= warning_threshold else RED)Slide Templates
Title Slide (Dark Mode)
def make_title_slide(prs, title, subtitle, date_str):
slide = prs.slides.add_slide(SLIDE_LAYOUT)
bg = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, prs.slide_width, prs.slide_height)
bg.fill.solid()
bg.fill.fore_color.rgb = BG_DEEP
bg.line.fill.background()
add_textbox(slide, 0.8, 1.5, 11, 1.5, title, font_size=54, bold=False, color=TEXT_BRIGHT)
add_textbox(slide, 0.8, 3.2, 11, 0.8, subtitle, font_size=20, color=TEXT_SEC_DK)
add_textbox(slide, 0.8, 5.5, 5, 0.5, date_str, font_size=14, color=TEXT_MUTED_DK, font_name="Cartograph CF")
return slideKPI Scorecard Slide
def make_kpi_slide(prs, title, kpis):
"""kpis: list of dicts with keys: label, value, subtitle, color (optional)"""
slide = prs.slides.add_slide(SLIDE_LAYOUT)
bg = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, prs.slide_width, prs.slide_height)
bg.fill.solid()
bg.fill.fore_color.rgb = BG_LIGHT
bg.line.fill.background()
add_textbox(slide, 0.8, 0.4, 11, 0.6, title, font_size=32, bold=False, color=TEXT_PRIMARY)
n = len(kpis)
tile_width = min(2.4, (11.5 / n) - 0.3)
for i, kpi in enumerate(kpis):
x = 0.8 + i * (tile_width + 0.3)
add_shape_bg(slide, x, 1.4, tile_width, 2.2, fill_color=BG_CARD)
add_textbox(slide, x + 0.2, 1.6, tile_width - 0.4, 1.0, kpi["value"],
font_size=44, bold=True, color=kpi.get("color", ACCENT),
alignment=PP_ALIGN.CENTER, font_name="Cartograph CF")
add_textbox(slide, x + 0.2, 2.6, tile_width - 0.4, 0.4, kpi["label"],
font_size=12, alignment=PP_ALIGN.CENTER)
if kpi.get("subtitle"):
add_textbox(slide, x + 0.2, 3.0, tile_width - 0.4, 0.4, kpi["subtitle"],
font_size=10, color=TEXT_MUTED, alignment=PP_ALIGN.CENTER,
font_name="Cartograph CF")
return slideBar Chart Slide
def make_bar_chart_slide(prs, title, categories, values, value_label="Revenue",
insight_text="", recommendation="", chart_color=ACCENT):
"""Bar chart on left 60%, insight text on right 40%."""
slide = prs.slides.add_slide(SLIDE_LAYOUT)
bg = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, prs.slide_width, prs.slide_height)
bg.fill.solid()
bg.fill.fore_color.rgb = BG_LIGHT
bg.line.fill.background()
add_textbox(slide, 0.8, 0.4, 11, 0.6, title, font_size=24, bold=False, color=TEXT_PRIMARY)
chart_data = CategoryChartData()
chart_data.categories = categories
chart_data.add_series(value_label, values)
chart_frame = slide.shapes.add_chart(
XL_CHART_TYPE.BAR_CLUSTERED, Inches(0.8), Inches(1.3), Inches(7.2), Inches(5.5), chart_data
)
chart = chart_frame.chart
chart.has_legend = False
plot = chart.plots[0]
plot.gap_width = 80
series = plot.series[0]
series.format.fill.solid()
series.format.fill.fore_color.rgb = chart_color
series.has_data_labels = True
data_labels = series.data_labels
data_labels.font.size = Pt(10)
data_labels.font.color.rgb = TEXT_PRIMARY
data_labels.font.name = "Cartograph CF"
data_labels.number_format = "$#,##0"
if insight_text:
add_shape_bg(slide, 8.3, 1.3, 4.5, 3.0, fill_color=BG_CARD)
add_textbox(slide, 8.5, 1.5, 4.1, 0.4, "KEY INSIGHT", font_size=11, color=ACCENT, font_name="Cartograph CF")
add_textbox(slide, 8.5, 2.0, 4.1, 2.0, insight_text, font_size=12, color=TEXT_PRIMARY)
return slide---
Interactive HTML Dashboard (Jinja2 + Plotly.js)
Plotly Config Patterns
PLOTLY_ACCENT = "#3D7A5C"
PLOTLY_SERIES = ["#3D7A5C", "#6AB88A", "#8B7EC8", "#D4845A", "#C9A84C", "#C75B6F", "#93C9A8", "#8B949E"]
PLOTLY_FONT = "Switzer, Inter, system-ui, sans-serif"
PLOTLY_MONO = "Cartograph CF, Consolas, monospace"
def bar_chart_config(categories, values, title="", color=PLOTLY_ACCENT, orientation="h"):
return {
"data": [{
"type": "bar",
"x": values if orientation == "h" else categories,
"y": categories if orientation == "h" else values,
"orientation": orientation,
"marker": {"color": color},
"text": [f"${v:,.0f}" for v in values] if any(v > 100 for v in values) else values,
"textposition": "outside",
"textfont": {"family": PLOTLY_MONO},
}],
"layout": {
"title": {"text": title, "font": {"size": 16, "family": PLOTLY_FONT}},
"margin": {"l": 200, "t": 50, "r": 50, "b": 50},
"plot_bgcolor": "rgba(0,0,0,0)",
"paper_bgcolor": "rgba(0,0,0,0)",
}
}
def doughnut_chart_config(labels, values, title=""):
return {
"data": [{
"type": "pie", "labels": labels, "values": values, "hole": 0.5,
"marker": {"colors": PLOTLY_SERIES[:len(labels)]},
"textinfo": "label+percent", "textposition": "outside",
}],
"layout": {
"title": {"text": title, "font": {"size": 16, "family": PLOTLY_FONT}},
"showlegend": True, "legend": {"orientation": "h", "y": -0.15},
"paper_bgcolor": "rgba(0,0,0,0)",
}
}
def funnel_chart_config(stages, values, title=""):
return {
"data": [{
"type": "funnel", "y": stages, "x": values,
"textinfo": "value+percent initial",
"marker": {"color": PLOTLY_SERIES[:len(stages)]},
}],
"layout": {
"title": {"text": title, "font": {"size": 16, "family": PLOTLY_FONT}},
"margin": {"l": 150, "t": 50},
"paper_bgcolor": "rgba(0,0,0,0)", "plot_bgcolor": "rgba(0,0,0,0)",
}
}---
Matplotlib Charts (for Markdown/Image Output)
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams.update({
"figure.facecolor": "#FAF7F2",
"axes.facecolor": "#F2EDE6",
"axes.edgecolor": "#D6D0C8",
"text.color": "#0F0E0E",
"font.size": 11,
})
def save_horizontal_bar(categories, values, title, filepath, color="#3D7A5C",
value_format="${:,.0f}", figsize=(10, 6)):
fig, ax = plt.subplots(figsize=figsize)
y_pos = np.arange(len(categories))
bars = ax.barh(y_pos, values, color=color, height=0.6)
ax.set_yticks(y_pos)
ax.set_yticklabels(categories)
ax.invert_yaxis()
ax.set_title(title, fontsize=16, fontweight="light", pad=15)
for bar, val in zip(bars, values):
ax.text(bar.get_width() + max(values) * 0.02, bar.get_y() + bar.get_height() / 2,
value_format.format(val), va="center", fontsize=10, fontfamily="monospace")
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.xaxis.set_visible(False)
plt.tight_layout()
fig.savefig(filepath, dpi=150, bbox_inches="tight")
plt.close(fig)---
Data Parsing Utilities
import pandas as pd
import re
def parse_md_table(md_text, table_index=0):
tables = []
lines = md_text.split("\\n")
i = 0
while i < len(lines):
line = lines[i].strip()
if line.startswith("|") and i + 1 < len(lines) and "---" in lines[i + 1]:
headers = [h.strip() for h in line.split("|")[1:-1]]
rows = []
i += 2
while i < len(lines) and lines[i].strip().startswith("|"):
row = [c.strip() for c in lines[i].strip().split("|")[1:-1]]
rows.append(row)
i += 1
tables.append(pd.DataFrame(rows, columns=headers))
i += 1
return tables[table_index] if table_index < len(tables) else tables
def parse_currency(val):
if isinstance(val, (int, float)):
return float(val)
return float(re.sub(r"[,$]", "", str(val))) if val and val.strip() else 0.0
def parse_percentage(val):
if isinstance(val, (int, float)):
return float(val)
return float(re.sub(r"%", "", str(val))) if val and val.strip() else 0.0---
Dependencies
Already Installed
python-pptx-- PPTX generationpandas-- Data processingnumpy-- Numerical operationsjinja2-- HTML templatingPillow-- Image handling
Install If Needed
pip install matplotlib # PNG chart generation
pip install plotly # Local plotly (optional -- CDN works for HTML)python-pptx Chart Types
BAR_CLUSTERED,BAR_STACKED-- Horizontal barsCOLUMN_CLUSTERED,COLUMN_STACKED-- Vertical barsLINE,LINE_MARKERS-- Line chartsPIE,DOUGHNUT-- Composition chartsAREA,AREA_STACKED-- Area chartsXY_SCATTER-- Scatter plots