情节外的图例不适用于 Octave 中的 plotyy

Legend outside plot does not work with plotyy in Octave

我正在尝试使用 plotyy 在 Octave 中创建一个图(在 Windows 上使用 v4.4.1)并将图例放在图外(因为数据涵盖了所有可用的 space 在图中)。以下 MVCE 应该可以很好地重现该问题:

% Generate some random data to reproduce the issue
data = rand(1000,10);
data(:,1:8) = data(:,1:8)-0.5;
data(:,9:10) = data(:,9:10)+30;
timedate = linspace(737310,737313,size(data,1));
data_labels={'1';'2';'3';'4';'5';'6';'7';'8';'9';'10'};

% Plot the data
figure('Name','MVCE','Position',[300 200 1000 600])
[ax,h1,h2] = plotyy(timedate,data(:,1:8),timedate,data(:,9:10));
set(h2,'Visible','on'); 
datetick(ax(1),'x','HH:MM:SS')
datetick(ax(2),'x','HH:MM:SS')
ylim(ax(1),[-1 1])
ylim(ax(2),[20 50])
xlabel('Date & time')
ylabel(ax(1),'Something')
ylabel(ax(2),'Something else')
title('plotyy graph with legend problem')
[hl,hlo] = legend([h1;h2],data_labels,'location','eastoutside');
grid on

这是使用 gnuplot 图形工具包的代码输出:

如您所见,图例没有超出图,第二个 y 轴不可见(看起来图的一部分实际上被截断了)。

我曾尝试使用 qtfltk 图形工具包,它们各自存在问题:

  1. 使用 qt 图形工具包

  1. 使用 fltk 图形工具包

有人可以建议修复或至少解决方法吗?同样的问题是否也发生在 MATLAB 中,还是特定于 Octave 的?

编辑 使用 Tasos 回答中的建议,我几乎成功地使用了 gnuplot:

% Plot the data
figure('Name','MVCE','Position',[300 200 1000 600])
[ax,h1,h2] = plotyy(timedate,data(:,1:8),timedate,data(:,9:10));
set(h2,'Visible','on'); 
datetick(ax(1),'x','HH:MM:SS')
datetick(ax(2),'x','HH:MM:SS')
ylim(ax(1),[-1 1])
ylim(ax(2),[20 50])

ax1Pos = get(ax(1), 'position');   
ax2Pos = get(ax(2), 'position');
ax1Pos(3) = ax1Pos(3) * 0.73;      
ax2Pos(3) = ax2Pos(3) * 0.73;
set(ax(1), 'position', ax2Pos);    
set(ax(2), 'position', ax2Pos);

xlabel('Date & time')
ylabel(ax(1),'Something')
ylabel(ax(2),'Something else')
title('plotyy graph with legend problem')
[hl,hlo] = legend([h1;h2],data_labels,'location','eastoutside');
pos = get(hl,'Position');
pos(1) = 0.9;
set(hl,'Position',pos)
grid on

产生:

除了图例与第二个 y 轴标签重叠(它不在我的屏幕上,仅当打印到 jpg 时),问题是 Octave 似乎绘制了两个图例由于某种原因彼此重叠:一个具有第一组数据附加到第一组轴,一个具有完整数据集,两个轴都位于第一个图例的顶部。这显然是错误的,并且尝试将 hlVisible 属性 设置为 off 会删除两个图例,而不仅仅是一个。

已更新:处理影响图形的图例放置和 OpenGL 精度。

关于图例没有准确出现在你想要的位置的问题,你可以手动调整图形中涉及的所有坐标轴的位置,使其准确地出现在你想要的位置。

关于OpenGL无法处理小数与大数相加精度的问题,只绘制涉及小数的图形,然后简单调整xticklabels对应你想要的数字.

完整代码如下:

% Generate some random data to reproduce the issue
data = rand(1000,10);
data(:,1:8) = data(:,1:8)-0.5;
data(:,9:10) = data(:,9:10)+30;
t_offset = 737310;
timedate = linspace(0,3,size(data,1));
data_labels={'1';'2';'3';'4';'5';'6';'7';'8';'9';'10'};

% Plot the data
figure('Name','MVCE','Position',[300 200 1000 600])
[ax,h1,h2] = plotyy(timedate,data(:,1:8),timedate,data(:,9:10));
set(h2,'Visible','on'); 
ylim(ax(1),[-1 1])
ylim(ax(2),[20 50])
ylabel(ax(1),'Something')
ylabel(ax(2),'Something else')
title('plotyy graph with legend problem')
[hl,hlo] = legend([h1;h2],data_labels,'location','eastoutside');
set(hl, 'position', get(hl, 'position') .* [0.975, 1, 0.975, 1] )
grid on

ax1Pos = get(ax(1), 'position');   ax2Pos = get(ax(2), 'position');
ax1Pos(3) = ax1Pos(3) * 0.95;      ax2Pos(3) = ax2Pos(3) * 0.95;
set(ax(1), 'position', ax2Pos);    set(ax(2), 'position', ax2Pos);
XTicks = get(ax(1), 'xtick');
set(ax(1), 'xticklabel', datestr(XTicks + t_offset, 'HH:MM:SS'))
xlabel('Date & time')
set(ax(2), 'xtick', []);

输出: