Chart
An embedded chart recovered as data, not pixels — its series and plotted points, axis titles, and chart type, plus a ready-made Markdown rendering of the same values. result.charts is a list of these, in document order.
Charts are extracted from DOCX and PPTX only. Office files carry the chart's underlying data cache inside the document, so the numbers behind every bar and line are recoverable exactly — no OCR, no chart-reading model, no guessing at pixel positions. PDF and HTML charts are images by the time they reach the file, so result.charts is empty for those formats.
result = docslicer.parse_document("deck.pptx")
for chart in result.charts:
print(chart.title, "—", chart.chart_type, "— page", chart.page_number)
print(chart.markdown)Fields
| Field | Type | Description |
|---|---|---|
id | str | Unique identifier for this chart within the result. Referenced by chunk.chart_ids and block.chart_ids. |
chart_type | str | The chart's plot type, as named in the source file: barChart, lineChart, pieChart, scatterChart, and so on. |
title | str | None | The chart's title, when one was set. None otherwise. |
axis_x_title | str | None | Title of the category (x) axis, when set. |
axis_y_title | str | None | Title of the value (y) axis, when set. Often carries the unit — "$m", "% of revenue". |
page_number | int | 1-based page number (DOCX) or slide number (PPTX) the chart appears on. |
page_label | str | None | Printed page label, when one differs from page_number. None when no label was detected. |
chunk_id | str | ID of the chunk this chart belongs to. |
is_stacked | bool | True for stacked variants — series values accumulate rather than sit side by side. Changes how a total should be read off the chart. |
bbox | BBox | None | Shape geometry on the slide. Populated for PPTX only; None for DOCX. |
markdown | str | The chart's data rendered as a Markdown table — a convenience for display or for dropping into a prompt. How the chart is serialised into chunk text is a separate setting; see Chart representations. |
points | list[ChartPoint] | The plotted datapoints. See ChartPoint below. |
ChartPoint
Each entry in chart.points is a ChartPoint describing one plotted value. The fields cover every chart family, so which of them are populated depends on chart_type:
| Field | Type | Description |
|---|---|---|
series_index | int | 0-indexed position of the series this point belongs to. |
series_name | str | None | Name of the series, e.g. "Revenue 2024". None for unnamed single-series charts. |
point_index | int | 0-indexed position of the point within its series. |
category | str | None | Category-axis label for the point, e.g. "Q1". |
label | str | None | Explicit data label attached to the point, when the author added one. |
value | float | None | The plotted value. None when the source's cached value was non-numeric. |
x_value | float | None | X coordinate — scatter and bubble charts only. |
y_value | float | None | Y coordinate — scatter and bubble charts only. |
bubble_size | float | None | Bubble radius value — bubble charts only. |
percent | float | None | The point's share of its series total — pie and doughnut charts only. |
A point is the finest granularity a chart has: every value keeps its series, its category, and its position in plot order, with nothing flattened into a caption. That means a chart is queryable the same way a table is — you can pull one series, compare two years, or feed the numbers to an LLM as text. Parsers that treat charts as images give you a bitmap and, at best, a caption; the values behind it are gone and can't be recovered downstream.
Examples
Render as Markdown
print(chart.markdown)Work with the points as a DataFrame
to_dataframe() returns one row per point, with every ChartPoint field as a column:
df = chart.to_dataframe()
revenue = df[df["series_name"] == "Revenue 2024"]For all charts in the document at once, result.charts_df() returns the same shape with chart_id, chart_type, title, page_number, and page_label repeated onto every row:
df = result.charts_df()
df.groupby("chart_id")["value"].sum()List the series in a chart
series_names returns the unique series names in plot order, skipping unnamed series:
chart.series_names # ["Revenue 2024", "Revenue 2025"]Pull a single series
points = [p for p in chart.points if p.series_name == "Revenue 2025"]
values = {p.category: p.value for p in points}Find charts by heading or page
node = result.find_heading("Segment Performance")[0]
charts = result.charts_under(node)
result.charts_by_page(4) # by physical page / slide number
result.charts_by_page("A-2") # by printed page labelSee ParseResult for the full set of navigation methods.
Resolve a chunk's or block's charts
chunk.chart_ids and block.chart_ids hold Chart IDs — look them up against result.charts:
charts_by_id = {c.id: c for c in result.charts}
for chunk in result.chunks:
for chart_id in chunk.chart_ids:
print(charts_by_id[chart_id].markdown)Export every datapoint
result.export_charts_csv("charts.csv") # one row per point
result.export_charts_csv("charts.csv", encoding="utf-8-sig") # Excel-friendly
result.save("output/charts.parquet")Methods
series_names
Property. The unique series names in plot order; series with no name are excluded.
names = chart.series_namesto_dataframe()
Return the points as a pandas DataFrame, one row per point.
df = chart.to_dataframe()to_dict()
Serialize the chart — including its points — to a plain dict.
d = chart.to_dict()Chart.from_dict(d)
Reconstruct a Chart from a dict produced by to_dict().
chart = Chart.from_dict(d)