How to Control Relative Size of Figures with Colorbar in Matlab? - matlab

I am trying to line up a plot of a signal with an image where the image has a colorbar. The colorbar causes the axes to be offset horizontally.
My intuitive approach would be to fix the size of figures to something, like in Gnuplot with papersize. However, not sure which would be the best fit here.
To Adjust Scaling to Square in Full Screen Mode of Matlab?
I want to maintain the relations between the two figures. I cannot use squareform in the first figure for some reason, while I can in the latter figure.
Code
figure
ax2=subplot(2,2,2);
plot(mat2gray(pdist(data, 'correlation')));
title('Corr pdist');
cbar2 = colorbar(ax2);
xlim([0 size(mat2gray(pdist(data, 'correlation')),2)]);
set(cbar2, 'Visible', 'off');
ax4=subplot(2,2,4);
imshow(squareform( mat2gray(pdist(data, 'correlation')), 'tomatrix') );
colormap('parula'); colorbar;
title('Square Corr pdist');
Wrong Scaling in Output when Full Screen Mode of Matlab where you see the colorbar method is not sufficient for holding relations as proposed in the answer here about How to Control Relative Size of Figures with Colorbar in Matlab?
Right Scaling in Output when Default View
How can you maintain the square view of figures in the Full Screen Mode of Matlab?

I would simply create a colorbar for the top axes as well and set the visibility to off.
figure;
ax1 = subplot(2,1,1);
ax2 = subplot(2,1,2);
cbar1 = colorbar(ax1);
cbar2 = colorbar(ax2);
set(cbar1, 'Visible', 'off')
The benefit here is that you will get consistent behavior when resizing the figures, etc. because the size and position of the two axes will be rendered in the same way.
The other thing you will need to remember is to keep the axes the same in all aspects. So for example if you have an image in the bottom axes (using imshow), MATLAB by default sets the axes to a square. To get your top plot to also be square you will need to use axis square. Then they will continue to line up.
axis(ax1, 'square')

Related

MATLAB: Color of sphere distorts color scheme values

I have the following MWE, showing a surf-plot and a sphere,
figure(1)
[xx yy] = meshgrid(0:0.1:pi, 0:0.1:pi);
surf(xx, yy, zeros(size(xx)), 0.001*sin(xx), 'EdgeColor', 'none')
hold on
[xS,yS,zS] = sphere(50);
surf(xS+1, yS+1, zS+1,'FaceColor', 'k', 'edgecolor','none')
hold off
colorbar
The amplitude of the surf-plot is so small that one cannot see what value it has wrt. the colorbar. This is due to the sphere, which has a large amplitude and "distorts" everything.
Is there a way to somehow force the figure to not take into account the color of the sphere? Or maybe change its "amplitude"? I tried changing caxis, but it doesn't make a difference.
Set up manually the limits of your colorbar with caxis
your colors are C=0.001*sin(xx)
then, after the plotting, add caxis([min(C(:)) max(C(:))]) and you will have the limits are you wish

MATLAB: misaligned boxes in plotyy after saving as fig

I use plotyy to put two plots in one graph:
f = figure('Color','white');
[ax,p1,p2] = plotyy(xx, yy1, xx, yy2);
ylabel(ax(1),'Phase','FontSize',18);
ylabel(ax(2),'Spectrum','FontSize',18);
set(ax,{'ycolor'},{'k';'k'});
set(p1,'LineWidth',2,'Color',[0.4940,0.1840,0.5560]);
set(p2,'LineWidth',2,'Color','red');
xlabel(ax(1),['Frequency [THz]'],'FontSize',18);
set(ax,'FontSize',14)
Figure is displayed perfectly, but when I try to save it as fig something like misaligned boxes appears.
I tried to use linkaxes, but with no result.
plotyy has been one of my favorite MATLAB functions to love to hate. It's a really useful function that I always seem to run into bugs with, to the point where I've completely stopped using it in favor of just stacking two (or more) axes objects and plotting to them separately. You can then set the Position property of the 'sub' axes to the same as your primary axes and they will stack nicely.
A functional example:
xx = linspace(-15,15,100);
yy1 = sin(xx);
yy2 = cos(xx);
f = figure('Color','white');
ax(1) = axes('Parent', f);
ax(2) = axes('Parent', f, 'Color', 'none', 'XTick', [], 'YAxisLocation', 'right');
p1 = plot(ax(1), xx, yy1);
hold(ax(2), 'on'); % Hold to preserve our axes properties set above
p2 = plot(ax(2), xx, yy2);
hold(ax(2), 'off');
ylabel(ax(1),'Phase','FontSize',18);
ylabel(ax(2),'Spectrum','FontSize',18);
set(ax,{'ycolor'},{'k';'k'});
set(p1,'LineWidth',2,'Color',[0.4940,0.1840,0.5560]);
set(p2,'LineWidth',2,'Color','red');
xlabel(ax(1),'Frequency [THz]','FontSize',18);
set(ax,'FontSize',14)
set(ax, 'ActivePositionProperty', 'position'); % Resize based on position rather than outerposition
set(ax(2), 'Position', get(ax(1), 'Position')); % Set last to account for any annotation changes
Along with stacking the axes you will also note that I have set the ActivePositionProperty to position (rather than outerposition). MATLAB resizes axes automatically when the Units property is set to Normalized, and it seems like this is the main spot where the issue is arising. On resizing, MATLAB also modifies the OuterPosition value for the second axes, causing it to resize the plot portion. The difference is small, [0 0 1 1] vs. [0 0.0371 1.0000 0.9599] in my case, but the effect is obviously very pronounced. You can use get and set to fix this, but you'll have to do it on every resize which is fairly annoying. The alternative is to resize based on the Position, which seems to alleviate the issue and is a tweak present in the R2015b implementation of plotyy. This also fixes plotyy except for cases where the window is very small, so I have left my answer with the more generic approach.

