如何将这些子图连接到一张图上?
How to concatenate these subplots on one graph?
这是我的代码的更简单版本。
.....
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_a
和 mean_b
依赖于 ch_array
所以结果有 mean_a_36_f
, mean_a_40_f
,..., mean_a_161_f
和 mean_b
.
一样
这个for
循环根据ch_array
绘制图形,如下图:
如您所见,每个 ch_array
元素都绘制了相应的 mean_a_ch
和 mean_b_ch
。
现在,目的是将这些子图连接起来,以便所有内容都在一个数字上,但连接起来并不像 hold on
那样。串联应如下所示:
每个串联图的位置将在 X 轴上表示,如图所示。
你有两个问题。我将从你没有问过的那篇开始,因为我担心一旦我回答了另一篇你就会停止阅读。
您应该不使用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');
这是我的代码的更简单版本。
.....
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_a
和 mean_b
依赖于 ch_array
所以结果有 mean_a_36_f
, mean_a_40_f
,..., mean_a_161_f
和 mean_b
.
这个for
循环根据ch_array
绘制图形,如下图:
如您所见,每个 ch_array
元素都绘制了相应的 mean_a_ch
和 mean_b_ch
。
现在,目的是将这些子图连接起来,以便所有内容都在一个数字上,但连接起来并不像 hold on
那样。串联应如下所示:
每个串联图的位置将在 X 轴上表示,如图所示。
你有两个问题。我将从你没有问过的那篇开始,因为我担心一旦我回答了另一篇你就会停止阅读。
您应该不使用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');