【问题标题】:How to concatenate these subplots on one graph?如何在一张图上连接这些子图?
【发布时间】:2017-06-25 16:34:43
【问题描述】:

这是我的代码的一个更简单的版本。

.....
ch_array = [36, 40, 44, 48, 149, 161];
figure;

for i=1:length(ch_array) 
    ch = ch_array(i);     
    subplot(3, 3, i);
    eval(sprintf('plot(mean_a_%d_f, ''r'')', ch));
    hold on;
    eval(sprintf('plot(mean_b_%d_f, ''b'')', ch));
    xlabel('Subcarrier (f)');
    ylabel('Absolute values');
    eval(sprintf('title(''Channel: %d'')', ch));
end
.....

mean_amean_b 依赖于 ch_array,因此有 mean_a_36_fmean_a_40_f、...、mean_a_161_f,与 mean_b 相同。

这个for循环根据ch_array绘制图形,下图:

如您所见,为每个ch_array 元素绘制了对应的mean_a_chmean_b_ch

现在,目的是连接这些子图,以便所有子图都在一个数字上,但连接起来而不是hold on 的方式。串联应如下所示:

每个连接图的位置将在 X 轴上表示,如图所示。

【问题讨论】:

  • 这看起来像您之前的问题。如果是同一个问题,您应该编辑您的原始问题#1#2,而不是作为新问题发布
  • 是的,我是新来的,我决定只发一个新帖子。
  • 如前所述,您应该已经编辑了原始问题。另外,请摆脱导致您陷入邪恶eval 的动态变量名称,并使用矩阵(如果无法使用矩阵,则使用元胞数组/结构)。您的代码似乎可以工作,但这是对他的代码所能做的最糟糕的事情。 i.imgur.com/XtcajQS.gif
  • 为了回答您的问题,hold on 肯定会在这里工作。您只需要在 x 轴的值中添加一些偏移量。但是您上传的图中的xticks与原始图表不符
  • 如果你没有注意到,^that^ 正是我在my answer 中对你之前的问题提出的建议。

标签: matlab plot matlab-figure


【解决方案1】:

你有两个问题。我将从你没有问的那个开始,因为我担心一旦我回答另一个你就会停止阅读。

你不应该使用eval,除非真的有必要,而且从来没有必要。 eval 速度慢且不安全。如果您eval 恶意代码,它很容易对您的系统造成严重损害。在这种情况下,这不太可能,但仍然使用eval 会阻止 MATLAB 的即时编译器能够优化内部代码中的任何内容,因此您将获得最差的性能。

现在,您声称自己被 eval 卡住了,因为变量已经动态设置。请注意,这是 XY 问题的完美示例:您不应该首先得到这些数据。以不同的方式做它们。如果您无法控制数据创建,请继续敲打负责人的头部,让他们停下来。

无论如何,一旦造成伤害,你仍然可以快速从eval 的厄运深渊中恢复过来。您需要保存并重新加载变量,这允许您将它们推送到结构中。这很好,因为结构字段can be accessed dynamically。重写你的原作:

tmpfile = 'tmp.mat';
save(tmpfile,'mean_*_*_f'); % save relevant variables to tmp mat file
dat = load(tmpfile); % reload them into a struct named dat

ch_array = [36, 40, 44, 48, 149, 161]; % we could deduce these programmatically
figure;

for i=1:length(ch_array) 
    ch = ch_array(i);     
    subplot(3, 3, i);
    plot(dat.(sprintf('mean_a_%d_f',ch)), 'r'); % look, Ma, no eval!
    hold on;
    plot(dat.(sprintf('mean_b_%d_f',ch)), 'b');
    xlabel('Subcarrier (f)');
    ylabel('Absolute values');
    title(sprintf('Channel: %d',ch)); % seriously, this DID NOT need eval
end

现在,回答你的问题。问题是plot(y) 使用这种简单的语法将y 绘制为1:numel(y) 的函数:本质上是plot(1:numel(y),y)。你想要做的是手动移动每个数据集的x点,这样它们就不会重叠:

figure;

offset = 0;
midpoints = zeros(size(ch_array));
for i=1:length(ch_array) 
    ch = ch_array(i);     

    % deduce data to plot
    tmpdat_a = dat.(sprintf('mean_a_%d_f',ch));
    tmpdat_b = dat.(sprintf('mean_b_%d_f',ch));
    x_a = offset+1:offset+numel(tmpdat_a);
    x_b = offset+1:offset+numel(tmpdat_b);

    % plot
    plot(x_a, tmpdat_a, 'r');
    hold on;
    plot(x_b, tmpdat_b, 'b');

    % store xtick position
    midpoints(i) = mean(mean(x_a), mean(x_b));

    % increment offset
    offset = offset + numel(max([tmpdat_a, tmpdat_b])) + 10; % leave a border of width 10, arbitrary now
end

xlabel('Subcarrier (f)');
ylabel('Absolute values');
xticks(midpoints);
xticklabels(arrayfun(@num2str, ch_array, 'uniformoutput', false));
title('All channels');

【讨论】:

    猜你喜欢
    • 2014-10-14
    • 2017-10-19
    • 2013-01-20
    • 1970-01-01
    • 2012-03-09
    • 1970-01-01
    • 1970-01-01
    • 2013-11-09
    • 1970-01-01
    相关资源
    最近更新 更多