How to Embed Charts in a PDF
Export an existing Excel or PowerPoint chart, or generate a PDF with a vector chart in Python. Learn how to keep labels legible and check accessibility.
To put a chart in a PDF, either export the Office document that contains it or generate the PDF and chart together with a library such as ReportLab. Use a vector chart when you need it to stay sharp as it is scaled or printed. Whichever route you choose, check the exported PDF at its intended page size for readable labels, clipping, page breaks, and accessibility.
1. Choose a workflow
| Your situation | Recommended route | What to check |
|---|---|---|
| The chart already exists in Excel or PowerPoint | Prepare the source file, then export it to PDF from that application. | Page layout, chart size, accessibility settings, and the resulting PDF. |
| A script generates reports from data | Draw the chart into a PDF with ReportLab Graphics or another PDF library. | Page coordinates, labels, fonts, and vector or raster output. |
| The chart is already an image | Place the image in the PDF at a size that preserves legibility. | Image resolution at the final display or print size. |
Office export is usually the shorter path for an existing workbook or presentation. Programmatic generation gives you more control over repeatable layouts and automated reports.
2. Export a chart from Excel or PowerPoint
- Prepare the workbook or presentation. Give the chart a descriptive title, make axis labels and legends readable, and check colors and contrast.
- Set the page or slide layout so the chart fits in the exported PDF. Look for clipping, unexpected scaling, and unwanted page breaks.
- Use the application’s PDF export options. Microsoft documents PDF export for Word, Excel, and PowerPoint; available settings can vary by application and version.
- Open the PDF and inspect the chart at the size readers will use. Verify fonts, colors, labels, page breaks, and PDF accessibility tagging.
- If the chart conveys an important conclusion, state that conclusion in surrounding text and consider providing the underlying values in a data table.
For Excel, follow the workbook accessibility practices before export and review the resulting PDF. Microsoft’s guidance describes tags for workbook ranges and tables, and notes that decorative graphics can be marked as artifacts. A chart’s visual appearance alone does not make its data accessible.
For PowerPoint automation, Microsoft’s Presentation.ExportAsFixedFormat3 method includes PDF/UA tags only when DocStructureTags=True. Check the export options and the output; do not assume all export settings produce equivalent tags.
Microsoft explains PDF/UA tagging and Office export in its PDF accessibility overview, Excel accessibility guidance, and PowerPoint export method documentation.
3. Generate a PDF chart with Python and ReportLab
ReportLab Graphics provides chart and drawing objects that can be rendered as vectors in PDF. The example below creates a one-page PDF containing a vector bar chart, a title, and a short explanation. Install the library with python -m pip install reportlab, save this as chart_pdf.py, and run python chart_pdf.py.
from reportlab.graphics.charts.barcharts import VerticalBarChart
from reportlab.graphics.shapes import Drawing, String
from reportlab.graphics import renderPDF
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
output_path = "chart-report.pdf"
page_width, page_height = letter
# ReportLab canvas coordinates start at the lower-left of the page.
pdf = canvas.Canvas(output_path, pagesize=letter)
pdf.setTitle("Quarterly revenue chart")
# Build chart geometry in points, leaving room for the title and takeaway.
drawing = Drawing(480, 270)
drawing.add(String(20, 245, "Quarterly revenue", fontSize=16))
chart = VerticalBarChart()
chart.x = 55
chart.y = 55
chart.width = 390
chart.height = 165
chart.data = [(12, 16, 14, 21)]
chart.categoryAxis.categoryNames = ["Q1", "Q2", "Q3", "Q4"]
chart.valueAxis.valueMin = 0
chart.valueAxis.valueMax = 25
chart.valueAxis.valueStep = 5
chart.valueAxis.labelTextFormat = "%d"
drawing.add(chart)
# Place the drawing on the page. Coordinates are measured from bottom-left.
renderPDF.draw(drawing, pdf, 60, 390)
pdf.setFont("Helvetica", 10)
pdf.drawString(60, 365, "Takeaway: revenue peaked in Q4 in this example.")
pdf.save()
print(f"Wrote {output_path}")
The chart geometry is drawn into the PDF rather than pasted as a fixed-resolution bitmap, so it can remain crisp when scaled. ReportLab describes chart and drawing objects in its User Guide; its PDF generation guide also describes the canvas workflow and its lower-left coordinate origin.
Adapt the generated chart
- Change the data: replace the values in
chart.dataand updatecategoryNamesto match. - Set useful axis bounds: choose
valueMin,valueMax, andvalueStepto suit the data. Avoid implying a misleading comparison through an unexplained truncated axis. - Fit the page: adjust the drawing width and height and the coordinates passed to
renderPDF.draw. Leave room for a title, axis labels, legend, and explanatory text. - Add context: describe units, time period, and the chart’s main takeaway in the document. Do not rely on color alone to distinguish series.
- Use a raster image when appropriate: if the source is already a bitmap, embed it at a size where labels and details remain readable. There is no universal DPI threshold that fits every chart and use case.
4. Vector chart or chart image?
| Format | Good fit when | Check |
|---|---|---|
| Vector drawing in the PDF | The chart is generated from shapes or data and needs to remain sharp at different sizes or in print. | Fonts, clipping, and whether the PDF viewer renders the drawing as expected. |
| Raster image | The chart already exists as an image or image-based output is simpler for your workflow. | Legibility at the final page size; resizing cannot restore detail absent from the source image. |
ReportLab’s documentation describes its charts as vector-drawable in PDF. That makes vector output useful for sharp lines and small file sizes, but it does not by itself guarantee an accessible chart. A chart still needs readable labels and a meaningful text explanation.
5. Accessibility and final-PDF checks
- Give the chart a descriptive title and label axes, units, and series clearly.
- Ensure labels and legends are legible at the intended page size.
- Explain the essential takeaway in surrounding text; provide a data table or equivalent explanation when readers need the values.
- For Office exports, prepare the source workbook or presentation accessibly and inspect the PDF’s tags and structure.
- Review the complete PDF for clipped content, missing fonts, color changes, unexpected scaling, and page breaks.
- Do not assume that a chart’s visual appearance or a PDF export setting alone makes its information accessible.
6. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Axis labels or legend are clipped | The chart or drawing is too large for its allotted page area. | Reduce chart dimensions, reposition it, or reserve more space for labels and legends; regenerate and inspect the PDF. |
| Chart text is too small | The chart was scaled down to fit, or the source image lacks sufficient detail. | Give the chart more page area, shorten labels, or use a vector drawing. For a raster chart, use a more detailed source image. |
| Chart appears on an unexpected page | The Office print area, slide layout, or PDF page layout differs from expectations. | Check the source application’s page or slide setup and inspect the exported PDF page by page. |
| PDF lacks expected accessibility structure | Source content or export settings did not create the tags you expected. | Apply the application’s accessibility guidance, verify its export options, and inspect the resulting PDF. In the documented PowerPoint method, set DocStructureTags=True to include PDF/UA tags. |
| ReportLab chart is misplaced | Canvas coordinates use a lower-left origin, or the drawing’s dimensions and placement do not fit the page. | Recalculate x/y positions from the lower-left, check drawing width and height, and keep the entire drawing inside the page bounds. |
| Repeated embedded images make the PDF inefficient | The same bitmap may be added repeatedly instead of reused efficiently. | Review how images are placed; ReportLab’s guide notes that inline bitmaps can be inefficient when repeated. Prefer vector chart drawing when suitable. |
7. Performance, reliability, and cost
For a static chart in an existing file, exporting from the source application avoids rebuilding the chart. For repeated or data-driven reports, generating the chart and PDF in one script makes placement and page setup reproducible. Vector graphics are useful when sharp scaling matters; bitmap output may be simpler when an image is already the source. The reviewed documentation does not establish a universal size or speed advantage for every chart, so inspect the actual output and file size for your report.
Keep the data and report generation steps deterministic where reproducibility matters, and review generated PDFs when chart dimensions, fonts, or source data change. Office export settings and application versions can affect the result, so record the application and relevant settings in a production workflow.
8. Capture a web chart for a report
If the chart lives on a web page, a screenshot can preserve its rendered appearance for insertion into a PDF. It is an image of the chart, so the underlying data and accessibility structure are not carried over merely by capturing it. For data-led or accessible reports, prefer the source data or a chart embedded directly in the PDF when available.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. A single GET request captures a webpage as PNG, JPEG, WebP, or PDF. Its API can be useful when a rendered web chart needs capturing without setting up browser automation. The call below saves a clean WebP screenshot of a chart page; place that image in your PDF using your document or PDF library. See the ScreenshotNeo API documentation for configuration.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await require('node:fs/promises').writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
- Cookie and consent banners, newsletter popups, and chat widgets are removed before capture; each cleanup step can be turned off.
- Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing. Response headers say which page verdict and billing outcome applied.
- An MCP server lets AI agents, including Claude and Cursor, use tools to take screenshots, get page information, and capture PDFs.
- The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Every feature is on every plan.
Sign up for ScreenshotNeo and get 1,000 screenshots a month free, with no card.
FAQ
How do I export an Excel chart as a PDF?
Prepare the workbook for accessibility and print layout, export it as a PDF from Excel, then inspect the PDF for readable labels, correct page breaks, and tagging.
Can I put more than one chart in a PDF?
Yes. Place each chart in the page layout with room for titles, labels, and explanatory text. In a generated PDF, repeat the drawing and placement steps for each chart and page.
Does a chart screenshot preserve its data?
No. A screenshot captures appearance as an image. Include a data table or an equivalent explanation when readers need access to the values.
Should I use a vector chart or an image?
Use vector output when sharp scaling matters and the chart can be drawn into the PDF. Use an image when that suits your source, and check that it remains legible at final size.


