【问题标题】:Semilogarithmic plot (semilogy) ignores zeros in MATLAB半对数图(semilogy)在 MATLAB 中忽略零
【发布时间】:2016-09-08 18:53:38
【问题描述】:

我有一个包含三列的 CSV 文件。我基本上想阅读前两列,然后用这些值绘制一个semilogy 图。我有以下代码段:

filename = 'ber.csv';
M = csvread(filename, 1)

close all
figure 
semilogy(M(:,1), M(:,2), 'sb-', 'LineWidth', 2);
grid on
axis([0 25 10^-3 10^0])
xlabel('traceback depth, TB')
ylabel('Bit Error Rate');
title('BER with Viterbi decoding')
toc

上面的代码段,为我画了这样的东西:

问题是它在 x 轴上的 24 左右停止,而我有 30 个值。最后 10 个值如下所示(为简洁起见,其余部分省略):

   20.0000    0.0807        
   21.0000    0.0443    
   22.0000    0.0312        
   23.0000    0.0078        
   24.0000    0.0052        
   25.0000         0        
   26.0000         0         
   27.0000         0         
   28.0000         0         
   29.0000         0         
   30.0000         0    

我希望绘图一直持续到 30,并使其到达 x 轴,而从 25 到 30 的其余值仅为 0。有什么想法可以实现吗?

【问题讨论】:

  • 您需要更具体地了解它的外观。从技术上讲,0 在对数图中无限低。
  • @AnderBiguri 有什么办法可以让图表看起来像碰到 x 轴,我的意思是显示 y 值“达到”0?
  • 您不想“击中”x 轴,好像数据的值为 10^-3。那将是对您的数据的虚假陈述。您可以将 0 替换为非常非常低的数字,例如 10^-50 并限制 y 轴不显示这些值。这将显示一条从第 24 点开始向下延伸的线,可以按照您正在寻找的方式进行解释。
  • 顺便说一句,其实这个问题几乎不是关于编程的。

标签: matlab


【解决方案1】:

这里并不是真的有编码问题,而是有数学问题。如果您在 MATLAB 中输入log(0),您将得到答案-Inf。 MATLAB 不知道如何在有限屏幕上绘制-Inf

您说您希望您的线碰到 x 轴,但请注意您的轴的底部是 0.001。如果 x 轴向下移动到 0.00001 会怎样?你不会再撞到轴了。在显示数据时,您需要认真考虑要传达的内容。

如果您只想向下延伸到轴,您可以做的“最简单”的事情是尝试向下推断到 x 轴并在其中添加一个点并绘制它。

figure 
h = semilogy(M(:,1), M(:,2), 'sb-', 'LineWidth', 2);
grid on
axis([0 25 10^-3 10^0])
axis([0 25 10^-3 10^0])
xlabel('traceback depth, TB')
ylabel('Bit Error Rate');
title('BER with Viterbi decoding')

% Get the y limits
y_limits = ylim;

% Find the bottom x-axis
bottom_y_limit = min(y_limits);

% interp1 doesn't like repeated values so throw out the extra zeros
first_zero = find(M(:,2) == 0, 1, 'first');

% Figure out where your plot hits the x-axis.    
new_point = interp1(M(1:first_zero, 2), M(1:first_zero, 1), bottom_y_limit, 'pchip');

% Insert the new point into your data
Mnew = sortrows([M; new_point, bottom_y_limit]);

% Replace the data vector in the plot with the new data that includes the extra point
set(h, 'XData', Mnew(:, 1), 'YData', Mnew(:, 2));

对此的一些重要警告是,这是相当静态的,因此如果您更改轴限制,您的新点将不再触及轴。要使其正常工作,需要为您的轴设置一个回调函数。此外,这应该有效,因为您的样本数据在变为零方面非常单调。如果您的数据完全振荡,则插值将失败。我也只在您发布的数据子集上对此进行了测试。由于插值是使用“横向”数据完成的,要到达 x 轴,如果您的数据中有噪声使得 y 轴不再是单调的,您可能还需要进行一些调整以仅选择 1或 2 个点接近它下降到零的位置,而不是像我做的那样懒洋洋地把整个向量粘进去。

使用您在上面发布的数据:

M=[20.0000    0.0807        
   21.0000    0.0443    
   22.0000    0.0312        
   23.0000    0.0078        
   24.0000    0.0052        
   25.0000         0        
   26.0000         0         
   27.0000         0         
   28.0000         0         
   29.0000         0         
   30.0000         0  ];

我得到的输出是:

【讨论】:

  • 当我尝试上面的代码段时,我收到以下错误消息Error using vertcat Dimensions of matrices being concatenated are not consistent.。然后它继续绘制与我原来的帖子完全相同的东西。
  • 当我在您的帖子中复制并粘贴您的 M 值列表时,我得到一个 11x2 矩阵。你的错误听起来就像当你用csvread 读取数据时,你得到一个 2xN 矩阵,所以转置它。出现错误是因为我假设列数据,所以我可以使用sortrows 命令。
猜你喜欢
  • 2011-04-02
  • 1970-01-01
  • 1970-01-01
  • 2014-04-23
  • 2019-06-28
  • 2020-05-19
  • 1970-01-01
  • 1970-01-01
  • 2011-07-17
相关资源
最近更新 更多