【问题标题】:Plot a variable number of vectors at once?一次绘制可变数量的向量?
【发布时间】:2012-11-22 08:14:26
【问题描述】:

我想知道:

假设我有一个结构:

s(1).Xval=[1 2 3];
s(2).Xval=[1 2 3 4];
s(3).Xval=[1 2 3];

s(1).Yval=[1 2 3];
s(2).Yval=[4 3 2 1];
s(3).Yval=[3 2 1];

现在我想将这三条线绘制在一个图中。我可以这样做:

plot(s(1).Xval,s(1).Yval,s(2).Xval,s(2).Yval,s(3).Xval,s(3).Yval);

这是可能的,因为 MATLAB 通过以下语法为绘图函数提供了可变数量的输入参数:

plot(X1,Y1,...,Xn,Yn)

我的问题是:有没有办法在没有预定义数量的地块的情况下调用这个函数?所以在这种情况下,我绘制了三行,但如果我不知道要绘制多少行,这种语法是否仍然可行?

我当然知道我可以通过使用Hold All 和For 循环来做到这一点。但是,我问这个是因为我想在必要时避免循环。有没有一个优雅的解决方案?还是我应该只使用循环?

编辑:索引确实有错字。 s.Xval(1) 代替 s(1).Xval

【问题讨论】:

  • 查看link。希望有用
  • 请注意,您的示例是错误的,因为s.Xval 在每行中必须具有相同数量的元素。 s.Yval 也是如此。
  • @EitanT:我怀疑应该是s(1).Xval; s(2).Xval,等等。
  • @Jonas 我相信在这种情况下,建议的答案应该略有不同。
  • @EitanT 我不明白为什么它应该有所不同。你能详细谈谈?我假设 Johann3s 想要 plot(s(1).xVal, s(1).yVal, s(2).xVal, s(2).yVal, ...)。我的回答不会给出相同的结果吗?

标签: matlab for-loop struct plot


【解决方案1】:

您可以使用plot 函数来做到这一点。文档提到:

如果 Xn 或 Yn 是矩阵,它们必须是二维的且大小相同,并且 Yn 的列与 Xn 的列相对应。 plot 自动按照当前坐标区的 ColorOrder 和 LineStyleOrder 属性指定的顺序选择颜色和线型。

要制作 X 和 Y 矩阵,您需要用 NaN 填充它们。像这样:

X = [1 2 3 NaN
     1 2 3 4
     1 2 3 NaN]
Y = [1 2 3 NaN
     4 3 2 1
     3 2 1 NaN]

由于 plot 函数会根据列绘制列,并且您希望行对行,因此您需要转置它们。

plot(X',Y','Marker','x')

会给你

【讨论】:

    【解决方案2】:

    我假设你有一个错字,所以正确的结构是这样的:

    s(1).Xval=[1 2 3];
    s(2).Xval=[1 2 3 4];
    s(3).Xval=[1 2 3];
    
    s(1).Yval=[1 2 3];
    s(2).Yval=[4 3 2 1];
    s(3).Yval=[3 2 1];
    

    % 将所有数据收集到一个单元格中

    c = {};
    for k = 1 : length(s)
        c = cat(2, c, {s(k).Xval}, {s(k).Yval});
    end
    

    % 和绘图:

    plot(c{:});
    

    注意,c{:} 不是单个变量,而是c 的元素个数

    更新:没有循环,但是很丑

    c = reshape(reshape({s.Xval, s.Yval}, length(s), [])', [], 1);
    plot(c{:});
    

    【讨论】:

    • 确实有错字。感谢您的回答。唯一的事情是我想避免循环,现在你创建了一个新循环。在我看来,只在循环中绘制更合适?
    • @Johann3s,查看没有循环的更新。如果你经常需要这个,我建议把这个放到一个函数中,这样你就可以调用:plot_struct(s);
    • 两个答案都很好,但由于您的编辑付出了额外的努力,我接受了您的答案!
    • 还因为单元结构实际上正是我要寻找的:因为一个命令:c{:} 它扩展为多个函数输入参数。
    • 我为没有循环的解决方案添加了另一个答案,我认为这也是一个优雅的解决方案。
    【解决方案3】:

    我实际上找到了另一种在我看来相当不错的方法。

    plotdata = cell(length(s)*2,1);
    plotdata(1:2:end) = {s.Xval};
    plotdata(2:2:end) = {s.Yval};
    plot(axes,plotdata{:});
    

    此代码简单易读,无需循环。

    【讨论】:

      猜你喜欢
      • 2021-01-12
      • 1970-01-01
      • 2018-03-10
      • 2021-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多