Centering xlabel position in MATLAB - matlab

How can I center the position of an xlabel such that it is in the middle of a figure? I would like the center of the xlabel to be alligned with the center of a caption when using LaTeX

The xlabel function creates a string graphics object and sets this as the XLabel property of the current axes object. You can define properties for this string objects when calling xlabel. You can adjust the position of the center of the string object by adjusting the Position property which is by defaults set to [0 0].
First you get what the position is right now (after plotting and using xlabel):
vec_pos = get(get(gca, 'XLabel'), 'Position');
Then you update the position (adjust x with -0.5 for instance):
set(get(gca, 'XLabel'), 'Position', vec_pos + [-0.5 0 0]);
This is done in the data-units by default of the x-axis as far as the documentation goes. It seems to me that the label "Time (s)" is located at 0.13s (according to your figure). Let's adjust it to the left with 0.008 seconds to 0.122s (a "guestimate").
Force it to be "data" units and adjust with 0.008:
str_defaultUnits = get(get(gca, 'XLabel'), 'Units'); % copy this
set(get(gca, 'XLabel'), 'Units', 'data'); % change it
set(get(gca, 'XLabel'), 'Position', vec_pos + [-0.008 0 0]); % adjust position
set(get(gca, 'XLabel'), 'Units', str_defaultUnits); % set it back as it was
On another note: What you trying to achieve is somewhat wrong I would say :) The label of an axis should not be aligned by force to the entire figure caption. Why do this? The figure caption is centered on the entire figure, not just the plotting area. I fear it will look weird in the end. Your choice of course.

The specifics of what you're trying to do will depend on your matlab print settings and latex options (e.g. caption raggedright or centering), but this should at least put your xlabel in the centre of the figure, rather than the centre of the axes.
fh=figure;
ah=axes;
plot(ah,[2.0:10],[2:10])
xlh=xlabel(ah,'my xlabel');
drawnow;
xlh_pos=get(xlh,'position');
ah_pos=get(ah,'position');
x_lim=xlim;
xlh_pos_fig=0.5;%put it in the middle
xlh_pos(1)=(xlh_pos_fig - ah_pos(1))*(x_lim(2)-x_lim(1))/ah_pos(3)+x_lim(1);
set(xlh,'position',xlh_pos);

Related

Ezpolar plots function string over polar axes

I'm using Ezpolar function in order to plot some graphics. Three of them have as maximum value 4, but the last one only has a bit more than 2.
When I plot them, the last one is plotted with it's function over it (seems like if ezpolar paints it some pixels after it maxium value used as radius).
Code and Generated Plot
% This subplot is used since I've 4 graphics to draw.
subplot(2,2,4)
ezpolar('0.25*(5 - 4*cosd(-180 * sin(t) ))');
title('D')
If I don't use this subplot, using a complete figure to draw the graphics seems fine. However, since I need to have all four of them together, it results in (will draw only the problematic one, subplot 2,2,4):
As you can see, r = 0.25 (5 - 4...) is plotted just over the polar axes.
Why is it happening? How can I fix it?
The issue appears to be with the position of that annotation and the fact that when you use a subplot, the limits on the radius of the polar plot actually change but the position of the annotation does not.
To combat this, you could actually compute the limits of the axes and change the position of the text to be explicitly outside of the plot.
hax = subplot(2,2,4);
p = ezpolar('0.25*(5 - 4*cosd(-180 * sin(t) ))');
% Get the handle to the label text object
label = findobj(hax, 'type', 'text');
% Figure out the current axes limits
ylims = get(hax, 'ylim');
% Add some padding (as a percent) to the position
padding = 0.2;
set(label, 'Position', [0 ylims(1)*(1 + padding), 0]);
A better way to do this would be to change the Units of the label to use Normalized units (relative to the axes) rather than Data units. This way, it will not change if the axes limits change.
hax = subplot(2,2,4);
p = ezpolar('0.25*(5 - 4*cosd(-180 * sin(t) ))');
% Get the handle to the label text object
label = findobj(hax, 'type', 'text');
set(label, 'Units', 'Normalized', 'Position', [0.5, -0.2]);

Enlarge figure in MATLAB

