情节外的传说不适用于 Octave 中的 plotyy
Posted
技术标签:
【中文标题】情节外的传说不适用于 Octave 中的 plotyy【英文标题】:Legend outside plot does not work with plotyy in Octave 【发布时间】:2019-04-13 06:11:33 【问题描述】:我正在尝试使用plotyy
在 Octave(在 Windows 上使用 v4.4.1)中创建一个图,并将图例放在图之外(因为数据涵盖了图中的所有可用空间)。以下 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 轴不可见(看起来情节的一部分实际上被截断了)。
我尝试过使用qt
和fltk
图形工具包,它们会给出自己的问题:
-
带有
qt
图形工具包
-
带有
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 似乎在每个图例的顶部绘制了两个图例其他出于某种原因:一个将第一组数据附加到第一组轴,一个具有完整数据集,两个轴都位于第一个图例的顶部。这显然是错误的,尝试将hl
的Visible
属性设置为off
会删除两个图例,而不仅仅是一个。
【问题讨论】:
我认为应该删除 MATLAB 标签,因为这个问题是 Octave 特有的。除了增加曝光率之外,还有其他原因吗? @Dev-iL 公平评论 - 我认为它也可能适用于 MATLAB,因为语法相同并且应该适用于两个平台。我不能说在 MATLAB 上是否也会出现同样的问题。虽然这可能是 Octave 特有的,但一些具有 MATLAB 知识的人可能会提出宝贵的建议来解决这个问题。如果您确实认为 MATLAB 选项卡不合适,请随时将其删除。 事实上,如果有人可以访问 MATLAB,我很想知道在 MATLAB 中是否会发生同样的事情。 无法在 MATLAB R2017b 中重现,图例出现在绘图之外,并显示第二个 y 轴,带有标签等(尽管第二个 y 轴标签被图例覆盖,但这可能又是一个不同的问题)。我已相应地删除了 MALTAB 标记,如果您有直接的理由将其链接到 MATLAB,请恢复它。也许标记图形工具包而不是 【参考方案1】:更新:处理图例放置和影响图形的 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', []);
输出:
【讨论】:
谢谢。然而,数据看起来不对,全是乱七八糟的。只有 gnuplot 图形工具包似乎可以正确绘制数据。 @am304 我们是在谈论传说问题还是别的什么?你预计会发生什么? 您可以看到qt
和fltk
的数据看起来是错误的,丢失了大块数据。这是因为当 Octave 将数据传递到 OpenGL 后端时,它会自动从双精度转换为单精度(因为 OpenGL 是 32 位的)。 Octave 中日期的问题在于它们是相当大的数字,从一个数据点到下一个数据点的变化很小,在数据类型转换中会丢失。所以不幸的是,我不能使用qt
或fltk
图形工具包,因此。不过,您的建议确实让我更进一步。
谢谢,它成功了。我不得不调整轴和图例的缩放和偏移因子,就像“真实”数据一样,图例字符串有点长,而且当保存为 JPG 时,它看起来与屏幕上的不同,但基本上它有效.
只是一个随机的、可能无关的想法。我最终没有在这里使用它,但我经常最终依赖多个透明的“轴”层,它们位于同一个地方,x 轴/刻度适当地打开或关闭,只包含我需要的绘图元素。记住这是一个有用的技巧,并且通常比简单地尝试在同一个轴对象上绘制所有内容要好得多。在更糟糕的情况下,您甚至可以单独生成这些图层,并依赖一个简单的 gimp 脚本为您将图层与透明度结合起来。以上是关于情节外的传说不适用于 Octave 中的 plotyy的主要内容,如果未能解决你的问题,请参考以下文章
在 Rmarkdown 中动态创建选项卡不适用于 ggplot,而它适用于 plotly