ECharts 绘制奈奎斯特曲线避坑指南:新手最易踩的 3 个错误

编程狮(w3cschool.cn) 2026-10-30 10:13:12 浏览数 (51)
反馈

一句话先回答:用 ECharts 画奈奎斯特曲线,本质是画一条「虚部对实部」的参数曲线,最常见的三个错误是:把 xAxis 设成类目轴、把实部虚部拆成两条 series、采样点不够导致曲线变形。本文给出能直接套用的 option 配置和一段按频率对数采样的数据生成代码,照着改就能一次画对。

奈奎斯特图在控制理论和信号处理里用得非常多,它的价值在于把开环系统的频率响应「一眼看穿」:只需看曲线是否包围 -1 点,就能判断闭环稳不稳定。对前端同学来说,它也是练习 ECharts 参数曲线绘制的好素材——既不像普通折线图那样直白,又比三维图容易上手。但恰恰是「参数曲线」这个定位,让很多照着折线图模板改的同学反复踩坑。下面先把结论给清楚,再逐条解释每个错误的适用边界和正确写法,最后用一段可运行代码帮你验证结果。

ECharts 奈奎斯特曲线避坑要点

一、奈奎斯特曲线到底是什么

奈奎斯特图(Nyquist plot)是控制理论和信号处理里判断系统稳定性的常用图:它把开环传递函数 G(jω) 在频率 ω 从 0 扫到无穷大时的取值,画成复平面上的轨迹——横轴是实部,纵轴是虚部。这个图最适用的场景,是看系统在不同频率下的相位和幅值变化;它的边界也很清楚:它只描述「频率响应」这一种关系,不负责给出时域波形。先在 ECharts Tutorial 教程 里把基础配置过一遍,再回来对着本文改,会比凭记忆硬写稳妥得多。

关键认知只有一句:这是一条参数曲线,参数就是频率 ω,每个 ω 对应复平面上的一个点 (Re, Im)。只要抓住「一对坐标画一个点、按 ω 顺序连成线」这个本质,下面三个坑就都不会踩。把这件事想清楚,后面所有配置都只是落地细节,理解边界比背配置更重要。

二、最稳的写法:value 轴加成对坐标

最不容易出错的配置是把两个坐标轴都设成 type: 'value',series 用一条 line,数据直接给成 [实部, 虚部] 的二维数组。下面这段代码是 TypeScript 写法,如果你更习惯纯 JavaScript,可对照 TypeScript 教程 把类型标注去掉即可,运行逻辑完全一致。

const option = {
  xAxis: { type: 'value', name: '实部 Re' },
  yAxis: { type: 'value', name: '虚部 Im' },
  series: [{
    type: 'line',
    showSymbol: false,   // 点太多,关掉小圆点
    smooth: false,       // 参数曲线不要平滑,否则形状失真
    data: points         // points = [[re, im], ...]
  }]
};

这里 points 里的每个元素就是 [实部, 虚部],ECharts 会自动按第一个值当 x、第二个值当 y。很多新手把 xAxis 漏配,ECharts 默认就是 value,但显式写出来能避免后续被模板覆盖。这一条是后面所有正确写法的起点,也是配置上最该先确认的一步。

三、三个最容易踩的坑

错误一:把 xAxis 设成 category

有人照着折线图模板,把 xAxis.type 写成 'category',再手动填一串频率标签。结果是:横坐标被当成离散的分类刻度,频率之间的连续关系彻底丢失,曲线要么错位、要么被拉成无意义的折线。正确版本:牢牢记住奈奎斯特是连续参数曲线,xAxis 和 yAxis 都必须是 type: 'value',不要给任何类目数据。对比一下就能发现,类目轴和参数曲线是两种完全不同的画法,混用必然失败。

错误二:把实部、虚部拆成两条 series

另一个常见做法是建两个 series,一个画实部随 ω 的变化、一个画虚部随 ω 的变化。这画出的是两条「随频率变化」的曲线,根本不是奈奎斯特图——奈奎斯特要求的是「虚部对实部」的平面轨迹。正确版本:只用一条 series,数据写成 [实部, 虚部] 成对坐标,让 ECharts 在同一坐标系里把点连起来。如果你用 Git 管理图表配置,可以参考 Git 速查手册 把这次 option 提交成一个可回滚的版本,改错也能快速回退。

错误三:采样点太少,或没覆盖高频段

如果只在 ω 取几个整数点,连出来的线会严重变形,甚至漏掉穿越 -1 点附近的关键形状,而那段形状恰恰和稳定性判据(是否包围 -1)有关。低频段变化快、高频段变化慢,均匀采样要么低频不够密、要么高频冗余。正确版本:用对数间隔密集采样,从 0.01 一直扫到 100 以上,保证整条轨迹都平滑准确。这一步的性能代价很小,渲染负担主要来自点数,而不是采样本身。

奈奎斯特曲线三个常见错误对照

四、用代码生成采样并验证结果

下面这段代码按对数频率采样一个一阶系统 G(s) = 1 / (1 + s),直接产出可喂给 ECharts 的 points。如果你在 TRAE 这类 AI 编程工具里写 TypeScript,遇到类型或报错问题可看 TRAE 排错指南,它把常见的 TS 报错归因讲清楚了。

const points = [];
for (let i = 0; i <= 400; i++) {
  const w = 0.01 * Math.pow(10000, i / 400);   // 0.01 → 100,对数均匀采样
  const denom = 1 + w * w;
  points.push([1 / denom, -w / denom]);         // [实部, 虚部]
}

const option = {
  xAxis: { type: 'value', name: '实部 Re', scale: true },
  yAxis: { type: 'value', name: '虚部 Im', scale: true },
  series: [{
    type: 'line', showSymbol: false, smooth: false, data: points
  }]
};

运行这段后,检查输出的 points 第一项是不是接近 [1, 0]、最后一项是否趋近 [0, 0],就能确认采样方向没反。预期结果(未在本机执行):一阶系统的奈奎斯特曲线是复平面下半部的一条半圆,从 (1, 0) 出发、随频率升高渐近靠近原点,不会包围 -1 点,对应系统稳定。把 points 换成你自己的二阶或更高阶传递函数时,只要保证「每个频率算一次实部虚部、成对入数组」这个结构不变,绘图部分完全复用,验证方法也一致。

总结

  • 奈奎斯特曲线是「虚部对实部」的参数轨迹,参数就是频率 ω,适用场景是看频率响应。
  • 坐标轴必须都是 type: 'value',绝不能用 category,这是和折线图最大的画法差异。
  • 只用一条 series,数据写成 [实部, 虚部] 成对坐标,不要拆两条 series。
  • 用对数间隔密集采样,覆盖从低频到高频,曲线才不会变形漏判,性能代价也可忽略。

常见问题

Q:为什么我的曲线是直线而不是半圆?

几乎都是把 xAxis 设成了 category,或者把实部虚部拆成了两条 series。回到第二节的 value 轴加单 series 写法,曲线形状立刻正常。

Q:采样点越多越好吗?

不是无限多。一阶、二阶系统 200–500 个对数间隔点已经足够平滑;点数过多只是增加渲染负担。重点是低频段要够密、高频段要覆盖到。

Q:怎么判断系统稳不稳定?

奈奎斯特判据看曲线是否逆时针包围 -1 点,以及包围次数。画图只是第一步,稳定性结论要按判据来,本文只解决「画对曲线」这一步,不涉及稳定性判定的完整推导。

延伸学习

0 人点赞