如何用python-pptx绘制带平均值标记的高低范围水平图表?
技术需求:用python-pptx实现水平范围图表(含平均值菱形标记)
我需要绘制水平范围图表展示数据的低值到高值区间,同时用菱形标记标注平均值。目前通过堆叠条形图模拟出了初步效果(代码如下),但希望制作出目标样式的图表,请问能否通过python-pptx实现该需求?盼提供相关指导或思路。
现有实现代码
# Import relevant packages import pandas as pd import numpy as np from pptx import Presentation from pptx.dml.color import RGBColor from pptx.chart.data import CategoryChartData, ChartData from pptx.enum.chart import (XL_CHART_TYPE, XL_LEGEND_POSITION, XL_DATA_LABEL_POSITION, XL_TICK_LABEL_POSITION, XL_TICK_MARK, XL_LABEL_POSITION) from pptx.util import Inches # Set up data to be used in the chart lows = np.array([12.1, 12.6, 9.9, 9.4, 13.6]) # 1年低值 highs = np.array([20.6, 21.7, 15.1, 16.1, 24.0]) # 1年高值 avgs = [16.5, 17.3, 13.4, 12.3, 19.0] # 平均值 names2 = ['A', 'B', 'C', 'D', 'E'] high_low_range = (highs - lows).round(1).tolist() # 构建图表数据 chart_data3 = ChartData() chart_data3.categories = names2 chart_data3.add_series("1Y Low", lows) chart_data3.add_series("1Y High", high_low_range) # 创建幻灯片并添加图表 prs = Presentation() slide = prs.slides.add_slide(prs.slide_layouts[5]) x, y, cx, cy = Inches(6.3), Inches(1.), Inches(4.8), Inches(3.5) chart = slide.shapes.add_chart(XL_CHART_TYPE.BAR_STACKED, x, y, cx, cy, chart_data3).chart # 隐藏图例 chart.has_legend = False # 处理低值系列:设置为背景填充(隐藏) series1 = chart.series[0] for point in series1.points: fill = point.format.fill fill.background() # 处理区间系列:设置填充色 series2 = chart.series[1] for point in series2.points: fill = point.format.fill fill.solid() fill.fore_color.rgb = RGBColor(135, 175, 191) # 配置坐标轴 value_axis = chart.value_axis value_axis.visible = True category_axis = chart.category_axis category_axis.visible = True category_axis.format.line.fill.background() # 保存文件 prs.save('range_chart_initial.pptx')
效果对比
现有效果

目标效果

实现思路与指导
可以通过python-pptx实现目标样式,核心思路是在现有堆叠条形图基础上,添加散点图系列来标记平均值,具体步骤如下:
保留现有区间展示逻辑:继续使用堆叠条形图模拟低值到高值的区间,确保区间展示正确。
添加平均值散点系列:
- 在现有图表数据中添加平均值系列;
- 将该系列的图表类型改为散点图,设置标记样式为菱形;
- 校准散点的Y轴位置,使其与分类项(A-E)一一对应。
调整样式与布局:
- 隐藏散点图的多余坐标轴;
- 设置菱形标记的颜色、大小,匹配目标样式;
- 确保散点系列显示在条形图上方。
关键代码片段
以下是添加平均值菱形标记的核心代码,可插入到现有代码的坐标轴配置之后:
from pptx.enum.chart import XL_MARKER_STYLE, XL_CHART_TYPE # 添加平均值系列到图表数据 chart_data3.add_series("Avg", avgs) # 获取平均值系列并转为散点图 avg_series = chart.series[2] scatter_plot = chart.plots.add(XL_CHART_TYPE.XY_SCATTER) scatter_plot.series.append(avg_series) # 配置菱形标记样式 avg_series.marker.style = XL_MARKER_STYLE.DIAMOND avg_series.marker.size = 10 avg_series.marker.fill.solid() avg_series.marker.fill.fore_color.rgb = RGBColor(0, 0, 0) # 黑色菱形 avg_series.marker.line.fill.background() # 隐藏标记边框 # 隐藏散点图的坐标轴(复用条形图坐标轴) for axis in scatter_plot.axes: axis.visible = False # 保存最终文件 prs.save('range_chart_final.pptx')
注意事项
- 若出现菱形标记位置偏移,可通过调整散点的Y值(比如将分类索引转为带小数的数值)进行校准;
- 确保导入
XL_MARKER_STYLE枚举,否则无法设置菱形标记样式。
内容的提问来源于stack exchange,提问作者Dazz W
相关产品推荐
相关产品推荐

