Set legend over colorbar in matlab - 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.

Related

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.

Labeling 3D Surface Plots in MATLAB along respective axes

I have doubts regarding Labeling 3D Surface Plots in MATLAB along respective axes.
for j=1:length(op)
x = op{j}(:,1);
z = st:inc:en;
y = op{j}(:,2:end);
figure
surf(x,z,y.','FaceAlpha',1.0) % surface plot
xlabel('Non-Dimensional Number (k_0a)')
ylabel('Non-Dimensional Horizontal Force (HF_P)')
zlabel('Non-Dimensional Porous Parameter (G_S)')
axis tight
view(30,40)
grid on
end
The result is the following 3D plot having labels not alligned in respective axis. Any help on alligning the labels in respective axes is highly appreciated.
Many Thanks.
You can set the position and the rotation of the label as follow,
[x,y] = meshgrid(1:0.5:10,1:20);
z = sin(x) + cos(y);
figure
surf(x,y,z,'FaceAlpha',1.0) % surface plot
xlabel('Non-Dimensional Number (k_0a)','FontSize', 20)
ylabel('Non-Dimensional Horizontal Force (HF_P)','FontSize', 20)
zlabel('Non-Dimensional Porous Parameter (G_S)','FontSize', 20)
axis tight
view(30,40)
grid on
xh = get(gca,'XLabel'); % Handle of the x label
set(xh, 'Units', 'Normalized')
pos = get(xh, 'Position');
set(xh, 'Position',pos.*[1,-0.5,1],'Rotation',-10)
yh = get(gca,'YLabel'); % Handle of the y label
set(yh, 'Units', 'Normalized')
pos = get(yh, 'Position');
set(yh, 'Position',pos.*[1,-0.7,1],'Rotation',30)
the results,
Ref

Using roof of a graph as x-axis for another

I've plotted a graph using pcolor which gives me the following graph-
My aim is to use the roof of the graph (by roof) I mean the highest axis (in this case, the line which is defined by y=57) as the base for a further graph.
I was able to use hold on to generate the following-
Code for this (removed some parts that defined the axis labels etc for brevity)-
load sparsemap ;
load d ;
residues = 57 ;
z = zeros(residues,residues); % define the matrix
index = find(sparsemap(:,3) ~= 0) ;
values = length(index);
hold on
%Plots the map you see in the first photo-
for k = 1:values
z(sparsemap(index(k),1),sparsemap(index(k),2)) = sparsemap(index(k),3);
z(sparsemap(index(k),2),sparsemap(index(k),1)) = sparsemap(index(k),3);
end
%Plots the line plot at the bottom of the graph.
A = d(:,1);
B = d(:,2) ;
plot(A, B) ;
pcolor(1:residues,1:residues,z);
works = load('colormap_works');
colormap(works);
colorbar;
As you can see, the line plot is using the same x axis as the first graph.
I am trying to get the line plot to come on top of the figure. I imagine a final figure like so-
Any ideas as to how I can use the top part of the first graph?
You can use 2 subplots. Here is an example:
data = randi(50,20,20); % some data for the pcolor
y = mean(data); % some data for the top plot
subplot(5,1,2:5) % create a subplot on the lower 4/5 part for the figure
pcolor(data) % plot the data
colormap hot;
h = colorbar('east'); % place the colorbar on the right
h.Position(1) = 0.94; % 'push' the colorbar a little more to the right
ax = gca;
pax = ax.Position; % get the position for further thightning of the axes
ax.YTick(end) = []; % delete the highest y-axis tick so it won't interfere
% with the first tick of the top plot
subplot(5,1,1) % create a subplot on the upper 1/5 part for the figure
plot(1:20,y) % plot the top data
ylim([0 max(y)]) % compact the y-axis a little
ax = gca;
ax.XAxis.Visible = 'off'; % delete the x-axis from the top plot
ax.Position(2) = pax(2)+pax(4); % remove the space between the subplots
Which creates this:

Plot many horizontal Bar Plots in the same graph

I need to plot a x-y function, that shows the histograms at x-values. Something similar to the bottom plot of the next figure:
I tried to use matlab's "barh", but can't plot many in the same figure.
Any ideas?
Or, maybe displacing the origin (baseline, basevalue in barseries properties) of successive plots would work. How could I do that for barh?
thanks.
Using 'Position' of axes property
% generate "data"
m = rand( 40,10 );
[n x] = hist( m, 50 );
% the actual plotting
figure;
ma = axes('Position',[.1 .1 .8 .8] ); % "parent" axes
N = size(n,2); % number of vertical bars
for ii=1:N,
% create an axes inside the parent axes for the ii-the barh
sa = axes('Position', [0.1+(ii-1)*.8/N, 0.1, .8/N, .8]); % position the ii-th barh
barh( x, n(:,ii), 'Parent', sa);
axis off;
end

Multiple axis plot

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.