How to delete the axes coordinate in Matlab GUI?

I want to make a Matlab GUI program.
When i use the axes to display the image, there are the axes number around the axes.
How to delete it?
so my GUI program will display the axes without any coordinates around the axes.
here is my code for display an image in axes.
axes(handles.axes16);
handles.image_gray = image_gray;
imshow(image_gray);
guidata(hObject, handles);
And here is the axes coordinates that i meant.
Remember that the axes is an handle object with many properties. I would recommend setting the axes properties 'xtick', and 'ytick', to an empty array. That way, you preserve the border, and background color of the axes. Simply turning the axes off will make your lines render on top of the background figure, which may or may not be the effect you are looking for.
Example:
set(handles.axes16,'xtick',[],'ytick',[])
A quick way to turn off the axis is, well, axis off:
Example
figure;
plot([-10:10],randn(21,1));
xlabel('x');
ylabel('y');
Now turn axis off:
axis off

Set plot (axes) view "box" without affecting limits

I have a 2D plot with many data elements on it covering a extensive area. Although all the data is necessary, I am usually interested on a small element of the plot.
I would like to programmatically focus the view on that element of interest, while allowing to use the zoom tool ((-) in the GUI) to fastly go back to a wider perspective.
It is easy to use set(gca, 'xlim', [limitsXOfSmallElement]) and set(gca, 'ylim', [limitsYOfSmallElement]) to set axis limits so that the small element is in focus, but this makes impossible to use the GUI (-) zoom tool to go back to the general view without manually resetting back axis limits to original values.
My intuition is that this could be solved by controlling camera properties (CameraPosition, CameraTarget and/or CameraViewAngle), but when I apply them, posterior uses of the GUI zoom tool have weird effects on the axis, as changing its position and size on the figure.
Is there a good method for setting the fragment of the 2D canvas that is displayed in the axis?
Consider the following example:
function example_zoom
%# some plot
plot(1:10)
hAx = gca;
%# save original axis limits
setappdata(hAx, 'limits',get(gca,{'XLim','YLim'}))
%# create custom toolbar button
[X,map] = imread(fullfile(toolboxdir('matlab'),'icons','view_zoom_out.gif'));
icon = ind2rgb(X,map);
uipushtool('CData',icon, 'ClickedCallback',{#click_cb,hAx});
%# zoom
uiwait(msgbox('Zooming now, click button to reset', 'modal'))
set(gca, 'XLim',[3 7], 'YLim',[2 9])
%zoom on
end
function click_cb(o,e, hAx)
%# restore original axis limits
limits = getappdata(hAx, 'limits');
set(hAx, 'XLim',limits{1}, 'YLim',limits{2})
end
The idea is to create your own toolbar button that restores the axis limits to their original values.

Plot Overlay MATLAB

How do you take one plot and place it in the corner (or anywhere for that matter) of another plot in MATLAB?
I have logarithmic data that has a large white space in the upper right-hand side of the plot. In the white space I would like to overlay a smaller plot containing a zoomed in version of the log plot in that white space (sort of like a magnified view).
Before you tell me it can't be done, I would like to mention that I have seen it in action. If my description is lacking, just let me know and I'll attempt to better describe it to you.
An example:
x = 1:20;
y = randn(size(x));
plot(x, y,'LineWidth',2)
xlabel('x'), ylabel('y'), title('Plot Title')
h = axes('Position', [.15 .65 .2 .2], 'Layer','top');
bar(x,y), title('Bar Title')
axis(h, 'off', 'tight')
You can use axes properties 'position' and 'units' and make them overly. Pay attention to create small axes after big one or use uistack() function so that big does not hide small one.
What you can not do is to make an axes child of another one (like Mathworks do with legend). But you do not need it anyway.
For the second plot you have to use axes and line instead of plot and hold on.
Units as 'normalized' (which is default) allows uniform resizable look when parent figure is being resized (e.g. manually maximized).