Graphics Incompatibilities in Control System Toolbox between R2024a and R2024b

6 次查看(过去 30 天)
A1 = 1; wp1 = 10;
A2 = -2; wp2 = 20;
s = tf('s');
H1 = A1 / (1 + s/wp1); H2 = A2 / (1 + s/wp2);
H = H1 + H2;
figure;
bp = bodeplot(H, H1, H2);
hLines = findobj(gcf, Type='line');
set(hLines, LineWidth=2); % not working in R2024b?
set(hLines(6), LineWidth=6, DisplayName='H2'); % not working in R2024b?
set(hLines(3), LineWidth=6, DisplayName='H2'); % not working in R2024b?
set(findall(gcf, 'Type', 'axes'), LineWidth=1.5, Box="off", fontsize=12); % not working in R2024b?
% Any correct/equivalent/recommended practice in R2024b?
figure;
pzmap(H, H1, H2);
set(gca, YTick=[], Box="off", LineWidth=1.5, XAxisLocation='origin', YAxisLocation='origin');
% get an R2024b Error using controllib.chart.PZPlot/set Unrecognized property YTick for class PZPlot.
% Any correct/equivalent/recommended practice in R2024b?
R2024a:
R2024b:
The "Version History" of "BodePlot" and "PZPlot" does point out changes in "gca", but for the "Chart Object" mentioned in it, I Googled it and couldn't find the relevant documentation, so I don't know how to get axes from Chart Object. Since the R2024b version is too new, I don't know where to find the information.
  4 个评论
Rarity Brown
Rarity Brown 2024-9-27
编辑:Rarity Brown 2024-9-27
I apologize for the imprecise wording and unclear code in my previous comment.
The support's original statement was, "It appears to be a bug with the Live Editor. I will report this to our development team for a fix in future releases. In the meantime, please use a .m script as a workaround, which should allow you to change figure properties without issues."
I have provided another similar code snippet for testing purposes, along with screenshots of the results when running the code in a .m file and in the Live Editor (.mlx). Therefore, I believe this can be considered a bug? Or perhaps the old API wasn't completely removed, resulting in two different behaviors?
A1 = 1; wp1 = 10;
A2 = -2; wp2 = 20;
s = tf('s');
H1 = A1 / (1 + s/wp1); H2 = A2 / (1 + s/wp2);
H = H1 + H2;
figure;
bp = bodeplot(H, H1, H2);
hLines = findobj(gcf, Type='line');
set(hLines, LineWidth=2); % not working in R2024b?
set(hLines(6), LineWidth=6, DisplayName='H'); % not working in R2024b?
set(hLines(3), LineWidth=6, DisplayName='H'); % not working in R2024b?
set(findall(gcf, 'Type', 'axes'), LineWidth=1.5, Box="off", fontsize=12); % not working in R2024b?
.m running in R2024b:
.mlx:
Andrew Ouellette
Andrew Ouellette 2024-9-27
Unforunately, this is a result of control plots being more permissive of undocumented behaviors before R2024b. Workflows including "findobj" and "findall" happened to work with the plots before R2024b, but this behavior was never documented. With the switch to charts in R2024b, many workflows including "findobj" and "findall" still work for standalone charts; however, these workflows cannot be serialized by charts, and are therefore lost during save/load operations and while using the Live Editor.

请先登录,再进行评论。

采纳的回答

Andrew Ouellette
Andrew Ouellette 2024-9-13
Hello,
You can achieve most of this behavior by interacting with the new chart API.
Give the following a go:
A1 = 1; wp1 = 10;
A2 = -2; wp2 = 20;
s = tf('s');
H1 = A1 / (1 + s/wp1); H2 = A2 / (1 + s/wp2);
H = H1 + H2;
figure;
bp = bodeplot(H, H1, H2);
bp.Responses(1).LineWidth = 2;
bp.Responses(2).LineWidth = 2;
bp.Responses(3).LineWidth = 6; %Name is already H2!
bp.AxesStyle.Box = 'off';
bp.AxesStyle.FontSize = 12;
%You cannot set LineWidth through API currently, here is a workaround
ax = findall(bp,'Type','axes'); %Undocumented, may change in a future release
set(ax,LineWidth=1.5);
figure;
pp = pzplot(H, H1, H2);
pp.AxesStyle.Box = 'off';
%You cannot set the rest through API currently, here is a workaround
ax = findall(pp,'Type','axes') ;%Undocumented, may change in a future release
set(ax,YTick=[], LineWidth=1.5, XAxisLocation='origin', YAxisLocation='origin');
  3 个评论
