Multiple axis plot - matlab

I have to plot some data and I need two x and y axes.
The main x and y give me displacement infos, the secondary (x on top and y on the right) give me infos on energy.
The issue I have is that if I make the plot window bigger the secondary axes don't resize properly and, but it is very minor, the plot title is written under the tool bar and I can see only the lower part of the letters.
Someone knows how to fix the main issue on secondary axes?
The code I used for secondary axis is:
figure(1)
%%%%voglio fare un plot tenendo fisse le dimensioni delle icone nella legenda
hplot = plot(yH(1,:),xH(1,:),'^', yC(:,1),xC(:,1),'*',yC(:,2),xC(:,2),'*',...
yC(:,3),xC(:,3),'*',yC(:,4),xC(:,4),'*',yC(:,5),xC(:,5),'*',...
yC(:,6),xC(:,6),'*','MarkerSize',s); % Markersize: specifys the size of the marker in points (s in questo caso)
hold on
plot(Ymcporigine,Xmcporigine,'k-','MarkerEdgeColor','k','MarkerSize',1); %Plot contorno MCP
hold on
plot(Yh, Xh, 'b-', 'MarkerSize', s); %Plot alone circolare
hold off
%Labe assi principali - It is necessary to give the label instructions after plot in order to avoid overlap
xlabel(gca, 'Deflessione magnetica [m]'); % label lower x axis
ylabel(gca,'Deflessione elettrica [m]'); %label left y axis
%particles outside MCP radius won't be appear in figure
xlim([0, Rmcp])
ylim([0, Rmcp])
%%%% legenda assi principali
l=legend(hplot, 'H^+','C^+','C^{+2}','C^{+3}','C^{+4}','C^{+5}','C^{+6}', 'Location','BestOutside');
a=get(l,'children');
set(a(1:3:end),'MarkerSize',10);
%%%% doppio Asse x
%xlabel(gca, 'Deflessione magnetica [m]'); % label asse x principale
%set secondary x limit as the momentum of a H+ at distance equal to the MCP radius
% Secondo Harres y=(q*B*LB*L)/sqrt(2mEkin) ==> mv=q*B*LB*L/y
mv_max = (q*B*LB*L)/Rmcp;
%mv_max = 1;
%Layout instruction
set(gca,'Box','off'); % Turn off the box surrounding the whole axes
axesUnits=get(gca,'Units');
axesPosition = get(gca,'Position'); %# Get the current axes position
hNewAxes = axes('Position',axesPosition,... %# Place a new axes on top...
'Units', axesUnits,...
'ActivePositionProperty', 'OuterPosition',...
'Color','none',... %# ... with no background color
'XAxisLocation','top',... %# ... located on the top
'Ytick', [],... %# ... with no y tick marks
'Xlim', [0, mv_max],... %# ... should define x axis scale (need to set xmax = mv_max)
'Box','off'); %# ... and no surrounding box
xlabel(hNewAxes,'Momentum (H^+)'); %# Add a label to the top axis
set(gca, 'XTickLabel', num2str(get(gca,'XTick')','%g'))
%%%%%Plot title - It is necessary to give the title instruction after secondary x axis in order to avoid overlap
title(['Calcolo approssimato interazione ioni campo magnetico B=', num2str(B), 'Tesla']);
%%%% doppio Asse y
%ylabel(gca,'Deflessione elettrica [m]'); %label asse y principale
%set secondary y limit as the energy of a H+ at distance equal to the MCP radius
% Secondo Harres x=(q*E*Le*L)/(2mEkin) ==> Ekin=q*E*Le*L/2mx
Le = 0.07; %Estensione del C.E. : 70 mm
E = 100000; %campo TP.m
Ekin_max = (q*E*Le*L)/(2*m_H*Rmcp);
%mv_max = 1;
set(gca,'Box','off'); % Turn off the box surrounding the whole axes
axesUnits = get(gca,'Units');
axesPosition = get(gca,'Position'); %# Get the current axes position
hNewAxes = axes('Position',axesPosition,... %# Place a new axes on top...
'Units', 'normalized',...
'ActivePositionProperty', 'OuterPosition',...
'Color','none',... %# ... with no background color
'YAxisLocation','right',... %# ... located on the right
'Ylim', [0, Ekin_max],... %# ... should define y axis scale (need to set ymax=Ekin_max)
'Xtick', [],... %# ... with no y tick marks
'Box','off'); %# ... and no surrounding box
ylabel(hNewAxes,'Energy (H^+)'); %# Add a label to the top axis
set(gca, 'YTickLabel', num2str(get(gca,'YTick')','%g'))

I remembered seeing this walkthrough on how to set up multiple axes in the Matlab documentation. I tried their sample code and everything resizes fine.
Where your code differs from the Matlab documentation, is that you need to define your x axis and y axis at the same time, not in two different new-axis statements. So take out your two hNewAxes statements and replace it with one that includes all the properties:
hNewAxes = axes('Position',axesPosition,... %# Place a new axes on top...
'Units', 'normalized',...
'ActivePositionProperty', 'OuterPosition',...
'Color','none',... %# ... with no background color
'YAxisLocation','right',... %# ... located on the right
'XAxisLocation','top',...
'Xlim', [0, mv_max],...
'Ylim', [0, Ekin_max],... %# ... should define y axis scale (need to set ymax=Ekin_max)
'Box','off'); %# ... and no surrounding box
If you want to plot some of your data lines with respect to one set of axes, and some with respect to the second, then for the second set you'll have to plot them in the style laid out at the end of the walkthrough:
hl2 = line(x2,y2,'Color','k','Parent',ax2);
where the 'Parent' property tells Matlab which axes to use.

From the Matlab docs it looks like you should set the ActivePositionProperty as OuterPosition instead of Position. I can't reproduce the scaling issue, but setting that does seem to adjust the title position.

Related

Set legend over colorbar in matlab

I'd like to have the legend (of some contours) over the colorbar of a surf plot.
How can I have a layout similar to the image in a figure plot?
From the black
colorbar;
legend('label1','label2','Location','northeastoutside');
to the red one?
You can manually change the position of both the colorbar and the legend
% Make a demo plot
figure(); hold on
plot( rand(20,3) ); % lines for the legend
peaks(10); % surface for the colorbar
view(3); % 3D view
% Create a legend and colorbar, retain their handles
L = legend( 'show', 'location', 'eastoutside' );
C = colorbar();
% Get some key variables from the current position of the colorbar/legend
% -> avg mid point of colorbar and legend
x = ( L.Position(1) + (C.Position(1)+C.Position(3)) ) / 2;
% -> Max width of the two objects
w = max( L.Position(3), C.Position(3) );
% -> A nominal y value and padding to dictate the spacing
y = 0.1;
pad = 0.05;
% Move the legend and colorbar
% First move the x/y coords of the legend to be on top, centred around common x
L.Position(1:2) = [x - L.Position(3)/2, 1 - y - L.Position(4)];
% Then move the x/y coords of the colorbar to be on the bottom, centred around common x
C.Position(1:2) = [x - C.Position(3)/2, y];
% Then resize the colorbar to use the vertical space not utilised by the legend
C.Position(4) = L.Position(2) - pad - y;
% By moving the legend/colorbar the axes will have "popped" to use the full width
% Need to move it to span between the current left edge and the newly moved leg/colorbar
ax = gca();
ax.Units = 'Norm';
ax.Position(3) = (x-w/2) - pad - ax.Position(1) ;
Result:
You can do this interactively by clicking the "Cursor" icon in the top of the plot window and adjusting the legend/colorbar. Once you have finished editing choose "Generate Code" in the "File" menu of the plot window to have code generated so you can repeatedly create the plot.

How to see text outside image matlab

I want to represent the values of a matrix as an image, adding some text in its margins. To do so, I proceed as follows:
matrix = rand(10); %Suppose this matrix
figure('color','w')
imshow(matrix,[min(matrix(:)), max(matrix(:))])
colormap(gca,jet(256))
colorbar
truesize([400,400])
for i=1:size(matrix,1)
text(-2,i,['long text ' num2str(i)], 'Interpreter', 'none')
h = text(i,0,['column ' num2str(i)], 'Interpreter', 'none');
set(h,'Rotation',90);
end
The original figure is:
I can see the text on the left increasing the figure width (with the mouse for instance):
However, if I increase the figure height as well, the image increases, and I cannot see the full text on the left and on the top at the same time.
I have 2 questions:
Is there a neater way to represent a matrix including information outside like in this example?
How could I see the full text properly?
For the first part of your question, I would do something like this, so that you don't have to keep track of the position of the labels:
matrix = rand(10);
figure('color','w')
imagesc(matrix) % plot your matrix
axis equal % correct aspect-ratio
xlim([0.5, 10.5])
colormap(gca, jet(256))
colorbar
% Create your labels
x = cell(1, size(matrix, 1));
y = x;
for i = 1:size(matrix, 1)
x{i} = sprintf('Column %u', i);
y{i} = sprintf('Long text %u', i);
end
% Edit your x axis
set(gca, ...
'XTick', 1:size(matrix, 1), ... % select the ticks to be displayed
'XTickLabel', x, ... % select their labels
'XTickLabelRotation', 90, ... % rotate the labels vertically
'XAxisLocation', 'top'); % put the x axis on top
% Similar for the y axis
set(gca, ...
'YTick', 1:size(matrix, 1), ... % select the ticks to be displayed
'YTickLabel', y); % select their labels
For your second question, there is probably a way to automatically detect the optimal size of your axes, but you can simply do it by trial and error:
set(gca, 'OuterPosition', [0, 0.05, 1, 0.9]) % for example?
In particular, you might want to change the first and third element of the vector to modify the horizontal position and width (in fraction of the figure size), and the second and fourth element for the vertical position and height.

How to format graph so that border starts at max x and y and how to replace a plot command

I am trying to format my graph so that the border ends at the max x and max y so there is not extra space between them and the border. Also, I'm trying to completely replace my first plot command with my second one. Should I just delete my first plot? Currently, the second plot goes over my first plot, removing most of my formatting.
clear all, close all
%%command to clear all variables and log history
x = linspace(-pi, pi, 200);
%creating x variable between - pi and 200 with pi distance between each
%value
y = sin(x) + cos(x);
%Creating y varable with the help of x
figure
plot(x,y)
title('2-D Plot')
xlabel('Theta (in radians)')
ylabel('Function Y')
xlim([-pi pi])
ylim([-1.414 1.414])
grid
plot(x,y,'r--')
grid
To fit the axes box tightly around the data without manually adjusting the axis limits, use:
axis tight;
and instead of re-plotting, you can update the relevant properties of the line.
x = linspace(-pi, pi, 200);
y = sin(x) + cos(x);
figure;
h = plot(x,y); %handle for the line plot
title('2-D Plot');
xlabel('Theta (in radians)');
ylabel('Function Y');
grid;
axis tight; %to set the axis limits equal to the range of the data
set(h, 'LineStyle', '--', 'Color', 'r'); %Updating the plot with required changes

Saving two fig that can be superposed_ Matlab

I am saving two matlab figures as png and I want them to have the same size in order to be perfectly superposable.
The first figure is computed by the function 'FilledCircle2' which is a circle divided in half with two colors.
The second figure is computed by function 'FilledCircleL' which is the left half of the circle computed by the function 'FilledCircle2'.
I want to be able to have two figures, both with the same size so they can be perfectly superposed.
Can someone help me understand what I am doing wrong?
Here is my code, with both of the functions and respective outputs:
function []=FilledCircle2(x0,y0,Radius,N, col1, col2)
if(N<=1)
error('N must be greater than 1');
end
hold on
axis equal
axis off
hold on
t=(0:N)*2*pi/N; %t=-pi:0.01:pi
x=Radius*cos(t)+x0;
y=Radius*sin(t)+y0;
plot(x,y)
hold on
%Divide circle in to 2 equal parts
n=2;
thetas = linspace(-pi, pi,n+1); %linspace generates n points. The space between the points is [(pi/2)-(-pi/2)]/(n)
% Specify any colors wanted
colors = [col1; col2];
for k = 1:n
tt = linspace(thetas(k), thetas(k+1));
xi = Radius * cos(tt) + x0;
yi = Radius * sin(tt) + y0;
c2= fill([xi(:); x0], [yi(:); y0], colors(k,:)); %Assign diffrent colors to each circle 'slice'
set (c2, 'edgecolor','white')
set(c2,'LineWidth',2.0)
set(gcf,'PaperUnits','inches','PaperSize',[0.8666,0.8666],'PaperPosition',[0 0 0.8666 0.8666])%setting size (130/150, 130/150, 150pixels per inch being the default size of img), paper position is imporrtant as otherwise i will have extra border
set(gca, 'Position', [0 0 1 1]);
set(gcf,'color',[0.49019607843137 0.49019607843137 0.49019607843137])%figure properties, rgb(125/255,125/255,125/255)
fig = gcf;
fig.InvertHardcopy = 'off'; %saves the fig with the set background color
%rotates the plot
az= 90; %azimuth, az, is the horizontal rotation about the z axis as measured in degrees from the negative y-axis. Positive values indicate counterclockwise rotation
el= 90; % vertical elevation of the view point in degrees
view(az,el);
hold on
end
Here is the output of the function FilledCircle2(0,0,10,300, 'y', 'r'):
[
function []=HalfFilledCircleL(x0,y0,Radius,N, col1)
if(N<=1)
error('N must be greater than 1');
end
hold on
axis equal
% axis tight
axis off
hold on
t=(0:N)*(-pi)/N; %t=-pi:0.01:pi
x=Radius*cos(t)+x0;
y=Radius*sin(t)+y0;
hold on
c1=fill(x,y,col1); %filling the semi-circle
set (c1, 'edgecolor','white') %setting the outline color of the semi-circle
set(gcf,'color',[0.49019607843137 0.49019607843137 0.49019607843137])%figure properties, rgb(125/255,125/255,125/255)
set(c1,'LineWidth',2.0)
set(gcf,'PaperUnits','inches','PaperSize',[0.8666,0.8666],'PaperPosition',[0 0 0.8666,0.8666])%setting size (130/150, 130/150, 150pixels per inch being the default size of img), paper position is imporrtant as otherwise i will have extra border
set(gca, 'Position', [0 0 1 1]);
fig = gcf;
fig.InvertHardcopy = 'off'; %saves the fig with the set background color
% %rotates the plot
az= 90; %azimuth, az, is the horizontal rotation about the z axis as measured in degrees from the negative y-axis. Positive values indicate counterclockwise rotation
el= 90; % vertical elevation of the view point in degrees
view(az,el);
end
Here is the output of the function HalfFilledCircleL(0,0,10,300, 'r'):
use xlim and ylim to set the xy limits of the axes:
figure;
HalfFilledCircleL(0,0,10,300, 'r');
xlim([-12 12]);ylim([-12 12]);
az= -90; %azimuth, az, is the horizontal rotation about the z axis as measured in degrees from the negative y-axis. Positive values indicate counterclockwise rotation
el= 90; % vertical elevation of the view point in degrees
view(az,el);
figure;
FilledCircle2(0,0,10,300, 'y', 'r');
xlim([-12 12]);ylim([-12 12]);

Zoom region within a plot in Matlab

I'm using Matlab to produce figures, and I'm wondering if there is a way to plot a zoomed region in a figure of the overall data?
I have scatter data plotted over one week, with the x-axis in hours, and I want to zoom into the first 3 hours, and display them within the main figure with the x-axis label of minutes.
The plotting code I have so far is as follows:
allvalsx = marabint(:,2)
allvalsy = marabint(:,5)
subvalsx = marabint(1:7,2);
subvalsy = marabint(1:7,2);
%% Plots the scatter chart.
sizemarker = 135
handle = scatter(allvalsx, allvalsy, sizemarker, '.')
figure(1)
axes('Position',[.2 .2 .2 .2])
handle2 = scatter(subvalsx, subvalsy, '.r')
title(plotTitle)
xlabel('Time since treatment (hours)')
ylabel('Contact angle (deg)')
% Axis scales x1, x2, y1, y2
axis([0, marabint(length(marabint),2) + 10, 0, 120]);
% This adds a red horizontal line indicating the untreated angle of the
% sample.
untreatedLine = line('XData', [0 marabint(length(marabint),2) + 10], 'YData', [untreatedAngle untreatedAngle], 'LineStyle', '-', ...
'LineWidth', 1, 'Color','r');
% Adding a legend to the graph
legendInfo = horzcat('Untreated angle of ', untreatedString)
hleg1 = legend(untreatedLine, legendInfo);
% This encases the plot in a box
a = gca;
% set box property to off and remove background color
set(a,'box','off','color','none')
% create new, empty axes with box but without ticks
b = axes('Position',get(a,'Position'),'box','on','xtick',[],'ytick',[]);
% set original axes as active
axes(a)
% link axes in case of zooming
linkaxes([a b])
set(gcf,'PaperUnits','inches');
set(gcf,'PaperSize', [8.267 5.25]);
set(gcf,'PaperPosition',[0 0.2625 8.267 4.75]);
set(gcf,'PaperPositionMode','Manual');
set(handle,'Marker','.');
print(gcf, '-dpdf', '-r150', horzcat('markertest4.pdf'));
This produces the following
Can anyone help me out with this?
yeah, I think I know what you need. Try this:
zoomStart = 0;
zoomStop = 3;
set(gca, 'XLim', [zoomStart zoomStop])
Let me know if that doesn't do what you need, and I'll give you a different way.