Home

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

FieldTypeDescription
idstrUnique identifier for this chart within the result. Referenced by chunk.chart_ids and block.chart_ids.
chart_typestrThe chart's plot type, as named in the source file: barChart, lineChart, pieChart, scatterChart, and so on.
titlestr | NoneThe chart's title, when one was set. None otherwise.
axis_x_titlestr | NoneTitle of the category (x) axis, when set.
axis_y_titlestr | NoneTitle of the value (y) axis, when set. Often carries the unit — "$m", "% of revenue".
page_numberint1-based page number (DOCX) or slide number (PPTX) the chart appears on.
page_labelstr | NonePrinted page label, when one differs from page_number. None when no label was detected.
chunk_idstrID of the chunk this chart belongs to.
is_stackedboolTrue for stacked variants — series values accumulate rather than sit side by side. Changes how a total should be read off the chart.
bboxBBox | NoneShape geometry on the slide. Populated for PPTX only; None for DOCX.
markdownstrThe 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.
pointslist[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:

FieldTypeDescription
series_indexint0-indexed position of the series this point belongs to.
series_namestr | NoneName of the series, e.g. "Revenue 2024". None for unnamed single-series charts.
point_indexint0-indexed position of the point within its series.
categorystr | NoneCategory-axis label for the point, e.g. "Q1".
labelstr | NoneExplicit data label attached to the point, when the author added one.
valuefloat | NoneThe plotted value. None when the source's cached value was non-numeric.
x_valuefloat | NoneX coordinate — scatter and bubble charts only.
y_valuefloat | NoneY coordinate — scatter and bubble charts only.
bubble_sizefloat | NoneBubble radius value — bubble charts only.
percentfloat | NoneThe 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 label

See 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_names

to_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)