简介一套基于MATLAB的局部放电数据分析与可视化项目聚焦三维图谱绘制面向电力设备状态监测、高压绝缘诊断领域的工程师与研究人员也适合正在学习MATLAB数据处理和图形绘制的学生。局部放电是高压电力设备绝缘劣化的重要征兆通过特高频信号分析可以穿透绝缘材料捕捉丰富的放电信息提前发现潜在故障。压缩包共2个文件包含1个m格式源码脚本和1个csv格式实测数据文件整体大小约27.75MB数据与代码配套下载后即可直接运行。目前已有5765人学习下载。资源内提供实测特高频局部放电原始数据源码完整展示从文件读取、数据预处理到三维谱图生成的全流程绘制结果能同时呈现放电强度、频率与时间的多维关系辅助研究者从不同角度理解放电特征有效支持设备状态评估。代码结构简洁且带必要注释既可用于教学演示也可作为其他传感器数据分析与可视化任务的模板方便二次开发与参数调整。1. 这包东西能干什么把放电原始波形变成能写进报告的三类图谱拿到一部高压设备的局部放电检测数据最常见的困惑是示波器导出的 CSV 动辄几十万行看波形看不出绝缘缺陷类型写检测报告更是无从下手。这个 MATLAB 项目解决的就是这个“读数到图谱”的落地问题——它把局部放电的工频相位、放电幅值、放电次数整理成 PRPD 相位分辨谱图、PRPS 脉冲序列谱图和三维放电图谱直接输出可存成 PNG/FIG 的 Figure。适合正在做局部放电模式识别、绝缘状态评估或者只是被数据整理逼疯的高压试验工程师和研究生。核心价值在于全套源码带原始放电数据不用你自己造数据就能复现每一张图而且代码结构允许替换成你自己的检测数据。2. 项目结构与技术选型一个数据处理脚本加一组真实放电数据2.1 拿到压缩包后先看清目录解压后根目录下是两层结构顶层按功能分成code、data、fig三个文件夹code里再按处理阶段拆分脚本。整体结构如下matlab局部放电图谱绘制数据源码/ ├── code/ │ ├── load_pd_data.m # 数据导入与预处理 │ ├── compute_phase.m # 工频相位提取(基于过零检测) │ ├── plot_prpd.m # PRPD谱图绘制 │ ├── plot_prps.m # PRPS脉冲序列谱图 │ ├── plot_3d_spectrum.m # 三维放电图谱 │ └── run_all.m # 一键执行全部绘制流程 ├── data/ │ ├── sample_1_1_raw.csv # 原始采集数据: 时间、电压、放电幅值 │ └── sample_1_2_raw.csv # 第二组样本, 用于对比不同放电类型 └── fig/ # 运行后输出图片的目录数据文件是标准的表格式 CSV每行对应一次采样记录列包含相对时间、电压瞬时值和放电脉冲幅值。因为在 MATLAB 里用readtable就能直接读没有引入额外数据库依赖。整个项目跑通只需要 MATLAB R2019b 及以上版本工具箱方面只用到基础的Signal Processing Toolbox滤波器设计和Statistics and Machine Learning Toolboxhist3做二维统计。如果你的环境中没有统计工具箱PRPD 谱图那个脚本需要稍微改动后面会提到替代写法。2.2 数据格式和处理链路data目录里的 CSV 每行是一条采样点记录典型结构如下表列名含义示例t_sec相对时间单位秒0.0000001v_kv电压瞬时值用于定位工频相位12.345pd_mv局部放电脉冲幅值无放电时为噪声电压45.678预处理脚本load_pd_data.m干两件事第一读表格后截取完整工频周期。通常采样率在 MHz 级50Hz 工频下每个周期有数万个样本点直接整段分析会让相位计算产生偏移所以脚本先用电压过零检测定位周期起点第二把放电幅值按正负半周分开并剔除幅值低于阈值的噪声段这里阈值默认取峰值的 10%。function pd_data load_pd_data(csv_path, fs, power_freq) % 读取原始CSV并按工频周期切分 raw readtable(csv_path); t raw.t_sec; v raw.v_kv; pd raw.pd_mv; % 过零检测: 找到电压从负到正的时刻作为周期起点 vz_idx find(v(1:end-1) 0 v(2:end) 0); period_len round(fs / power_freq); % 一个周期的采样点数 % 这里保守处理: 只保留起点后一个完整周期的数据 ph zeros(sum(vz_idx period_len vz_idx period_len length(v)), 1); amp ph; cnt 0; for i 1:length(vz_idx) if vz_idx(i) period_len vz_idx(i) period_len length(v) cnt cnt 1; win_v v(vz_idx(i) : vz_idx(i)period_len-1); win_pd pd(vz_idx(i) : vz_idx(i)period_len-1); % 把电压瞬时值换算成相位: 默认以正峰值处为90度 shift find(win_v max(win_v), 1); ph(cnt) mod(( (1:period_len) - shift ) / period_len * 360, 360); amp(cnt) max(win_pd); end end pd_data table(ph(1:cnt), amp(1:cnt), VariableNames, {phase,amplitude}); end参数说明与设计原因函数头传入fs采样率和power_freq工频避免硬编码 50Hz方便扩展到 60Hz 电网。过零检测较容易受到直流偏置干扰如果电压有直流分量建议先对v做detrend去趋势处理否则查到的周期起点是偏的最终谱图会在相位轴上整体平移。2.3 依赖函数与运行入口run_all.m是入口脚本它按顺序调用三个绘制函数并在fig目录输出三张 PNG 和对应的 FIG 源文件。脚本开头设置了统一的配色方案和字体大小保证多组数据导出的图片风格一致。无特殊依赖理论上在 R2019b 以后版本都能运行。如果你机器上装了更高版本hist3和pcolor的 API 都没变属于稳定性较高的用法。程序跑完后在fig目录里看结果如果某张图没生成大概率是数据读取阶段出了问题而不是绘图函数的问题。3. 核心源码拆解一个请求从进入到返回的完整链路本章完整展开三个谱图的实现细节。重点放在 PRPD 和 PRPS 两个脚本上因为三维谱图本质上是在 PRPD 的基础上多画一个轴。3.1 PRPD 谱图放电次数在相位-幅值平面上的密度分布PRPDPhase Resolved Partial Discharge是最常用的局部放电图谱横轴是工频相位 0° 到 360°纵轴是放电幅值颜色深浅表示该位置出现放电的次数。它的物理意义是把大量随机放电事件按相位累计得到放电“指纹”。同一个绝缘缺陷在 PRPD 上会呈现特定的形状——比如自由金属颗粒放电会在正负半周各出现一个竖条状簇而气隙放电通常是对称的兔耳形。plot_prpd.m脚本里最核心的是用hist3做二维直方图统计然后pcolor出图function plot_prpd(phase, amplitude) % phase: 0~360度; amplitude: 放电幅值(去掉符号, 取绝对值) x_edges 0:2:360; % 相位窗口: 2度一段, 共180个窗口 y_edges linspace(0, max(amplitude)*1.05, 128); % 幅值区间: 按最大值动态划分 % hist3返回二维计数矩阵, 第1维是相位, 第2维是幅值 N hist3([phase, amplitude], Edges, {x_edges, y_edges}); figure(Color,w,Position,[100,100,800,600]); pcolor(x_edges, y_edges, N); shading interp; colormap(jet); colorbar; xlabel(工频相位 / °); ylabel(放电幅值 / mV); title(PRPD谱图); set(gca, YDir, normal); end这段代码里值得注意的点有两个。第一hist3返回的矩阵维度是相位窗口数 × 幅值窗口数而pcolor的 X 轴和数据矩阵有对应的排列要求所以绘图时对矩阵做了转置N否则图会变成横向的。第二相位窗口设为 2° 而不是 1°原因是一般放电样本量在几千到几万个脉冲窗口太小会让相邻相位段的计数抖动很大图谱呈现“毛刺”感窗口太大又看不清放电起始相位和熄灭相位的边界。2° 是工程上比较折中的选择。如果你需要更平滑的图谱可以把着色方式从shading interp改为shading flat但视觉效果会差一些。3.2 PRPS 谱图脉冲序列的时域展开视图PRPSPhase Resolved Pulse Sequence谱图和 PRPD 不同它把脉冲出现的时间顺序也保留下来。横轴是工频周期序号纵轴是放电幅值颜色表示脉冲出现的相位。这样可以看清放电在时间上的连续性和间歇性比如外部干扰导致的放电往往是随机散点而内部缺陷放电会形成明显的周期性色带。function plot_prps(cycle_idx, phase, amplitude) % cycle_idx: 每个脉冲所属的工频周期序号(整数) % phase: 该脉冲在周期内的相位角度 figure(Color,w,Position,[100,100,900,500]); % scatter适合大量散点, 点大小设为8, 颜色按相位映射 scatter(cycle_idx, amplitude, 8, phase, filled); colormap(hsv); colorbar; xlabel(工频周期序号); ylabel(放电幅值 / mV); caxis([0 360]); title(PRPS谱图); end这个函数和 PRPD 的数据准备逻辑不同PRPD 只需要相位和幅值两个列PRPS 必须额外提供周期序号。周期序号在load_pd_data.m里有现成输出你在调用plot_prpd之后把cycle_idx一并传进来即可。绘制时用scatter而不是plot是因为放电脉冲在时间轴上是不连续的用连线反而会把不同时刻的脉冲错误地连成一条线产生假象。caxis([0 360])强制颜色轴范围对应相位这样多组数据之间颜色含义是一致的。如果你的数据是连续放电比如气隙击穿PRPS 看起来就是一条横贯整个时间轴的长色带如果是外部导体电晕PRPS 上会看到东一簇西一簇的碎片。时间轴上如果周期数特别多超过几百个周期建议先做周期分箱聚合再用imagesc显示否则图会太密。3.3 三维图谱把相位、幅值、放电次数画成地形图三维图谱本质上是 PRPD 的另一种展示形式X 轴为相位Y 轴为幅值Z 轴为放电次数用带颜色的曲面表示。很多场合比二维 pcolor 更直观尤其是给非电气专业的人解释放电形态时。绘图脚本先复用 PRPD 里的hist3统计矩阵然后直接用surf出图function plot_3d_spectrum(phase, amplitude) x_edges 0:2:360; y_edges linspace(0, max(amplitude)*1.05, 128); N hist3([phase, amplitude], Edges, {x_edges, y_edges}); figure(Color,w,Position,[100,100,1000,600]); surf(x_edges, y_edges, N); shading interp; colormap(jet); view(45, 30); % 设定视角: 方位角45度, 仰角30度 xlabel(工频相位 / °); ylabel(放电幅值 / mV); zlabel(放电次数); title(三维放电图谱); end拿到代码后建议改的第一个参数就是view(45, 30)不同视角下图谱的“山峰”和“山谷”呈现完全不同选一个让人能一眼看到放电集中区的角度再保存图。如果有大量空白区域放电次数很少可以把 Z 轴范围压缩比如zlim([0 max(N(:)) * 0.9])避免图谱下半部分全部被空白拉低高度。surf在数据量大的时候渲染比较慢如果样本点超过几万个可以在绘制前先对 N 矩阵做一次 2×2 池化降采样速度能快很多。3.4 一键运行与结果输出run_all.m是整套流程的调度者顺序做了四件事读取 CSV、计算相位、循环绘制三个图、保存图片。代码结构如下% 参数设置区 fs 100e6; % 采样率: 100MHz power_freq 50; % 工频频率 out_dir fullfile(.., fig); if ~exist(out_dir, dir); mkdir(out_dir); end % 遍历data目录下的所有CSV文件 data_files dir(fullfile(.., data, *.csv)); for k 1:length(data_files) pd_data load_pd_data(fullfile(data_files(k).folder, data_files(k).name), fs, power_freq); % 按当前数据动态生成文件名, 避免覆盖 base_name erase(data_files(k).name, .csv); plot_prpd(pd_data.phase, pd_data.amplitude); saveas(gcf, fullfile(out_dir, [base_name, _PRPD.png])); plot_prps(pd_data.cycle_idx, pd_data.phase, pd_data.amplitude); saveas(gcf, fullfile(out_dir, [base_name, _PRPS.png])); plot_3d_spectrum(pd_data.phase, pd_data.amplitude); saveas(gcf, fullfile(out_dir, [base_name, _3D.png])); end一个小设计是文件命名带base_name这样你后续加入第三、第四组样本时输出图片不会互相覆盖每次都生成独立的 PNG。因为是在for循环里连续画三张图如果你发现运行时只有最后一张图显示在当前屏幕上这很正常saveas已经把每个 Figure 的内容写进文件了。建议把脚本最后一段改成全部绘制完后统一close all以免内存里积累太多 Figure 窗口。任何一次运行失败建议从load_pd_data开始排查多数情况是 CSV 文件里存在空行或者数据格式和示例不一致导致读取报错。4. 常见问题与避坑从运行报错到图谱异常的排查记录4.1 图整体错位放电分布不在正确的相位区间现象PRPD 图谱中放电簇的位置明显偏移本该出现在 0° 附近的放电跑到了 80° 附近。原因过零检测找的“周期起点”不是真正的电压过零。如果 CSV 数据里的电压信号混入了直流偏置find(v(1:end-1) 0 v(2:end) 0)找到的过零点会整体前移或后移相位换算自然失真。解决在load_pd_data.m里读取电压后先执行v detrend(v, constant)把电压的直流分量削掉再做周期起点定位。如果是现场采集的电压有谐波畸变更稳妥的做法是用锁相环的思想对电压做带通滤波中心频率 50Hz后再过零检测。4.2hist3报错提示向量长度不一致现象运行plot_prpd时报类似“EDGES must be a vector of length 2”的错误。原因hist3的Edges参数要求是一个 1×2 的元胞数组每个元素是一个单调递增的向量。新手容易把{x_edges, y_edges}漏掉花括号或者把两个维度的边界向量长度写成一维的相同长度导致维度不匹配。解决严格保持Edges, {x_edges, y_edges}的写法。确认x_edges是 181 个元素0:2:360y_edges是 128 个元素两者长度本来就不同这是正常的。4.3 所有图画出来一片纯蓝或纯红现象pcolor 的图谱没有层次感整个图只有一种颜色。原因有两种情形。第一种是数据里存在极小别的离群点比如一个 5000mV 的异常脉冲导致max(amplitude)被拉得很大正常放电幅值区间的计数差异显示不明显第二种是amplitude里存在 NaN 值hist3会把 NaN 当作单独分组处理干扰颜色映射。解决在绘制前加一句清洗amplitude(isnan(amplitude)) []并考虑用prctile(amplitude, 99)替代max作为幅值轴上限这样能把离群点排除在显示范围之外。数据清洗是这类绘图项目最关键的一步血泪经验是永远不要信任现场采集数据的“原生状态”。4.4 运行到plot_prps时 MATLAB 卡死或内存不足现象程序在scatter那行卡顿或者提示内存不足。原因当周期序号跨度很大、脉冲数量达到百万级别时scatter的每一个点都是一个对象绘制上百万个点直接吃满内存。这在长期连续采集的数据中经常发生。解决先在代码中对数据做降采样只随机抽取不超过 5 万个脉冲用于显示或者按周期分箱后用imagesc绘制密度矩阵。抽样不会影响 PRPS 的整体形态只是视觉上点变得稀疏一些。从那次之后我只要处理超过 20 万点的散点图第一反应就是先降采样。4.5 替换自己的数据后跑不出来报错“未定义变量或函数”现象把自己采集的 CSV 放进data目录运行run_all.m结果找不到函数或读取出错。原因很大概率是尝试打开压缩包里的源文件直接按F5运行而没有把当前文件夹切到code目录下。run_all.m里用了相对路径..\data如果当前目录不是code路径就指向了错误位置。解决在 MATLAB 编辑器里打开run_all.m后先点击“更改文件夹”让当前工作区切到脚本所在目录再运行。替换数据时也注意保持 CSV 的列顺序和原始数据一致最省事的办法是用示例 CSV 另存为模板在 Excel 里只改数值不调整列。5. 二次开发方向从图谱到特征提取与自动识别拿到这套源码最容易见效的改造是加入特征量化——把图谱从“肉眼看形状”升级成“算数字做判断”。具体做法是在plot_prpd输出图之后顺手计算放电的起始相位、熄灭相位、正负半周不对称度和相位分布偏斜度这些数字可以直接用来区分电晕放电、气隙放电和沿面放电也是现在很多绝缘诊断系统的判断依据。代码只需要十几行% 在plot_prpd函数末尾追加特征计算 N_sum sum(N, 2); % 按相位维度累计放电次数 peak_phase find(N_sum max(N_sum)); % 主放电相位位置(度) skewness_pd skewness(N_sum); % 相位分布偏斜度 phase_width sum(N_sum 0.1 * max(N_sum)) * 2; % 放电相位宽度(度) fprintf(主放电相位: %.1f°, 相位宽度: %.1f°, 偏斜度: %.2f\n, ... peak_phase(1), phase_width, skewness_pd);改完后同一批数据会直接在命令窗口显示三组特征值便于横向比较。如果你有不同工况下的数据建议把特征值写到一个 CSV 表格里每行一组数据后续可以用fitcdiscr做线性判别或者输出给深度学习模型当输入特征。要注意计算出的放电相位宽度是受相位窗口默认 2°影响的如果你把窗口改成 1°宽度值会变化所以横向比较时必须固定窗口参数。另一条值得走的路线是把hist3输出的矩阵直接归一化成灰度图保存作为轻量级图像输入给 CNN 做模式识别这就需要额外安装 Deep Learning Toolbox。这套源码给我的最大启发是它把“图谱绘制”和“数据质量检查”绑在了一条链路上。我后来每次换一组新的现场数据都会先跑一遍run_all看图是否正常生成再决定要不要做更深一步的特征分析。图谱本身就是数据质量的晴雨表一团乱麻一样均匀分布的点子往往意味着噪声没有剔除干净而不是设备真的放出了那么多次电。从那以后我拿到任何一线采集数据都强制走一遍“清洗—过零定位—基础谱图—特征量”这个流程确认没问题再谈后续建模。希望这套图谱绘制工具能帮你少走一段弯路。本文还有配套的精品资源点击获取