【问题标题】:Custom Scaling on y-axis in matlabmatlab中y轴上的自定义缩放
【发布时间】:2013-11-02 21:15:33
【问题描述】:

我在 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]。

缩放不是对数的。刻度之间的间距不相等。当然,它不是线性的。您可以仅在一个 y 轴上详细查看大数字 (0.9... 0.999) 和非常小的数字 (0.0001... 0.1)。我不知道如何在 MATLAB 中进行操作。我用谷歌搜索了它,但我找不到。谁能帮我?提前致谢。

图为如下代码:

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

【问题讨论】:

标签: matlab scaling


【解决方案1】:

在 OP 发布的图中,刻度线根本不是均匀分布的。此外,轴的比例是 sigmoidal 的 inverse(见下文)。为了真正了解那篇论文的作者做了什么,我们可以将这个图骨架化

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 刻度标签 y_val(将您的 y_axis 翻转为升序)作为这些像素位置 y_px 的函数,您可以确认该关系完全符合 @chapjc 建议的 S 型关系。但是,为了生成类似的图,您可能更希望反转公式并定义一个函数

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));

结果应该是这样的

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

【讨论】:

  • 非常感谢,它解决了我的问题。但我认为你不需要转换你的 x_axis。基本上,我从您的回答中理解如下: 1. 保持轴刻度为 y_axis = [0.0001 0.0005 ...]; 2. 然后使用反函数 px_y = @(y) log(-y ./ (y - 1)); 转换你原来的 y_data 3. 然后使用反函数变换你的 y_axis。 4. 最后将 y_ticks 放在变换后的 y_axis 向量上。你不需要在 x_axis 上做任何事情。非常感谢你。我现在将最终的 MATLAB 代码放在下面。
  • 准确地说,您为'ytick' 设置了transformed 值。我看到您在自己的解决方案中正确地做到了这一点。对于xy 之间的混淆,我们深表歉意。
【解决方案2】:

试试这个:

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

【讨论】:

  • 使用 'Ytick' 只是在 y 轴上添加标签。它不会缩放它。我添加了MATLAB代码,你可以检查它。谢谢你的回答..
  • 我明白了。我想我误解了the space between the ticks are not equal 的意思。您实际上希望刻度的图形间距相等,即使标签以非线性方式增加。
  • @user2948661 - 要扩展您的数据,您需要对数据应用映射。是这个意思吗?
  • @chappjc:您的剂量反应曲线看起来像是一个合理的转换。升余弦或根升余弦也可能是不错的选择(它们很容易反转)。
  • 是的,你是对的。抱歉我的解释不好。我认为当您运行代码时,您会明白这一点。 MATLAB fileexchange上有一些matlab函数。 mathworks.com/matlabcentral/fileexchange/21864-breakplot。但它会从轴的一部分中删除空白。但是我们的情况有点复杂。
【解决方案3】:

要了解此自定义 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))) 找到的方程。这是它的样子:

表格看起来不错。其中一个术语可能有一个常数来调整形状。如果你想把你的数据放在这个空间里,应用这个函数(yscFun = @(x) exp(x)./(1+exp(x))yscFun = @(x) 1./(1+exp(-x)))。然后按照 nisio 的建议将刻度标签设置为 y_axisset(gca,'YTickLabel',num2cell(fliplr(y_axis)));

【讨论】:

  • 一般来说,如果你想探索其他可能的映射,这类 S 形函数称为“sigmoids”。
  • 让我试试这个解决方案。我会尽快告诉你结果。谢谢你的回答..
  • @nispio - 感谢您的链接。 user2948661 可以尝试从您的链接中选择不同的 sigmoid 并按照此处的建议使用它们。
  • 感谢您的解决方案。当我绘制曲线时,它似乎是正确的。但我不明白如何将我的数据放在这个空间中。你能再解释一下吗?
【解决方案4】:

这是我找到的最终解决方案。非常感谢你。我不知道 sigmoid 函数。下面是这个目的的 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' )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    • 2020-07-22
    • 1970-01-01
    • 2016-09-04
    • 2014-05-06
    • 2011-10-20
    相关资源
    最近更新 更多