Creating and configuring charts including bar, line, pie, scatter, and bubble charts. Includes data binding, series management, formatting, and chart element customization for professional data visualization.
Create and structure data for different chart types using specialized data container classes.
class CategoryChartData:
"""Data container for category-based charts (bar, column, line, area, pie)."""
@property
def categories(self) -> list:
"""List of category labels."""
def add_series(self, name: str, values: list = None) -> CategorySeriesData:
"""
Add a data series to the chart.
Parameters:
- name: Series name for legend
- values: List of numeric values (optional, can set later)
Returns:
CategorySeriesData object for further configuration
"""
class CategorySeriesData:
"""Individual data series for category charts."""
@property
def name(self) -> str:
"""Series name."""
@name.setter
def name(self, name: str):
"""Set series name."""
@property
def values(self) -> list:
"""List of data values."""
@values.setter
def values(self, values: list):
"""Set data values."""
class XyChartData:
"""Data container for XY scatter charts."""
def add_series(self, name: str) -> XySeriesData:
"""
Add XY data series.
Parameters:
- name: Series name
Returns:
XySeriesData object
"""
class XySeriesData:
"""Individual XY data series."""
@property
def name(self) -> str:
"""Series name."""
def add_data_point(self, x: float, y: float) -> XyDataPoint:
"""
Add data point to series.
Parameters:
- x, y: Coordinate values
Returns:
XyDataPoint object
"""
class BubbleChartData:
"""Data container for bubble charts."""
def add_series(self, name: str) -> BubbleSeriesData:
"""Add bubble data series."""
class BubbleSeriesData:
"""Individual bubble data series."""
def add_data_point(self, x: float, y: float, size: float) -> BubbleDataPoint:
"""
Add bubble data point.
Parameters:
- x, y: Position coordinates
- size: Bubble size value
"""Add charts to slides with data and basic configuration.
# Chart creation through shapes collection
def add_chart(chart_type: XL_CHART_TYPE, x: int, y: int, cx: int, cy: int, chart_data) -> GraphicFrame:
"""
Add chart to slide.
Parameters:
- chart_type: XL_CHART_TYPE enum (COLUMN_CLUSTERED, LINE, PIE, etc.)
- x, y: Position in EMU
- cx, cy: Chart dimensions in EMU
- chart_data: CategoryChartData, XyChartData, or BubbleChartData
Returns:
GraphicFrame containing Chart object
"""Configure chart appearance, elements, and behavior after creation.
class Chart:
"""Chart object with formatting and data access."""
@property
def chart_type(self) -> XL_CHART_TYPE:
"""Type of chart."""
@property
def series(self) -> SeriesCollection:
"""Collection of data series in chart."""
@property
def plots(self) -> list:
"""List of plot areas (usually one)."""
@property
def legend(self) -> Legend:
"""Chart legend formatting."""
@property
def chart_title(self) -> ChartTitle:
"""Chart title."""
@property
def value_axis(self) -> ValueAxis:
"""Primary value (Y) axis."""
@property
def category_axis(self) -> CategoryAxis:
"""Category (X) axis."""
@property
def has_legend(self) -> bool:
"""True if chart has a legend."""
@property
def has_title(self) -> bool:
"""True if chart has a title."""
def replace_data(self, chart_data):
"""Replace chart data with new dataset."""Manage chart titles and title formatting.
class ChartTitle:
"""Chart title with text and formatting."""
@property
def text_frame(self) -> TextFrame:
"""Text frame for title content."""
@property
def format(self) -> ChartFormat:
"""Title formatting options."""
@property
def has_text_frame(self) -> bool:
"""True if title has text content."""Configure chart legends including position, formatting, and visibility.
class Legend:
"""Chart legend formatting and positioning."""
@property
def position(self) -> XL_LEGEND_POSITION:
"""Legend position relative to chart."""
@position.setter
def position(self, position: XL_LEGEND_POSITION):
"""Set legend position."""
@property
def include_in_layout(self) -> bool:
"""True if legend affects chart plot area size."""
@include_in_layout.setter
def include_in_layout(self, include: bool):
"""Set whether legend affects layout."""
@property
def font(self) -> Font:
"""Legend text font formatting."""Configure chart axes including scales, labels, and gridlines.
class ValueAxis:
"""Value (Y) axis for numeric data."""
@property
def minimum_scale(self) -> float:
"""Minimum axis value."""
@minimum_scale.setter
def minimum_scale(self, minimum: float):
"""Set minimum axis value."""
@property
def maximum_scale(self) -> float:
"""Maximum axis value."""
@maximum_scale.setter
def maximum_scale(self, maximum: float):
"""Set maximum axis value."""
@property
def major_unit(self) -> float:
"""Major tick interval."""
@major_unit.setter
def major_unit(self, unit: float):
"""Set major tick interval."""
@property
def has_major_gridlines(self) -> bool:
"""True if major gridlines are visible."""
@property
def major_gridlines(self) -> MajorGridlines:
"""Major gridlines formatting."""
@property
def axis_title(self) -> AxisTitle:
"""Axis title."""
@property
def tick_labels(self) -> TickLabels:
"""Tick label formatting."""
class CategoryAxis:
"""Category (X) axis for categorical data."""
@property
def category_type(self) -> XL_CATEGORY_TYPE:
"""Category axis type (AUTOMATIC, CATEGORY_SCALE, TIME_SCALE)."""
@category_type.setter
def category_type(self, cat_type: XL_CATEGORY_TYPE):
"""Set category axis type."""
@property
def tick_labels(self) -> TickLabels:
"""Category label formatting."""
@property
def axis_title(self) -> AxisTitle:
"""Axis title."""
class AxisTitle:
"""Axis title text and formatting."""
@property
def text_frame(self) -> TextFrame:
"""Title text frame."""
@property
def format(self) -> ChartFormat:
"""Title formatting."""
class TickLabels:
"""Axis tick label formatting."""
@property
def font(self) -> Font:
"""Tick label font."""
@property
def number_format(self) -> str:
"""Number format string."""
@number_format.setter
def number_format(self, format_str: str):
"""Set number format."""Configure individual data series including colors, markers, and data labels.
class SeriesCollection:
"""Collection of chart data series."""
def __getitem__(self, index: int):
"""Get series by index."""
def __len__(self) -> int:
"""Number of series."""
class BarSeries:
"""Bar chart data series."""
@property
def name(self) -> str:
"""Series name."""
@property
def values(self) -> list:
"""Series data values."""
@property
def format(self) -> ChartFormat:
"""Series formatting (fill, line, etc.)."""
@property
def data_labels(self) -> DataLabels:
"""Data label collection."""
class LineSeries:
"""Line chart data series."""
@property
def line(self) -> LineFormat:
"""Line formatting."""
@property
def marker(self) -> Marker:
"""Data point markers."""
@property
def smooth(self) -> bool:
"""True if line is smoothed."""
@smooth.setter
def smooth(self, smooth: bool):
"""Set line smoothing."""
class PieSeries:
"""Pie chart data series."""
@property
def points(self) -> CategoryDataPoints:
"""Individual pie slice data points."""Configure data labels that display values on chart elements.
class DataLabels:
"""Collection of data labels for a series."""
@property
def show_value(self) -> bool:
"""True if values are displayed."""
@show_value.setter
def show_value(self, show: bool):
"""Set value display."""
@property
def show_category_name(self) -> bool:
"""True if category names are shown."""
@show_category_name.setter
def show_category_name(self, show: bool):
"""Set category name display."""
@property
def show_percentage(self) -> bool:
"""True if percentages are shown."""
@show_percentage.setter
def show_percentage(self, show: bool):
"""Set percentage display."""
@property
def position(self) -> XL_DATA_LABEL_POSITION:
"""Data label position."""
@position.setter
def position(self, position: XL_DATA_LABEL_POSITION):
"""Set label position."""
@property
def font(self) -> Font:
"""Label text font."""from pptx.enum.chart import XL_CHART_TYPE
# Column and bar charts
XL_CHART_TYPE.COLUMN_CLUSTERED
XL_CHART_TYPE.COLUMN_STACKED
XL_CHART_TYPE.COLUMN_STACKED_100
XL_CHART_TYPE.BAR_CLUSTERED
XL_CHART_TYPE.BAR_STACKED
# Line charts
XL_CHART_TYPE.LINE
XL_CHART_TYPE.LINE_MARKERS
XL_CHART_TYPE.LINE_STACKED
XL_CHART_TYPE.LINE_STACKED_MARKERS
# Area charts
XL_CHART_TYPE.AREA
XL_CHART_TYPE.AREA_STACKED
XL_CHART_TYPE.AREA_STACKED_100
# Pie charts
XL_CHART_TYPE.PIE
XL_CHART_TYPE.PIE_EXPLODED
XL_CHART_TYPE.DOUGHNUT
XL_CHART_TYPE.DOUGHNUT_EXPLODED
# Scatter charts
XL_CHART_TYPE.XY_SCATTER
XL_CHART_TYPE.XY_SCATTER_LINES
XL_CHART_TYPE.XY_SCATTER_LINES_NO_MARKERS
XL_CHART_TYPE.XY_SCATTER_SMOOTH
XL_CHART_TYPE.XY_SCATTER_SMOOTH_NO_MARKERS
# Bubble charts
XL_CHART_TYPE.BUBBLE
XL_CHART_TYPE.BUBBLE_THREE_D_EFFECTUsage examples:
from pptx import Presentation
from pptx.chart.data import CategoryChartData
from pptx.enum.chart import XL_CHART_TYPE, XL_LEGEND_POSITION
from pptx.util import Inches
from pptx.dml.color import RGBColor
prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[6])
# Create chart data
chart_data = CategoryChartData()
chart_data.categories = ['Q1', 'Q2', 'Q3', 'Q4']
# Add data series
series1 = chart_data.add_series('Revenue', [100, 120, 140, 110])
series2 = chart_data.add_series('Costs', [80, 90, 95, 85])
# Create chart
x, y, cx, cy = Inches(2), Inches(2), Inches(6), Inches(4.5)
chart_frame = slide.shapes.add_chart(
XL_CHART_TYPE.COLUMN_CLUSTERED, x, y, cx, cy, chart_data
)
chart = chart_frame.chart
# Configure chart title
chart.chart_title.text_frame.text = "Quarterly Performance"
chart.chart_title.text_frame.paragraphs[0].font.size = Pt(18)
# Configure legend
chart.legend.position = XL_LEGEND_POSITION.BOTTOM
chart.legend.include_in_layout = False
# Format axes
value_axis = chart.value_axis
value_axis.minimum_scale = 0
value_axis.maximum_scale = 200
value_axis.major_unit = 50
value_axis.axis_title.text_frame.text = "Amount ($000)"
category_axis = chart.category_axis
category_axis.axis_title.text_frame.text = "Quarter"
# Format data series
series = chart.series[0] # Revenue series
series.format.fill.solid()
series.format.fill.fore_color.rgb = RGBColor(0, 112, 192)
# Add data labels
series.data_labels.show_value = True
series.data_labels.position = XL_DATA_LABEL_POSITION.OUTSIDE_END
# Create pie chart
pie_data = CategoryChartData()
pie_data.categories = ['Product A', 'Product B', 'Product C', 'Product D']
pie_data.add_series('Sales', [300, 200, 150, 100])
pie_slide = prs.slides.add_slide(prs.slide_layouts[6])
pie_chart_frame = pie_slide.shapes.add_chart(
XL_CHART_TYPE.PIE, Inches(1), Inches(1), Inches(8), Inches(6), pie_data
)
pie_chart = pie_chart_frame.chart
pie_chart.chart_title.text_frame.text = "Sales by Product"
# Format pie chart data labels
pie_series = pie_chart.series[0]
pie_series.data_labels.show_category_name = True
pie_series.data_labels.show_percentage = True
prs.save('charts-example.pptx')from pptx.chart.data import XyChartData, BubbleChartData
# XY Scatter chart
xy_data = XyChartData()
series = xy_data.add_series('Correlation')
series.add_data_point(1.2, 2.3)
series.add_data_point(2.1, 3.5)
series.add_data_point(3.7, 1.8)
scatter_chart = slide.shapes.add_chart(
XL_CHART_TYPE.XY_SCATTER, x, y, cx, cy, xy_data
).chart
# Bubble chart
bubble_data = BubbleChartData()
bubble_series = bubble_data.add_series('Performance')
bubble_series.add_data_point(10, 20, 5) # x, y, size
bubble_series.add_data_point(20, 30, 8)
bubble_series.add_data_point(15, 25, 12)
bubble_chart = slide.shapes.add_chart(
XL_CHART_TYPE.BUBBLE, x, y, cx, cy, bubble_data
).chart