当前位置:首页>python>Python科研绘图:半对数刻度折线图,绘制幅频响应曲线(0.1、1、10三个刻度等间距)

Python科研绘图:半对数刻度折线图,绘制幅频响应曲线(0.1、1、10三个刻度等间距)

  • 2026-09-10 15:46:48
Python科研绘图:半对数刻度折线图,绘制幅频响应曲线(0.1、1、10三个刻度等间距)
点击👇关注:数学建模BOOM,
后台回复“科研”,
获取「AI科研写作与Python绘图合集」

搞信号处理、电路分析或者控制系统的同学,常用到幅频响应曲线。

频率从 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.5    y = magnitude + offset    ax.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 记住这一个函数,频响曲线、伯德图、滤波器特性,这些图你就都有了底子~

【往期文章】

已经有人用Gemini 四小时写出一篇论文了

Nature:如何利用vibe coding助力科研——论文产出提高75%

数模AI知识库更新国赛板块——基于RAG增强检索,最懂数模的AI

想参加数学建模比赛,但什么都不会,该怎么学呢?

-----------------------------------

点击下方关注公众号,在后台回复

回复 “群”,加入数模交流群;

回复“课程”,查看入门级数学建模精品课程(常用模型的原理讲解+例题+matlab编程,附带课件与代码)

最新文章

随机文章