如何将这些子图连接到一张图上? [英] How to concatenate these subplots on one graph?
问题描述
这是我的代码的简单版本.
Here is the a simpler version of my code.
.....
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
相同的内容.
The mean_a
and mean_b
depend on the ch_array
so that as a result, there are mean_a_36_f
, mean_a_40_f
,..., mean_a_161_f
and the same thing with the mean_b
.
此for
循环根据ch_array
绘制图形,如下图:
This for
loop plots graphs according to ch_array
, the following figure:
如您所见,为每个ch_array
元素绘制了相应的mean_a_ch
和mean_b_ch
.
As you can see, for each ch_array
element is plotted the corresponding mean_a_ch
and mean_b_ch
.
现在,目的是连接这些子图,以便所有子图都在一个图形上,但是被连接,而不是hold on
的方式.串联应如下所示:
Now, the purpose is these subplots to concatenate so that all are on one figure, but concatenated and not so how the hold on
does. The concatenation should look like this:
每个级联图的位置将在X轴上表示,如图所示.
where for the each concatenated plot will be denoted on the X axis, as can be seen on the pic.
推荐答案
您有两个问题.我将从您没有问到的那本书开始,因为我担心一旦我回答了另一本书,您就会停止阅读.
You have two problems. I'll start with the one you didn't ask about, since I'm worried you'll stop reading once I answer the other one.
除非确实有必要,否则就不要不要使用eval
. eval
是缓慢且不安全的.如果您eval
恶意代码,它很容易对您的系统造成严重损害.在这种情况下,这不太可能,但是仍然使用eval
会阻止MATLAB的即时编译器优化内部代码中的任何内容,因此您将获得最糟糕的性能.
You should not be using eval
unless it's really necessary, and it's never necessary. eval
is slow and insecure. If you eval
malicious code, it can easily do serious harm to your system. In this case this is unlikely, but still using eval
prevents MATLAB's just-in-time compiler to be able to optimize anything in the code inside, so you'll get the worst possible performance.
现在,您声称自己受困于eval
,因为变量已经动态设置.请注意,这是XY问题的完美示例:您不应该首先获得这些数据.用不同的方式做.如果您无法控制数据的创建,请不断敲打数据处理人员的头部,以便他们停止操作.
Now, you're claiming that you're stuck with eval
because the variables are already set up dynamically. Note that this is a perfect example of an XY problem: you shouldn't end up with these data in the first place. Do them differently. If you're not in control of data creation, keep hitting the head of the person who is, so that they stop.
无论如何,一旦造成伤害,您仍然可以迅速从eval
厄运之坑中恢复过来.您需要保存并重新加载变量,这允许您将其推入结构中.很好,因为可以访问结构域动态.重写您的原始照片:
Anyway, once the damage is done, you can still quickly recover from the eval
pit of doom. You need to save and reload your variables, which allows you to push them into a struct. This is nice, because struct fields can be accessed dynamically. Rewriting your original:
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
点,以使它们不重叠:
Now, for your question. The problem is that plot(y)
with this simple syntax plots y
as a function of 1:numel(y)
: essentially plot(1:numel(y),y)
. What you want to do is manually shift the x
points for each data set so they don't overlap:
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');
这篇关于如何将这些子图连接到一张图上?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!