I want to create figure that is enlarged, I use:
fig = figure(1); %These two lines maximize the figure dialogue
set (fig, 'Units', 'normalized', 'Position', [0,0,1,1]);
The dialogue is enlarged. What should I do if I also want the graph inside this dialogue also enlarged? Although I can use "zoom in" and "pan" in the dialogue to enlarge and reposition my graph I want this be done automatically by codes.
Thanks a lot.
Update of my question:
I am trying to plot 3D block which the value is represented by color of each small unit block:
clear; close all; clc;
fig = figure(1);
set (fig, 'Units', 'normalized', 'Position', [0,0,1,1]);
fig_color='w'; fig_colordef='white';
cMap=jet(256); %set the colomap using the "jet" scale
faceAlpha1=1;
faceAlpha2=0.65;
edgeColor1='none';
edgeColor2='none';
NumBoxX=100;%box number in x direction
NumBoxY=100;%box number in y direction
NumBoxZ=5;%box number in z direction
fid = fopen('Stress.dat','r');
datacell = textscan(fid, '%f%f%f%f%f%f%f%f%f%f%f%f%f%f');
fclose(fid);
all_data = cell2mat(datacell);
M=zeros(NumBoxX,NumBoxY,NumBoxZ);
for i=1:NumBoxX
for j=1:NumBoxY
for k=1:NumBoxZ
num=k+NumBoxZ*(j-1)+NumBoxZ*NumBoxY*(i-1);
M(i,j,k)=all_data(num,4); %the forth column of all_data is dislocation density
end
end
end
indPatch=1:numel(M);
[F,V,C]=ind2patch(indPatch,M,'v'); %Call the function ind2patch in order to plot 3D cube with color
title('\sigma_{xy}','fontsize',20);
xlabel('y','fontsize',20);ylabel('x','fontsize',20); zlabel('z','fontsize',20); hold on;
set(get(gca,'xlabel'),'Position',[5 -50 30]);
set(get(gca,'ylabel'),'Position',[5 50 -15]);
set(get(gca,'zlabel'),'Position',[64 190 -60]);
patch('Faces',F,'Vertices',V,'FaceColor','flat','CData',C,'EdgeColor','k','FaceAlpha',0.5);
axis equal; view(3); axis tight; axis vis3d; grid off;
colormap(cMap); caxis([min(M(:)) max(M(:))]);
cb = colorbar;
set(get(cb,'title'),'string','Stress (MPa)','fontsize',20);
lbpos = get(cb,'title'); % get the handle of the colorbar title
set(lbpos,'units','normalized','position',[0,1.04]);
zoom(1.9);
I maximize the dialogue, read data from a file and use a function "ind2patch" found in internet to create boxes each has a color determined by a value assigned to it. At the last part I used zoom(1.9) to enlarge it but I want to shift the whole figure without moving the colorbar.
The following is the original picture before zoomed:
https://www.dropbox.com/s/xashny3w1fwcb2f/small.jpg?dl=0
The following picture is enlarged using zoom(1.9):
https://www.dropbox.com/s/0sfqq1lgo7cm5jd/large.jpg?dl=0
MyAxes=gca;
set(MyAxes,'Units','Normalized','position',[0.1,0.1,0.8,0.8]);
Note that the position you define is with respect to your axes parent, i.e. the figure.
If the figure you want to enlarge is not the current figure, you'll have to dig in your fig object's children in order to find your axes :
MyAxes=get(fig,'Children');
set(MyAxes,'Units','Normalized','position',[0.1,0.1,0.8,0.8]);
Note that, if your figure contains several subplots (thus several axes), you'll have to loop over all of them in order to enlarge them the way you want.
UPDATE : In order to reposition your graph as would the "pan" button do, you'll have to change your axes 'xlim' and 'ylim' properties. For example, if you want to move it 5% to the right and 10% to the top :
%Get current limits
MyXLimits=get(MyAxes,'xlim'); %1x2 vector [xmin,xmax]
MyYLimits=get(MyAxes,'ylim'); %1x2 vector [ymin,ymax]
%Calculate desired limits
MyNewXLimits=[MyXLimits(1)+0.05*(MyXLimits(2)-MyXLimits(1))...
MyXLimits(2)+0.05*(MyXLimits(2)-MyXLimits(1))];
MyNewYLimits=[MyYLimits(1)+0.1*(MyYLimits(2)-MyYLimits(1))...
MyYLimits(2)+0.1*(MyYLimits(2)-MyYLimits(1))];
% Set desired limits
set(MyAxes,'xlim',MyNewXLimits);
set(MyAxes,'ylim',MyNewYLimits);
Or if you know a priori the X and Y limits you want :
%Set desired limits directly
set(MyAxes,'xlim',[Myxmin Myxmax]);
set(MyAxes,'ylim',[Myymin Myymax]);
I think you can figure out how to zoom in/zoom out by yourself, as it also involves playing with the limits of your graph.

Rotate MATLAB legend

