如果没有房间,如何使传奇继续更多行?

KiW*_*KiW 1 matlab plot legend word-wrap matlab-figure

我有一个多线的情节,我想在框下面显示图例(southoutside).问题是目前我的传奇太长了,无法放在一条线上.因此问题是我如何在传奇中获得换行符?

目前我生成的图例如下:

hLegend = legend([l1,l2,l3,l4], 'This is a very, very long legend text', 'Test2', ...
                                'A bit longer', 'This is quite long');
set(hLegend,'Fontsize',8,'Location', 'southoutside', 'Orientation','horizontal');
Run Code Online (Sandbox Code Playgroud)

那么这会发生:

在此输入图像描述

如你所见,我有四行(可能会有更多),第一行有一个很长的名字.

我希望以这种方式保持方向以减少所需的图形空间,并且如果图例超出图片宽度(即之前l3l4此处用黄色或紫色线表示),我想要设置自动换行符.

有什么想法吗?我使用的宽度为15.75厘米.

编辑

非常感谢到目前为止的答案.虽然这两个答案都提供了将图例分成两行的机会,但我的主要问题仍然存在.如果假设现在,该地块有更多然后四行,可以说20,我想有传说南边,它使用最小的空间的方式水平,是有办法不拆的传说中的一个图例文本,但一个条目.我生成了一个新的数字,通常描绘了我正在寻找的东西(它在Paint中制作,因此它只是显示了一般的想法).

在此输入图像描述

编辑2

columnlegend遗憾的是,Matlab文件交换中可用的包不支持图中的图例(至少说明中没有指定选项,它只列出以下可能的位置:'NorthWest','NorthEast','SouthEast','SouthWest "

感谢帮助.

Dev*_*-iL 5

介绍:

这是传说文本包装的概念验证,使用了一些未记录的输出legendMATLAB -> python界面.我将首先展示代码,然后简要解释它为何/如何工作.

这是在MATLAB 2016a中完成的.

码:

function q39456339
%% Definitions:
MAX_LENGTH_IN_CHARS = 20;
OPTION = 2;
%% Plot something:
x = 1:10;
figure('Position',[450 400 800 270]); 
plot(x,x,x,2*x,x,10-x,x,20-2*x);
%% Using python's TextWrapper to wrap entries:
% web(fullfile(docroot, 'matlab/matlab_external/call-python-from-matlab.html'))
switch OPTION
  case 1
    [~,hT] = legend({'This is a very, very long legend text', 'Test2', 'A bit longer', ...
      'This is quite long'},'Location', 'SouthOutside', 'Orientation','Horizontal',...
      'Fontsize',8,'Box','Off');
    texts = hT(arrayfun(@(x)isa(x,'matlab.graphics.primitive.Text'),hT));
    wrapLegendTexts(texts,MAX_LENGTH_IN_CHARS);
  case 2
    hL = legend({'This is a very, very long legend text', 'Test2', 'A bit longer', ...
      'This is quite long'},'Location', 'SouthOutside', 'Orientation','Horizontal',...
      'Fontsize',8,'Interpreter','tex');
    TEX_NEWLINE = '\newline';
    addNewlinesThroughPython(hL, MAX_LENGTH_IN_CHARS, TEX_NEWLINE);
end

end

%% Helper functions:
function wrapLegendTexts(textObjs,maxlen)
  tw = py.textwrap.TextWrapper(pyargs('width', int32(maxlen)));
  for ind1 = 1:numel(textObjs)
    wrapped = cellfun(@char,cell(wrap(tw,textObjs(ind1).String)), 'UniformOutput', false);
    textObjs(ind1).Text.String = reshape(wrapped,[],1);
  end
end

function addNewlinesThroughPython(hLeg, maxlen, newlineStr)
  tw = py.textwrap.TextWrapper(pyargs('width', int32(maxlen)));
  for ind1 = 1:numel(hLeg.PlotChildren)
    hLeg.PlotChildren(ind1).DisplayName = char(...
      py.str(newlineStr).join(wrap(tw,hLeg.PlotChildren(ind1).DisplayName)));
  end
end
Run Code Online (Sandbox Code Playgroud)

结果:

选项1: 包含选项1,maxlen 20

选项2: 包含选项2,maxlen 20

说明(选项1):

首先,让我们来看看签名legend:

>> dbtype legend 1

1     function [leg,labelhandles,outH,outM] = legend(varargin)
Run Code Online (Sandbox Code Playgroud)

我们可以看到第二个输出返回某种句柄.当我们进一步调查时:

arrayfun(@class, hT, 'UniformOutput', false)

ans = 

    'matlab.graphics.primitive.Text'
    'matlab.graphics.primitive.Text'
    'matlab.graphics.primitive.Text'
    'matlab.graphics.primitive.Text'
    'matlab.graphics.primitive.Line'
    'matlab.graphics.primitive.Line'
    'matlab.graphics.primitive.Line'
    'matlab.graphics.primitive.Line'
    'matlab.graphics.primitive.Line'
    'matlab.graphics.primitive.Line'
    'matlab.graphics.primitive.Line'
    'matlab.graphics.primitive.Line'
Run Code Online (Sandbox Code Playgroud)

和:

hT(1)

ans = 

  Text (This is a very, very long legend text) with properties:

                 String: 'This is a very, very long legend text'
               FontSize: 9
             FontWeight: 'normal'
               FontName: 'Helvetica'
                  Color: [0 0 0]
    HorizontalAlignment: 'left'
               Position: [0.0761 0.5128 0]
                  Units: 'data'

  Show all properties
Run Code Online (Sandbox Code Playgroud)

啊哈!这是第一个图例文本条目.我们在上面的列表中看到了几个有趣的属性(这里有更多),但我们关心的是String.

那么这是一个如何包装所述字符串的问题.幸运的是,这正是MATLAB文档中提供的使用python 接口的示例,因此我不会详细介绍它.这是python文档的textwrap链接.页面的正确版本(可通过左上角的下拉列表选择)应与您的本地python版本相对应(请参阅输出pyversion).

我的其余代码只是python接口的包装器,用于处理所有图例条目.

说明(选项2):

这里我们不使用任何额外的输出legend,而是修改hLeg.PlotChildren.DisplayName.此属性不接受字符串的单元格数组(多行字符串的方式通常在MATLAB中定义),因此我们需要根据解释器识别的语法插入换行符"标记"(..或字符10 - ASCII值一个"换行符",如excaza的回答所示).找到换行符的正确位置仍然是使用python完成的,但这次是join编辑字符串(中间有换行符标记)而不是转换为cell列.

笔记:

  • 在1 的选择可能提供一些额外所需的调整为代价的更多的控制.在包装字符串之后,可能需要使用Texts' Position参数来使图例看起来更好一些
  • 分配第二个输出legend会略微改变它的行为(您可以从上图中的重叠图例条目中看​​到它).