【问题标题】:MATLAB textbox in a constant position on top of spinning 3D plot?MATLAB 文本框位于旋转 3D 绘图顶部的恒定位置?
【发布时间】:2014-09-22 18:08:12
【问题描述】:

我试图在 MATLAB 中在旋转图上创建一个文本框,但我不希望文本框更改其相对于图形的位置。我认为text 函数中的'units','normalized' 可以做到这一点,但它并不完全有效,如下面的示例所示。我想我可以使用uicontrol,但我想使用希腊字母,但我无法让uicontrol 看起来和text 一样好。以下示例重现了我的问题。您会注意到文本框随着情节的旋转而移动,但我希望它只停留在它开始的左上角区域。谢谢!

part_x = rand(1000,3)-.5;                         %generate random 3D coordinates to scatter
fig1 = figure;
scatter3(part_x(:,1), part_x(:,2), part_x(:,3))
axis equal vis3d
axis([-1 1 -1 1 -1 1])
set(fig1,'color','w')

for tau = 1:150
    view(tau+20,30);                              %spin the plot
    pause(.01)
    if tau~=1; delete(tau_text); end;             %delete the previous text if it exists
    tau_text = text(.1,.7,...
                    ['\tau = ',num2str(tau)],...
                    'units','normalized',...      %text coordinates relative to figure?
                    'Margin',3,...                %these last 3 lines make it look nice
                    'edgecolor','k',...
                    'backgroundcolor','w');
end

【问题讨论】:

  • +1 表示可重复的示例

标签: matlab text 3d location figure


【解决方案1】:

几件事:

1) 正如您所发现的 - 使用 annotation 对象而不是 text 对象是要走的路。区别很好地解释了here

2) 您应该只创建一次annotation,然后修改它的字符串,而不是在每次迭代时删除并重新创建它。

最后:

part_x = rand(1000,3)-.5;
fig1 = figure;
scatter3(part_x(:,1), part_x(:,2), part_x(:,3))
axis equal vis3d
axis([-1 1 -1 1 -1 1])
set(fig1,'color','w')

%// Create the text outside the loop:
tau_text = annotation('textbox',[0.2 0.8 0.1 0.05],...
                  'string','\tau = NaN',...
                  'Margin',4,... 
                  'edgecolor','k',...
                  'backgroundcolor','w',...
                  'LineWidth',1);

for tau = 1:150
    view(tau+20,30); 
    pause(.01)
    set(tau_text,'String',['\tau = ',num2str(tau)]); %// Modify the string
end

注意事项:

1) 有趣的是,@Otto 建议使用 legend 会导致创建 axes(因为这就是 legend 对象的含义 - 带有 axes annotation儿童)。然后,您可以手动定位图例,并使用get(gco,'position')(假设它是您单击的最后一件事)或更一般地使用get(findobj('tag','legend'),'position') 获取它的位置。之后,无论何时创建图例,您都可以将其 position 设置为您之前获得的那个。您还可以通过从legend 中删除line 类型的相应child 来消除图例中的行\标记,例如:

ezplot('sin(x)');
hLeg = legend('\tauex\tau');
delete(findobj(findobj('Tag','legend'),'Type','line'));
hA1 = findobj(findobj('Tag','legend'),'Type','text');
set(hA1,'Position',[0.5,0.5,0],'HorizontalAlignment','center');

当然也可以直接使用图例的句柄(hA1)来操作图例的String

2) This post on UndocumentedMatlab 讨论了annotation 对象的行为以及一些未记录的操作它们的方法。

【讨论】:

  • +1 感谢您提供指向 Yair 网站的链接,很高兴知道!
【解决方案2】:

你可以使用

legend(['\tau = ',num2str(tau)],'Location','NorthWestOutside')

【讨论】:

    【解决方案3】:

    感谢 Dev-iL! annotationtext 工作得更好,并且实现非常相似。感谢您提供有关修改字符串而不是删除重新创建字符串的建议。

    这是现在的代码,效果更好:

    part_x = rand(1000,3)-.5;                         %generate random 3D coordinates to scatter
    fig1 = figure;
    scatter3(part_x(:,1), part_x(:,2), part_x(:,3))
    axis equal vis3d
    axis([-1 1 -1 1 -1 1])
    set(fig1,'color','w')
    
    tau_text = annotation('textbox',[0.2 0.8 0.1 0.05],...
                          'string','',...
                          'Margin',4,...                %these last 4 lines make it look nice
                          'edgecolor','k',...
                          'backgroundcolor','w',...
                          'LineWidth',1);
    
    for tau = 1:150
        view(tau+20,30);                              %spin the plot
        pause(.01)
        set(tau_text,'String',['\tau = ',num2str(tau)]);
    end
    

    【讨论】:

    • 看到您不接受自己的(工作)答案,我将您的答案合并到我自己的答案中,并添加了对legend 的小讨论。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多