
搞信号处理、电路分析或者控制系统的同学,常用到幅频响应曲线。
频率从 0.1kHz 到 10kHz,如果用普通线性坐标,低频段的细节全挤在一坨。这时候就需要半对数坐标。
一句话讲清楚半对数坐标:x 轴取对数,y 轴保持线性。低频段被拉宽,高频段被压缩。效果就是频率按数量级均匀分布,0.1、1、10 这三个刻度在图上间距相等。幅值在低频段的微小变化不再被挤压,你的数据特征一目了然。
代码里实现这件事的只有一行:
ax.semilogx(frequency, y, '-', linewidth=1, color=C[i], alpha=0.8)semilogx 的含义是「semi-log x」,x 轴对数,y 轴线性。这一行代替了 ax.plot(),其他参数完全一样。
下面是完整Python代码,实际用的时候把模拟数据删掉,换成你自己的数据数组,根据你的数据范围改 ylim。直接复制粘贴即可运行:
""" Semi-Log Line Plot Magnitude Response (dB). """# 关注微信公众号:数学建模BOOM,后台回复“科研”,获取AI科研写作与Python绘图合集import numpy as npimport matplotlib.pyplot as pltimport matplotlib as mplfrom matplotlib import ticker# 用到负号,设置微软雅黑字体避免出错mpl.rcParams['font.sans-serif'] = ['Microsoft YaHei']mpl.rcParams['axes.unicode_minus'] = False# 换成真实数据时,把 `frequency` 和 `magnitude` 替换成你自己的数组就行。# 此处使用仿真数据,频率从 0.1 kHz 到 10 kHz,幅度是一个衰减的正弦函数,模拟了某个系统的频率响应。frequency = np.logspace(-1, 1, 100)magnitude = np.sin(2 * np.pi * frequency) * np.exp(-0.3 * frequency) * 5# 10 行 3 列的 RGB 数组,除以 255 归一化到 0-1。颜色从深红渐变到深蓝,10 条曲线一条不撞色。C = np.array([[163, 6, 67],[217, 69, 77],[246, 122, 73],[253, 186, 107],[254, 233, 155],[246, 251, 177],[205, 234, 157],[138, 208, 164],[75, 164, 177],[75, 102, 173]]) / 255# 画布尺寸,figsize的单位是英寸。宽 5.8 厘米转换单位5.8/2.54英寸,dpi设置为300,是学术期刊的底线分辨率。fig, ax = plt.subplots(figsize=(5.8/2.54, 4.5/2.54), dpi=300)ax.set_facecolor('white')fig.patch.set_facecolor('white')# 半对数曲线绘制,y轴是幅度,x轴是频率。# for循环每条曲线的幅度在原始数据基础上加一个偏移量,形成10条不重叠的曲线。for i in range(10):offset = (i - 5) * 0.5y = magnitude + offsetax.semilogx(frequency, y, '-', linewidth=1, color=C[i], alpha=0.8)# 设置标题和坐标轴标签字体ax.set_title('Magnitude Response (dB)', fontsize=6, fontfamily='Arial', pad=3)ax.set_xlabel('Frequency (kHz)', fontsize=6, fontfamily='Arial')ax.set_ylabel('Magnitude (dB)', fontsize=6, fontfamily='Arial')ax.tick_params(labelsize=5)ax.set_ylim(-6.5, 6.5)ax.grid(True, linewidth=0.3, alpha=0.3, which='both') # 网格线# 四条边框线宽都 0.5,顶部和右侧不画刻度,只保留左侧和底部。这是科研论文的标准风格。for spine in ['top', 'bottom', 'left', 'right']:ax.spines[spine].set_linewidth(0.5)ax.spines[spine].set_color([0.1, 0.1, 0.1])ax.spines[spine].set_visible(True)# 刻度只保留左侧和底部的,这是科研论文的标准风格ax.xaxis.set_tick_params(width=0.5, length=2)ax.yaxis.set_tick_params(width=0.5, length=2)ax.tick_params(top=False, right=False)# 关注微信公众号:数学建模BOOM,后台回复“科研”,获取AI科研写作与Python绘图合集plt.tight_layout()plt.show()fig.savefig('半对数刻度折线图.png', dpi=300, bbox_inches='tight', facecolor='white')print('图像已保存为 半对数刻度折线图.png')
semilogx 记住这一个函数,频响曲线、伯德图、滤波器特性,这些图你就都有了底子~

【往期文章】
Nature:如何利用vibe coding助力科研——论文产出提高75%
数模AI知识库更新国赛板块——基于RAG增强检索,最懂数模的AI
-----------------------------------
点击下方关注公众号,在后台回复
回复 “群”,加入数模交流群;
回复“课程”,查看入门级数学建模精品课程(常用模型的原理讲解+例题+matlab编程,附带课件与代码)
