如何基于欧氏距离矩阵绘制semilogx单折线图?
问题描述
尝试基于欧氏距离矩阵绘制对数正态阴影路径损耗模型的semilogx图,期望用单条折线展示路径损耗随距离的变化差异,但使用cdist生成的欧氏距离矩阵时无法实现该效果;改用distance = np.arange(0.05, 15, 0.1) ** 2生成的距离变量则能正常显示单折线。以下是原始代码,预期效果为单折线带离散点的对数坐标图。
from scipy.spatial.distance import cdist import matplotlib.pyplot as plt import numpy as np # % Log-distance or Log-normal shadowing path loss model # % Inputs: fc : Carrier frequency[Hz] # % d : Distance between base station and mobile station[m] # % d0 : Reference distance[m] # % n : Path loss exponent # % sigma : Variance[dB] def logdist_or_norm(fc, d, d0, n, sigma): lamda = 3e8 / fc PL = -20 * np.log10(lamda / (4 * np.pi * d0)) + 10 * n * np.log10(d / d0) if sigma: PL = PL + sigma * np.random.randn(len(d)) return PL # % Channel Parameters fc = 2.4e9 #% operation in 2.4 GHz d0 = 0.25 #% good choice for indoor distances (microcells) sigma = 3 #% keep the book suggestion Gt = 1 #% No transmitter antenna gain as provided by nordic datasheet Gr = 1 #% No receiver antenna gain as provided by nordic datasheet Exp = 4 #% Mid value in the obstructed in building range (Table 1.1) # % Distance vector also for plot m = np.random.random((8, 2)) distance = cdist(m, m) # % Log-normal shadowing model y_lognorm = logdist_or_norm(fc, distance.flatten(), d0, Exp, sigma) # % Plot Path loss versus distance plt.semilogx(distance.flatten(), y_lognorm, 'k-o') plt.grid(True), plt.axis([0.05, 20, 0, 110]), plt.legend('Log-normal shadowing model') plt.title(['Log-normal Path-loss Model, f_c = ', str(fc/1e6),'MHz,', '\sigma = ', str(sigma), 'dB, n = 2']) plt.xlabel('Distance[m]'), plt.ylabel('Path loss[dB]')
问题原因
cdist(m, m)生成的是8×8的距离矩阵,展平后包含大量重复距离值,且这些距离是无序的。semilogx会严格按照输入数据的顺序绘制点,无序的距离会导致折线来回交叉,无法形成随距离递增的单条折线。而np.arange生成的是有序递增的距离序列,因此能正常绘制符合预期的单折线。
解决方案
要实现预期效果,需要生成有序的距离序列,并为每个距离计算对应的路径损耗(含阴影衰落)。修改后的代码如下:
from scipy.spatial.distance import cdist import matplotlib.pyplot as plt import numpy as np # 对数正态阴影路径损耗模型 def logdist_or_norm(fc, d, d0, n, sigma): lamda = 3e8 / fc PL = -20 * np.log10(lamda / (4 * np.pi * d0)) + 10 * n * np.log10(d / d0) if sigma: PL = PL + sigma * np.random.randn(len(d)) return PL # 信道参数 fc = 2.4e9 # 2.4GHz载波频率 d0 = 0.25 # 参考距离(室内微小区适用) sigma = 3 # 阴影衰落方差 Exp = 4 # 路径损耗指数(室内遮挡场景中间值) # 生成有序距离序列(替代无序的欧氏距离矩阵) # 覆盖0.05到20m范围,步长0.1m,保证距离递增 distance = np.arange(0.05, 20, 0.1) # 计算对数正态阴影路径损耗 y_lognorm = logdist_or_norm(fc, distance, d0, Exp, sigma) # 绘制路径损耗vs距离 plt.semilogx(distance, y_lognorm, 'k-o') plt.grid(True) plt.axis([0.05, 20, 0, 110]) plt.legend(['Log-normal shadowing model']) plt.title(f'Log-normal Path-loss Model, f_c = {fc/1e6:.0f}MHz, σ = {sigma}dB, n = {Exp}') plt.xlabel('Distance[m]') plt.ylabel('Path loss[dB]') plt.show()
关键修改说明
- 替换
cdist生成的无序距离矩阵为np.arange生成的有序递增距离序列,确保x轴数据按从小到大排列 - 用f-string简化标题的字符串拼接,格式更规范
- 修正
legend参数格式,传入列表而非单个字符串 - 添加
plt.show()确保图形正常显示
内容的提问来源于stack exchange,提问作者mmik
相关产品推荐
相关产品推荐

