在matlab中的y轴上自定义缩放

时间:2013-11-02 21:15:33

标签: matlab scaling

我在IEEE期刊论文中遇到了一个奇怪的y轴缩放。

从上到下

y_axis = [0.9999 0.9995 0.999 0.995 0.99 0.98 0.95 0.9 0.8 0.7 0.5 0.3 0.2 0.1 0.05 0.02 0.01 0.005 0.001 0.0005 0.0001]。

缩放不是logaritmic。刻度之间的空格不相等。当然,它不是线性的。您只能在一个y轴上详细查看大数字(0.9 ... 0.999)和非常小的数字(0.0001 ... 0.1)。我不知道如何在MATLAB中做。我用Google搜索,但我找不到。谁能帮我?提前谢谢。

该图是以下代码:

clear all
close all
set(0,'defaulttextinterpreter','latex')
P_tb = 1e-2;
Ntrial = 1e7;                  % # of Monte Carlo trials
jey=sqrt(-1);
omega_db = -15;                % sidelobe gain of main antenna
omega = db2pow(omega_db);      % omega in linear scale 
F_db = [-5 -2 0 2 5];
JNR_db = -5:20;
beta_db = 2;
F_lin = 10.^(0.1*F_db);
JNR = 10.^(0.1*JNR_db);
beta = 10.^(0.1*beta_db);
temp = cell (length(F_db),1);
P_b = zeros (length(JNR_db), length(F_db));
for ii = 1:length(F_db)
    SNR = JNR;
    x = sqrt(omega);
    F = F_lin(ii);
    P_b(:,ii) = 1 - 1./(F+1).*(1-marcumq(x.*sqrt(2.*SNR./(F+1)),sqrt(2.*SNR.*F./(F+1))))-F./(F+1).*marcumq(sqrt(2.*SNR.*F./(F+1)), x.*sqrt(2.*SNR./(F+1)));
    temp (ii) = {['$F=$' num2str(F_db(ii)) ' dB']};
end
figure,
h = plot(JNR_db, (P_b));
set(gca,'YTick',fliplr([0.9999 0.9995 0.999 0.995 0.99 0.98 0.95 0.9 0.8 0.7 0.5 0.3 0.2 0.1 0.05 0.02 0.01 0.005 0.001 0.0005 0.0001]))
set(gca,'YTickLabel',num2cell(fliplr([0.9999 0.9995 0.999 0.995 0.99 0.98 0.95 0.9 0.8 0.7 0.5 0.3 0.2 0.1 0.05 0.02 0.01 0.005 0.001 0.0005 0.0001])));
 grid on

4 个答案:

答案 0 :(得分:3)

在OP发布的图中,勾选标记根本没有均匀分布。此外,轴的比例更像是S形的(见下文)。要真正看到该论文的作者所做的事情,我们可以对图形进行镂空

im = conv2(im, fspecial('gaussian', [5, 5], 2));
im = ~bwmorph(im < 2.5, 'skel', inf);

并获取

中的确切位置y_px
y_px = flipud(find(im(:, 285) == 0));
y_px([1, 2, 3, 11, 15, 19, 28]) = [];

我正在删除一些来自趋势线或x轴的-10刻度标记的检测。

如果您绘制y-tick标签y_val(将y_axis翻转为升序)作为这些像素位置y_px的函数,您可以确认该关系是完全S形的正如@chapjc所建议的那样。但是,为了生成类似的图,您可能更愿意反转公式并定义函数

px_y = @(y) log(-y ./ (y - 1));

您可以使用此功能进行绘图。您引用的论文显示范围x = -10 : 0.1 : 4中的数据。让我们在同一范围内绘制一个介于0.0001和0.9999之间的正弦函数。请注意,我们使用缩放函数px_y,然后替换y-tick位置标签

plot(x, px_y(0.7 + sin(x) / 4));
set(gca(), 'ytick', px_y(y_val), 'yticklabel', num2cell(y_val));

导致看起来像这样的东西

enter image description here

总之,您可以定义一个函数y_px来转换您的y数据,然后设置轴的ytickyticklabel属性。无论您为此方法选择何种比例,都必须使用相同的函数转换两个 ytick值和所有y数据。

答案 1 :(得分:1)

要了解此自定义y轴空间,您可以执行plot(linspace(-5,5,numel(y_axis)),fliplr(y_axis),'r')。这看起来很像剂量曲线,因此绘制我用hold on; x=-5:0.01:5; plot(x,exp(x)./(1+exp(x)))找到的等式。这是它的样子:

enter image description here

表格看起来正确。调整形状的其中一个术语可能是一个常数。如果您想将数据放在此空间中,请应用此功能(yscFun = @(x) exp(x)./(1+exp(x))yscFun = @(x) 1./(1+exp(-x)))。然后按照nispio的建议,使用y_axis将刻度标签设置为set(gca,'YTickLabel',num2cell(fliplr(y_axis)));

答案 2 :(得分:1)

试试这个:

set(gca,'YTick',fliplr([0.9999 0.9995 0.999 0.995 0.99 0.98 0.95 0.9 0.8 0.7 0.5 0.3 0.2 0.1 0.05 0.02 0.01 0.005 0.001 0.0005 0.0001]));
set(gca,'YTickLabel',num2cell(fliplr([0.9999 0.9995 0.999 0.995 0.99 0.98 0.95 0.9 0.8 0.7 0.5 0.3 0.2 0.1 0.05 0.02 0.01 0.005 0.001 0.0005 0.0001])));

Matlab希望这些数字按顺序递增,因此我只是调用fliplr而不是重新排序您的数字。

答案 3 :(得分:1)

enter image description here这是我找到的最终解决方案。非常感谢你。我不知道sigmoid功能。下面是这个puporse的MATLAB代码。

close all
clear all
%your desired y_ticks
y_axis = [0.9999 0.9995 0.999 0.995 0.99 0.98 0.95 0.9 0.8 0.7 0.5 0.3 0.2 0.1 0.05 0.02 0.01 0.005 0.001 0.0005 0.0001];
%order in increasing way
y_val = fliplr (y_axis);
% the Sigmoid function and its inverse
py_x = @(x) 0.5*erf(x*sqrt(pi/8)) + 0.5;
px_y = @(x) sqrt (8/pi)*erfinv (2*x - 1);

beta = 10^(0.1*-15);
F = 10^(0.1*-5);
JNR_db = -5:20;
SNR = 10.^(0.1.*JNR_db);
% my original data
P_b = @ (x) 1 - 1./(F+1).*(1-marcumq(x.*sqrt(2.*SNR./(F+1)),sqrt(2.*SNR.*F./(F+1))))-F./(F+1).*marcumq(sqrt(2.*SNR.*F./(F+1)), x.*sqrt(2.*SNR./(F+1)));
P_b1 = P_b(sqrt(beta));
% tranfrom it using inverse function
P_b2 = px_y(P_b1);
figure,
plot(JNR_db, P_b2);
grid on
ylim ([ px_y(0.0001) px_y(0.9999) ]);
% tranform the desired y_tick using inverse function
set(gca(), 'ytick', px_y (y_val));  
set (gca (), 'yticklabel', num2cell(y_val));
% % Sigmoid function verification
x_temp = linspace(-5,5,numel(y_axis));
figure
plot(x_temp, fliplr(y_axis), 'r');
hold on
plot (x_temp, py_x (x_temp), 'b' )