Is there a way to rotate the MATLAB legend inside a plot? The image below should clarify my requirement.
the legend function can return serval of args:
[leg,labelhandles,outH,outM] = legend(varargin)
When you ask for the 2nd argument you get a list of all the Children and then you can use what phil's answer:
set(hc(3),'Position',[0.5 0.6 0],'Rotation',90); % Relocate and rotate text
set(hc(2),'Xdata',[0.5 0.5],'YData',[0.1 0.5]); % rotate the line
set(hc(1),'XData',0.5,'YData',0.3); % R
This is correct for matlab 2021b
You'll need to play around with the positioning, and need to do more work if you have more than one line plotted, but the following does it for your example.
plot(1:10); % create a dummy line
ha = legend('Plot'); %create a legend
set(ha,'Units','pixels'); % set axes unit to pixels
pos = get(ha,'Position'); % get the axes position
set(ha,'Position',[pos(1) pos(2)-pos(3) pos(4) pos(3)]); % Set the new position
hc = get(ha,'Children'); % Get the legend contents
set(hc(3),'Position',[0.5 0.6 0],'Rotation',90); % Relocate and rotate text
set(hc(2),'Xdata',[0.5 0.5],'YData',[0.1 0.5]); % rotate the line
set(hc(1),'XData',0.5,'YData',0.3); % Rotate the Marker
The example is not fully automated but should set you on the right route. You need to rotate the box containing the legend, and the label with the text./
% Example plot
plot(1:10)
h = legend('something')
% Rotate legend
set(h,'CameraUpVector', [1 0 0], 'Units','pixels','position',[460 230 25 150])
% Rotate text label
txt = findobj(h,'type','text');
set(txt,'rotation',90)
Unfortunately, the save as function restores the 'CameraUpVector'.

Plotting a subplot on top of another plot in Matlab

I need to plot several plots along a sloped line at different positions.
For example, if I:
plot(0:200,'k');
plotpts = 5:5:200;
I would like to be able to plot a smaller plot at each of my plotpts on top of the original 0:200 line.
I know you can use hold on and plot over top that way, but I need to change my origin each time. Does anyone have any suggestions? I would really like to stay in matlab. Thanks!
Here is a flexible way I usually do it:
plot(1:10, 'k')
plotpts = 2:2:8;
mainbox = get(gca, 'Position');
xlims = get(gca, 'XLim');
ylims = get(gca, 'Ylim');
for i=1:length(plotpts)
originx = mainbox(1) + (plotpts(i) - xlims(1)) * (mainbox(3)) / (xlims(2) - xlims(1));
originy = mainbox(2) + (plotpts(i) - ylims(1)) * (mainbox(4)) / (ylims(2) - ylims(1));
axes('position', [originx originy 0.1 0.1], 'Color', 'none')
% Do some plotting here...
end
It's quite a bit of work, but you probably want to use the axes command. A figure window can host any number of axes, where each axes has it's own position, data, annotations, color etc.
The most difficult thing for the application you describe is that each axis position needs to be defined in the coordinate frame of the underlying figure, which means that some math may be required to create the illusion that the axis is correctly positioned within a parent axes/
For example, if you first create a simple plot
figure(1234); clf;
plot(1:10, rand(1,10),'.k-','linewidth',5);
xlim([1 10]);
ylim([0 1]);
set(gca,'color','y'); %This just helps demonstrate the next steps
You can place another axis directly on top of the first, and then
ha = axes('position',[.2 .3 .1 .1])
plot(linspace(0,2*pi,100), sin(linspace(0,2*pi,100)), 'b-')
xlim([0 2*pi])
You can adjust the the properties of the inset axis to suit your particular needs, for example
set(ha,'color','none'); %A transparent axis
set(ha,'xtick',[],'ytick',[]); %Remove tick labels
title(ha,'This is an inset plot')
Is the command subplot not what you're looking for?

Add legend outside of axes without rescaling in MATLAB

I've got a GUI in MATLAB with a set of axes pre-placed. I'm using the location property of the legend to place it to the right hand side of the axes. However, by doing this the axes get re-scaled so that the axes+legend take up the original width of the axes. Is there any way to circumvent the re-size?
Example:
x=0:.1:10;
y=sin(x);
figure
pos=get(gca,'position');
pos(3)=.5; %#re-size axes to leave room for legend
set(gca,'position',pos)
plot(x,y)
So far I get:
Place legend:
legend('sin(x)','location','eastoutside')
...aaaaand...
MATLAB squishes it all into the original axes space. Any way around this?
EDIT
%# create three axes with custom position
x=0:.1:10;
y=sin(x);
hAx1 = axes('Position',[0.05 0.05 0.7 0.2]); plot(hAx1, x,y)
hAx2 = axes('Position',[0.05 0.4 0.7 0.2]); plot(hAx2, x,y)
hAx3 = axes('Position',[0.05 0.75 0.7 0.2]); plot(hAx3, x,y)
%# add legend to middle one
h = legend(hAx2, 'sin(x)'); pos = get(h,'position');
set(h, 'position',[0.8 0.5 pos(3:4)])