Andrew Ouellette
Andrew Ouellette 2024-9-30
For the first point, your interpretation is correct- the API expects one style per response, and therefore doesn't give you the flexibility to set different marker sizes for poles and zeros. There are a couple workarounds here:
1) You can use "findall" in the following manner, but again, this will not work in the Live Editor or after saving & loading.
% common part:
A1 = 1; wp1 = 10;
A2 = -2; wp2 = 20;
s = tf('s');
H1 = A1 / (1 + s/wp1);
H2 = A2 / (1 + s/wp2);
H = H1 + H2;
figure;
pzp = pzplot(H);
pzp.Responses(1).LineWidth = 8;
pzp.Responses(1).MarkerSize = 20;
poleScatter = findall(pzp,'Marker','x'); %Undocumented, may change in a future release
poleScatter.SizeData = 30^2;
2) You can create two responses and give them each different marker sizes. This will cause duplicate entries to appear in the chart's context menu (unavoidable) and legend (avoidable).
% common part:
A1 = 1; wp1 = 10;
A2 = -2; wp2 = 20;
s = tf('s');
H1 = A1 / (1 + s/wp1);
H2 = A2 / (1 + s/wp2);
H = H1 + H2;
Hz = zpk(zero(H),[],1);
Hp = zpk([],pole(H),1);
figure;
pzp = pzplot(Hz,Hp);
pzp.Responses(1).Name = "H";
pzp.Responses(1).LineWidth = 8;
pzp.Responses(1).MarkerSize = 20;
pzp.Responses(2).Name = "H"; %same name
pzp.Responses(2).LegendDisplay = false; %hide duplicate entry on legend
pzp.Responses(2).Color = pzp.Responses(1).Color; %blue
pzp.Responses(2).LineWidth = 8;
pzp.Responses(2).MarkerSize = 30;
For the second point, you should use the "stepplot" function. The "plot" functions in Control System Toolbox allow for much more customization than the no output syntax of their non-"plot" equivalents.
A1 = 1; wp1 = 10;
A2 = -2; wp2 = 20;
s = tf('s');
H1 = A1 / (1 + s/wp1);
H2 = A2 / (1 + s/wp2);
H = H1 + H2;
figure;
sp = stepplot(H, H1, H2);
sp.Responses(1).LineWidth = 2;
sp.Responses(2).LineWidth = 2;
sp.Responses(3).LineWidth = 6;
sp.AxesStyle.Box = 'off';
sp.AxesStyle.FontSize = 12;
ax = findall(sp,'Type','axes'); %Undocumented, may change in a future release
set(ax,LineWidth=1.5,XTick=[]);
Rarity Brown
Rarity Brown 2024-9-30
Thanks for the info! Can't wait for MATLAB to support more fine-tuned API control over charts!

请先登录,再进行评论。

更多回答(2 个)

Walter Roberson
Walter Roberson 2024-9-12
The hack for R2024b is:
yticks(gca().NodeChildren.Children, [])
  1 个评论
Rarity Brown
Rarity Brown 2024-9-12
Thank you for your response. Now the both graphs have the same problem, i.e. the code doesn't report any errors, but it doesn't have any effect either.
A1 = 1; wp1 = 10;
A2 = -2; wp2 = 20;
s = tf('s');
H1 = A1 / (1 + s/wp1); H2 = A2 / (1 + s/wp2);
H = H1 + H2;
figure;
bp = bodeplot(H, H1, H2);
hLines = findobj(gcf, Type='line');
set(hLines, LineWidth=2); % not working in R2024b?
set(hLines(6), LineWidth=6, DisplayName='H'); % not working in R2024b?
set(hLines(3), LineWidth=6, DisplayName='H'); % not working in R2024b?
set(findall(gcf, 'Type', 'axes'), LineWidth=1.5, Box="off", fontsize=12); % not working in R2024b?
figure;
pzmap(H, H1, H2);
set(gca().NodeChildren.Children, YTick=[], Box="off", LineWidth=1.5, XAxisLocation='origin', YAxisLocation='origin')
% not working in R2024b?
% or using yticks(gca().NodeChildren.Children, [])
R2024b:
R2024a (expected behavior):

请先登录,再进行评论。


Madheswaran
Madheswaran 2024-9-13
编辑:Madheswaran 2024-9-13
Hi,
As you can notice, while running in MATLAB R2024b, the `findobj` function returns only six lines: three with the tag `BodeMagnitudeLine` and three with the tag `BodePhaseLine`. So, to change the ‘LineWidth’ and ‘DisplayName’ of the desired line, you can change the indexing used in ‘hLines’ array as shown below:
% ... existing code
figure;
bp = bodeplot(H, H1, H2);
hLines = findobj(gcf, Type='line');
set(hLines, LineWidth=2);
set(hLines(1), LineWidth=6, DisplayName='H');
set(hLines(4), LineWidth=6, DisplayName='H');
set(findall(gcf, 'Type', 'axes'), LineWidth=1.5, Box="off", fontsize=12);
Similarly, in the context of `pzmap`, the `gca` function now returns a `PZPlot` chart object instead of an axes object within the plot. Since 'YTick' is not a property of 'PZPlot', the error appears. You can access the axes by indexing the children of 'PZPlot' object as demosntrated below:
figure;
pzmap(H, H1, H2);
set(gca().Children(1), YTick=[], Box="off", LineWidth=1.5, XAxisLocation='origin', YAxisLocation='origin')
Using MATLAB R2024b, the code above will produce the expected plot as shown below:
Please refer to the following MathWorks documentations on the following topics:
  1. pzmap - https://mathworks.com/help/control/ref/lti.pzmap.html
  2. bodeplot - https://mathworks.com/help/ident/ref/controllib.chart.bodeplot.html
  3. PZPlot - https://mathworks.com/help/control/ref/controllib.chart.pzplot.html
Hope this helps!

类别

Help CenterFile Exchange 中查找有关 Axes Appearance 的更多信息

产品


版本

R2024a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by