资讯动态

基于Python3+MATLAB的RSSI测距多边定位仿真全流程

发布时间:2026/9/14 5:44:04 来源:尧图企业网站定制
简介面向课程设计场景的无线传感器网络仿真项目基于Python与MATLAB双环境实现重点解决基于接收信号强度指示测距的多边定位法仿真问题同时配合节点覆盖、介质访问控制协议、路由协议等实验构成一套完整的课程设计方案。压缩包共八十九个文件整体大小约一点四七兆包含十七个Python源文件、十二个MATLAB脚本、三十四张网络拓扑图与流程图、八份原理说明与部署文档另有若干数据文件辅助复现方便对照源码与文档逐步理解无线定位、网络分层与协议实现细节。项目源码经过严格测试运行稳定并附带部署说明可直接用于软件工程、物联网、通信工程等专业的课程设计、大作业或入门实践。目前已有上百人学习参考整套内容层次分明既可作为规范化作业示例也方便在此基础上扩展与改进是掌握无线传感器网络仿真流程的实用资料。1. 做WSN定位仿真先想清楚你要仿真的是算法还是系统很多人在课程设计里选了“基于Python3MATLABRSSI测距的多边定位法”这个题目结果一头扎进代码调了几天RSSI转距离的公式最后画出来的误差图却没法说服老师。问题通常不在代码而在你没想清楚这个题目要求的其实是一个“完整链路”从信号传播模型到测距误差注入再到多边定位求解最后是误差评估。Python3负责数据处理和算法验证MATLAB负责可视化对比和报告出图RSSI测距是核心输入多边定位法才是你要证明有效性的对象。所以这不是一个“调库就能交差”的题目。你需要自己写路径损耗模型、自己构造锚节点和未知节点的几何关系、自己做最小二乘或三边定位迭代还要能解释清楚“为什么RSSI测出来的距离有抖动定位结果就偏了”。这篇文章按我实际做这类仿真课设的习惯把从信道模型到误差分析的完整套路讲一遍。适合正在做课程设计、毕业设计或想快速搭建WSN定位仿真环境的人Python3和MATLAB你至少得熟一个两个都会更好。读完你就能直接跑通一条最小链路并知道哪些参数能调、哪些坑必须躲。2. RSSI测距模型和多边定位的数学基础2.1 无线传感器网络里RSSI为什么能测距RSSI测距的本质是利用信号在空间传播时的衰减规律——接收功率和传播距离之间存在函数关系。无线传感器网络里节点硬件成本低没有办法像GPS那样做高精度授时测距所以RSSI成了最廉价的测距手段。它的基本原理是发射功率已知、发射天线增益已知、接收机灵敏度已知那么接收信号强度指示RSSI就能反推出发射端到接收端的路径损耗进而估算距离。最常用的经验模型是对数距离路径损耗模型Log-Distance Path Loss Model[ PL(d) PL(d_0) 10n \log_{10}\left(\frac{d}{d_0}\right) X_\sigma ]其中PL(d)是距离为d时的路径损耗单位dBPL(d_0)是参考距离d_0处的路径损耗n是路径损耗指数环境越复杂n越大X_\sigma是均值为0、标准差为σ的高斯随机变量用来模拟阴影衰落。在代码里一般直接写成接收信号强度def rssi_from_distance(d: float, Pt: float -20, n: float 2.5, d0: float 1.0, sigma: float 3.0) - float: 根据距离生成RSSI值Pt是发射功率(dBm)返回接收功率(dBm) pl_d0 40.0 # 1米处路径损耗经验值 rssi_ideal Pt - pl_d0 - 10 * n * math.log10(d / d0) noise random.gauss(0, sigma) return rssi_ideal noise这里sigma是阴影衰落标准差室内环境一般取2~6dB室外开阔环境取1~3dB。n是关键参数自由空间取2室内有遮挡取2.5~3.5密集城区取3.5~5。课程设计里如果老师给定了环境参数你就要用对应值如果没给n2.5, sigma3是最不容易被质疑的默认组合。反向由RSSI求距离的公式是def distance_from_rssi(rssi: float, Pt: float -20, d0: float 1.0, n: float 2.5) - float: 由RSSI反推距离注意这个距离自带误差 pl_d0 40.0 pl Pt - rssi d d0 * 10 ** ((pl - pl_d0) / (10 * n)) return d这个公式本身很简单但它有一个致命问题n和pl_d0是环境参数实际部署时你不可能精确知道所以测距误差几乎不可避免。这就是为什么后面的定位算法必须容忍距离误差不能一上来就用纯几何解析法。2.2 多边定位法的数学本质最小二乘解多边定位法的思路是已知M个锚节点坐标以及未知节点到每个锚节点的估算距离求未知节点坐标。用数学语言描述就是求解一个非线性最小二乘问题。假设未知节点坐标为(x, y)锚节点坐标为(x_i, y_i)观测距离为d_i那么理论距离应该满足[ \sqrt{(x - x_i)^2 (y - y_i)^2} d_i \epsilon_i ]平方后展开用第一个锚节点作为参考减去其他方程就能线性化。设第i个方程减去第1个方程[ (x - x_i)^2 - (x - x_1)^2 (y - y_i)^2 - (y - y_1)^2 d_i^2 - d_1^2 ]整理成矩阵形式Ax bimport numpy as np def multilateration(anchors: np.ndarray, distances: np.ndarray) - np.ndarray: 多边定位最小二乘解 anchors: (M, 2) 锚节点坐标 distances: (M,) 观测距离带误差 返回: (2,) 定位坐标 n_anchors anchors.shape[0] A np.zeros((n_anchors - 1, 2)) b np.zeros(n_anchors - 1) for i in range(1, n_anchors): A[i-1, 0] 2 * (anchors[i, 0] - anchors[0, 0]) A[i-1, 1] 2 * (anchors[i, 1] - anchors[0, 1]) b[i-1] distances[0]**2 - distances[i]**2 \ anchors[i, 0]**2 anchors[i, 1]**2 - \ anchors[0, 0]**2 - anchors[0, 1]**2 result np.linalg.lstsq(A, b, rcondNone) return result[0]这个解法的好处是不需要迭代速度极快而且当锚节点数大于等于3二维定位时矩阵A是超定方程组最小二乘会给出一个使残差平方和最小的解。但我必须指出这个线性化解法没有考虑距离噪声的统计分布在噪声大时会有偏。如果你只是想完成课设这个解够用了如果你想做深入一点可以用加权最小二乘权重取1/d_i^2因为远距离的RSSI测距更不可靠。2.3 锚节点数量和几何布局对精度的影响很多人以为锚节点越多越好、越近越好这个直觉对但不完全对。锚节点数量增加能降低随机噪声的影响但前提是锚节点的几何位置不能太差。有一个专门概念叫GDOP几何精度因子锚节点围成的区域越大、越均匀GDOP越小定位精度越高。反过来如果所有锚节点几乎在一条直线上即使有20个锚节点定位结果也会沿那条直线方向产生巨大偏差。课程设计里如果想体现这一点建议做一组对比实验锚节点数量取3、4、5、6个分别放在正方形顶点和一条线上记录定位误差。你会发现线形布置时误差比正方形布置大几倍这比单纯调参数更能说明问题也是答辩时老师爱听的分析。写仿真代码时锚节点坐标不要写死在脚本里用参数列表定义方便后面做布局对比anchor_layouts { square: np.array([[0, 0], [20, 0], [20, 20], [0, 20]]), line: np.array([[0, 0], [5, 0], [10, 0], [15, 0], [20, 0]]), random: np.random.uniform(0, 20, (6, 2)) }3. Python3侧实现RSSI仿真与多边定位完整链路3.1 仿真场景参数怎么设才合理做WSN定位仿真第一步不是写代码而是把仿真场景参数定清楚。这些参数直接影响实验结果的可靠性也是报告里必写的内容。常见的做法是设定一个50m x 50m的区域在四个角和中间放锚节点未知节点的真实坐标随机生成然后让程序自动完成“从真实坐标生成RSSI → 由RSSI估计距离 → 多边定位 → 计算误差”的完整流程。参数配置适合用dataclass组织方便后续批量跑实验from dataclasses import dataclass dataclass class SimulationConfig: field_size: float 50.0 # 仿真区域边长单位米 tx_power: float -20 # 发射功率单位dBm path_loss_exp: float 2.5 # 路径损耗指数n shadow_std: float 3.0 # 阴影衰落标准差单位dB ref_loss_los: float 40.0 # 1米处路径损耗单位dB n_anchors: int 5 # 锚节点数量 n_trials: int 1000 # 蒙特卡洛实验次数这些参数不是拍脑袋定的。field_size50对应一个中等规模的室内或园区环境tx_power-20是蓝牙和802.15.4常见的发射功率档path_loss_exp2.5是室内有遮挡环境的典型值。如果你用的是ZigBee或LoRa参数要把tx_power和ref_loss_los相应调整这篇仿真代码的核心逻辑不受影响。3.2 生成带噪RSSI观测值并完成一次定位有了配置接下来写核心仿真脚本。一次蒙特卡洛实验的流程随机生成未知节点坐标计算每个锚节点到未知节点的真实距离通过路径损耗模型生成RSSI再由RSSI估计距离最后用多边定位求坐标。import math import random import numpy as np def run_single_trial(cfg: SimulationConfig, anchors: np.ndarray) - tuple: 一次完整仿真真实坐标 - RSSI测距 - 多边定位 - 返回误差 # 在仿真区域内随机生成一个未知节点 true_pos np.array([random.uniform(0, cfg.field_size), random.uniform(0, cfg.field_size)]) # 计算到所有锚节点的真实距离和RSSI观测值 true_dists np.linalg.norm(anchors - true_pos, axis1) rssi_obs np.array([ cfg.tx_power - cfg.ref_loss_los - 10 * cfg.path_loss_exp * math.log10(d) ] for d in true_dists if d 0) # 注意距离不能为0 # 加入阴影衰落 rssi_obs np.random.normal(0, cfg.shadow_std, sizerssi_obs.shape) # 由RSSI反推距离 est_dists np.array([ 10 ** ((cfg.tx_power - cfg.ref_loss_los - rssi) / (10 * cfg.path_loss_exp)) for rssi in rssi_obs ]) # 多边定位 est_pos multilateration(anchors, est_dists) # 计算定位误差 error np.linalg.norm(est_pos - true_pos) return true_pos, est_pos, error这里有个关键细节RSSI生成时距离不能为0否则对数模型会算出无穷大。通常锚节点和未知节点不会完全重合但随机生成坐标时可能距离很近所以代码里要加一个最小距离限制比如max(d, 0.1)。另一个容易忽略的是rssi_obs np.random.normal(...)这行噪声必须在RSSI域加不能在距离域加。有些同学图省事直接对距离加高斯噪声这从物理角度是错的因为RSSI测距的误差服从的是对数正态分布换算到距离域后是乘性噪声。答辩时能说清这一点会显得你真正理解了模型。3.3 跑蒙特卡洛实验并输出统计结果单次实验说明不了问题必须跑多次蒙特卡洛实验统计平均定位误差、均方根误差RMSE和误差累计分布。课程设计报告里通常需要这三项指标。def run_experiment(cfg: SimulationConfig, anchors: np.ndarray) - dict: 蒙特卡洛实验返回统计指标 errors [] positions [] for _ in range(cfg.n_trials): true_pos, est_pos, error run_single_trial(cfg, anchors) errors.append(error) positions.append((true_pos, est_pos)) errors np.array(errors) stats { mean_error: np.mean(errors), rmse: np.sqrt(np.mean(errors**2)), median_error: np.median(errors), p90_error: np.percentile(errors, 90), std_error: np.std(errors) } return statsmean_error反映平均性能rmse对大的定位偏差更敏感p90_error说明90%的定位误差在多少米以内。这些指标在报告里都要写老师看你给出了不止一个均值就会认为你做了扎实的统计验证。跑完实验后建议把结果存成CSV或JSON方便下一步导入MATLAB做图。3.4 Python3输出结果文件交给MATLAB出图Python3和MATLAB的分工我的建议是Python3负责所有数值计算和蒙特卡洛实验MATLAB负责画精美曲线和分布图。课程设计报告里的图MATLAB画的比matplotlib的更受传统老师待见这也是这个题目同时出现Python3和MATLAB的原因。import json import numpy as np def save_results_to_json(results: dict, filename: str): 把实验统计结果和误差序列存成JSON供MATLAB读取 with open(filename, w) as f: json.dump(results, f, indent2) # 同时可以保存详细的误差序列方便MATLAB画CDF np.savetxt(filename.replace(.json, _errors.csv), np.array(results[errors]), delimiter,) # 示例统计结果 results { errors: errors.tolist(), mean_error: float(np.mean(errors)), rmse: float(np.sqrt(np.mean(errors**2))) } save_results_to_json(results, simulation_results.json)把误差序列存成CSV是关键因为MATLAB读取JSON稍微麻烦但读CSV是一行命令的事。到时候MATLAB脚本里用readmatrix(simulation_results_errors.csv)就能把数据拉进来。3.5 MATLAB侧读取并绘制定位散布图与误差直方图MATLAB侧不只是画图你也可以用它复现一遍核心算法来做交叉验证这才是双语言课程设计该有的形态。下面这段MATLAB代码读取Python3生成的坐标估计结果画出定位散布图和误差直方图。% 读取Python3生成的估计坐标和真实坐标 % 假设已经通过 csvwrite 或 writematrix 导出 est_pos readmatrix(est_positions.csv); true_pos readmatrix(true_positions.csv); % 定位散布图 figure(Color, white, Position, [100 100 800 600]); scatter(true_pos(:,1), true_pos(:,2), 60, b, filled); hold on; scatter(est_pos(:,1), est_pos(:,2), 30, r, o); legend(真实位置, 估计位置, Location, best); xlabel(X坐标 (m)); ylabel(Y坐标 (m)); title(RSSI多边定位结果散布图); grid on; axis equal; % 误差直方图 figure(Color, white); errors sqrt(sum((true_pos - est_pos).^2, 2)); histogram(errors, 30, FaceColor, [0.2 0.5 0.8], EdgeColor, white); xlabel(定位误差 (m)); ylabel(频次); title(定位误差分布); grid on; % 标注统计指标 text(0.8*max(xlim), 0.85*max(ylim), ... sprintf(平均误差: %.2fm\nRMSE: %.2fm, mean(errors), sqrt(mean(errors.^2))), ... FontSize, 11);这段代码里scatter的蓝色填充点表示真实位置红色空心圆表示估计位置误差直方图能直观看出定位误差集中在哪个区间。有几个参数要注意Position, [100 100 800 600]是控制图窗大小和位置在报告出图时建议固定下来保证统一画幅axis equal必须加否则散布图在X和Y方向比例不一致看起来会误导阅读者。hold on是为了在同一张图上叠加两层数据没有它散点会被覆盖。更多MATLAB可视化技巧在报告里都很加分比如画误差CDF曲线、误差随锚节点数量变化的折线图这些都可以复用上面的读取和绘制模式。4. WSN定位仿真里的参数标定和误差控制4.1 路径损耗指数n取多少决定你仿真报告有没有可信度路径损耗指数n是全部仿真里最敏感的参数。它的物理含义是信号衰减速度n2时信号在自由空间传播每增加十倍距离衰减20dBn3时每十倍距离衰减30dB。在课程设计里如果不说明n的取值依据老师很容易觉得你在瞎调参数。常见做法是引用ITU标准或IEEE 802.15.4的建议值办公室环境n2.4~2.8开阔室外n2~2.4室内走廊有墙壁遮挡n3~4树丛或复杂工业环境n4~5。我一般会额外做一个灵敏度分析把n从2.0扫到4.0看定位RMSE如何变化。def sweep_path_loss_exp(cfg: SimulationConfig, anchors: np.ndarray, n_values: list) - dict: 扫描路径损耗指数观察对定位误差的影响 results {} for n in n_values: cfg.path_loss_exp n stats run_experiment(cfg, anchors) results[n] stats return results这个实验结果很多时候是反直觉的n大时RSSI随距离衰减更快理论上测距应该更“敏感”但同时也意味着同等RSSI波动对应更小的距离变化在某些信噪比区间反而误差更小。细节讨论留给报告模拟跑出来什么就是什么不要硬凑结论。你需要做的是让老师看到你考虑了n的影响并给出了实验依据。4.2 阴影衰落标准差σ对定位精度的影响σ描述的是环境遮挡造成的不可重复的随机衰落。在仿真代码里σ越大RSSI观测噪声越大测距越不准最终定位误差必然上升。这个结论太平淡体现不了你的工作量。进阶做法是把σ作为一个可调参数和多边定位的加权系数联动起来。常见的改进是加权最小二乘WLS替代普通最小二乘。权重取距离的倒数或平方倒数因为RSSI的对数模型决定了远距离测距的绝对误差更大、可信度更低。实现很轻量def wls_multilateration(anchors: np.ndarray, distances: np.ndarray) - np.ndarray: 加权最小二乘多边定位权重取1/d^2 n anchors.shape[0] A np.zeros((n - 1, 2)) b np.zeros(n - 1) w np.ones(n - 1) for i in range(1, n): A[i-1, :] 2 * (anchors[i, :] - anchors[0, :]) b[i-1] distances[0]**2 - distances[i]**2 \ np.sum(anchors[i, :]**2) - np.sum(anchors[0, :]**2) w[i-1] 1.0 / distances[i]**2 A_w A * w.reshape(-1, 1) b_w b * w return np.linalg.lstsq(A_w, b_w, rcondNone)[0]注意w是逐元素乘到每一行相当于给误差大的方程更大的权重。w[i-1] 1.0 / distances[i]**2这一行是核心距离越远权重越小正好抵消RSSI测距在远距离处更大的不确定性。在报告的对比实验里普通最小二乘和加权最小二乘在σ6dB时会拉开差距σ2dB时差距不大这也符合理论预期。4.3 未知节点不在锚节点凸包内时怎么处理这是定位仿真里一个特别容易被忽视的边界情况如果未知节点落在锚节点包围区域之外多边定位的最小二乘解仍然会给出一组坐标但这个坐标可能明显偏离真值而且没有任何警示。实际部署场景中用户的位置天然会超出锚节点覆盖范围所以仿真必须覆盖这个场景。处理思路之一是在仿真里检测凸包包含关系如果未知节点在凸包外则单独统计并分析该场景下的定位偏差from scipy.spatial import ConvexHull def in_convex_hull(point: np.ndarray, anchors: np.ndarray) - bool: 判断点是否在锚节点形成的凸包内 points np.vstack([anchors, point]) hull ConvexHull(points) # 如果新增的点成为凸包顶点说明它在原凸包外 return not any(np.all(hull.points[v] point) for v in hull.vertices)这段代码的原理是把未知节点加进去重新计算凸包若新点出现在凸包顶点里说明它不在原锚节点凸包内。这个技巧非常简单但答辩时能提出来说明你理解“多边定位法的适用边界”。不过要注意scipy.spatial不是标准库课程设计环境如果没有装scipy可以自己写一个简单的判断比如判断点是否在凸多边形内部的角度和法。为了稳妥建议优先用shapely.geometry.Point.within或干脆自己实现射线法避免依赖问题。4.4 距离为负或RSSI超出灵敏度范围时的数据清洗无线传感器网络仿真还有一个常见坑根据路径损耗模型生成的RSSI可能会低于接收机灵敏度尤其当距离很远或σ很大时。真实硬件在这种情况下根本收不到信号而你的仿真代码却会把它当作一个有效的负值参与计算这会严重拉低定位精度。正确做法是增加一个接收机灵敏度参数默认取-95dBm低于这个值的观测丢弃同时判断剩余锚节点是否够用def filter_by_sensitivity(anchors: np.ndarray, distances: np.ndarray, rssi_obs: np.ndarray, sensitivity: float -95.0) - tuple: 剔除低于接收机灵敏度的锚节点观测返回过滤后的数据 valid rssi_obs sensitivity if np.sum(valid) 3: # 锚节点不够无法定位 return None return anchors[valid], distances[valid], rssi_obs[valid]这里valid是一个布尔掩码anchors[valid]只保留RSSI大于灵敏度的锚节点。这样做才符合真实硬件行为报告里也能多一段“环境噪声下覆盖空洞如何处理”的讨论。如果过滤后锚节点数量不足3个定位直接失败统计时计入失败率不要硬算出个坐标来充数。5. 仿真结果验证与MATLAB报告级出图技巧5.1 做误差CDF曲线验证定位算法的统计特性基本的均值和RMSE不够课程设计要上档次至少要画一条误差累计分布函数曲线。CDF曲线能告诉你“有多少比例的错误小于某阈值”比单点均值更有决策意义。用MATLAB画CDF很简单但数据预处理要在Python3或MATLAB里先排序。% 读取误差序列 errors readmatrix(simulation_results_errors.csv); % 计算CDF sorted_errors sort(errors); cdf_values (1:length(sorted_errors)) / length(sorted_errors); % 绘制CDF曲线 figure(Color, white); plot(sorted_errors, cdf_values, b-, LineWidth, 2); hold on; % 在90%处画参考线 p90 prctile(errors, 90); % 或者用 quantile(errors, 0.9) xline(p90, r--, LineWidth, 1.5); yline(0.9, r--); text(p90, 0.5, sprintf(P90%.2fm, p90), Color, r, FontSize, 11); xlabel(定位误差 (m)); ylabel(累计概率); % 禁止使用默认标题要求写清实验条件 title(sprintf(RSSI多边定位误差CDF, n%.1f, σ%.1fdB, 2.5, 3.0)); grid on; xlim([0, max(sorted_errors)]); ylim([0, 1.05]);xline和yline是MATLAB R2018b之后才有的函数如果你用旧版本画法要改成plot([p90, p90], [0, 1], r--)的方式否则会报错。同理prctile函数用quantile替代也行。这段代码里title必须带上仿真参数方便老师直接从图里看到实验条件这也是报告出图的一致性原则——每张图都要能独立说明问题。5.2 锚节点数量从3扫到8时的误差趋势图如果想在报告里多一个“参数化实验”最常见的做法是固定其他条件不变改变锚节点数量观察定位误差的下降趋势。注意锚节点数量增加的收益是递减的通常从3个增加到5个误差下降明显再往后提升有限这正好和GDOP理论吻合。MATLAB画趋势图% 假设已经通过Python3计算出不同锚节点数对应的RMSE n_anchors [3, 4, 5, 6, 7, 8]; rmse_list [1.85, 1.42, 1.18, 1.05, 0.98, 0.94]; % 示例数据实际由仿真生成 figure(Color, white); plot(n_anchors, rmse_list, bo-, LineWidth, 2, MarkerSize, 8); xlabel(锚节点数量); ylabel(RMSE (m)); title(锚节点数量对RSSI多边定位精度的影响); grid on; set(gca, XTick, n_anchors);这里set(gca, XTick, n_anchors)保证X轴刻度只显示整数锚节点数量避免出现非整数刻度。MarkerSize控制数据点大小LineWidth影响曲线粗细两个值在报告里尽量统一多张图放在一起时视觉效果才协调。如果你是用LaTeX写报告强烈建议MATLAB导出图时指定分辨率exportgraphics(gcf, rmse_vs_anchors.pdf, Resolution, 300)。5.3 Python3和MATLAB联合仿真的文件接口约定两个语言协作最容易出的问题就是文件格式不统一。我建议固定用CSV和JSON两种格式CSV存数值序列、JSON存结构化统计。Python3侧统一用pandas.DataFrame.to_csv或numpy.savetxt导出MATLAB侧统一用readmatrix和jsondecode读取。这里有一个常见坑MATLAB的readmatrix读取CSV时如果文件里有表头会自动忽略表头但如果你用旧版csvread遇到非数值内容会直接报错。所以要么导出时不要表头要么用readtable读取。一个稳妥的接口约定是# 从Python3侧导出 python3 simulator.py --config config.json --output result_dir/ # 目录结构 # result_dir/ # estimated_positions.csv # 每行: est_x, est_y # true_positions.csv # 每行: true_x, true_y # stats.json # {rmse: 1.18, mean_error: 0.95, ...}然后再在MATLAB侧写一个统一load_results.m函数一次读取所有数据避免反复改路径。这个函数不需要太复杂核心是清楚记录列顺序编号、横坐标、纵坐标、误差别把列顺序搞混。5.4 论文报告里最优定位图怎么排最后一节讲一个很实用的出口经验MATLAB画好的图怎么放进报告里才显专业。课程设计报告里常见问题是图太小、图注不清楚、坐标轴字体太小。更严重的是没有给图编号和引用。我建议每张图都采用统一风格白色背景、无边框、线宽紧凑、坐标轴字体10pt或11pt、图注写在图下方居中。插图格式用PDF矢量格式或300dpi以上的PNG放大也不糊。具体到一个可执行的最小方案我在MATLAB里固定一个函数保存所有报告图function save_fig_for_report(fig, name) % 统一保存报告用图PDF矢量格式300dpi PNG双份 exportgraphics(fig, [name .pdf], ContentType, vector); exportgraphics(fig, [name .png], Resolution, 300); fprintf(已保存 %s.pdf 和 %s.png\n, name); end这里ContentType, vector确保文字和曲线是矢量格式PDF里放大不失真Resolution, 300是PNG的分辨率印刷级别够用。导出前记得先figure(Color, white)不然默认图背景是灰色放进报告非常难看。使用这个函数的方式很简单画出散布图之后调用save_fig_for_report(gcf, fig_scatter)整个报告出图流程就规范了。报告里配合一句“本文所有仿真图均由MATLAB处理Python3生成的仿真数据得到”就能把双语言工具链的合理性圆上。剩下的时间你可以用来做更深入的误差模型对比比如把对数正态模型换成正态模型跑一组实验看看定位结果差多少。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价