MATLAB quickie:如何在频率图上绘制标记?

MATLAB quickie: How to plot markers on a freqs plot?

我有一段时间没有使用 MATLAB,我被一个小细节卡住了。如果有人能帮助我,我将不胜感激!

所以我正在尝试使用名为 freqs 的特定函数绘制传递函数,但我不知道如何在图表上标记特定点。

b = [0 0 10.0455];      % Numerator coefficients
a = [(1/139344) (1/183.75) 1];    % Denominator coefficients
w = logspace(-3,5); % Frequency vector
freqs(b,a,w)
grid on

我想用标记标记点 x=600 Hz7500 Hz 处的值,或者更具体地说,点 (600,20)(7500,-71),这两个点都应该位于在曲线上。出于某种原因,freqs 不允许我这样做。

freqs 当你想依靠它为你绘制频率响应时,它是非常有限的。基本上,您无法控制如何在 MATLAB 为您生成的图形之上修改图形。

相反,您可以自己在向量中生成输出响应,然后自己绘制输出的幅度和相位,以便您拥有完全的控制权。如果你在调用freqs时指定一个输出,你将得到系统的响应。

有了这个,你可以通过abs and the phase by angle找到输出的大小。顺便说一句,(600,20)(7500,-71) 绝对没有意义,除非你谈论的是以 dB 为单位的幅度……我假设目前是这种情况。

因此,我们可以通过以下方式重现freqs给出的情节。关键是用semilogx得到一个x轴的半对数图。最重要的是,声明那些你想在幅度上标记的点,所以 (600,20)(7500,-71):

%// Your code:
b = [0 0 10.0455];      % Numerator coefficients
a = [(1/139344) (1/183.75) 1];    % Denominator coefficients
w = logspace(-3,5); % Frequency vector

%// New code
h = freqs(b,a,w); %// Output of freqs
mag = 20*log10(abs(h)); %// Magnitude in dB
pha = (180/pi)*angle(h); %// Phase in degrees

%// Declare points
wpt = [600, 7500];
mpt = [20, -71];

%// Plot the magnitude as well as markers
figure;
subplot(2,1,1);
semilogx(w, mag, wpt, mpt, 'r.');
xlabel('Frequency');
ylabel('Magnitude (dB)');
grid;

%// Plot phase
subplot(2,1,2);
semilogx(w, pha);
xlabel('Frequency');
ylabel('Phase (Degrees)');
grid;

我们得到这个:

如果您检查 freqs 为您生成的内容,您会发现我们得到了相同的结果,但幅度是增益 (V/V) 而不是 dB。如果你想要它在 V/V 中,那么只需绘制没有 20*log10() 调用的幅度。使用您的数据,我绘制的标记不在图表上(wptmpt),因此请将点调整到您认为合适的位置。

在我们尝试回答您的问题之前有几个问题。首先,在 600Hz 或 7500Hz 处没有数据点。当使用 freqs 命令绘制图形时,这些频率落在数据点之间。请参见下图,其中以交互方式添加了数据提示。我复制粘贴了您的代码以生成此数据。

其次,(600,20) 或 (7500,-71) 似乎都不在曲线上,至少对于您在上面输入的数据而言是这样。

一种解决方案是在所需位置上绘制标记,然后使用 "text" 对象添加描述该点的字符串。我使用您的数据编写了一个脚本,以生成此图:

代码如下:

b = [0 0 10.0455];
a = [(1/139344) (1/183.75) 1];
w = logspace(-3,5);
freqs(b,a,w)
grid on

figureHandle = gcf;
figureChildren = get ( figureHandle , 'children' ); % The children this returns may vary.
axes1Handle = figureChildren(1);
axes2Handle = figureChildren(2);
axes1Children = get(axes1Handle,'children'); % This should be a "line" object.
axes2Children = get(axes2Handle,'children'); % This should be a "line" object.

axes1XData = get(axes1Children,'xdata');
axes1YData = get(axes1Children,'ydata');

axes2XData = get(axes2Children,'xdata');
axes2YData = get(axes2Children,'ydata');

hold(axes1Handle,'on');
plot(axes1Handle,axes1XData(40),axes1YData(40),'m*');
pointString1 = ['(',num2str(axes1XData(40)),',',num2str(axes1YData(40)),')'];
handleText1 = text(axes1XData(40),axes1YData(40),pointString1,'parent',axes1Handle);

hold(axes2Handle,'on');
plot(axes2Handle,axes2XData(40),axes2YData(40),'m*');
pointString2 = ['(',num2str(axes2XData(40)),',',num2str(axes2YData(40)),')'];
handleText2 = text(axes2XData(40),axes2YData(40),pointString2,'parent',axes2Handle);