"hold on" strangely doesn't work after contourf() - matlab

I am trying to plot a vertical line on top of the current plot, but for some reason "hold on + plot()" doesn't work in this case. How could it be done?
figure1=figure(4)
axes1 = axes('Parent',figure1,'YScale','log','XScale','log','Layer','top');
grid(axes1,'on');
hold(axes1,'on');
[C,h]=contourf(peaks,[10],'LineColor','none');
clabel(C,h);
hold on %doesn't work
plot([10 10],[0 10],'--k','LineWidth',2) %doesn't work
axis tight;
axis([1 50 1 50])
xlabel('\lambda_x','Fontsize',20);
ylab=ylabel('y^+','Fontsize',20);
grid off
set(ylab, 'Units', 'Normalized', 'Position', [-0.1, 0.5, 0]);
set(gca,'linewidth',1.5,'FontSize',16)
colormap(flipud(gray(256)));
colorbar;
ax2 = axes('Position',axes1.Position,'YScale','log','XScale','log','XAxisLocation','top','YAxisLocation','right','Color','none','YTick',[]);
xla2=xlabel(ax2,'\lambda_x^+','Fontsize',20);
axis(ax2,[1*100 50*100 1*100 50*100])
set(ax2,'linewidth',1.5,'FontSize',16)

It's not the hold on that doesn't work. Change your plot line to something like this:
plot([10 10],[1e-10 10],'--k','LineWidth',2)
Note that 0 should be drawn at -inf in logarithmic scale. That sometimes causes problems.

Related

Tight subplot with colorbars and subplot's 3rd parameter in Matlab?

