如何用python-pptx调整环形图大小并在单页幻灯片放置多幅
解决方案
要在单页幻灯片中添加1-3幅环形图并自动适配尺寸,核心是根据图表数量动态计算每个图表的位置与大小,同时合理规划幻灯片布局避免元素重叠。以下是调整后的完整实现:
关键调整思路
- 避开标题区域,定义专属的图表摆放范围,确保标题与图表不重叠
- 针对1/2/3三种图表数量,设计不同的布局规则:
- 1个图表:占据图表区域的大部分空间,居中放置
- 2个图表:左右并排,中间留合理间距
- 3个图表:采用左一右二的布局,左侧大图表、右侧上下两个小图表
- 封装图表创建逻辑,通过循环批量生成对应数量的环形图
完整代码
from pptx import Presentation from pptx.util import Pt, Cm from pptx.chart.data import ChartData from pptx.enum.chart import XL_CHART_TYPE def create_ppt(chart_count=1): # 限制图表数量范围 if chart_count not in (1, 2, 3): raise ValueError("仅支持添加1、2、3个环形图") pr = Presentation() # 使用空白幻灯片布局,避免默认占位框干扰 slide_layout = pr.slide_layouts[6] slide1 = pr.slides.add_slide(slide_layout) # 添加标题 title_shape = slide1.shapes.add_textbox(left=Cm(0), top=Cm(1), width=Cm(25), height=Cm(3)) title_text_frame = title_shape.text_frame title_paragraph = title_text_frame.add_paragraph() title_paragraph.text = "Data" title_paragraph.font.name = "Arial (Headings)" title_paragraph.font.size = Pt(34) # 定义图表区域边界(避开标题,左右留边) chart_area_left = Cm(1) chart_area_top = Cm(4) chart_area_width = Cm(23) chart_area_height = Cm(14) # 测试数据集,可替换为实际业务数据 chart_datasets = [ (["X1", "X2", "X3", "X4"], [75, 10, 5, 4], "数据1"), (["A", "B", "C"], [40, 35, 25], "数据2"), (["P", "Q", "R", "S", "T"], [20, 30, 15, 25, 10], "数据3") ] # 根据图表数量计算每个图表的位置和尺寸 charts_info = [] if chart_count == 1: # 单个图表居中放置 x = chart_area_left + (chart_area_width - Cm(18)) / 2 y = chart_area_top + (chart_area_height - Cm(12)) / 2 charts_info.append((x, y, Cm(18), Cm(12))) elif chart_count == 2: # 两个图表左右并排,中间留1cm间距 single_width = (chart_area_width - Cm(1)) / 2 x1, y1 = chart_area_left, chart_area_top x2 = chart_area_left + single_width + Cm(1) charts_info.extend([(x1, y1, single_width, chart_area_height), (x2, y1, single_width, chart_area_height)]) elif chart_count == 3: # 左一右二布局:左侧大图表,右侧上下两个小图表 left_width = chart_area_width * 0.55 right_width = chart_area_width * 0.4 right_height = (chart_area_height - Cm(1)) / 2 x_left, y_left = chart_area_left, chart_area_top x_right = chart_area_left + left_width + Cm(1) y_right_top = chart_area_top y_right_bottom = chart_area_top + right_height + Cm(1) charts_info.extend([ (x_left, y_left, left_width, chart_area_height), (x_right, y_right_top, right_width, right_height), (x_right, y_right_bottom, right_width, right_height) ]) # 循环创建环形图 for idx, (x, y, cx, cy) in enumerate(charts_info): categories, values, series_name = chart_datasets[idx] chart_data = ChartData() chart_data.categories = categories chart_data.add_series(series_name, values) chart = slide1.shapes.add_chart( XL_CHART_TYPE.DOUGHNUT, x, y, cx, cy, chart_data ).chart chart.has_legend = True chart.legend.include_in_layout = False apply_data_labels(chart) pr.save(f"多环形图演示_{chart_count}个.pptx") def apply_data_labels(chart): plot = chart.plots[0] plot.has_data_labels = True for series in plot.series: for idx, point in enumerate(series.points): data_label = point.data_label data_label.has_text_frame = True data_label.text_frame.text = str(series.values[idx]) # 调用示例:创建包含3个环形图的幻灯片 create_ppt(chart_count=3)
代码说明
- 布局控制:使用空白幻灯片布局,手动添加标题,避免默认占位框影响图表位置
- 动态适配:通过
chart_count参数自动切换布局规则,无需手动调整坐标 - 数据灵活替换:
chart_datasets可直接替换为实际业务数据,支持不同维度的环形图展示 - 标签优化:简化数据标签赋值逻辑,用
enumerate替代计数器,代码更简洁
内容的提问来源于stack exchange,提问作者ninjacode
相关产品推荐
相关产品推荐

