change background color of subplot area - matlab

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')

Related

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

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.

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

Background Grid Lines Across Spacing of Figures in Matlab?

I would like to have vertical/horizontal grid lines across spacing of figures in Matlab 2015b.
I know that you can have a background image that can be a network of gridlines by background, something partial about it at How do I add a background image to my GUI or figure window?
However, I think gridlines without a picture would be a better choice
Example code
data=randi(513,513);
D=mat2gray(pdist(data, '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');
title('Corr pdist');
cbar2 = colorbar();
set(ax2, 'XLim', [0 size(D,2)]);
set(cbar2, 'Visible', 'off')
grid minor;
% Force a draw event to have the axes determine where the
labelconverter = #(x)sprintf('%.2g', x); % https://stackoverflow.com/a/35780915/54964
callback = #(varargin)set(ax2, 'xticklabels', arrayfun(labelconverter, get(ax2, 'xtick'), 'uniform', 0));
set(hFig, 'SizeChangedFcn', callback);
callback(); % necessary for the original small window and its scientific numbering
D_square=squareform(D, 'tomatrix');
ax4 = axes('OuterPosition', [0.51 0 0.5 0.5]);
imshow( D_square );
colormap('parula'); colorbar;
axis(ax4, 'square');
title('Square Corr pdist');
where the system is based on relative positions, rather than subplot as described in the answer here about Tight subplot with colorbars and subplot's 3rd parameter in Matlab?
Hypothetical methods
have master figure which has grid lines; embed those two figures there as parent positions; not sure if possible
assign gridlines function to the function background
have a separate background image which has static gridlines
Function about Suever's script
function [ hFig ] = init_background_grid(thickness)
%% Background
hFig=figure;
backax = axes('Parent', hFig);
% Ensure that this is below other objects
uistack(backax, 'bottom');
% Span the whole figure
set(backax, 'Position', [0 0 1 1]);
grid(backax, 'on')
% Make it invisible except for the grid and
% ensure it isn't able to be interacted with
set(backax, 'HitTest', 'off', ...
'HandleVisibility', 'off', ...
'GridLineStyle', '-', ...
'Color', 'none', ...
'XColor', 'none', ...
'YColor', 'none')
% Determine grid spacing with x/y ticks
% Increase nLines for a finer grid
nLines = thickness; % 30 default
set(backax, 'XTick', linspace(0, 1, nLines), ...
'YTick', linspace(0, 1, nLines));
end
How can you have grid lines in the background i.e. in the spacing between figures?
I would probably just setup an axes that spans your entire figure, then turn on the grid lines, then set the color of the axes to 'none'. A full example is shown below.
fig = figure();
backax = axes('Parent', fig);
% Ensure that this is below other objects
uistack(backax, 'bottom');
% Span the whole figure
set(backax, 'Position', [0 0 1 1]);
grid(backax, 'on')
% Make it invisible except for the grid and
% ensure it isn't able to be interacted with
set(backax, 'HitTest', 'off', ...
'HandleVisibility', 'off', ...
'GridLineStyle', '-', ...
'Color', 'none', ...
'XColor', 'none', ...
'YColor', 'none')
% Determine grid spacing with x/y ticks
% Increase nLines for a finer grid
nLines = 20;
set(backax, 'XTick', linspace(0, 1, nLines), ...
'YTick', linspace(0, 1, nLines));
You can then add any plots, uicontrols, etc. on top of this and it should work just fine. It will also handle the case where you decide that you want a different figure color.

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.