I would like to have a tight subplot i.e. minimum spacing between figures in the subplot where
you have subplot's 3rd parameter i.e. you can decide where the picture is going to be i.e. easy to move between subplot and new_tight_subplot, and
you can use it with colorbars.
I have profiled the most popular tight subplots in FileExchange of Matlab.
None (etc most popular here Pekka's version) can pass the following code
data=randi(513,513);
ax1=subplot(2,1,1);
plot(mat2gray(pdist(data, 'correlation')));
cbar1=colorbar(ax1);
axis(ax1, 'square');
xlim([0 size(mat2gray(pdist(data, 'correlation')),2)]);
set(cbar1, 'Visible', 'off')
ax2=subplot(2,1,2);
imshow(squareform( mat2gray(pdist(data, 'correlation')), 'tomatrix') );
colormap('parula'); colorbar;
axis(ax2, 'square');
Pekka's tight_subplot requires the syntax without the third parameter.
It also fails with colorbars as in the example. I do not understand why.
Hypothesis about the 2nd problem with colorbars
I think the problem can be the fact that colorbar objects are children of the figure, not axis, and their position is defined in normalized figure units; like for annotated objects as discussed here.
However, I am unsure how to adjust the tight subplot for this.
Test output after Author's edit in tight_subplot in FileExchange 3.3.2016
Code
data = randi(513, 513);
ax1=tight_subplot(2,1,[.01 .03],[.1 .01],[.01 .01]);
plot(mat2gray(pdist(data, 'correlation')));
ax2=tight_subplot(2,1,[.01 .03],[.1 .01],[.01 .01]);
imshow(squareform( mat2gray(pdist(data, 'correlation')), 'tomatrix') );
You get
where the plot fails and there is noisy part in the second figure for some reason. Why?
Extension of Suever's answer to 2x2 figures
ax1=axes('OuterPosition', [0 0.5 0.5 0.5]);
plot(u, 'Parent', ax1);
set(ax1, 'XLim', [0, size(u,1)]);
cbar1 = colorbar(); % not needed to assign ax1
set(cbar1, 'Visible', 'off')
ax3 = axes('OuterPosition', [0 0 0.5 0.5]);
image(data, 'Parent', ax3);
D=mat2gray(pdist(pTFD, 'correlation'));
ax2 = axes('OuterPosition', [0.51 0.5 0.5 0.5]);
plot(D, 'Parent', ax2);
set(ax2, 'XLim', [0, size(D,1)])
axis(ax2, 'square');
xlim([0 size(D,2)]);
set(cbar2, 'Visible', 'off')
ax4 = axes('OuterPosition', [0.51 0 0.5 0.5]);
imshow( D_square );
axis(ax4, 'square');
where 2x2 figure system and where I think equivalent
xlim([0 size(D,2)]); is same as set(ax1, 'XLim', [0, size(D,2)]);. Right?
...
How can you use Matlab's tight subplot with colorbars and third parameter?
The third parameter of tight_subplot defines the gaps between axis objects. For the built-in subplot command, the third parameter defines which axis is set as the CurrentAxes of the Figure. This option is not available in tight_subplot because I personally did not find it useful. Typically, I use the returned axes handles to specify where to add graphics.
Existing axes objects are repositioned when you add a colorbar.
I have added a second output argument to tight_subplot which provides the output position of the axes so that you can "reset" the axes positions after adding a colorbar.
[hax, position] = tight_subplot();
% Add a colorbar which alters the positions
colorbar();
% Now reset the positions back to where they were
set(hax, {'Position'}, pos);
Rather than trying to deal with subplot and different versions on the file exchange, I would probably just manually set the positions of my axes objects to get the effect that you want. You can use normalized units so that the positions scale as the size of the parent figure changes.
Also, you can set the OuterPosition property of the axes which takes into account the room needed to properly display all text labels of the axes.
figure
data=randi(513,513);
set(0, 'defaultaxeslooseinset', [0 0 0 0])
D = mat2gray(pdist(data, 'correlation'));
square = squareform(D, 'tomatrix');
% Set normalized outer position (x,y,width,height)
ax1 = axes('OuterPosition', [0, 0.5, 1, 0.5]);
plot(D, 'Parent', ax1);
set(ax1, 'XLim', [0, size(square, 1)])
axis(ax1, 'square');
cbar1 = colorbar();
set(cbar1, 'Visible', 'off')
% Set normalized outer position (x,y,width,height)
ax2 = axes('OuterPosition', [0 0 1 0.5]);
imshow(square);
colormap('parula'); colorbar;
axis(ax2, 'square');
And if you remove the x and y ticks on the axes
set([ax1,ax2], 'xtick', [], 'ytick', []);
This can easily be adapted to any dimensions with something similar to the following
figure;
% [Rows, Columns]
axdim = [3, 3];
width = 1 ./ axdim(2);
height = 1./ axdim(1);
[x,y] = meshgrid(linspace(0,1,axdim(2)+1), ...
linspace(0,1, axdim(1)+1));
for k = 1:numel(x)
ax = axes('OuterPosition', [x(k), y(k), width, height]);
set(ax, 'xtick', [], 'ytick', []);
end

No Gap Next to Axis Label in Matlab?

Matlab 2015b or Matlab 2016a.
I would like to have grid lines going across Subplot's spacing between the figures in order to evaluate better two pictures horizontally.
However, I have a small gap between the two figures at the lower right-hand-side corner because which is misaligning the figures
where the gap is because of the 10^4 at lower right-hand-side corner.
I would also like to have horizontal lines going across the spacing between the two figures, but I cannot do it before the gap problem is solved.
Code where the relative alignment is done as described in the answer here about the thread Tight subplot with colorbars and subplot's 3rd parameter in Matlab?
data=randi(513,513);
D=mat2gray(pdist(data, 'correlation'));
% Set normalized outer position (x,y,width,height)
ax1=axes('OuterPosition', [0 0.5 0.5 0.5]);
plot(D, 'Parent', ax1);
xlim([0 size(D,2)]);
set(cbar1, 'Visible', 'off')
title('Signal');
ax2=axes('OuterPosition', [0.51 0.5 0.5 0.5]);
plot(D, 'Parent', ax2);
set(ax2, 'XLim', [0, size(D,1)])
axis(ax2, 'square');
title('Corr pdist');
Output of Suever's answer
I tried unsuccessfully change two (2) in sprintf('%.2g', x) bigger and smaller
ax2 = axes('OuterPosition', [0.51 0.5 0.5 0.5]);
plot(D, 'Parent', ax2);
set(ax2, 'XLim', [0, size(D,1)])
axis(ax2, 'square');
title('Corr pdist');
cbar2 = colorbar(); % ax2 not needed here in brackets
set(ax2, 'XLim', [0 size(D,2)]);
set(cbar2, 'Visible', 'off')
grid minor;
% https://stackoverflow.com/a/35776785/54964
xticks = get(ax2, 'xtick');
labels = arrayfun(#(x)sprintf('%.2g', x), xticks, 'uniform', 0);
set(ax2, 'xticklabels', labels);
It gives
where those ticks are not XMinorTicks but simply ticks (wrongly marked in the picture).
They are zero points at some points in the x-axis. When x-axis gets larger, MATLAB automatically adds new xtick marks but without complete labels.
I think it would be better to have another symbol than zero there. How can you have some other mark than zero for incomplete labels of xticks?
How can you align the 10^4 next to the last number in the second figure?
I would get the current xtick locations, convert those to strings, and then set the xticklabels property of the axes.
xticks = get(ax2, 'xtick');
labels = arrayfun(#(x)sprintf('%.2g', x), xticks, 'uniform', 0);
set(ax2, 'xtick', xticks, 'xticklabels', labels);
If you want them to dynamically be computed as the figure changes size (and the xticks get recomputed) you can link this code to the SizeChangedFcn of the figure.
func = #(varargin)set(ax2,'xticklabels',arrayfun(#(x)sprintf('%.2g',x),get(ax2, 'xtick'),'uni',0));
set(gcf, 'SizeChangedFcn', func)

change background color of subplot area

I have open a figure with 2 subplots ([1,2]). On the first subplot I am draw a point cloud object with size that is smaller then the subplot, like this (ignore the plot in subplot 2):
Note that the background of the figure has filled the space that isn't being used by subplot 1.
I am looking for a way to control the background color of space that isn't being used by subplot. For example, for red background:
Any ideas?
You cannot do what you want easily. Probably the easiest thing to do is to place your plot within a uipanel and set it that way
f = figure()
panel1 = uipanel('Parent', f, ...
'Units', 'norm', ...
'Position', [0 0 0.5 1], ...
'BorderType', 'none');
panel2 = uipanel('Parent', f, ...
'Units', 'norm', ...
'Position', [0.5 0 0.5 1], ...
'BorderType', 'none');
ax1 = axes('Parent', panel1);
ax2 = axes('Parent', panel2);
set(panel1, 'BackgroundColor', 'r')
set(panel2, 'BackgroundColor', 'g')

Resize figure to Axes Position in Matlab

I have a figure with a bar plot in it, I have removed all ticks and titles, so now only the bars themselves are shown. I'd like to have the figure shrink to the size of the bar plot.
I've tried the following:
set(gca,'Units', 'Pixels');
set(gca,'XLim', [0.5 10.5],'YLim', [0 1],'Units', 'Pixels');
a=get(gca, 'Position');
set(gcf, 'Units', 'Pixels');
b=get(gcf,'Position');
set(gca, 'DataAspectRatioMode', 'manual', 'XLimMode', 'manual','YLimMode', 'manual')
set(gca, 'Position', [5,5,a(3),a(4)]);
set(gcf, 'Position', [10,10, a(3)+10,a(4)+10]);
This however doesn't work. after some investigations I found that the main problem is that the axes don't snap to the axis size.
Any way to solve this without calculating the size of every plot in the figure?
I want to decrease the blank areas around the plot below:
this is the figure after running my code, still a lot of space remains, this is because this is the size of the axes:
Thanks
edit: The problem stems from axes size as illustrated by the image below, upper picture is with DataAspectRatio set to [1 1 1] and lower picture without (automatic mode). note that the axes size doesn't change (noted by black squares)
*there is some change due to opening plot tools, which docks the figure.
Does it help?
f = figure;
% generate bar
y = [75.995,91.972,105.711,123.203,131.669,...
150.697,179.323,203.212,226.505,249.633,281.422];
bar(y);
% end of graph
axis tight;
allAx = findall(f,'type','axes');
pa = get(gca, 'Position');
pf = get(f, 'Position');
% change shape of the figure to match
% xsize(figure)/yszie(figure) = xsize(axis)/ysize(axis)
pf(4) = ((pf(3)-pf(1))*pa(4)+pa(2)*(pf(1)-pf(3))+pf(2)*pa(3)-pa(1)*pf(2))/(pa(3)-pa(1));
set(allAx, 'Units', 'Normalized', 'Position', [0, 0, 1, 1]);
set(f, 'Position', pf);

Zoomed In/Out Plots within Subplots in Matlab

I've run into a bit of a hiccup trying to plot some data in the way I want it - any advice would be greatly appreciated.
left and right are vectors of a few hundred thousand in length, obtained elsewhere.
The code below plots left, twice - the second plot lies on top of the first, roughly towards one corner.
ax1 = axes;
plot(ax1, left, 'b');
set(ax1, 'xlim', [7.075*10^4 7.5*10^4]);
set(ax1, 'ylim', [-0.02 0.02]);
ax2 = axes('Position', get(ax1,'Position'), 'XAxisLocation', 'top', 'YAxisLocation', 'right', 'Color', 'none', 'XColor', 'k', 'YColor', 'k', 'NextPlot', 'add');
plot(ax2, left, 'b');
set(ax2, 'Units', 'normalized', 'Position', [0.6 0.60 0.25 0.25]);
What I'd like to do is have the same kind of thing for right, and then display each pair of plots as a subplot, with the two subplots side by side. I've tried adapting the way I'm doing it above to use subplot, but I'm obviously doing something wrong since I keep on nuking the contents of each subplot and ending up with two empty subplots.
Also, is it possible to prevent the smaller inset plot from having a transparent background?
Consider the following example:
%# sample data
x = 1:100;
left = randn(100,1);
right = cumsum(rand(100,1)-0.5);
%# build axes positions
hBig = [subplot(121) subplot(122)]; %# create subplots
posBig = get(hBig, 'Position'); %# record their positions
delete(hBig) %# delete them
posSmall{1} = [0.275 0.63 0.16 0.24];
posSmall{2} = [0.717 0.63 0.16 0.24];
%# create axes (big/small)
hAxB(1) = axes('Position',posBig{1});
hAxB(2) = axes('Position',posBig{2});
hAxS(1) = axes('Position',posSmall{1});
hAxS(2) = axes('Position',posSmall{2});
%# plot
plot(hAxB(1), x, left, 'b');
plot(hAxB(2), x, right, 'b');
plot(hAxS(1), x, left, 'r');
plot(hAxS(2), x, right, 'r');
%# set axes properties
set(hAxB, 'XLim',[1 100], 'YLim',[-10 10]);
set(hAxS , 'Color','none', 'XAxisLocation','top', 'YAxisLocation','right');
If you want the background color of the smaller axes to be opaque, just set their colors to white:
set(hAxS , 'Color','w')
To change the background, use (for red background)
set(ax2,'color',[1 0 0])
Regarding the subplot, if you post the code that doesn't work it will help.