I'm trying to have a textbox in MATLAB on a spinning plot, but I don't want the textbox to change its position relative to the figure. I thought that 'units','normalized'
in the text
function would do it, but it's not quite working, as the example below illustrates. I suppose I could use uicontrol
but I'd like to use Greek letters and I can't get uicontrol
looking quite as good as text
. The following example recreates my problem. You'll notice the text box moves as the plot spins, but I'd like it to just stay in the top left region where it starts. Thank you!
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
Several things:
1) As you found out - using an annotation
object instead of text
object is the way to go. The difference is explained very nicely here.
2) You should only create the annotation
once and then modify its string instead of deleting and recreating it on every iteration.
Finally:
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
Notes:
1) It is interesting to note that @Otto's suggestion of using legend
results in the creation of an axes (because this is what a legend
object is - an axes
with annotation
children). You could then position the legend manually, and get its location using either get(gco,'position')
(assuming it was the last thing you clicked) or more generally get(findobj('tag','legend'),'position')
. Afterwards, whenever you create the legend, you can just set its position
to the one you previously got. You could also get rid of the line\marker inside the legend by deleting the appropriate child
of type line
from the legend
, e.g.:
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');
It is of course also possible to manipulate the legend's String
using its handle (hA1
) directly.
2) This post on UndocumentedMatlab discusses the behavior of annotation
objects and some undocumented ways to manipulate them.
You could use
legend(['\tau = ',num2str(tau)],'Location','NorthWestOutside')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With